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中os和shutil模块实用方法集锦
May 13 Python
python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 Python
解决Python中由于logging模块误用导致的内存泄露
Apr 23 Python
Python中Continue语句的用法的举例详解
May 14 Python
在Python的Flask中使用WTForms表单框架的基础教程
Jun 07 Python
python解决网站的反爬虫策略总结
Oct 26 Python
使用python在本地电脑上快速处理数据
Jun 22 Python
Django中日期处理注意事项与自定义时间格式转换详解
Aug 06 Python
python实现将视频按帧读取到自定义目录
Dec 10 Python
python异常处理try except过程解析
Feb 03 Python
python如何使用代码运行助手
Jul 03 Python
python excel多行合并的方法
Dec 09 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支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
Redis构建分布式锁
2017/03/28 PHP
PHP基于自定义函数实现的汉字转拼音功能实例
2017/09/30 PHP
Laravel框架实现超简单的分页效果示例
2019/02/08 PHP
jquery.lazyload  实现图片延迟加载jquery插件
2010/02/06 Javascript
cookie中的path与domain属性详解
2013/12/18 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
2014/10/17 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
2015/05/09 Javascript
JavaScript中的 attribute 和 jQuery中的 attr 方法浅析
2017/01/04 Javascript
jquery实现表单获取短信验证码代码
2017/03/13 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
vue2.0使用swiper组件实现轮播效果
2017/11/27 Javascript
vuejs 动态添加input框的实例讲解
2018/08/24 Javascript
jquery图片预览插件实现方法详解
2019/07/18 jQuery
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
[01:03:42]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[51:53]完美世界DOTA2联赛决赛日 Inki vs LBZS 第二场 11.08
2020/11/10 DOTA
使用PYTHON创建XML文档
2012/03/01 Python
Python中的条件判断语句与循环语句用法小结
2016/03/21 Python
Python selenium如何设置等待时间
2016/09/15 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
python 随机生成10位数密码的实现代码
2019/06/27 Python
Python类如何定义私有变量
2020/02/03 Python
python内打印变量之%和f的实例
2020/02/19 Python
ONLY瑞典官网:世界知名服装品牌
2018/06/19 全球购物
英国首屈一指的票务公司:See Tickets
2019/05/11 全球购物
PHP两种查询函数array/row的区别
2013/06/03 面试题
软件配置管理有什么好处
2015/04/15 面试题
兴趣小组活动总结
2014/05/05 职场文书
大学生翘课检讨书范文
2014/10/06 职场文书
2014年前台个人工作总结
2014/11/14 职场文书
捐款通知怎么写
2015/04/24 职场文书
个人欠条范本
2015/07/03 职场文书
golang生成vcf通讯录格式文件详情
2022/03/25 Golang