乱択アルゴリズムと確率的解析
なぜ乱数を混ぜると最悪ケースを潰せるのかが腑に落ちる。乱択クイックソートやミラーラビン素数判定を題材に、期待計算量と成功確率の保証、Las Vegas と Monte Carlo の違いを原理から正確に押さえる。
- 1.乱択アルゴリズムは内部で乱数を引き、入力ではなく自分の乱択の上で平均を取る。だから敵対的な最悪入力でも期待計算量や成功確率を保証できる。
- 2.Las Vegas は答えが常に正しく実行時間が確率変数(乱択クイックソートは期待 O(n log n))、Monte Carlo は実行時間が決まる代わりに低確率で誤る(ミラーラビン素数判定)。
- 3.Monte Carlo の誤り確率は独立試行の反復で指数的に下げられる。片側誤りのミラーラビンは k 回で誤り (1/4)^k 以下になり、実用上ゼロに近づく。
乱数を引くと最悪ケースが消える理由
通常のアルゴリズムの計算量は入力だけで決まり、最悪計算量(Big-O)はその入力空間の中で一番不利なケースを指します。問題は、攻撃者やデータ生成側がその最悪入力を狙って作れることです。乱択アルゴリズム(randomized algorithm)は、実行中に内部で乱数(コイン投げ)を引き、その乱数に応じて挙動を変えます。これにより計算量や正しさが、固定の最悪入力ではなく自分が引いた乱数の上で平均された量になります。
決定的な平均ケース解析との違いが核心です。平均ケース解析は「入力がこの確率分布から来る」と仮定して期待値を取りますが、その仮定が崩れれば保証は消えます。乱択アルゴリズムは入力を一切仮定しません。乱数は自分が引くので、どんな敵対的な入力に対しても、期待計算量や成功確率が成り立ちます。乱数の引き方が入力から独立しているため、攻撃者は「いつも遅くなる入力」を構成できないのです。
乱択の解析で問う確率は「入力が出る確率」ではなく「アルゴリズムが特定の乱数列を引く確率」です。だから期待値は固定した1つの入力に対して取られ、結果は全入力で一様に成立します。「ランダムな入力で速い」ではなく「どんな入力でもランダムな自分の選択でならせば速い」――この向きの違いが乱択の強さの源です。
Las Vegas と Monte Carlo
乱数が「正しさ」と「実行時間」のどちらに不確実性を持ち込むかで、乱択アルゴリズムは2種類に分かれます。
| 種類 | 答えの正しさ | 実行時間 | 保証の形 | 代表例 |
|---|---|---|---|---|
| Las Vegas | 常に正しい | 確率変数(運で変動) | 期待実行時間を保証 | 乱択クイックソート |
| Monte Carlo | 低確率で誤る | 確定(上界が固定) | 成功確率を保証 | ミラーラビン素数判定 |
Las Vegas 型は出力が必ず正しく、揺れるのは実行時間だけです。たまたま悪い乱数を引けば遅くなりますが、間違った答えは返しません。Monte Carlo 型は実行時間を固定する代わりに、低い確率で誤った答えを返すことを許します。この2つは無関係ではなく、Las Vegas のアルゴリズムに「時間切れで打ち切ったら適当に答える」打ち切りを入れれば Monte Carlo に変換でき、逆に Monte Carlo を「正しい答えが出るまで結果を検証して繰り返す」ことで Las Vegas にできます(検証が安く可能な場合)。
答えの正しさが絶対に譲れない(ソート結果、探索結果など)なら Las Vegas を選び、実行時間のばらつきを受け入れます。逆に時間制約が固い、または誤り確率を十分小さくできて実用上問題ない(巨大な素数判定など)なら Monte Carlo が向きます。Monte Carlo の魅力は、後述するように誤り確率を反復で指数的に削れる点にあります。
乱択クイックソート(Las Vegas の典型)
通常のクイックソートはピボットを「先頭要素」など固定位置から選びます。すると既ソート列のような特定の入力でピボットが毎回最小(または最大)になり、分割が偏って O(n^2) に劣化します。これは決定的なので、攻撃者は最悪入力を構成できます。
乱択クイックソートはピボットを毎回一様ランダムに選びます。出力(ソート結果)は常に正しいので Las Vegas 型です。揺れるのは比較回数だけ。鍵となる事実は、ランダムなピボットが「上位 1/4 から下位 1/4 を除いた中央寄りの半分」に入る確率が 1/2 あり、そのとき両側の部分問題サイズがどちらも全体の 3/4 以下になることです。良いピボットが定数確率で出るので、分割の深さは期待で O(log n) に収まります。
期待比較回数の見方(指標変数法):
- 値の組 (i番目に小さい要素, j番目に小さい要素) が比較されるのは
両者の間の値の中で「先にピボットに選ばれたのが i か j」のときだけ
- その確率は 2 / (j - i + 1)
- 全ペアで総和すると Σ 2/(j-i+1) ≒ 2n·ln n
=> 期待比較回数 = O(n log n)
重要なのは、この O(n log n) がどの入力に対しても成り立つことです。既ソートだろうが逆順だろうが、ピボットは入力と無関係にランダムなので、最悪入力という概念が消えます。最悪計算量自体は依然 O(n^2)(運悪く毎回偏った場合)ですが、その確率は天文学的に小さく、期待値が O(n log n) に張り付きます。分割統治の漸化式としての見方は分割統治法とマスター定理に接続します。
乱択クイックソートの最悪計算量は今も O(n^2) です。乱択が保証するのは「期待値」と「高確率(with high probability)での上界」であって、絶対的な上界ではありません。確定した最悪 O(n log n) が必要なら、中央値の中央値法でピボットを決定的に選ぶか、ヒープソート・マージソートを使います。乱択の利点は定数倍の軽さと、攻撃耐性にあります。
ミラーラビン素数判定(Monte Carlo の典型)
巨大な整数 n が素数かを判定する問題です。試し割りは n の桁数に対して指数時間で実用になりません。ミラーラビン法はフェルマーの小定理の強化版を使い、多項式時間で判定します。
土台はフェルマーの小定理「n が素数なら、1 <= a < n のすべての a で a^(n-1) ≡ 1 (mod n)」です。ただしこの逆は偽で、カーマイケル数のように合成数でも全ての a で成立してしまう例外があり、単純なフェルマー判定は破れます。ミラーラビンはこれを強めます。n - 1 を 2^s * d(d は奇数)と分解し、各 a について次の強い条件を課します。
n-1 = 2^s · d (d は奇数)
証人 a が「素数らしい」と認める条件は、次のどちらか:
(1) a^d ≡ 1 (mod n)
(2) ある r (0 <= r < s) で a^(2^r · d) ≡ -1 (mod n)
どちらも満たさない a が見つかれば、n は確実に合成数(a はその「証人」)
この強い条件のおかげで、n が合成数なら、1 < a < n-1 の範囲のうち少なくとも 3/4 が「合成数であることの証人」になることが証明できます。つまりランダムに a を1個選んで判定すると、合成数を誤って素数と認める確率は高々 1/4 です。素数を合成数と誤ることは決してない(素数なら全 a で条件成立)ので、これは片側誤りの Monte Carlo です。
ミラーラビンは「合成数を素数と誤る」方向にしか間違えません。だから a を独立に k 回選んで全て「素数らしい」となったときだけ素数と判定すれば、合成数を見逃す確率は (1/4)^k 以下に落ちます。k=20 で (1/4)^20 ≒ 10^(-12)、k=40 でハードウェアのビット反転より低い水準です。「独立試行の反復で誤り確率を指数的に下げる」が確率増幅(probability amplification)の定石で、暗号ライブラリの素数生成はこれで実用上ゼロの誤りを実現します。
確率増幅と誤り確率の設計
Monte Carlo の誤り確率を反復で下げられるのは、各試行が独立だからです。1回の誤り確率が p なら、独立な k 回がすべて誤る確率は p^k。p < 1 である限り、k を線形に増やすだけで誤り確率は指数的に減ります。これが乱択の実務的な威力の中心です。
ただし「片側誤り」か「両側誤り」かで増幅の手順が変わります。
| 誤りの型 | 性質 | 増幅の方法 | 例 |
|---|---|---|---|
| 片側誤り | 片方向にしか間違えない(例: 合成数だけ誤る) | 反復して一度でも「確実側」が出たら確定。誤り確率は p^k | ミラーラビン |
| 両側誤り | 両方向に間違いうる(誤り確率 < 1/2) | 多数決を取る。チェルノフ限界で誤りが k に対し指数的に減少 | 多数決型の判定問題 |
片側誤りは単純で、ミラーラビンのように「証人が1つでも見つかれば確定」できます。両側誤りは多数決を取り、チェルノフ限界により「過半数が誤る確率」が試行回数に対して指数的に小さくなることを使います。いずれにせよ、必要な信頼度から逆算して試行回数 k を決められるのが乱択設計の利点です。誤り確率という連続量を、計算コストと引き換えに好きなだけ小さくできるわけです。
これらの保証はすべて「引く乱数が真に独立かつ一様」という前提に立ちます。質の低い疑似乱数や、攻撃者に予測可能なシードを使うと、最悪ケースを潰すという乱択の前提が崩れます。攻撃者がピボット選択やハッシュのシードを予測できると、決定的アルゴリズムと同じ最悪ケースを突かれます。ハッシュテーブルのハッシュフラッディング対策(ハッシュ関数の設計で扱う鍵付きハッシュ)も、本質はこの「予測不能な乱択」を守る話です。
まとめ: 乱数が与える2つの保証
乱択アルゴリズムは、入力ではなく自分の引く乱数の上で平均を取ることで、敵対的入力に対しても性能や正しさを保証します。Las Vegas は答えを常に正しく保ちつつ実行時間を確率変数にし(乱択クイックソートは期待 O(n log n)、最悪入力が消える)、Monte Carlo は実行時間を固定して低確率の誤りを許します(ミラーラビンは片側誤りで誤り (1/4)^k)。Monte Carlo の誤り確率は独立試行の反復で指数的に削れるため、コストと信頼度を自由に調整できます。決定的アルゴリズムが「最悪入力に縛られる」一方、乱択は「予測不能性そのものを設計資源にする」――この発想は、難問の近似や計算量クラス P・NPをめぐる議論にも通じる、アルゴリズム設計の強力な一手です。
プログラミング Article
乱択アルゴリズムと確率的解析を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
アルゴリズム
比較で見る軸
難易度: advanced / カテゴリ: プログラミング / タグ数: 5
導入後に効く点
Las Vegas は答えが常に正しく実行時間が確率変数(乱択クイックソートは期待 O(n log n))、Monte Carlo は実行時間が決まる代わりに低確率で誤る(ミラーラビン素数判定)。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- プログラミング
- タグ数
- 5
判断チェックリスト
- 自社の用途が「アルゴリズム / 乱択アルゴリズム」に近いか確認する。
- 強みである「乱択アルゴリズムは内部で乱数を引き、入力ではなく自分の乱択の上で平均を取る。だから敵対的な最悪入力でも期待計算量や成功確率を保証できる。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。