29467079bd35e3c3fa2d2c1510674a21.png

1、实验目的

理解和掌握产生式系统的推理方法,能够用选定的编程语言实现推理机。

2、实验内容和要求

(1)以实验1的动物识别系统的规则库和综合数据库为基础;

(2)用选定的编程语言开发一个推理机,该推理机能利用实验1的规则库和综合数据库进行推理。

834e0bca1cfb407521e027c1d801501c.pngafbc5f10dc5e4f3ac07a1fdbaffb43b4.png

3d214ab9981599054570785c1e17e453.png

话不多说,直接上代码

C++版本
运行截图0dc5943cbde2a24f47d5aacf8bdb645f.png

  #include  #include  #include  #include  #include     using namespace std;     const int fact_num = 31;      //知识库中的知识:31种知识  const int rule_num = 15;      //知识库中的规则:15条规则  const int rule_volume = 4;    //规则中每个结果最多有4个前提条件  const int object_range_begin = 25;  //从第25个知识开始  const int object_range_end = 31;    //到第31个知识为目标结论  const int object_middle_begin = 21;     //中间结果起始位置      string fact[fact_num] =                 {    "有毛发","产奶","有羽毛","会飞","会下蛋",    "吃肉","有犬齿","有爪","眼盯前方","有蹄",    "反刍","黄褐色","有斑点","有黑色条纹","长脖",    "长腿","不会飞","会游泳","黑白二色","善飞",    "哺乳类","鸟类","食肉类","蹄类","金钱豹",    "虎","长颈鹿","斑马","鸵鸟","企鹅","信天翁"  };     int rule_prerequisite[rule_num][rule_volume] =        {    {1,0,0,0},    {2,0,0,0},    {3,0,0,0},    {4,5,0,0},    {21,6,0,0},    {7,8,9,0},    {21,10,0,0},    {21,11,0,0},    {23,12,13,0},    {23,12,14,0},    {24,15,16,13},    {24,14,0,0},    {22,15,16,4},    {22,18,19,4},    {22,20,0,0}  };     int rule_result[rule_num] =  {    21,    21,    22,    22,    23,    23,    24,    24,    25,    26,    27,    28,    29,    30,    31  };     bool backward_reasoning(int num,int message[]) ;  bool inference(int num,int message[])         //迭代推理机{    int ii, ij, ik,im,in;    int hit_num = 0;          //输入前提也规则前提重合数    int prerequisite_num;     //规则前提数    int *message_c;           //迭代前提    int num_c;                //迭代前提数量    for (ik = 0; ik < num; ik++)     //剪枝函数    {      if (message[ik] >= object_range_begin&&message[ik] <= object_range_end)      {        cout << "归并信息:" << fact[message[ik] - 1] << endl;        cout << "推理成功!" << endl<<endl;        system("pause");        exit(0);      }    }    for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配    {      prerequisite_num = 0;      hit_num = 0;      for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数      {        if (rule_prerequisite[ii][ij] == 0)        {          break;        }        prerequisite_num++;      }      for (ij = 0; ij < prerequisite_num; ij++)      {        for (ik = 0; ik < num; ik++)        {          if (rule_prerequisite[ii][ij] == message[ik])          {            hit_num++;          }        }      }      if (hit_num == prerequisite_num)  //满足某个规则集全部前提      {        bool flag;        for (ik = 0; ik < num; ik++)        {          if (message[ik] == rule_result[ii])          {            break;          }        }        if (ik == num)        {          num_c=num - hit_num+1;          flag = true;        }        else        {          num_c = num - hit_num;          flag = false;        }        message_c = new int[num_c];        in = 0;        for (ik = 0; ik < num; ik++)        {          for (im = 0; im < hit_num; im++)          {            if (rule_prerequisite[ii][im] == message[ik])            {              break;            }          }          if (im < hit_num)          {            continue;          }          message_c[in++] = message[ik];        }        if (flag == true)        {          message_c[in] = rule_result[ii];        }        cout << "推导信息:";        for (int iz = 0; iz < num; iz++)        {          cout << fact[message[iz]-1] << " ";        }        cout << endl;        return inference(num_c,message_c);      }    }    cout << "归并信息:";    for (int iz = 0; iz < num; iz++)    {      cout << fact[message[iz]-1] << " ";    }    cout << endl;    backward_reasoning(num,message);    return false;  }     bool backward_reasoning(int num,int message[])   //反向推理{    int ii,ij,ik;    int prerequisite_num = 0;    int hit_num = 0;    int need_rule_number[rule_num];    int hit_rule_number[rule_num];    float hit_rule_rate[rule_num];    float best_hit_rule_rate=0;    int best_hit_rule_number;    int *new_message;    for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配    {      prerequisite_num=0;      hit_num=0;      for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数      {        if (rule_prerequisite[ii][ij] == 0)        {          break;        }        prerequisite_num++;      }      need_rule_number[ii]=prerequisite_num;      for (ij = 0; ij < prerequisite_num; ij++)   //计算输入信息命中规则集中的前提数      {        for (ik = 0; ik < num; ik++)        {          if (rule_prerequisite[ii][ij] == message[ik])          {            hit_num++;          }        }      }      hit_rule_number[ii]=hit_num;      hit_rule_rate[ii]=(float)hit_num/prerequisite_num;  //命中率      for(ij=0;ij      {        if(message[ij]==rule_result[hit_rule_number[ii]])        {          break;        }      }      if(hit_rule_rate[ii]==1&&ij==num)      {        new_message=new int[num+1];        for(ik=0;ik        {          new_message[ik]=message[ik];        }        new_message[num]=rule_result[hit_rule_number[ii]];        num++;        return inference(num,new_message);      }      cout<<"rule "<2)<      <<"命中率:"<endl;    }    best_hit_rule_number=-1;    for(ii=0;ii    {      if(best_hit_rule_rate        rule_result[ii]>=object_middle_begin)      {        best_hit_rule_rate=hit_rule_rate[ii];        best_hit_rule_number=ii;      }    }    if(best_hit_rule_number==-1)    {      cout<<"您输入的信息对本系统无效!按任意键退出..."<<endl<<endl;      system("pause");      exit(0);    }    cout<<endl;    cout<<"best_hit_rule_number="<endl;    cout<<"best_hit_rule_rate="<endl;    cout<<"最佳匹配最终结果="<-1]<<    for(ii=0;ii    {      for(ij=0;ij      {        if(rule_prerequisite[best_hit_rule_number][ii]==message[ij])        {          break;        }      }      if(ij!=num)      {        continue;      }      else      {        if(rule_prerequisite[best_hit_rule_number][ii]        {          cout<<endl<<"请问您持有的信息是否包含\"";          cout<-1];          cout<<"\"?(y or n)"<<endl;          char input;          while(true)          {            cin>>input;            if(input=='n')            {              new_message=new int[num];              for(ik=0;ik              {                new_message[ik]=message[ik];              }              break;            }            else if(input=='y')            {              new_message=new int[num+1];              for(ik=0;ik              {                new_message[ik]=message[ik];              }              new_message[num]=rule_prerequisite[best_hit_rule_number][ii];              num++;              return inference(num,new_message);            }            else            {              cout<<"请重新输入(y or n)!";            }          }        }        else      //询问是否有中间结果rule_prerequisite[best_hit_rule_number][ii]        {            int middle_result=rule_prerequisite[best_hit_rule_number][ii];          for(ii=0;ii          {            if(rule_result[ii]==middle_result)            {              for(ik=0;ik              {                if(rule_prerequisite[ii][ik]>=object_middle_begin-1)                {                  continue;                }                for(ij=0;ij                {                  if(rule_prerequisite[ii][ik]==message[ij])                  {                    break;                  }                }                if(ij!=num)                {                  continue;                }                else                {                  cout<<endl<<"请问您持有的信息是否包含\"";                  cout<-1];                  cout<<"\"?(y or n)"<<endl;                  char input;                  while(true)                  {                    cin>>input;                    if(input=='n')                    {                      break;                    }                    else if(input=='y')                    {                      new_message=new int[num+1];                      for(int iq=0;iq                      {                        new_message[iq]=message[iq];                      }                      new_message[num]=rule_prerequisite[best_hit_rule_number][ii];                      num++;                      return inference(num,new_message);                    }                    else                    {                      cout<<"请重新输入(y or n)!";                    }                  }                }              }            }          }        }      }    }  }     int main(int argc, char **argv){    bool flag;    int num;    int *message;    int ii,ij;    cout<<"《知识库》"<<endl;    for(ii=0;ii    {      cout<      cout<2)<      if(ii%4==0)      {        cout<<endl;      }    }    cout <<endl<<endl<< "请输入初始信息个数:(数字)" << endl;    cin >> num;    message = new int[num];    cout << "请输入已有信息:(不重复的数字,以空格隔开)" << endl;    for (ii = 0; ii < num; ii++)    {      cin >> message[ii];    }    cout << endl << "初始信息:";    for (ij = 0; ij < num; ij++)    {      cout << fact[message[ij]-1] << " ";    }    cout << endl<<endl;    if(!inference(num,message))    {      cout<<"通过您的输入无法得出结果!"<<endl;    }    system("pause");    return 0;  }

                    Python 图形交互与语音播报

