n皇后编程问题
n皇后编程问题是一个经典问题,记得2018年北京航空航天大学计算机学院的博士招聘的上机题目就是这个,这里给出几种实现方法:
import time
import itertools
Num = 8
# Num = 12 # 8
def f1():
def test_queens(queens):
for x in range(Num):
for y in range(x+1, Num):
if abs(queens[x]-queens[y])==abs(x-y):
return False
return True
counter = 0
for i in range(12345678, 87654321, 1):
s = str(i)
if "0" in s or "9" in s:
continue
if len(set(s)) != 8:
continue
if test_queens([int(digit)-1 for digit in s]):
counter += 1
return counter
def f2():
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=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
return queens()
def f3():
num = Num
def conflict(queen):
for x in range(num):
for y in range(x+1, num):
if abs(queen[x]-queen[y])==(y-x):
return True
return False
queens = []
for queen in itertools.permutations(range(num)):
if not conflict(queen):
queens.append(queen)
return queens
_a = time.time()
print(f1())
_b = time.time()
print(_b - _a)
_a = time.time()
print(len([x for x in f2()]))
_b = time.time()
print(_b - _a)
_a = time.time()
print(len([x for x in f3()]))
_b = time.time()
print(_b - _a)
上面的实现中,当n=8时,f1()函数实现、f2()函数实现、f3()函数实现的运行时间如下(单位为秒):
92
11.19756269454956
92
0.005673408508300781
92
0.019522428512573242
可以看到f1()函数的实现是f2实现的2000倍的用时,因此在下面的n=12时我们只给出f2()和f3()函数实现下的用时:
14200
4.591862201690674
14200
295.7449884414673
可以看到,f3()的实现下用时是f2()实现下的60倍。
总结:
f2()方法实现是运行时间最短的方法。
f3()方法是f2()用时的60倍。
f1()方法是f2()用时的2000倍。
不过在n=8时,也就是8皇后问题下,f2()和f3()的用时都是符合一般要求的(1秒以内或5秒以内)。
由于f2()中使用了yield,这一点并不通用,于是将其改为return,并加入sss=[ ]作为状态保存,具体代码如下:
import time
import itertools
Num = 8
def f2():
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=()):
sss = []
for pos in range(num):
if not conflict(state, pos):
if len(state) == num-1:
# yield (pos, )
sss.append((pos,))
else:
for result in queens(num, state+(pos, )):
# yield (pos, ) + result
sss.append( (pos, ) + result )
return sss
return queens(8)
_a = time.time()
print(len([x for x in f2()]))
_b = time.time()
print(_b - _a)
运行结果如下:
不过考虑到即使把f2()中的yield改为return也是需要使用递归算法的,而递归算法是可以使用循环算法来替代的,于是使用循环算法修改f2()中的递归,得到如下代码:
import time
def f2():
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():
s = [[i, ] for i in range(8)] # 初始化
s_tmp = []
count = 0
while count<8-1:
for state in s:
for pos in range(8):
if not conflict(state, pos):
state_copy = state.copy()
state_copy.append(pos)
s_tmp.append(state_copy)
s = s_tmp
s_tmp = []
count += 1
return s
return queens()
_a = time.time()
print(len([x for x in f2()]))
_b = time.time()
print(_b - _a)
运行结果如下:
个人github博客地址:
https://devilmaycry812839668.github.io/
n皇后编程问题的更多相关文章
- 8皇后-----回溯法C++编程练习
/* * 八皇后问题回溯法编程练习 * 在8×8的棋盘上,放置8个皇后,两个皇后之间不能两两攻击 * 也即,直线,垂直45度.135度方向不能出现两个皇后 * * copyright Michael ...
- Java编程思想—八皇后问题(数组法、堆栈法)
Java编程思想-八皇后问题(数组法.堆栈法) 实验题目:回溯法实验(八皇后问题) 实验目的: 实验要求: 实验内容: (1)问题描述 (2)实验步骤: 数组法: 堆栈法: 算法伪代码: 实验结果: ...
- N皇后问题(C++实现和函数式编程实现)
题意 在 N * N 的方格棋盘放置了 N 个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.求出有多少种合法的放置方法. C++实现(位运算 ...
- Python学习二(生成器和八皇后算法)
看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 ...
- 回溯法解决N皇后问题(以四皇后为例)
以4皇后为例,其他的N皇后问题以此类推.所谓4皇后问题就是求解如何在4×4的棋盘上无冲突的摆放4个皇后棋子.在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平.竖直.以及45度 ...
- 啊哈C!思考快你一步——用编程轻松提升逻辑力
啊哈C!思考快你一步——用编程轻松提升逻辑力(双色)(每个人都应该学习如何编程,因为它教会你如何思考.——史蒂夫.乔布斯) 啊哈磊著 ISBN 978-7-121-21336-6 2013年9月出版 ...
- N皇后问题--回溯法
1.引子 中国有一句古话,叫做“不撞南墙不回头",生动的说明了一个人的固执,有点贬义,但是在软件编程中,这种思路确是一种解决问题最简单的算法,它通过一种类似于蛮干的思路,一步一步地往前走,每 ...
- [转]如何学好windows c++编程 学习精髓(收集,整理)
以下是很多VC爱好者的学习经历,希望对大家有所帮助: 我记得我在网上是这么说的:先学win32的SDK,也就是API, 再学MFC,这么一来呢,就先有个基础,MFC是API的封装, 如果API用的熟了 ...
- BJDP结对编程活动
7月21日参与了 BJDP北京的活动 在北京首次参与能够参与动手编程活动,感觉挺不错的. 本次活动共有三项内容 1. 金锐分享单元测试的Mocking技术,20 mins 2. 伍 ...
- Java实现八皇后
实验题目 回溯法实现8皇后问题 实验要求 a.掌握递归回溯算法的基本思想. b.学习掌握应用面向对象通用回溯程序框架解决实际问题. 提高面向对象编程的技能. 作业描述:在8*8格的棋盘上放置 ...
随机推荐
- cnetos7.3离线安装vscode
1.从官网下载压缩包(话说下载下来解压就直接可以运行了咧,都不需要make) #下载vscode包 访问Visual Studio Code官网 https://code.visualstudio.c ...
- 树上倍增求 LCA 模板
void dfs(int x,int fa,int d){ deep[x]=d;dp[x][0]=fa; for(int i=1;i<=lg2[deep[x]];++i){ dp[x][i]=d ...
- 使用 SSH 转义代码来控制连接
OpenSSH 最常被忽视的一个非常有用的功能是能够从连接内部控制会话的某些方面.通过使用 SSH 转义代码,我们能够在会话内部与本地 SSH 软件进行交互. 强制从客户端断开连接(如何退出卡住或冻结 ...
- 基于PaddleNLP信息抽取,uie微调打造自己专属的信息抽取模型
基于PaddleNLP信息抽取,uie微调打造自己专属的信息抽取模型 UIE模型简介 UIE优势 应用示例 UIE开箱即用 UIE适用抽取示例 命名实体识别(Named Entity Recognit ...
- Docker高级:Redis集群实战!4主4从缩容到3主3从,怎么处理?
在上一篇,我们学会了redis集群的扩容.从3主3从扩容到4主4从. 那么,接着,活动过去了.流量没有那么大了.需要缩容了.从4主4从缩容到3主3从了.那么这个时候又该怎么处理呢? PS本系列:< ...
- C语言指针的作业
指针的作业 求Sn = a + aa + aaa + aaaa + aaaaa的前五项和,其中a是一个数字. 例如:2 + 22 + 222 + 2222 + 22222 /* 求Sn = a + a ...
- Naive UI 2.38.1
https://www.naiveui.com/zh-CN/os-theme/docs/i18n 配置字体 Naive UI 可以和 vfonts 配合,你可以简单的引入 vfonts 中的字体,包含 ...
- Spring —— AOP(面向切面编程)
AOP(Aspect Oriented Programming)简介 面向切面编程,一种编程范式,指导开发者如何组织程序结构 作用:在不惊动原始设计的基础上为其进行功能增强 Spring理念:无入侵式 ...
- 暑假集训SCP提高模拟10
我(看着百度百科):我已经知道这场谁组的题了 CTH: 谁 我:你想想,能在模拟赛里塞四道数学题还玩邦的,还能有谁 CTH: 我不知道 我:我不知道 CTH: 我知道了 我:我知道了 我:我是 Bob ...
- std::variant快速上手
std::variant 是 C++17 引入的一种类型安全的联合体,用来存储多个可能类型中的一种值,且保证使用时的类型安全.相比于传统的 union,std::variant 不仅能够存储不同类型的 ...