PFDS 5.5 Pairing heap

41
5.5 Pairing Heap 2012/03/04 (初版) 2012/04/13 (2版) @yuga

description

Purely Functional Data Structures 5.5 Pairing Heap

Transcript of PFDS 5.5 Pairing heap

Page 1: PFDS 5.5 Pairing heap

5.5 Pairing Heap

2012/03/04 (初版)

2012/04/13 (2版)

@yuga

Page 2: PFDS 5.5 Pairing heap

目次

• データ構造

• 特徴

• 実装

• 解析(最悪実行時間)

• 解析(Amortized時間)

Page 3: PFDS 5.5 Pairing heap

データ構造

• ヒープ規則で順序づけられた多分岐木

– (整数で小さい順なら)親はどの子より小さい ※以後、これを採用して説明します

• data PairingHeap a = E | T a [PairingHeap a]

– ただし、Heapの子に E は登場しない

Fredman, Michael L.; Sedgewick, Robert; Sleator, Daniel D.; Tarjan, Robert E. (1986),

"The pairing heap: a new form of self-adjusting heap“

http://www.lb.cs.cmu.edu/afs/cs.cmu.edu/user/sleator/www/papers/pairing-heaps.pdf

Page 4: PFDS 5.5 Pairing heap

図解: データ構造

3

5

2

7 8

9 4 6

Page 5: PFDS 5.5 Pairing heap

特徴

• 実装が単純で簡単

• 実用上すぐれた性能をもつ

• 正確なamortized時間を解析することが困難

Page 6: PFDS 5.5 Pairing heap

実装: Heapの関数

テキストより:

• findMin

• merge

• insert

• deleteMin

Page 7: PFDS 5.5 Pairing heap

実装: findMin

• 木はヒープ規則で順序づけられているので、findMinの実装は自明

• 単にheapの最上位要素を返す

findMin (T x _) = x

Page 8: PFDS 5.5 Pairing heap

実装: merge

• merge関数はふたつの木のルート要素を比較して、

小さい方を結果のルートに残し、大きい方とその部分木をルートの部分木として追加する

merge h E = h merge E h = h merge h1@(T x hs1) h2@(T y hs2) | x < y = T x (h2:hs1) | otherwise = T y (h1:hs2)

Page 9: PFDS 5.5 Pairing heap

図解: merge

merge 3

6 4

5

2

7 8

9

3

6 4

5

2

7 8

9

3

5

2

7 8

9 4 6

Page 10: PFDS 5.5 Pairing heap

実装: insert

• insert関数は追加する要素に対して新しい木を作り、追加先の木にマージする。

insert x h = merge (T x []) h

Page 11: PFDS 5.5 Pairing heap

図解: insert

insert 5 E

insert 4 5

insert 3 4

5

insert 6 3

4

5

5

4

5

3

4

5

3

6 4

5

Page 12: PFDS 5.5 Pairing heap

実装: deleteMin

• ルートを取り除き、部分木をマージする。

mergePairs [] = E mergePairs [h] = h mergePairs (h1:h2:hs) = merge (merge h1 h2) mergePairs hs deleteMin (T x hs) = mergePairs hs

Page 13: PFDS 5.5 Pairing heap

図解: deleteMin

merge merge merge merge

merge

merge

② Pairing

③ Combining

① 削除

Page 14: PFDS 5.5 Pairing heap

図解: deleteMin

3

5

2

7 8

9 4 6 5

3

7 8

9

4 6

Page 15: PFDS 5.5 Pairing heap

実装: 二分木への変換

• 二分木のデータ構造

• 変換

toBinary :: PairingHeap a -> BinTree a toBinary E = E' toBinary (T x hs) = T' (tree hs) x E' where tree [] = E' tree ((T x hs1):hs2) = T' (tree hs1) x (tree hs2)

data BinTree a = E' | T' (BinTree a) a (BinTree a)

Page 16: PFDS 5.5 Pairing heap

図解: half-ordered binary tree へ変換

3

5

2

7 8

9 4 6

2

3

6

4

5

7

8

9

E

E

E E

E

E E E E

Page 17: PFDS 5.5 Pairing heap

解析: 最悪実行時間

• O(1)

– findMin、insert、mergeの各関数は、最悪時間O(1)で実行できる

• 実装をみればすぐわかる

• O(n)

– deleteMin関数は最悪O(n)時間を要する

• ルートの子に、他のすべてのノードがあるような場合、そこから最少のノードを見つけるのにO(n)

