nazoki
Post on 24-May-2015
3.241 Views
Preview:
DESCRIPTION
TRANSCRIPT
van Emde Boas Trees〜明日から使えない謎の速い木〜
catupper
van Emde Boas Treesとは
● 読み:ばん えんで ぼーす● 以下「謎木」● 集合(set)● 非常に速い● あらゆる操作がO(lg lg u)● 実装が重い
機能要件
● MAXIMUM 最大値● MINIMUM 最小値● MEMBER 有無● INSERT 挿入● DELETE 削除● SUCCESSOR それより大きい最小の要素● PREDECESSOR それより小さい最大の要素
平衡二分探索木
● 葉にビットを立てて有無を表現● 親は全子孫のORの結果を保持(Summary)
1
0 1
0 0 0 1
0 0 0 0 0 0 1 0
0 1 2 3 4 5 6 7
各オーダー
● MAXIMUM log u● MINIMUM log u● MEMBER log u● INSERT log u● DELETE log u● SUCCESSOR log u● PREDCESSOR log u● 木の深さに依存
深さを
log log uにしたい
平方兵法
● サイズu の親は サイズ√uの子を√u個持つ● 最小サイズは2● 深さはlog log u
サイズ256
サイズ4 サイズ4 サイズ4 サイズ4
サイズ2 サイズ2
各ノードのデータ
● サイズuのノード
● 最大値● 最小値● 子へのポインタ● Summary
– 各子に対する そのノードとその子孫のOR値
サイズ U
Summary 木
Cluster
木 木 木 木 木
最大値 max 最小値 min
全体図
各オペレーションのオーダー
MIN,MAX,MEMBER
● MIN、MAX– 子孫の最大値と最小値を各親が持ってる
– O(1)
● MEMBER– 該当箇所へ降りて行って確認するだけ
– 処理数は深さ分
– O(log log u)
SUCCESSOR,PREDCESSOR
● SUCCESSOR
– 木を下りながら
– minより小さくなったらminを返す
– maxより大きくなったら次の兄弟のminを返す
– 次の兄弟はsummaryからSUCCESSORで探す
– 処理数は深さ分
– O(log log u)● PREDCESSOR
– 逆も然り
INSERT
● INSERT– 該当場所へ向かって木を降りて行って
– minもmaxも未定義だったら両方に入れてsummaryを更新して終わる
– minより小さかったら値を交換して再帰続行
– maxより大きかったらmaxを更新
– 処理数は深さ分
– O(log log u)
DELETE
● DELETE– 該当箇所に向かって降りていく
– minとmaxが等しかったら削除して終了
– minと等しかったらsummaryのminのminで更新
– maxと等しかったらsummaryのmaxのmaxで更新
– いた木のminとmaxが等しかったらsummary更新
– O(log log u)
超ややこしい
要するに
● maxとminで要素数が0か1か2以上かを判断– Summaryの更新が必要かを判断
● どの要素もいずれかの木のmin– min maxを中心にオペレーションを回せる
● Summaryはminを扱わない– 削除のとき更新が楽になる
● 要素数が2未満ならそこで再帰終了– 必要メモリが減る
空間計算量
● 扱う数字の範囲分(u)必要● よってO(u)● Int型なら32bit● 大きい
使えない?
工夫
● オペレーションは空の木の子に行かない● 空の木はINSERT時以外更新されない● INSERT時に動的につくればええやん● 木の数は要素数(n)を超えない● よって空間計算量O(n)
やったねたえちゃん
二分ヒープと同じ
まとめ
● ヒープ並のメモリ使用量でO(log log u)で同じ機能をサポート
● 実装– ややこしいオペレーション関数
– ややこしい構造
– 動的ハッシュ
– スクリプト言語に向いてない
– デバッグ大変でした
まとめ
使えるまでメモリを削減するには動的ハッシュが必要
実装が重い!
結論
結論
実装できんかった><
謎木速いんだけど
微妙にバグる
結論
ご清聴ありがとうございました
top related