当前位置: 首页 > article >正文

图的最短路径算法

//最小起始边
void Dijkstra(const V& src, vector<W>& dist, vector<int>& pPath)  //有负权值会失效
{
	size_t srci = GetVertexIndex(src);
	size_t n = _vertexs.size();
	dist.resize(n, MAX_W);
	pPath.resize(n, -1);

	dist[srci] = 0;
	pPath[srci] = srci;

	vector<bool> S(n,false);//已经确定最短路径的顶点集合
	

	for(size_t j = 0;j<n ;j++)
	{
		//选最短路径的顶点更新其他路径

		int u = 0;
		W min = MAX_W;
		for (size_t i = 0; i < n; i++)
		{
			if (S[i] == false && dist[i] < min)
			{
				u = i;
				min = dist[i];
			}

		}
		S[u] = true;//更新u连接v srci->u  u->v  srci->v
		for (size_t v = 0; v < n ; v++)
		{
			if (S[v]==false &&_matrix[u][v] != MAX_W && dist[u] + _matrix[u][v] < dist[v])
			{
				dist[v] = dist[u] + _matrix[u][v];
				pPath[v] = u;
			}
		}
	}
}









void PrintShortPath(const V& src, const vector<W>& dist, const vector<int>& pPath)
{
	size_t srci = GetVertexIndex(src);
	size_t n = _vertexs.size();

	for (size_t i = 0; i < n; i++)
	{
		if (i != srci)
		{
			vector<int> path;//找出i顶点的路径
			size_t parent = i;
			while (parent != srci)
			{
				path.push_back(parent);
				parent = pPath[parent];
			}
			path.push_back(srci);
			reverse(path.begin(), path.end());

			for (auto e : path)
			{
				cout << _vertexs[e] << "->";
			}
			cout <<"权值和:"<< dist[i] << endl;
		}
	}
}










bool Bellman_ford(const V&src , vector<W>&dist , vector<int> & pPath)  //找终止边  解决不了负权回路
{
	size_t n = _vertexs.size();
	size_t srci = GetVertexIndex(src);

	dist.resize(n, MAX_W);//记录srci 其他顶点最短路径权值数组

	pPath.resize(n, -1); // 记录srci 其他顶点最短路径父顶点数组

	dist[srci] = W();//先更新srci->srci为缺省值

	for (size_t k = 0; k < n; k++)  //i->j暴力更新k次  总体最多更新n轮
	{
		bool updata = false;
		for (size_t i = 0; i < n; i++)
		{
			for (size_t j = 0; j < n; j++)
			{
				if (_matrix[i][j] != MAX_W && dist[i] + _matrix[i][j] < dist[j])
				{
					updata = true;
					dist[j] = dist[i] + _matrix[i][j];
					pPath[j] = i;
				}
			}
		}
		if (updata == false) //没更新就退出 不需要走了
		{
			break;
		}
	}

	for (size_t i = 0; i < n; i++) //还能更新就是带负权回路
	{
		for (size_t j = 0; j < n; j++)
		{
			if (_matrix[i][j] != MAX_W && dist[i] + _matrix[i][j] < dist[j])
			{
				return false;
			}
		}
	}
	return true;
}









void floyd( vector<vector<W>>& vvdist, vector<vector<int>>& vvpPath) //多源最短路径 任意两点
{
	size_t n = _vertexs.size();
	vvdist.resize(n);
	vvpPath.resize(n);

	for (size_t i = 0; i < n; i++)
	{
		vvdist[i].resize(n, MAX_W);
		vvpPath[i].resize(n, -1); // n行
	}

	//直接相连的边更新一下
	for (size_t i = 0; i < n; i++)
	{
		for (size_t j = 0; j < n; j++)
		{
			if (_matrix[i][j] != MAX_W)
			{
				vvdist[i][j] = _matrix[i][j];
				vvpPath[i][j] = i;
			}
			if (i == j)
			{
				vvdist[i][j] = W();
			}
		}
	}

	//最短路径的更新 i->j 中间可能经过k个顶点最多
	//把所有点都作为中间点 k作为中间点 是任意点 去更新i->j
	for (size_t k = 0; k < n; k++)
	{
		for (size_t i = 0; i < n; i++)
		{
			for (size_t j = 0; j < n; j++)
			{
				if (vvdist[i][k] != MAX_W && vvdist[k][j] != MAX_W && vvdist[i][k] + vvdist[k][j] < vvdist[i][j])//已经有路径
				{
					vvdist[i][j] = vvdist[i][k] + vvdist[k][j];

					//找跟j相连的结点
					//如果k直接和j相连 vvpath[k][j] = k
					//如果k不和j相连 k->..x->j  vvpath[k][j]=x
					vvpPath[i][j] = vvpPath[k][j];
				}
			}
		}
	}

	// 打印权值和路径矩阵观察数据
	for (size_t i = 0; i < n; ++i)
	{
		for (size_t j = 0; j < n; ++j)
		{
			if (vvdist[i][j] == MAX_W)
			{
				//cout << "*" << " ";
				printf("%3c", '*');
			}
			else
			{
				//cout << vvDist[i][j] << " ";
				printf("%3d", vvdist[i][j]);
			}
		}
		cout << endl;
	}
	cout << endl;

	for (size_t i = 0; i < n; ++i)
	{
		for (size_t j = 0; j < n; ++j)
		{
			//cout << vvParentPath[i][j] << " ";
			printf("%3d", vvpPath[i][j]);
		}
		cout << endl;
	}
	cout << "=================================" << endl;
}


http://www.kler.cn/news/340497.html

相关文章:

  • threads_created增加过大?
  • TLS 加密的原理和过程
  • C++实现字符串 trim,C++实现字符串split, C++如何分割字符串为数组,C++如何去除字符串两边的空格
  • (笔记)第三期书生·浦语大模型实战营(十一卷王场)–书生基础岛第3关---浦语提示词工程实践
  • 如何使用pymysql和psycopg2执行SQL语句
  • 使用XML实现MyBatis的基础操作
  • pandas的用法
  • Github界面学习
  • C++ 函数重载
  • 手动更换SSL证书教程及注意事项
  • 【论文阅读】AUTOREGRESSIVE ACTION SEQUENCE LEARNING FOR ROBOTIC MANIPULATION
  • 接着上一篇stp 实验继续
  • Http 协议和 RPC 协议有什么区别?
  • OpenAI .NET 库稳定版发布,支持 GPT-4o 并改进 API 功能
  • 逼近理论及应用精解【9】
  • 【优选算法】(第三十篇)
  • 详解JavaScript作为命名空间的函数
  • 腾讯云SDK项目管理
  • 图像数据增强库综述:10个强大图像增强工具对比与分析
  • Facebook 正式推出了一项专为 Z 世代设计的全新改版