lecture2

Lecture02-Binary Search Trees
通信情報システム専攻 岩間伊藤研究室 M1 前田圭介
前回の復習
・データ構造のモデル(List)
・find(x)はリストの最初から始める。
・最初からi 番目の要素へのアクセスにはコスト i が必要
・2つの隣接した要素の入れ替えにはコスト1が必要
・ある要素を見つけたとき、その要素を前方へ動かすのにコストは必要ない
・・・
1
2
3
・・・
i
List
今回の発表内容
今回の発表ではデータ構造として二分木を扱う。
・Binary Search Trees (二分探索木)の定義
・モデルの定義
・二分探索木についてのアルゴリズム
・Splay Trees(スプレー木)
二分探索木(Binary Search Trees)
7
例
3
9
全て7未満
全て7以上
5
8
11
左の子の要素の値 < 現在のノードの要素の値 <= 右の子の要素の値
二分探索木の探索コスト
・二分探索木における操作は次の3つである。
・ポインタを右に移動させる
・ポインタを左に移動させる
・現在のノードを回転させる(後述、Listにおけるswapに対応した操作)
find(5)
7
5<7
3
9
5>3
コスト3
5
8
11
競合比(competitiveness)
・アルゴリズムを評価する際に用いられる指標
あるアルゴリズムがk-competitiveであるとは、どんな入力列 x に対しても
COST ( x)  k  OPT ( x)  c
が成立することである。
COST (x) : 評価したいアルゴリズムの x に対するコスト
OPT (x) : x に対する最小のコスト(オフラインで計算)
あるオンラインアルゴリズムがoptimal であるとは、
それがO(1)-competitiveであることをいう。
今回の発表内容
今回の発表ではデータ構造として二分木を扱う。
・Binary Search Trees (二分探索木)の定義
・モデルの定義
・二分探索木についてのアルゴリズム
・Splay Trees(スプレー木)の定義
・スプレー木の計算量解析
・スプレー木についての結果
stochastic and static model
・stochastic(確率) model
n 個の変数に対して、アクセスされる確率が毎回それぞれ独立である。
1
2
p1 p2
・・・
i
・・・
n
・・・
pi
・・・
pn
・static(静的) model
n 個の変数に対して、アクセスされる確率が毎回独立でなくてもよい。
木のrotateを許さない。(木が初期状態から動かない)
例 アクセス列{1 2 1 2 1 2 1 2 ….}
・stochastic and static model
n 個の変数に対して、アクセスされる確率が毎回それぞれ独立である。
木のrotateを許さない。(木が初期状態から動かない)
stochastic model
・stochastic modelかそうでないかの違いは大きなものである。
[前回の復習] List型のデータ構造におけるTransposeアルゴリズム
10
1
1
2
7
3
・・・
2
3
n/2
find(3) → 3 を一つ前に持ってくる。
・・・
n
stochastic model
・stochastic modelかそうでないかの違いは大きなものである。
[前回の復習] List型のデータ構造におけるTransposeアルゴリズム
10
1
1
2
7
3
・・・
3
2
・・・
n/2
n
find(3) → 3 を一つ前に持ってくる。
・stochastic modelでない場合
アクセス列{3 2 3 2 3 2 3 2 3 2 3…} に対して、最も良い場合に比べてO(n)倍
のコストがかかる。
・stochastic modelの場合
2
3
1/2
1/2
のようなアクセスに対しても、optimalである。
最適な二分探索木
静的モデルの最適な二分探索木は動的計画法(dynamic programming, DP)を
用いて求めることができる。
あるr をrootにして、その左の部分木(<r)と右の部分木(>r)のoptimalを求める。
Cost (r )  1  Pr(left )Cost (left )  Pr( right )Cost (right )
左の木が探索される確率
subproblemsは、O (n 2 ) 個あり、rootの選び方はn 通りあるので、
3
合計O (n ) 時間で解くことができる
このとき、OPTは次のように表現される。
H  log H  log e  1  OPT  H  3
ただし、 H 
 p log 1 / p であり、これはハフマン木のエントロピーである。
i
i
i
dynamic model
木のrotate変換を許すモデル
3
7
rotate 3
3
7
9
5
5
8
11
9
8
11
動的モデルの二分探索木における最適コストの求め方はまだわかっていない。
当然、O(1)-competitiveかどうかもわかっていない。
一般にAVL木や赤黒木のような平衡二分探索木の場合、
探索コストがO(log n)かかることになる
log n
n
木のrotateをうまく利用することで探索コストをo(log n)にできないかを考える。
今回の発表内容
今回の発表ではデータ構造として二分木を扱う。
・Binary Search Trees (二分探索木)の定義
・モデルの定義
・二分探索木についてのアルゴリズム
・Splay Trees(スプレー木)
アクセス頻度の反映


