コード:
パブリック クラスDjkstra { / * 単一ソース最短パス 優先キューの実装に応じO(ElogV)の時間複雑さ、 空間複雑性O(V) djkstr従来幅優先、少しだけより考慮に非常に類似している。一方が異なる重み(必ずしも1) 共通の幅優先思想に基づいて、この経験する頂点=頂点の数のエッジに到達するまでの最短距離を 目的と一般的な幅優先アルゴリズムdjkstrは、のように、周りに到達できるようにします頂点、そしてアクセスへの最初の時間は、(最小コストの頂点へのアクセスを得る) 、その後、問題は体重のプラス側の後、どのように我々はその普通の幅優先思考にそれを発行することがありますか? :1つの方法である 我々は、からなるエッジの中間ノード匿名番号含む重み付け縁を想像することができ 、例えば 1つの画像 (4)A-を- > B \ - (3) - ^ AからBへの2の合計側 点Bから重量3側点として見ることができる -0-0-B(0匿名頂点) しながら、 点Bに、別のエッジがあり、重みは4であるので、と見なすことができます A- 0-0-0-B 、その後完全な画像ショー -0-0-0-B \ -0-0 - ^ 普通幅優先考え方に従い、この時点では、開始点から、最初の点bに行くことができますそれをエッジ点bに到達するための最小コスト、でなければなりませんか? 小さな重量はその辺の重みであります 一般的な幅優先アルゴリズム、共通キューにある私たちが、プライオリティキューに置き換え たび我々はエッジの頂点に達したのコストを探求する+現在の頂点から、計算し、周囲の頂点を探索することができ、時間コスト=ポイントを探索するために、現在の点からコストが 、その後探求とプライオリティキューでのコストの頂点を探求する(パスがそのポイントに到達するならば、我々は常にプライオリティキューの低コストを維持するので、複数ある) の下で私たちは最も低コストに到達できることが第一である、次の頂点を探索するものであるプライオリティキューの頂点から取り出したらその頂点 余分: 同様のアイデア、プリムの加重有向グラフインスタントバージョンの最小スパニングツリーまた、(プライオリティキュー)に使用され、それを探求するために累積ポイントにコストを探検しませんが、直接ことを除いて、 ソートされたプライオリティキューにポイントの最短経路のコストを探索する(これは保証すること探査の次のポイント、歩行過去が現在最低のコスト(貪欲なアイデアの一種))で知られているが 一般的に使用される最短経路も存在します 方法:ベルマンフォード、 * * / EdgeWeightedGraph EWG; IndexMinPQ <フロート> minPQ; フロート []コスト; // Vコスト頂点に達する エッジ[] fromEdge; // 探査を除いて、上でそこから頂点Vエッジを記録頂点は、それぞれが持っている のint Sを、 公衆Djkstra(EdgeWeightedGraph EWG、INT S){ この .ewg = EWG。 この .S = S; minPQ = 新しい IndexMinPQ <> (ewg.v()); コスト = 新しい フロート[ewg.v()]。 fromEdge = 新しいエッジ[ewg.v()]。 以下のために(INT I 0 =; I <cost.length; I ++ ) コスト[I] = Integer.MAX_VALUEの; DJ(); この .ewg = nullを。 } プライベート のボイド DJ(){ minPQ.insert(S + 1 、0F); ながら(!{minPQ.isEmpty())、 int型 V = minPQ.topIndex() - 1; // 探索する現在の頂点 フロート minPQ.delTop vcostを=(); // 現在の頂点に達するの総コストの探索 コストを[V] = vcost; のための(Eエッジ:ewg.adj(V)){ // 頂点の周りにエンキュー INT W = e.other(V); // 現在の位相頂点頂点O のIF(コスト[W] = Integer.MAX_VALUEでは!) // 我々は再び探査を検討していない 続行; IF(minPQ.contain(W + 1)){ //プライオリティキューが既に存在する場合、小の総コストは、探索保持 IF(minPQ.get(W + 1)>コスト[V] + e.weight()){ minPQ.change(W + 1、コストを[W] + e.weight()); fromEdge [W] = E; } } 他{ minPQ.insert(W + 1、コスト[V] +。e.weight()); fromEdge [W] = E; // 最初の頂点を探索する } } } } // 総コストを点Vへの原点から 公共 フロート toVCost(int型V){ 戻りコスト[V]; } // vの点に達する縁そこから開始点から 公共エッジtoVEdgeは(INT V){ 戻り[V] fromEdgeを; } // Vパスポイントにポイント パブリックスタック<エッジ> toVEdges(int型V){ スタック <エッジ>エッジ= 新しい新しいスタック<> (); エッジE = fromEdge [V]; INT TOV = V; ながら(!E = NULL ){ edges.push(E); TOV e.other =(TOV); //到達現在点の原点 E = fromEdge [TOV]; } 戻りエッジ; } パブリック 静的 ボイドメイン(文字列[]引数){ / * *(2) 。。* 1 ---- 3 *(2)/ | \ | * / | \(3)| * 0 | \ |(2) * \ |(1)\ | *(1)\ | \ | * ---- 2. 4 *(4) * * / EdgeWeightedGraph EWG = 新しい新 EdgeWeightedGraph(5。); ewg.addEdge( 0 ,. 1、2 )。 ewg.addEdge(0、2、1 )。 ewg.addEdge( 1、2、1 )。 ewg.addEdge( 1、3、2 )。 ewg.addEdge( 1、4、3 )。 ewg.addEdge( 2、4、4 ); ewg.addEdge( 3、4、2 )。 System.out.println(EWG)。 int型 S = 0 ; INT W = 4 。 Djkstra DJ = 新しいDjkstra(EWG、S)。 System.out.println( + S + "から" + W + "へ" "のパス" ); スタック <エッジ>エッジ= dj.toVEdges(W)。 しばらく(!edges.empty()){ エッジe = edges.pop()。 System.out.print(E + "" ); } のSystem.out.println(); System.out.println( "総コスト:" + dj.toVCost(W))。 } }
輸出
0:0-1 2.00 0-2 1.00 、 1:0-1 2.00 1-2 1.00 1-3 2.00 1-4 3.00 、 2:0~2 1.00 1-2 1.00 2-4 4.00 、 3:1〜2.00 3-4 2.00 、 4:1-4 3.00 2-4 4.00 3-4 2.00 、 より 0~4のパスに: 0-2 1.00 2-4 4.00 、 総コスト: 5.0