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中的XML库4Suite Server的介绍
Apr 14 Python
python学习笔记之列表(list)与元组(tuple)详解
Nov 23 Python
Django学习笔记之ORM基础教程
Mar 27 Python
Python使用while循环花式打印乘法表
Jan 28 Python
详解python调用cmd命令三种方法
Jul 08 Python
tensorflow 大于某个值为1,小于为0的实例
Jun 30 Python
python跨文件使用全局变量的实现
Nov 17 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 11 Python
Python之京东商品秒杀的实现示例
Jan 06 Python
Python爬虫进阶之Beautiful Soup库详解
Apr 29 Python
Python操作CSV格式文件的方法大全
Jul 15 Python
Python学习之异常中的finally使用详解
Mar 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中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
PHP新手NOTICE错误常见解决方法
2011/12/07 PHP
关于初学PHP时的知识积累总结
2013/06/07 PHP
laravel通过创建自定义artisan make命令来新建类文件详解
2017/08/17 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
JavaScript控制Session操作方法
2013/01/17 Javascript
jquery ajax jsonp跨域调用实例代码
2013/12/11 Javascript
类似php的js数组的in_array函数自定义方法
2013/12/27 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
jQuery向后台传入json格式数据的方法
2015/02/13 Javascript
js实现从中间开始往上下展开网页窗口的方法
2015/03/02 Javascript
基于javascript实现文字无缝滚动效果
2016/03/22 Javascript
基于Bootstrap的UI扩展 StyleBootstrap
2016/06/17 Javascript
纯前端JavaScript实现Excel IO案例分享
2016/08/26 Javascript
JS库之wow.js使用方法
2017/09/14 Javascript
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
js实现Tab选项卡切换效果
2020/07/17 Javascript
Koa2微信公众号开发之消息管理
2018/05/16 Javascript
layui layer select 选择被遮挡的解决方法
2019/09/21 Javascript
Python创建文件和追加文件内容实例
2014/10/21 Python
python中list循环语句用法实例
2014/11/10 Python
Python功能键的读取方法
2015/05/28 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
CSS3实现渐变背景兼容问题
2020/05/06 HTML / CSS
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
德国家具折扣店:POCO
2020/02/28 全球购物
创联软件面试题笔试题
2012/10/07 面试题
城市轨道专业个人求职信范文
2013/09/23 职场文书
专科应届毕业生求职信
2014/06/04 职场文书
询价采购方案
2014/06/09 职场文书
寒暑假实习证明书模板
2014/11/29 职场文书
财务统计员岗位职责
2015/04/14 职场文书
高中历史教学反思
2016/02/19 职场文书
opencv读取视频并保存图像的方法
2021/06/04 Python
Mybatis是这样防止sql注入的
2021/12/06 Java/Android
讲解Python实例练习逆序输出字符串
2022/05/06 Python