ファイブバックトラックアルゴリズム

        検索アルゴリズムをバックトラックすることは、私たちの目標を達成するために、良好な状態にプレスを前方検索し、また、経験則として知られている最適な選択方法、です。しかし、探索するステップは、オリジナルの選択が優れていないか、その目標を達成するために発見したときに、それが再選択し、この死者バックトラックの戻り歩行技術の端、およびいくつかの点状態条件での素敵なバックにステップバックでいわゆる「バックトラックポイント。」

        バックトラック工程によって解決される問題は、N個の選択肢には、ツリー構造によって各状態の対応を説明することができます。完全なパーミュテーション問題の後、例えば、[1、2、3]完全に配置など、各時間値は1、2、3、および次の1から値を選択することができ、2、3、から選択されます。このプロセスは、各ノードが1、2、3 3つの子ノードを有するツリーとして描画されます。全体のツリー構造をトラバースし、時間計算量が指数関数的である場合、ノード条件が満たされない場合、典型的には、ツリー深さ優先方法のトラバーサル、即ち、第1トラバーサル方法は、特定の条件を介してバックトラックの法則は、決定され、それはルートを横断する必要性を減らし、木の剪定ので、ノードは、次のトラバース開始にフォールバックします。後戻りしながら重複値を持たない構成の結果として、この条件は、検索結果のための3の長さとして、バック冗長パス、ならびに終了条件を差し引くことができます。

 

 

そのため、実際には、決定木のトラバーサルを問題を解決するためにバックトラック。考慮すべき4つの要因があります。

  • 現在のパス:すでに行った選択を指します。
  • リストを選択:すべてが利用できる現在のオプションを指します。
  • バック条件:それが有効であるかどうかを確認するために参照してください。
  • 終了条件は:あなたが条件を選択しない、底に到達するために決定木を指します。

コード側では、アルゴリズムはフレームワークを次のバックトラック、そのコアがある ため  、再帰呼び出しの後に「メークの選択」、「選択解除」への再帰呼び出しの前に、再帰のループ内。

=結果[] 
DEFバックトラック(現在の経路、選択リスト):
    IF 終了条件が満たされる:
        result.add(パス)
        のリターン

のための選択選択リスト:
         IF 条件バックを満足する:
            選択する
            (選択リストを現在のパス)バックトラックを
            選択解除

 

まず、完全な配列の問題

例えば、[2]の電流経路は、選択可能な数は、赤ノードステータス完全または配置[2,3]であるが、場合は、次の条件を満たす、すなわち重複なしバックのみ[1,3]検索結果の3の全体の長さの終了条件。

コードは以下の通りであります:

クラスのソリューション{
 パブリック
    ベクトル <ベクトル< int型 >> RES。
    ベクター <ベクトル< INT >>並び替える(ベクトル< INT >&NUMS){ 
        ベクトル < INT > TMP。
        バックトラック(TMP、NUMS)。
        リターンのres; 
    } 
    ボイドバックトラック(ベクトル< 整数 > TMP、ベクトル< INT > NUMS)
    { 
        場合(tmp.size()== nums.size())
        { 
            res.push_back(TMP)。
            リターン; 
        }
        以下のためにINT iが= 0 ; I <nums.sizeを(); I ++ 
        { 
            ベクトル < INT > ::イテレータITER。
            ITER = STD ::検索(tmp.begin()、tmp.end()、NUMS [I])。
            もし(ITER == tmp.end())
            { 
                tmp.push_back(NUMS [I])。
                バックトラック(TMP、NUMS)。
                tmp.pop_back(); 
            } 
        } 
    } 
}。

 

        この時点で、我々は完全な順列の問題でアルゴリズムをバックトラックの基本原理を説明します。もちろん、全体の構成を解決するには、このアルゴリズムがあるため、ベクトル時間計算量O(N)であるを使用して見つける必要の非常に効率的ではありません。スイッチング素子で実現するためのより良い方法。しかし、背中の枠組みに沿ったものであり、全粒網羅ツリーは避けることができないので、あまりO(N!)の時間複雑よりではありませんどんなに最適化された、と述べている必要があります。また、アルゴリズムは、純粋なブルートフォース、一般的に高いの複雑さであるバックトラック、サブ問題を重複最適化するために、バックトラッキングアルゴリズムとは異なり、動的プログラミングを備えています。

 

第二に、ブラケットの生成問題

        Nは、世代の数は括弧内に与えられている、あなたが関数を記述表し、ブラケットと効果的なのすべての可能な組み合わせを生成することが可能です。例えば、所与のN = 3、結果を生成することです:[ "((()))"、 "(()())"、 "(())()"、 "()(())"、「 ()()()「]。

私の二つの条件を満足させる法的括弧の組み合わせ:

  • 左括弧法的括弧の数は括弧の右側の番号の組み合わせと同じでなければならない、これは明白です。
  • 組み合わせ生成処理正当ブラケットは、左ブラケット一定数発生器は、数以上右括弧を生成します。ブラケットの例えば、組み合わせ「))((」最初のいくつかのサブストリングがより右括弧より括弧の組み合わせが明確正当でない、括弧を残しています。

 

        上記バックトラック4つの要素によれば、我々は一つ一つを分析し、赤色のノードに対して、現在のパスが「((」であり、任意の数である[「(」「」)〕;バックトラッキング条件は:n以下の左括弧から、あまり左ブラケットから右括弧番号生成するステップと、終了条件:ブラケットの総数* 2コードは次のように生成されたnに等しいです。

クラスのソリューション{
 パブリック
    ベクトル < 文字列 > のres;
    int型は =左0をint型の右= 0 ; 
    
    ベクター < ストリング > generateParenthesis(int型N){ 
        バックトレース("" 、N)。
        リターンのres; 
    } 
    
    ボイドバックトレース(文字列 TMP、INT N)
    { 
        場合(tmp.size()== N * 2 
        { 
            res.push_back(TMP)。
            リターン; 
        } 

        場合(<左N)
        { 
            tmp.push_backを(' ' );  ++ ; 
            バックトレース(TMP、N); 
            tmp.pop_back();  - ; 
        } 
        場合(右< 左)
        { 
            tmp.push_back(' ' );  ++ ; 
            バックトレース(TMP、N)。
            tmp.pop_back();  - ; 
        }  
    }
}。

 

おすすめ

転載: www.cnblogs.com/BobPong/p/12663204.html