传教士过河答案

合集下载

传教士野人过河问题-两种解法思路

传教士野人过河问题-两种解法思路

实验 传教士野人过河问题37030602 王世婷一、实验问题传教士和食人者问题(The Missionaries and Cannibals Problem )。

在河的左岸有3个传教士、1条船和3个食人者,传教士们想用这条船将所有的成员运过河去,但是受到以下条件的限制:(1)传教士和食人者都会划船,但船一次最多只能装运两个;(2)在任何岸边食人者数目都不得超过传教士,否则传教士就会遭遇危险:被食人者攻击甚至被吃掉。

此外,假定食人者会服从任何一种过河安排,试规划出一个确保全部成员安全过河的计划。

二、解答步骤(1) 设置状态变量并确定值域M 为传教士人数,C 为野人人数,B 为船数,要求M>=C 且M+C <= 3,L 表示左岸,R 表示右岸。

初始状态 目标状态L R L RM 3 0 M 0 3C 3 0 C 0 3B 1 0 B 0 1(2) 确定状态组,分别列出初始状态集和目标状态集用三元组来表示f S :(ML , CL , BL )(均为左岸状态)其中03,03ML CL ≤≤≤≤,BL ∈{ 0 , 1}0S :(3 , 3 , 1) g S : (0 , 0 , 0)初始状态表示全部成员在河的的左岸;目标状态表示全部成员从河的左岸全部渡河完毕。

(3) 定义并确定规则集合仍然以河的左岸为基点来考虑,把船从左岸划向右岸定义为Pij 操作。

其中,第一下标i 表示船载的传教士数,第二下标j 表示船载的食人者数;同理,从右岸将船划回左岸称之为Qij 操作,下标的定义同前。

则共有10种操作,操作集为F={P01,P10,P11,P02,P20,Q01,Q10,Q11,Q02,Q20}P 10 if ( ML ,CL , BL=1 ) then ( ML –1 , CL , BL –1 )P 01 if ( ML ,CL , BL=1 ) then ( ML , CL –1 , BL –1 )P 11 if ( ML ,CL , BL=1 ) then ( ML –1 , CL –1 , BL –1 )P 20 if ( ML ,CL , BL=1 ) then ( ML –2 , CL , BL –1 )P 02 if ( ML ,CL , BL=1 ) then ( ML , CL –2 , BL –1 )Q 10 if ( ML ,CL , BL=0 ) then ( ML+1 , CL , BL+1 )Q 01 if ( ML ,CL , BL=0 ) then ( ML , CL+1 , BL +1 )Q 11 if ( ML ,CL , BL=0 ) then ( ML+1 , CL +1, BL +1 )Q20 if ( ML ,CL , BL=0 ) then ( ML+2 , CL +2, BL +1 )Q02if ( ML ,CL , BL=0 ) then ( ML , CL +2, BL +1 )(4)当状态数量不是很大时,画出合理的状态空间图图1 状态空间图箭头旁边所标的数字表示了P或Q操作的下标,即分别表示船载的传教士数和食人者数。

传教士问题

传教士问题

一.问题描述有M个传教士和N个野人来到河边准备渡河,河岸有一条船,每次至多可供k人乘渡。

任何时刻在河的两岸以及船上的野人数目总是不超过传教士的数目。

二.问题分析本问题采用A*算法求解,解答的关键与难点如下:1.评估函数的建立。

评估函数为f=h+d=M+N-2*B+d.。

M表示左岸的传教士的人数,N表示左岸野人的数目,B取值为0或1 。

1表示船在左岸,0 表示船在右岸。

d 表示节点的深度。

下面我们来证明h(n)=M+C-2B是满足A*条件的。

我们分两种情况考虑。

先考虑船在左岸的情况。

如果不考虑限制条件,也就是说,船一次可以将三人从左岸运到右岸,然后再有一个人将船送回来。

这样,船一个来回可以运过河2人,而船仍然在左岸。

而最后剩下的三个人,则可以一次将他们全部从左岸运到右岸。

所以,在不考虑限制条件的情况下,也至少需要摆渡[(M+N-3)/2]*2+1次。

其中分子上的"-3"表示剩下三个留待最后一次运过去。

除以"2"是因为一个来回可以运过去2人,需要[(M+N-3)/2]个来回,而"来回"数不能是小数,需要向上取整,这个用符号[ ]表示。

而乘以"2"是因为一个来回相当于两次摆渡,所以要乘以2。

而最后的"+1",则表示将剩下的3个运过去,需要一次摆渡。

化简有:M+N-2。

再考虑船在右岸的情况。

同样不考虑限制条件。

船在右岸,需要一个人将船运到左岸。

因此对于状态(M,N,0)来说,其所需要的最少摆渡数,相当于船在左岸时状态(M+1,N,1)或(M,N+1,1)所需要的最少摆渡数,再加上第一次将船从右岸送到左岸的一次摆渡数。

因此所需要的最少摆渡数为:(M+N+1)-2+1。

其中(M+N+1)的"+1"表示送船回到左岸的那个人,而最后边的"+1",表示送船到左岸时的一次摆渡。

传教士野人问题

传教士野人问题

问题:野人过河问题属于人工智能学科中的一个经典问题,问题描述如下:有三个牧师(也有的翻译为传教士)和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢?解答一:一、算法分析先来看看问题的初始状态和目标状态,假设和分为甲岸和乙岸:初始状态:甲岸,3野人,3牧师;乙岸,0野人,0牧师;船停在甲岸,船上有0个人;目标状态:甲岸,0野人,0牧师;乙岸,3野人,3牧师;船停在乙岸,船上有0个人;整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。

问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):渡1野人、渡1牧师、渡1野人1牧师、渡2野人、渡2牧师算符知道以后,剩下的核心问题就是搜索方法了,本文采用深度优先搜索,通过一个FindNext(…)函数找出下一步可以进行的渡河操作中的最优操作,如果没有找到则返回其父节点,看看是否有其它兄弟节点可以扩展,然后用Process(…)函数递规调用FindNext(…),一级一级的向后扩展。

搜索中采用的一些规则如下:1、渡船优先规则:甲岸一次运走的人越多越好(即甲岸运多人优先),同时野人优先运走;乙岸一次运走的人越少越好(即乙岸运少人优先),同时牧师优先运走;2、不能重复上次渡船操作(通过链表中前一操作比较),避免进入死循环;3、任何时候河两边的野人和牧师数均分别大于等于0且小于等于3;4、由于只是找出最优解,所以当找到某一算符(当前最优先的)满足操作条件后,不再搜索其兄弟节点,而是直接载入链表。

5、若扩展某节点a的时候,没有找到合适的子节点,则从链表中返回节点a的父节点b,从上次已经选择了的算符之后的算符中找最优先的算符继续扩展b。

二、基本数据结构仔细阅读问题,可以发现有些基本东西我们必须把握,例如:每时刻河两岸野人牧师各自的数目、船的状态、整个问题状态。

过河问题(牛虎过河、商人仆人过河、农夫妖怪过河、传教士野人过河)(内测第2届第2题)

过河问题(牛虎过河、商人仆人过河、农夫妖怪过河、传教士野人过河)(内测第2届第2题)

过河问题(⽜虎过河、商⼈仆⼈过河、农夫妖怪过河、传教⼠野⼈过河)(内测第2届第2题)题⽬要求问题描述:三只⽜三只虎过河,船最多只能容纳两只动物,且船在往返途中不能为空。

在任⼀岸边,若⽜的数量少于虎的数量,则⽜就会被⽼虎吃掉。

为了使动物全部过河且使⽆损失,请制定合理的渡河⽅案。

解决⽅案这也是⼀个经典的渡河问题了,由此衍化出的版本有商⼈仆⼈(随从)过河,农夫妖怪过河,传教⼠野⼈过河...除了⾓⾊有变化,内容本质上是⼀样的。

假设原来的动物和船都在A岸,现在想渡河到对⾯的B岸。

考虑⽜虎数量和船的位置,可以将本题中的所有可能出现的情形描述为静态属性和动态属性。

静态属性就是船停靠在A岸或者B岸时,A岸⽜、虎的数量(A岸数⽬⼀定时,B岸也⼀定,所以只需考虑⼀边就⾏),动态属性就是船在运⾏中时,A岸或者B岸⽜、虎的数量。

进⼀步考虑,只要知道了相邻的两个静态属性,也就知道了发⽣在其间的动态属性。

⽐如开始船在A岸,A岸有⽜、虎各三只,下⼀个状态为船在B岸,A岸有⽜虎各两只,那它们之间的动态属性⼀定是船由A到B,且运送了⼀⽜⼀虎过去(不考虑重复的状况)。

所以在这⾥,我们只需要确定每⼀步对应的静态属性,在编程中,将其描述为状态。

对于岸边的⽜或者虎的数量,只有0到3这四个取值,对于船的停靠位置,只有A岸和B岸两种情形,这样⼀来,就有了4*4*2=32种状态。

在这32种状态中,有些状态会引起⽜吃虎,这必须被排除掉。

到这⾥,制定渡河⽅案的问题就转换为在这32个状态中探寻合理“状态路径”的问题。

我们从初始状态——A岸⽜虎各三只,船在A岸这个状态出发,不断判断遇到的下⼀个状态是否合理。

