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中使用lambda高效操作列表的教程
Apr 24 Python
使用python加密自己的密码
Aug 04 Python
浅析Python的web.py框架中url的设定方法
Jul 11 Python
Python Socket使用实例
Dec 18 Python
python3 实现验证码图片切割的方法
Dec 07 Python
python感知机实现代码
Jan 18 Python
pandas的连接函数concat()函数的具体使用方法
Jul 09 Python
python 实现两个npy档案合并
Jul 01 Python
Python自动巡检H3C交换机实现过程解析
Aug 14 Python
Python连接mysql方法及常用参数
Sep 01 Python
pytest fixtures装饰器的使用和如何控制用例的执行顺序
Jan 28 Python
PyTorch中的torch.cat简单介绍
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概述.
2006/10/09 PHP
自动跳转中英文页面
2006/10/09 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
Ext javascript建立超链接,进行事件处理的实现方法
2009/03/22 Javascript
JavaScript加强之自定义callback示例
2013/09/21 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
动态加载js的方法汇总
2015/02/13 Javascript
浅析js中substring和substr的方法
2015/11/09 Javascript
jQuery复制节点用法示例(clone方法)
2016/09/08 Javascript
BootStrap Table对前台页面表格的支持实例讲解
2016/12/22 Javascript
详解nodejs中的process进程
2017/03/19 NodeJs
node实现定时发送邮件的示例代码
2017/08/26 Javascript
JavaScript中如何判断一个值的类型
2017/09/15 Javascript
详解如何将 Vue-cli 改造成支持多页面的 history 模式
2017/11/20 Javascript
js解决软键盘遮挡输入框的问题分享
2017/12/19 Javascript
微信小程序人脸识别功能代码实例
2019/05/07 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
vue中v-model对select的绑定操作
2020/08/31 Javascript
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
Python设计模式之建造者模式实例详解
2019/01/17 Python
Python使用mongodb保存爬取豆瓣电影的数据过程解析
2019/08/14 Python
Python matplotlib画曲线例题解析
2020/02/07 Python
pytorch ImageFolder的覆写实例
2020/02/20 Python
不到20行实现Python代码即可制作精美证件照
2020/04/24 Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
2020/06/03 Python
Keras 加载已经训练好的模型进行预测操作
2020/06/17 Python
python与js主要区别点总结
2020/09/13 Python
Lookfantastic澳大利亚官网:英国知名美妆购物网站
2021/01/07 全球购物
EJB面试题
2015/07/28 面试题
电子技术专业中专生的自我评价
2013/12/17 职场文书
《狐假虎威》教学反思
2014/02/07 职场文书
2015年乡镇统计工作总结
2015/04/22 职场文书
摘录式读书笔记
2015/07/01 职场文书
Python 如何安装Selenium
2021/05/06 Python
80行代码写一个Webpack插件并发布到npm
2021/05/24 Javascript