方法1

# 八皇后问题:
# 思路:确保每一个皇后的左上角、右上角或正上方没有皇后,用这个规则递归地每一行,再每一列循环过去,每一列或每一行只有一个元素
from tkinter import *
from PIL import Image, ImageTk


SIZE = 8

class EightQueen:
def __init__(self):
self.queens = SIZE * [-1] # 存放该行对应的列数
self.search(0)
window = Tk()
window.title("EightQueen demo")
image=ImageTk.PhotoImage(file=r"C:\Users\Lenovo\Desktop\queen.png")

self.canvas=Canvas(window)
self.canvas.pack()
for i in range(SIZE):
for j in range(SIZE):
if self.queens[i] == j:
Label(self.canvas,image=image).grid(row=i,column=j)
else:
Label(self.canvas,bg="red").grid(row=i,column=j)
window.mainloop()

def search(self, row):
if row == SIZE:
return True
else:
for column in range(SIZE):
self.queens[row] = column
if self.isValid(row, column) and self.search(row + 1):
return True


# 判断规则
def isValid(self, row, column):
for i in range(1, row + 1): # 表示范围是[1,row],下面对方下标是[0,row-1]的取值范围
if self.queens[row - i] == column or self.queens[row - i] == ( column - i ) or self.queens[row - i] ==( column + i):
return False
return True

EightQueen()

python八皇后问题2种解法_递归调用


python八皇后问题2种解法_八皇后问题_02

方法2

"""
八皇后问题
"""
import random

# 1、检查冲突
# 参数nextX表示下一个皇后的水平位置(x坐标,即列),而nextY为下一个皇后的垂直位置(y
# 坐标,即行)。这个函数对既有的每个皇后执行简单的检查:如果下一个皇后与当前皇后的x坐标
# 相同或在同一条对角线上,将发生冲突,因此返回True;如果没有发生冲突,就返回False。比
# 较难理解的是下面的表达式:
# abs(state[i] - nextX) in (0, nextY - i)
# 如果下一个皇后和当前皇后的水平距离为0(在同一列)或与它们的垂直距离相等(位于一
# 条对角线上),这个表达式就为真;否则为假

def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
if abs(state[i] - nextX) in (0, nextY - i):
return True
return False


# 2.基线条件
# 这段代码的意思是,如果只剩下最后一个皇后没有放好,就遍历所有可能的位置,并返回那
# 些不会引发冲突的位置。参数num为皇后总数,而参数state是一个元组,包含已放好的皇后的位
# 置。
# def queens(num, state):
# if
# for pos in range(num):
# if
# yield pos

# 可在递归条件中假设来自更低层级(编号更大的皇后)的结果都是正确的。
# 因此,只需在函数queens的前述实现中给if语句添加一个else子句。
# 你希望递归调用返回什么样的结果呢?你希望它返回当前行下面所有皇后的位置,对吧?假
# 设位置是以元组的方式返回的,因此需要修改基线条件,使其返回一个(长度为1的)元组,但
# 这将在后面处理。
# 因此,对于递归调用,向它提供的是由当前行上面的皇后位置组成的元组。对于当前皇后的
# 每个合法位置,递归调用返回的是由下面的皇后位置组成的元组。为了让这个过程不断进行下去,
# 只需将当前皇后的位置插入返回的结果开头
def queens(num=8, state=()):
for pos in range(num):
if not conflict(state, pos):
if len(state) == num - 1:
yield (pos,)
else:
for result in queens(num, state + (pos,)):
yield (pos,) + result


def pretty_print(solution):
def line(pos, length=len(solution)):
return '. ' * (pos) + 'X ' + '. ' * (length - pos - 1)

for pos in solution:
print(line(pos))


def main():
pretty_print(random.choice(list(queens(8))))# 随机获取1种解法


main()

python八皇后问题2种解法_元组_03