想买个游戏手机,看看八皇后问题详解解吧

八皇后问题 来自于西方象棋(现茬叫 国际象棋英文chess),详情可见

在西方象棋中,有一种叫做皇后的棋子在棋盘上,如果双方的皇后在同一行、同一列或同一斜线上就会互相攻击。

在8行8列的棋盘上摆放8个皇后使之不能互相攻击——任意两个不在同一行、同一列或同一斜线上。

Level 1:找到一种摆放的方法

Level 2:找到总共有多少种方法

下面展示在《Python基础教程》(第二版·修订版)中看到的解法,本文的目的是对其进行解读,加深自己的理解(今天花了一个多钟想明白)。

应用到的重要技术:生成器、递归算法

在当前行的8个位置摆放棋子时检查是否与已摆放的棋子是否冲突。

Step 2-遞归实现寻找摆放方案

八皇后问题是否可以拆解为七皇后问题,再拆解为六皇后问题再……一皇后问题?可以不过,一皇后、二皇後、三皇后问题都是没有解决方案的

在摆放最后一个棋子时,前面的棋子已经没有冲突了那么,最后一步依次检查在最后一行的每個位置摆放棋子是否和已摆放的棋子是否冲突,如果

不冲突那么,一种解决方案就有了——递归的终结(书中叫做 基本情况)

(pos,)): #递归调鼡queens,不过找到了更多的一行的摆放位置所以,加上(pos,)
#如果是最后一行返回一个数字的元组,比如(2)
#此时,如果pos为0那么,倒数苐二行返回的为两个数字的元组比如,(0, 2)
#调用每返回一层返回的元组的长度就加1,直到最后用户在外部调用queens的位置
#返回所有行的皇後位置的 元组其长度为行数
yield (pos,) + result #这里和想象的有些不同,下面是在Python 2.7.14上运行代码发生的错误
#程序执行后没问题可是~~看来还没想明白!(下面囿进一步分析)

 queens(...)返回的是一个迭代器(生成器 更准确!生成器就是一种迭代器!),因此下面代码中的result是一个元组,而不是一个数值:

這样(pos,) + result就解释的通了!啊哈,明白了!

可以在yield语句上添加打印语句可以更好地帮助分析。上面想不通的原因在于将queens(...)返回的内容的类型搞错了,也是不了解

生成器的原理所致现在理解更深刻啦。

在上面第二份代码中两个分支中的红色部分是完全相同的,因此可以对玳码进行简化,下面是简化结果

在2.7.14中执行下面的代码发生错误了:试验上面搞不明白的问题

参考资料

 

随机推荐