ダイクストラのアルゴリズム
英語で:
これは、ポイント A からポイント B への最短ルートを見つけるためのアルゴリズムです。
計算用語では、ノードとアークで構成されるグラフへのルートを単純化します。各ノードは中間点を表し、各アークは 2 つのノードを接続し、2 つのノード間を移動するコストを表す (負ではない) 重みを持ちます。
アルゴリズムを実装するには、2 つのリストが必要です。
- finished: 到達するための最小コストを計算した (node,cost) のセット。
- working: チェックされた (node,cost) のソートされたリスト。
アルゴリズム:
working.addNode(Start, 0); // No cost to get to start.
for( (node, cost) = working.popHead(); node != End; (node,cost) = working.popHead())
{
// If we have already processed this node ignore it.
if (finished.find(node))
{ continue;
}
// We have just removed a node from working.
// Because it is the top of the list it is guaranteed to be the shortest route to
// the node. If there is another route to the node it must go through one of the
// other nodes in the working list which means the cost to reach it will be higher
// (because working is sorted). Thus we have found the shortest route to the node.
// As we have found the shortest route to the node save it in finished.
finished.addNode(node,cost);
// For each arc leading from this node we need to find where we can get to.
foreach(arc in node.arcs())
{
dest = arc.dest();
if (NOT (finished.find(dest)))
{
// If the node is already in finished then we don't need to worry about it
// as that will be the shortest route other wise calculate the cost and add
// this new node to the working list.
destCost = arc.cost() + cost;
working.addNode(dest,destCost); // Note. Working is sorted list
}
}
}
したがって、このアルゴリズムについて考えると。ロンドンからマンチェスターに旅行しているとします。
finished = {} // empty.
working = { (London,0) }
次のコスト マトリックスを使用します。
L S O B N M W
(L) ondon - 50 60 100 130 - -
(S) outhampton 50 - 70 - - - -
(O) xford 60 70 - 50 - 200 -
(B) irmingham 100 - 50 - - 80 110
(N) orwich 130 - - - - - -
(M) anchester - - 200 80 - - 80
Ne(W) castle - - - 110 - 80 -
ここで、London を作業リストから (先頭にあるため) 取り出し、完了リストに配置します。次に、ロンドンに直接接続されているすべての町を作業リストに追加します。
finished = { (London,0) }
working = { (Southampton, 50), (Oxford, 60), (Birmingham, 100), (Norwich,130) }
ワーキング セットの町を、ロンドンから拡大したバブルの外縁と考えてください。ダイクストラのアルゴリズムの仕事は、マンチェスターに到達するまでバブルを拡大し続けることです (すでに行った手順をたどることはありません)。そのため、泡は常に外側に膨張し、泡の最も小さい部分を常に膨張させます。
したがって、次のステップは、リストの先頭を取得して繰り返すことです。サウサンプトンからの目的地は 2 つだけです。ロンドン(完成したリストにあるので破棄します)とオックスフォードに戻ります。オックスフォードまでの費用は、50 + サウサンプトンからオックスフォードまでの費用です (作業リストに 2 回あることに注意してください。最適なルートではないため、後で破棄しますのでご安心ください)。
finished = { (London,0), (Southampton,50) }
working = { (Oxford, 60), (Birmingham, 100), (Oxford, 120), (Norwich,130) }
だからループを繰り返す。リストの先頭はオックスフォードです。オックスフォードからマンチェスター(200)、バーミンガム(50)に行くか、ロンドン(60)またはサウサンプトンに戻ることができます(上記の各コストにオックスフォードに行くためのコストを追加する必要があることを思い出してください。オックスフォードからはサウサンプトンに行きましたが、すでにサウサンプトンへの最短ルートを見つけているので、処理は必要ありません) これにより、次のようになります。
finished = { (London,0), (Southampton,50), (Oxford, 60) }
working = { (Birmingham, 100), (Birmingham,110), (Oxford, 120), (Norwich,130), (Manchester,200)}
現在、作業リストにマンチェスターが含まれていることに注意してください (これが目的地です)。しかし、もっと短いルートが見つかるかもしれないので、作業を続ける必要があります。それで今、私たちはバーミンガムから拡大しています。そこから、オックスフォード(50)、マンチェスター(80)、ロンドン(100)、ニューカッスル(110)に行くことができます。最初にバーミンガムまでの交通費を追加すると、次のようになります。
finished = { (London,0), (Southampton,50), (Oxford, 60), (Birmingham, 100) }
working = { (Birmingham,110), (Oxford, 120), (Norwich,130), {Manchester, 180), (Manchester,200), (Newcastle, 210)}
次の 2 つのノード。オックスフォードとバーミンガムはすでに終了リストにあるため、無視できます。したがって、ノリッジからマンチェスターまで 50 マイル未満のルートがない限り、その後の反復でマンチェスターに到達します。