アルゴリズムパラダイムの系統(探索・最適化・近似の地図)
初見の問題にどの設計手法を当てるか、勘ではなく構造で選べるようになる。全探索から分割統治・動的計画・貪欲・乱択・近似・分枝限定までを1枚の地図に整理し、分岐の判断軸を示す。
- 1.設計パラダイムは「全探索を起点に、問題の構造を使って枝を刈る/コストを下げる派生」として1本の系統で捉えられる。
- 2.選択の判断軸は3つ。最適部分構造があるか、貪欲選択性が立つか、厳密解が要るか近似で足りるか。
- 3.NP困難で厳密解が現実的でないときは、分枝限定で枝を刈るか、近似比つき近似・乱択・メタヒューリスティックへ降りる。
なぜ「パラダイムの地図」が要るのか
個別のアルゴリズムは数百あっても、その背後にある設計パラダイムは十指に収まります。実務で問われるのは「ダイクストラを覚えているか」ではなく、初見の問題に対してどの設計枠を当てるべきかを構造から判断できるかです。本稿は全探索・分割統治・動的計画法・貪欲法・乱択・近似・分枝限定を1枚の系統図に並べ、分岐の判断軸を明示します。
地図の起点は1つだけです。あらゆる組合せ問題は、原理上は全探索(総当たり)で解ける。残りのパラダイムはすべて「全探索のままでは指数時間で破綻するので、問題の構造を使って探索空間を削る/コストを下げる」派生として理解できます。つまりパラダイムの系統とは、全探索から枝を刈っていく順序の系図です。計算量記法に不安があれば計算量と Big-O 記法を先に押さえてください。
起点としての全探索と、その2つの限界
全探索は、解の候補空間を漏れなく列挙して条件を満たすものを選ぶ手法です。正しさは自明で、必ず最適解に到達します。問題は2つだけ。
- 空間が指数的: 部分集合は
2^n、順列はn!通りあり、nがわずかに増えるだけで計算不能になる。 - 重複計算が多い: 同じ部分問題を何度も解き直すことがある。
この2つの限界のどちらを叩くかで、派生の方向が分かれます。空間を構造的に分割して征服するのが分割統治、重複計算を記憶で消すのが動的計画法、正しい一手を事前に確定して列挙そのものを省くのが貪欲法、列挙を続けつつ見込みのない枝を証明して捨てるのが分枝限定です。
全探索を素朴な多重ループでなく、解を1要素ずつ伸ばし矛盾したら戻る形で書くとバックトラッキングになります。N-Queens やナンプレが典型で、これは「制約を満たさない部分解で即座に枝刈りする全探索」です。分枝限定はこの枝刈りに**目的関数の限界値(bound)**を足した拡張版で、両者は地続きです。
構造を使う3系統: 分割・記憶・確定
全探索を実用化する3つの主要派生を、満たすべき構造とともに並べます。
| パラダイム | 全探索を改善する仕掛け | 必要な構造 | 典型例 |
|---|---|---|---|
| 分割統治 | 問題を独立な部分問題に割り再帰で征服 | 部分問題が互いに独立に解ける | マージソート / 二分探索 / FFT |
| 動的計画法 | 重なる部分問題の解を表に記憶し再利用 | 最適部分構造 + 部分問題の重複 | 編集距離 / ナップサック / 区間DP |
| 貪欲法 | 各段で局所最良を選び列挙を省略 | 最適部分構造 + 貪欲選択性 | 最小全域木 / ハフマン符号 |
3者の関係は入れ子です。分割統治は部分問題が独立(片方の解がもう片方に影響しない)なときに使えます。マージソートの左半分と右半分は独立です。ところが部分問題が重なると、分割統治のままでは同じ部分問題を指数回解き直してしまう。そこで重複分を表に記憶するのが動的計画法です。フィボナッチを素朴再帰で書くと指数時間なのに、メモ化すれば O(n) になるのが象徴的です。
さらに、DPでは全状態を試しますが、もし各段で選ぶべき一手が事前に確定できるなら、選択肢の列挙すら不要になります。これが貪欲法で、DPの特殊化と見なせます。「DPは全選択を試し最良を残す、貪欲は正しい一手が最初から分かっている」――この差が両者を分ける核心です。
全探索(指数時間・必ず最適)
├─ 部分問題が独立 → 分割統治
│ └─ 部分問題が重なる → 動的計画法(記憶で重複除去)
│ └─ 各段の最良手が確定 → 貪欲法(列挙を省略)
└─ 列挙しつつ見込みなき枝を証明して捨てる → 分枝限定
両者とも「部分問題に分けて解く」点は同じです。決定的な違いは部分問題の関係。独立なら分割統治で再帰するだけ、重複するなら記憶しないと指数爆発する。マスター定理が効くのは前者の世界です。詳しくは分割統治法とマスター定理を参照してください。
選択のための3つの判断軸
ここまでを、初見の問題に当てる手順としてまとめます。上から順に問うと、当てるべき枠がほぼ一意に絞れます。
- 軸1: 最適部分構造があるか。部分問題の最適解を組み合わせると全体の最適解になるか。なければ DP も貪欲も使えず、全探索/分枝限定の世界です。
- 軸2: 貪欲選択性が立つか。各段の局所最良を選んでよいことを交換論法などで証明できるか。立てば貪欲、立たなければ DP。
- 軸3: 厳密解が要るか、近似で足りるか。問題が NP困難で入力が大きいなら、厳密解は諦め近似・乱択・ヒューリスティックへ降りる。
軸3が地図の後半を分けます。多項式時間で厳密に解ける問題(P クラス)なら前半の3系統で足ります。しかし巡回セールスマン(TSP)やナップサック、頂点被覆のように NP困難な問題では、n が大きいと厳密解が事実上得られません。P と NP の境界そのものは計算量クラス P と NPで扱います。ここで「厳密だが遅い」か「速いが厳密でない」かの二者択一が生じます。
厳密だが遅い: 分枝限定
厳密解にこだわるなら、全探索の指数空間をいかに賢く刈るかが勝負です。分枝限定(branch and bound)は、解空間を木として分岐(branch)しつつ、各部分木が到達しうる目的関数の限界値(bound)を評価し、現在の暫定最適を超えられないと証明できた枝を丸ごと捨てる手法です。
branch_and_bound(problem):
best = +infinity # 最小化問題の暫定最適
stack = [root_partial_solution]
while stack not empty:
node = pop(stack)
if bound(node) >= best: # この枝の最良でも暫定に勝てない
continue # 枝ごと刈る(prune)
if is_complete(node):
best = min(best, cost(node))
else:
for child in branch(node):
push(stack, child)
return best
肝は bound の質です。緩めの下界しか出せないと刈れず、ほぼ全探索に退化します。逆に線形緩和(整数制約を実数に緩めて解く)などで強い下界を作れると、指数空間でも実用的に解けます。最悪計算量は指数のままですが、平均的には膨大な枝を刈れるのが価値です。整数計画ソルバの中核技術でもあります。
分枝限定が全探索より速いのは、強い限界値で枝を刈れたときだけです。下界が弱い、あるいは最適値付近に解が密集していると刈れず、計算量は指数のまま。NP困難問題で「分枝限定を使えば多項式時間になる」わけではありません。あくまで厳密性を保ったまま定数倍~平均挙動を改善する手法だと正確に理解してください。
速いが厳密でない: 近似・乱択・メタヒューリスティック
厳密解を諦める側の地図です。ここは「どこまで質を保証するか」で階層化されます。
| 手法 | 得られる保証 | 代表例 | 向くケース |
|---|---|---|---|
| 近似アルゴリズム | 最適値との比(近似比)を理論保証 | 頂点被覆2近似 / TSP(三角不等式)1.5近似 | 保証つきで NP困難に妥協 |
| 乱択アルゴリズム | 期待時間や成功確率を確率的に保証 | クイックソート / Miller-Rabin素数判定 | 平均で速い・確率的に正しい |
| メタヒューリスティック | 保証なし・経験的に良い解 | 焼きなまし / 遺伝的アルゴリズム / 局所探索 | 保証は要らず実用解が要る |
近似アルゴリズムは、最適値に対する解の比(近似比)を理論的に保証します。頂点被覆の極大マッチング法は必ず最適の2倍以内、距離が三角不等式を満たす TSP の Christofides 法は1.5倍以内、というように「最悪でもこの質」を約束できるのが価値です。
乱択アルゴリズムは乱数を使い、期待計算時間や正答確率を保証します。クイックソートは枢軸をランダム化すると期待 O(n log n)、Miller–Rabin 素数判定は誤答確率を任意に小さくできます。近似が「解の質」を保証するのに対し、乱択は「時間や確率」を保証する、と保証の対象が違う点を区別してください。
メタヒューリスティック(焼きなまし・遺伝的アルゴリズム・局所探索)は理論保証を持たず、経験的に良い解を返します。保証がない代わりに適用範囲が広く、定式化が難しい実問題で最後の手段になります。
「近似アルゴリズム」と「ヒューリスティック」は同義ではありません。近似アルゴリズムは近似比という理論保証を持つもの(例: 2近似なら必ず最適の2倍以内)。ヒューリスティックは保証がなく経験則で動くもの。試験でも実務でも「この手法の解は最適から何倍以内か証明できるか」を問えば両者は明確に区別できます。乱択の保証対象は質ではなく時間・確率である点も頻出の引っかけです。
1枚の地図にまとめる
最後に全体を1本の系統として俯瞰します。年代でなく枝刈りの論理で並べた系図です。
全探索(総当たり・必ず最適・指数時間)
│
├─ P クラス(多項式時間で厳密に解ける)
│ ├─ 部分問題が独立 → 分割統治
│ ├─ 部分問題が重複+最適部分構造 → 動的計画法
│ └─ 上記+貪欲選択性が成立 → 貪欲法
│
└─ NP困難(厳密解が現実的でない)
├─ それでも厳密解が要る → 分枝限定(強い下界で枝刈り)
└─ 近似で足りる
├─ 近似比を理論保証 → 近似アルゴリズム
├─ 時間・確率を保証 → 乱択アルゴリズム
└─ 保証は不要・実用解優先 → メタヒューリスティック
判断の順序を一文で言えば、**「最適部分構造はあるか → 貪欲選択性は立つか → 厳密解が要るか近似で足りるか」**の3問を上から潰すだけです。この地図を持っていれば、初見の問題でも当てるべきパラダイムを勘でなく構造から絞り込めます。個々のアルゴリズムを覚える前に、この分岐の論理を体に入れることが、設計力の土台になります。
プログラミング Article
アルゴリズムパラダイムの系統(探索・最適化・近似の地図)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
アルゴリズム
比較で見る軸
難易度: advanced / カテゴリ: プログラミング / タグ数: 5
導入後に効く点
選択の判断軸は3つ。最適部分構造があるか、貪欲選択性が立つか、厳密解が要るか近似で足りるか。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- プログラミング
- タグ数
- 5
判断チェックリスト
- 自社の用途が「アルゴリズム / 設計パラダイム」に近いか確認する。
- 強みである「設計パラダイムは「全探索を起点に、問題の構造を使って枝を刈る/コストを下げる派生」として1本の系統で捉えられる。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。