最短路径之Dijkstar算法详解

(这是一个无向有环图)

1
5
3
7
5
1
7
3
6
9
5
2
7
4
v0
v1
v2
v3
v4
v5
v6
v7
v8

计算v0到v8的最短路径,v0称为源节点,v8称为终节点。
定义三个向量:d向量,用于存储从v0到该节点的最短路径的权值,初始值为无穷大或记为inf
p向量,存储这个节点的前驱节点的索引号,初始值为0
final=1表示从v0到该节点的最短路径以求得,初始值为0.

第一步:
初始化
d[0] = 0;
d[1] = 1;
d[2] = 5;
final[0] = 1;
此时的各个向量表示

node   d       p     final
0      0       0       1
1      1       0       0
2      5       0       0
3      inf     0       :
4      inf     0       :
5      inf     0       :
6      inf     0       :
7      inf     0       :
8      inf     0       :

第二步:
遍历v0到各个与其相邻节点的最短路径,并更新d,p,final的值,
第三步:遍历在final=0的节点中,最短路径d最小的节点。如图此时为v1,那么下一个遍历的节点即为v1
v1到v2路径为3,则v0到v2的最短路径为4,比之前填入的d[2] = 5小,则进行替换,p[2] = 1,final[1] = 1;
d[3] = d[1] + v1 -> v3的路径权值,并p[3] = 1
d[4] = d[1] + v1 -> v4的路径权值, p[4] = 1
此时的图:

node   d       p     final
0      0       0       1
1      1       0       1
2      5       1       1
3      8       1       :
4      5       1       :
5      inf     0       :
6      inf     0       :
7      inf     0       :
8      inf     0       :

依照第二步和第三步依次往下进行遍历,直到所有的final都为1,
最后的图

node   d       p     final
0      0       0       1
1      1       0       1
2      4       1       1
3      7       4       1
4      5       2       1
5      8       4       1
6      10      3       1
7      12      6       1
8      16      7       1

如果p有相同的数值,则根据d中最小的进行计算

#define MAXVEX 9
#define  INFINITY 65535

typedef  int  Patharc[MAXVEX]; // 用于存储最短路径下标的数组
typedef int  ShortPathTable[MAXVEX]; // 用于存储到各点最短路径的权值和

void ShortestPath_Dijkstar(MGraph G, int V0, Patharc *P, ShortPathTable *D)
{
  int v, w, k, min;
  int final[MAXVEX]; // final[w] = 1 表示已经求得顶点V0到Vw的最短路径
  
  // 初始化数据
  for( v=0; v < G.numVertexes; v++ )
  {
    final[v] = 0; // 全部顶点初始化为未找到最短路径
    (*D)[V] = G.arc[V0][v]; // 将与V0点有连线的顶点加上权值
    (*P)[V] = 0; // 初始化路径数组P为0
  }
  (*D)[V0] = 0; // V0至V0的路径为0
  final[V0] = 1; // V0至V0不需要求路径
  
  // 开始主循环,每次求得V0到某个V顶点的最短路径
  for( v=1; v < G.numVertexes; v++ )
  {
    min = INFINITY;
    for( w=0; w < G.numVertexes; w++ )
    {
      if( !final[w] && (*D)[w]<min )
      {
        k = w;
        min = (*D)[w];
      }
    }
    final[k] = 1; // 将目前找到的最近的顶点置1
    
    // 修正当前最短路径及距离
    for( w=0; w < G.numVextexes; w++ )
    {
      // 如果经过v顶点的路径比现在这条路径的长度短的话,更新!
      if( !final[w] && (min+G.arc[k][w] < (*D)[w]) )
      {
        (*D)[w] = min + G.arc[k][w]; // 修改当前路径长度
        (*p)[w] = k; // 存放前驱顶点
      }
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值