Dijkstra算法求单源最短路径(一)

简介:

      本文实现的Dijkstra算法是最简单的方法,就是暴力搜索,其时间复杂度为O(V^2),后面会使用优先队列的方法,修改广度优先遍历来实现Dijkstra算法,这样的算法时间复杂度上会有所改善。

代码实例:

[c-sharp]  view plain copy print ?
  1. /* 
  2. 参考文献:http://baike.baidu.com/view/7839.htm 
  3. 算法流程: 
  4. 在以下说明中,s为源,w[u,v]为点u和v之间的边的长度,结果保存在dist[] 
  5. 1.初始化:源的距离dist[s]设为0,其他的点距离设为无穷大,同时把所有的点的状态设为没有扩展过。 
  6. 2.循环n-1次: 
  7.     在没有扩展过的点中取一距离最小的点u,并将其状态设为已扩展。 
  8.     对于每个与u相邻的点v,执行Relax(u,v),也就是说,如果dist[u]+w[u,v]<dist[v], 
  9.     那么把dist[v]更新成更短的距离dist[u]+w[u,v]。此时到点v的最短路径上,前一个节点即为u。 
  10. 3.结束。此时对于任意的u,dist[u]就是s到u的距离。 
  11. 直接实现:(本实例所采用的方法) 
  12. 最简单的实现方法就是,在每次循环中,再用一个循环找距离最短的点,然后用任意的方法更新与其相邻的边,时间复杂度显然为O(n2) 
  13. */  
  14. #include<fstream>  
  15. #include<cstring>  
  16. #include<iostream>  
  17. #include<stdlib.h>  
  18. using namespace std;  
  19. const int MaxNum=1000000; //边权最大值  
  20. int n; //节点数目  
  21. int dist[501]; //到节点1的最短路径值  
  22. bool state[501]; //节点被搜索过状态指示  
  23. int data[501][501]; //邻接矩阵  
  24. //查找权值最小的节点  
  25. int findmin()  
  26. {  
  27.     int minnode=0, min=MaxNum,i;  
  28.     for(i=1;i<=n;i++)  
  29.         if((dist[i]<min)&&(!state[i]))   
  30.         {  
  31.             min=dist[i];  
  32.             minnode=i;  
  33.         }  
  34.         return minnode;//如果minnode=0则表示没有找到最小节点  
  35. }  
  36. void Dijkstra()  
  37. {  
  38.     cout<<"输入定点数:"<<endl;  
  39.     cin>>n;//输入顶点数量  
  40.     //构造邻接矩阵,顶点到自身的距离是无穷大的。  
  41.     cout<<"输入邻接矩阵权值:"<<endl;  
  42.     for(int p=1; p<=n; p++)  
  43.         for(int q=1; q<=n; q++)  
  44.         {  
  45.             //in >> data[p][q];  
  46.             cin>>data[p][q];  
  47.             if (data[p][q]==0)   
  48.                 data[p][q]=MaxNum;  
  49.         }  
  50.     //初始化  
  51.     for(int i=1; i<=n; i++)  
  52.     {  
  53.         state[i]=0;//初始化,表示所有点都没有被扩展过  
  54.         dist[i]=data[1][i];//data[1][i]表示1为源点  
  55.     }  
  56.     state[1]=true;  
  57.     int done=1;  
  58.     while (done<n)//循环n-1次  
  59.     {  
  60.         int node=findmin();  
  61.         if (node!=0)  
  62.         {  
  63.             done++; //找到的点的数目加1  
  64.             state[node]=true//标记已经找到了从节点1到节点node的最短路径  
  65.             for(int i=1; i<=n; i++)//更新还没有找到的点的路径值  
  66.                 if ((dist[i]>dist[node]+data[node][i]) && (!state[i]))  
  67.                     dist[i]=dist[node]+data[node][i];  
  68.         }  
  69.         else  
  70.             break;  
  71.     }  
  72. }  
  73. int main()  
  74. {  
  75.     Dijkstra();   
  76.     for(int k=1; k<=n; k++)  
  77.     {  
  78.         if (dist[k]==MaxNum)  
  79.             cout<<-1;  
  80.         else  
  81.             cout<<dist[k];  
  82.         if(k==n)  
  83.             cout<<endl;//最后输出换行  
  84.         else  
  85.             cout<<" ";//没到最后则以空字符间隔  
  86.     }  
  87.     system("pause");  
  88.     return 0;  
  89. }  
  90. /* 
  91. 输入定点数: 
  92. 5 
  93. 输入邻接矩阵权值: 
  94. 0 4 2 0 0 
  95. 0 0 3 2 3 
  96. 0 1 0 4 5 
  97. 0 0 0 0 0 
  98. 0 0 0 1 0 
  99. */  

PS:2011-6-15

修改部分:

输出了过程中dist[i]的变化

