1. 程式人生 > >N皇后問題----回溯法

N皇后問題----回溯法

問題描述:

將n個皇后放置在n * n的棋盤上,使得任意兩個皇后不能相互攻擊。即任意兩個皇后都不在同一行,同一列,和同一條斜角線上。

問題分析:

1. 回溯法

回溯法的思想和基本概念在這裡就不再詳細闡述,想要深入瞭解的朋友可以自行查詢相關資料,在這裡我只簡單說明一下:
在求解滿足某些約束條件最優解的問題中,通過一個規範函式來測試正在構造的一個可能的解序列,若確定該解不可能構成一個可行解則跳過接下來的構造過程,捨棄該解,回溯到上一步,進行下一個構造過程。
拿n皇后問題舉例來說,例如一個4*4的棋盤,在構造解的過程中,若第一個皇后放在一行一列,第二個放在二行二列,此時檢測到兩個皇后已經在同一條斜角線上,則可停止該構造,因為已經能夠確定該序列不可能構成有效解。則回溯到上一步,即決定第二個皇后該放置在哪個位置。這樣就免去了做構造第三、第四個皇后的無用功。
這個過程說的通俗一點就是你可以無限悔棋。例如在走迷宮時,在每個路口你都從中選擇一條路,當你走到一半時發現這是一條錯誤的道路,便退回到上一個路口重新選擇另一條路,直到找出最後的出口。

2. 規範函式

n皇后問題的規範函式在於使得任意兩個皇后不能相互攻擊,同行同列的驗證比較簡單。對於不在同一條斜角線上的約束,可以發現,對於在棋盤同一條左上到右下的斜角線上所有元素都有相同的行減列值,而左下到右上斜角線上的元素都有相同的行加列值。
假設有兩個皇后被放置在(i,j)和(k,l)上,則當
i - j = k - l 或 i+j = k+l
時嗎他們在同一條斜角線上。將兩個等式分別變換為
j - l = i - k 和 j - l = k - i
則有 | j - l | = | i - k | 時兩個皇后在同一條斜角線上
故可以寫規範函式place(K,col)用來測定將皇后放置在某一行是否合法,及滿足不能相互攻擊的條件,相應的程式碼示例和相應的註解如下方所示

參考程式碼:

規範函式place(k, col)
其中列表 col(k) 儲存第k個皇后放置在第 col(k) 列。
該函式測試第k個皇后 放在第col(k)列是夠滿足條件,若滿足則返回真,否則返回假。

	def place(self, k, col) :
		i = 0
		while i < k :
			if (col[i] == col[k]) or(abs(col[i]-col[k]) == abs(i - k)) :
				return False
			i = i+1
		return True

回溯法解決N皇后問題

	def solveNQueens(self, n)
: #最終結果用字串表示,其中 # ‘.’表示空,‘Q’表示放置皇后 answer = [] #儲存最終的所有解 ori = '.' * n #初始化每行都為空 result = [] #存放每次構造的可行解 col = [0]*n #所有列初始化為0 col[0] = -1 k = 0 while k >= 0 : col[k] = col[k] +1 while col[k] < n and not self.place(k, col) : #尋找一個可行的列 col[k] = col[k] +1 if col[k] < n: #找到一個合法的列 if k == n-1: #如果此時已經處理到最後一行,表示已經產生一組可行解,加入到最終的解列表中 #該程式碼塊 (接下來的5行) 可理解為列印輸出結果 for i in range(n): index = col[i] result.append(ori[:index]+'Q'+ori[index+1:]) answer.append(result) result = [] #清空result,以便下一次使用 else: #該行不是最後一行,則行數加一,接著處理 k = k + 1 col[k] = -1 else: #沒有找到合法的列,則回溯到上一步 k = k-1 return answer

