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中装饰器的一个妙用
Feb 08 Python
ubuntu系统下 python链接mysql数据库的方法
Jan 09 Python
利用pyinstaller或virtualenv将python程序打包详解
Mar 22 Python
Python基于回溯法解决01背包问题实例
Dec 06 Python
tensorflow 获取模型所有参数总和数量的方法
Jun 14 Python
python将list转为matrix的方法
Dec 12 Python
python使用suds调用webservice接口的方法
Jan 03 Python
python实现画五角星和螺旋线的示例
Jan 20 Python
PyCharm搭建Spark开发环境实现第一个pyspark程序
Jun 13 Python
python实现的读取网页并分词功能示例
Oct 29 Python
Python代码需要缩进吗
Jul 01 Python
pytorch 实现变分自动编码器的操作
May 24 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继承的一个应用
2011/09/06 PHP
php中的boolean(布尔)类型详解
2013/10/28 PHP
js Event对象的5种坐标
2011/09/12 Javascript
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
IE8的JavaScript点击事件(onclick)不兼容的解决方法
2013/11/22 Javascript
jQuery中Dom的基本操作小结
2014/01/23 Javascript
jQuery实现延迟跳转的方法
2015/06/05 Javascript
使用AngularJS中的SCE来防止XSS攻击的方法
2015/06/18 Javascript
JS原型对象的创建方法详解
2016/06/16 Javascript
JS数组去掉重复数据只保留一条的实现代码
2016/08/11 Javascript
node网页分段渲染详解
2016/09/05 Javascript
require.js+vue开发微信上传图片组件
2016/10/27 Javascript
js原生实现FastClick事件的实例
2016/11/20 Javascript
微信小程序 UI与容器组件总结
2017/02/21 Javascript
JS实现加载和读取XML文件的方法详解
2017/04/24 Javascript
JS获取鼠标坐标并且根据鼠标位置不同弹出不同内容
2017/06/12 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
angularJS实现不同视图同步刷新详解
2018/10/09 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
layui table 表格模板按钮的实例代码
2019/09/21 Javascript
JS事件循环机制event loop宏任务微任务原理解析
2020/08/04 Javascript
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
python代码制作configure文件示例
2014/07/28 Python
使用Python操作Elasticsearch数据索引的教程
2015/04/08 Python
浅谈Python单向链表的实现
2015/12/24 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
详解Python在使用JSON时需要注意的编码问题
2019/12/06 Python
pandas apply多线程实现代码
2020/08/17 Python
css和css3弹性盒模型实现元素宽度(高度)自适应
2019/05/15 HTML / CSS
Araks官网:纽约内衣品牌
2020/10/15 全球购物
OnePlus加拿大官网:中国国际化手机品牌
2020/10/13 全球购物
服务承诺书怎么写
2014/05/24 职场文书
毕业典礼致辞
2015/07/29 职场文书
Python图片验证码降噪和8邻域降噪
2021/08/30 Python
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