数据结构与算法之算法 图论算法对比 Dijkstra/Floyd/Bellman Ford

数据结构与算法阿木 发布于 2025-07-11 11 次阅读


摘要:

图论是计算机科学中一个重要的分支,其中涉及多种算法用于解决路径搜索、最短路径等问题。本文将对比分析Dijkstra、Floyd和Bellman-Ford三种经典图论算法,通过代码实现来展示它们的原理和性能差异。

一、

在图论中,图是一种用于表示实体及其之间关系的抽象数据结构。图论算法广泛应用于网络路由、社交网络分析、地图导航等领域。本文将重点介绍三种用于求解最短路径问题的算法:Dijkstra、Floyd和Bellman-Ford。

二、Dijkstra算法

Dijkstra算法是一种用于在加权图中找到单源最短路径的贪心算法。它适用于边的权重非负的情况。

1. 原理

Dijkstra算法的基本思想是维护一个集合S,其中包含已找到最短路径的顶点。算法从源点开始,逐步将距离源点最近的顶点加入集合S,直到所有顶点都被处理。

2. 代码实现

python

import heapq

def dijkstra(graph, start):


distances = {vertex: float('infinity') for vertex in graph}


distances[start] = 0


priority_queue = [(0, start)]



while priority_queue:


current_distance, current_vertex = heapq.heappop(priority_queue)



if current_distance > distances[current_vertex]:


continue



for neighbor, weight in graph[current_vertex].items():


distance = current_distance + weight



if distance < distances[neighbor]:


distances[neighbor] = distance


heapq.heappush(priority_queue, (distance, neighbor))



return distances

示例图


graph = {


'A': {'B': 1, 'C': 4},


'B': {'A': 1, 'C': 2, 'D': 5},


'C': {'A': 4, 'B': 2, 'D': 1},


'D': {'B': 5, 'C': 1}


}

调用Dijkstra算法


distances = dijkstra(graph, 'A')


print(distances)


三、Floyd算法

Floyd算法是一种动态规划算法,用于在加权图中找到所有顶点对之间的最短路径。

1. 原理

Floyd算法通过迭代更新所有顶点对之间的最短路径。它使用一个三维数组来存储所有顶点对之间的距离,并在迭代过程中更新这些距离。

2. 代码实现

python

def floyd(graph):


distances = [[float('infinity')] len(graph) for _ in range(len(graph))]



for i in range(len(graph)):


distances[i][i] = 0



for i in range(len(graph)):


for j in range(len(graph)):


for k in range(len(graph)):


distances[i][j] = min(distances[i][j], distances[i][k] + distances[k][j])



return distances

示例图


graph = [


[0, 1, 4, float('infinity'), float('infinity')],


[1, 0, 2, 5, float('infinity')],


[4, 2, 0, 1, 3],


[float('infinity'), 5, 1, 0, 2],


[float('infinity'), float('infinity'), 3, 2, 0]


]

调用Floyd算法


distances = floyd(graph)


for row in distances:


print(row)


四、Bellman-Ford算法

Bellman-Ford算法是一种用于在加权图中找到单源最短路径的算法,它能够处理负权重边。

1. 原理

Bellman-Ford算法通过迭代更新所有顶点对之间的最短路径。它从源点开始,逐步将距离源点最近的顶点加入集合S,直到所有顶点都被处理。与Dijkstra算法不同的是,Bellman-Ford算法能够检测负权重循环。

2. 代码实现

python

def bellman_ford(graph, start):


distances = {vertex: float('infinity') for vertex in graph}


distances[start] = 0



for _ in range(len(graph) - 1):


for vertex in graph:


for neighbor, weight in graph[vertex].items():


if distances[vertex] + weight < distances[neighbor]:


distances[neighbor] = distances[vertex] + weight



检测负权重循环


for vertex in graph:


for neighbor, weight in graph[vertex].items():


if distances[vertex] + weight < distances[neighbor]:


raise ValueError("Graph contains a negative weight cycle")



return distances

示例图


graph = {


'A': {'B': 1, 'C': 4},


'B': {'A': 1, 'C': 2, 'D': 5},


'C': {'A': 4, 'B': 2, 'D': 1},


'D': {'B': 5, 'C': 1}


}

调用Bellman-Ford算法


distances = bellman_ford(graph, 'A')


print(distances)


五、总结

本文对比分析了Dijkstra、Floyd和Bellman-Ford三种图论算法。Dijkstra算法适用于非负权重边,Floyd算法适用于所有类型的边,而Bellman-Ford算法能够处理负权重边。通过代码实现,我们可以看到每种算法的原理和性能差异。在实际应用中,选择合适的算法取决于具体问题和数据特点。