这里是对于周一课上的老师教学的python八皇后问题的个人学习记录
八皇后问题出自国际象棋:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)
那么python怎么实现以及对于八皇后问题的求解呢?鉴于初学者水平只能讲讲递归回溯算法对于八皇后问题的求解
核心代码如下:
def isNotConfict(queen, row): #判断是否冲突
for i in range(0, row):
if queen[i] == queen[row] or abs(i - row) == abs(queen[i] - queen[row]):
return False
return True
对于皇后间不能在同一行,以及在对角线位置,这里采用循环遍历的方式,前一个皇后与后一个皇后之间的行数不等,对角线下表元素相减绝对值也不能等判断其位置是否冲突,这里采用老师给的代码
def confict(state,nextX):
nextY=len(state)
for i in range(nextY):
if abs(state[i]-nextX)in(0,nextY-i):
return True
return False
同一垂直线上abs(state[i]-nextX)==0,对角线上abs(state[i]-nextX)==nextY-i
把已知的皇后位置传给conflict函数进行判断,决定下一个皇后的位置是否会产生冲突
当只剩最后一个皇后时,只需要根据其他皇后位置自动形成他合适位置
def queen(num,state):
if len(state)==num-1:
for pos in range(num):
if not conflict(state,pos):
yield pos
这里采用生成器的方法,需要递归的方法,完成基本情况后需要做的就是为前面的queens函数实现if语句后增加else语句,在递归中想要得到更高位置皇后的位置,需要将位置信息作为一个元组返回,即yield(pos,),为了继续运行,需要把当前位置信息添加到元组中并传入给后面的皇后
else:
for pos in range(num):
if not conflict(state,pos):
for result in queens(num,state+(pos,)):
yield(pos,)+result
老师完整代码,采用了元组不可个更改的性质,生成器yield自动循环遍历下一个皇后的位置
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
def queens(num, 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