Page 18: PFDS 5.5 Pairing heap

解析: Amortized時間

どうする?

• 適当な構造を仮定してみる

– Scrambled Pairing

• 既存のデータ構造との類似点に注目する

– Splay木

Page 19: PFDS 5.5 Pairing heap

仮定: Scrambled Pairing (1)

以下の構造で、insert、deleteMinを繰り返す

insert

Root削除

pairing

最大の木に combining

Page 20: PFDS 5.5 Pairing heap

仮定: Scrambled Pairing (2)

• ポテンシャル関数 – 木のノード数をn、各ノードが持つ子の数をd – 木のポテンシャルは、各ノードのポテンシャルの合計 – 各ノードのポテンシャル

1 − min 𝑑, 𝑛

• 解析: 実コスト – ルートを削除したとき、k個の木が残ると仮定する – コストをPairing時のmerge回数とする ⇒ 𝑘/2 + 1

Page 21: PFDS 5.5 Pairing heap

仮定: Scrambled Pairing (3)

• 解析: ポテンシャルの変化 – ルートの削除で高々 2 𝑛 増加

• 削除されたルートのポテンシャル: 1 − √𝑛 から 0

• 少なくとも √𝑛 個の子を持つノードごとに 1 増加

– Pairing時のmergeごとに 1 減少 • ただし、 すでに √𝑛 個の子をもつノードを除く (そういうノードは高々 𝑛存在する)

⇒ 𝑘/2 − √𝑛

⇒ 𝑘/2 + 1 + 2 𝑛 + ( 𝑛 − 𝑘

2 ) = 𝑂(√𝑛)

Page 22: PFDS 5.5 Pairing heap

類似点: Splay木

• Pairing Heapでの構造変化

– Pairing

– Paring & Combining

• Splay木での構造変化

– Splaying

Page 23: PFDS 5.5 Pairing heap

図解: Pairingによる構造変化

X

Y

A

B C

X

B A

C

Y

Y

A B

C

X

X < Y の場合

X > Y の場合

Page 24: PFDS 5.5 Pairing heap

図解: Pairing & Combiningによる構造変化

Pairing

Combining

Page 25: PFDS 5.5 Pairing heap

図解: Splayingによる構造変化

トップダウン Splaying (zig-zig)

Page 26: PFDS 5.5 Pairing heap

類似点: Splay木

Pairing HeapのParing & CombiningはSplay木のSplayingと同じ効果がある。

Page 27: PFDS 5.5 Pairing heap

解析: Amortized時間

• Amortized時間

– Splay木との類似点から、insert関数、merge関数、deleteMin関数がどれもすべてO(log n)のamortized時間で実行するといえる

– insert関数とmerge関数は実際にはO(1)のamortized 時間で実行すると推測されているが、

しかし誰もこの主張を証明したり反証した者はいない

Page 28: PFDS 5.5 Pairing heap

解析: Amortized時間

Pairing HeapのParing & CombiningはSplay木のSplayingと同じ効果がある。

Splay木のポテンシャル関数を使おう。

Page 29: PFDS 5.5 Pairing heap

解析: ポテンシャル関数

• 定義

– Paring Heapを2分木に変換した木

• ノード数: n

• ノード x のサイズ: #x = x を根とする部分木のノード数(xを含む)

• ノード x のポテンシャル: φ(x) = log(#x)

• 木 t 全体のポテンシャル: Φ(t) = その木すべてのノードのポテンシャルの合計

Page 30: PFDS 5.5 Pairing heap

解析: ポテンシャル関数

• 定義(続き)

–複数の木の集合

• 木を持たない場合は 0

• 常にnon-negative

Page 31: PFDS 5.5 Pairing heap

解析: findMin

• O(1)

–ポテンシャルの変化がないため

Page 32: PFDS 5.5 Pairing heap

解析: insert / merge

• O(log n)

–高々 log(n) + 1のポテンシャル増加による

• ノード数の少ない方の木のルート: 高々log(n)増加

• ノード数の多い方の木のルート: 高々1増加

– より多い方のルートが配下に組み入れられる最大のノード数を持った相手は、自分と同じだけの数を持った相手)

log 𝑛 − log𝑛

2= log 𝑛 ×

2

𝑛= log 2 = 1

Page 33: PFDS 5.5 Pairing heap

解析: deleteMin

• O(log n)

– 実コスト

• 1 + mergeの実行回数

– ポテンシャルの変化

• ルートの削除 – ポテンシャルlog(n)の減少

• Pairing

