Python(广度优先搜索+回溯+递归)、lingo实现八皇后问题

文章介绍了八皇后问题,这是一种经典的回溯算法应用。通过解释回溯法、广度优先搜索和递归的概念,文章展示了如何使用Python和Lingo来解决这个问题。Python代码实现了一个递归函数,通过回溯找到所有可能的皇后布局,而Lingo由于限制只能找到一种解决方案。
摘要由CSDN通过智能技术生成

引言

在了解如何用python、lingo实现八皇后问题之前我们先了解什么是广度优先搜索、回溯、递归,因为python实现八皇后问题是回溯算法的一个经典算法习题,也是python实现八皇后问题用到的主要算法。

前言

广度优先搜索(Breadth First Search)简称广搜或者 BFS,是遍历存储结构的一种算法,既适用于无向图(网),也适用于有向图(网)。

回溯法(back tracking)(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回到上一步,重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

上述两种方法其实本质上就是枚举法,只不过是一种有策略的枚举-----------------------------------------根据问题的约束条件进行剪枝。

递归的思想是把一个大型复杂问题层层转化为一个与原问题规模更小的问题,问题被拆解成子问题后,递归调用继续进行,直到子问题无需进一步递归就可以解决的地步为止。

目录

引言

前言

算法简介

回溯法

广度优先搜索(Breadth First Search)

递归

问题描述

八皇后问题

 算法思路

代码实现

python实现如下

​​lingo实现如下


​​​​​​

算法简介

回溯法

用数据结构中的树简单举一个例子:

从树的根节点开始,对每一个子树都有两种操作(取、不取)(取其中一个就要舍弃其余的子树),直到树的最后一层。其中的每个被取子树都可以看作是一次尝试,每次尝试都可以得出一个结果。将得到的结果综合起来,就是的所有可能的取法。

广度优先搜索(Breadth First Search)

搜索本质上就是枚举,只不过是一种有策略的枚举, 通常在搜索前,根据条件降低搜索规模、根据问题的约束条件进行剪枝、利用搜索过程中的中间解,避免重复计算这几种方法从而进行算法上的优化 。

递归

主要的难点:

1、如何将原问题转化为一个与原问题规模更小的问题。

2、递归的终止条件。

问题描述

八皇后问题

八皇后问题是以国际象棋为背景的问题:有八个皇后(可以当成八个棋子),如何在 8*8 的棋盘
中放置八个皇后,使得任意两个皇后都不在同一条横线、纵线或者斜线上。

 算法思路

1.从棋盘的第一行、第一列开始,依次判断当前位置是否能够放置皇后。
判断的依据:新皇后与之前的所有行、列中的皇后所在位置进行比较,如果新皇后与之前的所有行、列中的皇后在同一行、同一列、同一条对角线上(两条对角线(正、负)),则判断不符合条件,继续检索后序位置。
2.如果该行中所有位置都不符合要求,则回溯到前一行,改变该皇后的位置,继续执行第一步进行探索。
3.如果试探到最后一行,则说明所有皇后位置摆放完毕,再回溯到前一行,改变该皇后的位置,继续执行第一步进行探索。

代码实现

python实现如下

def num_Eight_Empresses(num):   #判断新皇后与之前的所有行、列中的皇后在同一行、同一列、同一条对角线上
    ans = []
    def conflect(stack,y_next):
        for i in stack:
            x1,y1=i[0],i[1]
            if y1 == y_next or abs(x1 - len(stack)) == abs(y1 - y_next):
                return False
        return True

    def Eight_Empresses(x1,y1):
        li = [[0 for i in range(8)] for i in range(9)]
        stack = []
        stack.append((x1,y1))
        li[x1][y1] = 1
        while len(stack) > 0:
            if len(stack) == 8:         #所有皇后位置摆放完毕
                print(stack)            #输出所有皇后的位置
                ans.append(stack)       #记录有多少种方式可以存放8个皇后
                curnode = stack.pop(-1)     #回溯到前一行
                li[curnode[0]][curnode[1]] = 1
                for i in range(8):
                    li[curnode[0]+1][i] = 0
            elif len(stack) == 0:
                break
            for j in range(8):
                if conflect(stack,j):
                    if li[len(stack)][j] == 0:
                        stack.append((len(stack),j))
                        break
                    else:
                        continue
            else:
                curnode = stack.pop(-1)
                li[curnode[0]][curnode[1]] = 1
                for i in range(8):
                    li[curnode[0]+1][i] = 0
    for i in range(num):
        Eight_Empresses(0,i)            #递归寻找满足条件的8个皇后的位置
    return len(ans)
print(num_Eight_Empresses(8))

​​lingo实现如下

 因为lingo软件本身的限制,所以使用lingo进行求解,只能求出众多可行解中的一个可行解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

!continue!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值