zoukankan      html  css  js  c++  java
  • 任意两点最短路径问题

    问题描述

           输入:图G = (V,E)

           输出:图中任意两点的最短路径

    算法描述(Floyd算法)

         1. 分析优化子结构

           定理1,Vi,Vj的最短路径包含两点Vm,Vn,那么Vi,Vj的最短路径中对应Vm,Vn的部分一定是Vm,Vn在该图中的一条最短路径。

           证明1,可以通过反证法进行证明,如果不是,那么可以构造出比当前Vi,Vj的最短路径更短的路径。

         2. 分析子问题重叠性。

           首先,需要了解Vi,Vj的递归代价方程。

           定义:D(i,j)为Vi,Vj的最短路径长度。

    • D(i,j) = 0,if i = j.
    • D(i,j) = min ( D(i,j) , D(i,k) + D(k,j)),其中,i ≤ k ≤ j,if i ≠ j.

           那么此问题的计算形式基本上于矩阵链乘问题的计算形式,这就是一个划分动态规划,那么同理自然就有子问题重叠性。

         3.递归地定义最优解的代价 

    • D(i,j) = 0,if i = j.
    • D(i,j) = min ( D(i,j) , D(i,k) + D(k,j)),其中,i ≤ k ≤ j,if i ≠ j.

         4.自底向上地计算优化解的代价保存之,并获取构造最优解的信息

           对于该算法而言,计算顺序是值得思考的。如果直接进行遍历计算,可能当计算D(i,j)时,所使用的D(i,k)以及D(k,j)都并非是最小代价,可以说,每个D(i,j)都相互影响。

           解决办法为:构建顶点集合S以及表示任意两点之间最小路径代价的二维矩阵M,

    • 初始时,S为空,M中仅仅将边录入,无边记为无穷。
    • 依次向S中加入顶点,并仅仅将该顶点作为递归方程中的顶点Vk,更新M。
    • 当S = V时,M中记为最短路径代价。

          故而可以设计算法为:

    Floyd算法
    D <-- W
    P <-- 0
    For k = 1 to n Do /*k控制填入元素*/
         For i = 1 to n Do /*i,j控制矩阵的遍历*/
            for j = 1 to n
               if (D[ i, j ] > D[ i, k ] + D[ k, j ] )
               then D[ i, j ] = D[ i, k ] + D[ k, j ]
                       P[ i, j ] = k; 

         5.根据构造最优解的信息构造优化解

            注意,下列算法只打印中间节点,而不会答应起止节点,所以,P中无边或者直接有边的值均为0.

    path(index q, r)
         if (P[ q, r ]!=0)
             path(q, P[q, r])
             println( “v”+ P[q, r])
             path(P[q, r], r)
             return;
         //no intermediate nodes
         else return 

      6.算法复杂性分析:

           时间复杂性:

               计算代价的时间复杂性:O(n^3)。

               构造最优解时间复杂性:O(n)。最多只会遍历n个顶点

               空间复杂性:O(n^2)。

  • 相关阅读:
    ajax post 时 form数据serialize()
    dapper 自定义数据库字段和代码中Model字段不一致时候的mapping方法
    TImage 的一些操作
    AOP
    SSL、数字签名、CA 工作原理
    RESTFUL
    tomcat
    Hibernate
    设计模式
    Spring配置
  • 原文地址:https://www.cnblogs.com/zqybegin/p/13578093.html
Copyright © 2011-2022 走看看