最短路径——Dijkstra算法

1.Dijkstra算法:

1.这是一个图:

图

2.这是与这个图有关的表:

这里写图片描述
Dijkstra算法解决的问题一个顶点到其余各顶点的最短路径
主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
那么它是如何解决的呢?
见图:很明显,该顶点是V0,求的是V0到V1,V2,V3,V4的最短距离。
那么是如何做到的呢?
大致上是以起点向外扩展,当整个图都扩展出来时即得到了整个图的所有点到起点的最短路径。
详细解释见表:
在表中每个顶点下面都有三个参数,下面来详细解释一下这三个参数的意思:
S:标记点,有两种状态。0,1 。0,代表该点还未加入这个图里去。1,代表这个点已经加入图。
d:表示在以知的图里,各个点到起点的最短路径。注意在这里再详细解释一下。比如说,当这个图里只有0时,各个点到起点的最短路径就是各个点到起点的直接相连的边。如果该边不能到达则设置为无穷大。加入了新的点后,可以从起点,经过新的点间接的到达目标点。
p:路径,记录的是从哪个点到达目标点的。
原理解释:
创建两个表,OPEN, CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1. 访问路网中距离起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4. 重复第2和第3步,直到OPEN表为空,或找到目标点。
//注这里的open close对应S的零和一的状态。

const int  MAXINT = 32767;
const int MAXNUM = 10;
int dist[MAXNUM];
int prev[MAXNUM];

int A[MAXUNM][MAXNUM];

void Dijkstra(int v0)
{
    bool S[MAXNUM];                                  // 判断是否已存入该点到S集合中
      int n=MAXNUM;
    for(int i=1; i<=n; ++i)
    {
        dist[i] = A[v0][i];
        S[i] = false;                                // 初始都未用过该点
        if(dist[i] == MAXINT)    
              prev[i] = -1;
        else 
              prev[i] = v0;
     }
     dist[v0] = 0;
     S[v0] = true;   
    for(int i=2; i<=n; i++)
    {
         int mindist = MAXINT;
         int u = v0;                               // 找出当前未使用的点j的dist[j]最小值
         for(int j=1; j<=n; ++j)
            if((!S[j]) && dist[j]<mindist)
            {
                  u = j;                             // u保存当前邻接点中距离最小的点的号码 
                  mindist = dist[j];
            }
         S[u] = true; 
         for(int j=1; j<=n; j++)
             if((!S[j]) && A[u][j]<MAXINT)
             {
                 if(dist[u] + A[u][j] < dist[j])     //在通过新加入的u点路径找到离v0点更短的路径  
                 {
                     dist[j] = dist[u] + A[u][j];    //更新dist 
                     prev[j] = u;                    //记录前驱顶点 
                  }
              }
     }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值