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);
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值