如果下⼀个状态合理,就将其加⼊到“状态路径”当中,并留下访问标记(防⽌重复添加,形成环路),否则,跳过此状态。

在不断向前探寻的过程中,如果遇到⼀个标记为已访问的状态,说明该状态已加⼊路径,需要探寻下⼀种可能。

如果遇到了结束状态——A岸⽜虎为零,船在B岸,则说明找到了⼀条完整的“状态路径”,这时需要打印这条路径,并清除当前状态的访问标记,且退出上⼀个状态,继续寻找下⼀种可能性。

传教士和野人问题

传教士和野人问题

传教士和野人问题(Missionaries and Cannibals)传教士和野人问题是一个经典的智力游戏问题。

在这个问题中,实际上隐含了这样一个条件:如果在河的某一岸只有野人,而没有传教士,也同样被认为是合法状态。

在具体书写某些条件时,为了简便,这一点有时并没有考虑,但我们默认这个条件是被考虑了的。

有N个传教士和N个野人来到河边准备渡河,河岸有一条船,每次至多可供k人乘渡。

问传教士为了安全起见,应如何规划摆渡方案,使得任何时刻,在河的两岸以及船上的野人数目总是不超过传教士的数目。

即求解传教士和野人从左岸全部摆渡到右岸的过程中,任何时刻满足M(传教士数)≥C (野人数)和M+C≤k的摆渡方案。

设N=3,k=2,则给定的问题可用图1.2表示,图中L和R表示左岸和右岸,B=1或0分别表示有船或无船。

约束条件是:两岸上M≥C,船上M+C≤2。

图1.2 M-C问题实例由于传教士和野人数是一个常数,所以知道了一岸的情况,另一岸的情况也就知道了。

因此为了简便起见,在描述问题时,只描述一岸--如左岸--的情况就可以了。

另外,该问题我们最关心的是在摆渡过程中,两岸状态的变化情况,因此船上的情况并不需要直接表达出来。

在一次摆渡过程中,船上究竟有几个传教士和野人,可以通过两个相连的状态简单得到。

这样表达更简练,突出了问题的重点。

(1)综合数据库:用三元组表示左岸的情况,即(,,),其中0≤,≤3,∈{0,1},其中表示在左岸的传教士人数,表示在左岸的野人数,=1表示船在左岸,=0表示船在右岸。

则此时问题描述可以简化为:(3,3,1)→(0,0,0)N=3的M-C问题,状态空间的总状态数为4×4×2=32,根据约束条件的要求,可以看出只有20个合法状态。

再进一步分析后,又发现有4个合法状态实际上是不可能达到的。

因此实际的问题空间仅由16个状态构成。

下表列出分析的结果:()(001)达不到(传教士()(000)均在右,船在左)(011)(021)(031)(101)不合法(右岸野人多)(111)(121)不合法(左岸野人多)(131)不合法(左岸野人多)(201)不合法(右岸野人多)(211)不合法(右岸野人多)(221)(231)不合法(左岸野人多)(301)达不到(311)(321)(331)(010)(020)(030)达不到(100)不合法(右岸野人多)(110)(120)不合法(左岸野人多)(130)不合法(左岸野人多)(200)不合法(右岸野人多)(210)不合法(右岸野人多)(230)不合法(右岸野人多)(300)(220)(310)(320)(330)达不到规则集可以划分为两组:一组是从左岸到右岸,称为p 操作,另一组是从右岸到左岸,称为q操作。

传教士野蛮人过河问题--python

传教士野蛮人过河问题--python

传教⼠野蛮⼈过河问题--python三名传教⼠和三个野蛮⼈同在⼀个⼩河渡⼝,渡⼝上只有⼀条可容两⼈的⼩船。

问题的⽬标是要⽤这条⼩船把这六个⼈全部渡到对岸去,条件是在渡河的过程中,河两岸随时都保持传教⼠⼈数不少于野蛮⼈的⼈数,否则野蛮⼈会把处于少数的传教⼠状态集合为(x,y,b)三元组,x表⽰左岸野⼈数,y表⽰左岸传教⼠数,x,y取值0~3。

