美文网首页
Dijkstra算法 C++实现

Dijkstra算法 C++实现

作者: lazydecoder | 来源:发表于2018-04-14 21:34 被阅读0次

单源最短路径

对于图G =(V,E),给定源点 s 属于 V ,单源路径是指从 s 到图中其他各顶点的最短路径.

下图为带权有向图,从 v0 到其余各个顶点的最短路径如表所示。


image
Dijkstra
源点 终点 最短路径 路径长度
v0 v1 V0->v1 12
v2 v0->v2 10
v3 v0->v4->v3 50
v4 v0->v4 30
v5 v0->v4->v3->v5 60

Dijkstra算法

设图的邻接矩阵为 W ,Dijkstra 算法首先将图的顶点集合划分成两个集合 S 和 V-S 。

集合 S 表示最短路径已经确定的顶点集合,其余的顶点则存放在另一个集合 V-S 中。

初始状态时,集合 S 至包括源点,即 S = {s} ,表示此时只有源点到自己的最短路径称为从源点到顶点 v 到最短路径,并用数组 D 来记录当前所找到的从源点 s 到每个顶点的最短路径长度,用数组 path 来记录到达各个顶点的前驱顶点。

其中,如果从源点 s 到顶点 c 有弧 ,则以弧到权值作为 D[v] 的初始值;否则将 D[v] 的初始为无穷大,path 数组初始化为 s 。

Dijkstra 算法每次从尚未确定最短路径长度的集合 V-S 中取出一个最短特殊路径长度最小的顶点 u ,将 u 加入集合 S ,同时更新数组 D 、path 中由 s 可达大各个顶点的最短特殊路径长度。

更新 D 的策略是,若加进 u 做中间顶点,使得 vi 的最短特殊路径长度变短,则修改 vi 的最短特殊路径长度及前驱顶点编号,即当 D[u]+W[u ,vi]<D[vi] 时,令 D[vi] = D[u]+W[u,vi], path[vi] = u 。重复上述操作,一旦 S 包含了 V 中所有的顶点, D 记录了从源点 s 到各个顶点的最短路径长度,path 记录了相应最短路径的终点的前驱顶点编号。

下表直观地表示了 v0 到图中其他顶点的最短路径及最短路径长度。

顶 点   {v2} {v2,v1} {v2,v1,v4} {v2,v1,v4,v3} {v2,v1,v4,v3,v5}
v1 12 12
v2 10
v3 60 60 50
v4 30 30 30
v5 100 100 100 90 60
最短路径 v0v2 v0v1 v0v4 v0v4v3 v0v4v3v5
新顶点 v2 v1 v4 v3 v5
路径长度 10 12 30 50 60

代码实现

1.定义一个结构体,用来记录每个顶点的最短路径。

struct Path{
    string route;
        Path(){
        route = "";
    }
};

2.Dijkstra 算法的实现

void Dijkstra(int s,int  D[]){
    int n = VerticesNum();
    path = new Path[n];
    int i,j;
    for(i = 0;i<n;i++){
        D[i] = matrix[s][i];
        path[i].route = "v"+to_string(s) + "-->" + "v" + to_string(i);
    }
    Mark[s] = VISITED;
    D[s] = 0;

    
    for(i = 0;i<n;i++){
        //找到一条最短的特殊路径
        int min = INFINITY;
        int k = 0;
        for(j = 0;j<n;j++){
            if(Mark[j]==UNVISITED&&min>D[j]){
                min = D[j];
                k = j;
            }
        }
        Mark[k] = VISITED;
        for(Edge e = FirstEdge(k);IsEdge(e);e = NextEdge(e)){
            int endVertex = e.end;
            if(Mark[endVertex]==UNVISITED&&D[endVertex]>(D[k] + e.weight)&&e.weight!=INFINITY){
                //更新endVertex的最短特殊路径
                D[endVertex] = D[k] + e.weight;
                path[endVertex].route = path[k].route + "-->v"+to_string(endVertex);
            }
        }
    }
    for(int i = 0;i<n;i++){
        if(D[i]!=INFINITY){
            cout<<path[i].route<<endl;
        }
        else{
            cout<<"no road"<<endl;
        }
    }    
}

相关文章

  • Dijkstra算法 C++实现

    单源最短路径 对于图G =(V,E),给定源点 s 属于 V ,单源路径是指从 s 到图中其他各顶点的最短路径. ...

  • Dijkstra 算法

    Dijkstra 算法 前言 为了达到任意两结点的最短路径,我们有几种算法可以实现:Dijkstra 算法、Flo...

  • 图的最短路径

    Dijkstra算法&Floyd算法 一、Dijkstra算法 Dijkstra算法思想: 只计算v0出发到其他顶...

  • JavaScript模拟图操作

    JS操作实现无向网的Prim算法 最后输出结果如下: 其中例子中的图如下: JavaScript实现Dijkstra算法

  • 深入解析Dijkstra's Algorithm ——

    什么是Dijkstra算法? Dijkstra算法是用来寻找最短路径最著名的算法之一。具体来说,Dijkstra算...

  • OC算法实现--Dijkstra算法

    本文使用OC语言实现了Dijkstra算法,并实现了构图界面化,demo下载地址:github 效果图如下: 算法...

  • Dijkstra算法Java实现

    一、原文链接 http://blog.csdn.net/u011638883/article/details/17...

  • Python实现Dijkstra算法

    描述 地图上有 m 条无向边,每条边 (x, y, w) 表示位置 x 到位置 y 的权值为 w。从位置 0 到 ...

  • Aha! Algorithms - Dijkstra

    《啊哈!算法》第 6 章第 2 节,Dijkstra 算法求最短路径的 Swift 实现。 问题 已经若干顶点和路...

  • 寻找最短路径

    这方面的经典算法,有Dijkstra算法和Floyd算法。 下面简单说一下基于Dijkstra算法略作小改动的一个...

网友评论

      本文标题:Dijkstra算法 C++实现

      本文链接:https://www.haomeiwen.com/subject/htrrkftx.html