数理工学のすすめ
東京大学大学院情報理工学系研究科
数理情報学専攻
定兼 邦彦
2016年4月7日
http://researchmap.jp/sada/resources/
自己紹介
•
•
•
•
•
•
•
•
名前: 定兼 邦彦 (さだかね くにひこ)
所属: 東京大学大学院情報理工学系研究科数理情報学専攻
経歴: 1991年理1入学,2000年理学系研究科情報科学専攻修了
2000年 東北大学大学院情報科学研究科助手
2003年 九州大学大学院システム情報科学研究院助教授
2009年 国立情報学研究所准教授
2014年 東京大学大学院情報理工学系研究科教授
研究分野: データ圧縮,データ構造,情報検索
•
•
•
•
最近の研究:
ビッグデータ処理
簡潔データ構造
並列アルゴリズム
2
アルゴリズムとデータ構造
• アルゴリズム (algorithms, 算法): 計算等の手順
– 数を小さい順に並べる (ソート)
– Webのキーワード検索
– 最短経路探索
• データ構造 (data structures): 計算機にデータを
格納する方法
– 配列,リスト,ハッシュ,2分木
• アルゴリズムやデータ構造を工夫すると,
同じ問題が高速に解けるようになる
3
ビッグデータ処理の問題点
• 大量のデータがあるとき,それを圧縮することで
ディスク容量や通信コストを抑えられる
• しかし圧縮してあるデータを使うときは復元しな
ければならない
データを圧縮したまま使えないか?
• データを高速に処理するにはデータ構造を用い
るが,そのサイズも問題になる
データ構造も圧縮できないか?
4
モールス符号 (信号)
•
•
•
•
•
1830年代に提案
短点 ・ と長点 - の組み合わせ
長点は短点3つ分の長さ
SOS = ・ ・ ・- - -・ ・ ・
英語で使われる頻度の高い e, t は
短い符号 ・, - になっている
⇒データ圧縮
文字
符号
文字
符号
A
・-
N
-・
B
-・・・
O
---
C
-・-・
P
・--・
D
-・・
Q
--・-
E
・
R
・-・
F
・・-・
S
・・・
G
--・
T
-
H
・・・・
U
・・-
I
・・
V
・・・-
J
・---
W
・--
K
-・-
X
-・・-
L
・-・・
Y
-・--
M
--
Z
--・・
5
• s から t へ矢印の通りに移動するルートを
表現するには
t
Q
s
P
P:
Q:
0010110
1100001
7ビットで表現できる
もっと小さくできる?
6
• s から t へ矢印の通りに移動する行き方は
何通り?
• ルートは4個の→と3個の↑で表現できる
• 逆に,4個の→と3個の↑をどういう順に並べても,
それは s から t へのルートになっている
t
• 行き方は
通り
7 C3 7 C4 35
Q
7 7
35
3 4
• 26 = 64 > 35 なので,
6 ビットで表現できる
s
P
P:
Q:
• s から t へのルートを 6 ビットで表現するには
どう符号化すればいいか
• 各ルートを 0 から 34 の整数で表現する
6
• s から最初に右に行くルートは 20 通り
3
– 0 から 19 の整数で表現する
• s から最初に上に行くルートは
– 20 から 34 の整数で表現する
6
15
2
通り
t
Q
s
P
8
• s から最初に右に行くルート20個を考える
5
• 次に右に行くルートは 3 10 通り
– 0 から 9 の整数で表現する
• 次に上に行くルートは
5
10
2
通り
– 10 から 19 の整数で表現する
t
s
P
9
• s から右,右に行くルート10個を考える
4
• 次に右に行くルートは 3 4 通り
– 0 から 3 の整数で表現する
• 次に上に行くルートは
4
6
2
通り
– 4 から 9 の整数で表現する
t
s
P
10
• s から右右上に行くルート6個を考える
3
• 次に右に行くルートは 2 3 通り
– 4 から 6 の整数で表現する
• 次に上に行くルートは
3
3
1
通り
– 7 から 9 の整数で表現する
t
s
P
11
• s から右右上右に行くルート3個を考える
2
• 次に右に行くルートは 2 1 通り
– 4 から 4 の整数で表現する
• 次に上に行くルートは
2
2
1
通り
– 5 から 6 の整数で表現する
t
s
P
12
• s から右右上右上に行くルート2個を考える
1
• 次に右に行くルートは 1 1 通り
– 5 から 5 の整数で表現する
• 次に上に行くルートは
1
1
0
通り
– 6 から 6 の整数で表現する
t
s
P
13
• 結局,経路 P は整数 6 で表される
4 2 1
4 1 1 6
3 2 1
• 同様に,経路 Q は整数 30 で表される
6 5 0
20 10 0 30
3 2 1
t
Q
s
P
14
• 一般に,上に r 回,右に nr 回移動する場合,
ルートの数は n
r
• 最初に右に行くルートの数は
• 最初に上に行くルートの数は
n n 1 n 1
r r r 1
n 1
r
n 1
r 1
• n 個の矢印のうち,↑の位置を nr,nr1, …,n1 とすると
ルートは整数 nr nr 1 n1 で表される
r r 1
1
15
ルートの復元
•
•
•
•
ルートを表す整数 30 から,ルートを復元する
6
s から最初に右に行くルートは 3 20 通り
30>20 なので,最初は上に行っている
最初に上に行った点からルート 3020 = 10 を復元
t
Q
s
P
16
圧縮率
• 上に r 回,右に nr 回移動する場合
– n 個の矢印→↑…で表現: n ビット
– 整数に変換して表現:
n ビット
•
n
n
log
log
2
2 2 n
r
log 2
r
なので,変換する方が小さい
n
n
n
log 2 r log 2 n r log 2
r
nr
r
nH nr エントロピー
なので,r が小さければ圧縮率が高くなる
(もしくは nr が小さければ)
17
n
log 2
r
• 厳密には,ルートを表す
ビットの値の他に
n と r の値も保存する必要がある
n
• 合計で log r 2log n 2log n 2 ビット
2
2
2
18
n が大きい場合
• n > 10億
n
• r を計算するには,大きい数の掛け算,割り算が
必要になり,遅いしメモリも多く必要となる
t
s
19
• ルートを一定の長さ l ごとに区切る
• 各部分ルートに対し,↑の数を記録する
t
r4 = 2
r3 = 5
l=8
r2 = 2
r1 = 3
s
20
• 各部分ルートは
l
log
2
ri
ビットで表現できる
4
log 2
2
8
log
2
5
r4 = 2
r3 = 5
8
log
2
3
r2 = 2
t
8
log 2
2
l=8
r1 = 3
s
21
•
l
l
l
log
log
log
2 2 2
r1
r2
r3
はどれくらいの大きさ?
l
l
l
log 2 log 2 log 2
r1
r2
r3
l
l
l
log 2 1 log 2 1 log 2 1
r1
r2
r3
l l l n
log
r1 r2 r3 l
l l l n
log
r
r
r
1 2 3
l
n n
log
r l
• 分割してもサイズは
(あまり)増えない
22
• s から t への行き方は何通り?
t
s
23
• 5通り
24
• →と (, ↑ と ) を対応させると,各ルートは括弧
の対応の取れた(バランスした)括弧列を表す
(()())
((()))
()(())
()()()
(())()
25
• バランスした括弧列は,深さが常に 0 以上の
経路と対応する
((()))
(()())
()(())
(())()
()()()
26
バランスした括弧列と順序木には1対1対応がある
((()))
(()())
()(())
(())()
()()()
27
順序木の圧縮
• 木をバランスした括弧列で表現する
– 一番外側に括弧を追加する
• n 点の木は長さ 2n の括弧列で表現できる
• もっと短い表現は無いか
n=4
(((())))
((()()))
((())())
(()(()))
(()()())
28
順序木の個数
• n 点の順序木の個数を Tn とする
• Tn = (長さ 2n2 のバランスした括弧列の数)
< (長さ 2n2 の全ての括弧列の数) = 22n2
• Tn = (縦横n1マスずつの格子で対角線を
またがない経路の数)
1 2n 2
Cn 1
Tn
n n 1
• Cn はカタラン数 (Catalan number) と呼ばれる
n=4
29
カタラン数
2n 対角線を跨ぐ
Cn
n s t 経路の数
t
u
s’
s
• 対角線をまたぐ s-t 経路の数を求める
n=3
– 対角線を初めて跨いだ点を u とする
– s から u の経路を(紫の線で)折り返す
2n
– s’ から t の全ての経路の数と等しい
n 1
2n 2n
1 2n
Cn
n n 1 n 1 n
30
順序木の表現のサイズ
1 2n
4n
3 / 2
Cn
n 1 n n
•
•
•
•
(スターリングの公式より)
b ビットで表現できるものは最大 2b 種類
n 点の順序木は Cn1 種類ある
順序木を表現するには log 2 Cn 2n ビット必要
つまり,括弧列による順序木の表現は
ほぼ最適サイズ
31
カタラン数の漸化式
C0 1
Cn 1
2(2n 1)
Cn
n2
n
Cn 1 Ci Cn i
i 0
32
データの簡潔表現
• サイズが情報理論的下限に(ほぼ)一致する表現
• 入力がL通りのとき,情報理論的下限はlog L bits
• 例1: 集合 S {1,2,...,n} のサイズの下限
– log 2n = n bits
{1}
{2}
{3}
n=3
{1,2} {1,3} {2,3}
{1,2,3}
log の底は 2
33
• 例2: n ノードの順序木
1 2n 2
2n log n bits
log
n n 1
n=4
• 例3: n 文字の文字列
– n log bits (: アルファベットサイズ)
34
集合に対する演算
• 集合 S {1,2,...,n} に対して次の値を求めたい
– rank(S, x): S の中の x 以下の要素の数
– select(S, i): S の要素で i 番目に小さいもの
• S の要素を小さい順に配列に入れておくと
–
–
–
–
select(S, i) = A[i] なので定数時間
rank(S, x) は二分探索で O(log m) 時間 (m: 要素数)
データ構造のサイズ: m log n ビット
m > n / log n のとき,サイズは下限 n より大きい
1
2
3
4
5
6
7
A 1
3
7
9 10 14 15
35
集合の簡潔表現
•
•
•
•
B: 長さ n の 0,1 ベクトル B[1]B[2]…B[n]
x S B[x] = 1
サイズの下限 log 2n = n bits と一致する
rank, selectは O(n) 時間かかってしまう
⇒ 索引を用いる
1
2
3
4
A 1
3
7
9 10 14 15
1 3
5
6
7
7 9
B = 1010001011000110
n = 16
36
簡潔索引
• 決められた操作を実現するためのデータ構造
• サイズ: o(R) bits
– R: 簡潔表現のサイズ
– つまり,索引のサイズはほぼ無視できる
• 従来の表現と(ほぼ)同じ操作時間
37
Rankの簡潔索引1
• B を長さ log2 n のブロックに分割
• ブロックの境界での rank(x)の値を R に格納
x / log2 n
rank ( x) B[i] B[i]
x
i 1
i 1
x
B[i]
i x / log2 n 1
R[x/log2 n]
• Rのサイズ
n
n
log
n
bits
2
log n
log n
• rank(x): O(log2 n) 時間
38
Rankの簡潔索引2
• 各ブロックを長さ ½ log n の小ブロックに分割
• 小ブロックの境界での rank の値を R2 に格納
x / 12 logn
x
x / log2 n
rank ( x) B[i ] B[i ] B[i] B[i ]
i 1
i 1
i x / 12 log n 1
i x / log2 n 1
x
• R2のサイズ
R1[x/log2 n]
R2[x/log n]
n
4n log log n
2
log log n
bits
1
log n
2 log n
• rank(x): O(log n) 時間
39
Rankの簡潔索引3
• 小ブロック内での問い合わせに対する答えを
x
予め求め,表に格納しておく
x
B[i]
i x / 12 log n 1
½ log nビットの
Bの全パタン
• 表の大きさ
2
1 log n
2
12 log n log 12 log n
O n log n log log n
n log log n
bits
o
log n
000
001
010
011
100
101
110
111
0
0
0
0
0
1
1
1
1
1
0
0
1
1
1
1
2
2
2
0
1
1
2
1
2
2
403
定理: 長さ n のビットベクトルでのrankは
語長 (log n) bits のword RAM上で
n + O(n log log n/log n) bits を用いて
O(1) 時間で求まる.
注: 小ブロックでのrankを計算する表の大きさは
O n log n log log n bits だが,実際は無視できない
表を使わずに,ビット演算または POPCOUNT 命令
で計算するほうがいい.
41
Selectの簡潔索引
• rank同様にやってもうまくいかない
–
–
–
–
i = q (log2 n) + r (½ log n) + s とする
i が log2 n の倍数のときに select(i) を S1 に格納
i が ½ log n の倍数のときに select(i) を S2 に格納
S2 の要素は (n) になり得る→(log n) bits 必要
→ S2 全体で (n) bits
– rank の索引を使って2分探索で求まるが O(log n) 時間
• B を,1 を log2 n 個含む大ブロックに分割
• 大ブロックごとに2通りのデータ構造を使い分ける
42
• 大ブロックの長さが logc n を超えるとき
– log2 n 個の1の位置をそのまま格納
– 1つの大ブロックで log 2 n log n log 3 n bits
n
– そのような大ブロックは最大
個
c
log n
n
3
log
n bits
– 全体で log c n
n
– c = 4 とすると
bits
log n
43
• 大ブロックの長さ m が logc n 以下のとき
–
–
–
–
長さ ½ log n の小ブロックに分割
小ブロックを葉に持つ完全 log n 分木を構築
木のノードには,その子孫のベクトルの1の数を格納
大ブロック内の 1 の数は log2 n
→ 各ノードの値は 2 log log n bits
log n
9
3
1
2
4
0
1
1
O(c)
2
2
1
0
1
B = 100101000100010011100000001
m logc n
44
• 木の高さは O(c)
• ノードに格納する値は大ブロック全体で
cm log log n
bits
O
log n
• ベクトル全体で
cn log log n
bits
O
log n
• select(i) を求めるには,木の根から探索する
– 子ノードの情報は log n 2 log log n Olog n bits で
表現できるので,表引きで訪れる子が決まる
• 探索時間は O(c) つまり定数
45
定理: 長さ n のビットベクトルでの rank と select は
語長 (log n) bits のword RAM上で n+O(n log log n
/log n) bits を用いて O(1) 時間で求まる.
注: 子ノードの探索では log n 2 log log n Olog n bits
つまり (log log n)2 = O(log n) を仮定している.
これは小さい n では成立しない
補足: 大ブロック内の select の索引を用いて
rank を計算できる
木を葉から根にたどり,rankの和を求める
46
ベクトルの圧縮法
• ベクトルを長さ l = ½ log n の小ブロックに分割
• i 番目の小ブロック Bi 内の 1 の数を mi とする
– 小ブロックは
l
log l log
mi
1の数
bits で表現できる
1の数が決まったときの全パタンの数
• 全ブロックの合計は
l n / l
l
log l log log l log 1
i 0
mi
mi i 0
n/l
l n
log 1 log l
l
i 0 mi
n
n log log n
log O
m
log n
n/l
47
• rank, select の索引はベクトルが圧縮されていない
ときと全く同じで,O(n log log n /log n) bits
• 小ブロック内の 1 の数は select の索引に格納済
• 圧縮された小ブロックへのポインタが必要
• Bi へのポインタを pi とする
– 0 = p0 < p1 < <pn/l < n (圧縮されているので n 未満)
– pi pi1 ½ log n
• i が log n の倍数のときに pi をそのまま格納
n
n
log n
bits
2
log n
log n
• それ以外のときは差分で格納
n
1
log
2 log n log n O n log log n / log n bits
1
2 log n
48
定理: 長さ n, 1の数 m のビットベクトルは
n
n log log n
bits で表現でき,
log
m
log n
rank0, rank1, select0, select1 は 語長 (log n) bits の
word RAM上で O(1) 時間で求まる.
データ構造は O(n) 時間で構築できる.
このデータ構造は FID (fully indexable dictionary)
と呼ばれる (Raman, Raman, Rao).
n
n log log n
注:m << n のときは log m log n となることが
あり,rank/select の索引のサイズが無視できない 49
© Copyright 2026 ExpyDoc