zoukankan      html  css  js  c++  java
  • 最短路径-弗洛伊德(Floyd)算法

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

    弗洛伊德(Floyd)算法 是解决任意两点间的最短路径的一种算法  

    Floyd算法是一个经典的动态规划算法用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)

        从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离

    2).算法描述:

    a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。   

    b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。

    为了能讲明白弗洛伊德算法的精妙所在,我们先来看最简单的案例:

      弗洛伊德算法

    弗洛伊德算法

    D1[0][2] = min{D0[0][2], D0[0][1]+D[1][2]}

    弗洛伊德算法原理

    弗洛伊德算法

    弗洛伊德算法

    floyd

    floyd

    floyd

    floyd

    这是我们求V0到个点的距离则看V0对应的一行或者一列就好了此时为 {0.1.4.7.5.8.10.12.16} 此为距离值

    求路径是 看V0->V8 第一行为P[0][8]=1 用到V1

    看V1->V8 第一行为P[1][8]=2 用到V2

    看V2->V8 第一行为P[2][8]=4 用到V4

    看V4->V8 第一行为P[4][8]=3 用到V3

    看V3->V8 第一行为P[3][8]=6 用到V6

    看V6->V8 第一行为P[6][8]=7 用到V7

    看V7->V8 第一行为P[7][8]=8 用到V8

    路径为V0->V1->V2->V4->V3->V6->V7->V8

    typedef struct  
    {  
        char vers[numV];//顶点表  
        int edges[numV][numV];//邻接矩阵  
        int v,e;//看作是当前的顶点和边数  
    }MGraph;  
      
    void Floyd(MGraph G)  
    {  
        int A[G.v][G.v];//初始化 刚刚开始为邻接矩阵的copy 最终是我们要的结果  
        int path[G.v][G.v];  
        for(int i=0;i<G.v;i++)初始化  
        {  
            for(int j=0;j<G.v;j++)  
            {  
                A[i][j] = G.edges[i][j];  
                path[i][j] =j;  
            }  
        }  
        for(int k=0; k<G.v; k++)  
        {  
            for(int i=0;i<G.v;i++)  
            {  
                for(int j=0;j<G.v;j++)  
                {  
                    if(A[i][j] > (A[i][k]+A[k][j]))//如果经过K点的路径比原来两点见路径更短  
                    {  
                        A[i][j] = A[i][k]+A[k][j];  
                        path[i][j] = k;  
                    }  
                }  
            }  
        }  
    }  
    //求最短路径的显示代码可以这样写  
    void printWay(MGraph G, int* A, int* path)  
    {  
        for(int i=0;i<G.numV;i++)  
        {  
            for(int j=i+1;j<G.numV;j++)  
            {  
                cout<<"v"<<i<<"-"<<"v"<<j<<"weight:"<<A[i][j];  
                int k=path[i][j];  
                cout<<"path:"<<i;//打印出源点  
                while(k != j)  
                {  
                    cout<<"->"<<k;//打印路径顶点  
                    k = path[k][j];//获得下一个路径的顶点下标  
                }  
                cout<<"->"<<j;//打印终点  
            }  
            cout<<endl;  
        }  
    }  
    关注公众号 海量干货等你
  • 相关阅读:
    一步步介绍如何给项目添加单元测试
    日期格式化在移动端的问题
    使用VW时,图片的问题
    转:vw适配中使用伪类选择器遇到的问题
    ES6模块的import和export用法总结
    转:如何在Vue项目中使用vw实现移动端适配
    PhpStrom添加调试功能
    小程序商城笔记
    使用TortoiseGit对android studio工程进行代码版本控制
    Android Studio 常见异常解决办法
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734463.html
Copyright © 2011-2022 走看看