这里是对于周一课上的老师教学的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

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