1、 问题描述及实验要求
动物识别专家系统设计,并编程实现。
//包含事实库和规则库
//查找与规则前提链中前提号相同的事实
//如果事实的断言为真则判断下一个前提,为假,则表示该规则不适合
//事实断言为不知道的时候,向用户询问
规则I1 如果 该动物有毛发,那么 它是哺乳动物
规则I2 如果 该动物能产乳,那么 它是哺乳动物
规则I3 如果 该动物有羽毛,那么 它是鸟类动物
规则I4 如果 该动物能飞行,它能生蛋,那么 它是鸟类动物
规则I5 如果 该动物是哺乳动物,它吃肉,那么 它是食肉动物
规则I6 如果 该动物是哺乳动物,它长有爪子,它长有利齿,它眼睛前视,那么 它是食肉动物
规则I7 如果 该动物是哺乳动物,它长有蹄,那么 它是有蹄动物
规则I8 如果 该动物是哺乳动物,它反刍,那么 它是有蹄动物,并且是偶蹄动物
规则I9 如果 该动物是食肉动物,它的颜色是黄褐色,它有深色的斑点,那么它是猎豹
规则I10 如果 该动物是食肉动物,它的颜色是黄褐色,它有黑色条纹,那么它是老虎
规则I11 如果 该动物是有蹄动物,它有长腿,它有长颈,它的颜色是黄褐色,它有深色的斑点,那么 它是长颈鹿
规则I12 如果 该动物是有蹄动物,它的颜色是白的,它有黑色条纹,那么它是斑马
规则I13 如果 该动物是鸟类,它不会飞,它有长腿,它有长颈,它的颜色是黑、白色相杂,那么 它是鸵鸟
(规则I13的IF部分的条件“它有长腿”和“它有长颈”,也出现在规则I11的IF部分。I11是有蹄动物的,而I13是鸟的分类,无混淆)
规则I14 如果 该动物是鸟类,它不能飞行,它能游水,它的颜色是黑色和白色,那么 它是企鹅
规则I15 如果 该动物是鸟类,它善于飞行,那么 它是海燕
2、 算法描述
构造事实集
对以上的15条规则提取取样,可总结出本次动物识别的特征,如下:
[“有毛发”, “有奶”, “有羽毛”, “会飞”, “会下蛋”, “吃肉”, “有犬齿”, “有爪”, “眼盯前方”, “有蹄”, “嚼反刍”, “黄褐色”, “身上有暗斑点”, “身上有黑色条纹”,“有长脖子”, “有长腿”, “不会飞”, “会游泳”, “有黑白二色”, “善飞”, “哺乳动物”, “鸟”, “食肉动物”, “蹄类动物”, “猎豹”, “老虎”, “长颈鹿”, “斑马”, “鸵鸟”,“企鹅”, “海燕”]
构造规则集
为规则集里面的特征从1开始编号,根据上述的15条规则可构造出规则集:
[2] → [21]
[1] → [21]
[3] → [22]
[4, 5] → [22]
[8, 7, 9] → [23]
[6] → [23]
[21, 10] → [24]
[21, 11] → [24]
[21, 23, 12, 14] → [26]
[21, 23, 12, 13] → [25]
[24, 15, 16, 13] → [27]
[24, 14] → [28]
[22, 17, 16, 15, 19] → [29]
[22, 17, 18, 19] → [30]
[22, 4] → [31]
代码运行介绍
i 首先定义了事实库和规则库,用于匹配查找,定义了全局变量new_answer用来存放输入的所有特征
ii定义几个函数:
1) displayInfor:用来把事实库里面的动物特征打印输出,方便用户选择
2) input1:接收第一次的输入,以逗号为分隔符
3) input2:对于那些有大于1个特征的规则,可以继续输入
4) control:核心函数。识别动物。对每条规则进行判断,如果输入与规则集中的某一条相等的话,那么输出对应的结果。对于那些大于1条特征的规则,用set(A).issubset(set(B)),来判断两个集合的包含关系,如果包含的话,那么继续输入(即input2函数)。最后,如果都不符合,输出‘识别失败’。
iii 运行:先打印显示菜单,然后输入第一次特征集,运行control控制器进行匹配
3、 代码
import sys # 事实库 features = ["", "有毛发", "有奶", "有羽毛", "会飞", "会下蛋", "吃肉", "有犬齿", "有爪", "眼盯前方", "有蹄", "嚼反刍", "黄褐色", "身上有暗斑点", "身上有黑色条纹", "有长脖子", "有长腿", "不会飞", "会游泳", "有黑白二色", "善飞", "哺乳动物", "鸟", "食肉动物", "蹄类动物", "猎豹", "老虎", "长颈鹿", "斑马", "鸵鸟", "企鹅", "海燕"] # 规则库 rule = [[], [2], [1], [3], [4, 5], [8, 7, 9], [6], [21, 10], [21, 11], [21, 23, 12, 14], [21, 23, 12, 13], [24, 15, 16, 13], [24, 14], [22, 17, 16, 15, 19], [22, 17, 18, 19], [22, 4]] new_answer = [] # 显示选项菜单 def displayInfor(): print('以下是一些动物的特征:\n') i = 1 while i < 25: print('%d' % i + '.' + features[i] + ' ', end='') i = i + 1 if i % 6 == 1: print('\n') # 第一次添加 def input1(): answer = input('请选择动物的特征编号,用英文逗号分开,回车结束输入:') try: answer = list(answer.split(',')) new_answer = [int(x) for x in answer] return new_answer except Exception: print('您输入的是数字格式有误') sys.exit() # 继续添加特征 def input2(arr): answer = input('请继续添加动物的特征编号,用英文逗号分开,回车结束输入:') try: answer = list(answer.split(',')) new_answer = [int(x) for x in answer] for val in new_answer: arr.append(val) except Exception: print('您输入的是数字格式有误') sys.exit() # 控制器 def control(): while 1: if new_answer == rule[1]: print(features[21]) break elif new_answer == rule[2]: print(features[21]) break elif new_answer == rule[3]: print(features[22]) break elif set(new_answer).issubset(set(rule[4])): if new_answer == rule[4]: print(features[22]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[5])): if new_answer == rule[4]: print(features[23]) break else: input2(new_answer) elif new_answer == rule[6]: print(features[23]) elif set(new_answer).issubset(set(rule[7])): if new_answer == rule[7]: print(features[24]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[8])): if new_answer == rule[8]: print(features[24]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[9])): if new_answer == rule[9]: print(features[26]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[10])): if new_answer == rule[10]: print(features[25]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[11])): if new_answer == rule[11]: print(features[27]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[12])): if new_answer == rule[12]: print(features[28]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[13])): if new_answer == rule[13]: print(features[29]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[14])): if new_answer == rule[14]: print(features[30]) break else: input2(new_answer) elif set(new_answer).issubset(set(rule[15])): if new_answer == rule[15]: print(features[31]) break else: input2(new_answer) else: print('识别失败!') displayInfor() new_answer = input1() control()
4、 实验结果分析
实验结果截图:
图1-动物识别专家系统