农夫过河试验报告_第1页
农夫过河试验报告_第2页
农夫过河试验报告_第3页
农夫过河试验报告_第4页
农夫过河试验报告_第5页
免费预览已结束,剩余10页可下载查看

下载本文档

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

文档简介

1、“数据结构与算法综合实验”课程设计报告题目:农夫过河问题学院计算机科学技术年级2014级专业计算机科学与技术学号20142060姓名高哈日期2016年3月30日星期三成绩评语黑龙江大学计算机科学技术学院、软件学院数据结构与算法综合实验报告1 .系统概述(1)一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸,他要把这些东西全部运到北岸。他面前只有一只小船,船只能容下他和一件物品,另外只有农夫才能撑船。如果农夫在场,则狼不能吃羊,羊不能吃白菜;否则狼会吃羊,羊会吃白菜。所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,但是狼不吃白菜。要求给出农夫将所有东西运过河的方案。(2)为农夫过河

2、问题抽象数据模型,体会数据模型在求解问题中的重要作用。(3)掌握顺序表和队列的逻辑结构和存储结构。2 .系统需求分析(1) 针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,可定义一个结构体来实现对四个对象狼、羊、白菜和农夫的表示。对于起始岸和目的岸,可以用0或者1来表示,以实现在程序设计中的简便性。(2) 题目要求给出四种事物的过河步骤,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,进行下一步试探。这就需要使用循环或者递归算法,避免随机盲目运算且保证每种情况均试探到,不接受非法输入。(3) 题目要求求出农夫带一只羊,一条狼和一颗白菜过河的办法

3、,所以依次成功返回运算结果后,需要继续运算,直至求出结果,即给出农夫的过河方案。输出界面要求具有每一步中农夫所带对象及每步之后各岸的物体,需要定义不同的数组来分别存储上述内容,并使界面所示方案清晰简洁。(4) 实验运行环境为VC+6.0.3 .系统概要设计(1)数据结构设计要模拟农夫过河的问题,用四位二进制数顺序分别表示农夫,狼,羊,白菜的位置。用0表示农夫或某种东西在河的南岸,1表示在河的北岸。则问题的初始状态是整数(二进制数表示为0000);问题的终结状态是整数15(二进制表示为1111)。用一个整数队列MoveTo把搜索过程中所有可能达到的状态都保存起来。队列中的每一个元素表示一个可以到

4、达的中间状态。另外用一个整数数组route记录被访问过的状态,以及已经被发现的能够到达这些状态的前驱。数组只需使用16个元素,每个元素的初始化值均为-1,每当队列中加入一个新状态时,数组中以该状态做下标的元素改为到达这一状态的前一状态的下标值。所以数组的第i个元素不仅记录状态i是否被过,同时还保存该状态的前驱状态下标。算法结束后可以利用route数组元素的值生成一个正确的状态路径。系统状态转换结构如图1所示:图1系统状态转换结构图(2)软件结构设计农夫过河管理系统根据需求分析中的功能分析,可以提炼出主要有搜索功能,判断事物安全功能,输出过河方案功能。而搜索功能又可以利用不同算法,如广度优先算法

5、,深度优先算法等等。判断事物安全功能需要将事物位置进行分析,通过位置分布的代码来判断当前状态是否安全,使用“与”位操作来考察狼和羊、羊和白菜是否在同一侧,且它们与农夫不一侧。若是,该状态即为不安全状态,否则为安全状态。若一个状态已经被访问过,或只有农夫一人从南岸过到北岸,则该状态被判为无效状态。输出功能就是将过河方案在屏幕上进行显示。系统软件结构如图1所示图1农夫过河管理系统软件模块结构图4 .系统详细设计与实现(1)搜索算法设计搜索过程可利用广度优先搜索算法从初始状态二进制0000(全部在河的南岸)出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸)为最终目标,

6、并且在序列中的每一个状态都可以从前一个状态得到。为避免重复,要求在序列中不出现重复的状态。(2)确定状态的安全有效性的功能模块设计通过位置分布的代码来判断当前状态是否安全,使用“与”位操作来考察狼和羊、羊和白菜是否在同一侧,且它们与农夫不一侧。若是,该状态即为不安全状态,否则为安全状态。若一个状态已经被访问过,或只有农夫一人从南岸过到北岸,则该状态被判为无效状态。若状态安全且有效,则返回1,否则返回00该模块算法流程图如图2所示。图2确定状态的安全有效性的功能模块设计算法流程图(3)输出模块设计输出农夫过河问题的可行性方案时,可从目标状态(1111)开始,将其记入队列(或栈)中,然后再找出其前

