建造用以识别虎、金钱豹、斑马、长颈鹿、企鹅、鸵鸟和信天翁 7 种动物的产生式实验系统(包括规则库和事实库),然后实现推理过程。即,实现可以输入任何的事实,并基于原有的规则和输入的事实进行推理。
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 该动物是信天翁
提示,识别动物的基本思路:首先根据简单的条件对动物进行初次的分类划分,然后根据题中逐渐增加的细化条件,缩小分类范围,最后得出识别以上 7种动物的规则结果。
需要注意的是,
(1) 当已知的事实不完全时,虽不能推出最终结论,但可以得到分类结果;
(2) 当需要增加对其它动物的识别时,规则中只需增加关于这些动物的识别规则,可以充分利用前导规则;
1.用C++模板库的容器构造特征表,用数字表示动物特征和动物类别:
2.构建规则库:
3.实现原理
用C++STL库的set_difference()函数求规则库与输入数据的差集放入tmp_sec的vector容器中,如果该容器的大小为0,说明输入数据中的某一/某些特征符合规则库中的规则,可以继续推理下去,如果该容器的大小不为0,说明输入数据中的某一/某些特征只是规则库中的某一/某些规则的一部分条件,不能进行推理;
主要过程:
map<vector<int>, int>::iterator vec_iter;
vector<int> tmp_sec;
vec_iter = classific.begin();
i = 0;
while (vec_iter != classific.end()) {
i++;
set_difference(vec_iter->first.begin(), vec_iter->first.end(), fact.begin(), fact.end(), inserter(tmp_sec, tmp_sec.begin()));
if (tmp_sec.size() == 0) {
//得到结果
result.push_back(vec_iter->second);
}
tmp_sec.clear();
vec_iter++;
}
#include
#include
#include
#include
using namespace std;
//映射特征表
map<int, string> tables =
{
{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,"金钱豹"}
};
//推理表(规则库)
map<vector<int>, int> classific =
{
{{1},21}, //1
{{2},21},
{{3},22},
{{4,5},22},
{{6},23}, //5
{{7,8,9},23},
{{10,21},24},
{{11,21},24},
{{12,13,21,23},31},
{{12,14,24,26},30}, //10
{{13,15,16,24},29},
{{14,24},28},
{{15,16,17,19,22},27},
{{20,22},26},
{{17,18,19,22},25}//15
};
bool have_result = false;
int main()
{
int i, j, a, b, c;
int num;
vector<int> fact, temp, result;
vector<int>::iterator p;
int flag = 1;
cout << "欢迎来到产生式系统:" << endl;
//打印选项单
map<int, string>::iterator iter;
iter = tables.begin();
while (iter->first <= 24) {
cout << iter->first << "." << iter->second << "\t";
if (iter->first % 5 == 0)
cout << endl;
iter++;
}
cout << endl;
while (flag == 1) {
//输入信息
cout << "请输入特征数:" << endl;
cin >> num;
cout << "请输入特征:" << endl;
for (i = 0; i < num; i++) {
cin >> a;
fact.push_back(a);
}
sort(fact.begin(), fact.end());
//实现推理过程
map<vector<int>, int>::iterator vec_iter;
vector<int> tmp_sec;
vec_iter = classific.begin();
i = 0;
while (vec_iter != classific.end()) {
i++;
set_difference(vec_iter->first.begin(), vec_iter->first.end(), fact.begin(), fact.end(), inserter(tmp_sec, tmp_sec.begin()));
if (tmp_sec.size() == 0) {
//得到结果
result.push_back(vec_iter->second);
}
tmp_sec.clear();
vec_iter++;
}
//判断是否得出结论
p = result.begin();
if (result.begin() == result.end())
{
cout << "不能推导出!" << endl;
}
else
{
while (p != result.end())
{
if (*p < 21)//特征
{
cout << "不能推导出!" << endl;
break;
}
else
{
cout << "该动物可能是" << tables[*p] << endl;
}
p++;
}
}
fact.clear();
result.clear();
cout << "请选择:1.继续 0.退出" << endl;
cin >> flag;
}
return 0;
}
1.完全符合规则库的某一规则:
2.部分符合规则库的某一/某些规则:
3. 都不符合规则库的某一/某些规则
4.超出范围:
文章参考自:c++实现简单的产生式推理系统