当前位置:   article > 正文

实验报告——基于Dijsktra算法的最短路径求解_用迪杰斯特拉算法求最短路径实验目的要求

用迪杰斯特拉算法求最短路径实验目的要求

一个不知名大学生,江湖人称菜狗
original author: jacky Li
Email : 3435673055@qq.com
Last edited: 2022.12.3

f65e6a2d969044f6a4c8a2f02066848e.jpeg

 

目录

一、实验目的

二、实验设备

三、实验内容

【问题描述】

【输入要求】

【输出要求】

【输入样例】

【输出样例】

四、实验提示

五、实验步骤

5.1

六、实验结果

6.1程序完成后关键源码及运行结果截图

七、实验总结

八:划重点参考代码

作者有言


 

课程名称:

数据结构

项目名称:

基于Dijsktra算法的最短路径求解

实验类型:

设计性实验

 

一、实验目的

1.掌握图的邻接矩阵表示法,掌握采用邻接矩阵表示法创建图的算法。

2.掌握求解最短路径的Dijsktra算法。


二、实验设备

装有Dev C++的计算机一台


三、实验内容

结合在头歌上已完成的实训任务进行填写,不限于下方要求。可自行补充算法分析、算法描述或流程图

 

【问题描述】

一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知。给定地图的一个起点城市和终点城市,利用Dijsktra算法求出起点到终点之间的最短路径。

【输入要求】

多组数据,每组数据有m+3行。第一行为两个整数n和m,分别代表城市个数n和路径条数m。第二行有n个字符,代表每个城市的名字。第三行到第m+2行每行有两个字符a和b和一个整数d,代表从城市a到城市b有一条距离为d的路。最后一行为两个字符,代表待求最短路径的城市起点和终点。当n和m都等于0时,输入结束。

【输出要求】

每组数据输出2行。第1行为一个整数,为从起点到终点之间最短路的长度。第2行为一串字符串,代表该路径。每两个字符之间用空格隔开。

【输入样例】

3 3

A B C

A B 1

B C 1

C A 3

A C

6 8

A B C D E F

A F 100

A E 30

A C 10

B C 5

C D 50

D E 20

E F 60

D F 10

A F

0 0

【输出样例】

2

A B C

60

A E D F

四、实验提示

此实验内容即为主教材算法6.10的扩展内容,算法6.10求出源点v0到图中其余所有顶点的最短路径。本实验要求求出一个指定起点到一个指定终点的最短路径。为了提高算法的效率,在求解时,可以加以判断,当已求得的终点为指定终点时,则可以终止求解,按要求输出相应结果。

五、实验步骤


5.1

此部分可包含解题思路、最初填写的但没有通过的程序,通过调试如何找到问题并做出改正,可粘贴调整规范的截图或可视化效果

 

六、实验结果

6.1程序完成后关键源码及运行结果截图

可以将最终完成的代码、运行结果或可视化效果在此展示。

  

 

七、实验总结

用简介、准确的语言描述本次实验重点解决了什么问题,学习了什么知识,自己掌握的如何等等