• Combining

– 全体

Page 34: PFDS 5.5 Pairing heap

解析: Pairing (1)

部分木Cが空でない場合: – Pairingでmergeを1回実行したときのポテンシャルの増加( 部分)

ϕ 𝑥′ − 𝜙 𝑦 = log #𝑎 + #𝑏 + 1 − log (#𝑏 + #𝑐 + 1)

x

y

a c

y'

c x'

a

b b

merge

Page 35: PFDS 5.5 Pairing heap

解析: Pairing (2)

– mergeによるポテンシャル増加の上界 𝑥, 𝑦 > 0 , 𝑥 + 𝑦 ≤ 1 となる、すべての x, y について

log 𝑥 + log 𝑦 ≤ −2 したがって、 log #𝑎 + #𝑏 + 1 + log #𝑐 − 2 log #𝑎 + #𝑏 + #𝑐 + 2

= log#𝑎 + #𝑏 + 1

#𝑎 + #𝑏 + #𝑐 + 2+ log

#𝑐

#𝑎 + #𝑏 + #𝑐 + 2

≤ −2 log #𝑐 ≤ log(#𝑏 + #𝑐 + 1) だから、②と③より、

log #𝑎 + #𝑏 + 1 − log #𝑏 + #𝑐 + 1< 2 log #𝑎 + #𝑏 + #𝑐 + 2 − 2 log #𝑐 − 2 = 2 log #𝑥 − 2 log #𝑐 − 2

Page 36: PFDS 5.5 Pairing heap

解析: Pairing (3)

部分木Cが空の場合: – Paringでmergeを1回実行したときのポテンシャルの増加

ϕ 𝑥′ − 𝜙 𝑦 = log #𝑎 + #𝑏 + 1 − log #𝑏 + 1 ≤ 2log #𝑎 + #𝑏 + 2 = 2 log #𝑥

x

y a c

y'

c x'

a

b b

merge

Page 37: PFDS 5.5 Pairing heap

解析: Pairing (4)

• Pairing全体のポテンシャル増加の上界 𝑥1, 𝑥2, 𝑥3, 𝑥4, … , 𝑥2𝑘−1, 𝑥2𝑘 をParingでmergeする部分木のルート集合と

する。

2log #𝑥2𝑖−1 − 2 log #𝑥2𝑖+1 − 2

𝑘−1

𝑖=1

+ 2 log 𝑥2𝑘−1

𝑥1 𝑥2 𝑥3 𝑥4 𝑥2𝑘−1 𝑥2𝑘

⑥ ④ ⑤

Page 38: PFDS 5.5 Pairing heap

解析: Pairing (5)

⑥ = 2 log #𝑥2𝑖−1 − 2 log #𝑥2𝑖+1

𝑘−1

𝑖=1

+ 2 log 𝑥2𝑘−1 − 2 𝑘 − 1

= 2 log #𝑥1 − 2 𝑘 − 1

= 2 log 𝑛 − 2(𝑘 − 1)

Page 39: PFDS 5.5 Pairing heap

解析: Combining

𝜙 𝑥′ + 𝜙 𝑦′ − 𝜙 𝑥 + 𝜙 𝑦

= log 𝑛 − 1 + log 𝑛 − log 𝑛 − log 1

= log 𝑛 − 1

z

x’

y’

x

y z

Page 40: PFDS 5.5 Pairing heap

解析: deleteMin全体

実コスト +①ルート除去 +⑦𝑃𝑎𝑟𝑖𝑛𝑔 +⑧𝐶𝑜𝑚𝑏𝑖𝑛𝑔

= 2𝑘 + 1 + − log 𝑛 + 2 log 𝑛 − 2(𝑘 − 1) + log 𝑛 − 1

= log 𝑛 + log 𝑛 − 1 + 3

≤ 2log 𝑛 + 3 = 𝑂 log 𝑛

Page 41: PFDS 5.5 Pairing heap

参考文献

• Chris Okasaki, “5.5 Paring Heaps”, Purely Functional Data Structures, Cambridge University Press (1999)

• Wikipedia, “Paring heap”, on 29 January 2012 at 15:45 http://en.wikipedia.org/wiki/Pairing_heap

• Fredman, Michael L.; Sedgewick, Robert; Sleator, Daniel D.; Tarjan, Robert E., "The pairing heap: a new form of self-adjusting heap“, 1986 http://www.lb.cs.cmu.edu/afs/cs.cmu.edu/user/sleator/www/papers/pairing-heaps.pdf