1 回答

TA貢獻(xiàn)1869條經(jīng)驗 獲得超4個贊
當(dāng)在第一列之一發(fā)生回溯并且必須嘗試下一行時,該算法需要相當(dāng)多的時間。將奇數(shù) N 板與 N-1 板進(jìn)行比較確實(shí)表明,偶數(shù)板的解決方案通常需要進(jìn)行更多此類回溯/嘗試下一個處理。例如,N=19 的解的左上角如下所示:
1 0 0 0 0
0 0 0 1 0
0 1 0 0 0
0 0 0 0 1*
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
前五列中的這 5 個皇后很快找到,因為它們是第一個不與之前的皇后發(fā)生碰撞的皇后。顯然可以放置其他皇后而不必重新考慮前五個皇后。
對于 N=18,解決方案的同一角落如下所示:
1 0 0 0 0
0 0 0 1 0
0 1 0 0 0
0 0 0 0 0-
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1*
注意標(biāo)有減號的位置。這個看起來很有希望(就像 19 板一樣):它的調(diào)查需要相當(dāng)長的時間才能得出無法正確放置其他皇后的結(jié)論。這種早期失敗的代價。
因此,19 板的解決方案比 18 板更快地找到。
請注意,27 的解決方案比 26 的解決方案花費(fèi)的時間略多,盡管這并不重要:看起來時間復(fù)雜度是O(2 n ),因此要比較不同板尺寸的時間,最好在對數(shù) Y 軸:
“work”表示函數(shù)safe執(zhí)行的次數(shù)。
這種算法是否總是對偶數(shù)板花費(fèi)相對更多的時間(與 N+1 板所需的時間相比)尚不清楚,但對于這幾個板尺寸,它似乎與該算法自然形成的騎士跳躍有關(guān),開始從左上角。請注意,這種模式如何完美地適用于 5 號和 7 號棋盤:下一個皇后可以坐在而不干擾先前定位的皇后的第一個位置始終是解決方案的一部分。而對于 4 號和 6 號棋盤,甚至沒有任何解決方案在角落里有一個皇后,這是該算法的起點(diǎn)。
備擇方案
從程序員的角度來看這個問題,有一種補(bǔ)救方法可以(平均而言)消除差異:以不同(甚至隨機(jī))的順序選擇列。事實(shí)證明,采用正常順序是獲得解決方案的效率較低的方法之一。
換檔選擇
該算法的一個簡單轉(zhuǎn)變,除非所有其他行都失敗,否則您不考慮前兩行,已經(jīng)大大改變了統(tǒng)計數(shù)據(jù):
在solve_help改變這個:
for i in range(N):
到:
for i in range(N):
i = (i + 2) % N
看看現(xiàn)在平均性能是如何提高的:log(work)/n的所有測量值都低于 1,除了 n=6。而且:現(xiàn)在更頻繁地查看 N 的奇數(shù)值。
隨機(jī)挑選
for i in random.sample(range(N), N):
以下是這樣一次隨機(jī)運(yùn)行的結(jié)果:
比原始訂單更好的統(tǒng)計數(shù)據(jù)!當(dāng)然,你會時不時地得到一個糟糕的統(tǒng)計數(shù)據(jù),......因為它是隨機(jī)的。但平均而言,它的表現(xiàn)(好得多)。
其他非隨機(jī)順序的方式可能包括col
, 和N//2
不同的系數(shù), 如i = (i + col*2 + N//2) % N
, ...等。但請參閱下面的最后評論。
其他備注
我將應(yīng)用以下優(yōu)化:跟蹤哪些行、前向“對角線”和后向“對角線”已被采用。您可以為此使用列表或集合。請注意,如果兩個單元格的坐標(biāo)之和相等,則兩個單元格位于同一對角線上。后對角線上的單元格的共同點(diǎn)是它們的坐標(biāo)差相等。這樣您就不必每次都在這些行中掃描“1”。
此外,board
可能只是列號列表。無需存儲所有這些零。僅保留用于顯示。
最后,有一些簡單的方法可以在線性時間內(nèi)獲得解決方案。參見維基百科。
添加回答
舉報