GeeksforGeeks

前提条件:

  • 再帰
  • 複雑性分析

バックトラッキングは、任意の時点で問題の制約を満たすことができない解を削除して、一度に一つずつ漸進的に解を構築しようとすることによって、問題を再帰的に解決するアルゴリズム技術です(時間によって、ここでは、検索ツリーの任意のレベルに達するまでの経過時間と呼ばれます)。 Wikiの定義によると

,

バックトラッキングは、計算問題を解決するために可能なすべての組み合わせを検索することを考慮する一般的なアルゴリズム技術として定義

バックトラッキングには、次の3つのタイプの問題があります。–

  1. 意思決定問題-この中で、我々は実現可能な解決策を探します。
  2. 最適化問題–これで、最良の解決策を探します。
  3. 列挙問題–これで、すべての実現可能な解決策が見つかります。

バックトラッキングを使用して問題を解決できるかどうかを判断する方法は?

一般に、任意の客観的な解に対して明確かつ明確に定義された制約を持つすべての制約満足問題は、候補を有効な解に完了できないと判断したときにすぐに、解への候補を段階的に構築し、候補を放棄する(”バックトラッキング”)。 しかし、議論されている問題のほとんどは、入力サイズの順に対数、線形、線形対数時間複雑性の動的計画法や貪欲アルゴリズムのような他の既知のアル しかし、今までそれらを解決するためのバックトラッキングアルゴリズムしか持たないいくつかの問題が残っています。

目の前に三つの箱があり、そのうちの一つだけが金貨を持っているが、どちらがわからないという状況を考えてみてください。 だから、コインを得るためには、すべてのボックスを一つずつ開く必要があります。 コインが含まれていない場合は、コインを見つけるまでそれを閉じて2番目のボックスをチェックする必要があります。 これは、可能な限り最良の解決策に到達するために、すべてのサブ問題を1つずつ解決することです。

バックトラッキングアプローチをより正式に理解するために、

任意の計算問題PとdataDインスタンスに対応するインスタンスが与えられた場合、問題を解決するために満たす必要があるすべての制約はCで表されます。

アルゴリズムは、空の解集合Sから始まり、解の構築を開始します。 S= {}

  1. 残っている最初の移動をSに追加します(可能なすべての移動はSに1つずつ追加されます)。 これで、アルゴリズムの検索ツリーに新しいサブツリーsが作成されます。
  2. s+sCの各制約を満たしているかどうかを確認します。
    • はいの場合、サブツリーsはさらに”子”を追加するために”適格”です。そうでなければ、サブツリー全体sは役に立たないので、引数Sを使用してステップ1に戻ります。
  3. 新たに形成されたサブツリーsの「適格性」が発生した場合、引数S+sを使用して、ステップ1に戻ります。
  4. s+sをチェックすると、データ全体Dの解であることが返されます。 プログラムを出力して終了します。 そうでない場合は、現在のsで解決策が不可能であることを返し、それを破棄します。

再帰とバックトラッキングの違い:

再帰では、関数は基本ケースに達するまで自分自身を呼び出します。 バックトラッキングでは、問題に対して最良の結果が得られるまで、再帰を使用してすべての可能性を探索します。

バックトラッキングのための擬似コード:

1. 再帰的なバックトラッキングの解決策。

void findSolutions(n, other params) : if (found a solution) : solutionsFound = solutionsFound + 1; displaySolution(); if (solutionsFound >= solutionTarget) : System.exit(0); return for (val = first to last) : if (isValid(val, n)) : applyValue(val, n); findSolutions(n+1, other params); removeValue(val, n);

2. 解が存在するかどうかを見つける

boolean findSolutions(n, other params) : if (found a solution) : displaySolution(); return true; for (val = first to last) : if (isValid(val, n)) : applyValue(val, n); if (findSolutions(n+1, other params)) return true; removeValue(val, n); return false;

標準的なバックトラッキング問題、N-Queen問題を解決しようとしましょう。
N女王は、n×Nのチェス盤にN個のチェスの女王を配置して、二つの女王が互いに攻撃しないようにする問題です。 たとえば、以下は4つの女王問題の解決策です。

期待される出力は、queensが配置されているブロックに対して1sを持つバイナリ行列です。 例えば、以下は上記の4つのクイーン解の出力行列である。

{ 0, 1, 0, 0}{ 0, 0, 0, 1}{ 1, 0, 0, 0}{ 0, 0, 1, 0}

バックトラッキングアルゴリズム:アイデアは、左端の列から始まる、異なる列に女王を一つずつ配置することです。 列に女王を配置すると、既に配置されている女王との衝突をチェックします。 現在の列で、衝突がない行が見つかった場合、この行と列を解決策の一部としてマークします。 衝突のためにそのような行が見つからない場合は、バックトラックしてfalseを返します。

1) Start in the leftmost column2) If all queens are placed return true3) Try all rows in the current column. Do following for every tried row. a) If the queen can be placed safely in this row then mark this as part of the solution and recursively check if placing queen here leads to a solution. b) If placing the queen in leads to a solution then return true. c) If placing queen doesn't lead to a solution then unmark this (Backtrack) and go to step (a) to try other rows.3) If all rows have been tried and nothing worked, return false to trigger backtracking.

上記のアプローチの完全な実装については、Backtracking|Set3(N Queen Problem)に関する記事を参照することができます。
より多くのバックトラッキングの問題:

  • バックトラッキング/セット1(騎士のツアー問題)
  • バックトラッキング|セット2(迷路の中のラット)
  • バックトラッキング/セット4(サブセット合計)
  • バックトラッキング/セット5(m着色問題)
  • –> 詳細はこちらをクリック
記事タグ:
練習タグ:

コメントを残す

メールアドレスが公開されることはありません。