Primのアルゴリズムをいつ使用する必要があるのか、Kruskalがいつ最小のスパニングツリーを見つけるのかについて疑問に思っていましたか?どちらにも簡単なロジックがあり、最悪の場合は同じです。違いは、少し異なるデータ構造を含む可能性のある実装だけです。それで、決定的な要因は何ですか?
Primのアルゴリズムをいつ使用する必要があるのか、Kruskalがいつ最小のスパニングツリーを見つけるのかについて疑問に思っていましたか?どちらにも簡単なロジックがあり、最悪の場合は同じです。違いは、少し異なるデータ構造を含む可能性のある実装だけです。それで、決定的な要因は何ですか?
回答:
エッジの多いグラフがある場合は、プリムのアルゴリズムを使用します。
フィボナッチヒープを使用している場合、V頂点がEエッジのグラフの場合、クラスカルのアルゴリズムはO(E log V)時間で実行され、プリムのアルゴリズムはO(E + V log V)の償却時間で実行できます。
Primのアルゴリズムは、頂点よりもはるかに多くのエッジを持つ本当に密度の高いグラフを取得している場合、制限内で大幅に高速になります。Kruskalは、より単純なデータ構造を使用しているため、一般的な状況(スパースグラフ)でパフォーマンスが向上します。
ネットで非常にわかりやすいスレッドを見つけ、その違いを非常に簡単に説明しました:http : //www.thestudentroom.co.uk/showthread.php?t=232168。
クラスカルのアルゴリズムは、サイクルを作成しないという条件で、次に安いエッジを追加することにより、最も安いエッジからソリューションを成長させます。
Primのアルゴリズムは、次に安価な頂点を追加することにより、ランダムな頂点からソリューションを成長させます。これは、現在ソリューションに含まれていないが、最も安価なエッジによって接続されている頂点です。
ここに添付されているのは、そのトピックに関する興味深いシートです。
KruskalとPrimの両方を最適な形式で実装する場合:ユニオン検索とフィンボナッチヒープをそれぞれ使用すると、Primに比べてKruskalの実装が簡単であることがわかります。
プリムはフィボナッチヒープではより困難です。これは主に、グラフノードとヒープノード間の双方向リンクを記録するために簿記テーブルを維持する必要があるためです。ユニオンファインドを使用すると、その逆になります。構造はシンプルで、ほとんど追加コストなしで直接mstを生成することもできます。
V-1
エッジを持っているときにあなたが木を見つけたことを知っています。
私はあなたがこれを要求しなかったことを知っていますが、より多くの処理ユニットがある場合は、簡単に並列化できる可能性があるため、常にBorůvkaのアルゴリズムを検討する必要があります。
エッジが線形時間でソートできる場合、またはエッジがすでにソートされている場合、Kruskalのパフォーマンスが向上する可能性があります。
頂点へのエッジの数が多い場合、プリムの方が適しています。
クラスカル時間複雑度の最悪のケースはO(E log E)です。これは、エッジを並べ替える必要があるためです。 一次時間の複雑性の最悪のケースは、優先キュー付きのO(E log V)またはそれ以上、フィボナッチヒープ付きのO(E + V log V)です。エッジが既にソートされている場合、または線形時間でエッジをソートできる場合は、グラフがスパース、つまりE = O(V)のようにエッジの数が少ない場合、クラスカルを使用する必要があります。グラフが密集している場合、つまりE = O(V²)のようにエッジの数が多い場合は、Primを使用する必要があります。