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代码真的很爽
Aug 26 Python
Python使用scrapy采集时伪装成HTTP/1.1的方法
Apr 08 Python
Python selenium实现微博自动登录的示例代码
May 16 Python
tensorflow实现加载mnist数据集
Sep 08 Python
对python 读取线的shp文件实例详解
Dec 22 Python
详解python的四种内置数据结构
Mar 19 Python
python 图像的离散傅立叶变换实例
Jan 02 Python
手动安装python3.6的操作过程详解
Jan 13 Python
pandas 强制类型转换 df.astype实例
Apr 09 Python
浅析Python中字符串的intern机制
Oct 03 Python
python中用ggplot绘制画图实例讲解
Jan 26 Python
Python各协议下socket黏包问题原理
Apr 12 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 zend解密软件绿色版测试可用
2008/04/14 PHP
php读取数据库信息的几种方法
2008/05/24 PHP
php实现每日签到功能
2018/11/29 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
新页面打开实际尺寸的图片
2006/08/25 Javascript
jquery中ajax学习笔记4
2011/10/16 Javascript
js 高效去除数组重复元素示例代码
2013/12/19 Javascript
js实现文字向上轮播功能
2017/01/13 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
nodejs个人博客开发第一步 准备工作
2017/04/12 NodeJs
详解Webstorm 新建.vue文件支持高亮vue语法和es6语法
2017/10/26 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
[02:10]DOTA2 TI10勇士令状玩法及不朽Ⅰ展示:焕新世界,如你所期
2020/05/29 DOTA
Python 变量类型及命名规则介绍
2013/06/08 Python
Python isinstance函数介绍
2015/04/14 Python
Python中的日期时间处理详解
2016/11/17 Python
Python入门_浅谈for循环、while循环
2017/05/16 Python
浅析Python中return和finally共同挖的坑
2017/08/18 Python
详解Django之admin组件的使用和源码剖析
2018/05/04 Python
Python递归调用实现数字累加的代码
2020/02/25 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
2020/03/13 Python
基于django2.2连oracle11g解决版本冲突的问题
2020/07/02 Python
Python scrapy爬取小说代码案例详解
2020/07/09 Python
Python在字符串中处理html和xml的方法
2020/07/31 Python
Python调用高德API实现批量地址转经纬度并写入表格的功能
2021/01/12 Python
初探CSS3中的calc()功能
2015/07/14 HTML / CSS
2014社区三八妇女节活动方案
2014/03/30 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
社区党员公开承诺书
2014/08/30 职场文书
党的群众路线教育实践活动剖析材料
2014/09/30 职场文书
借名购房协议书范本
2014/10/06 职场文书
销售口号霸气押韵
2015/12/24 职场文书
2016见义勇为事迹材料汇总
2016/03/01 职场文书
python 实现图片特效处理
2022/04/03 Python
SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法
2022/07/07 Java/Android