mirror of
https://github.com/krahets/hello-algo.git
synced 2026-11-02 03:05:24 +08:00
* Retranslate the complete Japanese online edition from Chinese * Fit Japanese homepage labels and localize heading permalinks * Point Japanese contribution instructions to the Japanese preview * Replace locale conditionals with multilingual UI tables
3.4 KiB
3.4 KiB
まとめ
要点の振り返り
- バックトラッキングは本質的に総当たり法で、解の空間を深さ優先で走査し、条件を満たす解を探します。見つかった解を記録し、すべての解を得るか、走査が終わるまで続けます。
- 探索は試行と後戻りからなります。深さ優先探索で選択肢を試し、制約を満たさない場合は直前の選択を取り消して元の状態に戻り、ほかの選択肢を試します。試行と後戻りは互いに逆の操作です。
- バックトラッキングの問題には通常、複数の制約があり、それらを枝刈りに利用できます。不要な探索分岐を早めに打ち切ることで、効率を大きく高められます。
- 主に探索問題と制約充足問題に使われます。組合せ最適化問題も解けますが、より効率的な方法や、よりよい結果を得られる方法があることが多いです。
- 順列列挙問題では、与えられた集合の要素のすべての並べ方を探します。各要素が選択済みかを配列に記録し、同じ要素を再び選ぶ分岐を枝刈りして、各要素を一度だけ選びます。
- 順列列挙で集合に重複した要素があると、結果の順列も重複します。通常はハッシュ集合を使い、同じ値の要素を各回の選択で一度だけ選ぶよう制限します。
- 部分集合和問題では、与えられた集合から、和が目標値になる部分集合をすべて探します。集合は順序を区別しませんが、探索はすべての順序を出力するため、重複が生じます。探索前にソートし、各回の走査の開始位置を変数で指定することで、重複を生む分岐を枝刈りします。
- 部分集合和問題では、配列内の同じ値の要素も重複した集合を生みます。ソート済みであることを利用し、隣り合う要素が同じかを調べて枝刈りすることで、同じ値を各回で一度だけ選ぶようにします。
nクイーン問題では、n個のクイーンをn \times nの盤面に、どの 2 個も攻撃し合わないよう配置します。行、列、主対角線方向、副対角線方向の制約があります。行の制約は、各行に一つずつ配置する戦略で満たします。- 列と対角線の制約は似た方法で扱います。列には、各列にクイーンがあるかを記録する配列を使い、選んだマスが有効かを判定します。対角線には二つの配列を使い、各方向の線上にクイーンがあるかを記録します。難しいのは、同じ主(副)対角線方向の線上にあるマスの、行・列インデックスの規則を見つけることです。
Q & A
Q:バックトラッキングと再帰の関係は、どう理解すればよいですか。
大まかに言うと、バックトラッキングは「アルゴリズムの戦略」で、再帰は「道具」に近いものです。
- バックトラッキングは通常、再帰で実装します。ただし、バックトラッキングは再帰の用途の一つであり、探索問題に再帰を使う方法です。
- 再帰の構造は「部分問題に分解する」という解き方を表し、分割統治、バックトラッキング、動的計画法(メモ化再帰)などによく使われます。