結果示例:
以下是n=5時的結果
![n=5](https://img-blog.csdnimg.cn/20181125195212144.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MTQ4NzU0,size_16,color_FFFFFF,t_

相關推薦

USACO1.5.4 Checker Challenge跳棋的挑戰 解題報告(N皇后 回溯)

Description 檢查一個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行,每列,每條對角線(包括兩條主對角線的所有對角線)上都至多有一個棋子。 列號 0 1 2 3 4 5 6 ----------------------

8皇后-----回溯C++程式設計練習

/* * 八皇后問題回溯法程式設計練習 * 在8×8的棋盤上,放置8個皇后,兩個皇后之間不能兩兩攻擊 * 也即,直線,垂直45度、135度方向不能出現兩個皇后 * * copyright Michael 2014-12-19 * QQ 1192065414 *

回溯解決N皇后問題

八皇后問題 在棋盤上放置8個皇后,使得它們互不攻擊,此時每個皇后的攻擊範圍為同行同列和同對角線,要求找出所有解。 遞迴函式將不再遞迴呼叫它自身,而是返回上一層呼叫,這種現象稱為回溯(backtracking)。 當把問題分成若干步驟並遞迴求解時,如果當前步驟沒有合法選擇,則函式將返回

回溯解決N皇后問題(以四皇后為例)

回溯法解決N皇后問題(以四皇后為例) 其他的N皇后問題以此類推。所謂4皇后問題就是求解如何在4×4的棋盤上無衝突的擺放4個皇后棋子。在國際象棋中,皇后的移動方式為橫豎交叉的,因此在任意一個皇后所在位置的水平、豎直、以及45度斜線上都不能出現皇后的棋子,例子 要求程式設計求出符合要求的情

【資料結構與演算法】回溯解決N皇后問題,java程式碼實現

N皇后問題 問題描述 在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法,這稱為八皇后問題。 延伸一下,便為N皇后問題。 核心思想 解決N皇后問題有兩個關鍵點。一是如何進行放置棋子,二是如何驗證棋子是否符合

一、試探回溯(N皇后問題)

 一、試探回溯法概念 在介紹試探回溯法的概念之前,先簡要介紹一個簡短的古希臘神話故事,邪惡的半人半牛藏身於一個複雜的迷宮,很難找到它並殺死它,就是能成功殺死它怎麼回來也是個難事。不過,在公主阿里阿德涅的幫助下,英雄忒修斯還是想到辦法並消滅了怪物,並輕輕鬆鬆地走出了迷宮,他是怎麼做到

n皇后問題_回溯

 具體問題如下圖 先看一下4*4的回溯過程   程式結束條件: 一組解:設標誌,找到一解後更改標誌,以標誌做為結束迴圈的條件。 所有解:k=0 判斷約束函式判斷第k個後能不能放在x[k]處 兩個皇后不能放在統一斜線上: 若2個皇后放置的位置分別是(i,j)和(k,l), 且

n皇后問題(回溯-遞迴和迴圈

n皇后問題簡單解釋 對於一個n*n的棋盤來說,皇后如果是同行同列或者是在同一斜對角上,就是會相互擊殺。 所以,我們需要找到一個安全的(使得所有皇后之間不相互擊殺)安排方式。 遞迴版本 #include

POJ 1321 簡單搜尋 回溯n皇后問題

要求:在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。 方法:回溯法 1.深搜函式的引數為行數。 2.used[i]=1表示第i列已

使用回溯解決八皇后問題(同樣適用於N皇后)。

在學習資料結構的時候,看到了一道八皇后的問題。寫完後,再去網上檢視發現原來這個問題有這麼多的優化解法,相比之下相形見絀。但我還是記錄下來,有興趣的小夥伴可以看看。 先大致說下我的思路 建立一個初始化值為0的8x8的陣列,0代表無皇后且不在其他

N皇后問題----回溯

問題描述: 將n個皇后放置在n * n的棋盤上,使得任意兩個皇后不能相互攻擊。即任意兩個皇后都不在同一行,同一列,和同一條斜角線上。 問題分析: 1. 回溯法 回溯法的思想和基本概念在這裡就不再詳細闡述,想要深入瞭解的朋友可以自行查詢相關資料,在這裡我只簡單說

回溯N皇后問題

N皇后問題要求求解在N*N的棋盤上放置N個皇后,並使各皇后彼此不受攻擊的可能的棋盤佈局,皇后彼此不受攻擊的所有可能的佈局,皇后彼此不受攻擊的約束條件是:任何兩個皇后均不能在棋盤同一行、同一列或者在對角線上出現。 由於N皇后問題不允許兩個皇后在同一行,所以,可用

n皇后問題回溯---java圖形介面實現回溯過程

/*<span style="white-space:pre"> </span>by wbin 2015/12/18實現n皇后問題的回溯法過程,以java圖形介面展示,程式碼寫得略醜,見諒.*/import java.awt.Color; impo

HDU2553 N皇后問題【回溯

N皇后問題 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S

N皇后問題 回溯

回溯法過程 在試探過程中,皇后的放置需要檢查她的位置是否和已經放置好的皇后發生衝突,因此需要一個檢查函式 假如兩個皇后被放置在(i,j)和(k,l)上 ,當且僅當 |i-k|==|j-l| 時

華為機試—N皇后問題(高階題160分:兩種回溯解決 吐血整理)

一、問題描述:     在n×n格的棋盤上放置彼此不受攻擊的n個皇后。按照國際象棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。n後問題等價於再n×n的棋盤上放置n個皇后,任何2個皇后不妨在同一行或同一列或同一斜線上。 輸入:     給定棋盤的大小

【演算法筆記】回溯——n皇后問題

回溯法——n皇后問題 問題描述 按照國際象棋的規則,皇后可以攻擊同一行、同一列、同一斜線上的棋子。求n×n格的棋盤上彼此不受攻擊的n個皇后的擺法。 下圖為4皇后問題的一個解: Q Q

【演算法分析】回溯解八皇后問題(n皇后問題)

回溯法解題思路: (1)針對所給問題,定義問題的解空間;    (2)確定易於搜尋的解空間結構;    (3)以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋。 八皇后問題:

HDU2553 N皇后問題(回溯

此題是經典的N皇后問題,描述:在一個N*N的棋盤上要擺放N個皇后,要求任意兩個皇后不能在同一行,同一列或者同一條與棋盤的邊成45度角的斜線上,即與對角線平行的斜線上,求對於不同的N,各有多少種擺法使任意兩個皇后不能相互攻擊。 用回溯法就可以解決,設皇后的編號依次為1,2,

回溯解決N皇后問題(java實現)

1.簡單介紹回溯法思路,就是將所有的結果變成一棵樹,從樹的結點開始訪問,採用深度優先策略,從樹的根結點開始訪問,如果滿足條件,繼續訪問下一層,如果不滿足條件,返回上一個結點,繼續訪問其它結點。重複操作。 2. 對於N皇后問題,我特意做了一張圖片。首先放置第一