算法-广度优先遍历-实战-多轮状态

算法-广度优先遍历-实战-多轮状态

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)

  

posted on 2020-10-30 11:46  lexn  阅读(172)  评论(0编辑  收藏  举报

导航