传教士和野人问题(Missionaries   and   Cannibals)               

  这是一个经常在有关讨论人工智能的书籍中见到的问题,   其描述是这样的:   
  有N个传教士和N个野人来到河边渡河,   河岸有一条船,   每次至多可供k人乘渡。问传教士为了安全起见,   应如何规划摆渡方案,   使得任何时刻,   河两岸以及船上的野人数目总是不超过传教士的数目(否则不安全,   传教士有可能被野人吃掉)。即求解传教士和野人从左岸全部摆渡到右岸的过程中,   任何时刻满足M(传教士数)≥C(野人数)和M+C≤k的摆渡方案。

  我们此处举例   ,   只讨论N为3、k为2的乘渡问题,   这样传教士和野人问题的描述就具体为如下:   
  三个传教士与三个野人来到河边,   有一条船可供一人或两人乘渡,   问题是如何用这条船渡河才能使得河的任一岸上野人的数目总不超过传教士的数目(当然,   如果某一岸上只有野人而没有传教士是允许的)。

  我们用一个三元组(m   c   b)来表示河岸上的状态,   其中m、c分别代表某一岸上传教士与野人的数目,   b=1表示船在这一岸,   b=0则表示船不在。   
  设N=3,   k=2,   则给定的问题可用下图表示,   图中L和R表示左岸和右岸,   B=1或0分别表示有船或无船。         
约束条件是:   两岸上M≥C,   船上M+C≤2。   
  我们采用产生式系统来解决这一问题。由于传教士与野人的总数目是一常数,   所以只要表示出河的某一岸上的情况就可以了,   为方便起见,   我们选择传教士与野人开始所在的岸为所要表示的岸,   并称其为左岸,   另一岸称为右岸。但显然仅用描述左岸的三元组描述就足以表示出整个情况,   因此必须十分重视选择较好的问题表示法。以后的讨论还可以看到高效率的问题求解过程与控制策略有关,   合适的控制策略可缩小状态空间的搜索范围,   提高求解的效率。因而问题的初始状态是(3   3   1),   目标状态是(0   0   0)。

  (1)   综合数据库:   用三元组表示,   即   (ML,   CL,   BL),   其中0≤ML,   CL≤3,   BL∈{0,   1}   
此时问题述简化为   (3,   3,   1)®   (0,   0,   0)             
N=3的M-C问题,   状态空间的总状态数为4×4×2=32,   根据约束条件的要求,   可以看出只有20个合法状态。再进一步分析后,   又发现有4个合法状态实际上是不可能达到的。因此实际的问题空间仅由16个状态构成。下表列出分析的结果:   
    (ML,   CL,   BL)   (ML,   CL,   BL)   
    (0   0   1)达不到   (0   0   0)   
    (0   1   1)   (0   1   0)   
    (0   2   1)   (0   2   0)   
    (0   3   1)   (0   3   0)达不到   
    (1   0   1)不合法   (1   0   0)不合法   
    (1   1   1)   (1   1   0)   
    (1   2   1)不合法   (1   2   0)不合法   
    (1   3   1)不合法   (1   3   0)不合法   
    (2   0   1)不合法   (2   0   0)不合法   
    (2   1   1)不合法   (2   1   0)不合法   
    (2   2   1)   (2   2   0)   
    (2   3   1)不合法   (2   3   0)不合法   
    (3   0   1)达不到   (3   0   0)   
    (3   1   1)   (3   1   0)   
    (3   2   1)   (3   2   0)   
    (3   3   1)   (3   3   0)达不到    

  (2)   规则集合:   由摆渡操作组成。该问题主要有两种操作:   pmc操作(规定为从左岸划向右岸)和qmc操作(从右岸划向左岸)。每次摆渡操作,   船上人数有五种组合,   因而组成有10条规则的集合。下面定义的规则前5条为pmc操作(从左岸划向右岸),   后5条为qmc操作(从右岸划向左岸)。   
    if   (ML,   CL,   BL=1)   then   (ML-1,   CL,   BL-1);   (p10操作)   
    if   (ML,   CL,   BL=1)   then   (ML,   CL-1,   BL-1);   (p01操作)   
    if   (ML,   CL,   BL=1)   then   (ML-1,   CL-1,   BL-1);   (p11操作)   
    if   (ML,   CL,   BL=1)   then   (ML-2,   CL,   BL-1);   (p20操作)   
    if   (ML,   CL,   BL=1)   then   (ML,   CL-2,   BL-1);   (p02操作)

    if   (ML,   CL,   BL=0)   then   (ML+1,   CL,   BL+1);   (q10操作)   
    if   (ML,   CL,   BL=0)   then   (ML,   CL+1,   BL+1);   (q01操作)   
    if   (ML,   CL,   BL=0)   then   (ML+1,   CL+1,   BL+1);   (q11操作)   
    if   (ML,   CL,   BL=0)   then   (ML+2,   CL,   BL+1);   (q20操作)   
    if   (ML,   CL,   BL=0)   then   (ML,   CL+2,   BL+1);   (q02操作)

  (3)   初始和目标状态:   即(3,   3,   1)和(0,   0,   0)。和八数码游戏的问题一样,   建立了产生式系统描述之后,   就可以通过控制策略,   对状态空间进行搜索,   求得一个摆渡操作序列,   使其实现目标状态。

  在讨论用产生式系统求解问题时,   有时引入状态空间图的概念很有帮助。状态空间图是一个有向图,   其节点可表示问题的各种状态(综合数据库),   节点之间的弧线代表一些操作(产生式规则),   它们可把一种状态导向另一种状态。这样建立起来的状态空间图,   描述了问题所有可能出现的状态及状态和操作之间的关系,   因而可以较直观地看出问题的解路径及其性质。实际上只有问题空间规模较小的问题才可能作出状态空间图,   例如N=3的M-C问题,的其状态空间图如下图所示,   此时采用的控制策略为顺序选取规则。由于每个摆渡操作都有对应的逆操作,   即pmc对应qmc,   所以该图也可表示成具有双向弧的形式。           
