2012/06/12 ディー・エヌ・エー 渋谷オフィス (TopCoder Meetup in Japan)




      プログラミングコンテストでの
          乱択アルゴリズム
                 東京大学情報理工学系研究科

                   秋葉 拓哉 / [[iwi]]

                                                         1
自己紹介
• 秋葉 拓哉 / [[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
                             → ケース 1, 2 両方
• Random sampling
• Abundance of witnesses     → ケース 2 後半
• Fingerprinting and hashing → 文字列アルゴリズム等
•   Random re-ordering          → 二分探索の枝刈り,嘘解法
•   Load balancing
•   Rapidly mixing Markov chains
•   Isolation and symmetry breaking
•   Probabilistic methods and existence proofs
                                             8
ケース 1 : 多数あるものを 1 つ見つける



                          9
最近のコンテストでの状況
• 京都大学プログラミングコンテスト 2011
   – 問題D : 列の構成
   – 問題G : XOR 回路       この 4 問はいずれも,
• Google Code Jam 2012 多数あるものを1つ見つける
  – R1C-C : Equal Sums   ために乱択を用いる
   – R2-B : Aerobics
• AtCoder (2012)
   – ARC#3-D : シャッフル席替え




                                  10
基本原理
          𝑁個




𝑁 個の箱があります.
開けるまで分かりませんが,
半分はアタリだと知っています.

箱を開けて,アタリを見つけよう!
                   11
基本原理
                 𝑁個




【乱択アルゴリズム】     Random sampling

アタリが出るまで,ランダムに選んで開ける
【開ける箱の個数の期待値】
             1     1     1
     期待値 ≤ 1 + +       +     +⋯≤2個
             2     4     8
アタリが大量にあるので,すぐにあたる
                                     12
ランダムである意味
(´・_・`)

大量にあるなら,とにかく選べばアタリが出てくる.
なんでもいいけど,まあランダムでいっか.




                       13
ランダムである意味
(´・_・`)

大量にあるなら,とにかく選べばアタリが出てくる.
なんでもいいけど,まあランダムでいっか.



違うぞ,ランダムじゃなければいけない
舐めてんのか!!!!!

                    ( ・`д・´)
                           14
ランダムである意味
いっぱいあってどうせすぐあたるから,
選び方はどうでも良い?前から順とかはどうか?

     こういう時は全然平気だが




   「意地悪」をされるとひとたまりもない




                         15
ランダムである意味
• 前からに限らず,取る順番が決まっているので
  あれば,必ず「意地悪」がされ得る
 – 最初に取る 𝑁/2 個をハズレにしといてやればよい




• 一方,ランダムの場合,意地悪が出来ない
 – どれを取るかわからない
 – 何されても 2 回程度で当たる
                     Foiling an adversary

                                      16
ランダムである意味
• 実際には,相手が居て,意地悪され得るような
  場合とは限らない

• しかし,分布の偏りはよくある
 – 例えば,ハズレは近いところに連続する傾向とか
 – そういうので頭からやってしまうと,やはりまずい


• 従って,ランダムに選ぶことに意味がある


                             17
問題「列の構成」(KUPC’11 D)
                     http://old.atcoder.jp/problem/detail/78

長さ 𝑁 の 0,1 からなる列 𝑆 をつくれ,ただし
• 列 𝑐 𝑖 = {𝑐 𝑖,1 , 𝑐 𝑖,2 , … , 𝑐 𝑖, 𝑁 } が与えられている
                                    2
    𝑁                        3𝑁
•       ≤    𝑗   𝑆 𝑐 𝑖,𝑗 ≤        を満たさなければならない
    8                        8

            𝑁                                  𝑁        3𝑁
• 長さ             の部分列たちの和を                         から        に入れたい
            2                                  8        8
                                                              𝑁
•   𝑆 をランダム列とすると,和の期待値は                                           (←OK)
                                                              4
• ランダム列はそこそこの確率で条件を満たしそう
• 生成してみてチェックして OK なら出力
    (確率についての考察はアルゴリズムの単純さに比べ複雑
        http://www.kupc.jp/2011/editorial/D.pdf)
                                                                          18
問題「Aerobics」(GCJ’12 R2 B)
 http://code.google.com/codejam/contest/1842485/dashboard#s=p1

(詳細省略)
• □の上に●を置いていく
• □は十分大きいことが保証されている

• 問題文の条件より,大きい方から置いていくと,そ
  こまでどのような置き方をしていても,次の●の中
                                  1
 心が置ける場所が,全体の はある
                                  5

• よって,ランダムな場所を選んで,
• 置けるかチェックし,置けるなら置く
                                                                 19
ケース 2 : 推定する


               20
モンテカルロ法
• 確率 𝑝 を求めたい
• でも,標本空間の全体ついて調べるのは無理
 – 大きすぎたり,連続だったり


このような場合に,標本空間をランダムに選んで
調べ,それから確率を推定する  Random sampling


(何故ランダム? → 前同様,偏ってても大丈夫に)
                     Foiling an adversary

                                       21
円周率
• [0, 1] × [0, 1] の上でランダムな点
• 原点からの距離が 1 以下かを調べる




• 青の面積が推定できて,円周率が推定できる!
(円周率計算にはもっと良い方法があるのでこれは使われない)




                                22
問題「シャッフル席替え」(ARC#3-D)
      http://arc003.contest.atcoder.jp/tasks/arc003_4

• 円形に人が順に 1,2, … , 𝑛 と並んでる
• 二人を選び場所を入れ替える,をランダムに 𝑘 回
•   𝑚 組の指定された二人組が全く隣り合わない確率は?
𝑛, 𝑚, 𝑘 10 程度,許容誤差 2 × 10−3


• 実際にランダムに何度もやってみる




                                                        23
モンテカルロ法の収束速度
• 正しい確率を 𝑝 とする

• 𝑛 回の試行での推定値 𝑝 𝑛 は,二項分布 𝐵𝑖 𝑛, 𝑝/𝑛
 – 分散 𝑝(1 − 𝑝)/𝑛
                       1
• よって,絶対誤差はだいたい                に比例
                           𝑛
 – 精度を 10 倍にするには,𝑛 は 100 倍




                                     24
問題「PM 3」(POJ                      3213)
          http://poj.org/problem?id=3213

• 𝑛 × 𝑛 行列 𝐴, 𝐵, 𝐶 が与えられます
• 𝐴 × 𝐵 = 𝐶 であるか答えてください
 𝑛 ≤ 1000


• 𝐴 × 𝐵 を素直に計算すると 𝑂 𝑛3 ,間に合わない
  (もっと計算量の良い掛け算アルゴリズムもあるが,無理)


• 判定だけ出来れば良い点を生かせないか

                                               25
問題「PM 3」(POJ                        3213)
            http://poj.org/problem?id=3213

                                       Abundance of witnesses
【解法】
                                             Random sampling
• ランダムなベクトル 𝑥 を作る
• 𝐴𝐵𝑥 = 𝐶𝑥 であるかで推定する
 – 𝐴𝐵𝑥 は 𝐴 𝐵𝑥 の順で計算すれば 𝑂 𝑛2 !

• 直感的にも,行列が違ったら違うベクトルが出てきそう
• 真面目に考えると:行列が違うのに等しくなったとすると
 – 𝐴𝐵と 𝐶に異なる行が 1 つは存在,その差を 𝑣 とおくと 𝑣𝑥 = 0.
                    𝑛−1
 – すなわち,𝑥 𝑛 = −    𝑖=1    𝑣 𝑖 𝑥 𝑖 /𝑣 𝑛 となっている.
 – 𝑥 𝑛 を𝐾個の数からランダムに選んでるとすると,確率高々1/𝐾
                                                          26
問題「PM 3」(POJ                      3213)
          http://poj.org/problem?id=3213


• 𝐴𝐵𝑥 ≠ 𝐶𝑥 となるような 𝑥 が有れば,
  𝐴𝐵 ≠ 𝐶 とわかる

• こういう 𝑥 を witness (証人) と呼ぶ

• witness が一杯ある状況では,ランダムを用いて
  witness を 1 つ手に入れてしまえば良い
  – 逆に全然見つからなかったら 𝐴𝐵 = 𝐶 と判断
              Abundance of witnesses       Random sampling

                                                        27
その他での乱択の登場


             28
その他の乱択の登場
既成アルゴリズム・データ構造・テクニックの利用
• Rolling-Hash を用いた文字列検索 (Rabin-Karp)
   (→ プログラミングコンテストチャレンジブック 第二版のみ P.332)
• Tutte 行列を用いた一般グラフの最大マッチング
   (→ プログラミングコンテストチャレンジブック P.197)

• Treap, RBST
   (→ プログラミングコンテストでのデータ構造2 http://slidesha.re/GW3BH6)
• Miller-Rabin 素数判定
• 二分探索の枝刈り
嘘解法
• 山登り法
• ランダム回転

                                                        29
二分探索の枝刈り
              0
                                              𝑥
check(1, 𝑥)            false          true
check(2, 𝑥)        false       true
check(3, 𝑥)          false       true


                  ここの 𝒙 の値を知りたい!

• 各 𝑖, 𝑥 に対し,check(i, x) は true か false を返す
• どれかの 𝑖 で true が得られる最小の 𝑥 を計算したい
   → x の値で二分探索 (常套手段)

                                                  30
二分探索の枝刈り
  double lb = 0, ub = 1E10;
  for (int iter = 0; iter < T; ++iter) {                𝑇 回イテレーションする
    double mid = (lb + ub) / 2;                         二分探索

      bool f = false;                                    𝑛 個 check 呼んで
      for (int i = 0; i < N; ++i) f |= check(i, mid);   or をとる

      if (f) ub = mid;                                  どれか true になってたら
      else lb = mid;                                    下へ,そうでなければ上へ
  }


• check(i, x) は各 i に対して,x の増加に伴いどこかで false から true
  になる単調な関数
• どれかの i に対し check(i, x) が true になる最小の x を求めている
• このコードでは,check が 𝑇𝑁 回 呼ばれる
                                                                         31
二分探索の枝刈り
 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);                      𝑛 個の値の最小値を求める
 }


• i のループを外に出した
• これだけだと何も変わらない

                                                          32
二分探索の枝刈り
 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);
 }

• 現在の暫定答え ans より大きい答えには興味が無い
• 従って,そこで check を一度計算すると,二分探索しなくてよい!

                                                      33
二分探索の枝刈り
• さらに 𝑖 をランダム順にループすることにすると,
  check を呼ぶ回数の期待値を見積もれる

1. 最初は必ず二分探索する
2. 次は 1/2 の確率で二分探索する
3. その次は 1/3 の確率で二分探索する


             𝑇   𝑇
       𝑁 + 𝑇 + + + ⋯≒𝑁 + 𝑇 log 𝑁 回
             2   3
      → 𝑇𝑁 回から随分と減らすことに成功!

                                     34
まとめ
話したこと
• 乱択アルゴリズムとは何か
• 多数あるものを 1 つ見つける
• 性質を推定する
• その他:二分探索の枝刈り




                    35
出題側の課題
• 乱択アルゴリズムの出題は上手くいっているか?

• 乱択アルゴリズムの成功確率を保証しようとすると,ど
  うしても,「ゆるい」問題になる
• 変なヒューリスティクスなどが通ってしまいやすい
 – 想定できれば落とせるかもだが,全てを想定するのは無理
 – 想定できたものだけが落ちる? → 枝刈り探索系と類似の問題点




                                36
謝辞
有用なコメントを頂きました,感謝


      岩田陽一さん
     (wata / @wata_orz)



       𠮷田悠一さん
          (@oxy)


                          37

プログラミングコンテストでの乱択アルゴリズム

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