各ノードのアクセス頻度は一定でない
頻繁にアクセスするノードをより浅い位置に置く
多
アクセス頻度
少


オンラインアルゴリズムを考えるので、アクセス列全体を
見て頻繁にアクセスされるノードを上に持っていくことは
できない
最後にアクセスしたノードを浅い位置に持っていく
Transposeアルゴリズム
・最後にアクセスしたノードを一つ上のノードに持っていく(一回rotateする)。
find(D)
find(D)
A
A
B
C
G
D
E
H
F
D
rotate(D)
B
C
G
F
E
D
B
rotate(D)
H
C
A
E
C
G
H
Transposeの探索コスト
・Transposeアルゴリズムは等確率で各ノードにアクセスするような確率モデル
においては平均探索コストがO ( n ) と悪くなってしまう。
[ノード数が3つの場合]
全てのノードのアクセス確率が等確率のとき、全ての状態が等確率で出現する。
A
B
C
A
C
B
C
1/5
C
A
B
1/5
C
A
B
B
1/5
1/5
A
1/5
Move to rootアルゴリズム
・最後にアクセスしたノードがrootにくるまでrotateをおこなう。
find(D)
A
B
C
D
G
D
E
H
F
B
rotate(D),rotate(D)
C
A
E
C
G
H
Move to rootの探索コスト(1)
Move to rootの探索コストの解析はList型のMove to frontの解析と
ほとんど同様である。
i < j としたとき、i がj の祖先となっている確率をb(i, j)とする。
A
B
C
E
BはFの祖先
EはFの祖先でない
D
F

このとき、
j
b(i, j )   pi (1   pl ) 
pi
k
k 0
l i
j
p
l i
l
Move to rootの探索コスト(2)
Move to rootの探索コストCost(MR)は、
n
n
j 1
i 1
i j
Cost ( MR )   p j (1   b(i, j ))  1  2
n 1
 1  2 pi
i 1
ここで、  i , j
1i  j  n
n
p
j i 1
i
pj
 p j
 ( pi    p j ) / pi とすると
 i , j   i , j 1
Cost ( MR )  1  2 pi 
 i, j
i 1
j i 1
n 1

n
pi p j
pi    p j
Move to rootの探索コスト(3)
n 1
 1
 i , j   i , j 1
Cost ( MR )  1  2 pi 
 1  2 pi 

 i, j
x
i 1
j  i 1
i 1
n 1
n
i ,n
i ,i
y = 1/x
 i , j 1
n 1
1  2 pi 
i 1
 i ,n
 i ,i
 i, j  i , j 1
n 1
n 1
1
 1   pi ln  i ,n  1   pi ln( 1 / pi )
x
i 1
i 1
n
 1  (2 ln 2) pi log( 1 / pi )
i 1
Move to rootの探索コスト(3)
・Move to rootアルゴリズムの平均探索コストは
2 ln 2  H  2 ln 2  stochastic OPT
となる。
・これはstochasticであるという条件の下で成立するものであり、
意地の悪いアクセス列を想定した場合はもっと悪くなってしまう。
今回の発表内容
今回の発表ではデータ構造として二分木を扱う。
・Binary Search Trees (二分探索木)の定義
・モデルの定義
・二分探索木についてのアルゴリズム
・Splay Trees(スプレー木)
スプレー木(Splay Tree) [Sleator and Tarjan 1985]



Move to rootの一種。
アクセスしたノードを単純にrootまで持っていくだけでなく、
平衡状態をできるだけ保つようにして移動させる。
rotateをおこなうときに、直前のノードだけでなく2つ上の
ノードまで見てrotate操作の方法を決める。
スプレー木のrotate操作(1)
Zig case: 二つ上のノードが存在しない場合
root
root
A
B
rotate(B)
B
C
E
D
今までと同じようにrotate操作をする。
A
C
D
E
スプレー木のrotate操作(2)
Zig-Zig case:
A
4
B
C
1
3
2
C
rotate(B),rotate(C)
1
B
2
A
3
4
スプレー木のrotate操作(3)
Zig-Zag case:
A
4
B
1
C
rotate(C),rotate(C)
C
2
B
1
3
Move to rootアルゴリズムと同様の操作である。
A
2
3
4
スプレー木のrotate操作(4)
Zig case, Zig-Zig case, Zig-Zag caseの3つを組み合わせてアクセスしたノードを
rootまで移動させる。
E
C
D
A
6
5
rotate(C),
rotate(C)
B
rotate(D),
rotate(C)
1
B
1
2
4
C
2
D
3
3
E
A
4
5
6
スプレー木とMove to root(1)
・Move to rootは均衡をとらない
6
1
5
6
4
5
3
1
2
4
2
3
スプレー木とMove to root(2)
・スプレー木は均衡をとる
6
1
5
4
5
2
3
3
1
4
2
Move to rootアルゴリズムよりは探索コストが少なくて済みそう
6
スプレー木の計算量

