Upload
takuya-akiba
View
21.657
Download
0
Embed Size (px)
Citation preview
プログラミングコンテストでの
乱択アルゴリズム
東京大学情報理工学系研究科
秋葉 拓哉 / [[iwi]]
1
2012/06/12 ディー・エヌ・エー 渋谷オフィス (TopCoder Meetup in Japan)
自己紹介
• 秋葉 拓哉 / [[iwi]]
– Twitter: @iwiwi
• 東京大学 情報理工学系研究科 コンピュータ科学専攻
• プログラミングコンテスト凄い好き
– 世界大会の常連をやっています
– ここ 1 年で 3 回,来月も行きます
• プログラミングコンテストチャレンジブック共著
2
今日の話
「乱択アルゴリズム」
• 既存の乱択アルゴリズムの紹介を延々とはしません
– そういうアルゴリズム解説は一杯あります
• コンテストに焦点を絞り,乱択アルゴリズムを設計
できるようにする,ということを目指す
(簡単めの話になります,中上級者の方々ごめんなさい)
3
最近のコンテストでの状況
• 京都大学プログラミングコンテスト 2011
– 問題D : 列の構成
– 問題G : XOR 回路
• Google Code Jam 2012
– R1C C : Equal Sums
– R2 B : Aerobics
• その他 (2012)
– ICPC OB/OG 会 冬コンテスト : Sunny Graph
– ARC #3 D : シャッフル席替え
出題が激増中! 4
乱択アルゴリズムとは?
5
乱択アルゴリズムとは?
乱数を用いて挙動を決めるアルゴリズム
乱数を用いるので,
• 計算時間が一定ではないかもしれない
– そういうものを,Las Vegas アルゴリズムと呼ぶ
• さらに,計算結果が必ず正しいとは限らないものも
– そういうものを,Monte Carlo アルゴリズムと呼ぶ
6
乱択アルゴリズムの重要な原理
定番教科書 Randomized Algorithms の序文より
(Rajeev Motwani & Prabhakar Raghavan)
• Foiling an adversary
• Random sampling
• Abundance of witnesses
• Fingerprinting and hashing
• Random re-ordering
• Load balancing
• Rapidly mixing Markov chains
• Isolation and symmetry breaking
• Probabilistic methods and existence proofs
7
コンテストでは?
定番教科書 Randomized Algorithms の序文より
(Rajeev Motwani & Prabhakar Raghavan)
• Foiling an adversary
• Random sampling
• Abundance of witnesses
• Fingerprinting and hashing
• Random re-ordering
• Load balancing
• Rapidly mixing Markov chains
• Isolation and symmetry breaking
• Probabilistic methods and existence proofs
8
→ ケース 1, 2 両方
→ ケース 2 後半
→ 文字列アルゴリズム等
→ 二分探索の枝刈り,嘘解法
ケース 1 : 多数あるものを 1 つ見つける
9
最近のコンテストでの状況
• 京都大学プログラミングコンテスト 2011
– 問題D : 列の構成
– 問題G : XOR 回路
• Google Code Jam 2012
– R1C-C : Equal Sums
– R2-B : Aerobics
• AtCoder (2012)
– ARC#3-D : シャッフル席替え
10
この 4 問はいずれも,
多数あるものを1つ見つける
ために乱択を用いる
基本原理
11
𝑁 個の箱があります.
開けるまで分かりませんが,
半分はアタリだと知っています.
箱を開けて,アタリを見つけよう!
𝑁 個
基本原理
12
𝑁 個
【乱択アルゴリズム】
アタリが出るまで,ランダムに選んで開ける
【開ける箱の個数の期待値】
期待値 ≤ 1 +1
2+1
4+1
8+⋯ ≤ 2 個
アタリが大量にあるので,すぐにあたる
Random sampling
ランダムである意味
13
(´・_・`)
大量にあるなら,とにかく選べばアタリが出てくる.
なんでもいいけど,まあランダムでいっか.
ランダムである意味
14
(´・_・`)
大量にあるなら,とにかく選べばアタリが出てくる.
なんでもいいけど,まあランダムでいっか.
( ・`д・´)
違うぞ,ランダムじゃなければいけない
舐めてんのか!!!!!
ランダムである意味
いっぱいあってどうせすぐあたるから,
選び方はどうでも良い?前から順とかはどうか?
15
こういう時は全然平気だが
「意地悪」をされるとひとたまりもない
ランダムである意味
• 前からに限らず,取る順番が決まっているので
あれば,必ず「意地悪」がされ得る
– 最初に取る 𝑁/2 個をハズレにしといてやればよい
• 一方,ランダムの場合,意地悪が出来ない
– どれを取るかわからない
– 何されても 2 回程度で当たる
16
Foiling an adversary
ランダムである意味
• 実際には,相手が居て,意地悪され得るような
場合とは限らない
• しかし,分布の偏りはよくある
– 例えば,ハズレは近いところに連続する傾向とか
– そういうので頭からやってしまうと,やはりまずい
• 従って,ランダムに選ぶことに意味がある
17
問題「列の構成」(KUPC’11 D) http://old.atcoder.jp/problem/detail/78
長さ 𝑁 の 0,1 からなる列 𝑆 をつくれ,ただし
• 列 𝑐𝑖 = {𝑐𝑖,1, 𝑐𝑖,2, … , 𝑐𝑖,𝑁2
} が与えられている
•𝑁
8≤ 𝑆𝑐𝑖,𝑗𝑗 ≤
3𝑁
8 を満たさなければならない
18
• 長さ 𝑁
2 の部分列たちの和を
𝑁
8 から
3𝑁
8 に入れたい
• 𝑆 をランダム列とすると,和の期待値は 𝑁
4 (←OK)
• ランダム列はそこそこの確率で条件を満たしそう
• 生成してみてチェックして OK なら出力
(確率についての考察はアルゴリズムの単純さに比べ複雑
http://www.kupc.jp/2011/editorial/D.pdf)
問題「Aerobics」(GCJ’12 R2 B) http://code.google.com/codejam/contest/1842485/dashboard#s=p1
• 問題文の条件より,大きい方から置いていくと,そ
こまでどのような置き方をしていても,次の●の中
心が置ける場所が,全体の 1
5 はある
• よって,ランダムな場所を選んで,
• 置けるかチェックし,置けるなら置く
19
(詳細省略)
• □の上に●を置いていく
• □は十分大きいことが保証されている
ケース 2 : 推定する
20
モンテカルロ法
• 確率 𝑝 を求めたい
• でも,標本空間の全体ついて調べるのは無理
– 大きすぎたり,連続だったり
21
Random sampling
このような場合に,標本空間をランダムに選んで
調べ,それから確率を推定する
(何故ランダム? → 前同様,偏ってても大丈夫に)
Foiling an adversary
円周率
22
• [0, 1] × [0, 1] の上でランダムな点
• 原点からの距離が 1 以下かを調べる
• 青の面積が推定できて,円周率が推定できる!
(円周率計算にはもっと良い方法があるのでこれは使われない)
問題「シャッフル席替え」(ARC#3-D) http://arc003.contest.atcoder.jp/tasks/arc003_4
• 実際にランダムに何度もやってみる
23
• 円形に人が順に 1,2,… , 𝑛 と並んでる
• 二人を選び場所を入れ替える,をランダムに 𝑘 回
• 𝑚 組の指定された二人組が全く隣り合わない確率は?
𝑛,𝑚, 𝑘 10 程度,許容誤差 2 × 10−3
モンテカルロ法の収束速度
• 正しい確率を 𝑝 とする
• 𝑛 回の試行での推定値 𝑝𝑛 は,二項分布 𝐵𝑖 𝑛, 𝑝/𝑛
– 分散 𝑝(1 − 𝑝)/𝑛
• よって,絶対誤差はだいたい 1
𝑛 に比例
– 精度を 10 倍にするには,𝑛 は 100 倍
24
問題「PM3」(POJ 3213) http://poj.org/problem?id=3213
• 𝐴 × 𝐵 を素直に計算すると 𝑂 𝑛3 ,間に合わない
(もっと計算量の良い掛け算アルゴリズムもあるが,無理)
• 判定だけ出来れば良い点を生かせないか
25
• 𝑛 × 𝑛 行列 𝐴, 𝐵, 𝐶 が与えられます
• 𝐴 × 𝐵 = 𝐶 であるか答えてください
𝑛 ≤ 1000
問題「PM3」(POJ 3213) http://poj.org/problem?id=3213
【解法】
• ランダムなベクトル 𝑥 を作る
• 𝐴𝐵𝑥 = 𝐶𝑥 であるかで推定する
– 𝐴𝐵𝑥 は 𝐴 𝐵𝑥 の順で計算すれば 𝑂 𝑛2 !
• 直感的にも,行列が違ったら違うベクトルが出てきそう
• 真面目に考えると:行列が違うのに等しくなったとすると
– 𝐴𝐵と 𝐶に異なる行が 1 つは存在,その差を 𝑣 とおくと 𝑣𝑥 = 0.
– すなわち,𝑥𝑛 = − 𝑣𝑖𝑥𝑖𝑛−1𝑖=1 /𝑣𝑛 となっている.
– 𝑥𝑛を𝐾個の数からランダムに選んでるとすると,確率高々1/𝐾
26
Random sampling
Abundance of witnesses
問題「PM3」(POJ 3213) http://poj.org/problem?id=3213
• 𝐴𝐵𝑥 ≠ 𝐶𝑥 となるような 𝑥 が有れば,
𝐴𝐵 ≠ 𝐶 とわかる
• こういう 𝑥 を witness (証人) と呼ぶ
• witness が一杯ある状況では,ランダムを用いて
witness を 1 つ手に入れてしまえば良い
– 逆に全然見つからなかったら 𝐴𝐵 = 𝐶 と判断
27
Random sampling Abundance of witnesses
その他での乱択の登場
28
その他の乱択の登場
既成アルゴリズム・データ構造・テクニックの利用
• Rolling-Hash を用いた文字列検索 (Rabin-Karp) (→ プログラミングコンテストチャレンジブック 第二版のみ P.332)
• Tutte 行列を用いた一般グラフの最大マッチング (→ プログラミングコンテストチャレンジブック P.197)
• Treap, RBST (→ プログラミングコンテストでのデータ構造2 http://slidesha.re/GW3BH6)
• Miller-Rabin 素数判定
• 二分探索の枝刈り
嘘解法
• 山登り法
• ランダム回転
29
二分探索の枝刈り
• 各 𝑖, 𝑥 に対し,check(i, x) は true か false を返す
• どれかの 𝑖 で true が得られる最小の 𝑥 を計算したい
→ x の値で二分探索 (常套手段)
30
false
𝑥
true
false true
false true
ここの 𝒙 の値を知りたい!
check(1, 𝑥)
check(2, 𝑥)
check(3, 𝑥)
0
二分探索の枝刈り
• check(i, x) は各 i に対して,x の増加に伴いどこかで false から true
になる単調な関数
• どれかの i に対し check(i, x) が true になる最小の x を求めている
• このコードでは,check が 𝑇𝑁 回 呼ばれる
31
double lb = 0, ub = 1E10;
for (int iter = 0; iter < T; ++iter) {
double mid = (lb + ub) / 2;
bool f = false;
for (int i = 0; i < N; ++i) f |= check(i, mid);
if (f) ub = mid;
else lb = mid;
}
𝑇 回イテレーションする
二分探索
𝑛 個 check 呼んで
or をとる
どれか true になってたら
下へ,そうでなければ上へ
二分探索の枝刈り
• i のループを外に出した
• これだけだと何も変わらない
32
double ans = 1E10;
for (int i = 0; i < N; ++i) {
double lb = 0, ub = 1E10;
for (int iter = 0; iter < T; ++iter) {
double mid = (lb + ub) / 2;
if (check(i, mid)) ub = mid;
else lb = mid;
}
ans = min(ans, ub);
}
𝑖 のループ
二分探索
𝑛 個の値の最小値を求める
二分探索の枝刈り
• 現在の暫定答え ans より大きい答えには興味が無い
• 従って,そこで check を一度計算すると,二分探索しなくてよい!
33
double ans = 1E10;
for (int i = 0; i < N; ++i) {
if (check(i, ans) == false) continue;
double lb = 0, ub = 1E10;
for (int iter = 0; iter < T; ++iter) {
double mid = (lb + ub) / 2;
if (check(i, mid)) ub = mid;
else lb = mid;
}
ans = min(ans, ub);
}
←枝刈り!
二分探索の枝刈り
• さらに 𝑖 をランダム順にループすることにすると,
check を呼ぶ回数の期待値を見積もれる
1. 最初は必ず二分探索する
2. 次は 1/2 の確率で二分探索する
3. その次は 1/3 の確率で二分探索する
𝑁 + 𝑇 +𝑇
2+𝑇
3+⋯≒𝑁 + 𝑇 log𝑁 回
→ 𝑇𝑁 回から随分と減らすことに成功!
34
まとめ
話したこと
• 乱択アルゴリズムとは何か
• 多数あるものを 1 つ見つける
• 性質を推定する
• その他:二分探索の枝刈り
35
出題側の課題
• 乱択アルゴリズムの出題は上手くいっているか?
• 乱択アルゴリズムの成功確率を保証しようとすると,ど
うしても,「ゆるい」問題になる
• 変なヒューリスティクスなどが通ってしまいやすい
– 想定できれば落とせるかもだが,全てを想定するのは無理
– 想定できたものだけが落ちる? → 枝刈り探索系と類似の問題点
36
𠮷田悠一さん
(@oxy)
謝辞
有用なコメントを頂きました,感謝
37
岩田陽一さん
(wata / @wata_orz)