您的位置:首页 > 其它

算法导论学习笔记(19)——每对顶点间的最短路径(基于Floyd_Warshall算法)

2012-05-07 20:49 411 查看
Floyd-Warshall算法的运行时间为Θ(V3),它同样允许存在负权边,但假设不存在负权回路。该算法考虑的最优子结构与上述描述类似,即最短路径的子路径是最短路径。但是,它对中间路径的范围加以限制,使其增长与最短路径的最大边数的增长同步。令dij(k)=为从顶点i到顶点j、且满足所有中间顶点属于集合{1,2,…,k}的一条最短路径的权值,定义递归解:如果k=0,dij(k)=wij;如果k≥1,dij(k)=min{
dij(k-1), dik(k-1)+ dkj(k-1)}。可以想象,当k=1时,i到j的最短路径或者由边(i,j)构成,或者由边(i,1)、(1,j)构成。当k=2时,i到j的最短路径可能由子路径i到2和子路径2到j构成,而子路径2到j又可能由边(2,1)、(1,j)构成,即k=2的解包含了k=1的解。以此类推,当k=n时,即可得到每对顶点间最短路径的权值。

为了构造最短路径,定义πij(k)为从i出发的一条最短路径上顶点j的前趋,而这条路径上的中间顶点属于集合{1,2,…,k}。定义πij(k)的递归公式,对于k=0,如果i=j或wij=∞,πij(0) =NIT(-1);如果i≠j和wij<∞,πij(0) =i。对于k≥1,如果dij(k-1)≤dik(k-1)+
dkj(k-1),πij(k) =πij(k-1);如果dij(k-1)>dik(k-1)+ dkj(k-1),πij(k) =πkj(k-1)。

完整的实现代码如下:

完整的实现代码如下:

view plaincopy
to clipboardprint?

#include <iostream>

#include <string>

#include <stdio.h>

using
namespace std;

#define MaxVertexNum 100

#define INF 32767

typedef
struct

{

char vertex[MaxVertexNum];

int edges[MaxVertexNum][MaxVertexNum];

int n,e;

}MGraph;

void CreateMGraph(MGraph
&G)

{

int i,j,k,p;

cout<<"请输入顶点数和边数:";

cin>>G.n>>G.e;

cout<<"请输入顶点元素:";

for (i=0;i<G.n;i++)

{

cin>>G.vertex[i];

}

for (i=0;i<G.n;i++)

{

for (j=0;j<G.n;j++)

{

G.edges[i][j]=INF;

if (i==j)

{

G.edges[i][j]=0;

}

}

}

for (k=0;k<G.e;k++)

{

cout<<"请输入第"<<k+1<<"条弧头弧尾序号和相应的权值:";

cin>>i>>j>>p;

G.edges[i][j]=p;

}

}

void Dispath(int
A[][MaxVertexNum],int path[][MaxVertexNum],int
n);

void Floyd(MGraph
G)

{

int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum];

int i,j,k;

for (i=0;i<G.n;i++)

{

for (j=0;j<G.n;j++)

{

A[i][j]=G.edges[i][j];

path[i][j]=-1;

}

}

for (k=0;k<G.n;k++)

{

for (i=0;i<G.n;i++)

{

for (j=0;j<G.n;j++)

{

if (A[i][j]>A[i][k]+A[k][j])

{

A[i][j]=A[i][k]+A[k][j];

path[i][j]=k;

}

}

}

}

Dispath(A,path,G.n);

}

void Ppath(int
path[][MaxVertexNum],int i,int
j)

{

int k;

k=path[i][j];

if (k==-1)

{

return;

}

Ppath(path,i,k);

printf("%d",k);

Ppath(path,k,j);

}

void Dispath(int
A[][MaxVertexNum],int path[][MaxVertexNum],int
n)

{

int i,j;

for (i=0;i<n;i++)

{

for (j=0;j<n;j++)

{

if (A[i][j]==INF)

{

if (i!=j)

{

printf("从%d到%d没有路径/n",i,j);

}

}

else

{

printf(" 从%d到%d=>路径长度:%d路径:",i,j,A[i][j]);

printf("%d,",i);

Ppath(path,i,j);

printf("%d/n",j);

}

}

}

}

int main()

{

MGraph G;

CreateMGraph(G);

Floyd(G);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: