演算法分析與設計 八皇后問題的詳解

2021-05-27 17:59:12 字數 1287 閱讀 8281

八皇后問題是乙個以西洋棋

為背景的問題:如何能夠在 8×8 的西洋棋棋盤上放置八個皇后

,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題:這時棋盤的大小變為n×n,而皇后個數也變成n。

這個問題簡化描述就是:在8x8的棋盤上放8顆子,要求它們【不在同一行】【不在同一列】【不在同一斜線】上。面對問題,我們的思維要清晰:

第一,我們怎麼用資料表示棋盤【資料表示】;

第二,我們用什麼思路解決問題【解題策略】;

第三,我們怎麼實現最後的**【**實現】。

【資料表示】:

這個問題的最簡單資料表示方式,是用長度為8的一維陣列,比如arr[8]=表示的就是上圖的棋盤,arr[0]==3表示第0行(計算機中習慣從0開始)的皇后放在第3列(d列),arr[1]==6表示第1行的皇后放在第6列(g列)

【解題策略】

1.【窮舉法】是不現實的,因為哪怕只是8x8的棋盤,所有解就包括 [00000000] 到 [77777777] ,共有16777216個解。

2.【分治法】是低效的,因為分治法一般相當於遍歷樹型解空間的所有枝葉,在此題中其實相當於窮舉法。

3.【回溯發】是最佳策略,回溯和分治十分相似,但回溯不會遍歷整個解空間,在遍歷過程中有剪枝步驟。

【**實現】

const int num  = 8;/*可以隨意修改,num是多少解的就是幾皇后問題*/

int arr[num];

int count =0;

void display()/*乙個簡單的陣列輸出函式,順便統計解的個數*/

**由三部分組成

function

begin

檢查上一步是否正確【剪枝】

如果滿足條件就輸出【輸出】

遞迴下一步的可能值【遞迴】

end

這就像你自己下棋:

1.每次都檢查上一步的局勢,如果已經輸了就結束這一盤的【剪枝】,後面我再怎麼落子都是白搭(窮舉法則會繼續走),這盤咱們不玩兒了,。

2.如果還沒有輸,那麼是不是應經贏了,如果應經贏了,這盤咱們結束了【輸出】,再來新的一盤。

3.如果還在焦灼狀態,殺得難分難解,那麼我繼續落子【遞迴】,直到「我輸」或者「我贏」。

回溯法是不是有種「弈棋之道」的感覺?

演算法分析與設計 八皇后問題(回溯法)

在西洋棋中,皇后是最厲害的棋子,可以橫走 直走,還可以斜走。棋手馬克斯 貝瑟爾 1848 年提出著名的八皇后問題 即在 8 8 的棋盤上擺放八個皇后,使其不能互相攻擊 即任意兩個皇后都不能處於同一行 同一列或同一條斜線上。例如 現在我們把棋盤擴充套件到 n n 的棋盤上擺放 n 個皇后,請問該怎麼擺...

演算法設計與分析 n皇后問題

在 n n 的棋盤上擺放n個皇后,使其不能互相攻擊,即任意兩個皇后不能處於同一行 同一列或者同一斜線上。遇到的問題 雙重迴圈內外層弄反了,如果先判斷擺過的棋子,那麼第一遍連迴圈都進不去。同樣,dfs語句也要放在內層迴圈外部。應該先大致判斷這一行能放在第幾列,再來判斷是否衝突。如下 include i...

八皇后演算法詳解

1.引子 中國有一句古話,叫做 不撞南牆不回頭 生動的說明了乙個人的固執,有點貶義,但是在軟體程式設計中,這種思路確是一種解決問題最簡單的演算法,它通過一種類似於蠻幹的思路,一步一步地往前走,每走一步都更靠近目標結果一些,直到遇到障礙物,我們才考慮往回走。然後再繼續嘗試向前。通過這樣的波浪式前進方法...