7、驱,记入队列(或栈)中,然后在找其前驱,一直到找到的是开始状态(0000)为止。要求输出时根据位置分布代码(即4位二进制数)各个位置上的0、1代码所表示的含义输出容易理解的文字。5 .系统测试对于该程序而言并没有实际输入,需要观察的就是输出结果。对于该程序的测试及其测试用例如表3所示。表3输出测试用例测试内容测试用例预期结果实际结果第0狼羊北岸第1步:南岸狼白菜北岸农夫羊第2步:南岸农夫狼白菜北岸羊第3步:南岸狼输出过河方案具体步骤无与预期结果相同北岸农夫羊白菜第4步:南岸农夫狼羊北岸白菜第5步:南岸羊北岸农夫狼白菜第6步:南岸农夫羊北岸狼白菜第7步:南岸北岸农夫狼白菜羊6 .小结(1)通过这

8、2周的程序设计使我了解到了自己在数据结构方面的不足,也坚定了我学好编程的信心。(2)采用广度优先的算法,利用数组只能记寻前一个前驱,导致另一个路径的丢失,不是很令人满意,所以采用第二种算法,深度优先算法,利用栈来记录路径前驱。参考文献1严蔚敏,李冬梅,吴伟民.数据结构(C语言版)M.北京:人民邮电出版社,2011:54-110.附录1 .广度优先算法#include<iostream>#include<cstdlib>#defineMAXNUM20usingnamespacestd;typedefstruct/顺序队列类型定义一一intf,r;/f表示头,r表示尾int

9、qMAXNUM;顺序队SqQueue,*SqQueuePtr;SqQueuePtrcreateEmptySQueue()/创建空队歹USqQueuePtrsqueue=newSqQueue;if(squeue=NULL)cout<<”申请内存失败"<<endl;exit(0);squeue->f=squeue->r=0;returnsqueue;boolisEmptyQueue(SqQueuePtrsqueue)/判断是否空队列return(squeue->f=squeue->r);voidenQueue(SqQueuePtrsqueu

10、e,intx)/向队歹!J中寸f入元素xif(squeue->r+1)%MAXNUM=squeue->f)cout<<”队歹!J已满"<<endl;elsesqueue->qsqueue->r=x;squeue->r=(squeue->r+1)%MAXNUM;)voiddeQueue(SqQueuePtrsqueue)岫对(if(isEmptyQueue(squeue)cout<<"对列为空"<<endl;elsesqueue->f=(squeue->f+1)%MAXN

11、UM;)intgetHead(SqQueuePtrsqueue)/对非空队列,求队列头部元素(if(squeue->f!=squeue->r)returnsqueue->qsqueue->f;)boolfarmerLocation(intlocation)判断农夫位置对0做与运算,还是原来的数字,用来判断位置(return0!=(location&0x08);)boolwolfLocation(intlocation)/判断狼位置(return0!=(location&0x04);)boolcabbageLocation(intlocation)判断白菜

