最短路径问题

1.dijkstar算法(迪杰斯特拉算法)


 dijkstar是用来计算图中单源最短路径问题,即算出从图中某一结点出发到其它结点的最短路径,也是基于贪心策略的算法。它每次选择图中的已经找到最小路径的顶点选择一条到达没有找到顶点的最小路径加入集合中。
 dijkstar算法最的应用场所很多,比如在网络通信中,在网络层采用ospf协议进行ip数据包传输,每个路由器记录自己的到邻居的代价信息,这样可以把整个ospf区域网抽象成为一张图,采用dijkstar算法就可以找到代价最小的路由路径。

 现在我们来看dijkstar算法是怎样执行的,下面是一个简单图结构,我们演示如何从v1找到其它顶点的最短路径。
最短路径问题_第1张图片

上图的邻接矩阵为:

1 2 3 4 5
1 0 10 5
2 0 1 2
3 0 4
4 7 6 0
5 3 9 2 0

dijkstar算法需要维护一个dist 和 一个path数组,同时需要一个辅助数组set,具体用法请集合代码注释理解
算法开始 初始化dist数组为矩阵的第一行,算法中用99999代替无穷大。初始化path的值为0;
初始化set数组的值为-1;

然后从dist中找到非零的最小值,并且判断最小值达到的顶点是否在集合s中,若在,则不加入s
,若不在则加入s,置s[i]的值为1表示加入。

然后根据新加入的顶点,判断有没有更小路径,然后更新dist和path数组
最短路径问题_第2张图片

然后重复执行,知道所有顶点加入到了集合S中,求解过程如下
最短路径问题_第3张图片
最短路径问题_第4张图片

算法执行过程状态如下:
最短路径问题_第5张图片

这里是代码:

//在这里,我们采用邻接矩阵的方式存储图

#include
#include
#include

using namespace std;

#define MAX 5
#define MAXCOST 99999 //最大权值 

typedef int Graph;

//打印数组信息 
void print_arr(string arr_name,int a[] ,int n){
	cout<

1.Floyd算法(弗洛伊德算法)

 floyd算法是用来求多源最短路径的算法,即在一个图中任意点到其他点的最短路径可以用floyd算法求出。Floyd是一个基于动态规划思想的算法,它的每一次迭代都是基于前一次的计算。
Floyd 算法的基本思想是:递推产生一个n 阶方阵序列A(-1),A¹,A²,.....,A(k)。其中A(k)[i][j]表示从顶点vi到vj的路径长度,k表示绕行第k个顶点的运算步骤。初始时,A(-1)为图的邻接矩阵。以后再原路径加入顶点vk作为中间点。若增加中间定点后,得到路径比原来的路径更短,就更新方阵A(k)。

如对于有向图G,它的邻接矩阵如右图。
最短路径问题_第6张图片

开始时,让A(-1)为邻接矩阵,然后进行一次迭代,将v0作为中间点,修改A(-1)称为A(0);
对于所有顶点,如有A[I][J]>A[i][0]+A[0][j],则将A[i][j]更新为A[i][0]+A[0][j]。一次类推进行迭代,由于图中只有三个顶点,只需要三次迭代就可以找到任意顶点到其它顶点的最短路径。三次迭代的结果为:
最短路径问题_第7张图片

floyd的核心算法是:

void Floyd(Graph g){
	int A[MAX][MAX],path[MAX][MAX];//A记录每个顶点之间的最短路径值,path记录最短路径如何到达
	int i,j,k;
	for (i=0;iA[i][k]+A[k][j]){//如果有更短的路径,则更新A,并且记录路径。
					A[i][j]=A[i][k]+A[k][j];
					path[i][j]=k;
				}
			}
		}
	}
}

你可能感兴趣的:(最短路径问题)