gpt4 book ai didi

python - 为什么我的 N Queens 算法到达最后一行?

转载 作者:行者123 更新时间:2023-12-03 21:57:59 37 4
gpt4 key购买 nike

我想我理解 NQueens 算法的重点 - 您检查每一行是否存在可用空间,如果它们存在,则在那里放置一个皇后,然后递归地将算法调用到下一行。这是我的算法(N 大小为 3)

from typing import List
import pdb
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
self.solutions = 0
self.attack_zone = [[0]*n for i in range(n)]
self.size = n
self.backtrack_nqueens(0,0) #start on row 0
return self.solutions
def backtrack_nqueens(self,row,iteration):
#starting at row
for col in range(self.size):
if self.is_not_under_attack(row,col):
print("on iteration",iteration,row,col,"was a safe place for some reason")
#adds queen to this row
self.place_or_remove_queen(row,col,True)
if row + 1 == self.size:
## THIS SHOULD NEVER HAPPEN
self.solutions += 1
else:
self.backtrack_nqueens(row+1,iteration+1)
#removes queen from this row
self.place_or_remove_queen(row,col,False)

def place_or_remove_queen(self,row,col,place):
flag = 1 if place else 0
self.attack_zone[row] = [flag]*self.size
#for col
for r in range(self.size):
self.attack_zone[r][col] = flag
#lower right
for r,c in zip(range(row,self.size,1),range(col,self.size,1)):
self.attack_zone[r][c] = flag
#upper right
for r,c in zip(range(row,-1,-1),range(col,self.size,1)):
self.attack_zone[r][c] = flag
#lower left
for r,c in zip(range(row,self.size,1),range(col,-1,-1)):
self.attack_zone[r][c] = flag
#upper left
for r,c in zip(range(row,-1,-1),range(col,-1,-1)):
self.attack_zone[r][c] = flag

def is_not_under_attack(self,row,col):
return self.attack_zone[row][col] == 0
s = Solution()
print(s.solveNQueens(3))

当我运行它时,self.solutions 最终为 3 - 基本上它为我们都知道不应该发生的女王找到了 3 个位置。我不明白它是如何到达我说##THIS SHOULD NEVER HAPPEN 的那一行的。

我唯一能想到的就是我以某种方式移除了一个不应该被移除的女王?所以我的attack_zone在不应该有空位时有空位。有人可以指出我在递归中做错了什么会导致这种情况,为什么?

最佳答案

问题是,当你移除一个皇后时,你将相应的方格标记为“空闲”,即将它们的“威胁计数”设置为零,而不管另一个皇后是否也威胁到那个方格。考虑到您的示例,会发生以下情况:

# Iteration 1     # Iteration 2     # Iteration 3

| 1 | 1 | Q | | 1 | 1 | Q | | 0 | 0 | Q |
+---+---+---+ +---+---+---+ +---+---+---+
| 0 | 1 | 1 | | Q | 1 | 1 | | 0 | 0 | 0 |
+---+---+---+ +---+---+---+ +---+---+---+
| 1 | 0 | 1 | | 1 | 1 | 1 | | 0 | 0 | 1 |

在迭代 #3 中, (1, 0) 上的女王被删除,所有相应的方块都被标记为 0 ,还有那些实际上在 (0, 2)上受到女王威胁的人.同样的情况也发生在 (1, 1) 上的皇后身上。和 (1, 2)后者最终导致 (2, 0) 上的一个自由方块这是最后一行。

为了使算法工作,您可以维护一个“威胁计数”,它跟踪一个正方形受到威胁的皇后数。放置一个皇后会增加一个计数,移除一个皇后会减少一个。您可以通过更改 flag 的值来实现这一点。至 flag = 1 if place else -1然后使用 self.attack_zone[r][c] += flag无处不在而不是 self.attack_zone[r][c] = flag .这给出了以下图片:
# Iteration 1     # Iteration 2     # Iteration 3

| 1 | 1 | Q | | 2 | 2 | Q | | 1 | 1 | Q |
+---+---+---+ +---+---+---+ +---+---+---+
| 0 | 1 | 1 | | Q | 2 | 2 | | 0 | 1 | 1 |
+---+---+---+ +---+---+---+ +---+---+---+
| 1 | 0 | 1 | | 2 | 1 | 1 | | 1 | 0 | 1 |

关于python - 为什么我的 N Queens 算法到达最后一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61107641/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com