Floyd算法

求最短路径的第二种算法Floyd算法,前一个算法Dijkstra的时间复杂度是O(n3)

这个算法的时间复杂度也是O(n3),不过这个算法更加精妙。

其基本思想:我们从任意节点A到任意节点B的最短距离不外乎2种可能,1是直接A到B,2是从A经过若干个节点X后到B。

我们假设Dis(AB)为节点A到节点B的最短路径距离,那么我们要做的事就是检查Dis(AX)+Dis(XB)是否小于Dis(AB),如果小于则将Dis(AB)=Dis(AX)+Dis(XB),再次遍历,遍历完所有的X节点之后,得到的Dis(AB)就是最短路径的距离。

那下面就是实现过程,图的结构仍然使用的是邻接矩阵的形式。

我们对上述Dis(AX)求解的时候,我们应该首先计算靠外的部分,而不应该先计算内部,如果先计算内部,则会出现外部的距离很短却不知道的情况。

这样我们对于每一个点X,我们都先计算出所有的i到j之后再检查下一个节点,这样就不会有遗漏的情况。

好,下面我们要给出最短路径的话,我们就要添加一个辅助数组path,这个path数组中给出A到B的路径经过路径,比如A->D,经过B,C,路径是A->B->C->D,则path存储的是P(AD)=B,P(AD)=C,P(CD)=D

好,那下面给出代码:

#include <stdio.h>

#define MAXVEX 9
#define INFINITY 65535

//定义一个图结构
typedef struct MGraph
{
    char vexs[MAXVEX];
    int arc[MAXVEX][MAXVEX];
    int numVertexes,numEdges;
}MGraph;
void createMGraph(MGraph *g);
void shortPathFloyd(MGraph g,int p[][MAXVEX],int s[][MAXVEX]);

void createMGraph(MGraph *g)
{
    int i,j;
    g->numEdges=16;
    g->numVertexes=9;

    for(i=0;i<MAXVEX;i++)
    {
        g->vexs[i]=i;
    }

    for(i=0;i<g->numVertexes;i++)
    {
        for(j=0;j<g->numVertexes;j++)
        {
            if(i==j)
            {
                g->arc[i][j]=0;
            }
            else
            {
                g->arc[i][j]=g->arc[j][i]=INFINITY;
            }
        }
    }

    g->arc[0][1]=1;
    g->arc[0][2]=5;
    g->arc[1][2]=3;
    g->arc[1][3]=7;
    g->arc[1][4]=5;
    g->arc[2][4]=1;
    g->arc[2][5]=7;
    g->arc[3][4]=2;
    g->arc[3][6]=3;
    g->arc[4][5]=3;
    g->arc[4][6]=6;
    g->arc[4][7]=9;
    g->arc[5][7]=5;
    g->arc[6][7]=2;
    g->arc[6][8]=7;
    g->arc[7][8]=4;

    for(i=0;i<g->numVertexes;i++)
    {
        for(j=i;j<g->numVertexes;j++)
        {
            g->arc[j][i] =g->arc[i][j];
        }
    }
}

void shortPathFloyd(MGraph g,int p[][MAXVEX],int s[][MAXVEX])
{
    int i,j,k;
    for(i=0;i<g.numVertexes;i++)
    {
        for(j=0;j<g.numVertexes;j++)
        {
            s[i][j]=g.arc[i][j];
            p[i][j]=j;

        }

    }
    for(k=0;k<g.numVertexes;k++)
    {
        for(i=0;i<g.numVertexes;i++)
        {
            for(j=0;j<g.numVertexes;j++)
            {
                if(s[i][j]>s[i][k]+s[k][j])
                {
                    s[i][j]=s[i][k]+s[k][j];
                    p[i][j]=p[i][k];
                }
            }
        }
    }
}


int main()
{
    MGraph g;
    int i,j,k;
    int patharc[MAXVEX][MAXVEX],shortPath[MAXVEX][MAXVEX];
    createMGraph(&g);
    shortPathFloyd(g,patharc,shortPath);
    for(i=0;i<g.numVertexes;i++)
    {
        for(j=i+1;j<g.numVertexes;j++)
        {
            printf("v%d-v%d weight: %d ",i,j,shortPath[i][j]);
            k=patharc[i][j];
            printf(" path: %d",i);
            while(k!=j)
            {
                printf(" -> %d",k);
                k=patharc[k][j];
            }
            printf(" -> %d\n",j);
        }
        printf("\n");
    }
    return 0;
}
posted @ 2014-03-03 17:23  越影&逐日而行  阅读(329)  评论(0编辑  收藏  举报