Floyd-Warshall 算法

     Floyd-Warshall 算法用来找出每对点之间的最短距离。它需要用邻接矩阵来储存边,这个算法通过考虑最佳子路径来得到最佳路径。

注意单独一条边的路径也不一定是最佳路径。

  • 从任意一条单边路径开始。所有两点之间的距离是边的权,或者无穷大,如果两点之间没有边相连。
  • 对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。
  • 不可思议的是,只要按排适当,就能得到结果 
// dist(i,j) 为从节点i到节点j的最短距离
For i←1 to n do
   For j←1 to n do
      dist(i,j) = weight(i,j) 
 
For k←1 to n do // k为“媒介节点”
   For i←1 to n do
      For j←1 to n do
         if (dist(i,k) + dist(k,j) < dist(i,j)) then // 是否是更短的路径?
            dist(i,j) = dist(i,k) + dist(k,j)

这个算法的效率是O(V3)。它需要邻接矩阵来储存图。
这个算法很容易实现,只要几行。

即使问题是求单源最短路径,还是推荐使用这个算法,如果时间和空间允许(只要有放的下邻接矩阵的空间,时间上就没问题)。

    一个演示的例子代码:

#include < stdio.h >
#define  NV 5
#define  MA 9999999

int  main( void )
{
        
int  graph[NV][NV] =
        {
                
0 1 7 2 8 ,
                
1 0 3 2 2 ,
                
7 3 0 4 4 ,
                
2 2 4 0 3 ,
                
8 2 4 3 0  
        };
      
int  num = NV;
        
int  path[NV][NV];
        
int  i,j,k;
    
for (i = 0 ;i < num;i ++ )      {
                
for (j = 0 ;j < num;j ++ )
                        printf(
" %d  " ,graph[i][j]);
                printf(
" " );
        }
        
for (i = 0 ;i < num;i ++ ) {
                
for (j = 0 ;j < num;j ++ ){
                        path[i][j]
= graph[i][j];
                }
        }

        
for (k = 0 ;k < num;k ++ )
                
for (i = 0 ;i < num;i ++ )
                        
for (j = 0 ;j < num;j ++ )
                                
if (path[i][j] > graph[i][k] + graph[k][j])
                                        path[i][j]
= graph[i][k] + graph[k][j];
        
for (i = 0 ;i < num;i ++ )
    {     
for (j = 0 ;j < num;j ++ )
                        printf(
" Shortest distance between <%d,%d>: %d  " ,i + 1 ,j + 1 ,path[i][j]);
    }
        
return   0 ;
}

 

 

 

你可能感兴趣的:(Floyd-Warshall 算法)