最短経路(フロイドアルゴリズム、フロイドアルゴリズム、マルチソース最短経路)

アルゴリズムのアイデア:最初は、頂点間の最短経路は隣接行列の値です。頂点が追加されるたびに、他の開始点が頂点を通過して残りの頂点に到達し、最短経路を取得できるかどうかが判断されます。以前よりも短くなっています。見つかった場合は、最短パスと重みの合計を更新します
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

アルゴリズムの擬似コード

ここに画像の説明を挿入

コードの実装と関連するコードコメント

#include<iostream>
using namespace std;
#define Max 10//最大顶点数
#define MANY 65535
class Graph
{
    
    
private:
	int verNum;//顶点个数
	int arcNum;//边的个数
public:
	int ver[Max];//顶点数组
	int arc[Max][Max];//网图的邻接矩阵
public:
	Graph(int v[], int n, int e);
	int getVernum()
	{
    
    
		return verNum;
	}
	int getArcnum()
	{
    
    
		return arcNum;
	}

};
Graph::Graph(int v[], int n, int e)
{
    
    
	verNum = n;
	arcNum = e;
	for (int i = 0; i < verNum; i++)
		ver[i] = v[i];
	for (int i = 0; i < verNum; i++)
	{
    
    
		for (int j = 0; j < verNum; j++)
		{
    
    
			if (i == j)
			{
    
    
				arc[i][j] = 0;
			}
			else {
    
    
				arc[i][j] = MANY;
			}
		}
	}
	cout << "请输入每条边依附的两个顶点和权值:" << endl;
	int vi = 0, vj = 0, k = 0;
	for (int i = 0; i < arcNum/2; i++)
	{
    
    
		cin >> vi >> vj >> k;
		arc[vi][vj] = k;
		arc[vj][vi] = k;
	}
}
//佛洛伊德算法:最短路径P数组  最短路径长度d数组
void Shorttestpath_Floyd(Graph G, int(*p)[Max], int(*d)[Max])
{
    
    
	//初始化最短路径数组p和最短路径长度数组d
	for (int i = 0; i < G.getVernum(); i++)
	{
    
    
		for (int j = 0;j < G.getVernum(); j++)
		{
    
    
			//最短路径长度一开始就是邻接矩阵中记录各顶点不通过其他顶点所能到达其他顶点的距离
			d[i][j] = G.arc[i][j];
			//初始化时:0---1的最短路径就是0---1,0---2的最短路径就是0----2
			p[i][j]=j;
		}
	}
	//外层循环,每一次加入一个新顶点,例如:先加入v0看是否产生最优解,再挨个加入剩余顶点,每一次都查看是否产生最优解
	for (int i = 0; i < G.getVernum(); i++)
	{
    
    
		//两重内层循环遍历最短路径长度的数组
		for (int j = 0; j < G.getVernum(); j++)
		{
    
    
			for (int k = 0; k < G.getVernum(); k++)
			{
    
    
				//例如初始时d[0][2]=1表示0-->2的最短距离为1,加入第二个节点1后,此时d[0][1]+d[1][2]=7
				//表示0---1----2的距离为7,比当前存储的最短路径长度长,因此不做更新
				if (d[j][k] > d[j][i] + d[i][k])
				{
    
    
					//满足条件就更新
					d[j][k] = d[j][i] + d[i][k];
					//如果加入节点1后,0---1---2的距离为2,而没有加入前最短距离为7,那么此时更新最短路径
					//把之前p[0][2]=2,表示通过0可以直接到达2,不需要经过其他顶点
					//把p[0][2]=p[0][1]=1,从而去查找p[1][2]查看1--->2是否还需要经过其他顶点
					//表示0---2需要经过顶点1,但是我们在最后输出最短路径的时候,还需要去寻找1--->2是否还需要经过其他顶点
					p[j][k] = p[j][i];
				}
			 }
		}
	}
}
//打印最短路径
void display(Graph g, int(*p)[Max],int(*d)[Max])
{
    
    
	//外层循环是每次循环求出一个顶点的最短路径
	for (int i = 0; i < g.getVernum(); i++)
	{
    
    
	      //内存循环负责求出当前顶点的最短路径
		//p[i][j]是为了求出当前顶点i到剩余出i之外的顶点的最短路径
		for (int j = i+1; j < g.getVernum(); j++)
		{
    
    
			cout << i << "->" << j << "的最短路径长度:" << d[i][j] << endl;
			cout << "最短路径:";
			int k = p[i][j];//获得第一个路径顶点的下标
			//打印当前最短路径的起点
			cout << i;
			//如果打印的不是终点
			while (k != j)
			{
    
    
				//打印起点到达终点的过程中所有经过的顶点
				cout << "->" << k;
				k = p[k][j];//获得下一个路径顶点的下标
			}
			//打印终点j
			cout << "->" << j << endl;
		}
	}
}
//测试----------------------
void test()
{
    
    
	int v[3] = {
    
     0,1,2 };//顶点数组
	Graph g(v, 3, 6);//3个顶点连通网图
	cout << "打印邻接矩阵" << endl;
	for (int i = 0; i < g.getVernum(); i++)
	{
    
    
		for (int j = 0; j < g.getVernum(); j++)
		{
    
    
			cout << g.arc[i][j]<<"\t";
		}
		cout << endl;
	}
	//最短路径数组
	int minPath[Max][Max] = {
    
     0 };
	//最短路径长度数组
	int minLen[Max][Max] = {
    
     0 };
	Shorttestpath_Floyd(g, minPath, minLen);
	cout << "打印最短路径" << endl;
	display(g, minPath, minLen);
}
int main()
{
    
    
	test();
	system("pause");
	return 0;
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_53157173/article/details/115255509