传教士问题.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
传教士问题

一. 问题描述 ? ? 有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,表示送船到左岸时的一次摆渡。 化简有:(M+N+1)-2+1=M+N。   ? 综合船在左岸和船在右岸两种情况下,所需要的最少摆渡次数用一个式子表示为:M+N-2B。其中B=1表示船在左岸,B=0表示船在右岸。   由于该摆渡次数是在不考虑限制条件下,推出的最少所需要的摆渡次数...... 从前有一条河,河的左岸有m个传教士(Missionary)和m个野人(Cannibal),和一艘最多可乘n人的小船。约定左岸,右岸和船上或者没有传教士,或者野人数量少于传教士,否则野人会把传教士吃掉。 编程,接收m和n,搜索一条可让所有的野人和传教士安全渡到右岸的方案。 ? 我们先假设左岸有3个传教士和3个野人,小船最多可乘2人。把当前左岸的状态抽象为: (3,3,1) 前两个3代表左岸有3个传教士和3个野人,1代表船在左岸。把每一次可行的渡船方案作为算符。比如,在初始状态,让1个传教士和1个野人上船并渡到右岸,这一算符可表示为: (1,1) 算符的两位数分别代表要移动的传教士,野人的数量;把人移到没有船的岸边并且改变状态向量中船的值。 对于固定大小的小船,算符的数量是一定的: class Move { public: ??? int missionary;????? //要移动的传教士数量 ??? int cannibal;??????? //野人 }; class MoveGroup { public: ??? Move move[500];????? //算符集 ??? int numMove;???????? //可用算符的总数 ??? MoveGroup(int MAX_ON_BOAT) {??? //利用构造器求算符集 ?????? int m, c, i = 0; ?????? for (m = 0; m = MAX_ON_BOAT; m++) ?????????? for (c = 0; c = MAX_ON_BOAT; c++) ????????????? if (c==0 m!=0) { move[i].missionary=m; move[i].cannibal=0; i++; } ????????????? else if (m==0 c!=0) { move[i].missionary=0; move[i].cannibal=c; i++; } ????????????? else if (m+c=MAX_ON_BOAT m+c!=0 m=c) { move[i].missionary = m; move[i].cannibal = c; i++; } ?????? numMove = i; ??? } }; 创建一个MoveGroup 对象 MoveGroup mg(2); 即可得到当小船最多可乘2人时的算符集。 ? 这个程序所要做的,就是通过这个已知的算符集,将初始状态(3,3,1)转变为最终状态(0,0,0)。我们应将状

文档评论(0)

ldj215322 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档