数理工学のすすめ 東京大学大学院情報理工学系研究科 数理情報学専攻 定兼 邦彦 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 2025 ExpyDoc