zoukankan      html  css  js  c++  java
  • 迪科斯彻算法

    迪科斯彻算法(Dijkstra)是由荷兰计算机科学家艾兹格·迪科斯彻(Edsger Wybe Dijkstra)发明的。算法解决的是有向图中单个源点到其他顶点的最短路径问题。举例来说,如果图中的顶点表示城市,而边上的权重表示著城市间开车行经的距离,迪科斯彻算法可以用来找到两个城市之间的最短路径。

    迪科斯彻算法的输入包含了一个有权重的有向图 G,以及G中的一个来源顶点 S。我们以 V 表示 G 中所有顶点的集合。每一个图中的边,都是两个顶点所形成的有序元素对。(u, v) 表示从顶点u  v 有路径相连。我们以 E 所有边的集合,而边的权重则由权重函数 w: E  [0, ] 定义。因此,w(u, v) 就是从顶点 u 到顶点 v 的非负花费值(cost)。边的花费可以想像成两个顶点之间的距离。任两点间路径的花费值,就是该路径上所有边的花费值总和。已知有 V 中有顶点 s  tDijkstra 算法可以找到 s  t 的最低花费路径(例如,最短路径)。这个算法也可以在一个图中,找到从一个顶点 s 到任何其他顶点的最短路径。

     

    算法描述

    这个算法是通过为每个顶点 v 保留目前为止所找到的从sv的最短路径来工作的。初始时,原点 s 的路径长度值被赋为 0 d[s] = 0),同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于 V 中所有顶点 v  s d[v] = ∞)。当算法结束时,d[v] 中储存的便是从 s  v 的最短路径,或者如果路径不存在的话是无穷大。 Dijkstra 算法的基础操作是边的拓展:如果存在一条从 u  v 的边,那么从 s  v 的最短路径可以通过将边(u, v)添加到尾部来拓展一条从 s  u 的路径。这条路径的长度是 d[u] + w(u, v)。如果这个值比目前已知的 d[v] 的值要小,我们可以用新值来替代当前 d[v] 中的值。拓展边的操作一直执行到所有的 d[v] 都代表从 s  v 最短路径的花费。这个算法经过组织因而当 d[u] 达到它最终的值的时候每条边(u, v)都只被拓展一次。

    算法维护两个顶点集 S  Q。集合 S 保留了我们已知的所有 d[v] 的值已经是最短路径的值顶点,而集合 Q 则保留其他所有顶点。集合S初始状态为空,而后每一步都有一个顶点从 Q 移动到 S。这个被选择的顶点是 Q 中拥有最小的 d[u] 值的顶点。当一个顶点 u  Q 中转移到了 S 中,算法对每条外接边 (u, v) 进行拓展。

     

    C++代码实现

    Dijkstra算法求一点到其他点的最短路径。关系矩阵可以写成半角阵,因为无向图矩阵是对称的,x代表断路,数字代表点之间的距离,图上一共8个点,自己到自己的距离是0。例如,书P166 7.3 求图7-13所示途中定点V0V5的最短路径。我们先将图7-13转换为如下矩阵:

    0 1 4 X X X

    1 0 2 7 5 X

    4 2 0 X 1 X

    X 7 X 0 3 2

    X 5 1 3 0 6

    X X X 2 6 0

    详细代码如下:

    #include <iostream>

    #include <vector>

    #include <list>

    #include <iterator>

    #include <algorithm>

    #include <numeric>

    #include <functional>

    #include <climits>

    using namespace std;

    int map[6][6]={          // map : (map)(用邻接矩阵(adjacent matrix)表示)

        {0,1,4,'X','X','X'},     //'x'ASCII码为120,显然远大于本题的两顶点见最大距离

    {1,0,2,7,5,'X'},

    {4,2,0,'X',1,'X'},

    {'X',7,'X',0,3,2},

    {'X',5,1,3,0,6},

    {'X','X','X',2,6,0}

    };

    int n;                 // n : 顶点个数

    int s;                 // s : 源点(source)

    vector<bool> known;        // known : 各点是否知道最短路径

    vector<int> dist;        // dist : 源点s到各点的最短路径长

    vector<int> prev;        // prev : 各点最短路径的前一顶点

    void Dijkstra()            // 贪心算法(Greedy Algorithm)

    {

        known.assign(n, false);

        dist.assign(n, INT_MAX);

        prev.resize(n);            // 初始化knowndistprev

        dist[s] = 0;            // 初始化源点s到自身的路径长为0

        while(1)

        {

            int min = INT_MAX, v = s;

            for (int i = 0; i < n; ++i)

                if (!known[i] && min > dist[i])

                    min = dist[i], v = i;    // 寻找未知的最短路径长的顶点v

            if (min == INT_MAX) break;        // 如果找不到,退出;

            known[v] = true;                // 如果找到,将顶点v设为已知,

            for (int w = 0; w < n; ++w)        // 遍历所有v指向的顶点w

                if (!known[w] && map[v][w] < INT_MAX && dist[w] > dist[v] + map[v][w])

                    dist[w] = dist[v] + map[v][w], prev[w] = v;    // 调整顶点w的最短路径长dist和最短路径的前一顶点 prev

        }

    }

    void Print_SP(int v)

    {

         if (v != s) Print_SP(prev[v]);

         cout << v << " ";

    }

    int main()

    {

        n=6;

        s = 0;

        Dijkstra();

        copy(dist.begin(), dist.end(), ostream_iterator<int>(cout, " ")); cout << endl;

        for (int i = 0; i < n; ++i)

            if(dist[i] != INT_MAX)

            {

                cout << s << "->" << i << ": ";

                Print_SP(i);

                cout << endl;

            }

       

        system("pause");

        return 0;

    }

     

    运行结果

  • 相关阅读:
    R语言:提取路径中的文件名字符串(basename函数)
    课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)—— 0、学习目标
    numpy.squeeze()的用法
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 4、Logistic Regression with a Neural Network mindset
    Python numpy 中 keepdims 的含义
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 3、Python Basics with numpy (optional)
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 2、编程作业常见问题与答案(Programming Assignment FAQ)
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 0、学习目标
    课程一(Neural Networks and Deep Learning),第一周(Introduction to Deep Learning)—— 0、学习目标
    windows系统numpy的下载与安装教程
  • 原文地址:https://www.cnblogs.com/ituff/p/2858557.html
Copyright © 2011-2022 走看看