广度优先搜索
,能够找出段数最少的路径。但是不能找出加权图的最短路径。
狄克斯特拉
算法,能够解决加权图中最短路径的问题(即总权数最小的路径)。只适用于有向无环图。且边的权重不能为负(贝尔曼 • 福德算法(Bellman-Ford algorithm)可以解决权重为负的问题)。
在下图中如果采用广度优先搜索就会得到如下最短路径。但这条路并不是耗时最短的路径。下面我我们来看看狄克斯算法的解决思路。
算法思路:
- 找出“最便宜”的节点,即可在最短时间内到达的节点。
- 更新该节点的邻居的开销。
- 重复这个过程,直到对图中的每个节点都这样做了 。
- 计算最终路径 。
根据下面的加权图,求解起点到终点的最短路径。
# 构造数据
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
# 构造路径关系
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None
# 记录处理过的节点
processed = []
# 构造损失字典
costs = {}
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs:
cost = costs[node]
if cost < lowest_cost and node not in processed:
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
node = find_lowest_cost_node(costs)
while node is not None:
cost = costs[node]
neighbors = graph[node]
for n in neighbors.keys():
new_cost = cost + neighbors[n]
if costs[n] > new_cost:
costs[n] = new_cost
parents[n] = node
processed.append(node)
node = find_lowest_cost_node(costs)
print(parents)
总结:
- 广度优先搜索用于在非加权图中查找最短路径。
- 狄克斯特拉算法用于在加权图中查找最短路径。
- 仅当权重为正时狄克斯特拉算法才管用。
- 如果图中包含负权边,请使用
贝尔曼 • 福德
算法。
参考