バックトラッキングと分枝限定法

バックトラッキング方法のアイデアの簡単な説明は次のとおりです:問題のソリューションスペースをグラフまたはツリー構造表現に変換し、深さ優先探索戦略を使用して、実行可能なすべてのソリューションまたは最適なソリューションをトラバース、記録、および検索しますトラバーサルプロセス中。

基本的な考え方は次のとおりです。

  • グラフ深さ優先探索
  • 二分木のポストオーダートラバーサル

バックトラッキング法は、深さ優先戦略に従って問題の解空間ツリーを検索します。最初に、解空間ツリーをルートノードから検索します。アルゴリズムが解空間ツリーのノードを検索するときは、最初にプルーニング関数を使用します。ノードが実行可能かどうかを判断します(つまり、問題の解決策を取得できます)。実行可能でない場合は、ノードをルートとするサブツリーの検索をスキップし、レイヤーごとにその祖先ノードに戻ります。それ以外の場合は、サブツリーに入り、深さ優先戦略に従って検索を続けます。

バックトラッキングメソッドの基本的な動作は検索です。検索プロセスでは、プルーニング関数を使用して無効な検索を回避します。プルーニング関数には、次の2つのタイプがあります。1。制約関数を使用して制約を満たさないパスをカットする。2。バインド関数を使用してGoをカットする最適な解決策を得ることができないパスに。

問題の鍵は、問題の解空間を定義し、それをツリー(つまり、解空間ツリー)に変換する方法です。解空間ツリーは、サブセットツリーと順列ツリーの2つのタイプに分けられます。2つのアルゴリズムは大まかにあります。構造と考え方は同じです。

【例】エイトクイーン問題。8×88 \ times8があります。8××8つの正方形のチェス盤に8つのクイーンを配置して、2つのクイーンが互いに攻撃できないようにします。つまり、同じ行と列に2つ以上のクイーンが存在できないようにします。平行線上に2つ以下のクイーンが存在するようにします。試してみてください。すべての配置方法を提供します。

【解決】

ここに画像の説明を挿入

xxしましょうxは行の添え字yyを表しますyは列の添え字を表し、制約を取得できます。任意の2つの位置(xi、yi)(x_i、y_i)xY(xj、yj)(x_j、y_j)xJYJ、有
{xi≠xjyi≠yj ∣ xi --xj ∣≠∣ yi --yj ∣ \ begin {cases} x_i \ ne x_j \\ \\ y_i \ ne y_j \\ \\ | x_i-x_j | \ ne | y_i --y_j | \ end {cases}バツ=バツJY=YJxバツJ=yYJ|
以下は、検索戦略を定義し、制約に従って分枝限定法を定義することです。

最も簡単なアイデアは、8番目のクイーンが配置されるまで最初のクイーンの配置を開始することです。

1番目から8番目のクイーンがそれぞれ1番目から8番目の列にあることを指定できます。その場合、適切な行番号の配置を解決するだけで済みます。

void queen(int row){
    
    
    if(row==8){
    
    
        total++;
    }else{
    
    
        for(int col=0; col!=8; col++){
    
    
            c[row]=col;
            if(is_ok(row)){
    
    
                queen(row+1);
            }
        }  
    }
}

queen(0)特定の問題を呼び出すと、コードを最小限に変更するだけで問題が解決します。

おすすめ

転載: blog.csdn.net/dreaming_coder/article/details/114378802