zoukankan      html  css  js  c++  java
  • 迪杰斯特拉算法学习

    转自:https://zhuanlan.zhihu.com/p/40338107

    1.介绍

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

    但它不能处理负权路径,如果先找到一条不为负的最短,但当前目标节点已经被访问过,就无法更新包括负权的路径了。

    2.基本过程

    • 指定起点s,定义两个集合S、U,其中S表示已经求出最短路径的节点,U表示待求的
    • 初始时S中只有s节点,从U中选取出距离最近的加入,并且更新U中其他节点经过u到s的最短距离。
    • 直到所有节点都被访问完。

    3.实现

    https://blog.csdn.net/qq_35644234/article/details/60870719

    void Graph_DG::Dijkstra(int begin){
        //首先初始化我们的dis数组
        int i;
        for (i = 0; i < this->vexnum; i++) {
            //设置当前的路径
    //begin默认为0,更新直接相连的为默认距离
            dis[i].path = "v" + to_string(begin) + "-->v" + to_string(i + 1);
            dis[i].value = arc[begin - 1][i];
        }
        //设置起点的到起点的路径为0
        dis[begin - 1].value = 0;
        dis[begin - 1].visit = true;//标记初始节点访问过
    
        int count = 1;
        //计算剩余的顶点的最短路径(剩余this->vexnum-1个顶点)
        while (count != this->vexnum) {
            //temp用于保存当前dis数组中最小的那个下标
            //min记录的当前的最小值
            int temp=0;
            int min = INT_MAX;
            for (i = 0; i < this->vexnum; i++) {//选择距离最小的顶点
                if (!dis[i].visit && dis[i].value<min) {
                    min = dis[i].value;
                    temp = i;
                }
            }
            //cout << temp + 1 << "  "<<min << endl;
            //把temp对应的顶点加入到已经找到的最短路径的集合中
            dis[temp].visit = true;//标记已找到最小距离
            ++count;
            for (i = 0; i < this->vexnum; i++) {
                //注意这里的条件arc[temp][i]!=INT_MAX必须加,不然会出现溢出,从而造成程序异常
                if (!dis[i].visit && arc[temp][i]!=INT_MAX && (dis[temp].value + arc[temp][i]) < dis[i].value) {
                    //如果新得到的边可以影响其他为访问的顶点,那就就更新它的最短路径和长度
                    dis[i].value = dis[temp].value + arc[temp][i];
                    dis[i].path = dis[temp].path + "-->v" + to_string(i + 1);
                }
            }
        }
    }

    4.时空复杂度

    https://www.cnblogs.com/gaochundong/p/dijkstra_algorithm.html

    m为边数,n为节点数,如果用邻接矩阵存储,并且只使用普通的数组存储距离的话,那么时间复杂度为O(n^2)。

    下图中V是顶点数目,E是边:

    //不太明白binary heap和斐波那契堆是什么。

  • 相关阅读:
    shell脚本基础
    rtsp冷门解释
    C++基础之动态内存
    树莓派3安装ros
    Trie树
    [LeetCode]The Skyline Problem
    [LeetCode]Implement Trie (Prefix Tree)
    C++基础之适配器
    配置树莓派3的openwrt中的网络
    [LeetCode]Self Crossing
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/14356365.html
Copyright © 2011-2022 走看看