演算法 遞迴與回溯演算法解決八皇后問題

2021-10-05 21:55:46 字數 2690 閱讀 8464

小結完整**

在沒有其他演算法的加持下時,回溯演算法簡單來說,就是不斷試錯的過程。通過不斷向下乙個節點列舉尋找滿足條件的答案,當無法尋找到時,則返回至上乙個節點,然後繼續向下列舉。

這句話可能看起來有點抽象,我們用乙個圖來演示一下。

這是一張a村到e村的地圖。假設你從起點a出發到終點e(不是e1),在不知道路怎麼走且時間、精力充足的情況下,你會選擇一條條路走過去,直到找到終點e為止。

當你從起點a出發時,在你面前的就是b1、b2兩條路。由於你你不知道哪條路是正確的,你只能通過試錯來排除錯誤路徑。當你選擇b2並走到b2時,你發現接下來擺在你面前的只有c4一條路,於是你毫不猶豫的走進了c4。但很可惜,c4之後已經沒有路可以走了。於是你便返回到b2,並在通往c4的路上插了面小紅旗,告訴自己這條路已經走過了,無法通往e村。接著你發現,b2之後除了c4沒有其他路可以走,於是你就只能繼續返回到起點a,並在通往b2的路上也插了面小紅旗,告訴自己只要走b2就無法通往e村。於是你就開始走b1路,如此往復:當發現路無法繼續向下走時,便返回上乙個路口,並把該路標記為走不通,然後走下一條路(如果沒有下一條路的話,則繼續返回上乙個路口)。

總的流程圖將會是這樣的:

如果走到n=1且觀察到接下來沒有未標記的路(n=n-1==0),就說明沒有一條路能夠達到目標地點。

在 8×8 格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上。

實現八皇后的目的:求出有多少種擺法。

通過上面的找路的例子可以發現,回溯演算法的核心類似於窮舉法,嘗試每一條不同的路徑,然後記錄下滿足需求的,拋棄不滿足的。

因此八皇后問題就可以用下面這種方式解決:

建立乙個8*8的二維陣列來表示乙個棋盤。

先在array[0][0]處放置第乙個皇后,然後檢視array[1][0]是否滿足,若不滿足則繼續嘗試array[1][1],array[1][2]…直至滿足條件後放第二個皇后,然後檢索第三個皇后的位置,檢索方法同第二個皇后,直到第八個皇后放完。

當第八個皇后放好後(假設位於array[7][3]),則返回到第七個皇后,繼續檢索array[7][4]滿不滿足條件。直到檢索出全部情況為止。

實現八皇后問題的關鍵有兩點:

判斷皇后放置的位置是否滿足遊戲條件

利用遞迴和回溯放置皇后到棋盤上

因此,我們在解決八皇后問題時,最主要的就是先把判斷皇后位置是否正確的方法寫出來。

tips:這裡用了個小小的演算法,用一維陣列來實現棋盤。具體實現如下:

3. 定義int array[8]陣列

4. array[n] = value 代表第n + 1個皇后(陣列下標從0開始)位於棋盤的第n+1行的第value + 1 列上。

/**

* 先定義乙個類,確定棋盤大小並定義完棋盤陣列array。

* count 用於記錄總共有多少種解法

*/class

eightqueens

public

boolean

judge

(int n)

}return

true

;}

擁有這個判斷方法之後,就可以通過遞迴和回溯,找到正確的八皇后解法了。

接下來構寫乙個方法開始放第乙個皇后

/**

* 該check方法在主方法被呼叫時,引數n只能傳入0,因為皇后只能從第0個開始放

*/public

void

check

(int n)

for(

int i =

0; i < max; i++

)//當皇后n judge判斷未通過而返回到皇后n-1級時,將會位於這個位置。

//接下來將執行的操作時for迴圈中的i++

}//當執行完for迴圈後,說明該行所有列都已經被judge過了,就return到上一級

}

構寫乙個主類和主函式檢查上述方法是否正確

public

class

test

}

其實單純的回溯演算法並不高效,簡單來說就是將所有能產生的情況全部列舉出來,然後找到正確答案。如果你願意的話,在judge函式中加入乙個計數器,就可以發現整個過程下來,judge函式執行了1.5w+次,所以需要加入其他演算法來優化。不過這也反映出遞迴與回溯的本質就是試錯法,或者說是窮舉法。

public

class

eightqueens

}return

true;}

public

void

check

(int n)

for(

int i =

0; i < max; i++)}

}public

void

print()

system.out.

println();}}

public

class

test

}

打靶 遞迴演算法 八皇后 回溯演算法

面試例題1 乙個射擊運動員打靶,靶一共有10環,連開10槍打中90環的可能性有多少種?請用遞迴演算法程式設計實現。中國某著名通訊企業h面試題 解析 靶上一共有10種可能 1環到10環,還有可能脫靶,那就是0環,加在一起共11種可能。這是一道考迴圈和遞迴的面試題。我們在這個程式中將利用遞迴的辦法實現打...

回溯遞迴演算法 八皇后問題

前,有皇帝。就拿八皇后。由此產生的一系列問題,凌亂。由此產生的八皇后問題。哈哈 開玩笑 八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即隨意兩個皇后都不能處於同一行 同一列或同一斜...

遞迴 八皇后問題(回溯演算法)

問題 在8x8的西洋棋的棋盤上擺八個皇后,使其不能夠互相攻擊。即任意兩個皇后不能夠處在同一行,同一列,或者是同一斜線,問有多少種擺法?92 思路分析 第乙個皇后放在第一行的第一列 第二個皇后從第二行第一列開始放,然後判斷可不可以,可以,就放第三個皇后,也從第三行第一列開始放 不可以在換下乙個位置,在...