本文实例讲述了Python基于回溯法子集树模板解决野人与传教士问题。分享给大家供大家参考,具体如下:

问题
在河的左岸有N个传教士、N个野人和一条船,传教士们想用这条船把所有人都运过河去,但有以下条件限制:
(1)修道士和野人都会划船,但船每次最多只能运M个人;
(2)在任何岸边以及船上,野人数目都不能超过修道士,否则修道士会被野人吃掉。
假定野人会服从任何一种过河安排,请规划出一个确保修道士安全过河的计划。
分析
百度一下,网上全是用左岸的传教士和野人人数以及船的位置这样一个三元组作为状态,进行考虑,千篇一律。
我换了一种考虑,只考虑船的状态。
船的状态:(x, y) x表示船上x个传教士,y表示船上y个野人,其中 |x|∈[0, m], |y|∈[0, m], 0<|x|+|y|<=m, x*y>=0, |x|>=|y|
船从左到右时,x,y取非负数。船从右到左时,x,y取非正数
解的编码:[(x0,y0), (x1,y1), ..., (xp,yp)] 其中x0+x1+...+xp=N, y0+y1+...+yp=N
解的长度不固定,但一定为奇数
开始时左岸(N, N), 右岸(0, 0)。最终时左岸(0, 0), 右岸(N, N)
由于船的合法状态是动态的、二维的。因此,使用一个函数get_states()来专门生成其状态空间,使得主程序更加清晰。
代码
n = 3 # n个传教士、n个野人
m = 2 # 船能载m人
x = [] # 一个解,就是船的一系列状态
X = [] # 一组解
is_found = False # 全局终止标志
# 计算船的合法状态空间(二维)
def get_states(k): # 船准备跑第k趟
global n, m, x
if k%2==0: # 从左到右,只考虑原左岸人数
s1, s2 = n - sum(s[0] for s in x), n - sum(s[1] for s in x)
else: # 从右到左,只考虑原右岸人数(将船的历史状态累加可得!!!)
s1, s2 = sum(s[0] for s in x), sum(s[1] for s in x)
for i in range(s1 + 1):
for j in range(s2 + 1):
if 0 < i+j <= m and (i*j == 0 or i >= j):
yield [(-i,-j), (i,j)][k%2==0] # 生成船的合法状态
# 冲突检测
def conflict(k): # 船开始跑第k趟
global n, m, x
# 若船上载的人与上一趟一样(会陷入死循环!!!!)
if k > 0 and x[-1][0] == -x[-2][0] and x[-1][1] == -x[-2][1]:
return True
# 任何时候,船上传教士人数少于野人,或者无人,或者超载(计算船的合法状态空间时已经考虑到了。)
#if 0 < abs(x[-1][0]) < abs(x[-1][1]) or x[-1] == (0, 0) or abs(sum(x[-1])) > m:
# return True
# 任何时候,左岸传教士人数少于野人
if 0 < n - sum(s[0] for s in x) < n - sum(s[1] for s in x):
return True
# 任何时候,右岸传教士人数少于野人
if 0 < sum(s[0] for s in x) < sum(s[1] for s in x):
return True
return False # 无冲突
# 回溯法
def backtrack(k): # 船准备跑第k趟
global n, m, x, is_found
if is_found: return # 终止所有递归
if n - sum(s[0] for s in x) == 0 and n - sum(s[1] for s in x) == 0: # 左岸人数全为0
print(x)
is_found = True
else:
for state in get_states(k): # 遍历船的合法状态空间
x.append(state)
if not conflict(k):
backtrack(k+1) # 深度优先
x.pop() # 回溯
# 测试
backtrack(0)
效果图
解的解释,从上往下看:
一个结论
貌似只有满足m = n-1,此问题才有解。
更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
# Python
# 回溯法
# 子集树模板
# 野人与传教士问题
# Python编程实现从字典中提取子集的方法分析
# python判断一个集合是否为另一个集合的子集方法
# Python判断两个list是否是父子集关系的实例
# Python实现求一个集合所有子集的示例
# 如何基于python生成list的所有的子集
# python的自变量选择(所有子集回归
# 后退法
# 逐步回归)
# 左岸
# 船上
# 修道士
# 递归
# 进阶
# 操作技巧
# 相关内容
# 主程序
# 遍历
# 数据结构
# 这条
# 给大家
# 才有
# 这样一个
# 换了
# 人与
# 更多关于
# 岸边
# 想用
# 可得
相关文章:
北京的网站制作公司有哪些,哪个视频网站最好?
如何在云主机快速搭建网站站点?
如何基于PHP生成高效IDC网络公司建站源码?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
电脑免费海报制作网站推荐,招聘海报哪个网站多?
网站制作壁纸教程视频,电脑壁纸网站?
湖州网站制作公司有哪些,浙江中蓝新能源公司官网?
如何用y主机助手快速搭建网站?
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
金*站制作公司有哪些,金华教育集团官网?
建站三合一如何选?哪家性价比更高?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
如何高效利用亚马逊云主机搭建企业网站?
建站VPS能否同时实现高效与安全翻墙?
高防服务器租用指南:配置选择与快速部署攻略
如何选择高性价比服务器搭建个人网站?
ppt制作免费网站有哪些,ppt模板免费下载网站?
如何在IIS管理器中快速创建并配置网站?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
如何在香港免费服务器上快速搭建网站?
如何快速搭建二级域名独立网站?
建站之星微信建站一键生成小程序+多端营销系统
山东云建站价格为何差异显著?
制作宣传网站的软件,小红书可以宣传网站吗?
建站之星如何实现PC+手机+微信网站五合一建站?
如何选择网络建站服务器?高效建站必看指南
香港服务器WordPress建站指南:SEO优化与高效部署策略
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
网站代码制作软件有哪些,如何生成自己网站的代码?
如何用腾讯建站主机快速创建免费网站?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
广东企业建站网站优化与SEO营销核心策略指南
宝塔建站助手安装配置与建站模板使用全流程解析
在线制作视频的网站有哪些,电脑如何制作视频短片?
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
如何零基础开发自助建站系统?完整教程解析
青浦网站制作公司有哪些,苹果官网发货地是哪里?
哈尔滨网站建设策划,哈尔滨电工证查询网站?
相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?
如何在Golang中处理模块冲突_解决依赖版本不兼容问题
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
文字头像制作网站推荐软件,醒图能自动配文字吗?
深入理解Android中的xmlns:tools属性
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
高端智能建站公司优选:品牌定制与SEO优化一站式服务
深圳网站制作的公司有哪些,dido官方网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。