動物產生式識別系統


  摘要:構造知識型系統和建立認知模型時常用的知識表示的形式系統。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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM