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

2021-10-07 15:56:42 字數 1731 閱讀 3218

回溯演算法相當於窮舉搜尋的巧妙實現,窮舉演算法是每一種可能都去嘗試, 回溯法會在嘗試的過程中做出判斷,當發現一些不符合標準的組合方案,直接跳過不去嘗試。因此, 回溯演算法能節省時間代價;

回溯演算法實質上還是暴力演算法,但是回溯演算法並不直接嘗試所有的可能,會刪除不可能的方案;

在一步內刪除一大組可能性的做法叫做裁剪

在嘗試解決問題時候, 每進行一步, 都是抱著試試看的態度;如果發現當前選擇並不是最好的,或者這樣繼續下去可定達不到目標時候, 就放棄本次操作,返回上一層操作,重新做選擇;

(走不通就回退);

回溯法與遞迴的區別:

1) 回溯法:

從問題本身出發,尋找可能實現的所有情況。和窮舉法的思想相近,不同在於窮舉法是將所有的情況都列舉出來以後再一一篩選,而回溯法在列舉過程如果發現當前情況根本不可能存在,就停止後續的所有工作,返回上一步進行新的嘗試。

2) 遞迴:

遞迴是從問題的結果出發,例如求 n!,要想知道 n!的結果,就需要知道 n*(n-1)! 的結果,而要想知道 (n-1)! 結果,就需要提前知道 (n-1)*(n-2)!。這樣不斷地向自己提問,不斷地呼叫自己的思想就是遞迴。

回溯和遞迴唯一的聯絡就是,回溯法可以用遞迴思想實現。

問題描述:

八皇后問題是以西洋棋為背景的問題:有八個皇后(可以當成八個棋子),如何在 8*8 的棋盤中放置八個皇后,使得任意兩個皇后都不在同一條橫線、縱線或者斜線上。

八皇后問題解決思路:

1) 從棋盤的第一行開始, 從第乙個位置開始, 依次判斷當前位置是否能夠放置皇后;判斷依據是:與之前行的資料比較, 不能與之前的同列, 或是處在對角線上;

2) 如果在當前行的所有列位置上都通過檢驗, 就返回到上一行重新選擇, 然後繼續試探;

3) 如果試探到最後一行,並且通過試探並擺放成功, 直接列印出棋盤。然後將棋盤恢復,以放置下一次嘗試;

具體**實現如下:

#include

#include

#define n 8

int queen[n]=;

int count =0;

intcheck

(int row,

int col)

return1;

}//根據一組queen陣列列印出乙個棋盤

void

printchess()

printf

("***************=\n");

}//對於第row行, 確定在該行的哪乙個位置擺放棋子

void

eightqueen

(int row)

//當前行row完成棋子放置之後, 對下一行嘗試放置棋子

eightqueen

(row +1)

;//當row行成功放置棋子後, 對row+1行進行遞迴呼叫;

//但這個遞迴呼叫返回之後, 已經完成了對row+1行的所有列的所有測試

//此時需要對row行的下乙個列col+1進行測試

//此時queen[row] 儲存的是col,因此需要將queen[row] 清零

queen[row]=0

;}}}

intmain()

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

八皇后問題是古老的問題,十八世紀由乙個西洋棋手提出的,即在乙個8 8 的西洋棋盤上,放置八個皇后,使它們不能相互攻擊到。即不能處於同一行,同一列,也不能處於同一條斜線上,問有多少種擺法。八皇后問題是經典的回溯演算法問題,後人利用計算機,算出了8 8 的棋盤上能擺出92種,而後又提出了n皇后問題。本人...

八皇后問題 回溯演算法

最近學習了一下列舉演算法,有兩種思路,遞迴構造和直接列舉。直接列舉的優點就是思路和程式很簡潔,缺點就在於無法簡便的減少列舉量,必須生成所有的解並進行判斷。遞迴構造就很簡單了,在生成列舉量的同時並且可以通過判斷減少列舉量從而達到了數量上的減少。簡單的說,直接列舉就是先找尋解再判斷,遞迴構造則是先判斷再...

回溯演算法 八皇后問題

問題描述 八皇后不能相互攻擊,即,八個皇后不能同行,同列,不同在同一條對角線上,對角線又可以分為左對角線和右對角線 左對角線上滿足 i j 7都相等 i,j分別是一維和二維的座標 右對角線滿足 i j 都相等 如下 include using namespace std int e q 8 8 in...