八のクイーンズ問題 - バックトラッキングソリューション

八台のクイーン問題:チェスの8×8のグリッド上の場所8人の女王を、それがお互いを攻撃することはできません、それは同じ列または同じスラッシュ、任意の二つの王妃が同じ行にすることはできません、され、どのように多くの振り子方法を尋ねました。

INT g_number = 0; //どのように多くの表示方法
 
ボイドEightQueen()
{
   CONSTのINT =クイーンズ8; //ボードサイズ
 
   INT columnIndexに[クイーン]; //列のインデックス
 //反復行
   のための(I = 0 int型、iが < クイーンズ; ++ I)
 
       columnIndexに[I] = I。

   順列(columnIndexに、クイーン、0);
}
 
ボイド順列(INT columnIndexに[]、int型の長さ、INTインデックス)
{
   IF(インデックス==長さ)
   {//满足条件
       (チェック(columnIndexに、長さ))であれば
       {
           ++ g_number。//摆法数+1
           PrintQueen(columnIndexに、長さ)。//输出
       }
   }
   そうでなければ
   {
       (I =インデックスをint型、私は長さ<; ++ i)が用
       {   
           int型TEMP = columnIndexに[I]。
           columnIndexに[I] = columnIndexに[インデックス]。
           columnIndexに[インデックス] = TEMP。
 
           順列(columnIndexに、長さ、インデックス+ 1)。

           columnIndexに= TEMP [インデックス];
 
           ; columnIndexに[インデックス]はcolumnIndexに[I] =
 
           columnIndexに[I] = TEMP;
       }
   }
}
//剪定関数!!!!!!!!
BOOLチェック(columnIndexにはint []、int型の長さを)
{
   私は長さ<;のための(I = 0 int型Iが++)
   {
       ため(INT I = J + 1、。J <長さ、J ++)
       {// 同じ列にハッチングまたは同じか否かを判断する
           (IF( I - columnIndexに== J [I] - columnIndexに[J])
               ||(J -私はcolumnIndexに[I] == - columnIndexに[J]))
           はfalseに戻り;
       }
   }
   真に戻ります;
}

 //出力表示g_numberとcolumnIndexに[I]の値に対応する
PrintQueen(columnIndexが[]、int型の長さをINT)ボイド
{
   のprintf( "%溶液Dの\のN-"、g_number); //プリントソリューション
   //プリントすべての列のインデックス値
   のための(I = 0 int型、Iは長さ<; ++ I)の
 
       printfの( "%D \ T"、columnIndexに[I]);
 
   のprintf( "\ N-");
}


:何がバックトラックされる
列挙するための検索処理と同様の試みを、条件を解決してきたが判明したときに別のパスを試すに戻る「戻る」で、満足していないです。
 
バックトラックは最適な選択である、検索方法、目標を達成するために最適な選択条件によって前方に検索します。しかし、時にステップが探索するために、オリジナルの選択肢が優れていないか、その目標を達成するために、それはバックトラックの戻り徒歩技術の再選択、この行き止まりにバックステップで発見。
 
問題解決する一般的な手順:
1を、用問題、解決策スペースの問題定義に、それは問題に少なくとも一つの(最適な)ソリューションが含まれています。
図2は、解空間を探索しやすい構造は、缶のように決定されるバックトラック全体の解空間を探索容易。
図3に示すように、深さ優先解空間の探索、および検索による検索処理において無効なプルーニングを防止する機能
 
 
の詳細なバックトラックを:
ノード(ルートノード)から開始するようにバックトラック、深さ優先全体の解空間を探索。開始ノードは、スリップノット点となるだけでなく、現在のノードの拡張となります。現在の拡張ノードでは、検索は、深さ方向の新しいノードへ移動します。新しいノードは、スリップノットの新しいポイントとなり、拡張ノードになります。モバイルがもはや現在のノードの深さ方向に伸びることができない場合、現在のノードは、拡張結節点となります。この場合には、最も近いポイントにスリップノットで(裏面)に戻されるべきであり、この点は、現在の拡張のスリップノットノードとなります。バックトラックということは作業のこのようである再帰的にそれがされるまで、これまでにない点のスリップノットが必要なソリューションや解空間を見つけることがあり解空間で検索します。

おすすめ

転載: www.cnblogs.com/fightingcode/p/10991995.html