zoukankan      html  css  js  c++  java
  • 《算法导论》读书笔记之图论算法—Dijkstra 算法求最短路径

    自从打ACM以来也算是用Dijkstra算法来求最短路径了好久,现在就写一篇博客来介绍一下这个算法吧 :)

    Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。
    主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,
    但由于它遍历计算的节点很多,所以效率低。
    Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,比如数据结构、图论、运筹学等。

    首先,大家需要明确的是,Dijkstra算法是用来解决non-negative-weight的最短路程问题的

    如果图中存在负权图,可以尝试使用 Bellman-Ford 暴力法或者 SPFA 算法解决

    那么用它能来解决什么问题呢?

    我之前写过如下几篇博文

    1. 多个起点,一个终点,求从起点到终点的最短路(也可以理解成可以解决多点到多点的最短路)http://www.cnblogs.com/wushuaiyi/p/3647246.html
    2. 第k短路(与A*算法有关) http://www.cnblogs.com/wushuaiyi/p/3892970.html
    3. 临接表下Dijkstra实现模板以及带heap优化http://www.cnblogs.com/wushuaiyi/p/3714674.html

    下面来一个最容易理解的Dijkstra C++实现版本 (邻接矩阵):

     1 const int  MAXINT = 32767;
     2 const int MAXNUM = 10;
     3 int dist[MAXNUM];
     4 int prev[MAXNUM];
     5 
     6 int A[MAXUNM][MAXNUM];
     7 
     8 void Dijkstra(int v0)
     9 {
    10     bool S[MAXNUM];                                  // 判断是否已存入该点到S集合中
    11       int n=MAXNUM;
    12     for(int i=1; i<=n; ++i)
    13     {
    14         dist[i] = A[v0][i];
    15         S[i] = false;                                // 初始都未用过该点
    16         if(dist[i] == MAXINT)    
    17               prev[i] = -1;
    18         else 
    19               prev[i] = v0;
    20      }
    21      dist[v0] = 0;
    22      S[v0] = true;   
    23     for(int i=2; i<=n; i++)
    24     {
    25          int mindist = MAXINT;
    26          int u = v0;                               // 找出当前未使用的点j的dist[j]最小值
    27          for(int j=1; j<=n; ++j)
    28             if((!S[j]) && dist[j]<mindist)
    29             {
    30                   u = j;                             // u保存当前邻接点中距离最小的点的号码 
    31                   mindist = dist[j];
    32             }
    33          S[u] = true; 
    34          for(int j=1; j<=n; j++)
    35              if((!S[j]) && A[u][j]<MAXINT)
    36              {
    37                  if(dist[u] + A[u][j] < dist[j])     //在通过新加入的u点路径找到离v0点更短的路径  
    38                  {
    39                      dist[j] = dist[u] + A[u][j];    //更新dist 
    40                      prev[j] = u;                    //记录前驱顶点 
    41                   }
    42               }
    43      }
    44 }
    算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,
    第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,
    以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),
    第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
    在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。
    此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,
    是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

      


    算法实例

    先给出一个无向图

    下面的表格可以帮助大家理解算法

    资料来源:http://cnblogs.com/wushuaiyi

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

  • 相关阅读:
    Java核心技术 卷一 笔记四 库类的直接使用
    Java核心技术 卷一 笔记三 大数值及数组
    Java核心技术 卷一 笔记2 字符串的复制
    Java核心技术 卷一 笔记1
    修改css 样式后, hover事件 不生效
    修改 element ui input 输入框 样式不生效问题
    css3 计算属性
    Vue3 改动系列
    浏览器实现,向下滑动 鼠标滚轮,页面横向移动
    linux ceont0s7 vue 打包压缩图片 一直报错
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4553119.html
Copyright © 2011-2022 走看看