Floyd 算法
Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
时间复杂度 O(n^3)
优缺点分析 Floyd算法适用于APSP(All Pairs Shortest Paths),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。
优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单
缺点:时间复杂度比较高,不适合计算大量数据。
代码:
void floyd (Graph G,int n,Graph D,Graph P)
{
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{D[i][j] = G[i][j]; P[i][j] = i;}
for(i = 0;i < n;i++) { D[i][i] = 0;P[i][i] = 0;}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(k=0;k<n;k++)
if(D[i][j]>D[i][k]+D[k][j])
{ D[i][j] = D[i][k]+D[k][j]; P[i][j] = P[k][j];}
}
求单源最短路径 Dijkstra算法
给定一个带权有向图G=(V,E),其中每天边的权是非负数。另外还给定一个V中一个顶点,称为源。计算从源到所有其他各个顶点的最短路长度。通常称为单源最短路径问题。
Dijkstra 算法是解决单源最短路径问题的一个贪心算法。该算法同时适用无向图和有向图。
伪代码如下:
清除所有点的标号
设d[0] = 0;其他d[i] = INF//为无穷大的整数d[i]表示distant(源到顶点i的最短路径长度)
循环n次
{在所有未标号的结点中,找出d值最小的结点x
给结点x标记
对于从x结点出发的所有边(x,y),更新d[y] = min{d[y],d[x]+w[x,y]}
}
下面是对应的程序,假设起点是结点0,它到结点i的路径长度为d[i]。未标号结点v[i]=0,已标号结点v[i] = 1,为简单起见w[x][y]=INF表示边(x,y)不存在。
memset(v,0.sizeof(v));
for(int i=0;i<n;i++) d[i] = (i==0 ? 0:INF);
for(int i=0;i<n;i++)
{
int x,m = INF;
for(int y = 0;y<n;y++) if(!v[y] && d[y]< m) m =d[x=y];
v[x] = 1;
for(int y = 0;y<n;y++) d[y] =min(d[y],d[x]+w[x][y]);
}