[c-sharp]  view plain copy print ?
  1. #include<fstream>  
  2. #include<cstring>  
  3. #include<iostream>  
  4. #include<stdlib.h>  
  5. using namespace std;  
  6. const int MaxNum=1000000; //边权最大值  
  7. int n; //节点数目  
  8. int dist[501]; //到节点1的最短路径值  
  9. bool state[501]; //节点被搜索过状态指示  
  10. int data[501][501]; //邻接矩阵  
  11. //查找权值最小的节点  
  12. int findmin()  
  13. {  
  14.     int minnode=0, min=MaxNum,i;  
  15.     for(i=1;i<=n;i++)  
  16.         if((dist[i]<min)&&(!state[i]))   
  17.         {  
  18.             min=dist[i];  
  19.             minnode=i;  
  20.         }  
  21.         return minnode;//如果minnode=0则表示没有找到最小节点  
  22. }  
  23. void Dijkstra()  
  24. {  
  25.     cout<<"输入定点数:"<<endl;  
  26.     cin>>n;//输入顶点数量  
  27.     //构造邻接矩阵,顶点到自身的距离是无穷大的。  
  28.     cout<<"输入邻接矩阵权值:"<<endl;  
  29.     for(int p=1; p<=n; p++)  
  30.         for(int q=1; q<=n; q++)  
  31.         {  
  32.             //in >> data[p][q];  
  33.             cin>>data[p][q];  
  34.             if (data[p][q]==0)   
  35.                 data[p][q]=MaxNum;  
  36.         }  
  37.     //初始化  
  38.     for(int i=1; i<=n; i++)  
  39.     {  
  40.         state[i]=0;//初始化,表示所有点都没有被扩展过  
  41.         dist[i]=data[1][i];//data[1][i]表示1为源点  
  42.     }  
  43.     cout<<"输出过程中的dist[i]"<<endl;  
  44.     for(int i=1; i<=n; i++)  
  45.     {  
  46.         cout<<dist[i]<<" ";  
  47.     }  
  48.     cout<<endl;  
  49.     state[1]=true;  
  50.     int done=1;  
  51.     while (done<n)//循环n-1次  
  52.     {  
  53.         int node=findmin();  
  54.         if (node!=0)  
  55.         {  
  56.             done++; //找到的点的数目加1  
  57.             state[node]=true//标记已经找到了从节点1到节点node的最短路径  
  58.             for(int i=1; i<=n; i++)//更新还没有找到的点的路径值  
  59.                 if ((dist[i]>dist[node]+data[node][i]) && (!state[i]))  
  60.                     dist[i]=dist[node]+data[node][i];  
  61.             for(int j=1;j<=n;j++)  
  62.                 cout<<dist[j]<<" ";  
  63.             cout<<endl;     
  64.         }  
  65.         else  
  66.             break;  
  67.     }  
  68. }  
  69. int main()  
  70. {  
  71.     Dijkstra();   
  72.     cout<<"输出最终dist[i]的值,-1表示源点"<<endl;  
  73.     for(int k=1; k<=n; k++)  
  74.     {  
  75.         if (dist[k]==MaxNum)  
  76.             cout<<-1;  
  77.         else  
  78.             cout<<dist[k];  
  79.         if(k==n)  
  80.             cout<<endl;//最后输出换行  
  81.         else  
  82.             cout<<" ";//没到最后则以空字符间隔  
  83.     }  
  84.     system("pause");  
  85.     return 0;  
  86. }  
  87. /* 
  88. 输入定点数: 
  89. 5 
  90. 输入邻接矩阵权值: 
  91. 0 4 2 0 0 
  92. 0 0 3 2 3 
  93. 0 1 0 4 5 
  94. 0 0 0 0 0 
  95. 0 0 0 1 0 
  96. 输出过程中的dist[i] 
  97. 1000000 4 2 1000000 1000000 
  98. 1000000 3 2 6 7 
  99. 1000000 3 2 5 6 
  100. 1000000 3 2 5 6 
  101. 1000000 3 2 5 6 
  102. 输出最终dist[i]的值,-1表示源点 
  103. -1 3 2 5 6 
  104. 请按任意键继续. . . 
  105. */  
 

Dijkstra算法求单源最短路径,其实相当于是从一个源点S出发,找出从S出发可达的所有其他点的最短路径。

因此分以下几步完成:

1.dist[i]用于标记从s到i的最短路径,初始化是只有dist[s]=0,其他dist[i]=maxWeitht,表示权值无穷大

2.因为源点已经找到,还需要遍历剩余的V-1个点来找寻最短路径。

3.从dist[i]中找寻i点没有被访问且dist最小的值作为下一个顶点minnode。

4.如果dist[minnode]的值加上其可达顶点j的边上的值小于dist[j]的值,则更新dist[j],表明j的前序节点是minnode。

 




本文转自xwdreamer博客园博客,原文链接:http://www.cnblogs.com/xwdreamer/archive/2011/06/13/2297004.html,如需转载请自行联系原作者


目录
相关文章
|
2月前
|
人工智能 算法 数据可视化
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-2
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-2
199 0
|
3月前
|
算法
最短路之Dijkstra算法
最短路之Dijkstra算法
24 0
|
2月前
|
存储 人工智能 算法
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-1
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-1
69 0
|
7天前
|
算法 定位技术 Windows
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
12 4
|
1月前
|
算法
关于Dijkstra算法
关于Dijkstra算法
|
1月前
|
人工智能 算法 Java
【算法设计与分析】— —单源最短路径的贪心算法
【算法设计与分析】— —单源最短路径的贪心算法
32 0
|
3月前
|
算法
bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图
bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图
22 0
|
3月前
|
算法
leetcode-675:为高尔夫比赛砍树 (最短路径算法bfs,dijkstra,A*)
leetcode-675:为高尔夫比赛砍树 (最短路径算法bfs,dijkstra,A*)
31 0
|
30天前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真

热门文章

最新文章