Transcript Document
コンピュータアルゴリズム2
4. 分割統治法
田浦
http://www.logos.ic.i.u-tokyo.ac.jp
/~tau/lecture/software/
内容
分割統治法(divide-and-conquer)の考え方
再帰呼び出しを有効利用したアルゴリズムの簡潔な記述
適用例
クイックソート,マージソート,FFT, 行列積,etc
その他の再帰呼び出し利用例
再帰呼び出しを含むプログラムの計算量
漸化式
分割統治の計算量の一般論
分割統治法のテンプレート
solve(X) {
if (trivial(X)) {
trivial_solve(X);
} else {
X1, X2, ..., Xp = divide(X);
A1 = solve(X1);
A2 = solve(X2);
...
Ap = solve(Xp);
return combine(A1, A2, ..., Ap);
}
}
X
X1
X2
X3
X4
分割統治法のマスター 再帰呼び出しの有効利用法のマスター
再帰呼び出しのマスターが重要な
理由
プログラムの「記述法」として
さもなければ非常にややこしくなるプログラムの記述が非
常に簡潔になる
解法の「発想法」として
「あたかも,より小さな問題の解はわかっている」と仮定し
て,解答を書けばいい
数学での類似物:漸化式による解法
最初から closed form での解を求めるのが難しい問題
を,いったん漸化式を書いてそれを解く,という方法
(用語の注)
再帰呼び出し=分割統治?
NO: ニュアンスとしては,「分割統治法」は,再帰呼び出しを
する際に問題のサイズが当初の問題より十分(定数倍)小さく
なっている場合をいうようである
たとえば普通以下を「分割統治」とは呼ばない
int fib(n) { if (n < 2) return 1; else fib(n – 1) + fib(n – 2); }
しかしそうであろうとなかろうと,「再帰呼び出し」が「記述法・
発想法として有効」なことには違いない
再帰呼び出しの練習(1)
例題: n (整数)が与えられた際に,可能なすべての n 個の{0,
1}列(2n個ある)を列挙せよ
0000...00
0000...01
0000...10
...
1111...11
再帰呼び出しの練習(2)
n要素の整数の配列(a[0], ..., a[n–1])と目標値Tが与えられる.
n個から値を選び出してその和がTとなるようにできるか?
例: a = { 2, 4, 3, 9 }, T = 5 解: 2 + 3 = 5
例: a = { 2, 4, 3, 9 }, T = 8 解: なし
再帰呼び出しの練習(3)
例題: n 円盤のハノイの塔を解く(手順を表示する)プログラ
ムを書け
move 1 a b
move 2 a c
move 1 b c
move 3 a b
move 1 c a
move 2 c b
move 1 a b
1
2
3
a
b
c
再帰呼び出しの練習(4)
1...nまでのすべての並び替えを列挙せよ
123
132
213
231
312
321
注:これらはどれも n に対して指数関数の計算時間を要する
アルゴリズムで,通常「分割統治法」とは呼ばない
「分割統治法」の例(1)
行列積
A00
A01
A
A10
A11
B00
B01
B
B10
C00
C
=
B11
A00 B00 +
A01 B10 =
C00
A00 B01 +
A01 B11 =
C01
A10 B00 +
A11 B10 =
C10
A10 B01 +
A11 B11 =
C11
C01
C10
C11
1辺 N の問題
1辺N / 2の問題 8
「分割統治法」の例(2)
FFT (高速フーリエ変換)
フーリエ変換(連続関数)
g ( y)
1
2
f ( x )e
ixy
dx
離散フーリエ変換(サンプル数N)
は1のN乗根の逆数 = e– i (2 / N)
N 1
g[k ]
f [ j ]
jk
N
(k = 0, 1, ..., N – 1)
j0
FFTはこの計算を高速に行う方法
離散フーリエ変換の行列表示
N 1
gk
f j
jk
N
j0
g 0 1
g1 1
g 1
2
g N 1 1
1
1
1
2
N 1
2
4
( N 1 ) 2
N 1
2 ( N 1 )
( N 1 )( N 1 )
1
f0
f1
f2
f N 1
通常の方法では明らかに N2 回の掛け算が必要
どのように「分割統治」(小さな問題へ分割)できるか
簡単のため N は偶数(後でわかるように2のべき)とする
N = 8の場合の行列
1
1
1
1
1
1
1
1
1
1
1
1
2
2
=
3
=–
4
6
=
3
6
9
4
8
12
5
10
15 =
6
12
18
7
14
21
1
1
5
6
8
10
12
= – 12
15
18
16
20
24
–
20
25
30
24
30
36
= –
28
35
42
=
=
4
1
1
7
14
21
28
35
42
49
偶数行(0, 2, 4, 6)の計算方法
+
しかもこの計算が良く見るとN/2 点 FFTそのもの
奇数行(1, 3, 5, 7)の計算方法
–
残念ながらここはFFTそのものではなく一工夫必要
奇数行の工夫
1
1
1
1
1
2
3
6
5
10
7
14
3
f 0
1
9
f1 1
15
f2
1
21
f 3 1
1
1
2
4
4
8
6
12
N / 2点FFT
1 f 0
6
f1
2
12
f2
3
18
f 3
N 1
g 2k
f j
2 jk
N
f j
jk
N /2
導出(偶数行)
j0
N 1
j0
N / 2 1
N 1
f j
jk
N /2
f j
j0
j N / 2
N / 2 1
N / 2 1
f j
j0
jk
N /2
f j N / 2
j0
N / 2 1
(f
j0
j
jk
N /2
f j N / 2 )
jk
N /2
jk
N /2
N 1
g 2 k 1
f j
2 jk j
N
f j
jk
N /2
導出(奇数行)
j0
N 1
j
N
j0
N / 2 1
N 1
f j
jk
N /2
j
N
f j
j0
j N / 2
N / 2 1
N / 2 1
f j
j0
jk
N /2
j
N
N / 2 1
(f
j0
j
f j N / 2
j0
f j N / 2 )
j
N
jk
N /2
jk
N /2
j
N
jk
N /2
( )
j
N
FFTの計算量は?
O(N log N)
ただし分割統治が続けられるよう, N が2のべきである必要が
ある
分割統治法の計算量に関する一般
論
問題設定(1)
以下のような分割統治法を考える
solve (X) {
if (size(X) = 1) return trivial_solve(X);
else {
X1, X2, ..., Xp = divide(X);
A1 = solve(X1);
...
Ap = solve(Xp);
return merge(A1, ..., Ap);
}
}
問題設定(2)
以下を仮定する.Xiの大きさを inとするとき,
分割と解の併合(divideとmerge)にかかる計算量はあわせ
てO(nk)
定数 c < 1 が存在し,各 i c
定数 d が存在し, 1k + 2k + ... + pk d
大きさ 1のデータに対する(trivial_solve(X)の)計算量は
高々定数(1とする)
定理
このとき大きさnのデータに対するこのアルゴリズムの計算量
T(n)は
O (n )
k
T ( n ) O ( n log n )
O ( n k log 1 / c d )
k
d 1 のとき
d 1 のとき
d 1 のとき
いくつかの例
マージソート
n が n/2 二つに分かれる
分割・併合は O(n)
k = 1, c = 1/2, d = 1 O(n log n)
クイックソート
ただし,定理中の定数 c < 1 の存在を仮定する(実際には
成り立たない)
分割・併合は O(n)
k = 1, d = 1 O(n log n)
行列積
n が n/2 八つに分かれる
分割・併合は O(n2)
k = 2, c = 1/2, d = (1/2)2 8 = 2 O(n2 + log2) = O(n3)
アルゴリズム体操
チャレンジ問題:授業期間を通じて「できた」という人の報告を待つ
アルゴリズム体操(1)
2 2 行列の積は通常 8つの掛け算が必要である
a00
a10
a01
a11
b00
b01
c00
c01
c10
c11
=
b10
b11
[難] これを7つの掛け算(その代わり足し算引き算の数は増え
る)で行う方法がある.それを考えよ
それが見つかるとn nの行列の掛け算をO(n2.81)で行う方法
が導かれる(nは2の冪としてよい)
アルゴリズム体操(2)
n個の要素からなる配列がある.これらの中でn/2個より多く
現れている要素があればそれを見つけ,そのような要素が
なければないと答えるアルゴリズムを作りたい
[易] 計算量 O(n log n)のアルゴリズムを考えよ
[難] 計算量 O(n)のアルゴリズムを考えよ
hint: 分割統治法でk = 1, d < 1となるようなものを見出
せ
アルゴリズム体操(3)
時間計算量O(n log n)が保証されたクイックソートアルゴリズ
ムは,以下の意味で「安全な」pivot pをO(n)で見つけることが
できれば実現可能である(※)
ある定数c < 1 が存在し
a[i] pであるiの個数 c n
a[i] pであるiの個数 c n
[易] (※) を証明せよ
[難] そのようなアルゴリズムFを見つけよ
hint: 分割統治法でk = 1, d < 1であるようなものを見出せ
アルゴリズム体操(4)
n個の相異なる数からなる配列がある.中央値(nの偶奇に応
じn/2番目または (n+1)/2番目の値)を見つけたい
[易] O(n log n)のアルゴリズムを見つけよ
[難] O(n)のアルゴリズムを見つけよ
hint : 前問で求めたアルゴリズムFを用いる.そして,こ
れを利用して分割統治法を使う(k = 1, d < 1)