八皇后(回溯算法) -- Python

本文介绍了回溯算法的概念,以八皇后问题为例详细阐述了如何运用回溯算法来解决。八皇后问题是在8x8棋盘上放置8个皇后,确保没有任何两个皇后在同一行、同一列或同一条对角线上。通过Python代码展示了回溯算法的实现过程,包括棋盘状态的初始化、打印棋盘、递归放置皇后以及回溯操作。代码运行结果显示了所有可能的解决方案数量。
摘要由CSDN通过智能技术生成

回溯算法,又称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯算法。
八皇后问题: 有八个皇后(可以当成八个棋子),如何在 8*8 的棋盘中放置八个皇后,使得任意两个皇后都不在同一条横线、纵线或者斜线上。
八皇后问题是使用回溯算法解决的典型案例。算法的解决思路是:

  • 从棋盘的第一行开始,从第一个位置开始,依次判断当前位置是否能够放置皇后,判断的依据为:同该行之前的所有行中皇后的所在位置进行比较,如果在同一列,或者在同一条斜线上(斜线有两条,为正方形的两个对角线),都不符合要求,继续检验后序的位置。
  • 如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探。
  • 如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。

下面是利用Python代码实现的:

def mat(n):
    place = [0 for i in range(n)] # # 表示第几行放在第几列,例如place[0] = 1, place[1] = 3
    flag = [0 for i in range(n)] # # 表示第n列被标记,比如第一列被标记 flag[1] = 1
    d1 = [0 for i in range(2*n - 1)] # 表示上对角线是否被标记,d[0+1] = 1
    d2 = [0 for i in range(2*n - 1)] # 表示下对角线是否被标记
    return place,flag,d1,d2

def print_mat(place,n):
    for i in range(n):
        for j in range(n):
            if place[i] == j:
                print("*",end=' ')
            else:
                print("-",end=' ')
        print()
    print()

def queen(row,n,place,flag,d1,d2):
    global count
    for col in range(n):
        if flag[col] == 0 and d1[row+col] == 0 and d2[row-col+n-1] == 0:
            place[row] = col
            flag[col] = 1
            d1[row+col] = 1
            d2[row-col+n-1] = 1
            if row < n - 1:
                queen(row+1,n,place,flag,d1,d2)
            else:
                count += 1
                print_mat(place,n)
            """ 这里是回溯,例如第三行不符合条件,则返回第二行,然后重新选择第二行的点 """
            flag[col] = 0
            d1[row + col] = 0
            d2[row - col + n - 1] = 0

if __name__ == "__main__":
    count = 0
    n = int(input("请输入:")) # 这里是输入N 表示一个N*N的棋盘
    place,flag,d1,d2 = mat(n)
    queen(0, n, place, flag, d1, d2)
    print(f"一共有{count}种可能")

这里代码运行结果:
在这里插入图片描述

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值