从状态空间图看出解序列相当之多,   但最短解序列只有4个,   例如   
  (p11、q10、p02、q01、p20、q11、p20、q01、p02、q01、p02)、   
  (p11、q10、p02、q01、p02、q11、p20、q01、p02、q10、p11)、   
  (p02、q01、p02、q01、p20、q11、p20、q01、p02、q01、p02)、   
  (p02、q01、p02、q01、p20、q11、p20、q01、p02、q10、p11),   
均由11次摆渡操作构成。若给定其中任意两个状态分别作为初始和目标状态,   就立即可找出对应的解序列来。在一般情况下,   求解过程就是对状态空间搜索出一条解路径的过程。

  以上这个例子说明了建立产生式系统描述的过程,   这也就是所谓问题的表示。对问题表示的好坏,   往往对求解过程的效率有很大影响。一种较好的表示法会简化状态空间和规则集表示,   例如八数码问题中,   如用将牌移动来描述规则,   则8块将牌就有32条的规则集,   显然用空格走步来描述就简单得多。又如M-C问题中,   用3×2的矩阵给出左、右岸的情况来表示一种状态当然可以,   但显然仅用描述左岸的三元组描述就足以表示出整个情况。

  如果我们用micro-PROLOG的SIMPLE语法来进行编程以实现求解乘渡的方案,   则根据你给出的询问是which(或all)还是is能给出全部摆渡方案或一个摆渡方案。下面的程序由于M-C关系的第一个语句用了回溯控制“/”,   所以实际上只能得出一个乘渡方案。             
下面我们进行程序设计:

  我们把满足条件的状态称为安全状态,   首先要定义出安全状态,   通过对问题的分析,   不难得出只有满足以下条件之一的状态才是安全的(以左岸为例):   
    1.   传教士与野人的数目相等;   
    2.   传教士都在左岸;   
    3.   传教士都不在左岸。

  safe关系的三个句子分别定义了这三种不同的情况,   其中safe的第一个变元表示传教士的数目,   第二个变元表示野人的数目。   
从一个状态到另一状态的转换,   通过关系Rule来完成,   它有两个句子,   分别描述了从左岸到右岸和从右岸到左岸的状态转换。Rule的两个变元都是三元组,   第一个三元组表示当前状态,   第二个三元组是得到的下一个满足条件的状态。

  关系M-C通过调用Rule来求解出传教士与野人的过河方案,   它有四个变元,   第一个变元是当前状态,   调用时用初始状态代入,   第二个变元是目标状态,   第三个变元是一个中间变量,   它以表的形式记录到目前为止所达到的状态,   调用的初始值是只含初始状态一个元素的表,   第四个变元也是一个表,   求解结束时,   它以逆序形式得到解的路径。

转自:http://www.cnblogs.com/gw811/archive/2012/10/12/2722035.html

转载于:https://www.cnblogs.com/noodleutopia/p/4348800.html

