递归回溯解决八皇后问题
生活随笔
收集整理的這篇文章主要介紹了
递归回溯解决八皇后问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 八皇后問題
- 問題解析
- 代碼實現
- 完整代碼
前言
八皇后問題是一個古老而著名的問題,是回溯算法的典型例題。該問題是十九世紀著名的數學家高斯1850年提出:在8X8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處于同一行、同一列或同一斜線上,問有多少種擺法。
高斯認為有76種方案。1854年在柏林的象棋雜志上不同的作者發表了40種不同的解,后來有人用圖論的方法解出92種結果。現代教學中,把八皇后問題當成一個經典遞歸算法例題。
八皇后問題
問題解析
首先八個皇后之間需要滿足:
- 不在同一列上
- 不在同一行上
- 不在同一斜線上
- 不在同一反斜線上
首先可以逐行進行遍歷,每一行遍歷出一個符合條件的位置,然后就開始遍歷下一行,尋找下一個符合條件的位置,如果找的到則繼續遍歷下一行,否則就回溯到上一行的位置,對其他位置進行遍歷重新尋找符合條件的位置。當順利地遍歷到最后一行仍然找得到符合條件的位置時,此時就完成了一種可行的八皇后擺放方案。然后繼續遍歷該行其他位置是否有符合條件的,沒有就返回到上一行繼續尋找,以此反復進行遍歷就可以得出所有的擺放方案。
代碼實現
-
初始化需要用到的變量
/*** 八個皇后*/ int max = 8;/*** 用一個一維數組來模擬整個棋盤<數組的索引表示第幾行,而索引所對應的數則表示皇后放在在該行的第幾列上>*/ int[] array = new int[max];/*** 用于記錄有多少種擺放方案 */ int count = 0; -
打印出八皇后的擺放位置
/*** 輸出八皇后的位置*/ public void print() {//滿足條件 count++;for (int i = 0; i < array.length; i++) {System.out.print(array[i]+"\t");}System.out.println(); } -
判斷八皇后之間是否產生沖突
/*** 判斷第n個皇后是否與之前的皇后發生沖突* @param n 第n個皇后* @return*/ public boolean judge(int n) {//遍歷第n個皇后之前的所有皇后for (int i = 0; i < n; i++) {//1.array[i] == array[n] ---> 第n個皇后和前面的皇后是否在同一列//2.Math.abs(i-n) == Math.abs(array[i] - array[n]) ---> 第n個皇后和前面的皇后是否在同一斜線if (array[i] == array[n] || Math.abs(i-n) == Math.abs(array[i] - array[n])){return false;}}return true; } -
利用遞歸擺放皇后
/*** 利用遞歸擺放皇后* @param n 表示第n個皇后* @return*/ public void check(int n) {//如果符合該條件說明已經完成了一種可行的擺法if (n == max){//打印擺放信息print();//回溯到上一行重新尋找可行的擺放位置return;}//通過循環從第一行開始逐列擺放皇后//通過遞歸來遍歷行數for (int i = 0; i < max; i++){array[n] = i;//判斷當前放置的皇后與其他位置上的皇后是否產生沖突if (judge(n)){check(n+1);}//如果沖突繼續執行array[n]=i 重新尋找該行上可行的擺放位置} }
完整代碼
/*** @Author: 又蠢又笨的懶羊羊程序猿* @CreateTime: 2021年08月12日 20:59:14*/ public class TheEightQueensOfDeath {public static void main(String[] args) {TheEightQueensOfDeath theEightQueensOfDeath = new TheEightQueensOfDeath();theEightQueensOfDeath.check(0);System.out.println("Result:"+theEightQueensOfDeath.count);}int max = 8;int[] array = new int[max];int count;/*** 利用遞歸擺放皇后* @param n 表示第n個皇后* @return*/public void check(int n){//如果符合該條件說明已經完成了一種可行的擺法if (n == max){//打印擺放信息print();//回溯到上一行重新尋找可行的擺放位置return;}//通過循環從第一行開始逐列擺放皇后//通過遞歸來遍歷行數for (int i = 0; i < max; i++){array[n] = i;//判斷當前放置的皇后與其他位置上的皇后是否產生沖突if (judge(n)){check(n+1);}//如果沖突繼續執行array[n]=i 重新尋找該行上可行的擺放位置}}/*** 檢測判斷該皇后擺放位置是否與前面的皇后產生沖突* @param n 表示第n個皇后* @return*/public boolean judge(int n){for (int i = 0; i < n; i++) {//1.array[i] == array[n] ---> 第n個皇后和前面的皇后是否在同一列//2.Math.abs(i-n) == Math.abs(array[i] - array[n]) ---> 第n個皇后和前面的皇后是否在同一斜線if (array[i] == array[n] || Math.abs(i-n) == Math.abs(array[i] - array[n])){return false;}}return true;}/*** 輸出八皇后的位置*/public void print(){count++;for (int i = 0; i < array.length; i++) {System.out.print(array[i]+"\t");}System.out.println();} }測試結果
Result:92---->共有92種擺放方案 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
以上。
如有不足或者錯誤歡迎評論指正。
總結
以上是生活随笔為你收集整理的递归回溯解决八皇后问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 回溯算法解决迷宫问题
- 下一篇: Java语言实现二分查找(可查询重复数据