b为0表⽰船在左边,b为1表⽰船在右边动作集合为⼀个传教⼠从左到右,两个传教⼠从左到右,⼀个野⼈从左到右,两个野⼈从左到右,⼀个野⼈⼀个传教⼠从左到右;从右到左类似也有5个动作,共10个动作,于是就可以画出⼀个状态转换图,下⾯的python代码可以帮助我们完成这个任state_legal判断给定状态是否合法,act_legal判断在当前状态执⾏给定动作是否合法,f(x,y,b)打印所有从(x,y,b)可以执⾏的动作和转移到的状态def state_legal(x, y, b):if x < 0 or y < 0 or x > 3 or y > 3:return Falseif y < x and y > 0:return Falseelif (3-y) < 3-x and 3-y > 0:return Falseelse:return Truedef act_legal(x, y, b, xx, yy, bb):if b != bb:return Falseif b == 0 and state_legal(x - xx, y - yy, 1 - b):return Trueelif b == 1 and state_legal(x + xx, y + yy, 1 - b):return Trueelse:return False#when calling f, (x,y,b) is ensured to be state_legaldef f(x,y,b):for act in actions:if act_legal(x, y, b, act[0], act[1], act[2]):if act[2] == 0:print(x,y,b,"---",act, '---', x - act[0], y - act[1], 1 - b)else:print(x,y,b,"---",act, '---', x + act[0], y + act[1], 1 - b)a = (0,1,2,3)actions = []for b in (0,1):for x in (0,1,2):for y in (0,1,2):if x + y >= 1 and x + y <= 2:actions.append((x,y,b))print(actions)for x in a:for y in a:for b in (0,1):if not(x == 0 and y == 0) and state_legal(x, y, b):f(x,y,b)#x is num of savages, y is num of missionaries。

有N个传教士和N个野人来到河边渡河

有N个传教士和N个野人来到河边渡河

有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)&reg; (0, 0, 0)N=3的M-C问题, 状态空间的总状态数为4×4×2=32, 根据约束条件的要求, 可以看出只有20个合法状态。

传教士野人过河问题两种解法思路

传教士野人过河问题两种解法思路
第5次:左岸到右岸,传教士过去2人,野人过去0人
第6次:右岸到左岸,传教士过去1人,野人过去1人
第7次:左岸到右岸,传教士过去2人,野人过去0人
第8次:右岸到左岸,传教士过去0人,野人过去1人
第9次:左岸到右岸,传教士过去0人,野人过去2人
第10次:右岸到左岸,传教士过去1人,野人过去0人
第11次:左岸到右岸,传教士过去1人,野人过去1人
F={P01,P10,P11,P02,P20,Q01,Q10,Q11,Q02,Q20}
P10ﻩif (ML,CL,BL=1)then(ML–1 , CL,BL–1)
P01ﻩif ( ML,CL , BL=1)then ( ML ,CL–1 , BL–1)
P11ﻩif (ML,CL,BL=1) then ( ML–1 , CL–1,BL–1)
二、解答步骤
(1)设置状态变量并确定值域
M为传教士人数,C为野人人数,B为船数,要求M>=C且M+C<=3,L表示左岸,R表示右岸。
初始状态ﻩﻩ目标状态
LﻩRﻩﻩﻩLR
Mﻩ30ﻩﻩﻩM03
Cﻩ30ﻩﻩﻩﻩﻩC03
B1ﻩ0ﻩﻩﻩﻩB0ﻩ1
(2)确定状态组,分别列出初始状态集和目标状态集
用三元组来表示 :(ML,CL,BL)(均为左岸状态)
图1状态空间图
箭头旁边所标的数字表示了P或Q操作的下标,即分别表示船载的传教士数和食人者数。
三、算法设计
方法一:树的遍历
根据规则由根(初始状态)扩展出整颗树,检测每个结点的“可扩展标记”,为“-1”的即目标结点。由目标结点上溯出路径。
见源程序1。
方法二:启发式搜索
构造启发式函数为:
选择较大值的结点先扩展。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

有三个食人族人和三个传教士要过河,现在只有一条船,但一次只能载两个人,而无论在河的哪一边,只要食人族人比传教士多,食人族人就会把传教士吃掉。

问他怎么样才能安全的过河?
设:要从河的a岸到河的b岸。

1、一食人族和一传教士开船过河,到了b岸后食人族留在河的b岸,传教士把船开回a岸;(现在是三个传教士和两个食人族在a岸,一食人族在b岸)。

2、船开回a岸后,两个食人族开船过河,到了b岸后,一食人族留在河的b岸,让一名食人族把船开回a岸;(现在是三个传教士和一个食人族在a岸,两个食人族在b岸)
3、其中一食人族把船开回a岸后,食人族下船,让两名传教士开船过河,过河后(到b岸后)又让一食人族和一传教士把船开a岸;(现在是两个传教士和两个食人族在a岸,一传教士一食人族在b岸)
4、船到a岸后,让两个传教士开船过河,到了b岸后,传教士下船让在b岸的那个食人族把船开回a岸;(现在是三传教士在b岸,三食人族在a岸)
5、船回到a岸后,两食人族过河,到b岸后一食人族把船开回a岸,再两食人族开船渡河。

相关文档
最新文档