运行截图08eee1684f40b68232a83733c4278670.png

052bd50b017a72d73b9e227cb12f4a22.png3bc5600e2ef49bcf82ee5060cd881a20.png6421970cb100a915e5c287a1f19c039d.png

5f9e920aca2bb172cd36b6e19f4aaa47.png=come on=585d1cd8ad794b0cf26e4bda553b3d8d.gif

# __author__:cv调包侠from tkinter.filedialog import *from tkinter import ttkimport tkinterimport tkinter.messageboximport pyttsx3import pyttsx3.driversimport pyttsx3.drivers.sapi5teacher = pyttsx3.init('sapi5')voices = teacher.getProperty('voices')# for i in voices:#     teacher.setProperty('voice', i.id)#     teacher.say('asdjfadf')#     teacher.say('aaaaa')# __author__:cv调包侠import tkinter as tkimport csvmammal1 = ["有奶"]mammal2 = ["有毛发"]Ungulates1 = ["有蹄", "mammal"]Ungulates2 = ["mammal", "嚼反刍动物"]birds1 = ["有羽毛"]birds2 = ["会飞", "下蛋"]Carnivores1 = ["吃肉"]Carnivores2 = ["有犬齿", "有爪", "眼盯前方"]leopard = ["Carnivores", "mammal", "黄褐色", "暗斑点"]tiger = ["Carnivores", "mammal", "黄褐色", "黑色条纹"]ostrich = ["bird", "长脖子", "长腿", "不会飞", "黑白二色"]penguin = ["bird", "会游泳", "不会飞", "黑白二色"]Albatross = ["bird", "会飞"]zebra = ["Ungulates", "黑色条纹"]giraffe = ["长脖子", "长腿", "暗斑点", "Ungulates"]mammal = [mammal1, mammal2]Ungulates = [Ungulates1, Ungulates2]birds = [birds1, birds2]Carnivores = [Carnivores1, Carnivores2]class Surface(ttk.Frame):    pic_path = ""    viewhigh = 600    viewwide = 600    update_time = 0    thread = None    thread_run = False    camera = None    def __init__(self, win):        ttk.Frame.__init__(self, win)        frame_left = ttk.Frame(self)        frame_right1 = ttk.Frame(self)        frame_right2 = ttk.Frame(self)        win.title("动物识别系统")        # win.state("zoomed")   # 全屏        # win.configure(background='pink')   # 去掉注释换颜色        self.pack(fill=tk.BOTH, expand=tk.YES, padx="5", pady="5")        frame_left.pack(side=LEFT, expand=1, fill=BOTH)        frame_right1.pack(side=TOP, expand=1, fill=tk.Y)        frame_right2.pack(side=RIGHT, expand=0, fill='both')        ttk.Label(frame_left, text='').pack(anchor="nw")        ttk.Label(frame_right1, text='').grid(column=0, row=0, sticky=tk.W)        from_world_ctl = ttk.Button(frame_right2, text="输入特征", width=40, command=self.input)        from_pic_ctl = ttk.Button(frame_right2, text="输出特征", width=40, command=self.output)        # from_pic_ctl2 = ttk.Button(frame_right2, text="继续输入", width=40, command=self.output1)        self.text = Entry(win, show=None, width=41, bg='cyan')  # 括号内增加  ,bg ='cyan' 文本框换颜色        self.image_ctl = ttk.Label(frame_left)        self.image_ctl.pack(anchor="nw")        self.roi_ctl = ttk.Label(frame_right1)        self.roi_ctl.grid(column=0, row=1, sticky=tk.W)        ttk.Label(frame_right1, text='识别结果:').grid(column=0, row=2, sticky=tk.W)        self.r_ctl = ttk.Label(frame_right1, text="")        self.r_ctl.grid(column=0, row=3, sticky=tk.W)        self.color_ctl = ttk.Label(frame_right1, text="", width="40")        self.color_ctl.grid(column=0, row=4, sticky=tk.W)        # from_vedio_ctl.pack(anchor="se", pady="5")        # from_pic_ctl3.pack(anchor="se", pady="5")        self.text.pack(anchor="se", pady="5")        # from_vedio_ctl1.pack(anchor="se", pady="5")        # from_vedio_ctl2.pack(anchor="se", pady="5")        from_world_ctl.pack(anchor="se", pady="5")        from_pic_ctl.pack(anchor="se", pady="5")    def from_words(self):        pass    def parse(self):        worlds = self.text.get()        k = 0        if not worlds:            k = 1            tkinter.messagebox.showwarning('警告', '输入为空,请重新输入!')        # worlds = "暗斑点 长脖子 长腿 有奶 有蹄"        features = [i for i in worlds.split(' ')]        print(features)        flag = 0        for mammals in mammal:            i = 0            for feature in features:                if feature in mammals:                    features.append('mammal')                    i = 1                    flag = 1                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:mamals')                    for i in voices:                        teacher.setProperty('voice', i.id)                        teacher.say('识别成功,这个动物属于:mamals(哺乳动物)')                        teacher.runAndWait()                    break            # if i == 1:            #     return        for Ungulate in Ungulates:            i = 0            for feature in features:                if feature in Ungulate:                    features.append('Ungulates')                    if flag == 1:                        break                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:Ungulates(有蹄类动物)')                    for i in voices:                        teacher.setProperty('voice', i.id)                        teacher.say('识别成功,这个动物属于:Ungulates(有蹄类动物)')                        teacher.runAndWait()                    i = 1                    break            if i == 1:                break        for bird in birds:            i = 0            for feature in features:                if feature in bird:                    features.append('bird')                    if flag == 1:                        break                    teacher.say('识别成功,这个动物属于:bird(鸟类动物)')                    teacher.runAndWait()                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:bird(鸟类动物)')                    i = 1                    break            if i == 1:                break        for Carnivores1 in Carnivores:            i = 0            for feature in features:                if feature in Carnivores1:                    features.append('Carnivores')                    if flag == 1:                        break                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:Carnivores')                    teacher.say('识别成功,这个动物属于:Carnivores(食肉动物)')                    teacher.runAndWait()                    i = 1                    break            if i == 1:                break        if k == 1:            return        return self.parse_animal(features)# __author__:cv调包侠    def parse_animal(self, parse):        print(parse)        i = 0        name = ''        for animl in leopard:            if animl not in parse:                i += 1        best = 1 - i / len(leopard)        best_name = 'leopard'        string1 = 'leopard命中率:' + '{}'.format(str(1 - i / len(leopard)))        if i == 0:            name = 'leopard'            print('leopard')            # return name        i = 0        for animl in tiger:            if animl not in parse:                i += 1        string2 = 'tiger命中率:' + '{}'.format(str(1 - i / len(tiger)))        if 1 - i / len(tiger) >best:            best = 1 - i / len(tiger)            best_name = 'tiger'        if i == 0:            name = 'tiger'            print('tiger')            # return name        i = 0        for animl in ostrich:            if animl not in parse:                i += 1        string3 = 'ostrich命中率:' + '{}'.format(str(1 - i / len(ostrich)))        if 1 - i / len(ostrich) >best:            best = 1 - i / len(ostrich)            best_name = 'ostrich'        if i == 0:            name = 'ostrich'            print('ostrich')            # return name        i = 0        for animl in penguin:            if animl not in parse:                i += 1        string4 = 'penguin命中率:' + '{}'.format(str(1 - i / len(penguin)))        if 1 - i / len(penguin) > best:            best = 1 - i / len(penguin)            best_name = 'penguin'        if i == 0:            name = 'penguin'            print('penguin')            # return name        i = 0        for animl in Albatross:            if animl not in parse:                i += 1        string5 = 'Albatross命中率:' + '{}'.format(str(1 - i / len(Albatross)))        if 1 - i / len(Albatross) > best:            best = 1 - i / len(Albatross)            best_name = 'Albatross'        if i == 0:            name = 'Albatross'            print('Albatross')            # return name        i = 0        for animl in zebra:            if animl not in parse:                i += 1        string6 = 'zebra命中率:' + '{}'.format(str(1 - i / len(zebra)))        if 1 - i / len(zebra) > best:            best = 1 - i / len(zebra)            best_name = 'zebra'        if i == 0:            name = 'zebra'            print('zebra')            # return name        i = 0        for animl in giraffe:            if animl not in parse:                i += 1        string7 = 'giraffe命中率:' + '{}'.format(str(1 - i / len(giraffe)))        if 1 - i / len(giraffe) > best:            best = 1 - i / len(giraffe)            best_name = 'giraffe'        if i == 0:            name = 'giraffe'            print('giraffe')            # return name        string = string1 + '\n' + string2 + '\n' + string3 + '\n' + string4 + '\n' + string5 + '\n' + string6 + '\n' + string7        print(string)        if best != 0:            tkinter.messagebox.showinfo('识别结果', '这是动物:{}--->置信度:{}'.format(best_name,best), )            teacher.say('前馈推理识别动物为:{}置信度为:{}'.format(best_name,best))            teacher.runAndWait()        return string    def output(self):        result = self.parse()        if result:            tkinter.messagebox.showinfo('命中率', result,)        # else:        #     tkinter.messagebox.showwarning('识别结果', '识别失败,请重新输入!')    def input(self):        tkinter.messagebox.showinfo('成功', '数据导入成功')        with open('./knowledge.csv', 'r', encoding='utf-8') as f:            reader = csv.reader(f)            for row in reader:                for i in row[0].split(' '):                    if 'mammal' in i:                        mammal1 = row[0].split(' ')[1]                        print('features: ', mammal1)                        return mammal1                    if 'birds' in i:                        birds1 = row[0].split(' ')[1]                        return birds1if __name__ == '__main__':    win = tk.Tk()    surface = Surface(win)    # parse = surface.parse('a')    # print(parse)    # surface.parse_animal(parse)# __author__:cv调包侠    # win.protocol('WM_DELETE_WINDOW', close_window)    win.mainloop()

关注一下~公众号,获取其他源码!!

eb82c0d3739912e26e4641224de94d7d.png

Logo

一站式 AI 云服务平台

更多推荐