有向图中单个源点到终点的最短路径--Dijkstra算法与实现
来源:互联网 发布:展示实时数据 时间轴 编辑:程序博客网 时间:2024/05/14 10:53
1、Dijkstra算法能够解决有向图中单个源点到另一终点的最短路径问题,它的算法过程如下:
1)用矩阵graph[]N[N](N为图中节点个数)表示带权的有向图G。若图中两个节点vi和vj是连通的,则graph[i][j]表示这两个节点之间边的权值;若两节点vi和vj不是连通的,则graph[i][j] = -1.
2)设S为从某点start_vec开始的最短路径path的终点集合,初始状态时,集合S中只有起始节点start_vec.设从起始节点start_vec到其余节点vi的最短路径长度为D[i]. 设剩余节点集合remanderLis,它表示未被选中的剩余节点,初始状态remanderLis 包含除起始节点start_vec之外图中任一节点。
3)对于非起始节点vi,初始化D[i] = graph[start_vec][i].
4)从remanderLis中选择一个节点,该节点是由起始节点经过当前已选中节点能够到达的节点中路径最短的节点,方法是比较当前的D数组D[j],从中选出最小的值D[j]且满足S中没有节点vj. 设选中的节点为min_vec, 将min_vec加入集合S中,并从集合remanderLis中删除节点min_vec.
5)修改从起始节点start_vec到任一剩余节点vk(集合remanderLis)的最短路径长度D[k]。若节点vk与min_vec之间有边,则视情况更新D[k],若D[k] == -1,即start_vec到vk没有边,D[k] = D[min_vec] + graph[min_vec][k];若D[k] != -1,则判段 D[k] = min{D[k], D[min_vec] + graph[min_vec][k]};
6)重复4到5过程,直到remanderLis集合为空。
2、下面给出图片说明(参考别人的)
从运算过程表中,我们可知v0到其余个点的最短路径,如下图
3、下面给出代码实现,我们知道Dijkstra算法肯定要输出源点到终点的路径,下面的算法中将会实现,简单说明就是在每次更新D[K]的时候更新数组pathArr,pathArr[k]用于存储由起始节点到节点vk最短路径上vk的上一个节点,当从起始节点到终点的路径过程中,每一个非起始节点都会存储它的上一个节点,所以只要从终点节点开始,遍历pathArr数组就可以找到从起始节点到终点的路径。本算法实现还有一个特殊的地方是采用-1来表示两个节点之间无边,你可能会好奇这样设置,到时找最小边的时候怎么办,任何有边的两点之间的权值都会大于-1,这能行吗?答案肯定的,下面的算法实现中会展现出来。好了,no bb, show you code.
#include <iostream>#include <list>#include <vector>#include <stack>#include <climits>using namespace std;#define N 6int graph[N][N] = /*{-1, -1, 10, -1, 30, 100, -1, -1, 5, -1, -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, -1, 20, -1, 60, -1, -1, -1, -1, -1, -1 };*/ { -1, 10, 12, -1, -1, -1, -1, -1, -1, 16, 25, -1, 4, 3, -1, 12, -1, 8, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 10, -1 };void dijkstra_algorithm(int graphArcs[][N], int start_vec, int end_vec){ int D[N] = {0}; //从起始点到其他点的最短路径,初始化为0 int selectedVecs[N] = {0}; selectedVecs[start_vec] = 1; //开始只有起始节点被选中,其他节点未被选中 vector<int> pathVecs; //在起始点到终点的最短路径过程中,vector[i]存储节点i的上一个节点 list<int> remanderLis; //剩余的节点集合 int i; for(i = 0; i < N; i++) { if(i == start_vec) continue; remanderLis.push_back(i); D[i] = graphArcs[start_vec][i]; //初始情况下初始节点到其他节点的最短路径长度 //cout << D[i] << " "; pathVecs.push_back(start_vec); //初始时候,将每个节点的上一个节点初始化为起始节点 } //cout << endl; while(!remanderLis.empty()) //没有剩余节点后或找到终点路径,则退出循环 { int j, minVec; unsigned int minArc = UINT_MAX; //这里定义无符号整形的作用是方便和-1比较,无符号整数 < -1 for(j = 0; j < N; j++) //从未被选中的剩余节点中,找出距离起始节点最近的节点 { if(selectedVecs[j] != 0) continue; if(minArc > D[j]) //当D[j]=-1时,表示节点j与起始点之间没有路径,且无符号整形与-1比较时,-1更大 { minArc = D[j]; minVec = j; } } if(selectedVecs[minVec] == 0) { selectedVecs[minVec] = 1; //在未被选中的点中距离起始节点最近的点将被选中 remanderLis.remove(minVec); //删除已经被选中的节点 } if(selectedVecs[end_vec] == 1) //若选中了end_vec,则退出循环 break; //选人新节点后,更新D[]数组 for(j = 0; j < N; j++) { if(selectedVecs[j] != 0) continue; //已被选中节点则跳过 if(graphArcs[minVec][j] != -1) //选中节点和各个节点直接有路径 { if(D[j] == -1) //起始节点到节点j没有路径 D[j] = D[minVec] + graphArcs[minVec][j]; else if(D[j] > D[minVec] + graphArcs[minVec][j]) D[j] = D[minVec] + graphArcs[minVec][j]; pathVecs[j] = minVec; } } } if(D[end_vec] == -1) { cout << "sorry, can't find the path from " << start_vec << " to " << end_vec << endl; return; } cout << "the path length from " << start_vec << " to " << end_vec << " is: " << D[end_vec] << endl; cout << "the path form " << start_vec << " to " << end_vec << " is: "; //vector<int>::iterator iter = pathVecs.rbegin(); stack<int> pathS; pathS.push(end_vec); i = end_vec; do { pathS.push(pathVecs[i]); i = pathVecs[i]; }while(i != start_vec); while(!pathS.empty()) { cout << pathS.top() << " "; pathS.pop(); }}int main(){ dijkstra_algorithm(graph, 0, 4); return 0;}
运行结果如下:
是不是挺简单的。
- 有向图中单个源点到终点的最短路径--Dijkstra算法与实现
- Dijkstra算法--有向图的源点到其他顶点的最短路径(连接矩阵、邻接矩阵两种方式)
- 单源点最短路径Dijkstra算法的JAVA实现
- 单源点最短路径Dijkstra算法的JAVA实现
- Dijkstra算法实现从一个源点到其他各点的最短路径
- 有向加权图的最短路径算法-Dijkstra
- 有向图某顶点到其他顶点最短路径的C程序实现代码(Dijkstra算法)
- 数据结构之有向网邻接矩阵Dijkstra实现源点至其余各顶点最短路径
- 图的最短路径(三)-单源点最短路径(Dijkstra算法)
- 单源点最短路径算法的设计与实现
- 单源点最短路径----Dijkstra算法
- 单源点最短路径(dijkstra算法)
- 图论-有向带权图的最短路径(Dijkstra)算法
- 单源点最短路径的Dijkstra算法
- Dijkstra最短路径算法(针对加权有向图)
- 单源点最短路径Dijkstra的java实现
- 用Java实现Dijkstra输出指定起点到终点的最短路径
- CQOI 1163 有向图的单源点最短路径
- FreeMarker 指令
- 库编译
- HDU-1863 畅通工程
- 北京-IT技术狗-顾名思义 解释一下当时随手写下这个名字
- Codeforces Round #201 (Div. 2) 347C Alice and Bob(脑洞)
- 有向图中单个源点到终点的最短路径--Dijkstra算法与实现
- muduo网络库源码学习————原子性操作Atomic.h
- 九度OJ 题目1130:日志排序
- JSP页面的五种跳转方法
- iOS 代理 协议
- swift学习之路-数组
- xamarin ios XibFree LinearLayout
- Nginx配置Https
- QT的信号与槽机制介绍