zoukankan      html  css  js  c++  java
  • 佛洛依德算法的学习与实现

    1、问题引入

      带权有向图中单源点的最短路径问题可以用地杰斯特拉算法求解,如果要求解图中每一对顶点之间的最短路径,类似可以想到的方法为:每次以一个顶点为源点,重复执行地杰斯特拉算法算法n次,这样,便可以求得每一对顶点之间的最短路径,总的执行时间为O(n3)。

      这里可以采用另外一种求解算法:Floyd算法。

    2、Floyd的基本思想为:

      从邻接矩阵a开始进行n次迭代,第一次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于1的顶点的最短路径长度;第k次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于k的顶点的最短路径长度 第n次迭代后a[i,j]的值就是从vi到vj的最短路径长度。

    3、算法描述:

      (1) 用数组d[i][j]来记录i,j之间的最短距离。初始化d[i][j],若i=j则d[i][j]=0,
        若i,j之间有边连接则d[i][j]的值为该边的权值,否则d[i][j]的值为max 。
      (2) 对所有的k值从1到n,修正任意两点之间的最短距离,计算d[i][k]+d[k][j]的值,
        若小于d[i][j],则d[i][j]= d[i][k]+d[k][j],否则d[i][j]的值不变。

    4、具体实现:

      带权有向图如下:

    在2.txt文件中保存的带权有向图的数据为:

    其中第一个数据4表述图中有4个节点,其他的四行四列数据表示各个节点之间的路径长度,9999表示两个节点之间不可达。

    具体代码为:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #define max 9999
     4 void Floyd(int,int **,int**,int**);
     5 void Searchpath(int,int,int**,int**);
     6 void main()
     7 {
     8     int i,j,num,first,last;
     9     FILE *p;
    10     p=fopen("2.txt","r");
    11     if(p==NULL)
    12     {
    13         printf("无法打开2.txt");
    14         exit(-1);
    15     }
    16     fscanf(p,"%d",&num);//获取点的个数;
    17     int **a=(int**)malloc(sizeof(int*)*num);
    18     for(i=0;i<num;i++)
    19         a[i]=(int*)malloc(sizeof(int)*num);
    20     for(i=0;i<num;i++)//获取图中各个点之间的路径长度;
    21         for(j=0;j<num;j++)
    22             fscanf(p,"%d",&a[i][j]);
    23     //path[i][j]用于记录从i到j的最短路径上j点的前一个节点
    24     int **path=(int**)malloc(sizeof(int*)*num);
    25     for(i=0;i<num;i++)
    26         path[i]=(int*)malloc(sizeof(int)*num);
    27     //d[i][j]用于记录从i到j的最短路径的长度
    28     int **d=(int**)malloc(sizeof(int*)*num);
    29     for(i=0;i<num;i++)
    30         d[i]=(int*)malloc(sizeof(int)*num);
    31     //佛洛依德算法程序调用
    32     Floyd(num,path,d,a);
    33     printf("最终得到的距离矩阵为:\n");
    34     for(i=0;i<num;i++)
    35     {
    36         for(j=0;j<num;j++)
    37             printf("%d  ",d[i][j]);
    38         printf("\n");
    39     }
    40     printf("请输入起始点(小于%d):",num);
    41     scanf("%d",&first);
    42     printf("\n请输入终止点(小于%d):",num);
    43     scanf("%d",&last);
    44     printf("起始点%d到终止点%d的最短路径长度为:%d\n",first,last,d[first][last]);
    45     Searchpath(first,last,path,d);//利用path[i][j]得出从i到j的最短路径
    46 }
    47 void Floyd(int num,int **path,int**d,int **a)
    48 {
    49     int i,j,k;
    50     for(i=0;i<num;i++)
    51     {
    52         for(j=0;j<num;j++)//初始化
    53         {
    54             if(a[i][j]<max) path[i][j]=j;//从i到j有路径
    55             else path[i][j]=-1;
    56             d[i][j]=a[i][j];
    57         }
    58     }
    59     for(k=0;k<num;k++)
    60         for(i=0;i<num;i++)
    61             for(j=0;j<num;j++)
    62                 if(d[i][j]>d[i][k]+d[k][j])//从i到j的一条更短的路径
    63                 {
    64                     d[i][j]=d[i][k]+d[k][j];
    65                     path[i][j]=path[i][k];
    66                 }
    67 }
    68 void Searchpath(int first,int last,int **path,int**d)
    69 {
    70     int k;
    71     if(d[first][last]==max)
    72         printf("起始点%d到终止点%d不可达",first,last);
    73     else
    74     {
    75         printf("起始点到终点的路径为:");
    76         k=last;
    77         printf("%d <-- ",k);
    78         while((k!=first)&&(k!=path[first][k]))
    79         {
    80             k=path[first][k];
    81             printf("%d <-- ",k);
    82             if(k==path[first][k])
    83                 k=first;
    84         }
    85         printf("%d\n",first);
    86     }
    87 }

    5、参考资料:

      (1)严蔚敏,数据结构。

      (2)http://blog.sina.com.cn/s/blog_3fe961ae0100nl6g.html

      (3)http://zhidao.baidu.com/question/349458736.html

  • 相关阅读:
    $().css() 设计的原理
    js无缝滚动
    Git 与Github---新手上传经验(快速学习)
    NDK_MODULE_PATH造成Android版无法编译
    Cocos2d-x中子ccb动画无法正常播放的问题
    Android版CCLabelTTF在setstring时出现黑块
    在iOS平台使用libcurl
    CCScrollView上和按钮相关的两个bug
    Cocosbuilder中的颜色自动校准bug
    实用命令杂记
  • 原文地址:https://www.cnblogs.com/lpshou/p/2459851.html
Copyright © 2011-2022 走看看