zoukankan      html  css  js  c++  java
  • 动物产生式识别系统

      摘要:构造知识型系统和建立认知模型时常用的知识表示的形式系统。1943年E.波斯特首先将他提出的一种计算形式体系命名为产生式系统。50年代末期,A.纽厄尔和H.A.西蒙在研究人类问题求解的认知模型时也使用了产生式系统这一术语。产生式系统现代已成为研制人工智能系统时采用的最典型的体系结构之一。本文主要论述计算机科学与技术专业大三下专业课《人工智能》第三个实验算法。


    关键字:人工智能,专家系统,产生式系统

    Production system

    Abstract: Constructs the knowledge system and cognitive model often used in the form of knowledge representation system. E. 1943 post first will he come up with a form of computing system named production system. The late 50 s, a. Newell and H.A. Simon in the study of human cognitive model of problem solving when the term is also used by the production system. Production system has become an artificial intelligence system in modern times, with one of the most typical architecture. This paper mainly discusses the computer science and technology under the junior in professional class "artificial intelligence" third experiment algorithm.

    Keywords: Artificial intelligence, expert system, production system

    1,问题重述 

      通过理解并体会知识库与控制系统相互独立的智能产生式系统与一般程序的区别,为以后设计并实现复杂的专家系统奠定基础。

    知识表示为产生式知识表示方法,设计并实现具有15条规则能自动识别7种动物的产生式系统。知识库与控制系统相互独立,系统完成后除了能识别已有的7种动物外,按产生式知识表示方法向知识库中添加、修改新的知识后,系统能在不修改控制系统程序的情况下仍然能正确识别。
     图片


    2,问题分析

    2.1.事实的表示:

    事实可看成是断言一个语言变量的值或是多个语言变量间的关系的陈述句,语言变量的值或语言变量间的关系可以是一个词。不一定是数字。一般使用三元组(对象,属性,值)或(关系,对象1,对象2)来表示事实,其中对象就是语言变量,若考虑不确定性就成了四元组表示(增加可信度)。这种表示的机器内部实现就是一个表

    2.2.规则的表示:

    规则用于表示事物间的因果关系,以if conditionthen action 的单一形式来描述,将规则作为知识的单位。其中的condition 部分称为条件式前件或模式,而action部分称作动作、后件或结论。

    产生式一般形式为:前件     后件。前件和后件也可以是有“与”、“或”、“非”等逻辑运算符的组合的表达式。条件部分常是一些事实的合取或析取,而结论常是某一事实B。如果不考虑不确定性,需另附可信度度量值。

    产生式过则的含义是:如果前件满足,则可得到后件的结论或者执行后件的相应动作,即后件由前件来触发。一个产生式生成的结论可以作为另一个产生式的前提或语言变量使用,进一步可构成产生式系统。

    蕴涵式表示的知识只能是精确的,产生式表示的知识可以是不确定的,原因是蕴涵式是一个逻辑表达式,其逻辑值只有真和假。蕴含式的匹配一定要求是精确的,而产生式的匹配可以是不确定的,原因是产生式的前提条件和结论都可以是不确定的,因此其匹配也可以是不确定的。 

    3,设计文档 

    <知识库>

    <事实>

    <条件>

    1:有毛发     2:产奶         3:有羽毛      4:会飞 

    5:会下蛋     6:吃肉         7:有犬齿      8:有爪

    9:眼盯前方   10:有蹄        11:反刍       12:黄褐色

    13:有斑点    14:有黑色条纹  15:长脖       16:长腿

    17:不会飞    18:会游泳      19:黑白二色   20:善飞

    </条件>

    <中间结论>

    21:哺乳类     22:鸟类     23:食肉类      24:蹄类  

    </中间结论>

    <结论>

    25:金钱豹   26:虎     27:长颈鹿      28:斑马      29:鸵鸟

    30:企鹅     31:信天翁

    </结论>

    </事实>

    <规则>

    有毛->哺乳类

    产奶->哺乳类

    有羽毛->鸟类

    会飞,会下蛋->鸟类

    哺乳类,吃肉->食肉类

    有犬齿,有爪,眼盯前方->食肉类

    哺乳类,有蹄->蹄类

    哺乳类,反刍->蹄类

    食肉类,黄褐色,有斑点->金钱豹

    食肉类,黄褐色,有黑色条纹->虎

    蹄类,长脖,长腿,有斑点->长颈鹿

    蹄类,有黑色条纹->斑马

    鸟类,长脖,长腿,会飞->鸵鸟

    鸟类,会游泳,黑白二色,会飞->企鹅

    鸟类,善飞->信天翁

    </规则>

    </知识库>

    **规则符号化

    1->21                  //有毛->哺乳类

    2->21                  //产奶->哺乳类

    3->22                  //有羽毛->鸟类

    4,5->22                //会飞,会下蛋->鸟类

    21,6->23               //哺乳类,吃肉->食肉类

    7,8,9->23              //有犬齿,有爪,眼盯前方->食肉类

    21,10->24              //哺乳类,有蹄->蹄类

    21,11->24              //哺乳类,反刍->蹄类

    23,12,13->25           //食肉类,黄褐色,有斑点->金钱豹

    23,12,14->26           //食肉类,黄褐色,有黑色条纹->虎

    24,15,16,13->27        //蹄类,长脖,长腿,有斑点->长颈鹿

    24,14->28              //蹄类,有黑色条纹->斑马

    22,15,16,4->29         //鸟类,长脖,长腿,会飞->鸵鸟

    22,18,19,4->30         //鸟类,会游泳,黑白二色,会飞->企鹅

    22,20->31              //鸟类,善飞->信天翁

    **

    **测试用例

    2,10,13,15,16 -> 27

    产奶,有蹄,有斑点,长脖,长腿 -> 长颈鹿

    */

    4,程序设计

    图片


    图片
     

      1 #include<iostream>
      2 #include<string>
      3 #include<cstdlib>
      4 #include<iomanip>
      5 #include<list>
      6 
      7 using namespace std;
      8 
      9 const int fact_num = 31;      //知识库中的知识:31种知识
     10 const int rule_num = 15;      //知识库中的规则:15条规则
     11 const int rule_volume = 4;    //规则中每个结果最多有4个前提条件
     12 const int object_range_begin = 25;  //从第25个知识开始
     13 const int object_range_end = 31;    //到第31个知识为目标结论
     14 const int object_middle_begin = 21;     //中间结果起始位置 
     15 
     16 string fact[fact_num] =               
     17 {
     18     "有毛发","产奶","有羽毛","会飞","会下蛋",
     19     "吃肉","有犬齿","有爪","眼盯前方","有蹄",
     20     "反刍","黄褐色","有斑点","有黑色条纹","长脖",
     21     "长腿","不会飞","会游泳","黑白二色","善飞",
     22     "哺乳类","鸟类","食肉类","蹄类","金钱豹",
     23     "","长颈鹿","斑马","鸵鸟","企鹅","信天翁"
     24 };
     25 
     26 int rule_prerequisite[rule_num][rule_volume] =      
     27 {
     28     {1,0,0,0},
     29     {2,0,0,0},
     30     {3,0,0,0},
     31     {4,5,0,0},
     32     {21,6,0,0},
     33     {7,8,9,0},
     34     {21,10,0,0},
     35     {21,11,0,0},
     36     {23,12,13,0},
     37     {23,12,14,0},
     38     {24,15,16,13},
     39     {24,14,0,0},
     40     {22,15,16,4},
     41     {22,18,19,4},
     42     {22,20,0,0}
     43 };
     44 
     45 int rule_result[rule_num] =
     46 {
     47     21,
     48     21,
     49     22,
     50     22,
     51     23,
     52     23,
     53     24,
     54     24,
     55     25,
     56     26,
     57     27,
     58     28,
     59     29,
     60     30,
     61     31
     62 };
     63 
     64 bool backward_reasoning(int num,int message[]) ;
     65 bool inference(int num,int message[])         //迭代推理机
     66 {
     67     int ii, ij, ik,im,in;
     68     int hit_num = 0;          //输入前提也规则前提重合数
     69     int prerequisite_num;     //规则前提数
     70     int *message_c;           //迭代前提
     71     int num_c;                //迭代前提数量
     72     for (ik = 0; ik < num; ik++)     //剪枝函数
     73     {
     74         if (message[ik] >= object_range_begin&&message[ik] <= object_range_end)
     75         {
     76             cout << "归并信息:" << fact[message[ik] - 1] << endl;
     77             cout << "推理成功!" << endl<<endl;
     78             system("pause");
     79             exit(0);
     80         }
     81     }
     82     for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配
     83     {
     84         prerequisite_num = 0;
     85         hit_num = 0;
     86         for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数
     87         {
     88             if (rule_prerequisite[ii][ij] == 0)
     89             {
     90                 break;
     91             }
     92             prerequisite_num++;
     93         }
     94         for (ij = 0; ij < prerequisite_num; ij++)
     95         {
     96             for (ik = 0; ik < num; ik++)
     97             {
     98                 if (rule_prerequisite[ii][ij] == message[ik])
     99                 {
    100                     hit_num++;
    101                 }
    102             }
    103         }
    104         if (hit_num == prerequisite_num)  //满足某个规则集全部前提
    105         {
    106             bool flag;
    107             for (ik = 0; ik < num; ik++)
    108             {
    109                 if (message[ik] == rule_result[ii])
    110                 {
    111                     break;
    112                 }
    113             }
    114             if (ik == num)
    115             {
    116                 num_c=num - hit_num+1;
    117                 flag = true;
    118             }
    119             else
    120             {
    121                 num_c = num - hit_num;
    122                 flag = false;
    123             }
    124             message_c = new int[num_c];
    125             in = 0;
    126             for (ik = 0; ik < num; ik++)
    127             {
    128                 for (im = 0; im < hit_num; im++)
    129                 {
    130                     if (rule_prerequisite[ii][im] == message[ik])
    131                     {
    132                         break;
    133                     }
    134                 }
    135                 if (im < hit_num)
    136                 {
    137                     continue;
    138                 }
    139                 message_c[in++] = message[ik];
    140             }
    141             if (flag == true)
    142             {
    143                 message_c[in] = rule_result[ii];
    144             }
    145             cout << "推导信息:";
    146             for (int iz = 0; iz < num; iz++)
    147             {
    148                 cout << fact[message[iz]-1] << " ";
    149             }
    150             cout << endl;
    151             return inference(num_c,message_c);
    152         }
    153     }
    154     cout << "归并信息:";
    155     for (int iz = 0; iz < num; iz++)
    156     {
    157         cout << fact[message[iz]-1] << " ";
    158     }
    159     cout << endl;
    160     backward_reasoning(num,message);
    161     return false;
    162 }
    163 
    164 bool backward_reasoning(int num,int message[])   //反向推理
    165 {
    166     int ii,ij,ik;
    167     int prerequisite_num = 0;
    168     int hit_num = 0;
    169     int need_rule_number[rule_num];
    170     int hit_rule_number[rule_num];
    171     float hit_rule_rate[rule_num];
    172     float best_hit_rule_rate=0;
    173     int best_hit_rule_number;
    174     int *new_message;
    175     for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配
    176     {
    177         prerequisite_num=0;
    178         hit_num=0;
    179         for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数
    180         {
    181             if (rule_prerequisite[ii][ij] == 0)
    182             {
    183                 break;
    184             }
    185             prerequisite_num++;
    186         }
    187         need_rule_number[ii]=prerequisite_num;
    188         for (ij = 0; ij < prerequisite_num; ij++)   //计算输入信息命中规则集中的前提数
    189         {
    190             for (ik = 0; ik < num; ik++)
    191             {
    192                 if (rule_prerequisite[ii][ij] == message[ik])
    193                 {
    194                     hit_num++;
    195                 }
    196             }
    197         }
    198         hit_rule_number[ii]=hit_num;
    199         hit_rule_rate[ii]=(float)hit_num/prerequisite_num;  //命中率
    200         for(ij=0;ij<num;ij++)
    201         {
    202             if(message[ij]==rule_result[hit_rule_number[ii]])
    203             {
    204                 break;
    205             }
    206         }
    207         if(hit_rule_rate[ii]==1&&ij==num)
    208         {
    209             new_message=new int[num+1];
    210             for(ik=0;ik<num;ik++)
    211             {
    212                 new_message[ik]=message[ik];
    213             }
    214             new_message[num]=rule_result[hit_rule_number[ii]];
    215             num++;
    216             return inference(num,new_message);
    217         }
    218         cout<<"rule "<<setw(2)<<ii<<" -> "<<setw(8)<<fact[rule_result[ii]-1]
    219         <<"命中率:"<<hit_rule_rate[ii]<<endl;
    220     }
    221     best_hit_rule_number=-1;
    222     for(ii=0;ii<rule_num;ii++)
    223     {
    224         if(best_hit_rule_rate<hit_rule_rate[ii]&&
    225             rule_result[ii]>=object_middle_begin)
    226         {
    227             best_hit_rule_rate=hit_rule_rate[ii];
    228             best_hit_rule_number=ii;
    229         }
    230     }
    231     if(best_hit_rule_number==-1)
    232     {
    233         cout<<"您输入的信息对本系统无效!按任意键退出..."<<endl<<endl;
    234         system("pause");
    235         exit(0);
    236     }
    237     cout<<endl;
    238     cout<<"best_hit_rule_number="<<best_hit_rule_number<<endl;
    239     cout<<"best_hit_rule_rate="<<best_hit_rule_rate<<endl;
    240     cout<<"最佳匹配最终结果="<<fact[rule_result[best_hit_rule_number]-1]<<endl;
    241     for(ii=0;ii<need_rule_number[best_hit_rule_number];ii++)
    242     {
    243         for(ij=0;ij<num;ij++)
    244         {
    245             if(rule_prerequisite[best_hit_rule_number][ii]==message[ij])
    246             {
    247                 break;
    248             }
    249         }
    250         if(ij!=num)
    251         {
    252             continue;
    253         }
    254         else
    255         {
    256             if(rule_prerequisite[best_hit_rule_number][ii]<object_middle_begin)
    257             {
    258                 cout<<endl<<"请问您持有的信息是否包含"";
    259                 cout<<fact[rule_prerequisite[best_hit_rule_number][ii]-1];
    260                 cout<<""?(y or n)"<<endl;
    261                 char input;
    262                 while(true)
    263                 {
    264                     cin>>input;
    265                     if(input=='n')
    266                     {
    267                         new_message=new int[num];
    268                         for(ik=0;ik<num;ik++)
    269                         {
    270                             new_message[ik]=message[ik];
    271                         }
    272                         break;
    273                     }
    274                     else if(input=='y')
    275                     {
    276                         new_message=new int[num+1];
    277                         for(ik=0;ik<num;ik++)
    278                         {
    279                             new_message[ik]=message[ik];
    280                         }
    281                         new_message[num]=rule_prerequisite[best_hit_rule_number][ii];
    282                         num++;
    283                         return inference(num,new_message);
    284                     }
    285                     else
    286                     {
    287                         cout<<"请重新输入(y or n)!";
    288                     }
    289                 }
    290             }
    291             else      //询问是否有中间结果rule_prerequisite[best_hit_rule_number][ii]
    292             {    
    293                 int middle_result=rule_prerequisite[best_hit_rule_number][ii];
    294                 for(ii=0;ii<rule_num;ii++)
    295                 {
    296                     if(rule_result[ii]==middle_result)
    297                     {
    298                         for(ik=0;ik<need_rule_number[ii];ik++)
    299                         {
    300                             if(rule_prerequisite[ii][ik]>=object_middle_begin-1)
    301                             {
    302                                 continue;
    303                             }
    304                             for(ij=0;ij<num;ij++)
    305                             {
    306                                 if(rule_prerequisite[ii][ik]==message[ij])
    307                                 {
    308                                     break;
    309                                 }
    310                             }
    311                             if(ij!=num)
    312                             {
    313                                 continue;
    314                             }
    315                             else
    316                             {
    317                                 cout<<endl<<"请问您持有的信息是否包含"";
    318                                 cout<<fact[rule_prerequisite[ii][ik]-1];
    319                                 cout<<""?(y or n)"<<endl;
    320                                 char input;
    321                                 while(true)
    322                                 {
    323                                     cin>>input;
    324                                     if(input=='n')
    325                                     {
    326                                         break;
    327                                     }
    328                                     else if(input=='y')
    329                                     {
    330                                         new_message=new int[num+1];
    331                                         for(int iq=0;iq<num;iq++)
    332                                         {
    333                                             new_message[iq]=message[iq];
    334                                         }
    335                                         new_message[num]=rule_prerequisite[best_hit_rule_number][ii];
    336                                         num++;
    337                                         return inference(num,new_message);
    338                                     }
    339                                     else
    340                                     {
    341                                         cout<<"请重新输入(y or n)!";
    342                                     }
    343                                 }
    344                             }
    345                         }
    346                     }
    347                 }
    348             }
    349         }
    350     }
    351 }
    352 
    353 int main(int argc, char **argv)
    354 {
    355     bool flag;
    356     int num;
    357     int *message;
    358     int ii,ij;
    359     cout<<"《知识库》"<<endl;
    360     for(ii=0;ii<fact_num;ii++)
    361     {
    362         cout<<setiosflags(ios::left);
    363         cout<<setw(2)<<ii+1<<":"<<setw(10)<<fact[ii]<<"  ";
    364         if(ii%4==0)
    365         {
    366             cout<<endl;
    367         }
    368     }
    369     cout <<endl<<endl<< "请输入初始信息个数:(数字)" << endl;
    370     cin >> num;
    371     message = new int[num];
    372     cout << "请输入已有信息:(不重复的数字,以空格隔开)" << endl;
    373     for (ii = 0; ii < num; ii++)
    374     {
    375         cin >> message[ii];
    376     }
    377     cout << endl << "初始信息:";
    378     for (ij = 0; ij < num; ij++)
    379     {
    380         cout << fact[message[ij]-1] << " ";
    381     }
    382     cout << endl<<endl;
    383     if(!inference(num,message))
    384     {
    385         cout<<"通过您的输入无法得出结果!"<<endl;
    386     }
    387     system("pause");
    388     return 0;
    389 }
  • 相关阅读:
    English trip -- VC(情景课)1 A Get ready
    隔板法总结
    CF 题目选做
    ZROI 提高十连测 DAY2
    2019 09 05
    线性基总结
    解决痛苦的方法/cy
    梅深不见冬 树上贪心
    ZROI 提高十连测 Day1
    [USACO09NOV]硬币的游戏 博弈 dp
  • 原文地址:https://www.cnblogs.com/guanghe/p/5485823.html
Copyright © 2011-2022 走看看