八皇后12组不重复解的pythonic编程法

八皇后问题,国际象棋盘上放8个皇后,互相不能攻击。这个问题如此有名,很多不会下国际象棋的人都听说过。
所有可能的布局解一共有92种,但其中大部分是重复的,比如左右对称,或者是旋转棋盘对称。据说其中完全独立的布局一共只有12种。虽然我得到了一个12个不同的布局,但在网上一直没有找到12种布局图,所以无法验证。

92种解

用python求解92种布局是比较简单的,网上算法有很多(不知道去重之后有多少种),这里展示一个自己原创的解法。算法的特点是使用了字典来记录局面,使用yield机制来返回结果。这样的算法应该是具有足够多的python特色了。

def checkBoard(A, col, row):
    flag= True
    for i in range(col):
        if A[i] == row or abs(row - A[i]) == col - i:
            flag = False
            break
    return flag

def queen(size, col=0, A={}):
    for row in range(size):
        if checkBoard(A, col, row):
            A[col]=row
            if col==size-1:
                yield [row]
            else:
                ret= queen(size, col+1, A)
                for item in ret:
                    yield [row]+item
ret= queen2(8)

在这里插入图片描述
在这里插入图片描述
上面这两个算法,在全部12种解法种,是唯二的具有角落点的布局。人工对比可以保证不重复。

12种不同解

去重算法,相对比较暴力。一个布局,它的衍生布局一共有8个:

  1. 自身
  2. 左右翻转
  3. 上下翻转
  4. 左右上下翻转
  5. 自身行列互换
  6. 左右翻转行列互换
  7. 上下翻转行列互换
  8. 左右上下翻转行列互换

逐个检视92个布局,选择完全不同的布局加入另外一个列表,最后获得12布局解。

def rot(A):
    B= [-1]*8
    for i in A:
        B[A[i]]=i
    return B
def sameBoard(A, B):
    B2= B[::-1]
    B3= [7-x for x in B]
    B4= rot(B)
    B5= rot(B2)
    B6= rot(B3)
    B7= [7-x for x in B2]
    B8= rot(B7)
    B_like=[B2,B3,B4,B5,B6,B7,B8]
    if A in B_like:
        return 1
    return 0

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上面这七个布局,至少有一个点在某条边的第二点上。

画图

这里是画棋盘和棋子布局的代码。

def drawBoard(board, num):
    from PIL import Image
    a= 55
    b= 55
    xd= 43
    yd= 43
    back= Image.open('棋盘.png')
    back= back.convert('RGB')
    qun= Image.open('queen_trans.png')
    qun= qun.resize((a,b), Image.ANTIALIAS)
    _,_,_,af= qun.split()
    for i in board:
        x= i*a+ xd
        y= board[i]*b+ yd
        back.paste(qun, (x,y), af)
    back.save('%d.jpg'%num)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
最后这三个布局,不存在角落点与第二点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

圣手书生肖让

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值