图的最短路径dijkstra算法
想法是这样的:
1. 最开始要建立4个list,分别存储
a. 所有的Vertex: allVertex[]
b. 一个空的Vertex list: emptyVertex[]
c. 一个前缀表 previous list(用来回溯路径用): previous[]
d. 一个表示最短距离的表(就是表示某个点与0点的最短距离):
前两个list是用来辅助操作的,后2个表则是输出,通过后2个表我们能得到想要的一切结果。
因此我们的任务其实就是,最终把c。d两个表填充完毕即可。
2. 我们要做一个循环,循环次数为VertexMax次,因为如果是连通图,每次循环都能处理一个Vertex。
3. 第一次循环前我们把start这个vertex从allVertex表,移动到emptyVertex表。
4. 这样我们就需要遍历,与empty表所有vertex关联的每一条line。找出这些line中最短的一条。
5. 找到最短的这条line之后,更新一下previous表,previous[line->end] = start; 然后更新一下distances表, (distances[line->end]) 同 (distances[start] + line->weight)取最小值
6. 然后,line->end作为新的start,重新进入循环。。重复3-5步即可。
#include <iostream>
using namespace std;const int MAX_VERTEX = 5;//图的顶点数
const int MAX_INT = 0x7fffffff;//4字节的整数
const int MIN_INT = 0xffffffff;//4字节的整数
enum Kind{NG, DG};//无向图,有向图
Kind k = NG;//图的种类
int graph[MAX_VERTEX][MAX_VERTEX];//图
int emptyVertex[MAX_VERTEX];//空的Vertex集合
int allVertex[MAX_VERTEX];//当前Vertex集合
int previous[MAX_VERTEX];//前缀
int distances[MAX_VERTEX];//distancevoid printGraph(){//打印图cout<<"-----------begin-------------"<<endl;for(int i = 0; i < MAX_VERTEX; i++){for(int j = 0; j < MAX_VERTEX; j++){if(graph[i][j] < MAX_INT){cout<<graph[i][j]<<"\t";}else{cout<<"∞\t";}}cout<<"\n\v";}cout<<"-----------end-------------"<<endl;
}void printArr(int *arr, int len){//打印数组for(int i = 0; i < len; i++){if(arr[i] >= MAX_INT){cout<<"∞\t";}else{cout<<arr[i]<<"\t";}}cout<<endl;
}void printSituation(){//打印整个结构的各个数据部分。cout<<"[[======================================"<<endl;//cout<<"graph:\n";//printGraph();cout<<"allVertex:\n";printArr(allVertex, MAX_VERTEX);cout<<"emptyVertex:\n";printArr(emptyVertex, MAX_VERTEX);cout<<"previous:\n";printArr(previous, MAX_VERTEX);cout<<"distances:\n";printArr(distances, MAX_VERTEX);cout<<"======================================]]"<<endl;
}void init(){//初始化for(int i = 0; i < MAX_VERTEX; i++){emptyVertex[i] = MAX_INT;allVertex[i] = i;previous[i] = MAX_INT;distances[i] = MAX_INT;for(int j = 0; j < MAX_VERTEX; j++){graph[i][j] = MAX_INT;}}distances[0] = 0;
}void addLine(int start, int end, int weight){//增加一条lineif(start >= MAX_VERTEX || end >= MAX_VERTEX) return;graph[start][end] = weight;if(k == NG){graph[end][start] = weight;}
}void rmLine(int start, int end){//移除一条lineif(start >= MAX_VERTEX || end >= MAX_VERTEX) return;graph[start][end] = MAX_INT;if(k == NG){graph[end][start] = MAX_INT;}
}void dijkstra(){int start = 0;int emptyI = 0;//emptyVertex数组的下标int numHandled = 0;//每次循环都能处理一个vertex,因此需要循环MAX_VERTEX次。while(numHandled < MAX_VERTEX){//1. 把start从allVertex中取出,放入emptyVertex中emptyVertex[emptyI++] = allVertex[start];allVertex[start] = MAX_INT;//2. 找出 已经加入到 empty中的所有点上 的所有的line, 选出其中最短的一条,其end点作为下一次访问的起始点。//3. 根据这些line重新计算distances, 更新distances表--同时更新前缀表,前缀表是随着distances表变化的。int shortestWeight = MAX_INT;int shortestEnd = MIN_INT;for(int j = 0; j < MAX_VERTEX; j++){int currentStart = emptyVertex[j];if(currentStart < MAX_INT){//每一个在empty中的vertex都必须参加比较。在所有的这些vertex中关联的line中选一条 end 值不在empty中的最短的line。for(int i = 0; i < MAX_VERTEX; i++){//i值表示 (currentStart -> i) 这条 line 的 end值if(graph[currentStart][i] >= MAX_INT) {//如果这条line不存在,搜索下一条continue;}else{if(allVertex[i] != MAX_INT && shortestWeight > graph[currentStart][i]){//并且这条line不能是计算过的。如果合法,则比较当前最小的weight。shortestWeight = graph[currentStart][i];//选中这条line。shortestEnd = i;//记住这条line。if(distances[i] >= MAX_INT){//调整distances和previous.distances[i] = graph[currentStart][i] + distances[currentStart];previous[i] = currentStart;}else{if(distances[currentStart] + graph[currentStart][i] < distances[i]){distances[i] = distances[currentStart] + graph[currentStart][i];previous[i] = currentStart;}}}}}}}//4. 把最短的line的end作为新的start重新循环,if(shortestEnd == MIN_INT){cout<<"error!! shortestEnd == MIN_INT"<<endl;}else{cout<<"&&shortest line "<<shortestEnd<<", shortestWeight = "<<shortestWeight<<endl;start = shortestEnd;}//5. numHandled++numHandled++;printSituation();}
}int main(){init();/*addLine(0, 1, 5);addLine(1, 2, 7);addLine(1, 4, 5);addLine(2, 3, 8);addLine(2, 4, 9);addLine(2, 5, 7);addLine(3, 5, 5);addLine(4, 5, 15);addLine(4, 6, 6);addLine(5, 6, 8);addLine(5, 7, 9);addLine(6, 7, 11);*/k = DG;addLine(0, 1, 10);addLine(0, 3, 30);addLine(0, 4, 100);addLine(1, 2, 50);addLine(2, 4, 10);addLine(3, 2, 20);addLine(3, 4, 60);dijkstra();
}
。。。
图的最短路径dijkstra算法相关推荐
- python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- 【数据结构】图(最短路径Dijkstra算法)的JAVA代码实现
最短路径的概念 最短路径的问题是比较典型的应用问题.在图中,确定了起始点和终点之后,一般情况下都可以有很多条路径来连接两者.而边或弧的权值最小的那一条路径就称为两点之间的最短路径,路径上的第一个顶点为 ...
- 三牛三虎过河问题--图的最短路径dijkstra算法--简单的Python实现
问题:三头牛三只虎要过河,船需要一只动物来划,另外至多还能载一物,而只有一头牛和一只虎会划船,并且当虎的数量多于牛的数量时,虎要吃牛,请设计一个安全渡河方案,并使渡河次数尽量少. 我们用一个数组来表示 ...
- c++ 遍历所有点且距离最短_C/C++ 图的最短路径 Dijkstra 算法
作者:小石王 链接:https://www.cnblogs.com/xiaoshiwang/p/9442391.html 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最 ...
- 最短路径-Dijkstra算法与Floyd算法
最短路径-Dijkstra算法与Floyd算法 原文:https://www.cnblogs.com/smile233/p/8303673.html 一.最短路径 ①在非网图中,最短路径是指两顶点之间 ...
- 最短路径——Dijkstra算法以及二叉堆优化(含证明)
一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...
- 使用邻接矩阵实现有向图最短路径Dijkstra算法
题目描述: 用邻接矩阵存储有向图,实现最短路径Dijkstra算法,图中边的权值为整型,顶点个数少于10个. 输入描述 首先输入图中顶点个数和边的条数: 再输入顶点的信息(字符型): 再输入各边及其权 ...
- 最短路径——Dijkstra算法与Floyd算法
最短路径 Dijkstra算法 C语言代码实现 代码解析 Floyd算法 算法解析 C语言代码实现 最短路径问题 最短路径问题是我们经常会面临的一种决策问题.在图论中,非网图(边没有权值)的最短路径就 ...
- 分支限界法:单源最短路径--dijkstra算法
单源最短路径–dijkstra算法 前面已经多次介绍过dijkstra算法是贪心算法,是动态规划,实际上可以从分支限界的角度来理解: 分支限界法 分支限界法,实际上就是回溯法,一般意义的回溯法是基于深 ...
最新文章
- python数据库gui_从python数据库在gui上打印数据
- QT+OpenCV照片动画风格转换
- kafka修改分区数_大数据技术:解析SparkStreaming和Kafka集成的两种方式
- Python判断一个字符串是否包含某个指定的字符串
- transform你不知道的那些事
- ASP.NET登录以及注册
- 面向对象 封装 集成 特性
- pytorch FC_regression
- [C#源码] 微信跳一跳POST修改分数漏洞
- 简单的时间间隔调度任务
- 冒泡排序(数组排序不用Array.Sort)
- SQL server中关于年月日周的添加
- python购物车----运维开发初学
- 英伟达驱动更新记录_手把手教你如何通过NVIDIA(英伟达显卡)官网及时更新升级显卡驱动程序版本-网络教程与技术
-亦是美网络...
- php laypage,LayUI分页和LayUI laypage分页区别详解
- VOLTE信令流程-IMS注册篇(五)
- 微信小程序开发 uniapp【bug修复】点击事件 传值 数据结构错误 $orig
- 【Python机器学习及实践】实战篇:泰坦尼克号罹难乘客预测
- mysql workbench pk_mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI_MySQL - numeric
- 今日头条测试开发实习生面试