Primではなく、Kruskalをいつ使用すればよいですか?


192

Primのアルゴリズムをいつ使用する必要があるのか​​、Kruskalがいつ最小のスパニングツリーを見つけるのかについて疑問に思っていましたか?どちらにも簡単なロジックがあり、最悪の場合は同じです。違いは、少し異なるデータ構造を含む可能性のある実装だけです。それで、決定的な要因は何ですか?

回答:


199

エッジの多いグラフがある場合は、プリムのアルゴリズムを使用します。

フィボナッチヒープを使用している場合、V頂点がEエッジのグラフの場合、クラスカルのアルゴリズムはO(E log V)時間で実行され、プリムのアルゴリズムはO(E + V log V)の償却時間で実行できます。

Primのアルゴリズムは、頂点よりもはるかに多くのエッジを持つ本当に密度の高いグラフを取得している場合、制限内で大幅に高速になります。Kruskalは、より単純なデータ構造を使用しているため、一般的な状況(スパースグラフ)でパフォーマンスが向上します。


8
平均ではなく「典型的な状況」と言います。たとえば、ハッシュテーブルの「平均サイズ」とは何かなど、わかりにくい用語だと思います。わからない
yairchu 2009

2
@SplittingField:リンゴとオレンジを比較していると思います。償却分析は、関数(いわば)の測定値を取得する方法を単純化したものです。最悪のケースであるか、平均的なケースであるかは、証明する内容によって異なります。実際(私が今調べているように)、ウィキの記事は、最悪の場合の分析にのみ使用されることを意味する言語を使用しています。さて、そのような分析を使用すると、特定の操作のコストについて強い約束をすることができなくなりますが、アルゴリズムが完了するまでに、最悪の場合でもO(E + VlogV)によって実際にアルゴリズムが実行されます。
agorenst 2009

10
理論的にはいいように聞こえますが、フィボナッチヒープを実装できる人は少ないと思います
Alexandru

2
@tgamblin、最悪の場合C(V、2)エッジが存在する可能性があります。それで、Primのアルゴリズムの時間の完全性は、フィボナッチヒープの場合、O(V ^ 2 + VlogV)、つまりO(V ^ 2)に要約されませんか?
緑のゴブリン

7
もう1つの重要な要素もあります。Primsの出力は、グラフが接続されている場合にのみMSTになります(他の方法では出力が役に立たないように見えます)が、Kruskalの出力は最小スパニングフォレストです(一部使用あり)。
Andrei I

100

ネットで非常にわかりやすいスレッドを見つけ、その違いを非常に簡単に説明しました:http : //www.thestudentroom.co.uk/showthread.php?t=232168

クラスカルのアルゴリズムは、サイクルを作成しないという条件で、次に安いエッジを追加することにより、最も安いエッジからソリューションを成長させます。

Primのアルゴリズムは、次に安価な頂点を追加することにより、ランダムな頂点からソリューションを成長させます。これは、現在ソリューションに含まれていないが、最も安価なエッジによって接続されている頂点です。

ここに添付されているのは、そのトピックに関する興味深いシートです。ここに画像の説明を入力してくださいここに画像の説明を入力してください

KruskalとPrimの両方を最適な形式で実装する場合:ユニオン検索とフィンボナッチヒープをそれぞれ使用すると、Primに比べてKruskalの実装が簡単であることがわかります。

プリムはフィボナッチヒープではより困難です。これは主に、グラフノードとヒープノード間の双方向リンクを記録するために簿記テーブルを維持する必要があるためです。ユニオンファインドを使用すると、その逆になります。構造はシンプルで、ほとんど追加コストなしで直接mstを生成することもできます。


2
Nitpick:それぞれの最後の「スライド」は「スパニングツリーができるまで繰り返す」と表示されます。再帰的なタスクの一部であるMSTまでは-それが最小限であることをどうやって知るのですか-それが私がプリム/クラスカルを最初にフォローしている理由です!
OJFord 2015年

@OllieFordこのスレッドは、PrimおよびKruskalアルゴリズムの簡単なイラストを検索したために見つかりました。アルゴリズムは、ツリーが見つかり、そのツリーがMSTであることを保証します。そして、あなたはあなたが正確な V-1エッジを持っているときにあなたが木を見つけたことを知っています。
mikedu95 2016年

@ mikedu95正解です。以前のコメントとは別の角度から同じ意見を述べています。
OJFord 2016年

ただし、頂点間の重みを1つだけ選択する必要があるという前提条件ではありません。上のグラフから重み2を複数回選択することはできません。次の重みを選択する必要がありますex:3 @Snicolas
ani0904071

30

私はあなたがこれを要求しなかったことを知っていますが、より多くの処理ユニットがある場合は、簡単に並列化できる可能性があるため、常にBorůvkaのアルゴリズムを検討する必要があります。


23

エッジが線形時間でソートできる場合、またはエッジがすでにソートされている場合、Kruskalのパフォーマンスが向上する可能性があります。

頂点へのエッジの数が多い場合、プリムの方が適しています。


19

クラスカル時間複雑度の最悪のケースはO(E log E)です。これは、エッジを並べ替える必要があるためです。 一次時間の複雑性の最悪のケースは、優先キュー付きのO(E log V)またはそれ以上、フィボナッチヒープ付きのO(E + V log V)です。エッジが既にソートされている場合、または線形時間でエッジをソートできる場合は、グラフがスパース、つまりE = O(V)のようにエッジの数が少ない場合、クラスカルを使用する必要があります。グラフが密集している場合、つまりE = O(V²)のようにエッジの数が多い場合は、Primを使用する必要があります。


Primはクラスカルより速度が悪いということはないようです。Eは少なくともV-1でなければならないので、スパニングツリーがあります。スパースグラフにKruskalを選択する理由は、データ構造が非常に単純だからです。
Yu Gu

16

ミドルプリムのアルゴリズムを停止すると、アルゴリズムは常に接続されたツリーを生成しますが、一方でクラスカルは接続されていないツリーまたはフォレストを与える可能性があります


5

クラスカルのアルゴリズムの1つの重要なアプリケーションは、シングルリンククラスタリングです。

n個の頂点を検討すると、完全なグラフがあります。それらのn個の点のk個のクラスターを取得するには、ソートされたエッジのセットの最初のn-(k-1)個のエッジに対してクラスカルのアルゴリズムを実行します。最大のグラフのk-クラスターを取得します間隔。


3

クラスカルの最高の時間はO(E logV)です。プリムがfibヒープを使用している場合、O(E + V lgV)を取得できます。したがって、密なグラフでは、プリムの方がはるかに優れています。


2

プリムは密度の高いグラフに適しています。この場合、主にノードを扱っているため、エッジを追加してサイクルにそれほど注意を払う必要はありません。複雑なグラフの場合、プリムはクラスカルよりも高速です。


2

クラスカルアルゴリズムでは、特定のグラフ上にエッジの数と頂点の数がありますが、各エッジには、値または重みがあります。これらの値または重みを使用して、循環していない、またはどの側からも近くてはならない新しいグラフを準備できます。

このようなグラフ_____________ | | | | | | | __________ | | 頂点a、b、c、d、e、fに名前を付けます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.