[概要]グラフ理論アルゴリズム - 最短経路

[概要]グラフ理論アルゴリズム - 最短経路

まず、概念

最短経路問題。すなわち、最短図中の2つの特定のノード間の経路の長さを求めます。図は、すなわち、右側、全てのノードの配列を介してエンドノードグラフ方法からノードに、すなわち、出発点、経路と呼ばれる経路長と経過しました。 

二、フロイドのアルゴリズム

元の隣接行列は、時間隣接行列保存任意の中間ノードの距離なしで最小値、[I] [j]はiがjはノードからノードへ値を示すエッジを介しあった場合(複数の辺は、隣接行列重量に格納された最小値をとり、無限大であってもよい、すなわち、到達不能)。ノードNに1の番号を付けたとし、我々は、iがjをノードからノードへ考えるだけ中間ノード番号を介して最短経路の長さを1に等しく未満である(又は通過しない場合があります)元の状態と比較して、パスを介して中間ノードには、ノード1の数を増加させることができます。また、最短経路上のノードは、(負の重みの存在に関係なく)重複しないことを知っています。次いで、経路はノード1は、2つの部分に分割されているので、ノード1と許可との間に2つのノードが新たな最短経路の出現を通過する場合:ノードiを1から経路上の中間ノードを通過しないが、中間ノードを介して、同じパスは、パスに、ノードjに1辺の総経路長である第二のセグメントではなく、[I] [1] +;パスは最初のセクション1である [1]〜[J]エッジ。許可されていないノードを通る経路は、1よりも短いかどうかを決定するために、我々は、エッジ[I] [1] +比較エッジ[1]〜[J] とエッジとの大小関係[I] [j]を前者の方が小さい場合、最短経路長に等しいJパスの中間ノード番号にIで表される値が1未満であると、パス1を介して中間ノードは、オリジナルよりも短い、そうでない場合、パスの長さは、元のままで値エッジ[i] [j]は、すなわち、ノード1も通過させるが、長さが最短経路が通過ありません。 

エッジ[I] [j]が唯一の最短経路長の中央を通って、ノードiからノードjに表す場合、より一般的な場合を考える点kの数よりも少ない数の中間を通過させたとき、我々は、これらの値から判断することができますkは、それらの間の最短経路の長さ、以下のノードである場合。また、元の状況と比較して、新たな症例が新たなノード番号のパス内の中間ノードは、K、我々はエッジを決定するのと同じ方法[I] [K] +エッジ[K] [j]の値である許容しましたエッジ値[I] [j]は、前者の方が小さければ値iがjはノードに新しいケースのノードからの最短経路の長さを表し、それ以外の場合、新しいパスの長さが変わらない場合。 

前述のように隣接行列表記において、エッジ[I] [j]はiは、任意のノードを通過することなく最短距離でjのノード、中間ノードによって表され、我々は、中間ノードを通過させました。ノード、ノード2、... Nまでのノード1点を追加し、これらのノードiは通過させJノードからノードへ追加した、長さ、即ち、全てのノードの最短経路長を求めることができますiがノードjへの元のパスの長さ上のノードです。

我々が設定最短経路長ANS [k]を[I] [j]はiはノード番号を介してK以下をノードからノードへJ許可です上述したように、ANS [0] [I] [j]は、エッジの値グラフ隣接行列表現に等しい[I] [j]があります。私たちは、次のサイクルを採用し、すべてのk対応ANSの完了[K] [i]の[ j]の値解決:

INT K = 1 ; K <= N; K ++)// 1からn個のサイクルKの
{
     ためint型 I = 1 ; Iは<= N Iは++ 
    { 
        ためINT J = 1 ; J <= N。 ++ J)// I、J全てトラバース
        {
             がiF(ANS [K - 1 ] [I] [K] == ANX無限|| [K - 1 ] [K] [J] ==無限大)// 許さパスK-1のノード、I、JおよびKは、チャイナユニコムは、日付のK ijを通る経路との間に存在しないことができない前に、
            { 
                ANS [K] [I]、[J] =のANS [K - 1 ] [Iは] [J]; //前とK-1のノードが前の経過時間の同じ経路長せた後、IからJ k個の点に、すなわち、アサートされ
                続けを; 
            } 
            IF(ANS [K - 1 ] [I] [J] ==無限| | ANX [K - 1 ] [I] [K] + ANS [K - 1 ] [K] [J] <ANS [K - 1 ] [I] [J])ANS [K] [I] [J] ANX = [K - 1 ] [I] [K] + ANS [K - 1 ] [K] [J]; // 最初のk-1節後、i、jは通信しないか、ノードkによって得ることができます短いパスは、最小値が更新
            他の ANS [K] [I]、[J] ANS = [K - 1 ] [I]、[J]; 
        } 
    } 
}

