产生式动物识别系统设计文档格式.docx
《产生式动物识别系统设计文档格式.docx》由会员分享,可在线阅读,更多相关《产生式动物识别系统设计文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
1、设计思路
根据上课老师的思路,本系统分为三个功能模块,分别是规则库、综合数据库和控制系统。
根据产生式系统的三部分可以搭建动物识别系统。
数据库的设计思想主要分为条件表和规则表。
在推理过程中,当规则表中某条规则的前提可以和综合数据库中的已知事实相匹配时,该规则被激活。
由它推出的结论将被作为新的事实放入数据库,称为后面推理的已知事实。
所以数据库系统结构如下:
图2数据库系统结构
此外,还需要包括连接数据库程序,添加规则和删除规则的规则库代码,整个系统设计跟自己所掌握的编程代码有所区别,所以没有采用老师的设计思路。
2、设计过程
1)建立规则库
为了识别这些动物,可以根据动物识别的特征,建立下述规则的规则库:
R1:
if动物有毛发then动物是哺乳动物
R2:
if动物有奶then动物是哺乳动物
R3:
if动物有羽毛then动物是鸟
R4:
if动物会飞and会生蛋then动物是鸟
R5:
if动物吃肉then动物是食肉动物
R6:
if动物有犀利牙齿and有爪and眼向前方then动物是食肉动物
R7:
if动物是哺乳动物and有蹄then动物是有蹄类动物
R8:
if动物是哺乳动物and反刍then动物是有蹄类动物
R9:
if动物是哺乳动物and是食肉动物and有黄褐色and有暗斑点then动物是豹
R10:
if动物是哺乳动物and是食肉动物and有黄褐色and有黑色条纹then动物是虎
R11:
if动物是有蹄类动物and有长脖子and有长腿and有暗斑点then动物是长颈鹿
R12:
if动物是有蹄类动物and有黑色条纹then动物是斑马
R13:
if动物是鸟and不会飞and有长脖子and有长腿and有黑白二色then动物是鸵鸟
R14:
if动物是鸟and不会飞and会游泳and有黑白二色then动物是企鹅
R15:
if动物是鸟and善飞then动物是信天翁
根据课本中规则库中的15条规则,每一个规则会有一个结论,从而得到结论编号库数组为{30,29,28,27,26,25,24,3,3,13,12,12,11,11,0}。
2)输入数据库
假设数据库中放入一下事实:
有暗斑点,有长脖子,有长腿,有奶,有蹄。
求解目标:
该动物是什么动物?
3)推理过程
(1)先从规则库中取出第一条规则r1,检查其前提是否可与综合数据库中的已知事实相匹配。
r1的前提是“有毛发”,但事实库中无此事实,故匹配失败。
然后取r2,该前提与已知事实“有奶”相匹配,r2被执行,并将其结论“该动物是哺乳动物”作为新的事实加入到综合数据库中。
此时,综合数据库的内容变为:
动物有暗斑,有长脖子,有长腿,有奶,有蹄,是哺乳动物。
(2)再从规则库中取r3,r4,r5,r6进行匹配,均失败。
接着取r7,该前提与已知事实“是哺乳动物”相匹配,r7被执行,并将其结论“该动物是有蹄类动物”作为新的事实加入到综合数据库中。
动物有暗斑,有长脖子,有长腿,有奶,有蹄,是哺乳动物,是有蹄类动物。
(3)此后,r8,r9,r10均匹配失败。
接着取r11,该前提“该动物是有蹄类动物AND有长脖子AND有长腿AND身上有暗斑”与已知事实相匹配,r11被执行,并推出“该动物是长颈鹿”。
由于“长颈鹿”已是目标集合中的一个结论,即已推出最终结果,故问题求解过程结束。
4)问题求解基本过程
(1)初始化综合数据库,即把欲解决问题的已知事实送入综合数据库中;
(2)检查规则库中是否有未使用过的规则,若无转(7);
(3)检查规则库的未使用规则中是否有其前提可与综合数据库中已知事实相匹配的规则,若有,形成当前可用规则集;
否则转(6);
(4)按照冲突消解策略,从当前可用规则集中选择一个规则执行,并对该规则作上标记。
把执行该规则后所得到的结论作为新的事实放入综合数据库;
如果该规则的结论是一些操作,则执行这些操作;
(5)检查综合数据库中是否包含了该问题的解,若已包含,说明解已求出,问题求解过程结束;
否则,转
(2);
(6)当规则库中还有未使用规则,但均不能与综合数据库中的已有事实相匹配时,要求用户进一步提供关于该问题的已知事实,若能提供,则转
(2);
否则,执行下一步;
(7)若知识库中不再有未使用规则,也说明该问题无解,终止问题求解过程。
四、实验结果
本实验基于VS2010进行编程实验,基本程序框架如下图所示
图3实验框架
按照数据库中存入的事实,在本系统中采用正向推理,得出结果,下面是长颈鹿的运行结果:
图4运行结果
五、实验心得
通过此次实验理解了产生式知识表示方法,并体会到产生式表示法的自然性、模块性、有效性和清晰性的优点。
掌握了构建产生式系统的基本过程,并能够利用编程建立一个基于产生式知识表示的简单的智能系统。
附录:
#include<
iostream>
algorithm>
#include"
StdAfx.h"
usingnamespacestd;
char*facts[]={"
"
"
反刍"
"
有蹄"
哺乳类"
眼向前方"
有爪"
犬齿"
吃肉"
下蛋"
能飞"
有羽毛"
蹄类"
食肉类"
鸟类"
有奶"
毛发"
善飞"
黑色白条纹"
游泳"
长腿"
长脖子"
黑条纹"
暗斑点"
黄褐色"
};
char*resultSet[]={"
信天翁"
企鹅"
鸵鸟"
斑马"
长颈鹿"
虎"
豹"
structfactDB{//综合数据库中的已知事实
intcurNum;
intfact[30];
intinitNum;
}factDb;
structRule{//规则结构体
intfactNum;
intfact[5];
boolendResult;
//是否为结果集
intresultID;
//推出的结果ID
boolused;
//已使用过标志
boolpossible;
//是否可能标志,针对-9(不能飞)若Rule中有9,而综合数据库中有-9则该规则标记不可能
intneedFactPos;
//通过事实比较,记录下一个需要的事实位置,方便下次比较开始点后移和首先寻找该位置值是否新增即可
}*rule;
boolfindNeedFact(intfactID,intpos)//寻找needFactPos位置值是否存在于综合事实库中
{
inti=pos;
for(;
i<
factDb.curNum;
i++)
{
if(factID==factDb.fact[i])returntrue;
if(factID<
factDb.fact[i])returnfalse;
}
returnfalse;
}
boolcmpArray(Rule&
r)//两个数组的事实比较
inti,j;
i=r.needFactPos;
j=i;
while(i<
r.factNum)
while(j<
factDb.curNum)
{
if(r.fact[i]==factDb.fact[j])
{
i++;
if(i==r.factNum)returntrue;
}
elseif(r.fact[i]<
factDb.fact[j])
if(r.fact[i]<
0&
&
findNeedFact(-r.fact[i],i))r.possible=false;
//当存在相反情况时,标记不可能
r.needFactPos=i;
returnfalse;
j++;
}
if(i<
r.factNum){r.needFactPos=i;
returnfalse;
returntrue;
intcmpFact(Rule&
r)
if(r.factNum>
factDb.curNum)return0;
//已知事实还没有该规则事实多
if(r.needFactPos)
if(!
findNeedFact(r.fact[r.needFactPos],r.needFactPos))return0;
//需要的值还不存在
elser.needFactPos++;
if(cmpArray(r))
r.used=true;
if(r.endResult)return1;
//得到了最终结果
elsereturn2;
//得到中间结果
}elsereturn0;
intmain()
freopen("
in.txt"
r"
stdin);
intn;
cin>
>
n;
rule=(Rule*)malloc(sizeof(Rule)*n);
for(i=0;
i++)
cin>
rule[i].factNum;
for(j=0;
j<
j++)
cin>
rule[i].fact[j];
sort(rule[i].fact,rule[i].fact+rule[i].factNum);
rule[i].endResult>
rule[i].resultID;
rule[i].used=false;
rule[i].possible=true;
rule[i].needFactPos=0;
factDb.initNum;
factDb.curNum=factDb.initNum;
cout<
<
原始事实综合数据库:
endl;
factDb.fact[i];
cout<
facts[factDb.fact[i]]<
\t"
;
endl<
sort(factDb.fact,factDb.fact+factDb.curNum);
intres;
boolisEnd=false;
while(!
isEnd)
isEnd=true;
for(i=0;
if(rule[i].used||!
rule[i].possible)continue;
res=cmpFact(rule[i]);
if(res==0)continue;
//不匹配
elseif(res==1)//匹配成功,得到最终结果
cout<
得到最终结果:
resultSet[rule[i].resultID]<
return0;
elseif(res==2)//匹配成功,得到中间结果
得到中间结果:
facts[rule[i].resultID]<
\t将其加入到现有的事实数据库中。
。
factDb.fact[factDb.curNum]=rule[i].resultID;
factDb.curNum++;
sort(factDb.fact,factDb.fact+factDb.curNum);
//这里是在有序数组里插入,应使用插入排序为宜
isEnd=false;
现有事实无法推断出结果!
return0;