【图】最短路径--迪杰斯特拉(Dijkdtra)算法

来源:互联网 发布:windows loader win10 编辑:程序博客网 时间:2024/06/01 10:11

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。

它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

算法思想
每次找到离源点最近的一个顶点,然后以该顶点为中心,然后得到源点到其他顶点的最短路径。贪心算法。

举例分析

以邻接矩阵为存储图

这里写图片描述

注:上图中,邻接矩阵的对称线也是无穷大,在初始时默认为无穷大。可以看上篇博客,图的存储。

(1) 用dis数组来存储源点1到其他顶点的初始路径,标记1号顶点,
这里写图片描述

此时dis数组中的值称为最短路径的估计值。

(2) 从dis数组中找出离源起点最近的点2号,以2号顶点为源点进行找最近的顶点。把2号顶点标记,表示已经有最小值。

以2号顶点为源点,看2号顶点有哪些出边,看能不能优化,再短一些
2->3:9,2->4:3
而dis中最短路径的估计值,1->2:1, 1->3:12
那么结合一下 1->2->3:1+9=10,比1->3:12 小,
1->2:1 和 2->4:3,那么1->2->4:4
所以要更新 dis中的最短路径估计值,

这里写图片描述

(3) 此时1号和2号顶点已经标记,表示已经最小值,现在在3号和4号找,4号顶点距离源点最近,所以以4号顶点进行找,标记4号顶点

4号的出边:
4->3:4,4->5:13,4->6:15。
用刚才的方法进行更新估计值。
1->3:10 比 1->4->3:4+4=8,大,所以更新
1->4:4,4->5:13+4=17,更新。
1->4:4,4->6:15+4 = 19。更新
这里写图片描述

(4)从3号,5号,6号,找最短路径8,标记3号顶点。
以相同的方法进行更新。

这里写图片描述

(5)从5号和6号顶点查找,标记5号。
以相同的方法进行更新。

这里写图片描述

(6)此时剩余6号顶点,6号的出边没有,
此时所有的顶点都以遍历完,dis中的值就是最终的结果。

这里写图片描述

步骤:
(1)将所有的顶点分为两个部分,已知最短路径的顶点集合P和未知的顶点集合Q,初始时,P中只有一个源顶点1号。这里用book数组来标记顶点是否在P中,1表示在P中,0表示在Q中。

dis数组来记录最短路径,数组下标来表示顶点的下标。

设置源点1到到其他顶点的路径值,放置到dis中。

(2)在dis中找到源点s到其他顶点的最短路径u顶点,将其加入P集合,并考察以x顶点为起点的出边,然后对dis 进行更新。即:如果存在一条从u到v的边,那么可以拓展一条从s到u再到v的边,路径长度为dis[u]+edge[u] [v] ,如果这个值比目前的值dis[v]小,那么就进行更新。

(3)重复第2步,直到Q为空,即book都被标记,此时dis数组中就是源点到各个顶点的最短路径。

代码实现

    //最短路径,Dijkdtra算法    vector<int> Dijkdtra(const V& start)    {        //保存结果值,下标为顶点元素的下标,        vector<int> dis(_ver.size());        //记录已确定的最小的值的顶点        vector<int> book(_ver.size(), 0);        //获取起始位置的下标,        int index = GetIndexOfVertex(start);        book[index] = 1;        //初始化dis        for (size_t idx = 0; idx < _edge[0].size(); ++idx)            dis[idx] = _edge[index][idx];               while (true)        {            int u = -1;//新的源点下标            int min = INT_MAX;            //寻找未被处理过,且距离最小的点            for (size_t i = 0; i < dis.size(); ++i)            {                if (book[i] == 0 && dis[i] < min)                {                    min = dis[i];                    u = i;//记录最近的顶点下标                               }            }            //都处理过,退出            if (u == -1)                break;            book[u] = 1;            //步骤2            for (size_t v = 0; v < _edge[0].size(); ++v)            {                if (_edge[u][v] < INT_MAX)                {                    if (dis[v] > _edge[u][v] + dis[u])                        dis[v] = _edge[u][v] + dis[u];                }            }        }        return dis;    }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq红包充值话费未到账怎么办 qq飞车充值至尊皇冠不到账怎么办 微信支付金额超过单日限制怎么办 不小心在qq钱包中充错话费怎么办 衣服质量不好穿了几次就坏了怎么办 手机丢了找到手机店的人怎么办 在手机店买手机买贵了怎么办 王者荣耀好多没对的东西怎么办 用电脑玩游戏键盘不管用怎么办? 王者荣耀跨系统送皮肤领不到怎么办 电脑使用迅雷时提示缓存过高怎么办 扣扣安全中心动态密码忘记了怎么办 pu管两头固定了中间换截怎么办 自己架设的传奇不能注册帐号怎么办 天堂2第八章读取服务端错误怎么办 苹果手机王者荣耀下了不能玩怎么办 苹果手机摔了一下触屏失灵怎么办 华为机回复出厂设置帐号忘了怎么办 华为手机里突然有个pp助手怎么办 华为手机与电脑连接不上怎么办 买房交了首付贷不了款怎么办 手机买贵了实体店不肯退怎么办 在实体店里手机买贵了怎么办 红米手机开启不了安装系统怎么办? 捡个荣耀8双清后要账号怎么办 荣耀7x升级8.0后耗电快怎么办 手机提示当前为耳机播放模式怎么办 华为手机进水了显示耳机模式怎么办 苹果6s突然变成耳机模式怎么办 华为手机出现耳机标志没声音怎么办 苹果手机微信变成耳机模式怎么办 5s不能用4g网络怎么办 华为麦芒四手机系统乱了好卡怎么办 信翼路由器登录密码忘了怎么办 苹果手机电信4g信号变3g怎么办 苹果7手机4g变3g怎么办 朵唯v3逆客手机不支持计步怎么办 移动卡升级4g后网络不好怎么办 电信办宽带送的手机卡不用了怎么办 移动华为悦盒遥控器丢了怎么办 移动签了两年套餐不想用了怎么办