最短路径寻优,Dijstra算法,附C++代码实现

最短路径寻优

(以下关于Dijstra的说明,是借用算法与数据结构的发帖说明、侵权即删)
原帖链接 最短路径寻优
在这里插入图片描述
如上图所示、如何寻求从 A 出发到 G 点的最短路径呢?
Dijstra算法就是要求出这个最短的路径;

让我们来演示一下迪杰斯特拉的详细过程:
	第1步,创建距离表。表中的Key是顶点名称,Value是从起点A到对应顶点的已知最短距离。
	但是,一开始我们并不知道A到其他顶点的最短距离是多少,Value默认是无限大:

在这里插入图片描述

第2步,遍历起点A,找到起点A的邻接顶点B和C。从A到B的距离是5,从A到C的距离是2。把这一信息刷新到距离表当中:

在这里插入图片描述

第3步,从距离表中找到从A出发距离最短的点,也就是顶点C。
第4步,遍历顶点C,找到顶点C的邻接顶点D和F(A已经遍历过,不需要考虑!!!!!!!!!!代码编写中就需要注意这一点)。
从C到D的距离是6,所以A到D的距离是2+6=8;从C到F的距离是8,所以从A到F的距离是2+8=10。把这一信息刷新到表中:

在这里插入图片描述

接下来重复第3步、第4步所做的操作:
第5步,也就是第3步的重复,从距离表中找到从A出发距离最短的点(C已经遍历过,不需要考虑),也就是顶点B。
第6步,也就是第4步的重复,遍历顶点B,找到顶点B的邻接顶点D和E(A已经遍历过,不需要考虑)。
从B到D的距离是1,所以A到D的距离是5+1=6,小于距离表中的8;从B到E的距离是6,所以从A到E的距离是5+6=11。把这一信息刷新到表中:

在这里插入图片描述

(在第6步,A到D的距离从8刷新到6,可以看出距离表所发挥的作用。
距离表通过迭代刷新,用新路径长度取代旧路径长度,最终可以得到从起点到其他顶点的最短距离)

第7步,从距离表中找到从A出发距离最短的点(B和C不用考虑),也就是顶点D。
第8步,遍历顶点D,找到顶点D的邻接顶点E和F。从D到E的距离是1,所以A到E的距离是6+1=7,小于距离表中的11;
从D到F的距离是2,所以从A到F的距离是6+2=8,小于距离表中的10。把这一信息刷新到表中:

在这里插入图片描述

第9步,从距离表中找到从A出发距离最短的点,也就是顶点E。
第10步,遍历顶点E,找到顶点E的邻接顶点G。从E到G的距离是7,所以A到G的距离是7+7=14。把这一信息刷新到表中:

在这里插入图片描述

第11步,从距离表中找到从A出发距离最短的点,也就是顶点F。
第10步,遍历顶点F,找到顶点F的邻接顶点G。从F到G的距离是3,所以A到G的距离是8+3=11,小于距离表中的14。把这一信息刷新到表中:

在这里插入图片描述

就这样,除终点以外的全部顶点都已经遍历完毕,距离表中存储的是从起点A到所有顶点的最短距离。显然,从A到G的最短距离是11。
(路径:A-B-D-F-G)

下面附上算法的C++实现

// dijstra.cpp : 
//寻求最短路径

#include "pch.h"
#include <iostream>
using namespace std;
typedef struct {
	char nextPointName;
	int  distance;
}NEXT_POINT;

typedef struct {
	int		curVaule;
	int		expandFlag;
	char	name;
	int		linkNum;
	NEXT_POINT  nextPoint[5];
	char	route[10] = {'A'};
}POINT;

POINT A = { 1000,0,'A' ,2,'B',5,'C',2};
POINT B = { 1000,0,'B' ,2,'D',1,'E',6};
POINT C = { 1000,0,'C' ,2,'D',6,'F',8};
POINT D = { 1000,0,'D' ,2,'E',1,'F',2};
POINT E = { 1000,0,'E' ,1,'G',7};
POINT F = { 1000,0,'F' ,1,'G',3};
POINT G = { 1000,0,'G' };


