導入された八のクイーンズ問題
エイトクイーン問題は、古い、よく知られた問題であるアルゴリズムをバックトラックの典型的なケース。問題は、マックス・ベテルが1848年に提示した国際チェスプレーヤーです:
国際チェス8×8のグリッド上に置く8つのクイーンズ、それはつまり、お互いを攻撃することはできません。任意の二つの女王は、同じ行、同じ列または同じスラッシュになるとどのように多くの振り子方法を尋ねたことができません。
その後、我々はの使用がどのように多くの振り子方式、計算するプログラムを使用するアルゴリズムをバックトラックを。
分析:
最初の行の最初の列を排出する1)クイーン
2)次に、第2行目の最初の列にクイーン、そしてOKを[すなわち判定が衝突である]、OKではない場合、すべての列に続く第二行目、3行目にあり続けるかどうかを決定を行うと見られます適当
8つのクイーンが正しい解決策を見出すことが、衝突の位置に配置できなくなるまで3)第三の女王を継続し、または最初の列、第二列......
4)正しい解を得るための時間は、スタックバックスタックになったとき、バックトラックし始める場合、最初は、すべて取得女王、最初の行にすべての権利溶液についてです。
5)第2のカラムの女王を続行し戻される、1,2,3,4のステップに戻ってループし続けます
説明:理論的に問題を解決する一次元アレイを使用して、実際のアルゴリズムによって、ボードを表す2次元配列を作成する必要があります。
ARR [8] = {0、4、7、5、2、6、1、3} //は[I] =ヴァル、valはIを表しARR ARR指数は、いくつかの女王の最初の、すなわち、最初の数行を示し、対応します+1クイーン、I +ヴァル+ 1の最初の行の1列に
実装コード:
以下のためのパッケージ変更com.recursion;
/ **
。* 2019年6月8日8クイーン問題ON wanbfによって作成
* /
パブリック クラスQueue8 {
// 最大を定義するには、女王の合計数が表す
int型 8 =最大;
// 配列の配列を定義し、保存します結果クイーン配置位置、例えばARR = {0 ,. 4 ,. 7 ,. 5,2 ,. 6 ,. 1 ,. 3}
値int []配列= 新しい新しい INT [最大];
静的 int型 COUNT = 0 ;
静的 INT judgeCount = 0 ;
公共 静的 ボイドメイン(文字列[]引数){
// テストA、8クイーン正しい
Queue8 queue8 = 新しい新 queue8()。
queue8.check( 0 );
System.out.printf( "ソリューション%dの合計" 、COUNT);
System.out.printf( "判定回数競合%dの総数"、judgeCount); // 1.5W
}
/ / N-女王の配置方法により調製
// 特別な注記:(I = 0をint型;私は、再帰進むためにそこにチェックするたびにチェックし 、最大の<;私は++)、 その裏があるだろう
プライベート ボイド(チェックINT N-){
IF(N - == MAX){ // N- = 8、実際には、女王8置くためである。
プリント();
戻り;
}
// 女王に変わり、衝突か否かを判断
するための(INT I = 0 ;私は最大の<;私++){
// 行のカラム1に、現在の女王nを置く
配列[N] = I;
// 、n列目I女王に配置されたときに決定されるか衝突
IF(Nジャッジ()){ //は競合しない
// 次に、N + 1クイーン放電、即ち、再帰が開始
チェック(N + 1); //
}
// 衝突した場合、配列[N]を継続= I; N-クイーンすぐに入れ銀行は、1つの位置をシフトした後
}
}
// 我々はn番目の女王を置くかどうかをチェックし、女王は女王の競合置きか、すでに検出するために、行ってきました
/ **
*
* @param n個のn番目の女王
*を@復帰
* /
プライベート ブール判事(int型 N-){
judgeCount ++ ;
のため(int型 ; Iは、N <I ++はI = 0 ){
// 説明
// 1配列[I] ==配列[n]はn番目の女王とn-1女王の前かどうかを判断する意味同じ列に
// 2 Math.abs(Ni)の== Math.abs(配列[N] -アレイは、[i])とn番目及びIクイーンクイーンは同じスラッシュであるか否かを決意表す
// N 1 =。 [1]。。。= 1 1 1 = N-アレイ最初の二つを配置
// Math.abs(1-0)1 == Math.abs(配列[N-] -配列[I]が)。Math.absは(1-0)= = 1
// 3は同じラインか否かを判断するには、各時間増分N-必要がない
場合(配列[I] ==配列[N-] || Math.abs(Ni)のMath.abs(配列[N- == ] - 配列[I])){
戻り falseに。
}
}
戻り値 をtrueに;
}
// 女王出力の位置を表示することができる方法書き込み
専用 ボイドプリント(){
COUNT ++を、
ため(int型 I = 0;私は<Array.lengthとすること; Iは++ ){
のSystem.outを。プリント(配列[I] + "" );
}
のSystem.out.println();
}
}
输出
0 4 7 5 2 6 1 3
0 5 7 2 6 3 1 4
0 6 3 5 7 1 4 2
0 6 4 7 1 3 5 2
1 3 5 7 2 0 6 4
1 4 6 0 2 7 5 3
1 4 6 3 0 7 5 2
1 5 0 6 3 7 2 4
1 5 7 2 0 3 6 4
1 6 2 5 7 4 0 3
1 6 4 7 0 3 5 2
1 7 5 0 2 4 6 3
2 0 6 4 7 1 3 5
2 4 1 7 0 6 3 5
2 4 1 7 5 3 6 0
2 4 6 0 3 1 7 5
2 4 7 3 0 6 1 5
2 5 1 4 7 0 6 3
2 5 1 6 0 3 7 4
2 5 1 6 4 0 7 3
2 5 3 0 7 4 6 1
2 5 3 1 7 4 6 0
2 5 7 0 3 6 4 1
2 5 7 0 4 6 1 3
2 5 7 1 3 0 6 4
2 6 1 7 4 0 3 5
2 6 1 7 5 3 0 4
2 7 3 6 0 5 1 4
3 0 4 7 1 6 2 5
3 0 4 7 5 2 6 1
3 1 4 7 5 0 2 6
3 1 6 2 5 7 0 4
3 1 6 2 5 7 4 0
3 1 6 4 0 7 5 2
3 1 7 4 6 0 2 5
3 1 7 5 0 2 4 6
3 5 0 4 1 7 2 6
3 5 7 1 6 0 2 4
3 5 7 2 0 6 4 1
3 6 0 7 4 1 5 2
3 6 2 7 1 4 0 5
3 6 4 1 5 0 2 7
3 6 4 2 0 5 7 1
3 7 0 2 5 1 6 4
3 7 0 4 6 1 5 2
3 7 4 2 0 6 1 5
4 0 3 5 7 1 6 2
4 0 7 3 1 6 2 5
4 0 7 5 2 6 1 3
4 1 3 5 7 2 0 6
4 1 3 6 2 7 5 0
4 1 5 0 6 3 7 2
4 1 7 0 3 6 2 5
4 2 0 5 7 1 3 6
4 2 0 6 1 7 5 3
4 2 7 3 6 0 5 1
4 6 0 2 7 5 3 1
4 6 0 3 1 7 5 2
4 6 1 3 7 0 2 5
4 6 1 5 2 0 3 7
4 6 1 5 2 0 7 3
4 6 3 0 2 7 5 1
4 7 3 0 2 5 1 6
4 7 3 0 6 1 5 2
5 0 4 1 7 2 6 3
5 1 6 0 2 4 7 3
5 1 6 0 3 7 4 2
5 2 0 6 4 7 1 3
5 2 0 7 3 1 6 4
5 2 0 7 4 1 3 6
5 2 4 6 0 3 1 7
5 2 4 7 0 3 1 6
5 2 6 1 3 7 0 4
5 2 6 1 7 4 0 3
5 2 6 3 0 7 1 4
5 3 0 4 7 1 6 2
5 3 1 7 4 6 0 2
5 3 6 0 2 4 1 7
5 3 6 0 7 1 4 2
5 7 1 3 0 6 4 2
6 0 2 7 5 3 1 4
6 1 3 0 7 4 2 5
6 1 5 2 0 3 7 4
6 2 0 5 7 4 1 3
6 2 7 1 4 0 5 3
6 3 1 4 7 0 2 5
6 3 1 7 5 0 2 4
6 4 2 0 5 7 1 3
7 1 3 0 6 4 2 5
7 1 4 2 0 6 3 5
7 2 0 5 1 4 6 3
7 3 0 2 5 1 6 4
一共有92解法一共判断冲突的次数15720次
从输出结果可以看出 一共有92中摆法,并且在执行过程中一共判断了15720次。