差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
次のリビジョン両方とも次のリビジョン
programming:algorithm:data_structure:union_find_tree [2017/08/07] ikatakosprogramming_algorithm:data_structure:union_find_tree [2017/10/08] – ↷ programming:algorithm:data_structure:union_find_tree から programming_algorithm:data_structure:union_find_tree へページを移動しました。 ikatakos
行 19: 行 19:
 =====アルゴリズム===== =====アルゴリズム=====
  
-  * 各グループの要素から、リーダーを1つ決める +  * 各グループの要素から、"代表"を1つ決める 
-  * リーダー以外の要素は、親となる要素を1つずつ持つ +  * 代表以外の要素は、""となる要素を1つずつ持つ 
-    * どの要素からでも、親の親の親……を辿っていけば自身のリーダーに着くようにする +    * どの要素からでも、親の親の親……を辿っていけば自身の代表に着くようにする 
-    * つまり、グループを、リーダーを根とした木構造で表現する+    * つまり、グループを、代表を根とした木構造で表現する
  
-  * ${\rm Union}(x, y)$は、一方のリーダーの親をもう一方のリーダー書き換える +<code> 
-  * ${\rm Find}(x, y)$は、xとyから親を辿って同じリーダーに行き着くか調べる+    1    4    8  ←代表 
 +  ↗↑    ↑ 
 + 2 5    6 
 + ↑     ↗  ↖ 
 + 3    7    9 
 +</code> 
 + 
 +  * ${\rm Union}(x, y)$は、一方の代表もう一方の代表につなぐ(親 
 +  * ${\rm Find}(x, y)$は、xとyから親を辿って同じ代表に行き着くか調べる
  
 ====高速化の工夫==== ====高速化の工夫====
  
-  * 木の階層を低く保たないと、リーダーを見つける処理に時間がかかる +  * 木の階層を低く保たないと、代表を見つける処理に時間がかかる 
-    * はやい例では2~4のどの要素からも、1回調べたらにたどり着ける +    * 以下の例、はやい例では2~4のどの要素からも、1回調べたら代表にたどり着ける 
-    * おそい例では、4からだと、4→3→2→1と3回辿らないとに着かない+    * おそい例では、4からだと、4→3→2→1と3回辿らないと代表に着かない
     * できるだけ、はやい例のような状態を保ちたい     * できるだけ、はやい例のような状態を保ちたい
 <code> <code>
行 44: 行 52:
 </code> </code>
  
-  * 経路圧縮 +===経路圧縮=== 
-    * 一度調べた経路上にある要素は、全て親をリーダーに書き換える +  * 一度調べた経路上にある要素は、全て親を代表に書き換える 
-      * おそい例において、4→3→2→1と調べて1がリーダーだとわかったら、2~4の親を1に書き換える +    * おそい例において、4→3→2→1と調べて1が代表だとわかったら、2~4の親を1に書き換える 
-  ランク + 
-    * 木の最大深さ(ランク)を記録しておく +===ランク=== 
-    * Union時、ランクの低い方のグループを、高い方のグループに吸収させる +  * 木の最大深さ(ランク)を記録しておく 
-      * 互いのランクが等しい場合を除き、ランクが高くならずに済む(等しい場合のみ1増える) +  * Union時、ランクの低い方のグループを、高い方のグループにつなぐ 
-    * ランクは深さでなく、要素数で考えることもある +    * 互いのランクが等しい場合を除き、ランクが高くならずに済む(等しい場合のみ1増える)
-      * 例: 要素数100,最大深さ2のグループと、要素数5,最大深さ4のグループ +
-      * たった5個の要素が深さ5になるより、100個の要素の深さが1ずつ増える方が効率悪くない?という考え方 +
-      * どちらがいいかは場合に依りけり+
  
 <code> <code>
行 69: 行 74:
                       |              |        8                       |              |        8
 </code> </code>
 +
 +ランクは深さでなく、要素数で考えることもある
 +
 +  * 例: 要素数100,最大深さ2のグループAと、要素数5,最大深さ4のグループB
 +    * AにBを繋ぐとBの5個の要素の深さが1ずつ増え、最大深さは5
 +    * BにAを繋ぐとAの100個の要素の深さが1ずつ増え、最大深さは4
 +    * 局所的に最大深さが深くなろうが、100個の要素の深さが1ずつ増える方が効率悪くない?という考え方か
 +  * A.V.Aho, John E. Hopcroft, Jeffrey D. Ulman, 『データ構造とアルゴリズム』, 培風館, 1987
  
 =====実装===== =====実装=====
 +
 +  * 要素数$n$の配列''**table**''を作り、-1で初期化する
 +    * ${\rm table}[x]$が負ならば、$x$は代表。絶対値はランクを示す
 +    * ${\rm table}[x]$が非負ならば、$x$は代表でない。値は$x$の親を示す
 +    * 最初は、$n$個の要素が別々の$n$個のグループに所属している状態
 +  * ''_root''で代表を再帰的に探索する
 +    * ついでに経路圧縮を行う
  
 <sxh python> <sxh python>
programming_algorithm/data_structure/union_find_tree.txt · 最終更新: 2023/05/26 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0