nサイクルこの後、我々は、すべてのノードの条件の下で経路長との間を通過させ、すべてのノードを取得することができ、経路長が最短経路長我々の要件があります。AB間の最短経路長を得るために必要な場合には、答えはANS [n]は[A] [B]値です。 

再帰ANSした値に[k]が値ごとに[i] [j]の[i]の[j]は、すべてのANS [K] [i]は - 私達は私達ANS [1 k]が通じていることに気づきました[J] ANSによって値[K - 1] [I] [J]とANS [K - 1] [I] [K] + ANS [K - 1]の大小関係の[K] [j]が決定されるが、 ANS [K] [I] [k]とANS [K] [K] [j]はANSでなければならない[K - 1] [I] [k]とANS [K - 1] [K] [j]の値同じこの更新が発生するのため、これらの値が変更されないこと。上記のコードでは、我々は次の形式に単純化: 

INT K = 1 ; K <= N; K ++)// 1からn個のサイクルKの
{
     ためint型 I = 1 ; Iは<= N Iは++ 
    { 
        ためINT J = 1 ; J <= N。 ++ J)// すべてのI、Jトラバース
        {
             IF(ANS [I] [K] ==無限||のANX [K] [J] == 無限)が続行;
             IF(ANS [I] [J] ==無限ANX || [I] [K] + ANS [K] [J] <ANS [I] [J])ANS [I] [J] = ANX [I] [K] + ANS [K] [J]。
        } 
    } 
}

コードフラグメントに示されているように、オリジナルの三次元アレイ、二次元アレイに還元され、各アップデートは、二次元アレイに直接更新します。これが理由であり、kの最も外側のループ- 1をkになる、各値ANS [I] [k]とANS [K] [j]は電流iに(この更新ため、変更されませんkはノードkしない)を介して最短経路途中で、これは順番にそれぞれの値と行わANS [I] [J]の値の比較を更新します。だから我々は、二次元アレイ上にこの更新を指示し、この値の決意がお互いに更新されては影響しません操作の元の値を維持し省略されている間、メモリ空間の多くを保存します。

例5.5 最短 

問題解決のためのアイデア

この例では、最短経路問題の最も簡単です。まず、3重ループを含むフロイドのアルゴリズムは、各ループ反復サイクル時間がNであり、アルゴリズムのフロイドこのような時間複雑性はO(N ^ 3)であり、我々は、上記に示したコードとして与えられた、複雑性を分析します空間の複雑さはNが両方の図内のノードの数であり、O(N ^ 2)です。

本実施形態ではNの最大値は100、N ^ 3時間複雑我々まだ許容範囲です。 

ACコード

#include <cstdioを> INT ANS [ 101 ] [ 101 ]; // グラフの隣接行列の初期値であり、二次元アレイ、int型のmain()
{ int型N-、M;
     一方(scanfの(" %Dの%のD "!&N-、&M)は= )EOFを
    { IF == - (nは0 && m個== 0BREAK ;
         のためのINT I = 1 ; I <= N; I ++は
        { ためINT J = 1 ; J <= N- ; J ++ 
                ANS [I] [J]




    
        
             
            { = - 1 ; // 無限のため-1で、隣接行列を初期化
            } 
            ANS [I] [I] = 0 ; // 独自の経路長に初期化し、0 
        }
         、一方(M- - )// 読み取りパス
        {
             int型A、B、C; 
            scanfの(" %D%D%D "、&​​A、&B、&C); 
            ANS [A] [B] =のANS [B] [A]を= C; // 無向グラフ、2つの代入
        }
         ためのint型 K = 1 ; K <= N; K ++ 
        { 
             INTI = 1 ; iが<= N; iが++ 
            { 
                ためINT J = 1 ; J <= nであり、j ++ 
                { 
                    場合(年[i]が[K] == - 1 ||年[K] [J] == - 1連続もし(年間[I] [J] == - 1 ||年[I] [K] +年[K] [J] <年[I] [J])年[i] [j]は年間= [I ] [K] + 年[K] [J]。
                } 
            } 
        } 
        のprintf(" %Dを\ n "、年[ 1 ] [N])。
    } 
    戻り 0; 
}
ACコード

おすすめ

転載: www.cnblogs.com/yun-an/p/11089120.html