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
在Python3中初学者应会的一些基本的提升效率的小技巧
Mar 31 Python
Python中random模块用法实例分析
May 19 Python
Python正则表达式匹配中文用法示例
Jan 17 Python
Python调用C语言的方法【基于ctypes模块】
Jan 22 Python
Python实现中一次读取多个值的方法
Apr 22 Python
python3获取当前文件的上一级目录实例
Apr 26 Python
python顺序执行多个py文件的方法
Jun 29 Python
django和vue实现数据交互的方法
Aug 21 Python
python随机生成库faker库api实例详解
Nov 28 Python
Python matplotlib 绘制双Y轴曲线图的示例代码
Jun 12 Python
Python高并发解决方案实现过程详解
Jul 31 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设计模式 Singleton(单例模式)
2011/06/26 PHP
jQuery 使用手册(五)
2009/09/23 Javascript
jquery 模式对话框终极版实现代码
2009/09/28 Javascript
js几个验证函数代码
2010/03/25 Javascript
jQuery中addClass()方法用法实例
2015/01/05 Javascript
js实现点击图片改变页面背景图的方法
2015/02/28 Javascript
简介JavaScript中getUTCMonth()方法的使用
2015/06/10 Javascript
Node.js 应用跑得更快 10 个技巧
2016/04/03 Javascript
JS实现动态表格的添加,修改,删除功能(推荐)
2016/06/15 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
2016/08/05 Javascript
简单实现js选项卡切换效果
2017/02/09 Javascript
jquery获取transform里的值实现方法
2017/12/12 jQuery
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
vue实现节点增删改功能
2019/09/26 Javascript
vue实现计步器功能
2019/11/01 Javascript
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
梯度下降法介绍及利用Python实现的方法示例
2017/07/12 Python
Queue 实现生产者消费者模型(实例讲解)
2017/11/13 Python
Python collections模块使用方法详解
2019/08/28 Python
Django学习之文件上传与下载
2019/10/06 Python
python bluetooth蓝牙信息获取蓝牙设备类型的方法
2019/11/29 Python
python中for in的用法详解
2020/04/17 Python
你应该知道的Python3.6、3.7、3.8新特性小结
2020/05/12 Python
美国最大的家庭鞋类零售商之一:Shoe Carnival
2017/10/06 全球购物
《再见了,亲人》教学反思
2014/02/26 职场文书
自我鉴定标准格式
2014/03/19 职场文书
关工委先进个人事迹材料
2014/05/23 职场文书
提拔干部考察材料
2014/05/26 职场文书
单位实习工作证明怎么写
2014/11/02 职场文书
小学感恩节活动总结
2015/03/24 职场文书
开学第一周总结
2015/07/16 职场文书
2015年教师个人业务工作总结
2015/10/23 职场文书
九年级语文教学反思
2016/03/03 职场文书
你知道Java Spring的两种事务吗
2022/03/16 Java/Android
mysql使用 not int 子查询隐含陷阱
2022/04/12 MySQL