C++实现迪杰斯特拉(dijkstra)算法(最小生成树)

迪杰斯特拉(dijkstra)算法是单源最短路径问题的求解方法。参考链接:算法之迪杰斯特拉(dijkstra)非常详细介绍_PRML_MAN的博客-CSDN博客_迪杰斯特拉

使用上面的链接提供的图片进行测试

在这里插入图片描述

从v0(家)到v7(学校)的最短路径如下图所示 

 在这里插入图片描述

 以上图片的邻接矩阵如下所示:

    float G[][8] = {
     0,  4, 3, 10, -1, -1, -1, -1,
     4,  0,-1,  3,  8, -1, -1, -1,
     3, -1, 0,  5, -1, -1, 12, -1,
     10, 3, 5,  0,  3, 12, -1, -1,
     -1, 8,-1,  3,  0,  3, -1,  5,
     -1,-1,-1, 12,  3,  0, -1,  1,
     -1,-1,12, -1, -1, -1,  0,  2,
     -1,-1,-1, -1,  5,  2,  2,  0
    };

可以追溯路径的代码

#include <iostream>
#include <string>
#include <vector>

void dij_learn();//函数声明
void main() {
	dij_learn();
}

class node {//节点结构
public:
	int index;
	float way;
	std::vector<node*> childs;
};
node diji(float G[][8], int start, float end);//函数声明
node iterate_tree(node tree, int end, std::vector<node>* result);//函数声明
void dij_learn() {
	float G[][8] = {
	 0,  4, 3, 10, -1, -1, -1, -1,
	 4,  0,-1,  3,  8, -1, -1, -1,
	 3, -1, 0,  5, -1, -1, 12, -1,
	 10, 3, 5,  0,  3, 12, -1, -1,
	 -1, 8,-1,  3,  0,  3, -1,  5,
	 -1,-1,-1, 12,  3,  0, -1,  1,
	 -1,-1,12, -1, -1, -1,  0,  2,
	 -1,-1,-1, -1,  5,  2,  2,  0
	};
	diji(G, 0, 7);
}

node diji(float G[][8], int start, float end) {//迪杰斯特拉方法
	//G表示一个图,start和end表示起点和重点(序号从0开始)
	//G中-1代表不邻接

	//初始化start节点
	node start_n;
	start_n.index = start;
	start_n.way = 0;

	std::vector<node*> N;//用于存放已经访问过的节点
	N.push_back(&start_n);
	node* min_node_father = new node();

	std::vector<int> visit(sizeof(G), 0);
	visit[start] = 1;

	//vector<int> dis(sizeof(G), INT_MAX);//该变量用于存储最短路径值
	while (1) {
		int min_point_index = -1;
		float min_dis = INT_MAX;
		for (int i = 0; i < N.size(); i++) {//遍历当前队列所有点的邻接点
			//查询G,即获得点的邻接点信息
			float* L = G[N[i]->index];
			for (int j = 0; j < sizeof(L); j++) {
				if (L[j] == -1 || visit[j] == 1 || i == j) {//已访问或不邻接的点跳过
					continue;
				}
				if (L[j] + N[i]->way < min_dis) {//记录最短路径
					min_node_father = N[i];
					min_point_index = j;
					min_dis = L[j] + N[i]->way;
				}
			}
			if (if_findend) {
				break;
			}
		}
		if (min_point_index == -1) {//当无法选出最短路径节点时,表面图已经结束,或者无法再继续搜寻
			break;
		}
		node* min_n = new node;
		min_n->index = min_point_index;
		min_n->way = min_node_father->way + G[min_node_father->index][min_point_index];
		min_node_father->childs.push_back(min_n);
		visit[min_point_index] = 1;
		N.push_back(min_n);
		min_node_father = nullptr;
		if (if_findend) {
			break;
		}
	}
	std::vector<node>* result = new std::vector<node>;//获取从tree到end的最短路径,结果存储在result里面
	node ways = iterate_tree(*N[0], end,result);
	result->push_back(ways);//最后将起点存入路径中
	return ways;
}
node iterate_tree(node tree, int end, std::vector<node>* result) {//获取从tree到end的最短路径,结果存储在result里面
//遍历迪杰斯特拉生成树,tree就是开头,end就是目的地
	node n;
	node null_node; null_node.index = -1;

	if (tree.index == end) {
		return tree;
	}
	else if (tree.childs.size() == 0 || tree.index == -1) {
		return null_node;
	}
	for (int i = 0; i < tree.childs.size(); i++) {
		n = iterate_tree(*tree.childs[i], end, result);
		if (n.index == end) {
			result->push_back(n);
			return tree;
		}
		else if (n.index != -1) {
			result->push_back(n);
			return tree;
		}
	}
	return null_node;
}

运行结果:(从v0到v7)0-1-3-4-5-7,way存储的是从原点到各个节点的最短路径

 该算法在点云中的应用(计算近似测地线距离)

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值