1. 程式人生 > >floydwarshall演算法(弗洛伊德演算法)的理解,就一句話

floydwarshall演算法(弗洛伊德演算法)的理解,就一句話

floydwarshall algorithm(弗洛伊德演算法):對每一個頂點,都要嘗試它作為任一對頂點的中轉頂點的可能性。基於此,形成一個基礎資料庫。在這個基礎資料庫的基礎上,追溯出任意兩點的最短路徑。

對幾個疑問的解釋:

1.簡單的迴圈條件,如for (k=0;k<n;k++)

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

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

是否會造成頂點的覆疊?比如k=1;i=0;j=1;

解釋:覆疊是會的。但是如例中情況,我們認為k=1,是i=0和j=1的中轉頂點。因而,和總體的原則是統一的,不會影響結果。

2.為什麼會要先有一個全面的基礎資料庫,不能直接得出任意兩點的最短路徑嗎?

答:任意兩點的路徑,它們之間可能有中轉頂點,也可能沒有。但是它們的中轉頂點之間,可能還有其他中轉頂點;其他中轉頂點之間,可能還有其他其他中轉頂點......因此,雖然只是兩個頂點的最短路徑問題,但是關乎全域性的頂點對之間的中轉資訊。因此,需要一個全面的包含所有的中轉頂點的基礎資料庫。

下面是floydwarshall algorithm(弗洛伊德演算法)的c語言程式碼。在最後追溯兩點之間的中間頂點的時候,我沒有用棧,而是用的遞迴函式。


#include    "stdio.h"
#define     NUM     4
#define     CN      ( (NUM-1)+1 )*NUM/2

void short_path(int E[NUM][NUM],int u,int v);
void trace_back(int path[][NUM],int u,int v);

main()
{
    int n;
    n = NUM;
    int E[n][n];
    int i,j;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if (i==j)
                E[i][j]=0;


    int ni[CN]={3,10,18,6,15,2};//necessary information;
    int k;
    k=0;
    for (i=0;i<n;i++)
        for(j=i+1;j<n;j++)
            E[i][j] = ni[k++];
    for(j=0;j<n;j++)
        for(i=j+1;i<n;i++)
            E[i][j] = E[j][i];
    for (i=0;i<n;i++)
        for(j=0;j<n;j++)
            if (j == n-1)
                printf("%-2d\n",E[i][j]);
            else
                printf("%-2d ",  E[i][j]);
short_path(E,0,3);


}

void short_path(int E[NUM][NUM],int u,int v)
{
    int n;
    n=NUM;
    int dist[NUM][NUM];
    int path[NUM][NUM];
    int i,j,k;

    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            dist[i][j]=E[i][j];

    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            path[i][j]=-1;

    for(k=0;k<n;k++)
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                if(dist[i][k]+dist[k][j]< dist[i][j])
                    {dist[i][j] = dist[i][k]+dist[k][j];
                        path[i][j] = k;}

printf("%d ",u);
trace_back(path,u,v);

}

void trace_back(int path[][NUM],int u,int v)
{

    if(path[u][v] != -1)
        trace_back(path,u,path[u][v]);
    printf("%d ",v);
}