AI Lab1: 产生式动物识别系统

AI Lab1: 产生式动物识别系统

梦猫 Lv2

一、实验要求

产生式识别系统通过一个规则库对特征进行识别,并推断出结果。
系统首先输入读入一些已知特征,随后根据规则库中的规则不断尝试推断出新的特征,直至最终得到结果,或是发现无法推出结果。

rules
rules

实验要求以上图规则库为基础,编写一个产生式动物识别系统。
simple
simple

如上图所示,要求程序首先输出所有可选特征,用户输入已知特征后,程序根据规则库进行推理,输出推理过程及最后的识别结果。

二、算法设计

算法本身很简单,正好最近在学python,试着用python写一写。

Init

我们先把所有特征存在一个数组里,以便后面推理过程的输出。
同时,我们按题目要求输出所有可选特征,并要求用户按序号进行输入。
最后,我们还需要根据特征序号存储所有的推理规则。推理规则都是由若干个特征推出一个新特征,一个键为向量、值为变量的键值对就可以很好的存储。
我们设键向量中的值为推理的前提特征,而值为推理得的新特征,根据实验所给的规则库一一编写即可。

CODE
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
32
feature = [
"空", "有毛发", "产奶", "有羽毛", "会飞", "会下蛋", # 空用于占位
"吃肉", "有犬齿", "有爪", "眼盯前方", "有蹄",
"反刍", "黄褐色", "有斑点", "有黑色条纹", "长脖",
"长腿", "不会飞", "会游泳", "黑白二色", "善飞",
"哺乳类", "鸟类", "食肉类", "蹄类", "金钱豹",
"虎", "长颈鹿", "斑马", "鸵鸟", "企鹅", "信天翁"
]

print("有动物特征如下:")
print("*1:有毛发 2:产奶 3:有羽毛 4:会飞 5:会下蛋")
print("*6:吃肉 7:有犬齿 8:有爪 9:眼盯前方 10:有蹄")
print("*11:反刍 12:黄褐色 13:有斑点 14:有黑色条纹 15:长脖")
print("*16:长腿 17:不会飞 18:会游泳 19:黑白二色 20:善飞")
print("*21:哺乳类 22:鸟类 23:食肉类 24:蹄类")
print("请输入数字选择动物的特征,结尾处用0:")

rules = [0] * 26
# 读入已知规则
while True:
t = int(input())
if t == 0:
break
rules[t] = 1

# 规则库
match = {
(1,): 21, (2,): 21, (3,): 22, (4, 5): 22,
(6,): 23, (6, 7, 8): 23, (21, 9): 24, (21, 11): 24,
(21, 23, 12, 13): 25, (21, 23, 12, 14): 26, (24, 15, 16, 13): 27,
(24, 14): 28, (22, 15, 16, 17, 19): 29, (22, 18, 17, 19): 30, (22, 20): 31
}

Inference

推理过程也很简单,我们只要写一个大循环,不断遍历所有规则,尝试寻找所有前提特征均已知且推出特征未知的规则,并将其推出特征加入已知特征即可。
需要注意,由于可能存在大序号特征推出小序号特征,进而导致出现新的可使用规则的情况,因此需要用while循环不断遍历,直至推得最终动物,或是没有任何一个规则可使用,即推理失败。循环嵌套比较多,也比较复杂,我也懒得对循环做拆分了,多设几个flag即可。
而在推理过程中,每当使用一个能推出新特征的规则,我们就用前面的特征数组输出该规则的前提特征和推出特征,即可实现中间过程的打印。
最终,我们输出系统的识别结果,代码如下。

CODE
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
flag = True
ans = 0
while flag:
check = 1
for v, res in match.items():
m = all(rules[i] == 1 for i in v)
if res < 25 and rules[res]:
m = False
if m:
check = 0
print(feature[v[0]], end="")
for i in range(1, len(v)):
print("+" + feature[v[i]], end="")
print(" ->", feature[res])
if res < 25:
rules[res] = 1
else:
ans = res
flag = False
break
if check:
flag = False

if ans:
print("该动物是:", feature[ans])
else:
print("无法推理出该动物是什么")

三、程序测试

随便测了两个,一个推出企鹅,一个推不出来。

test1
test1

test2
test2

四、实验总结

很简单,没啥总结的。
python语法真怪。

五、源码

最后放一下全部代码。

CODE
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
feature = [
"空", "有毛发", "产奶", "有羽毛", "会飞", "会下蛋", # 空用于占位
"吃肉", "有犬齿", "有爪", "眼盯前方", "有蹄",
"反刍", "黄褐色", "有斑点", "有黑色条纹", "长脖",
"长腿", "不会飞", "会游泳", "黑白二色", "善飞",
"哺乳类", "鸟类", "食肉类", "蹄类", "金钱豹",
"虎", "长颈鹿", "斑马", "鸵鸟", "企鹅", "信天翁"
]

print("有动物特征如下:")
print("*1:有毛发 2:产奶 3:有羽毛 4:会飞 5:会下蛋")
print("*6:吃肉 7:有犬齿 8:有爪 9:眼盯前方 10:有蹄")
print("*11:反刍 12:黄褐色 13:有斑点 14:有黑色条纹 15:长脖")
print("*16:长腿 17:不会飞 18:会游泳 19:黑白二色 20:善飞")
print("*21:哺乳类 22:鸟类 23:食肉类 24:蹄类")
print("请输入数字选择动物的特征,结尾处用0:")

rules = [0] * 26
# 读入已知规则
while True:
t = int(input())
if t == 0:
break
rules[t] = 1

# 规则库
match = {
(1,): 21, (2,): 21, (3,): 22, (4, 5): 22,
(6,): 23, (6, 7, 8): 23, (21, 9): 24, (21, 11): 24,
(21, 23, 12, 13): 25, (21, 23, 12, 14): 26, (24, 15, 16, 13): 27,
(24, 14): 28, (22, 15, 16, 17, 19): 29, (22, 18, 17, 19): 30, (22, 20): 31
}

flag = True
ans = 0
while flag:
check = 1
for v, res in match.items():
m = all(rules[i] == 1 for i in v)
if res < 25 and rules[res]:
m = False
if m:
check = 0
print(feature[v[0]], end="")
for i in range(1, len(v)):
print("+" + feature[v[i]], end="")
print(" ->", feature[res])
if res < 25:
rules[res] = 1
else:
ans = res
flag = False
break
if check:
flag = False

if ans:
print("该动物是:", feature[ans])
else:
print("无法推理出该动物是什么")
  • Title: AI Lab1: 产生式动物识别系统
  • Author: 梦猫
  • Created at : 2024-05-08 14:03:20
  • Updated at : 2024-05-24 13:35:57
  • Link: https://mengmaor.github.io/2024/05/08/产生式动物识别系统/
  • License: All Rights Reserved © 梦猫