zoukankan      html  css  js  c++  java
  • floyd算法学习笔记

    算法思路

    路径矩阵

    通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2),以此类推。最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
    状态转移方程
    其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值应该为0
    当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路。


    核心算法
    1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
    2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
    把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。


    时间复杂度与空间复杂度

    时间复杂度:因为核心算法是采用松弛法的三个for循环,因此时间复杂度为O(n^3)

    空间复杂度:整个算法空间消耗是一个n*n的矩阵,因此其空间复杂度为O(n^2)



    C++代码

    // floyd.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include"iostream"
    #include"fstream"
    #define maxlen 20
    #define maximum 100
    using namespace std;

    typedef struct graph
    {
     int vertex;
     int edge;
     int matrix[maxlen][maxlen];
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
     ofstream outwrite;
     outwrite.open("h.txt",ios::app|ios::out);
     outwrite<<"welcome to the graph world! ";
     outwrite<<"the initial matrix is: ";
     int vertexnumber;
     int edgenumber;
     int beginning,ending,weight;
     int mindistance[maxlen][maxlen];
     int interval[maxlen][maxlen];
     graph floydgraph;
     cout<<"welcome to the graph world!"<<endl;
     cout<<"input the number of the vertex: ";
     cin>>vertexnumber;
     cout<<"input the number of the edge: ";
     cin>>edgenumber;
     for (int i = 0; i < vertexnumber; i++)
     {
      for (int j = 0; j < vertexnumber; j++)
      {
       floydgraph.matrix[i][j]=maximum;
      }
     }
     for (int i = 0; i <edgenumber; i++)
     {
      cout<<"please input the beginning index: ";
      cin>>beginning;
      cout<<"please input the ending index: ";
      cin>>ending;
      cout<<"please input the distance of the two dot: ";
      cin>>weight;
      floydgraph.matrix[beginning][ending]=weight;
     }
     for (int i = 0; i <vertexnumber; i++)
     {
      for (int j = 0; j < vertexnumber; j++)
      {
       mindistance[i][j]=floydgraph.matrix[i][j];
       outwrite<<floydgraph.matrix[i][j]<<" ";
       interval[i][j]=-1;
      }
      outwrite<<" ";
     }
     for (int k = 0; k <vertexnumber; k++)
     {
      for (int i = 0; i < vertexnumber; i++)
      {
       for (int j = 0; j < vertexnumber; j++)
       {
        if(mindistance[i][j]>mindistance[i][k]+mindistance[k][j])
        {
         mindistance[i][j]=mindistance[i][k]+mindistance[k][j];
         interval[i][j]=k;
        }
       }
      }
     }
     outwrite<<" "<<"after the floyd transition, the matrix is: "<<" ";
     for (int i = 0; i < vertexnumber; i++)
     {
      for (int j = 0; j < vertexnumber; j++)
      {
       cout<<"the mindistance between "<<i<<"  and  "<<j <<" is: ";
       cout<<mindistance[i][j]<<endl;
       cout<<"the two points pass through the point: "<<interval[i][j];
       cout<<endl;
       outwrite<<mindistance[i][j]<<" ";
      }
      outwrite<<" ";
     }
     outwrite<<" ";
     outwrite<<"the points between the beginning point and the ending point is:"<<" ";
     for (int i = 0; i < vertexnumber; i++)
     {
      for (int j = 0; j < vertexnumber; j++)
      {
       outwrite<<interval[i][j]<<" ";
      }
      outwrite<<" ";
     }
     outwrite.close();
     getchar();
     getchar();
     getchar();
     return 0;
    }

  • 相关阅读:
    软件开发面试
    jQuery插件
    基于消息的软件架构
    线程池的原理及实现(转)
    java实现生产者消费者问题(转)
    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)
    JAVA CAS原理深度分析(转)
    菜鸟nginx源码剖析 框架篇(一) 从main函数看nginx启动流程(转)
    Android中利用Handler实现消息的分发机制(三)
    char* 和char[]的差别
  • 原文地址:https://www.cnblogs.com/DeerTrodis/p/6012826.html
Copyright © 2011-2022 走看看