算法-广度优先遍历-实战-多轮状态
算法-广度优先遍历-实战-多轮状态
1 实战-多轮状态
1)多轮对话如 导航->导航->天气
需求:只要知道 哪些领域可以作为起始,
每个领域的下一个领域是什么
结束的领域是什么。 如果没有可以规定轮次
2)多个状态在转移
需求:状态逻辑树,如 订外卖的一个逻辑树
逻辑树转为一个字典,键为状态节点,值[]为列表,列表内记录该节点的子节点
规定好叶子节点
2 代码
基于广度优先遍历
1 def bfs_gen(obj,choice): 2 print("=",obj) 3 return [now+[next] for now in obj for next in choice.get(now[-1],{}) if next] 4 5 6 # [now+[next] for now in objlist for next in choices.get(now[-1],{}) if next] 7 8 9 pic = {"1": ["4", "2"], "2": ["3", "4"], "3": ["6"], "4": ["5"]} 10 #print(dfs_gen([['1', '4', '5'], ['1', '2', '3'], ['1', '2', '4']],pic)) 11 def isnu(tf_): 12 for i in tf_: 13 if i: 14 return False 15 return True 16 17 def np(pic,start,end): 18 col=[] 19 while not isnu(start): 20 start = bfs_gen(start,pic) 21 for i in start: 22 if i[-1] in end: 23 col.append(i) 24 25 return col 26 27 def np_num(pic,start,num=0): 28 c=1 29 while c<num: 30 start=bfs_gen(start,pic) 31 c+=1 32 return start 33 34 35 print("==========",np(pic,[["1",]],["5","6"])) 36 37 print("count===",np_num(pic,[["1",]],num=3))
改进版
方法: 标出 起始点和 终止位置,以及多轮对话次数。
1 def bfs_gen(obj,choice): 2 print("=",obj) 3 return [now+[next] for now in obj for next in choice.get(now[-1],{}) if next] 4 5 6 # [now+[next] for now in objlist for next in choices.get(now[-1],{}) if next] 7 8 9 pic = {"1": ["4", "2"], "2": ["3", "4"], "3": ["6"], "4": ["5"]} 10 pic={"笑话":["再说一个","查询成功","查询失败"],"查询成功":["有输入语音","无输入"],"有输入语音":["导航","再说一个"],"再说一个":["笑话"],"查询失败":["有输入语音","无输入"]} 11 #print(dfs_gen([['1', '4', '5'], ['1', '2', '3'], ['1', '2', '4']],pic)) 12 def isnu(tf_): 13 for i in tf_: 14 if i: 15 return False 16 return True 17 18 def np(pic,start,end): 19 col=[] 20 while not isnu(start): 21 start = bfs_gen(start,pic) 22 print("start=",start) 23 for i in start: 24 if i[-1] in end: 25 col.append(i) 26 27 return col 28 def baohan(one,two): 29 n1=len(one) 30 n2=len(two) 31 32 if n1+1==n2: 33 if one==two[:n1]: 34 return True 35 else: 36 return False 37 else: 38 return False 39 pass 40 41 def baohan_zhi(one,two): 42 pass 43 44 def chaque(old,new): 45 col = [] 46 for n in new: 47 for i in old: 48 if baohan_zhi(i, n): 49 col.append(i) 50 return col 51 52 def chaque_zhi(old,new): 53 col=[] 54 for i in old: 55 if i not in new: 56 col.append(i) 57 return col 58 59 def np_for_case_zhi(pic,start,end,num=0): 60 c=0 61 col=[] 62 while not isnu(start) and c<num: 63 old=start 64 start = bfs_gen(start,pic) 65 xulie = chaque_zhi(old,start) 66 print("xulie=",xulie) 67 col.extend(xulie) 68 #print("start=",start) 69 for i in start: 70 if i[-1] in end: 71 col.append(i) 72 c+=1 73 74 return col 75 76 def np_for_case(pic,start,end,num=0): 77 c=0 78 col=[] 79 while not isnu(start) and c<num: 80 start = bfs_gen(start,pic) 81 #print("start=",start) 82 for i in start: 83 if i[-1] in end: 84 col.append(i) 85 c+=1 86 87 return col 88 89 def np_num(pic,start,num=0): 90 c=1 91 while c<num: 92 start=bfs_gen(start,pic) 93 c+=1 94 return start 95 96 #print("==========",np(pic,[["1",]],["5","6"])) 97 # 可以不用特意标出结尾状态词 98 print("==========",np_for_case_zhi(pic,[["笑话",]],["导航",],num=5)) 99 100 print("==========",np_for_case(pic,[["笑话",]],["导航","无输入"],num=5)) 101 102 #print("count===",np_num(pic,[["1",]],num=5))
精简版 建议采用
优点为:不用标出 结束关键点
使用方法:1 编写好pic
2 在函数入参中写入start起始点
3 写好nums生成对话次数
1 def bfs_gen(obj,choice): 2 return [now+[next] for now in obj for next in choice.get(now[-1],{}) if next] 3 4 5 pic = {"1": ["4", "2"], "2": ["3", "4"], "3": ["6"], "4": ["5"]} 6 pic={"笑话":["再说一个","查询成功","查询失败"],"查询成功":["有输入语音","无输入"],"有输入语音":["导航","再说一个"],"再说一个":["笑话"],"查询失败":["有输入语音","无输入"]} 7 8 def isnu(tf_): 9 for i in tf_: 10 if i: 11 return False 12 return True 13 14 15 def np_for_case(pic,start,end,num=0):
# 有结尾,也可以限制遍历层数 16 c=0 17 col=[] 18 while not isnu(start) and c<num: 19 start = bfs_gen(start,pic) 20 #print("start=",start) 21 for i in start: 22 if i[-1] in end: 23 col.append(i) 24 c+=1 25 26 return col 27 28 def np_for_case_noend(pic,start,num=0):
# 可能是一个环,限制遍历数 29 c=0 30 col=[] 31 while not isnu(start) and c<num: 32 start = bfs_gen(start,pic) 33 #print("start=",start) 34 for i in start: 35 if i[-1] not in pic: 36 col.append(i) 37 c+=1 38 39 return col 40 41 #print("==========",np(pic,[["1",]],end=["5","6"])) 42 43 #print("==========",np_for_case_noend(pic,[["笑话",]],["导航","无输入"],num=5)) 44 45 # 可以不用特意标出结尾状态词 46 print("==========",np_for_case_noend(pic,[["笑话",]],num=5))
-----------------------------------------------------------------------------------
1 遍历代码
# 遍历和记录下来路径是不一样的 def bianli(graph, start, ): # 1 规定队列 # 2 判断队列 # 3 生成节点,处理节点,记录节点 # import pdb; pdb.set_trace() rem=[[],] que = [] que.append(start) while que: n = que.pop(0) nodes = graph.get(n,None) if not nodes: continue for node in nodes: que.append(node) pic = {"1": ["4", "2"], "2": ["3", "4"], "3": ["6"], "4": ["5"]} print("count===",bianli(pic,"1"))
2 搜集到遍历的路径
# 收集走过的路径 def _bfs(graph, start): gather=[] for node in start: for nxt in graph.get(node[-1], {}): # 4 bfs node all add gather.append(node+[nxt]) return gather def jilupath(graph,start): # 1 定义起始路径记忆容器,先以root开始,记:[[root,]] col = [] path_start = [[start,]] while path_start: # 2 next node path_start = _bfs(graph, path_start) for i in path_start: # 3 collection if not graph.get(i[-1], None): col.append(i) return col pic = {"1": ["4", "2"], "2": ["3", "4"], "3": ["6"], "4": ["5"]} print("count===",bianli(pic,"1")) path = jilupath(pic,"1") print(path)