Python程序:查找到达目标的最短路径
在各种实际问题中,最短路径问题是一个经典的算法问题。例如:导航系统需要计算两点之间的最短路程,电路板设计中需要计算电路板中的最短路径等等。Python可以用多种方法来解决这个问题,包括深度优先搜索,广度优先搜索,狄克斯特拉算法等等。本文将介绍广度优先搜索算法的实现。
广度优先搜索(BFS)算法
广度优先搜索算法先遍历起点所有可以到达的节点,再遍历节点的邻居,以此类推。每次遍历时都是遍历当前已经到达的节点的“一度关系”,这种算法可以找到起点所有到达目标点的“最短路径”,实现步骤如下:
- 创建一个队列,用于存储需要遍历的节点,首先将起点加入队列。同时用一个visit列表来记录已经遍历过的节点;
- 当队列不为空时,取出队列的第一个节点,判断是否是目标节点。如果是,返回结果。否则,将该节点标记为已访问;
- 遍历该节点的邻居节点,如果邻居节点没有被访问过,并且该节点可以直接到达邻居节点,则将邻居节点加入队列中;
- 重复2-3步骤,直到队列为空。
下面是Python实现广度优先搜索算法的代码:
def bfs(start, goal, graph):
visited = []
queue = [[start]]
if start == goal:
return f"{start}到{goal}的最短路径是 {start}"
while queue:
path = queue.pop(0)
node = path[-1]
if node not in visited:
neighbours = graph[node]
for neighbour in neighbours:
new_path = list(path)
new_path.append(neighbour)
queue.append(new_path)
if neighbour == goal:
return f"从 {start} 到 {goal} 的最短路径是 {new_path}"
visited.append(node)
return f"{start}无法到达{goal}"
在上述代码中,我们通过一个递归函数来实现广度优先搜索算法。该函数首先输入一个起点、一个目标点和一个图(字典类型),然后我们创建了一个空的visited列表和一个只包含起点的队列。代码中包含了一个判断语句,当起点和目标点相同时,直接返回结果。
然后我们在循环中实现了核心的演步算法。我们从队列中弹出第一个节点,路径为该节点路径的最后一个节点。最后我们使用visited列表来存储已经访问过的节点。
下面是该代码的测试:
graph = {
'A': ['B', 'C', 'D'],
'B': ['E'],
'C': ['F'],
'D': ['G'],
'E': ['H'],
'F': ['I'],
'G': ['J'],
'H': ['I'],
'I': ['J']
}
assert bfs('A', 'H', graph) == "从 A 到 H 的最短路径是 ['A', 'B', 'E', 'H']"
assert bfs('A', 'J', graph) == "从 A 到 J 的最短路径是 ['A', 'D', 'G', 'J']"
assert bfs('A', 'A', graph) == "A到A的最短路径是 A"
assert bfs('C', 'F', graph) == "从 C 到 F 的最短路径是 ['C', 'F']"
assert bfs('J', 'A', graph) == 'J无法到达A'
我们的测试用例中包含了图中所有节点的最短路径的测试,包括起点和终点相同,起点无法到达终点等等情况。在测试结果中,可以看到每次我们都输出了从起点到终点的最短路径,这证明我们的算法是正确的。
结论
在本文中,我们介绍了广度优先搜索算法,在Python中的实现。该算法使用队列存储待遍历节点,并使用visit列表记录已经访问过的节点。这种方法可以查找起点和终点之间的最短路径,并能够处理一定大小的图。使用本文中提供的示例代码,读者可以直接在Python中查找几个点之间的最短路程。当然,如果需要处理更大的图,需要使用其他高效的算法。