问题描述
八皇后问题介绍
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
思路分析
由于国际象棋是一个8*8的棋盘,而且棋盘中总共需要放置8个皇后。那么肯定在每一行都会有且仅有一个皇后,那么可以直接使用一个一维数组,使用它的下标代表行数,数组的值代表每一行对应的列数。
具体步骤如下:
1)第一个皇后放在第一行第一列
2)第二个皇后放在第二行第第一列、然后判断是否OK;如果不OK,那么就横向右移,直到找到合适的位置
3)继续第三个皇后,还是重复第二行的操作,并且要同时判断和第一行和第二行的是否冲突,直到找到合适位置
4)当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一行的所有解,全部得到
5)然后将第一个皇后放到第二列,后面循环执行1,2,3,4的步骤
具体代码:
import math
class Queue(object):
def __init__(self):
self.cnt = 0#统计八个皇后的满足要求的摆放方式的个数
self.maxn = 8#数组的最大长度
self.array = [0 for i in range(8)]#数组下标代表行,每个下标的值为列
'''
打印皇后位置数组
'''
def Print(self):
for i in range(len(self.array)):
print("%d "%self.array[i],end='')
print()
'''
判断当前皇后位置和前几个皇后的位置是否冲突
'''
def judge(self,n):
for i in range(n):
if self.array[i]==self.array[n] or abs(n-i)==abs(self.array[n]-self.array[i]):
return False
return True
'''
回溯递归
'''
def check(self,n):
if n==self.maxn:
self.cnt+=1
self.Print()
return
for i in range(self.maxn):
self.array[n]=i
if self.judge(n):
self.check(n+1)
q = Queue()
q.check(0)
num = q.cnt
print('总共:%d'%num)