人样狼草过河数学建模new_第1页
人样狼草过河数学建模new_第2页
人样狼草过河数学建模new_第3页
人样狼草过河数学建模new_第4页
人样狼草过河数学建模new_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、课 程 设 计 报 告课程名称:数学建模设计题目:人狼羊草过河问题姓名学号:马高松(200705030) 易文辉(200705050) 陈邦生(200705010)指导老师:李沐春完成时间:2010年5月8日问题的提出在河的一岸,人、狼、羊、草、均要过河,船需人划,而且最多载一物,当人不在时,狼会吃羊,羊会吃草;试安排人狼羊草安全渡河。一 问题的分析人带着狼、羊和草,身处河的一岸。他要把这些东西全部运到彼岸。问题是他面前只有一条小船,船小到只能容下他和一件物品,另外船必须有人划。而且,因为狼能吃羊,而羊爱吃草,所以人不能留下羊和草或者狼和羊单独在河的一边。以下是解决方案:整个过程中我们把该过程

2、分为两种状态A和B,在各状态中,将人羊狼草用一个四维向量表示,A状态表示人羊狼草在河的左右岸的状态,当一物在左岸时,用分量0表示,当一物在右岸时,用分量1表示,例如状态A1(1,1,0,1)表示人羊草在河的右岸,狼崽河左岸,根据题中的要求,有些状态时允许的,有些状态是不允许的,这就牵涉到该方案的安全性,于是我们规定由条件允许存在的状态我们称之为可取状态,比如A1(0,1,0,1)是一个可取状态,而A2(0,0,1,1)则是一个不可取状态,因为他表示羊草在河的右岸,是不可取的;人然后是B状态,B状态表示用船渡河过程中表示船内运载的状况,当一物在船上时用1表示,不再船上则用0表示,当满足问题条件的

3、运载称为可取运载,当不满足条件的运载则是不可取运载,如B1(1,1,0,0)表示人狼崽船上,但它不是可取状态,同样B2(1,0,1,1)也不是可取状态,应为船不能载三物。我们可以通过穷举法得到可取状态向量: 人不在时: 三个全不在的 (1,1,1,1) 两个不在的 (1,1,1,0)、(1,1,0,1)、(1,0,1,1) 一个不在的 (1,0,1,0) 人在时: 三个全在的 (0,0,0,0) 一个不在的 (0,0,0,1)、(0,0,1,0)、(0,1,0,0) 两个不在的 (0,1,0,1)一共有10种状态。建模 状态转移方程:原状态运载现状态 一可取状态向量可取运载向量,称之为过河。

4、其中运算方式为“1+10,1+01,0+11,0+00”。二、模型 在规则“1+10,1+01,0+11,0+00”下,试求从最初可取状态向量(0,0,0,0)经过N步到最终状态向量(1,1,1,1)的可取转移方式。三 解法 1.穷举法注:在得到的状态后面的标示符中,“!”表示该状态不可取,“+”表示该状态可取,“*”表示该状态已经出现过,为重复状态。(1) (1,1,0,0) =(1,1,0,0) ! (0,0,0,0) + (1,0,1,0) =(1,0,1,0) +(1,0,0,1) =(1,0,0,1) !(1, 0, 0, 0) =(1,0,0,0) ! (2) (1 , 1 ,0

5、, 0 ) =(0,1,1,0) ! (1,0 ,1,0 ) + (1, 0, 1, 0 ) =(0,0,0,0) *(1, 0 , 0 , 1) =(0,0,1,1) ! (1 , 0 ,0 ,0 ) =(0,0,1,0) +(3) (1 , 1 ,0 , 0 ) =(1,1,1,0) + (0,0 ,1,0 ) + (1, 0, 1, 0 ) =(1,0,0,0) !(1, 0 , 0 , 1) =(1,0,1,1) + (1 , 0 ,0 ,0 ) =(1,0,1,0) *第三步中得到的结果有两个可取状态,故应分别计算先取(1,1,1,0)计算: (4)1 (1 , 1 ,0 , 0 )

6、 =(0,0,1,0) * (1,1 ,1,0 ) +(1, 0, 1, 0 ) =(0,1,0,0) +(1, 0 , 0 , 1) =(0,1,1,1) ! (1 , 0 ,0 ,0 ) =(0,1,1,0) !(5)1 (1 , 1 ,0 , 0 ) =(1,0,0,0) ! (0,1,0,0 ) +(1, 0, 1, 0 ) =(1,1,1,0) *(1, 0 , 0 , 1) =(1,1,0,1) + (1 , 0 ,0 ,0 ) =(1,1,0,0) !(6)1 (1 , 1 ,0 , 0 ) =(0,0,0,1) * (1,1,0,1 ) + (1, 0, 1, 0 ) =(0,

7、1,1,1) !(1, 0 , 0 , 1) =(1,0,0,0) ! (1 , 0 ,0 ,0 ) =(0,1,0,1) +(7)1 (1 , 1 ,0 , 0 ) =(1,0,0,1 ) ! (0,1,0,1 ) + (1, 0, 1, 0 ) =(1,1,1,1) +(1, 0 , 0 , 1) =(1,1,0,0) ! (1 , 0 ,0 ,0 ) =(1,1,0,1) *取(1,0,1,1)计算:(4)2 (1 , 1 ,0 , 0 ) =(0,1,1,1) ! (1,0,1,1) + (1, 0, 1, 0 ) =(0,0,0,1) +(1, 0 , 0 , 1) =(0,0,1,

8、0) * (1 , 0 ,0 ,0 ) =(0,0,1,1) !(5)2 (1 , 1 ,0 , 0 ) =(1,1,0,1) + (0,0,0,1 ) + (1, 0, 1, 0 ) =(1,0,1,1) *(1, 0 , 0 , 1) =(1,0,0,0) ! (1 , 0 ,0 ,0 ) =(1,0,0,1) !得到的可取状态和(5)1步骤一样,故运算(6)2、(7)2应该和(6)1、(7)1一样。所以总共可以通过七步运算使得人、狼、羊、草安全过河。 2.图解法四、算法实现1.问题分析完成了上面的准备工作,要模拟农夫过河问题,首先需要选择一个对问题中每个角色的位置进行描述的方法。一个很方

9、便的办法是用四位二进制数顺序分别表示人狼羊草的位置。例如用0表示人或者某物在河的南岸,1表示在河的北岸。因此整数3(其二进制表示为0011) 表示人和狼在河的南岸,而羊和草在河的北岸。现在的问题变成:从初始状态二进制0000(全部在河的南岸) 出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸) 为最终目标,并且在序列中的每一个状态都可以从前一状态通过人(可以带一样东西)划船过河的动作到达。2. 算法选择求解这个问题的最简单的方法是一步一步进行试探,每一步都搜索所有可能的选择,对前一步合适的选择再考虑下一步的各种方案。用计算机实现上述求解的搜索过程可以采用两种不同

10、的策略:一种是广度优先搜索,另一种是深度优先搜索。深度优先搜索就是在搜索树的每一层始终先只扩展一个子节点,不断地向纵深前进直到不能再前进(到达叶子节点或受到尝试限制)时,才从当前节点返回到上一级节点,沿另一方向又继续前进。这种方法的搜索是从树根开始一枝一枝逐渐形成的。深度优先搜索亦称为纵向搜索。由于一个有解的问题树可能含有无穷分枝,深度优先搜索如果误入无穷分枝(即深度无限),则不可能找到目标节点。所以,深度优先搜索策略是不完备的。另外,应用此策略得到 的解不一定是最佳解(最短路径)。深度优先搜索算法中,是深度越大的结点越先得到扩展。如果在搜索中把算法改为按结点的层次进行搜索,本层的结点没有搜索

11、处理完时,不能对下层结点进行处理,即深度越小的结点越先得到扩展,也就是说先产生的结点先得以扩展处理,这种搜索算法称为广度优先搜索法。 广度优先的含义就是在搜索过程中总是首先搜索下面一步的所有可能状态,然后再进一步考虑更后面的各种情况。要实现广度优先搜索,一般都采用队列作为辅助结构。把下一步所有可能达到的状态都列举出来,放在这个队列中,然后顺序取出来分别进行处理,处理过程中把再下一步的状态放在队列里。 由于队列的操作遵循先进先出的原则,在这个处理过程中,只有在前一步的所有情况都处理完后,才能开始后面一步各情况的处理。 五、程序代码#include<iostream>usin

12、g namespace std;int man(int n)return (0!=(n & 8);/ 判断农夫在不在,如果返回1,则表示农夫在。int wolf(int n)return (0!=(n & 4);int sheep(int n)return (0!=(n & 2);int grass(int n)return (0!=(n & 1);/安全检验int isSafe(int n)if(sheep(n)=grass(n) && sheep(n)!=man(n) return 0;if(sheep(n)=wolf(n) &&am

13、p; wolf(n)!=man(n) return 0;return 1;/1表示安全,0表示不安全/过河,使用广度优深算法遍历 int crossRiver(int result)int Status,nextStatus,choice=8,9,10,12;/农夫从某一状态出发,有4种走法 int queue16,front,rear;/定义循环队列 int i,j,visited16;/visitedi=0表示i未访问过 int route16;/routei表示第i步的前一步,意即往第i步走的方式rear=front=0;/队列初始化 for(i=0;i<16;i+)routei=

14、-1;visitedi=0;Status=0;nextStatus=-1; /从状态0(全部在南岸)开始 queuerear=Status; rear=(rear+1)%16;/入队while(front!=rear)Status=queuefront;front=(front+1)%16;/出队visitedStatus=1; /访问 for(j=0;j<4;j+)nextStatus=Statuschoicej; /从curStatus状态到下一状态nextStatus if(visitednextStatus=0 && isSafe(nextStatus)queue

15、rear=nextStatus; rear=(rear+1)%16;/入队routenextStatus=Status;/仅表示从Sattus可以走到nextStatus /如route10=0,意即从0000有路可走到1010/处理路径表:从路径表中反推(从最终步->开始步) i=15;/最后一步 if(routei=-1) /若没有方法可以走到1111,则任务失败。 cout<<"过河失败!"<<endl;return 0;for(j=15;routei!=-1 && i>=0;j-) /routei!=-1相当于那一

16、步走不通,那就不用选取了resultj=i;i=routei; resultj=i; /第一步 return 1; int main()int i,j,result16; /存结果序列 /16种状态(0000->1111)对应的文字提示 char name1620="人狼羊草tt空", "人狼羊ttt草", "人狼草ttt羊", "人狼ttt羊草", "人羊草ttt狼", "人羊ttt狼草", "人草ttt狼羊", "人ttt狼羊草&quo

17、t;, "狼羊草tt人", "狼羊ttt人草", "狼草ttt人羊", "狼ttt人羊草", "羊草ttt人狼", "羊ttt人狼草", "草ttt人狼羊", "空ttt人狼羊草" for(i=0;i<16;i+)resulti=-1;/初始化结果序列 if(crossRiver(result)=0) return 0;/输出结果 cout<<"步骤t南岸ttt北岸"<<endl; cout<<"-"<<endl;for(i=0,j=0;j<16;j+)if(resultj>=0) cout<<"第"<<i<<

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论