在棋盤上放置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 順序檢查這一行每乙個位置是否和上面所有的皇后,只要有乙個同列或者在斜線上就不能放置 若找到乙個滿足的,放...