• 每一对顶点间最短路径的Floyd算法


    Floyd思想可用下式描述:
    A-1[i][j]=gm[i][j]
    A(k+1)[i][j]=min{Ak[i][j],Ak[i][k+1]+Ak[K+1][j]}    -1<=k<=n-2
    该式是一个迭代公式,Ak表示已考虑顶点0,1,.......,k等k+1个顶点之后各顶点之间的最短路径,即Ak[i][j]表示由Vi到Vj已考虑顶点0,1,.......,k等k+1个顶点的最短路径;在此基础上再考虑顶点k+1并求出各顶点在考虑了顶点k+1之后的最短路径,即得到Ak+1.每迭代一次,在从vi到vj的最短路径上就多考虑了一个顶点;经过n次迭代后所得到的A(n-1)[i][j]值,就是考虑所有顶点后从Vi到Vj的最短路径,也就是最终的解。
    若Ak[i][j]已经求出,且顶点i到顶点j的路径长度为Ak[i][j],顶点i到顶点k+1的路径长度为Ak[i][k+1],顶点k+1到顶点j的路径长度为Ak[K+1][j],现在考虑顶点k+1,如果Ak[i][K+1]+Ak[k+1][j]<Ak[i][j],则将原来顶点i到顶点j的路径改为:顶点i到顶点k+1,再由顶点k+1到顶点j;对应的路径长度为:A(k+1)[i][j]=Ak[i][k+1]+Ak[k+1][j];否则无需修改顶点i到顶点j的路径.
    参考代码:
     1 #include<stdio.h>
     2 #define MAXSIZE 6//带权有向图中顶点的个数
     3 #define INF 32767
     4 
     5 void Ppath(int path[][MAXSIZE],int i,int j)//前向递归查找路径上的顶点,MAXSIZE为常数
     6 {
     7  int k;
     8  k=path[i][j];
     9  if(k!=-1)
    10  {
    11      Ppath(path,i,k);//找顶点vi的前一个顶点vk
    12      printf("%d->",k);//输出顶点vk序号k
    13      Ppath(path,k,j);//找顶点vk的前一个顶点vj
    14  }
    15 }
    16 
    17 void Dispath(int A[][MAXSIZE],int path[][MAXSIZE],int n)//输出最短路径的函数
    18 {
    19     int i,j;
    20     for(i=0;i<n;i++)
    21         for(j=0;j<n;j++)
    22             if(A[i][j]==INF)//INF为一极大常数
    23             {
    24                 if(i!=j)
    25                     printf("从%d到%d没有路径!
    ",i,j);
    26             }
    27             else//从vi到vj有最短路径
    28             {
    29                 printf("从%d到%d的路径长度:%d,路径:",i,j,A[i][j]);
    30                 printf("%d->",i);//输出路径上的起点序号i
    31                 Ppath(path,i,j);//输出路径上的各中间点序号
    32                 printf("%d
    ",j);//输出路径的终点序号j
    33             }
    34 }
    35 
    36 void Floyd(int gm[][MAXSIZE],int n)//Floyd算法
    37 {
    38     int A[MAXSIZE][MAXSIZE],path[MAXSIZE][MAXSIZE];
    39     int i,j,k;
    40     for(i=0;i<n;i++)
    41         for(j=0;j<n;j++)
    42         {A[i][j]=gm[i][j];//A-1[i][j]置初值
    43          path[i][j]=-1;//-1表示初始时最短路径不经过中间顶点
    44         }
    45         for(k=0;k<n;k++)//按顶点编号k递增的次序查找当前顶点之间的最短路径长度
    46             for(i=0;i<n;i++)
    47                 for(j=0;j<n;j++)
    48                     if(A[i][j]>A[i][k]+A[k][j])
    49                     {A[i][j]=A[i][k]+A[k][j];//从vi到vj经过vk时路径长度更短
    50                      path[i][j]=k;//记录中间顶点Vk的编号
    51                     }
    52                     Dispath(gm,path,n);//输出最短路径
    53 }
    54 
    55 void main()
    56 {
    57     int g[MAXSIZE][MAXSIZE]={{INF,20,15,INF,INF,INF},{2,INF,INF,INF,10,30},{INF,4,INF,INF,INF,10},
    58     {INF,INF,INF,INF,INF,INF},{INF,INF,INF,15,INF,INF},{INF,INF,INF,4,10,INF}};
    59     Floyd(g,MAXSIZE);
    60 }     


    输出结果:

  • 相关阅读:
    vue简单总结
    浅拷贝 与递归实现深拷贝封装
    利用mock生成随机的东西
    你不知道的JavaScript--面向对象高级程序设计
    超实用的JavaScript代码段 --倒计时效果
    超实用的JavaScript代码段 Item4 --发送短信验证码
    WEB前端性能优化:HTML,CSS,JS和服务器端优化
    超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝
    web开发必须知道的javascripat工具
    加快页面的运行速度
  • 原文地址:https://www.cnblogs.com/wxdjss/p/5515480.html
Copyright © 2020-2023  润新知