八:划重点参考代码

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <set>
  4. #include <vector>
  5. #include <map>
  6. #include <cmath>
  7. #include <cstring>
  8. #define IOS std::ios::sync_with_stdio(false)
  9. //#define YES cout << "YES" << endl
  10. //#define NO cout << "NO" << endl
  11. #define MAXLEN 20
  12. #define INFINE 99999
  13. using namespace std;
  14. typedef long long LL;
  15. typedef pair<LL, LL> PLL;
  16. const int N = 100;
  17. int n, m;
  18. typedef struct ArcNode //定义结构体
  19. {
  20. int adjvex;//邻接顶点下标
  21. int weight;//边的权值
  22. struct ArcNode *next; //指向下一个邻边节点指针
  23. }ArcNode;
  24. typedef struct
  25. {
  26. char vertex;//顶点标志
  27. ArcNode *firstedge;//保存第一个边节点指针
  28. }VertexNode;
  29. typedef struct
  30. {
  31. VertexNode adjlist[MAXLEN];//顶点数组
  32. int vexnum; //顶点数 
  33. int arcnum; //边数
  34. }AdjList;
  35. //创建邻接表
  36. AdjList *Created_Graph(AdjList *G)
  37. {
  38. int i, k, weight;
  39. ArcNode *s;
  40. char vex1, vex2; //顶点标志
  41. int n1, n2;//顶点下标
  42. G -> vexnum = n, G -> arcnum = m;
  43. for (i = 1; i <= G -> vexnum; i++)
  44. {
  45. cin >> G -> adjlist[i].vertex;
  46. G->adjlist[i].firstedge = NULL; //头节点指向为空;
  47. }
  48. for (k = 1; k <= G -> arcnum; k ++)
  49. {
  50. cin >> vex1 >> vex2;
  51. for (i = 1; i <= G -> vexnum; i ++)
  52. {
  53. if (G -> adjlist[i].vertex == vex1) n1 = i;
  54. if (G -> adjlist[i].vertex == vex2) n2 = i;
  55. }
  56. cin >> weight;
  57. s = new(ArcNode);
  58. s -> adjvex = n2, s -> weight = weight;
  59. s -> next = G -> adjlist[n1].firstedge;
  60. G -> adjlist[n1].firstedge = s;
  61. }
  62. return G;
  63. }
  64. //获取位置
  65. int getPosition(AdjList *G, char c)
  66. {
  67. int m;
  68. for (m = 1; m <= G -> vexnum; m ++)
  69. if (G -> adjlist[m].vertex == c)
  70. return m;
  71. return 1;
  72. }
  73. //获取G中边<start, end>的权值;若start和end不是连通的,则返回无穷大。
  74. int get_weight(AdjList *G, int start, int end)
  75. {
  76. ArcNode *node;
  77. if (start == end)
  78. return 0;
  79. node = G -> adjlist[start].firstedge;
  80. while (node != NULL)
  81. {
  82. if (end == node -> adjvex)
  83. return node -> weight;
  84. node = node -> next;
  85. }
  86. return INFINE;
  87. }
  88. /*
  89. * 迪杰斯特拉算法求最短路径。统计图(G)中"顶点vs"到其它各个顶点的最短路径。
  90. * 参数说明:
  91. * G -- 邻接图
  92. * vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
  93. * prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs""顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
  94. * dist -- 长度数组。即,dist[i]是"顶点vs""顶点i"的最短路径的长度。
  95. */
  96. void Dijkstra(AdjList *G, int vs, int prev[], int dist[], char over)
  97. {
  98. int i, j, k, t,m;
  99. int min;
  100. int tmp;
  101. int flag[INFINE]; // flag[i]=1表示"顶点vs""顶点i"的最短路径已成功获取。
  102. int path[MAXLEN][MAXLEN]={0};
  103. // 初始化
  104. for (i = 1; i <= G->vexnum; i++)
  105. {
  106. flag[i] = 0; // 顶点i的最短路径还没获取到。
  107. prev[i] = 0; // 顶点i的前驱顶点为0
  108. dist[i] = get_weight(G, vs, i); // 顶点i的最短路径为"顶点vs""顶点i"的权。
  109. path[i][0] = 0;
  110. }
  111. // 对"顶点vs"自身进行初始化
  112. flag[vs] = 1;
  113. dist[vs] = 0;
  114. path[vs][0] =1;
  115. // 遍历G->vexnum-1次;每次找出一个顶点的最短路径。
  116. for (i = 2; i <= G->vexnum; i++)
  117. {
  118. // 寻找当前最小的路径,即在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
  119. t = 0;
  120. min = INFINE;
  121. for (j = 1; j <= G->vexnum; j++)
  122. if (flag[j] == 0 && dist[j]<min)
  123. min = dist[j], k = j;
  124. // 标记"顶点k"为已经获取到最短路径
  125. flag[k] = 1;
  126. // 修正当前最短路径和前驱顶点,即当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"
  127. for (j = 1; j <= G->vexnum; j++)
  128. {
  129. tmp = get_weight(G, k, j);
  130. tmp = (tmp == INFINE ? INFINE : (min + tmp)); // 防止溢出
  131. if (flag[j] == 0 && (tmp < dist[j]))
  132. {
  133. dist[j] = tmp;
  134. prev[j] = k;
  135. path[j][t] = k;
  136. t++;
  137. }
  138. }
  139. }
  140. // 打印dijkstra最短路径的结果
  141. for (i = 1; i <= G -> vexnum; i++)
  142. {
  143. if(G -> adjlist[i].vertex == over)
  144. {
  145. cout << G -> adjlist[vs].vertex << "到" << over << "的最短路径长度为:" << dist[i];
  146. int showpath[MAXLEN] = {0};//存储最短路径上的节点
  147. for (m = 0; m < G->vexnum; m++)
  148. {
  149. if (path[i][m] == 0|| G->adjlist[path[i][m]].vertex == G->adjlist[vs].vertex) break;
  150. showpath[m] = path[i][m];
  151. }
  152. // //以下用于拼接路径
  153. if (dist[i]!= INFINE)
  154. {
  155. cout << endl << "当前最短路径为:" << G->adjlist[vs].vertex << "->";
  156. for (int q = MAXLEN - 1; q >= 0; q--)//存入的中间节点是【距离原点最远的顶点】依次递减存入的,故需逆序输出
  157. {
  158. if (showpath[q] == 0) continue;
  159. cout << G -> adjlist[showpath[q]].vertex << "->";
  160. }
  161. cout << G -> adjlist[i].vertex << endl;
  162. }
  163. }
  164. }
  165. }
  166. int main()
  167. {
  168. while(scanf("%d%d", &n, &m) != EOF)
  169. {
  170. AdjList G;
  171. char start1, over1;
  172. int ps;
  173. int dist[MAXLEN], prev[MAXLEN];
  174. AdjList *G2 = Created_Graph(&G);//创建表
  175. cin >> start1 >> over1;
  176. ps = getPosition(G2, start1);//获取起点位置
  177. Dijkstra(G2, ps, prev, dist, over1);
  178. }
  179. return 0;
  180. }

作者有言

如果需要代码,请私聊博主,博主看见回。

如果感觉博主讲的对您有用,请点个关注支持一下吧,将会对此类问题持续更新……

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号