zoukankan      html  css  js  c++  java
  • Floyd算法的原理和实现代码

    原理

    假设有向图G=(V,E)采用邻接矩阵存储。设置一个二维数组A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点i -> j的最短路径长度。然后,每次添加一个顶点,同时对A的数组进行筛选优化,期间会产生k个A数组。Ak[i][j]数组代表着从考虑0 -> k的i -> j 的最小距离,当k 等于全部顶点数的时候,就是已经找出了i -> j 的最短距离。
    在这里插入图片描述

    初始化

    在这里插入图片描述

    1. 二维数组 path [i] [j] 初始化时,i -> j有路径时,path [i] [j] = i (即指向j的前一个顶点位置); 没有路径时path [i] [j] 初始化为-1

    2.二维数组A[i][j] 初始化时就等价于边 i -> j 的权值。

    算法过程

    1. 用二维数组A存储最短路径长度:

      • Ak[i][j]表示考虑顶点0~k后得出的i -> j的最短路径长度。
      • An-1[i][j]表示最终的i -> j的最短路径长度。
    2. 用二维数组path存放最短路径:

      • pathk[i][j]表示考虑顶点0~k后得出的i -> j的最短路径。
      • pathn-1[i][j]表示最终i -> j的最短路径。

    在这里插入图片描述
    在这里插入图片描述

    实际上就是从一个个顶点开始分析,从一个到多个的过程中去筛选。初始化数据后,开始添加节点1,再去分析如果包含了节点1以后的各点之间路径是不是有变短,如果有的话就替换,这一遍分析过程被称为二维数组A的更新,也就是Ak数组,k是分析的节点1。而我们的path数组则是用来存放路径,其实就是i->j的路径上的j的上一步的顶点。

    3.路径的求解
    在这里插入图片描述

    实现

    Floyd算法的C语言实现如下:

    void Floyd(MatGraph g)	//求每对顶点之间的最短路径
    {  int A[MAXVEX][MAXVEX];	//建立A数组
       int path[MAXVEX][MAXVEX];	//建立path数组
      int i, j, k;
      for (i=0;i<g.n;i++)   		
         for (j=0;j<g.n;j++) 
         {  A[i][j]=g.edges[i][j];
            if (i!=j && g.edges[i][j]<INF)
    	    path[i][j]=i; 	//i和j顶点之间有一条边时
         else			//i和j顶点之间没有一条边时
    	    path[i][j]=-1;
         }
         //以上是初始化过程内容
       for (k=0;k<g.n;k++)		//求Ak[i][j]
      {   for (i=0;i<g.n;i++)
           for (j=0;j<g.n;j++)
    	    if (A[i][j]>A[i][k]+A[k][j])	//找到更短路径
    	    {   A[i][j]=A[i][k]+A[k][j];	//修改路径长度
    	         path[i][j]=path[k][j]; 	//修改最短路径为经过顶点k
            }
      }
          DispathFloyd(g, A, path);
    }	
    
    //以下为输出最短路径的函数
    void DispathFloyd(MatGraph g, int A[][MAXV], int path[][MAXV])
    {
        int i, j, k, s;
        int apath[MAXV], d;
    
        for (i = 0; i < g.n; i++)
            for (j = 0; j < g.n; j++)
            {
                if (A[i][j] != INF && i != j)
                {
                    printf("从%d到%d的路径是:", i, j);
                    k = path[i][j];
                    d = 0;
                    apath[d] = j;
                    while (k != -1 && k != i)
                    {
                        d++;
                        apath[d] = k;
                        k = path[i][k];
                    }
                    d++;
                    apath[d] = i;
                    printf("%d", apath[d]);
    
                    for (s = d - 1; s >= 0; s--)
                        printf(",%d", apath[s]);
                    printf("	路径长度为:%d
    ", A[i][j]);
                }
            }
    }
    
    

    可以看出时间复杂度为O(n^3)

    Enjoy

    在这里插入图片描述

  • 相关阅读:
    函数模板
    c#使用多线程的几种方式示例详解
    C#中数组、ArrayList和List三者的区别
    c# Thread类
    IEnumerable和IEnumerator 详解
    C#执行CMD命令并接收返回结果的实现方法
    C# Process.Start()方法详解
    C#Json转Xml格式数据的方法
    sql存储过程
    SQL存储过程基础
  • 原文地址:https://www.cnblogs.com/billyme/p/13543654.html
Copyright © 2011-2022 走看看