赞
踩
人工智能王浩算法python实现(附算法设计图)
实验课作业,没什么实际价值,不过还挺难的,copy一下应付作业没问题。
原作者: 王浩算法—DMU.
他的版本写的比较晦涩,我改了很多,加入了与、或、等价的处理方法,效率提高不少,当然也容易理解了,顺便把算法设计图写出来了。
一、算法设计图:
二、完整代码
验证案例:
s = ‘=> a -> ( b -> a )’
s = “=> ( a -> b ) -> ( ( ! b ) -> ( ! a ) )”
s = ‘=> ( a -> b ) -> ( ( a -> c ) -> ( a -> ( b & c ) ) )’
s = ‘=> ( a -> c ) -> ( ( b -> c ) -> ( ( a | b ) -> c ) )’
#s = ‘=> ( a <-> b ) -> ( a -> b )’
注:实验环境python3.8,pycharm
直接跑就行,在main函数那里可以改问题输入
import copy # 列表转字符串 def listtostr(m): s = '' for i in m: s = s + i + ' ' return s # 识别最外层括号,括号位置索引 def braces(m): o = [] p = [] bralist = [] for i in range(len(m)): if m[i] == '(': o.append(-1) p.append(i) # print('i',i,m[i]) elif m[i] == ')': o.append(1) p.append(i) # print('i',i,m[i]) else: continue t = sum(o) if t == 0: bralist.append([p[0], p[-1]]) o = [] p = [] # print('最外层括号:',bralist) return bralist # 识别最外层逗号(相继式符号),返回最外层逗号的位置列表 def comma(m): comlist = [-1] # 为字符串开头加一标志位 for i in range(len(m)): if m[i] == ',' or m[i] == '=>': # 逗号和相继式符号位置添加到逗号列表 comlist.append(i) return comlist # 识别符号!和-> def detect(dm): dmkuo = braces(dm) if dm[0] == '!': return 1 elif dm[1] == '->': return 2 elif dm[1] == '&': return 3 elif dm[1] == '|': return 4 elif dm[1] == '<->': return 5 elif dmkuo!=[]: if dm[dmkuo[0][-1] + 1] == '->': return 2 elif dm[dmkuo[0][-1] + 1] == '&': return 3 elif dm[dmkuo[0][-1] + 1] == '|': return 4 elif dm[dmkuo[0][-1] + 1] == '<->': return 5 #找出需要处理的字段 def find_(m, comlist): # print('find开始:-----------') t = m.index('=>') if comlist[1] - 1 == comlist[0]:#删除在开头的=> comlist.pop(0) k = 0 for i in comlist: if i + 2 == len(m) or m[i + 2] == ',' or m[i + 2] == '=>':#长度小于2的单一字段不需要处理 # print('单一元素位置:\n',m[i+1:i+2],i+1) k = k + 1 continue if comlist[k] == comlist[-1]:#仅剩一个逗号的情况,处理后半段 last = len(m) else: last = comlist[k + 1] dm = m[i + 1:last] print('要处理的子段是:', listtostr(dm)) dou = last j = detect(dm) if j == 1: if i < t: return nonleft(dm, m, dou - 1, i) elif i >= t: return nonright(dm, m, dou - 1, i) break elif j == 2: if i < t: return yunleft(dm, m, dou , i) elif i >= t: return yunright(dm, m, dou , i) break elif j == 3: return hequ(dm , m , dou , i) elif j == 4: return xiqu(dm , m , dou , i) elif j == 5: return dengjia(dm , m , dou , i) k = k + 1 # 处理多余逗号 def dd(m): for i in range(len(m)): if i == len(m) - 1: if m[i] == ',': m.pop() break elif m[i] == ',' and m[i + 1] == ',': m.pop(i) elif m[i] == ',' and m[i + 1] == '=>': m.pop(i) elif m[i] == '=>' and m[i + 1] == ',': m.pop(i+1) return m #i:开始位置 dou:结束位置 ss:要处理的字段 # 按照四种情况处理 M 列表 # 若 a ,!X,b => r 则 a, b =>X,r def nonleft(ss, m, dou, i): ss.pop(0)#删除非 kuoss = braces(ss) if kuoss != []:#删除括号 ss.pop(0) ss.pop(-1) for x in range(dou, i, -1):#删除非字段 m.pop(x) m = dd(m)#删除多余逗号 t = m.index('=>') ss.append(",") ss.insert(0,"=>") m[t:t+1]=ss # print('\n"!"在"=>"左边\n', '-------m-------\n',listtostr(m)) return [[m, '规则1', ' ', [0]]] # 若 a ,b =>!X, r 则 a, X =>b , r def nonright(ss, m, dou, i): ss.pop(0)#删除非 kuoss = braces(ss) if kuoss != []:#删除括号 ss.pop(0) ss.pop(-1) for x in range(dou, i, -1):#删除非字段 m.pop(x) m = dd(m)#删除多余逗号 t = m.index('=>') if t==0: ss.append("=>") m[t:t+1]=ss else: ss.insert(0, ",") ss.append("=>") m[t:t+1]=ss # print('\n"!"在"=>"右边\n','-------m-------\n',listtostr(m)) return [[m, '规则2', ' ', [0]]] #找出最外层需要处理的->位置 def yunhan(ss): dmkuo = braces(ss) if ss[1] == '->': return 1 else: return dmkuo[0][-1] + 1 # 若 a ,(X -> Y),b => r 则 a ,!X,b => r ; a ,Y,b => r def yunleft(ss, m, dou, i): yun = yunhan(ss) ssx = ss[:yun] ssy = ss[yun + 1:] kuossy = braces(ssy) if kuossy != []: ssy.pop(0) ssy.pop(-1) ssx.insert(0, '!') #m = deal(dou, i) m1 = copy.deepcopy(m) m2 = copy.deepcopy(m) if i==0: i=i-1 m1[i+1:dou]=ssx m2[i+1:dou]=ssy # print('\n"->"在"=>"左边\n',\ # '--------m1-------\n',listtostr(m1),\ # '\n--------m2-------\n',listtostr(m2)) # return listtostr(m1),listtostr(m2) return [[m1, '规则3', ' ', [0]], [m2, '规则3', ' ', [0]]] # 若 a => b, (X -> Y), r 则 a => b, !X , Y , r def yunright(ss, m, dou, i): yun = yunhan(ss)#找出最外层—>位置 ssx = ss[:yun] ssy = ss[yun + 1:] kuossy = braces(ssy) if kuossy != []: ssy.pop(0) ssy.pop(-1) ssx.insert(0, '!') ssxy = ssx + [','] + ssy m[i+1:dou]=ssxy # print('\n"->"在"=>"右边\n','-------m-------\n',listtostr(m)) return [[m, '规则4', ' ', [0]]] #对等价,合取,等价进行转换 #p&q to !(p->!q) p|q to !p->q p<->q to !((p->q)->(!(q->p))) def exchange(m): if '&' in m: t=m.index("&") p=m[0:t] q=m[t+1:len(m)] return ["!","("]+p+["->"]+q+[")"] elif '|' in m: t = m.index("|") p = m[0:t] q = m[t + 1:len(m)] return ["!"] + p + ["->"] + q elif '<->' in m: t = m.index("<->") p = m[0:t] q = m[t + 1:len(m)] return ["!","(","("] + p + ["->"] + q+[")","->","(","!","("]+ p + ["->"] + q+[")",")",")"] def hequ(ss, m, dou, i): ss=exchange(ss) m[i + 1:dou]=ss return [[m, '合取符号转换', ' ', [0]]] def xiqu(ss, m, dou, i): ss = exchange(ss) m[i + 1:dou] = ss return [[m, '析取符号转换', ' ', [0]]] def dengjia(ss, m, dou, i): ss = exchange(ss) m[i + 1:dou] = ss return [[m, '等价符号转换', ' ', [0]]] if __name__=='__main__': s = '=> a -> ( b -> a )' s = "=> ( a -> b ) -> ( ( ! b ) -> ( ! a ) )" s = '=> ( a -> b ) -> ( ( a -> c ) -> ( a -> ( b & c ) ) )' s = '=> ( a -> c ) -> ( ( b -> c ) -> ( ( a | b ) -> c ) )' #s = '=> ( a <-> b ) -> ( a -> b )' # s = input('请输入要推理的字符串(字符之间用空格做间隔):\n') # s = '=>'+' '+s m = s.split() e = 0 stock = [] stock.append([m, '结果', ' ', [0]]) stock1 = [] # print('first stock',stock) while (stock): e = e + 1 y = 0 print('\t\t*****', e, '*****') mm = stock.pop() # print("输出",mm) m = mm[0] if '->' not in m and '!' not in m and '|' not in m and '&' not in m and '<->' not in m : d = m.index('=>') m1 = m[:d] m2 = m[d + 1:] for i in m1: # 有相同元素,是公理 if i != ',': if i in m2: print(listtostr(m), '公理', '\n -------END------') stock1.append([listtostr(m), mm[1], '公理', mm[3]]) break else: y = y + 1 for i in m1: if i == ',': m1.remove(i) if y == len(m1): print(listtostr(m), '不是公理', '\n -------END------') stock1.append([listtostr(m), mm[1], '不是公理', mm[3]]) break continue stock1.append([listtostr(m), mm[1], mm[2], mm[3]]) print('要处理的字符串:', listtostr(m)) comlist = comma(m) f = find_(m, comlist) print('处理后的结果:') for i in range(len(f)): # 规则三返回两个结果 f[i][3] = [mm[3][0] + i] # f[i][3].append(mm[3][i]+i) print(listtostr(f[i][0]), f[i][1], '\n -------END------', ) stock.append(f[i]) for i in stock1: if i[2] == '不是公理': print("推理失败!!!\t" + i[0] + i[2]) exit() # 获取规则三的来源 ''' for i in stock1: print(i) ''' k = [] for i in range(len(stock1)): k.append([len(stock1) - i, stock1[i][3][0]]) rule3 = [] for x in range(len(k) - 1): if k[x][1] == k[x + 1][1] - 1: for i in range(x + 1, len(k)): if k[i][1] == k[x][1]: index = i rule3.append([k[x][0], k[index][0], k[x + 1][0]]) break for i in k: print(i) #print(rule3) stock1.reverse() print("__________") for x in stock1: print(x) p = [] for i in range(len(stock1)): flag = 1 for x in rule3: if i + 1 == x[0]: p.append([stock1[i][0], "由[" + str(x[1]) + "]、[" + str(x[2]) + "]和" + stock1[i - 1][1]]) flag = 0 if flag == 1: if stock1[i][2] == '公理': p.append([stock1[i][0], "公理"]) else: p.append([stock1[i][0], "由[" + str(i) + "]和" + stock1[i - 1][1]]) print("推理过程:") print("_" * 100) for i in range(len(p)): print("[" + str(i + 1) + "]", "{:<60}".format(p[i][0]), "\t\t", p[i][1]) print("推理结束")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。