python双向BFS

本文介绍了双向BFS算法,一种同时从起点和终点出发寻找最短路径的方法,通过Python的deque数据结构实现。示例中,对于给定的图结构,从节点A到节点E的最短路径被成功找到。
摘要由CSDN通过智能技术生成

#描述

    双向BFS(Bidirectional Breadth-First Search)是一种在图中寻找最短路径的算法,与传统的单向BFS不同的是,双向BFS从起点和终点同时开始搜索,直到它们的搜索路径相遇为止。是一种比较便捷的搜素方式,可以显著减少搜索空间,提高搜索效率。但是如果两个搜索路径没有相遇,则这样的搜索方式要比传统的BFS的搜索效率减少两倍。

#代码详解

from collections import deque
         deque是python库函数中collections的一个模块。deque是一个双向可操作队列,就是是因为与普通队列相比,他不仅仅只能够实现“先入先出(FIFO)",他也能够实现”后入先出“这一功能。例如:I=deque(),则I.pop()#默认弹出队列后端元素,I.leftpop()可弹出队列最前端top元素。 
def bidirectional_bfs(graph,start,end):
    if start == end:
        return [start]
        定义一个函数bidirectional_bfs,接受三个参数:graph表示图的邻接列表表示法,start表示起始节点,end表示目标节点。如果起始节点和目标节点相同,直接返回包含起始节点的列表作为路径。
    start_queue = deque([(start,[start])])
    end_queue = deque([(end,[end])])
    start_visited = set([start])
    end_visited = set([end])
        初始化起始节点和目标节点的队列、已访问节点集合:start_queue = deque([(start, [start])]): 起始节点队列,元素为起始节点和从起始节点到该节点的路径。
end_queue = deque([(end, [end])]): 目标节点队列,元素为目标节点和从目标节点到该节点的路径。
start_visited = set([start]): 起始节点已访问集合,用于记录已经访问过的节点。
end_visited = set([end]): 目标节点已访问集合,用于记录已经访问过的节点。
 while start_queue and end_queue:
        start_node, start_path = start_queue.popleft()
        end_node, end_path = end_queue.popleft()
        从当起始节点队列和目标节点队列都不为空时,继续搜索,并且弹出起始节点队列(start)和目标节点队列(end)中的第一个节点和路径。
neighbors=graph[start_node]

        for neighbor in neighbors:
            if neighbor not in start_visited:
                new_path=start_path+[neighbor]
                if neighbor in end_visited:
                    return new_path + end_path[::-1]
                start_queue.append((neighbor,new_path))
                start_visited.add(neighbor)

        neighbors=graph[end_node]

        for neighbor in neighbors:
            if neighbor not in end_visited:
                new_path=end_path+[neighbor]
                if neighbor in start_visited:
                    return new_path + start_path[::-1]
                end_queue.append((neighbor,new_path))
                end_visited.add(neighbor)
    return None
        遍历起始节点和目标节点的邻居节点,如果邻居节点未被访问过,更新路径并检查是否相遇,如果邻居节点在目标节点已访问集合中,返回路径连接两个方向的路径,否则将邻居节点加入队列和已访问集合。如果未找到路径,返回None。
        这段代码的主要逻辑是利用双向BFS算法同时从起始节点和目标节点开始搜索,直到两个搜索方向相遇,找到最短路径。您可以根据需要修改图的结构和起始/目标节点,然后调用这个函数来查找最短路径。

#完整代码

from collections import deque
def bidirectional_bfs(graph,start,end):
    if start == end:
        return [start]

    start_queue = deque([(start,[start])])
    end_queue = deque([(end,[end])])
    start_visited = set([start])
    end_visited = set([end])
    while start_queue and end_queue:
        start_node, start_path = start_queue.popleft()
        end_node, end_path = end_queue.popleft()

        neighbors=graph[start_node]

        for neighbor in neighbors:
            if neighbor not in start_visited:
                new_path=start_path+[neighbor]
                if neighbor in end_visited:
                    return new_path + end_path[::-1]
                start_queue.append((neighbor,new_path))
                start_visited.add(neighbor)

        neighbors=graph[end_node]

        for neighbor in neighbors:
            if neighbor not in end_visited:
                new_path=end_path+[neighbor]
                if neighbor in start_visited:
                    return new_path + start_path[::-1]
                end_queue.append((neighbor,new_path))
                end_visited.add(neighbor)
    return None

#执行和结果

graph={
    'A':['B','C'],
    'B':['A','D','E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

        定义一个字典。

结果:

start='A'
end='E'
result=bidirectional_bfs(graph,start,end)
print(result)

 

['E', 'B', 'A']

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晗14

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值