python8皇后不攻击问题_Python八皇后问题(落最后一颗子)

最近在看Python基础,遇到了八皇后问题,看得整个人晕晕乎乎,甚至开始怀疑人生。

问题是在一个8*8的国际象棋棋盘上摆放8个皇后,问题一是找出一个解,问题二是问有多少个解。这里我把我自己的理解写出来,只针对最后一个落子的情况,不涉及递归,希望能有所帮助。

首先定义冲突函数:

def conflict(state,nextQueenColumnIndex):

#state是当前已经放置的皇后在棋盘上面的列索引组成的元组,nextQueenColumnIndex是将要放置的下一个皇后(简称A)的列索引,这里关键问题在于要将A与之前放置的皇后一一比对,找出是否会被吃掉(存在冲突),因此需要做循环,之前已经放置的皇后个数当然是len(state),因为索引是从0开始算的,所以已经放置的最后一个皇后的行索引为len(state)-1,因此A的行索引为len(state)。

nextQueenRowIndex=len(state)

for everyqueen in range(nextQueenRowIndex):

#注意range右边是开区间,取出每一行等行索引。

if abs(state[everyqueen]-nextQueenColumnIndex) in (0,nextQueenRowIndex-everyqueen):

#,这里需要明白的是,假如state为(0,1,2,3),那么代表的是第一行皇后列索引为0,第二行皇后列索引为1,以此类推。那么state[everyqueen]实际上就是取出了每一行皇后的列索引。

return True

return False

#这里有两个关键点,第一、是abs(state[everyqueen]-nextQueenColumn)==0检查A是否与其他皇后在同一列,abs(state[everyqueen]-nextQueenColumn)==nextQueenRowIndex-everyqueen检查A是否与其他皇后在一条斜线上(对角线),其实就是行索引-行索引==列索引-列索引就代表在一条斜线上面。第二、注意return False是与for对齐的,因为只要存在冲突就会return True,当for循环执行完后都没有return的话,那么就会执行到return False,也即不存在冲突,那么A落在这个棋盘点就是对的!

以上,冲突函数就写完了。

然后,我们来写主函数

def MyQueen(state,queencount):

#state依然代表当前已经放置的皇后在棋盘上面的列索引组成的元组,queencount代表皇后的总数(包括已有的和准备下的),下面讨论的是最简单的一种情况,就是已知棋盘的状态,需要下最后一颗子。

if len(state)==queencount-1#len(state)代表已落子的个数,如果与总数-1相等的话,那么我们要下的必然是最后一颗子。这最后一颗子怎么下?当然是要与前面的每一行的皇后做冲突比对,好在我们的冲突函数已经写好了,可以直接用。

for n in range(queencount):取出每一列的列索引,其实就是说在当前棋盘状态下,落子第一列行不行?落子第二列行不行?。。。落子最后一列行不行?其实这里的range(queencount)只是方便我们按次序取出1,2,3,4,5。。。,因为要注意这道题的前提是棋盘是真方形,是在N*N的棋盘上面放置N个皇后,因此我们这里直接用queencount比较方便,当然如果你已经知道棋盘大小为8或者16直接用range(8)或者range(16)也行。

if not conflict(state,n):#n就是要落子的列索引

print(n)

#输出的n就是A的列索引了,也即最后一个皇后落子的棋盘列索引位置。

Over,上面就讨论了八皇后问题中落最后一颗子的简单情况,当然是用这个函数的前提是要知道棋盘的当前落子状态及皇后的总数,我目前刚把这个看懂,写出来,也为自己加深印象,后面的还要继续学习。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答关于八皇后问题的解决方案。 八皇后问题一个经典的问题,目的是在一个8x8的棋盘上放置8个皇后,使得它们不会互相攻击,即不在同一行、同一列或同一对角线上。这个问题可以使用穷举法来解决。 在Python中,可以使用NumPy库来方便地处理8x8的棋盘。首先,我们可以创建一个8x8的二维数组来表示棋盘,其中0表示该位置为空,1表示该位置有一个皇后。 然后,我们可以使用两个循环来遍历棋盘上的每个位置,将皇后放在该位置,并检查是否满足不互相攻击的条件。如果满足条件,则继续放下一个皇后,直到所有皇后都被放置。 以下是一个使用穷举法和NumPy库解决八皇后问题的简单示例代码: ```python import numpy as np def is_valid(board, row, col): # 检查行和列 if np.sum(board[row, :]) > 0 or np.sum(board[:, col]) > 0: return False # 检查对角线 n = board.shape[0] for i in range(n): for j in range(n): if board[i, j] == 1: if abs(i - row) == abs(j - col): return False return True def solve(board, row): if row == board.shape[0]: # 找到了一个解 print(board) else: for col in range(board.shape[1]): if is_valid(board, row, col): board[row, col] = 1 solve(board, row + 1) board[row, col] = 0 # 创建一个空棋盘 board = np.zeros((8, 8), dtype=int) # 开始求解 solve(board, 0) ``` 在上面的代码中,`is_valid()`函数用于检查当前位置是否满足不互相攻击的条件。`solve()`函数用于递归地放置皇后,并检查每个位置是否满足条件。 当找到一个解时,程序将打印出棋盘上每个位置的值,其中1表示该位置有一个皇后,0表示该位置为空。在本例中,程序将输出92个解,因为八皇后问题有92个不同的解决方案。 希望这个例能够帮助您理解如何使用穷举法和NumPy库来解决八皇后问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值