传教士与野人过河问题

简介:

360公司 2012年校园招聘会笔试题算法题

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

 
本文转自 K1two2 博客园博客,原文链接:http://www.cnblogs.com/k1two2/p/4975505.html   ,如需转载请自行联系原作者
相关文章
|
3月前
|
数据采集 前端开发 测试技术
Selenium中定位元素的9种方法
在Selenium中,定位页面元素是自动化测试和网页爬虫的基础。常用的9种元素定位方法包括:ID、Name、Class Name、Tag Name、CSS Selector、XPath、Link Text、Partial Link Text,以及XPath和CSS选择器的组合使用。每种方法各有优劣,建议根据页面的具体情况和元素的属性选择最合适的方法,并使用显式等待确保元素可用。
674 5
|
8月前
|
机器学习/深度学习 自然语言处理 监控
利用机器学习进行情感分析:技术详解与实践
【5月更文挑战第13天】本文探讨了利用机器学习进行情感分析的方法,包括技术原理、常用算法和实践应用。情感分析涉及文本预处理(如清洗、分词和去除停用词)、特征提取(如词袋模型、TF-IDF和Word2Vec)及分类器训练(如朴素贝叶斯、SVM和RNN/LSTM)。常见情感分析算法有朴素贝叶斯、支持向量机和深度学习模型。实践中,情感分析应用于社交媒体监控、产品评论分析等领域。通过本文,读者可了解情感分析的基础知识及其应用价值。
1031 2
|
5月前
|
存储 关系型数据库 MySQL
MySQL 上亿大表,如何深度优化?
【8月更文挑战第11天】随着大数据时代的到来,MySQL 作为广泛使用的关系型数据库管理系统,经常需要处理上亿级别的数据。当数据量如此庞大时,如何确保数据库的查询效率、稳定性和可扩展性,成为了一个亟待解决的问题。本文将围绕 MySQL 上亿大表的深度优化,分享一系列实用的技术干货,帮助你在工作和学习中应对挑战。
626 1
|
8月前
|
关系型数据库 MySQL 数据库
【MySQL】如何使用图形化界面DataGrip操作数据库
【MySQL】如何使用图形化界面DataGrip操作数据库
248 0
|
6月前
|
XML 数据挖掘 API
数据为王!深度挖掘天猫商品详情接口,赋能电商运营新策略
**天猫商品详情接口摘要** - 开放平台API,获取商品标题、价格、描述、销量等信息。 - 支持多语言,用于生成详情页、数据分析、营销策略、竞品分析和购物决策。 - 注册授权,获取AppKey和AppSecret,参照文档构建请求。 - 发送GET/POST请求,处理JSON或XML响应数据。 - 助力自动化运营、提升效率和竞争力,对商家和消费者都有价值。
|
7月前
|
算法 调度 决策智能
基于GA-PSO遗传粒子群混合优化算法的DVRP问题求解matlab仿真
该文介绍了车辆路径问题(VRP)的优化求解,特别是动态车辆路径问题(DVRP)。在MATLAB2022a中运用GA-PSO混合优化算法进行测试,展示了运行结果图像。核心程序包含粒子更新、交叉、距离计算等步骤。DVRP在物流配送、运输调度中有广泛应用,目标是最小化行驶距离并满足车辆容量限制。遗传算法通过选择、交叉和变异操作寻找解,而粒子群优化模拟鸟群行为更新速度和位置。GA-PSO混合算法结合两者优点,提高搜索效率。在DVRP中,算法需考虑问题特性和约束,以找到高质量解。
|
SQL Oracle 关系型数据库
Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版
Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版
625 0
|
8月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的论文管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的论文管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
133 0
|
8月前
|
移动开发 JavaScript
echarts生成图表并下载为PDF文件(附带js源码地址)
echarts生成图表并下载为PDF文件(附带js源码地址)
175 0
|
8月前
|
数据可视化 关系型数据库 Java
数据库导出神器:Database-Export
Database-Export是一款开源的数据库导出工具
729 0
数据库导出神器:Database-Export