数据结构(单源最短路径)

单源最短路径指的是找到A,B两点之间路径中权值之和最小的路径。
狄克斯特拉算法(Dikastra)
对于求单源点的最短路径问题,狄克斯特拉(Dikastra)提出了一个按路径长度递增的顺序逐步产生最短路径的构造算法。狄克斯特拉的算法思想是:设置两个顶点的集合S和T,集 合S中存放已找到最短路径的顶点,集合T中存放当前还未找到最短路径的顶点。初始状态时,集合S中只包含源点,设为v0,然后从集合T中选择到源点v0路径长度最短的顶点u加入到集合S中,集合S中每加入一个新的顶点u都要修改源点v0到集合T中剩余顶点的当前最短路径长度值,集合T中各顶点的新的最短路径长度值为原来的当前最短路径长度值与
从源点过顶点u到达该顶点的新的最短路径长度中的较小者。此过程不断重复,直到集合T中的顶点全部加到集合S中为止。
算法实现:

public void Dijkstra(ref bool[,] pathMatricArr, 
ref int[] shortPathArr, Node<T> n) 
{ 
int k = 0; 
bool[] final = new bool[nodes.Length]; 
//初始化 
for (int i = 0; i < nodes.Length; ++i) 
{ 
final[i] = false; 
shortPathArr[i] = matrix[GetIndex(n),i]; 
for (int j = 0; j < nodes.Length; ++j) 
{ 
pathMatricArr[i,j] = false; 
} 
if (shortPathArr[i] != 0 && shortPathArr[i] < int.MaxValue) 
{ 
pathMatricArr[i,GetIndex(n)] = true; 
pathMatricArr[i,i] = true; 
} 
} 
// n为源点 
shortPathArr[GetIndex(n)] = 0; 
final[GetIndex(n)] = true; 
//处理从源点到其余顶点的最短路径 
for (int i = 0; i < nodes.Length; ++i) 
{ 
int min = int.MaxValue; 
//比较从源点到其余顶点的路径长度 
for (int j = 0; j < nodes.Length; ++j) 
{ 
//从源点到j顶点的最短路径还没有找到 
if (!final[j]) 
{ 
/从源点到j顶点的路径长度最小 
if (shortPathArr[j] < min) 
{ 
k = j; 
min = shortPathArr[j]; 
} 
} 
} 
//源点到顶点k的路径长度最小 
final[k] = true; 
//更新当前最短路径及距离 
for (int j = 0; j < nodes.Length; ++j) 
{ 
if (!final[j] && (min + matrix[k,j] < shortPathArr[j])) 
{ 
shortPathArr[j] = min + matrix[k,j]; 
for (int w = 0; w < nodes.Length; ++w) 
{ 
pathMatricArr[j,w] = pathMatricArr[k,w]; 
} 
pathMatricArr[j,j] = true; 
} 
} 
} 
}
单源最短路径是指从图中的一个源点出发,到达图中其他所有顶点的最短路径。数据结构中常用的两种单源最短路径算法是Dijkstra算法和Bellman-Ford算法。 1. Dijkstra算法: Dijkstra算法是一种贪心算法,用于解决带权有向图或无向图的单源最短路径问题。该算法的基本思想是:将图中的所有顶点分成两个集合,一个集合为已求出最短路径的顶点集合S,另一个为未求出最短路径的顶点集合V-S。初始时,集合S中只有源点,即S={v},V-S为除源点外的其他顶点。然后,从V-S中选择与源点距离最短的顶点u,将其加入到S中,并更新从源点v到集合V-S中所有顶点的距离。重复执行该过程,直到集合V-S为空。 2. Bellman-Ford算法: Bellman-Ford算法是一种动态规划算法,用于解决带权有向图或无向图的单源最短路径问题。该算法的基本思想是:对于图中的任意一条边(u,v),如果存在从源点s到u的最短路径,则从源点s到v的最短路径就是从源点s到u的最短路径加上边(u,v)的权值。因此,Bellman-Ford算法通过对所有边进行松弛操作,不断更新从源点s到各个顶点的最短路径估计值,直到所有边的松弛操作都无法使最短路径估计值发生变化为止。 下面是两种算法的Python实现: 1. Dijkstra算法: ```python import heapq def dijkstra(graph, start): # 初始化距离字典和堆 dist = {node: float('inf') for node in graph} dist[start] = 0 heap = [(0, start)] # 循环直到堆为空 while heap: # 弹出堆中距离最小的顶点 (d, node) = heapq.heappop(heap) # 如果该顶点已经处理过,则跳过 if d > dist[node]: continue # 遍历该顶点的所有邻居 for neighbor, weight in graph[node].items(): # 计算从起点到该邻居的距离 distance = dist[node] + weight # 如果该距离比已有的距离小,则更新距离字典和堆 if distance < dist[neighbor]: dist[neighbor] = distance heapq.heappush(heap, (distance, neighbor)) return dist ``` 2. Bellman-Ford算法: ```python def bellman_ford(graph, start): # 初始化距离字典 dist = {node: float('inf') for node in graph} dist[start] = 0 # 循环V-1次,对所有边进行松弛操作 for i in range(len(graph) - 1): for u in graph: for v, weight in graph[u].items(): if dist[u] + weight < dist[v]: dist[v] = dist[u] + weight # 检查是否存在负权回路 for u in graph: for v, weight in graph[u].items(): if dist[u] + weight < dist[v]: raise ValueError("Graph contains negative weight cycle") return dist ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值