# Dijkstra算法求最短路径 def dijkstra(graph, start, end): n = len(graph) dist = [float('inf')] * n dist[start] = 0 visited = [False] * n heap = [(0, start)] while heap: d, u = heapq.heappop(heap) if visited[u]: continue visited[u] = True for v in range(n): if graph[u][v] > 0: if dist[u] + graph[u][v] < dist[v]: dist[v] = dist[u] + graph[u][v] heapq.heappush(heap, (dist[v], v)) return dist[end] # Bellman-Ford算法求最短路径 def bellman_ford(graph, start, end): n = len(graph) dist = [float('inf')] * n dist[start] = 0 for i in range(n-1): for u in range(n): for v in range(n): if graph[u][v] > 0: if dist[u] + graph[u][v] < dist[v]: dist[v] = dist[u] + graph[u][v] return dist[end] # 求最短距离和最短路径 print("Dijkstra算法:") print("最短距离:", dijkstra(graph, 0, 9)) print("最短路径:") path = [] n = len(graph) dist = [float('inf')] * n dist[0] = 0 prev = [-1] * n heap = [(0, 0)] while heap: d, u = heapq.heappop(heap) if u == 9: break for v in range(n): if graph[u][v] > 0: if dist[u] + graph[u][v] < dist[v]: dist[v] = dist[u] + graph[u][v] prev[v] = u heapq.heappush(heap, (dist[v], v)) if prev[9] == -1: print("不存在路径") else: v = 9 while v != -1: path.append(v) v = prev[v] path.reverse() print(path) print("Bellman-Ford算法:") print("最短距离:", bellman_ford(graph, 0, 9))代码分析
时间: 2024-03-30 19:38:43 浏览: 160
这段代码实现了Dijkstra算法和Bellman-Ford算法来求解最短路径问题。其中,Dijkstra算法是一种贪心算法,每次取距离起点最短的未被访问节点,更新其邻居节点的距离。Bellman-Ford算法则是一种动态规划算法,通过多次松弛操作来得到最短路径。在这段代码中,graph表示图的邻接矩阵,其中graph[i][j]表示节点i到节点j的距离。start和end表示起点和终点的编号。
在Dijkstra算法中,使用一个堆来存储待访问的节点,并按照距离起点的距离从小到大排序。每次取出堆中距离最小的节点,更新其邻居节点的距离。当堆为空或者终点被访问时,算法结束。最后通过prev数组来回溯路径。
在Bellman-Ford算法中,需要进行n-1次松弛操作,其中n为节点数。每次将所有边进行松弛操作,即如果从起点到u的距离加上u到v的距离小于从起点到v的距离,则更新从起点到v的距离。如果还能进行松弛操作,则说明存在负环路,否则得到的dist数组即为最短距离。
相关问题
import random import heapq # 生成无向图 def generate_graph(n, p): graph = [[0] * n for _ in range(n)] for i in range(n): for j in range(i+1, n): if random.random() < p: graph[i][j] = graph[j][i] = random.randint(1, 10) return graph # Prim算法求最小生成树 def prim(graph): n = len(graph) visited = [False] * n heap = [(0, 0)] mst = [] while heap: weight, node = heapq.heappop(heap) if visited[node]: continue visited[node] = True mst.append((weight, node)) for i in range(n): if not visited[i] and graph[node][i] > 0: heapq.heappush(heap, (graph[node][i], i)) return mst # Kruskal算法求最小生成树 def kruskal(graph): n = len(graph) edges = [] for i in range(n): for j in range(i+1, n): if graph[i][j] > 0: edges.append((graph[i][j], i, j)) edges.sort() parent = list(range(n)) mst = [] for weight, u, v in edges: pu, pv = find(parent, u), find(parent, v) if pu != pv: mst.append((weight, u, v)) parent[pu] = pv return mst def find(parent, x): if parent[x] != x: parent[x] = find(parent, parent[x]) return parent[x] # 生成图 graph = generate_graph(10, 0.6) print(graph) mst_prim = prim(graph) print("Prim算法求最小生成树:", mst_prim) mst_kruskal = kruskal(graph) print("Kruskal算法求最小生成树:", mst_kruskal) # Dijkstra算法求最短路径 def dijkstra(graph, start, end): n = len(graph) dist = [float('inf')] * n dist[start] = 0 visited = [False] * n heap = [(0, start)] while heap: d, u = heapq.heappop(heap) if visited[u]: continue visited[u] = True for v in range(n): if graph[u][v] > 0: if dist[u] + graph[u][v] < dist[v]: dist[v] = dist[u] + graph[u][v] heapq.heappush(heap, (dist[v], v)) return dist[end] # Bellman-Ford算法求最短路代码分析
这段代码主要实现了生成无向图、Prim算法和Kruskal算法求最小生成树、Dijkstra算法和Bellman-Ford算法求最短路径。具体分析如下:
1. 生成无向图:通过调用generate_graph函数,可以生成一个无向图,其中n表示节点数,p表示两个节点之间有边的概率,边的权重是随机生成的。
2. Prim算法求最小生成树:通过调用prim函数,可以求出一个无向图的最小生成树,返回的是由边和对应权重组成的列表。prim函数通过维护一个堆heap来实现,每次取出堆顶元素,并将与该节点相邻的未访问节点加入堆中。
3. Kruskal算法求最小生成树:通过调用kruskal函数,同样可以求出一个无向图的最小生成树,返回的也是由边和对应权重组成的列表。kruskal函数通过将图中所有边按权重从小到大排序,然后依次加入到生成树中去,同时使用并查集来判断是否形成环。
4. Dijkstra算法求最短路径:通过调用dijkstra函数,可以求出一个无向图中从起点到终点的最短路径长度。dijkstra函数同样维护一个堆heap,每次取出堆顶元素,并将与该节点相邻的节点加入堆中,同时更新起点到这些节点的距离。
5. Bellman-Ford算法求最短路:通过调用bellman_ford函数,同样可以求出一个无向图中从起点到终点的最短路径长度。bellman_ford函数通过不断进行松弛操作来更新起点到各个节点的距离,同时也可以检测负权环的存在。
dijkstra 算法求最短路径 c语言
下面是用C语言实现Dijkstra算法求最短路径的示例代码:
```c
#include <stdio.h>
#include <limits.h>
#define V 6 // 图的顶点数
int minDistance(int dist[], int visited[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++) {
if (!visited[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
}
return min_index;
}
void printSolution(int dist[]) {
printf("Vertex \t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t %d\n", i, dist[i]);
}
void dijkstra(int graph[V][V], int src) {
int dist[V]; // 存储从源节点到各个节点的最短距离
int visited[V]; // 标记节点是否已被访问
// 初始化所有节点的距离为无穷大,标记为未访问
for (int i = 0; i < V; i++) {
dist[i] = INT_MAX;
visited[i] = 0;
}
dist[src] = 0; // 源节点到自身的距离为0
// 求解最短路径
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, visited); // 选择当前未被访问的距离最短的节点
visited[u] = 1; // 标记该节点为已访问
// 更新与节点u相邻的节点的最短距离
for (int v = 0; v < V; v++) {
if (!visited[v] && graph[u][v] && dist[u] != INT_MAX && dist[u]+graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}
}
printSolution(dist); // 输出最短路径
}
int main() {
int graph[V][V] = {
{0, 4, 0, 0, 0, 0},
{4, 0, 8, 0, 0, 0},
{0, 8, 0, 7, 0, 4},
{0, 0, 7, 0, 9, 14},
{0, 0, 0, 9, 0, 10},
{0, 0, 4, 14, 10, 0}
};
dijkstra(graph, 0);
return 0;
}
```
该示例代码中的图是一个有向带权图,其中0表示源节点,其他数字表示图中其他节点之间的距离。运行该代码,即可输出从源节点到其他各个节点的最短距离。
阅读全文