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编写暴力破解FTP密码小工具
Nov 19 Python
浅谈Python 集合(set)类型的操作——并交差
Jun 30 Python
Python随机数用法实例详解【基于random模块】
Apr 18 Python
Mac中Python 3环境下安装scrapy的方法教程
Oct 26 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
Jan 15 Python
python使用pandas处理大数据节省内存技巧(推荐)
May 05 Python
python3.6 如何将list存入txt后再读出list的方法
Jul 02 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
Jun 28 Python
Python ConfigParser模块的使用示例
Oct 12 Python
如何利用python检测图片是否包含二维码
Oct 15 Python
Python模拟登录requests.Session应用详解
Nov 17 Python
opencv深入浅出了解机器学习和深度学习
Mar 17 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 PDO中文乱码解决办法
2009/07/20 PHP
php 生成随机验证码图片代码
2010/02/08 PHP
php的字符串用法小结
2010/06/08 PHP
PHP 无限分类三种方式 非函数的递归调用!
2011/08/26 PHP
PHP中图片等比缩放的实例
2013/03/24 PHP
PHP命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
PHP数组和explode函数示例总结
2015/05/08 PHP
thinkPHP5.0框架URL访问方法详解
2017/03/18 PHP
javascript 对象的定义方法
2007/01/10 Javascript
[HTML/CSS/Javascript]WWTJS
2007/09/25 Javascript
javascript使用eval或者new Function进行语法检查
2010/10/16 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
JavaScript学习心得之概述
2015/01/20 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
2016/09/21 Javascript
jQGrid Table操作列中点击【操作】按钮弹出按钮层的实现代码
2016/12/05 Javascript
简单实现AngularJS轮播图效果
2020/04/10 Javascript
Vue项目中跨域问题解决方案
2018/06/05 Javascript
原生JS+HTML5实现的可调节写字板功能示例
2018/08/30 Javascript
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
小程序登录/注册页面设计的实现代码
2019/05/24 Javascript
JavaScript canvas绘制圆弧与圆形
2020/02/18 Javascript
手把手教你实现 Promise的使用方法
2020/09/02 Javascript
python unittest实现api自动化测试
2018/04/04 Python
python去掉 unicode 字符串前面的u方法
2018/10/21 Python
Python如何获得百度统计API的数据并发送邮件示例代码
2019/01/27 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
python3字符串操作总结
2019/07/24 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
浅谈Python3识别判断图片主要颜色并和颜色库进行对比的方法
2019/10/25 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
Python实现列表中非负数保留,负数转化为指定的数值方式
2020/06/04 Python
css3的@media属性实现页面响应式布局示例代码
2014/02/10 HTML / CSS
The North Face意大利官网:服装、背包和鞋子
2020/06/17 全球购物
人事主管岗位职责范本
2013/12/04 职场文书
党干部专题民主生活会对照检查材料思想汇报
2014/10/06 职场文书
安全教育培训心得体会
2016/01/15 职场文书