ここでは新しいですが、かなり長い間ゲストとして潜んでいました:)
さて、私はフィボナッチ ヒープ (Java で) を使用して、ダイクストラの最短パス アルゴリズムを実行しようとしています。いくつかの検索の後、フィボナッチ ヒープを表す 2 つの既製の実装に出くわすことができました。最初の実装は非常によくできていて、ここで見つけることができます。2 番目の実装は、あまり洗練されていないように見えますが、ここにあります。
さて、これはすべて見栄えがよく、うまく見えます。ただし、ダイクストラのアルゴリズムのバージョンにこれらの実装の1つを使用したいのですが、まだ運がありません。使用中のダイクストラの実装は次のとおりです。
public void dijkstra(Vertex source) {
{
source.minDistance = 0.;
PriorityQueue<Vertex> vertexQueue = new PriorityQueue<>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex u = vertexQueue.poll();
// Visit each edge exiting u
for (Edge e : u.adjacencies) {
Vertex v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
vertexQueue.remove(v);
v.minDistance = distanceThroughU;
v.previous = u;
vertexQueue.add(v);
}
}
}
}
}
明らかなように、この実装では Java ベースの PriorityQueue クラス (バイナリ ヒープ自体に基づいていると思われます) を使用します。Java の PriorityQueue の代わりに前述のフィボナッチ ヒープ実装のいずれかを使用するように、上記のコードを変更したいと考えています。
私は多くのことを試しましたが、数行のコードを置き換えるのと同じくらい簡単だと確信していますが、それを行う方法がわかりません。
私は十分に明確であることを願っています。これは文字通り、これらのボードでの私の最初の投稿です。
どんな助けでも大歓迎です。
編集:コメントに応えて、私は自分の試みのシナリオの 1 つを使用して投稿を拡張すると考えました。
以下は、前にリンクされた 2 番目のフィボナッチ ヒープ実装を使用した、上記のダイクストラ法の修正版です。
public static void computePathsFibonacciHeap(Node source) {
{
source.minDistance = 0.;
FibonacciHeap myHeap = new FibonacciHeap();
myHeap.insert(source, source.minDistance);
while (!myHeap.isEmpty()) {
Node u = myHeap.min();
// Visit each edge exiting u
for (Edge e : u.adjacencies) {
Node v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
v.minDistance = distanceThroughU;
myHeap.decreaseKey(v, v.minDistance);
v.previous = u;
}
}
}
}
}
これはほとんど疑似コードから直接変換されたものです (したがって、正しく変換しなかった可能性は十分にあります)。「decreaseKey() の値が大きくなりました」というエラーが表示されます。最小値を削除しようとすると、NullPointerException が発生します。
私は何か間違ったことをしていると確信しています。それが何であるかを知りたいです。繰り返しますが、これは 2 番目の FHeap 実装を使用しています。私は最初の実装を使用してそれを行うことを好みましたが (それはより徹底的でプロフェッショナルに見えます)、残念ながらその方法を理解できませんでした。