最小スパニングツリーを見つけるために Primのアルゴリズム と Kruskal's を使用する必要があるのはいつですか?どちらにも簡単なロジックがあり、最悪の場合も同じですが、実装が異なるだけで、データ構造が少し異なる場合があります。それで、決定要因は何ですか?
グラフに多数のエッジがある場合は、Primのアルゴリズムを使用します。
V頂点Eエッジを持つグラフの場合、クラスカルアルゴリズムはO(E log V)時間で実行され、PrimのアルゴリズムはO(E + V log V )フィボナッチヒープ を使用した場合の償却時間。
Primのアルゴリズムは、頂点よりもはるかに多くのエッジを持つ非常に高密度のグラフを取得した場合に、限界において非常に高速になります。 Kruskalは、単純なデータ構造を使用するため、一般的な状況(スパースグラフ)でパフォーマンスが向上します。
ネット上で非常に簡単な方法で違いを説明する非常に素晴らしいスレッドを見つけました: http://www.thestudentroom.co.uk/showthread.php?t=232168 。
Kruskalのアルゴリズムは、サイクルを作成しない限り、次に安いEdgeを追加することにより、最も安いEdgeからソリューションを成長させます。
Primのアルゴリズムは、次に安価な頂点を追加することにより、ランダムな頂点からソリューションを成長させます。この頂点は、現在ソリューションに含まれていないが、最も安価なEdgeによって接続されています。
このトピックに関する興味深いシートを添付します。
KruskalとPrimの両方を最適な形式で実装する場合、それぞれunion findとfinbonacciヒープを使用すると、KruskalがPrimと比較して実装が簡単であることに気付くでしょう。
主にフィボナッチヒープでは、グラフノードとヒープノード間の双方向リンクを記録するためにブック管理テーブルを維持する必要があるため、Primはより困難です。 Union Findを使用すると、逆になります。構造は単純で、ほとんど追加費用なしで直接mstを生成できます。
あなたはこれを要求しなかったことを知っていますが、より多くの処理ユニットがある場合は、 Borůvkaのアルゴリズム を常に考慮する必要があります。プリムアルゴリズム。
Kruskalは、エッジが線形時間で並べ替えられるか、既に並べ替えられている場合、パフォーマンスが向上します。
頂点へのエッジの数が多い場合、プリムの方が優れています。
中間プリムのアルゴリズムでアルゴリズムを停止すると、常に接続されたツリーが生成されますが、一方、クラスカルは切断されたツリーまたはフォレストを与える可能性があります
Kruskal時間の複雑さの最悪のケースはO(E log E)です。これは、エッジをソートする必要があるためです。 Prim時間の複雑さの最悪のケースはO(E log V) with priority queueまたはそれ以上、O(E + V log V) with フィボナッチヒープ。グラフがまばらな場合、つまりE = O(V)などの少数のエッジの場合、エッジが既にソートされている場合、または線形時間でソートできる場合は、クラスカルを使用する必要があります。 E = O(V²)のように、グラフが密集している場合、つまりエッジの数が多い場合は、Primを使用する必要があります。
Kruskalのアルゴリズムの重要な用途の1つは、シングルリンククラスタリングです。
N個の頂点を検討すると、完全なグラフが得られます。これらのn個のポイントのkクラスターを取得するには、ソートされたエッジセットの最初のn-(k-1)エッジに対してKruskalのアルゴリズムを実行します。間隔。
クラスカルの最適な時間はO(E logV)です。 fibヒープを使用するプリムの場合、O(E + V lgV)を取得できます。したがって、密なグラフでは、プリムの方がはるかに優れています。
Kruskalアルゴリズムでは、特定のグラフにエッジの数と頂点の数がありますが、各エッジにいくつかの値または重みがあり、そのために、新しいグラフを準備することができます。
このようなグラフ_____________ | | | | | | | __________ | |頂点a、b、c、d、e、fに名前を付けます。
Primの方が密度の高いグラフに適しています。また、主にノードを扱っているため、Edgeを追加してサイクルにあまり注意を払う必要もありません。複雑なグラフの場合、プリムはクラスカルよりも高速です。