回溯法(八皇后)
阿新 • • 發佈:2019-02-01
回溯法(探索與回溯法)是一種選優搜尋法,又稱為試探法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為”回溯點”。
八皇后問題,是一個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於1848年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。 高斯認為有76種方案。1854年在柏林的象棋雜誌上不同的作者發表了40種不同的解,後來有人用圖論的方法解出92種結果。計算機發明後,有多種計算機語言可以解決此問題
程式碼:
public class Queen {
public static int num = 0;//累計方案
public static final int MAXQUEEN = 8;
public static int[] cols = new int[MAXQUEEN];//定義cols陣列,表示8列棋子皇后擺放的位置,一列一列的插入
/**
*
* @param n 填第n列的皇后
*/
public void getCount(int n){
boolean [] rows = new boolean [MAXQUEEN];//記錄每列每個方格是否可以放皇后
for(int m = 0;m<n;m++){
rows[cols[m]] = true;
int d = n - m;//斜對角
//正斜方向
//if判斷防止行數為負或大於最大行數
if(cols[m]-d>=0){
rows[cols[m] -d] = true;
}
//反斜方向
if(cols[m]+d<=(MAXQUEEN-1 )){
rows[cols[m]+d] = true;
}
}
//到此知道了哪些位置不能放皇后
for(int i = 0;i<MAXQUEEN;i++){
if(rows[i]){
//不能放
continue;
}
cols[n] = i;
if(n<MAXQUEEN-1){
getCount(n+1);
}else{
//找到完整的一套方案
num++;
printQueen();
}
//下面可能仍然有合法位置
}
}
private void printQueen() {
System.out.println("第"+num+"種方案");
for(int i = 0;i<MAXQUEEN;i++){
for(int j = 0;j<MAXQUEEN;j++){
if(i == cols[j]){
System.out.print("0 ");
}else{
System.out.print("+ ");
}
}
System.out.println();
}
}
public static void main(String[] args){
Queen queen = new Queen();
queen.getCount(0);
}
}
結果:
第1種方案
0 + + + + + + +
+ + + + + + 0 +
+ + + + 0 + + +
+ + + + + + + 0
+ 0 + + + + + +
+ + + 0 + + + +
+ + + + + 0 + +
+ + 0 + + + + +
第2種方案
0 + + + + + + +
+ + + + + + 0 +
+ + + 0 + + + +
+ + + + + 0 + +
+ + + + + + + 0
+ 0 + + + + + +
+ + + + 0 + + +
+ + 0 + + + + +
未顯示完全