【转】传教士和野人问题(Missionaries and Cannibals)相关推荐

  1. 野人与传教士过河java_传教士和野人过河(经典MC问题)

    这个问题本来是<人工智能技术导论>第三章的课后题,今天上午考试正巧考到了这道题,要我们画状态转换图,我之前思考过一点,所以写出的状态表示应该没有问题,但这些状态太多了.......,十来种 ...

  2. 【算法】传教士和野人问题

    有N个传教士和N个野人来到河边准备渡河,河岸有一条船,每次至多可供k人乘渡.问传教士为了安全起见,应如何规划摆渡方案,使得任何时刻,在河的两岸以及船上的野人数目总是不超过传教士的数目.即求解传教士和野 ...

  3. AI传教士和野人渡河问题-实验报告

    一 题目要求: 设有m个传教士和n个野人来到河边,打算乘一只船从左岸渡到右岸去,该船每次最多载3人.在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉.他们怎样才能用这条船安全地把所有人 ...

  4. 人工智能实验二——prolog语言求解渡河问题(传教士和野人渡河,农夫渡河问题)实现详解

    农夫渡河问题求解 这两个问题都是渡河问题,思路和方式是一样的:给出求解Prolog代码: 问题描述 一个农夫带着一匹狼.一只羊.一颗白菜要过河, 只有一条船而且 农夫每次最多只能带一个动物或物品过河, ...

  5. C语言版,传教士与野人渡河问题,使用深度优先搜索法求解(DFS),变态版,随便输入人数和船的最大载人数,人工智能经典题目,简单易懂,注释到位,没有bug

    目录 一.问题描述 二.迟来的代码 运行截图 三.简单分析 一.问题描述 有n个传教士和n个野人准备渡河,但只有一条能容纳c个人的小船,为了防止野人侵犯传教士,要求无论在何处,传教士的人数不得少于野人 ...

  6. 传教士与野人过河问题 人工智能实验算法

    问题描述 有 N 个传教士和 N 个野人来到河边渡河,河岸有一条船,每次至多可供 k 人乘渡.问:传教士为了安全起见,应如何规划摆渡方案,使得任何时刻, 河两岸以及船上的野人数目总是不超过传教士的数目 ...

  7. 【C++】人工智能实验一 猴子摘香蕉/传教士与野人(含完整代码与状态迁移图)

    文章目录 一.猴子摘香蕉问题 1.问题描述 2.解题思路 3.实验结果及分析 实验结果一 实验结果二 实验结果三 4.实验结果 5.实验代码 二.传教士(牧师)与野人问题 1.问题描述 2.实验步骤 ...

  8. 传教士与野人过河问题(A*搜索 C++)

    传教士与野人过河问题: 任意时刻,左岸.右岸.船上如果传教士人数少于野人人数,传教士就会被野人吃掉.当然野人会划船.传教士人数为0也是可以的. 启发函数 f=g+h.  g当前结点所在解空间树的深度. ...

  9. python深度优先搜索传教士和野人_传教士和野人问题解题思路

    传教士和野人渡河问题 刘宪国050422023 野人过河问题描述如下:有三个传教士和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于传教士的人数,那么传教士就会有危险 ...

  10. 传教士与野人问题的C++搜索实现

      人工智能引论课第一次作业:使用搜索解决传教士与野人问题. 题目要求   河岸的一侧有野人与传教士各 m m m个,有一条能容纳 n n n个人的船.传教士与野人都会划船,现在要求任何情况下,野人数 ...

最新文章

  1. 计算机专业课 复习,计算机专业课复习经验:各个突破、全面掌握
  2. 苹果App Icon的问题
  3. python 文件操作 os.mkdir()函数
  4. 大数据WEB阶段(十三)JSP(一)JSP基础、JSP指令详解、四大域九大隐式对象总结
  5. 一道Python面试题
  6. CCIE理论-第十篇-IPV6 VS IPV4(带你们看看U.S.A的ISP的设备)
  7. Java Script 学习笔记 -- Ajax
  8. Eclipse和debug的一些快捷键:F8一直执行到下一个断点。
  9. python读取sas数据集_利用Python获取SAS和R自带数据集
  10. Python入门最完整的基础知识大全【纯干货,建议收藏】
  11. unity3D 移动开发代码优化
  12. 雷达线性调频信号的脉冲压缩处理
  13. MySQL5.5安装步骤
  14. linux默认的分区是fat,linux下开机自动挂载FAT分区
  15. ECMAScript6 Proxy和Reflect 对象操作拦截以及自定义
  16. CAD中XCLIP命令的使用及图块和参照编辑
  17. nginx 监听多个端口 80和81
  18. 武汉市10月双软认定好处、认定条件及9月认定名单公示
  19. JDK11占比第一?
  20. html内容页上一页下一页,帝国CMS内容页增加内容分页上一页标签功能!

热门文章

  1. vue去除input在360兼容模式下删除图标
  2. AT32 XMC驱动PC卡/CF卡
  3. 苹果专用视频播放器Elmedia Video Player pro
  4. 组台式计算机配置清单整套,组装台式电脑配置清单有哪些 台式电脑什么配置好...
  5. 信息检索1.3.学术搜索引擎--谷歌学术搜索引擎
  6. 十三天学会C语言笔记
  7. 淘宝6.18叠猫猫赚猫币自动生成
  8. Go开源说第十七期 分布式事务DTM
  9. 搜索引擎优化(SEO) 基础常识
  10. 怎样批量修改图片大小?