回溯法解決N皇后問題

2021-08-30 15:15:18 字數 1771 閱讀 6616

在棋盤上放置8個皇后,使得它們互不攻擊,此時每個皇后的攻擊範圍為同行同列和同對角線,要求找出所有解。

遞迴函式將不再遞迴呼叫它自身,而是返回上一層呼叫,這種現象稱為回溯(backtracking)。

當把問題分成若干步驟並遞迴求解時,如果當前步驟沒有合法選擇,則函式將返回上一級遞迴呼叫,這種現象稱為回溯。 正是因為這個原因,遞迴列舉演算法常被稱為回溯法,應用十分普遍。

// n皇后問題:生成-測試法

// rujia liu

#include

using namespace std;

// c索引表示行,值表示列

// tot表示解的個數

// nc表示執行遞迴函式次數

int c[50]

, tot =

0, n =

8, nc =0;

void

search

(int cur)

printf

("\n");

}else

for(i =

0; i < n; i++)}

intmain()

c[i] == c[j] || i-c[i] == j-c[j] || i+c[i] == j+c[j]只比較列、主對角線、副對角線,原理見下圖:

輸入輸出:

// n皇后問題:普通回溯法

// rujia liu

#include

using namespace std;

int c[50]

, tot =

0, n =

8, nc =0;

void

search

(int cur)

else

for(i =

0; i < n; i++

)//如果合法,則繼續遞迴

if(ok)

search

(cur+1)

;}}int

main()

輸入輸出

4皇后執行了17次,比生成-測試法的341次,少了不少。

// n皇后問題:優化的回溯法

// rujia liu

#include

#include

using namespace std;

// vis表示列、主對角線、副對角線

int c[50]

, vis[3]

[50], tot =

0, n =

8, nc =0;

void

search

(int cur)

else

for(i =

0; i < n; i++)}

}int

main()

如果在回溯法中使用了輔助的全域性變數,一定要及時把他們恢復原狀。特別的,如果函式有多個出口,則需要在每個出口初恢復被修改的值。

回溯法解決n皇后問題

回溯法的基本行為是搜尋,搜尋過程使用剪枝函式來為了避免無效的搜尋。剪枝函式包括兩類 1.使用約束函式,剪去不滿足約束條件的路徑 2.使用限界函式,剪去不能得到最優解的路徑。1 針對所給問題,確定問題的解空間 首先應明確定義問題的解空間,問題的解空間應至少包含問題的乙個 最優 解。2 確定結點的擴充套...

回溯法解決N皇后的問題

使用回溯法解決n皇后的問題 def mk lst size 生成棋盤 return 0 for i in range size for j in range size def is legal posi loca,size 判斷是否合法座標 x,y loca 0 loca 1 size 1 if 0...

N 皇后問題 回溯法

n 皇后問題 在 n n 的棋盤上放置彼此不受攻擊的 n 個皇后,任意兩個皇后不同行 不同列 不同斜線。思路 1.因為皇后不能同行,所以,在每一行放置乙個皇后就行 2.當在一行放置皇后的時候 1 順序檢查這一行每乙個位置是否和上面所有的皇后,只要有乙個同列或者在斜線上就不能放置 若找到乙個滿足的,放...