12、位置(return0!=(location&0x02);)boolgoatLocation(intlocation)/判断羊的位置(return0!=(location&0x01);)/*其中一共有两种状态是不安全的:狼和羊单独在一起;羊和白菜单独在一起*/boolisSafe(intlocation)/若状态安全则返回true(if(goatLocation(location)=cabbageLocation(location)羊和白菜单独在一起&&(goatLocation(location)!=farmerLocation(location)return0

13、;if(goatLocation(location)=wolfLocation(location)&&(goatLocation(location)!=farmerLocation(location)/狼和羊单独在一起return0;return1;/其他状态是安全的)voidfarmerProblem()(intmovers,i,location,newlocation;introute16;/记录已考虑的状态路径intprintMAXNUM;SqQueuePtrmoveTo;moveTo=createEmptySQueue();晰的队歹!J判断路径enQueue(moveT

14、o,0x00);/初始状态为0for(i=0;i<16;i+)routei=-1;/-1表示没有记录过路径route0=0;while(!isEmptyQueue(moveTo)&&(route15=-1)队列不为空,路径未满时循环(一location=getHead(moveTo);/从队头出队,location表示位置,0为北岸,1为南岸deQueue(moveTo);已出队的删除for(movers=1;movers<=8;movers<<=1)向左移位,movers分另U0001,0010,0100,1000,/也就是依次判断过河的可行性(if(

15、0!=(location&0x08)=(0!=(location&movers)/判断农夫和要移动的物品是否在同岸(newlocation=locationA(0x08|movers);/过岸if(isSafe(newlocation)&&(routenewlocation=-1)判断是否安全,以及路径是否可用(routenewlocation=location;enQueue(moveTo,newlocation);记录路径并入队,位置改变)/*打印路径*/if(route15!=-1)(cout<<"过河步骤是:"<&l

16、t;endl;cout<<"tt南岸ttt北岸"<<endl;i=7;for(location=15;location>=0;location=routelocation)(printi=location;i-;if(location=0)break;)for(intj=i+1;j<=7;j+)(cout<<"第"<<j<<"步:";switch(printj)(case0:cout<<"tt农夫狼白菜羊ttt"<<en

17、dl;break;case 1: cout<<"tt农夫狼白菜tt羊"<<endl;break;case 2: cout<<"tt农夫狼羊tt白菜"<<endl;break;case 4: cout<<"tt农夫白菜羊ttt狼”<<endl;break;case6:cout<<"tt农夫羊tt狼白菜"<<endl;break;case9:cout<<"tt狼白菜ttt农夫羊"<<endl

18、;break;case11:cout<<"tt狼ttt农夫羊白菜"<<endl;break;case 13: cout<<"tt白菜ttt农夫狼羊"<<endl;break;case 14: cout<<"tt羊ttt农夫狼白菜"<<endl;break;case 15: cout<<"ttttt农夫狼羊白菜"<<endl;break;intmain()farmerProblem();return0;2.深度优先算法#i

19、nclude<iostream>#include<cstdlib>#defineMAXNUM20usingnamespacestd;intsolutionCout=0;typedefstructint*base;栈底指针int*top;/栈顶指针intstacksize;栈可用的最大容量SqStack;voidcreateEmptyStack(SqStack&S)构造一个空栈SS.base=newintMAXNUM;if(!S.base)(cout<<”申请内存失败"<<endl;exit(0);)S.top=S.base;/W

20、始为空栈S.stacksize=MAXNUM;)一voidPush(SqStack&S,intx)/f入一个元素x(if(S.top-S.base=S.stacksize)橇满(cout<<"栈满";)*S.top+=x;)voidPop(SqStack&S)/出栈(if(S.top=S.base)/假空(cout<<"栈空";)-S.top;)一intgetTop(SqStackS)取栈顶元素(return*(S.top-1);)voidprint(SqStackS)/灯E|3路径(int*p=S.base;so

21、lutionCout+;intprintMAXNUM;inti=0;while(!(p=S.top)(printi=*p;i+;P+;)cout<<"方案"<<solutionCout<<"过河步骤是:"<<endl;cout<<"tt南岸ttt北岸"<<endl;for(intj=0;j<i;j+)cout<<"第"<<j<<"步:";switch(printj)case0:cou

22、t<<"tt农夫狼白菜羊ttt"<<endl;break;case 1: cout<<"tt农夫狼白菜tt羊"<<endl;break;case 2: cout<<"tt农夫狼羊tt白菜"<<endl;break;case4:cout<<"tt农夫白菜羊tt狼”<<endl;break;case6:cout<<"tt农夫羊tt狼白菜"<<endl;break;case9:cout<

23、<"tt狼白菜ttt农夫羊"<<endl;break;case11:cout<<"tt狼ttt农夫羊白菜"<<endl;break;case 13: cout<<"tt白菜ttt农夫狼羊"<<endl;break;case 14: cout<<"tt羊ttt农夫狼白菜"<<endl;break;case 15: cout<<"ttttt农夫狼羊白菜"<<endl;break;)boo

24、lfarmerLocation(intlocation)/判断农夫位置对0做与运算,还是原来的数字,用来判断位置return0!=(location&0x08);)boolwolfLocation(intlocation)/判断狼位置return0!=(location&0x04);)boolcabbageLocation(intlocation)判断白菜位置(return0!=(location&0x02);)boolgoatLocation(intlocation)/判断羊的位置(return0!=(location&0x01);)/*其中一共有两种状态是不安全的:狼和羊单独在一起;羊和白菜单独在一起*/boolisSafe(intlocation)/若状态安全则返回true(if(goatLocation(location)=cabbageLocation(location)羊和白菜单独在一起&&(goatLocation(location)!=farmerLocation(location)return0;if(goatLocation(location)=

温馨提示

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

评论

0/150

提交评论