[概要]グラフ理論アルゴリズム - 最短経路
まず、概念
最短経路問題。すなわち、最短図中の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個== 0)BREAK ; のための(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; }