void Dijkstra(POINT* startPoint, POINT* endPoint, POINT* piontArray, int pointNum);
int main()
{
	POINT array[10] = { A,B,C,D,E,F,G };
	Dijkstra(&A,&G,array,7);
	
	cout << "	最短路径为	"<<G.route <<endl<<"	最短路径长度为	"<< G.curVaule  << endl;
	system("pause");
}

void Dijkstra(POINT* startPoint, POINT* endPoint, POINT* piontArray,int pointNum) {
	
	POINT unexpandPoint[20] = {0};
	
	int leftNum = pointNum;
	POINT expandPoint=*(startPoint);	
	int temp = 0;

	for (int i = 0; i < pointNum; ++i) {
		unexpandPoint[i] = piontArray[i];
	}
	unexpandPoint[0].curVaule = 0;

	while (1) {
		expandPoint = unexpandPoint[0];
		for (int i = 0; i < leftNum; ++i) {
			if (expandPoint.curVaule > unexpandPoint[i].curVaule) {
				expandPoint = unexpandPoint[i];
				temp = i;
			}
		}
		if (expandPoint.name == endPoint->name) {
			*(endPoint) = expandPoint;

			break;
		}	
		for (int i = 0; i < leftNum; ++i) {
			if (i > temp) {
				unexpandPoint[i - 1] = unexpandPoint[i];
			}	
		}
		temp = 0;
		leftNum--;
		for (int i = 0; i < expandPoint.linkNum; ++i) {	
			for (int j = 0; j < leftNum; ++j) {
				if (expandPoint.nextPoint[i].nextPointName == unexpandPoint[j].name) {
					if (unexpandPoint[j].curVaule > expandPoint.nextPoint[i].distance + expandPoint.curVaule) {
						unexpandPoint[j].curVaule = expandPoint.nextPoint[i].distance+ expandPoint.curVaule;					
					}
					if (unexpandPoint[j].curVaule > 1000) {
						unexpandPoint[j].curVaule -= 1000;
					}

					//路径更新
					for (int k = 0; k < 10; ++k) {
						unexpandPoint[j].route[k] = 0;								
					}
					for (int k = 0; k < 10; ++k) {
						if (expandPoint.route[k] != 0) {
							unexpandPoint[j].route[k] = expandPoint.route[k];
						}
						else {
							unexpandPoint[j].route[k] = unexpandPoint[j].name;
							break;
						}
					}							
				}			
			}					
		}		

	}
}

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用C++实现的Dijkstra算法代码示例: ```cpp #include <iostream> #include <vector> #include <queue> #include <climits> using namespace std; // 定义图的邻接矩阵表示 const int MAX = 100; vector<vector<int>> graph(MAX, vector<int>(MAX, 0)); // Dijkstra算法实现 void dijkstra(int start, int n) { vector<int> dist(n, INT_MAX); // 存储起始点到各个顶点的最短距离 vector<bool> visited(n, false); // 记录顶点是否已被访问 dist[start] = 0; // 起始点到自身的距离为0 for (int i = 0; i < n - 1; i++) { int minDist = INT_MAX; int minIndex = -1; // 找到当前未访问的顶点中距离起始点最近的顶点 for (int j = 0; j < n; j++) { if (!visited[j] && dist[j] < minDist) { minDist = dist[j]; minIndex = j; } } if (minIndex == -1) { break; } visited[minIndex] = true; // 更新最短距离 for (int j = 0; j < n; j++) { if (!visited[j] && graph[minIndex][j] != 0 && dist[minIndex] != INT_MAX && dist[minIndex] + graph[minIndex][j] < dist[j]) { dist[j] = dist[minIndex] + graph[minIndex][j]; } } } // 输出最短距离 cout << "最短路径长度:" << endl; for (int i = 0; i < n; i++) { cout << start << " 到 " << i << " 的最短距离为:" << dist[i] << endl; } } int main() { int n = 6; // 图中顶点的数量 // 初始化图的邻接矩阵 graph = { {0, 2, 0, 1, 0, 0}, {2, 0, 4, 0, 0, 0}, {0, 4, 0, 1, 3, 0}, {1, 0, 1, 0, 2, 0}, {0, 0, 3, 2, 0, 1}, {0, 0, 0, 0, 1, 0} }; int start = 0; // 起始点 dijkstra(start, n); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ah_yl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值