如何解决使用广度优先搜索返回最短路径
graph = {}
graph['you'] = ['alice','bob','claire']
graph['bob'] = ['anuj','peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom','jonny']
graph['anuj'] = []
graph['peggy'] = []
graph['thom'] = []
graph['jonny'] = []
确定我的终端节点的函数:
def person_is_seller(name):
return name[-1] == 'm' # thom is the mango seller
广度优先搜索算法:
from collections import deque
def search(name):
search_queue = deque()
search_queue += graph[name]
searched = set()
while search_queue:
# print(search_queue)
person = search_queue.popleft()
if person not in searched:
# print(f'Searching {person}')
if person_is_seller(person):
return f'{person} is a mango seller'
else:
search_queue += graph[person]
searched.add(person)
return f'None is a mango seller'
search('you')
# 'thom is a mango seller'
我想知道这个算法是否可以返回从you
到thom
的最短路径?
[you,claire,thom] # as this is the shortest path to thom which is my end node
我检查了 this answer,它指出它不会让我找到最短路径,但第二个答案指出可以提供最短路径,我假设不使用 Djikstra's algorithm。所以我有点困惑,我可以以某种方式跟踪前一个节点,如果到达最后一个节点,请提供最后一个代码片段或任何其他格式中的最短路径?
解决方法
您可以将 searched
设为字典而不是集合,然后让每个键的值作为对您来自的节点的反向引用。
当您找到目标时,您可以通过返回这些反向引用来恢复路径,然后返回反向引用。
修改后的代码:
def search(name):
search_queue = deque()
search_queue.append((name,None))
searched = {} # dict instead of set
while search_queue:
# print(search_queue)
person,prev = search_queue.popleft()
if person not in searched:
searched[person] = prev
# print(f'Searching {person}')
if person_is_seller(person):
result = []
while person is not None:
result.append(person)
person = searched[person]
return result[::-1]
else:
search_queue += [(neighbor,person) for neighbor in graph[person]]
return []
现在函数返回一个列表。当找到路径时,它将具有开始和结束节点,因此在这种情况下:
['you','claire','thom']
如果没有找到路径,结果是一个空列表。
,如果每条边的长度相同,您可以使用 BFS 找到最短路径。当不同的边具有不同的权重时,Dykstra 算法是必要的。
纯形式的 Dykstra 算法仅计算最短路径的长度。由于您可能需要最短路径本身,因此您需要将每个访问过的节点与边缘另一端的节点相关联,这通常使用关联数组(Python 中的“字典”)完成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。