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

2021-08-21 09:29:26 字數 984 閱讀 4616

今天偶爾看到了乙個演算法問題(八皇后問題),回想一下還是在演算法課上學習過的,於是,自己總結了一下,寫了這篇日誌

演算法提出:

在西洋棋棋盤上(8*8)放置八個皇后,使得任意兩個皇后之間不能在同一行,同一列,也不能位於同於對角線上。問共有多少種不同的方法,並且指出各種不同的放法。

演算法思路:

首先我們分析一下問題的解,我們每取出乙個皇后,放入一行,共有八種不同的放法,然後再放第二個皇后,同樣如果不考慮規則,還是有八種放法。於是我們可以用乙個八叉樹來描述這個過程。從根節點開始,樹每增加一層,便是多放乙個皇后,直到第8層(根節點為0層),最後得到乙個完全八叉樹。  

緊接著我們開始用深度優先遍歷這個八叉樹,在遍歷的過程中,進行相應的條件的判斷。以便去掉不合規則的子樹。

那麼具體用什麼條件來進行子樹的裁剪呢?

我們先對問題解的結構做乙個約定。

用x[i]來表示,在第i行,皇后放在了x[i]這個位置。

於是我們考慮第乙個條件,不能再同一行,同一列於是我們得到x[i]不能相同。剩下乙個條件是不能位於對角線上,這個條件不是很明顯,我們經過分析得到,設兩個不同的皇后分別在j,k行上,x[j],x[k]分別表示在j,k行的那一列上。那麼不在同一對角線的條件可以寫為abs((j-k))!=abs(x[j]-x[k]),其中abs為求絕對值的函式。

於是下面我們便可以利用乙個遞迴的呼叫來遍歷八叉樹。

我們首先定義乙個訪問某節點所有子節點的函式

void backtrack(int t)

cout<}

else

for(int i = 1;i<=num;i++)

}

bool place(int k)

static int num;

static int *x;

static int sum;

void main()

經典回溯演算法 八皇后問題

八皇后問題是由19世紀數學家 搞死先生 高斯先生 提出的,具體的問題是這樣的 在西洋棋的棋盤中 有8 8格 擺放 8個皇后,這八個皇后不能相互攻擊到 皇后的攻擊方向很廣 橫著,豎著,斜著都能攻擊 即 8個皇后不能處於同行 同列 同一正反對角線上,這樣就不能相互攻擊到了。那麼,這樣的皇后佔位的方法,一...

八皇后問題 經典回溯演算法

八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。高斯認為有76種方案。1854年在柏林的象棋雜誌上不同的作者發表了...

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

問題描述 八皇后問題 eight queens problem 是十九世紀著名的數學家高斯於1850年提出的。問題是 在8 8的棋盤上擺放八個皇后,使其不能互相攻擊。即任意兩個皇后都不能處於同一行 同一列或同一斜線上。可以把八皇后問題擴充套件到n皇后問題,即在n n的棋盤上擺放n個皇后,使任意兩個皇...