在本系统当中,知识库中的知识用产生式规则来表示,共有如下15条规则。
R1 IF该动物有奶THEN该动物是哺乳动物
R2 IF该动物有毛发THEN该动物是哺乳动物
R3 IF该动物有羽毛THEN该动物是鸟
R4 IF该动物会飞AND会下蛋THEN该动物是鸟
R5 IF该动物有爪AND有犬齿AND眼盯前方THEN该动物是食肉动物
R6 IF该动物吃肉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该动物是信天翁
原文链接:https://blog.csdn.net/zzzzlei123123123/article/details/82976783
有所更新增加了一些功能,且认定中间结论不输出,只输出最终结论
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int RULENUM=15;//动物识别系统的规则库有条规则
int CAUSENUM=5;//各条规则中的前提条件最多有个
int count = 0;//记录所选择的动物特征的个数
/*事实*/
int factIndex[2]={24,31};//第一个放条件知识最后一个位置的下标,第二个放结论知识最后一个下标
string fact[100] ={ "", "有毛发", "有奶", "有羽毛", "会飞", "会下蛋", "吃肉", "有犬齿", "有爪","眼盯前方", "有蹄", "嚼反刍", "黄褐色", "身上有暗斑点", "身上有黑色条纹", "有长脖子","有长腿", "不会飞", "会游泳", "有黑白二色", "善飞", "哺乳动物", "鸟", "食肉动物", "蹄类动物", "金钱豹", "虎", "长颈鹿", "斑马", "鸵鸟", "企鹅", "信天翁" };
/*规则*/
int ruleIndex[2]={8,15};//第一个放一级规则最后一个位置的下标,第二个放第能推出结论的
int rule[100][6]={{ 0, 0, 0, 0, 0, 0 },{21, 1, 0, 0, 0, 0 },{ 21, 2, 0, 0, 0, 0 }, { 22, 3, 0, 0, 0, 0 }, {22, 4, 5, 0, 0, 0 },{ 23, 6, 0, 0, 0, 0 }, { 23, 7, 8, 9, 0, 0 }, { 24, 21, 10, 0, 0, 0 }, { 24, 21, 11, 0, 0, 0 }, { 25, 21, 23, 12, 13, 0 }, { 26, 21, 23, 12, 14, 0 }, { 27, 24, 15, 16, 13, 0 }, { 28, 24, 14, 0, 0, 0 }, { 29, 22, 15, 16, 17, 19 }, { 30, 22, 18, 17, 19, 0 }, { 31, 22, 20, 0, 0, 0 } };int conditionlist[100];//所选择的动物特征void checkrules(); //A查看规则库bool match(int a); //匹配函数
int inference(); //推理函数
void recognition(); //B动物识别 void addrule(); //C增加一条规则void addfact(); //D增加一个知识void delrule(); //E删除一个规则 void changerule(); //F修改一个规则
int main()
{ char option='A';//A.查看规则库 B.进行动物识别 while(1){cout<<"================================="<<endl;cout<<"请选择你要进行的操作"<<endl;cout<<"A.查看规则库"<<endl;cout<<"B.进行动物识别"<<endl;cout<<"C.增加规则库"<<endl;cout<<"D.增加知识库"<<endl;cout<<"E.删除规则库里的一条规则"<<endl; cout<<"F.修改规则库里的一条规则"<<endl;cout<<"G.结束系统"<<endl; cout<<"================================="<<endl;cin>>option; if(option=='A'||option=='a'){checkrules();}if(option=='B'||option=='b'){recognition(); }if(option=='C'||option=='c'){addrule(); }if(option=='D'||option=='d'){addfact(); }if(option=='E'||option=='e'){delrule(); }if(option=='F'||option=='f'){changerule(); }if(option=='G'||option=='g'){cout<<"成功退出系统,欢迎下次使用"<<endl;return 0; }}
return 0;
}//A.查看规则库
void checkrules()
{for(int i=1;i<=RULENUM;i++){if(rule[i][4]!=0){cout<<i<<'.'<<"IF"<<rule[i][4]<<fact[rule[i][4]];for(int j=3;j>0;j--)if(rule[i][j]!=0)cout<<"And"<<rule[i][j]<<fact[rule[i][j]];cout<<"THEN"<<rule[i][0]<<fact[rule[i][0]]<<endl;}else{cout<<i<<'.'<<"IF";for(int j=3;j>1;j--)if(rule[i][j]!=0)cout<<rule[i][j]<<fact[rule[i][j]]<<"And";cout<<rule[i][1]<<fact[rule[i][1]]<<"THEN"<<rule[i][0]<<fact[rule[i][0]]<<endl;}}
}
//======================================================================================================
//B动物识别
/*知识匹配*/
bool match(int a)//判断第a条规则是否满足所有条件
{int i;//用于综合数据库 int j;//规则数据库int matchnum=0;//综合数据库与一条规则匹配的条件数 int rulenum=0;//一条规则里的条件; for(i=0;i<=count;i++){rulenum=0; for(int k=1;k<6;k++)//一条规则至多5个条件 {if(rule[a][k]==0){break;} if(conditionlist[i]==rule[a][k]){matchnum++;break;}rulenum++; } }if(rulenum==matchnum) //条件数与匹配数相等时返回true return true;else return false;}
/*推理*/
int inference()
{int i;bool flag=1;for (i=1; i<=RULENUM;i++){flag=1; for(int j=0;j<count;j++)//防止录入重复条件 {if(conditionlist[j]==rule[i][0]){flag=0;}}if (match(i)==true&&flag==1)//匹配则在综合数据库内增加条件 {count++;conditionlist[count-1]=rule[i][0];for(i=0;i<count;i++)cout<<fact[conditionlist[i]]<<' ';cout<<endl; }for(int j=0;j<count;j++){if(conditionlist[j]>factIndex[0])//最后的输出需要满足结论知识才能输出 { cout<<"该动物名称为:"<<endl;cout<<fact[conditionlist[j]]<<endl; return 0;}}}for(i=0;i<count;i++)cout<<fact[conditionlist[i]]<<' ';cout<<"条件不足,请重新输入"<<endl;return 0;}
void recognition(){cout<<"以下是一些动物的特征:"<<endl;for (int i=1;i<=factIndex[0];i++){cout<<i<<".";cout<<setiosflags(ios::left)<<setw(14)<<fact[i]<<" ";if (i%4==0){cout<<endl;}}int a;int k=0;cout<<"请选择动物的特征:(输入0停止)"<<endl;while((cin>>a)) //a为整形的,按任意字母可结束循环{conditionlist[k]=a; k++;count++;if(a==0)break; } inference();
}
//==========================================================================================
//C增加规则库
void addrule(){RULENUM++;int n;cout<<"请输入结论编号"<<endl;cin>>rule[RULENUM][0];cout<<"请输入该规则所需的条件数(最多5条)"<<endl;cin>>n;for(int i=1;i<=n;i++){cout<<"请输入第"<<i<<"个条件的编号"<<endl; cin>>rule[RULENUM][i];}
}
//=============================================================================================
//D增加知识库
void addfact(){int select;cout<<"请选择增加的知识类型"<<endl;cout<<"1.条件类型知识 如:有毛,哺乳动物等"<<endl;cout<<"2.结论类型知识 如:金钱豹,虎等"<<endl;cin>>select;if(select==1) {factIndex[0]++;//条件类型知识最后一个坐标+1 factIndex[1]++;//结论类型知识最后一个坐标+1 for(int i=factIndex[1];i>=factIndex[0];i--){fact[i]=fact[i-1];}cout<<"请输入所添加的知识"<<endl;cin>>fact[factIndex[0]];}if(select==2) {factIndex[1]++;//结论类型知识最后一个坐标+1 cout<<"请输入所添加的知识"<<endl;cin>>fact[factIndex[1]];}cout<<"知识库更新为"<<endl;for(int i=1;i<=factIndex[1];i++){cout<<i<<fact[i]<<' ';} cout<<endl;
}
//============================================================================================
//E删除一条规则
void delrule(){int index;cout<<"请输入你想删除的规则的序号"<<endl;checkrules();cin>>index; if(0<index&&index<=ruleIndex[0])//删除了条件规则 {for(int i=index;i<=RULENUM;i++){for(int j=0;j<=5;j++){rule[i][j]=rule[i+1][j];}}RULENUM--;ruleIndex[0]--;//条件类型知识最后一个坐标-1 ruleIndex[1]--;//结论类型知识最后一个坐标+1 cout<<"规则库变为"<<endl;checkrules(); }else if(index>ruleIndex[0]&&index<=ruleIndex[1]){for(int i=index;i<=RULENUM;i++){for(int j=0;j<=5;j++){rule[i][j]=rule[i+1][j];}}RULENUM--;ruleIndex[1]--;//结论类型知识最后一个坐标-1 cout<<"规则库变为"<<endl;checkrules(); }else{cout<<"输入的序号不存在"<<endl;}
}//===========================================================================================
//F修改一条规则
void changerule(){int index;cout<<"请输入你想修改的规则序号"<<endl;checkrules();cin>>index;cout<<"以下是一些动物的特征:"<<endl;for (int i=1;i<=factIndex[0];i++){cout<<i<<".";cout<<setiosflags(ios::left)<<setw(14)<<fact[i]<<" ";if (i%4==0){cout<<endl;}}cout<<"要输入5个条件编号,不足5条补0(1-"<<factIndex[0]<<"),不修改的条件请按原条件输入"<<endl;for(int i=1;i<=5;i++) {cin>>rule[index][i];}cout<<"规则库变为"<<endl;checkrules();
}