1. 程式人生 > >回溯法(八皇后)

回溯法(八皇后)

回溯法(探索與回溯法)是一種選優搜尋法,又稱為試探法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為”回溯點”。

八皇后問題,是一個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於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 + + + + +
未顯示完全