亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么偶數 N 比奇數 N 花費更長的時間?

為什么偶數 N 比奇數 N 花費更長的時間?

森林海 2022-01-18 17:02:16
我這里有一些代碼可以在 python 中使用回溯來解決 n 個皇后問題。當我運行它時,賠率總是比偶數花費的時間少得多。當 n 達到 20+ 左右時,這一點尤其明顯。有人知道為什么是這樣嗎?import timeglobal NN = int(input("Enter N: "))def display_solution(board):    print('\n'.join(['\t'.join([str(cell) for cell in row]) for row in     board]))def safe(board, row, col):    for i in range(col):        if board[row][i] == 1:            return False    for i, j in zip(range(row, -1, -1), range(col, -1, -1)):        if board[i][j] == 1:            return False    for i, j in zip(range(row, N, 1), range(col, -1, -1)):        if board[i][j] == 1:            return False    return Truedef solve_help(board, col):    if col >= N:        return True    for i in range(N):        if safe(board, i, col):            board[i][col] = 1            if solve_help(board, col + 1) is True:                return True            board[i][col] = 0    return Falsedef solve():    board = [[0 for x in range(N)] for y in range(N)]    if solve_help(board, 0) is False:        print("Solution does not exist")        return False    display_solution(board)    return Truestart = time.clock()solve()end = time.clock()print(N, "\t", end-start)我假設它必須與對角線的賠率與偶數不同有關。我也不確定這是否是所有回溯算法的問題,或者只是這個特定的代碼。不管怎樣,謝謝你的幫助。
查看完整描述

1 回答

?
MMTTMM

TA貢獻1869條經驗 獲得超4個贊

當在第一列之一發生回溯并且必須嘗試下一行時,該算法需要相當多的時間。將奇數 N 板與 N-1 板進行比較確實表明,偶數板的解決方案通常需要進行更多此類回溯/嘗試下一個處理。例如,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 個皇后很快找到,因為它們是第一個不與之前的皇后發生碰撞的皇后。顯然可以放置其他皇后而不必重新考慮前五個皇后。


對于 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*

注意標有減號的位置。這個看起來很有希望(就像 19 板一樣):它的調查需要相當長的時間才能得出無法正確放置其他皇后的結論。這種早期失敗的代價。


因此,19 板的解決方案比 18 板更快地找到。


請注意,27 的解決方案比 26 的解決方案花費的時間略多,盡管這并不重要:看起來時間復雜度是O(2 n ),因此要比較不同板尺寸的時間,最好在對數 Y 軸:

http://img1.sycdn.imooc.com//61e682350001ac7812530484.jpg

“work”表示函數safe執行的次數。


這種算法是否總是對偶數板花費相對更多的時間(與 N+1 板所需的時間相比)尚不清楚,但對于這幾個板尺寸,它似乎與該算法自然形成的騎士跳躍有關,開始從左上角。請注意,這種模式如何完美地適用于 5 號和 7 號棋盤:下一個皇后可以坐在而不干擾先前定位的皇后的第一個位置始終是解決方案的一部分。而對于 4 號和 6 號棋盤,甚至沒有任何解決方案在角落里有一個皇后,這是該算法的起點。


備擇方案

從程序員的角度來看這個問題,有一種補救方法可以(平均而言)消除差異:以不同(甚至隨機)的順序選擇列。事實證明,采用正常順序是獲得解決方案的效率較低的方法之一。


換檔選擇

該算法的一個簡單轉變,除非所有其他行都失敗,否則您不考慮前兩行,已經大大改變了統計數據:


在solve_help改變這個:


for i in range(N):

到:


for i in range(N):

   i = (i + 2) % N

http://img1.sycdn.imooc.com//61e68246000117fe12540484.jpg

看看現在平均性能是如何提高的:log(work)/n的所有測量值都低于 1,除了 n=6。而且:現在更頻繁地查看 N 的奇數值。

隨機挑選

for i in random.sample(range(N), N):

以下是這樣一次隨機運行的結果:

http://img1.sycdn.imooc.com//61e68255000176c612490486.jpg

比原始訂單更好的統計數據!當然,你會時不時地得到一個糟糕的統計數據,......因為它是隨機的。但平均而言,它的表現(好得多)。

其他非隨機順序的方式可能包括col, 和N//2不同的系數, 如i = (i + col*2 + N//2) % N, ...等。但請參閱下面的最后評論。

其他備注

我將應用以下優化:跟蹤哪些行、前向“對角線”和后向“對角線”已被采用。您可以為此使用列表或集合。請注意,如果兩個單元格的坐標之和相等,則兩個單元格位于同一對角線上。后對角線上的單元格的共同點是它們的坐標差相等。這樣您就不必每次都在這些行中掃描“1”。

此外,board可能只是列號列表。無需存儲所有這些零。僅保留用于顯示。

最后,有一些簡單的方法可以在線性時間內獲得解決方案。參見維基百科


查看完整回答
反對 回復 2022-01-18
  • 1 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號