Dijkstra算法的C++实现

来源:互联网 发布:服装尺码软件 编辑:程序博客网 时间:2024/05/01 06:17

引自:http://blog.csdn.net/doufei_ccst/article/details/7841311

对于该算法的实现思想网上已经有很多,所以这里只是简单介绍原理,重点在于实现代码。


Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),算法解决的是有向图中单个源点到其他顶点的最短路径问题。

举例来说,如果图中的顶点表示城市,而边上的权重表示著城市间开车行经的距离,Dijkstra 算法可以用来找

到两个城市之间的最短路径。

它的实现如下:

 Dijkstra 算法的输入包含了一个有权重的有向图 G,以及G中的一个来源顶点 S。我们以 表示 中所有顶点的集合,

以 表示中所有边的集合。(u, v) 表示从顶点 到 有路径相连,而边的权重则由权重函数 w: E → [0, 定义。

因此,w(u, v) 就是从顶点 到顶点 非负花费值(cost),边的花费可以想像成两个顶点之间的距离。
任两点间路径的花费值,就是该路径上所有边的花费值总和。

    已知有 V 中有顶点 及 tDijkstra 算法可以找到 到 的最低花费路径(例如,最短路径)。这个算法也可以在一个图中,

找到从一个顶点 到任何其他顶点的最短路径。

引用算法导论中的伪代码:
DIJKSTRA(G, w, s)
1  INITIALIZE-SINGLE-SOURCE(G, s)
2  S ← Ø
3  Q ← V[G]                                 //V*O1
4  while Q ≠ Ø
5      do u ← EXTRACT-MIN(Q)     //EXTRACT-MINV*OV),V*OlgV
6         S ← S ∪{u}
7         for each vertex v ∈ Adj[u]
8             do RELAX(u, v, w)       //松弛技术,E*O1),E*OlgV)。

好了,下面给出我自己的实现代码以及运行结果:

[cpp] view plaincopy
  1. //  
  2. //  main.cpp  
  3. //  testC++05  
  4. //  
  5. //  Created by fei dou on 12-8-7.  
  6. //  Copyright (c) 2012年 vrlab. All rights reserved.  
  7. //  
  8.   
  9. #include <iostream>  
  10. #include <iostream>  
  11. #include <vector>  
  12. #include <stack>  
  13. using namespace std;  
  14.   
  15.   
  16. int map[][5] = {                     //定义有向图  
  17.     {0, 10, INT_MAX, INT_MAX, 5},  
  18.     {INT_MAX, 0, 1, INT_MAX, 2},  
  19.     {INT_MAX, INT_MAX, 0, 4, INT_MAX},  
  20.     {7, INT_MAX, 6, 0, INT_MAX},  
  21.     {INT_MAX, 3, 9, 2, 0}  
  22. };  
  23.   
  24. void Dijkstra(  
  25.               const int numOfVertex,    /*节点数目*/  
  26.               const int startVertex,    /*源节点*/  
  27.               int (map)[][5],          /*有向图邻接矩阵*/  
  28.               int *distance,            /*各个节点到达源节点的距离*/  
  29.               int *prevVertex           /*各个节点的前一个节点*/  
  30.               )  
  31. {  
  32.     vector<bool> isInS;                 //是否已经在S集合中  
  33.     isInS.reserve(0);  
  34.     isInS.assign(numOfVertex, false);   //初始化,所有的节点都不在S集合中  
  35.       
  36.     /*初始化distance和prevVertex数组*/  
  37.     for(int i =0; i < numOfVertex; ++i)  
  38.     {  
  39.         distance[ i ] = map[ startVertex ][ i ];  
  40.         if(map[ startVertex ][ i ] < INT_MAX)  
  41.             prevVertex[ i ] = startVertex;  
  42.         else  
  43.             prevVertex[ i ] = -1;       //表示还不知道前一个节点是什么  
  44.     }  
  45.     prevVertex[ startVertex ] = -1;  
  46.       
  47.     /*开始使用贪心思想循环处理不在S集合中的每一个节点*/  
  48.     isInS[startVertex] = true;          //开始节点放入S集合中  
  49.       
  50.       
  51.     int u = startVertex;  
  52.       
  53.     for (int i = 1; i < numOfVertex; i ++)      //这里循环从1开始是因为开始节点已经存放在S中了,还有numOfVertex-1个节点要处理  
  54.     {  
  55.           
  56.         /*选择distance最小的一个节点*/  
  57.         int nextVertex = u;  
  58.         int tempDistance = INT_MAX;  
  59.         for(int j = 0; j < numOfVertex; ++j)  
  60.         {  
  61.             if((isInS[j] == false) && (distance[j] < tempDistance))//寻找不在S集合中的distance最小的节点  
  62.             {  
  63.                 nextVertex = j;  
  64.                 tempDistance = distance[j];  
  65.             }  
  66.         }  
  67.         isInS[nextVertex] = true;//放入S集合中  
  68.         u = nextVertex;//下一次寻找的开始节点  
  69.           
  70.           
  71.         /*更新distance*/  
  72.         for (int j =0; j < numOfVertex; j ++)  
  73.         {  
  74.             if (isInS[j] == false && map[u][j] < INT_MAX)  
  75.             {  
  76.                 int temp = distance[ u ] + map[ u ][ j ];  
  77.                 if (temp < distance[ j ])  
  78.                 {  
  79.                     distance[ j ] = temp;  
  80.                     prevVertex[ j ] = u;  
  81.                 }  
  82.             }  
  83.         }  
  84.     }  
  85.       
  86.       
  87.       
  88. }  
  89.   
  90.   
  91. int main (int argc, const char * argv[])  
  92. {  
  93.     int distance[5];  
  94.     int preVertex[5];  
  95.       
  96.     for (int i =0 ; i < 5; ++i )  
  97.     {  
  98.         Dijkstra(5, i, map, distance, preVertex);  
  99.          for(int j =0; j < 5; ++j)  
  100.          {  
  101.              int index = j;  
  102.              stack<int > trace;  
  103.              while (preVertex[index] != -1) {  
  104.                  trace.push(preVertex[index]);  
  105.                  index = preVertex[index];  
  106.              }  
  107.                
  108.              cout << "路径:";  
  109.              while (!trace.empty()) {  
  110.                  cout<<trace.top()<<" -- ";  
  111.                  trace.pop();  
  112.              }  
  113.              cout <<j;  
  114.              cout <<" 距离是:"<<distance[j]<<endl;  
  115.   
  116.                
  117.          }  
  118.     }  
  119.   
  120.     return 0;  
  121. }  
运行效果如下图:

0 0
原创粉丝点击