Python基于回溯法子集树模板解决野人与传教士问题示例


Posted in Python onSeptember 11, 2017

本文实例讲述了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)

效果图

Python基于回溯法子集树模板解决野人与传教士问题示例

解的解释,从上往下看:

Python基于回溯法子集树模板解决野人与传教士问题示例

一个结论

貌似只有满足m = n-1,此问题才有解

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
对于Python装饰器使用的一些建议
Jun 03 Python
Python打造出适合自己的定制化Eclipse IDE
Mar 02 Python
Python中关于Sequence切片的下标问题详解
Jun 15 Python
Python3实现的字典遍历操作详解
Apr 18 Python
使用python进行文本预处理和提取特征的实例
Jun 05 Python
python 读取.csv文件数据到数组(矩阵)的实例讲解
Jun 14 Python
通过Python模块filecmp 对文件比较的实现方法
Jun 29 Python
2019 Python最新面试题及答案16道题
Apr 11 Python
Django 外键的使用方法详解
Jul 19 Python
python滑块验证码的破解实现
Nov 10 Python
python多进程使用函数封装实例
May 02 Python
Python使用pycharm导入pymysql教程
Sep 16 Python
Python 高级专用类方法的实例详解
Sep 11 #Python
Python 异常处理的实例详解
Sep 11 #Python
Python基于回溯法子集树模板解决马踏棋盘问题示例
Sep 11 #Python
Python基于回溯法子集树模板解决找零问题示例
Sep 11 #Python
详解 Python 与文件对象共事的实例
Sep 11 #Python
Python 私有函数的实例详解
Sep 11 #Python
Python模拟用户登录验证
Sep 11 #Python
You might like
php判断字符以及字符串的包含方法属性
2008/08/30 PHP
ThinkPHP中的三大自动简介
2014/08/22 PHP
PHP使用PDO调用mssql存储过程的方法示例
2017/10/07 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
利用PHP计算有多少小于当前数字的数字方法示例
2020/08/26 PHP
用 JavaScript 迁移目录
2006/12/18 Javascript
非阻塞动态加载javascript广告实现代码
2010/11/17 Javascript
editable.js 基于jquery的表格的编辑插件
2011/10/24 Javascript
给artDialog 5.02 增加ajax get功能详细介绍
2012/11/13 Javascript
JQuery each()函数如何优化循环DOM结构的性能
2012/12/10 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
地址栏传递中文参数乱码在js里用escape转码
2013/08/28 Javascript
Jquery的hide及toggle方法让超链接慢慢消失
2013/09/06 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
简介JavaScript中Boolean.toSource()方法的使用
2015/06/05 Javascript
jQuery 自定义下拉框(DropDown)附源码下载
2016/07/22 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
基于node.js的fs核心模块读写文件操作(实例讲解)
2017/09/10 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
详解html-webpack-plugin插件(用法总结)
2018/09/12 Javascript
vue移动端html5页面根据屏幕适配的四种解决方法
2018/10/19 Javascript
js回调函数仿360开机
2019/12/26 Javascript
Vue实现兄弟组件间的联动效果
2020/01/21 Javascript
weui上传多图片,压缩,base64编码的示例代码
2020/06/22 Javascript
[01:11:02]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
[01:14]2019完美世界城市挑战赛(秋季赛)全国总决赛精彩花絮
2020/01/08 DOTA
python分块读取大数据,避免内存不足的方法
2018/12/10 Python
应届毕业生自我鉴定范文
2013/12/27 职场文书
庆中秋节主题活动方案
2014/02/03 职场文书
中学生个人自我评价
2014/02/06 职场文书
军训自我鉴定范文
2014/02/13 职场文书
防灾减灾日活动总结
2014/08/26 职场文书
世界环境日活动总结
2015/02/11 职场文书
2015毕业生简历自我评价
2015/03/02 职场文书
《我在为谁工作》:工作的质量往往决定生活的质量
2019/12/27 职场文书
vue如何清除浏览器历史栈
2022/05/25 Vue.js