償却計算量(amortized complexity)を用いて解析する。


スプレー操作1回ごとに計算
木構造自体にポテンシャルを保持させる。


不均衡な木:ポテンシャルが大きい
均衡な木:ポテンシャルが小さい
計算量解析
・各ノードは次のように表現されるポテンシャルを保持していると定義する。
Ci   log | Ti ( x) |
xTi
Ti:スプレー操作をi回おこなった木
ノード数の和
T0
T1
スプレー操作
T1(x)
T0(x)
x
T0(y)
y
すべての部分木の和をとったものがCi
x
・Ciは平衡な木ほど小さな値になる。
3
1
1
C  log 3  2 log 1  log 3
3
2
1
C  log 3  log 2  log 1  log 3  log 2
ZigZig Caseの計算量
Ti-1
Ti
A
C
B
C
1
4
3
2
B
1
A
2
3
4
ai  2  Ci  Ci 1
 2  log | Ti ( A) |  log | Ti ( B) |  log | Ti (C ) |  log | Ti 1 ( A) |  log | Ti 1 ( B) |  log | Ti 1 (C ) |
 2  log | Ti ( A) |  log | Ti ( B) |  log | Ti 1 ( B) |  log | Ti 1 (C ) |
ZigZig Caseの計算量
a  b  c のとき
( a
b ) 2  a  b  2 ab  0 より
c
ab 
2
が得られて
log a  log b  log c  2
ZigZig Caseの計算量
| Ti (C ) | が成立するので、
ここで、| Ti 1 (C ) |  | Ti ( A) | log | Ti 1 (C ) |  log | Ti ( A) | 2 log | Ti (C ) | 2 が成立
ai  2  log | Ti ( A) |  log | Ti ( B) |  log | Ti 1 ( B) |  log | Ti 1 (C ) | より
ai  2 log | Ti (C ) | 2 log | Ti 1 (C ) |  log | Ti ( B) |  log | Ti 1 ( B) |
A
B
C
1
4
3
2
C
B
1
A
2
3
4
ZigZig Caseの計算量
ai  2 log | Ti (C ) | 2 log | Ti 1 (C ) |  log | Ti ( B) |  log | Ti 1 ( B) |
log | Ti 1 (C ) | log | Ti 1 ( B) |
ここで、 log | Ti ( B) | log | Ti (C ) |,  ai  3 log | Ti (C ) | 3 log | Ti 1 (C ) |
A
B
C
1
4
3
2
C
B
1
A
2
3
4
全体の計算量
ZigZig Case
ai  3(log | Ti (C ) |  log | Ti 1 (C ) |)
ZigZag Case
ai  2(log | Ti (C ) |  log | Ti 1 (C ) |)
Zig Case
ai  1  log | Ti (C ) |  log | Ti 1 (C ) |
Access Lemma
スプレー木における1回のスプレー操作の償却計算量aiは
ai  3(log | Ti (C ) |  log | Ti 1 (C ) |)
として上界を抑えることができる。
このAccess lemmaを用いて、スプレー木に対する様々な結果を導くことができる。
スプレー木の計算量
アクセスした要素をrootに移動させるまでスプレー操作をm回おこなうとする。
m
m
i 1
i 1
A   ai   3(log | Ti (C ) |  log | Ti 1 (C ) |)
 3(log | Tm (C ) |  log | T0 (C ) |)  3 log | Tm (C ) | 3 log n
アクセス回数をk回とすると、 ai
k
 2  Ci  Ci 1 より
k
A
  Ti  Ck  C0
3k log n
O(n log n)
i 1
i
i 1
スプレー木の計算量の結果
以上のことから次のような結果が得られる。
[Logarithmic Access Cost]
スプレー木における1回あたりの探索コストは O (log
n)
・これは、スプレー木の探索コストが平衡二分木と
同程度であることを示している。
今回の計算量解析ではポテンシャルとしてノード数の和を用いた。
ノード数の和ではなく出現確率の和としてポテンシャルをとると、
次のような結果が得られる。
[Static Optimality Theorem]
スプレー木における1回あたりの探索コストは O(log 1 /
pi )
・これは、static treeのOPTと同程度の探索コストで
探索できることを示している。
Ti-1
Ti
A
C
B
C
1
4
3
2
B
1
A
2
3
4
[Static Finger Theorem]
探索をrootから始めるのではなく、あるノードf を指定して
そこから探索を始めるようなモデルを考える。
このときポテンシャルとして1 /(1  (i  f ) 2 )
をとると次のような結果が得られる
スプレー木における1回あたりの探索コストは O (log[ 2 |
x  f |])