数据结构课程设计报告---农夫过河问题_第1页
数据结构课程设计报告---农夫过河问题_第2页
数据结构课程设计报告---农夫过河问题_第3页
数据结构课程设计报告---农夫过河问题_第4页
数据结构课程设计报告---农夫过河问题_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

1、目录引言21 问题描述3基本要求32.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性;32.2设计一个算法求解农夫过河问题,并输出过河方案;33 概要设计33.1 数据结构的设计。33.1.1农夫过河问题的模型化33.1.2 算法的设计44、运行与测试65、总结与心得7附录7参考文献13引言所谓农夫过河问题是指农夫带一只狼、一只羊和一棵白菜在河南岸, 需要安全运到北岸。一条小船只能容下他和一件物品, 只有农夫能撑船。问农夫怎么能安全过河, 当然狼吃羊, 羊吃白菜, 农夫不能将这两种或三种物品单独放在河的一侧, 因为没有农夫的照看, 狼就要吃羊, 而羊可能要吃白菜? 这类问题的实质

2、是系统的状态问题, 要寻求的是从初始状态经一系列的安全状态到达系统的终止状态的一条路径。 1 问题描述一个农夫带一只狼、一棵白菜和一只羊要从一条河的南岸过到北岸,农夫每次只能带一样东西过河,但是任意时刻如果农夫不在场时,狼要吃羊、羊要吃白菜,请为农夫设计过河方案。基本要求2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性;2.2设计一个算法求解农夫过河问题,并输出过河方案;3 概要设计3.1 数据结构的设计。3.1.1农夫过河问题的模型化分析这类问题会发现以下特征: 有一组状态( 如农夫和羊在南, 狼和白菜在北) ; 从一个状态可合法地转到另外几个状态( 如农夫自己过河或农夫带着

3、羊过河) ; 有些状态不安全( 如农夫在北, 其他东西在南) ; 有一个初始状态( 都在南) ; 结束状态集( 这里只有一个, 都在北) 。问题表示: 需要表示问题中的状态, 农夫等位于南p北( 每个有两种可能) 。可以采用位向量, 4 个二进制位的0p1 情况表示状态, 显而易见, 共24= 16种可能状态。从高位到低位分别表示农夫、狼、白菜和羊。0000( 整数0) 表示都在南岸, 目标状态1111( 即整数15) 表示都到了北岸。有些状态0011,0101, 0111, 0001, 1100, 1001 是不允许出现的, 因为这些状态是不安全状态。根据上述条件可以画出系统的状态图如图1

4、所示。图1 系统状态转换图其中双向的箭头表示状态可逆, 即农夫可以带着某种东西过去, 也可以带着该东西回来。箭头上的字母表示农夫所携带的东西: f( farmer) , w(wolf) , g(goat) , c( cabbage) 分别表示农夫自己、农夫携带狼、农夫携带羊、农夫携带菜过河。现在的问题转化为: 找一条合法路径( 相邻状态之间的转移合法) , 从开始状态到某个结束状态, 途中不经过不安全状态。3.1.2 算法的设计求农夫、狼、白菜和羊的当前状态的函数为每一种状态做测试, 状态安全则返回0, 否则返回1。安全性判断函数, 若状态安全则返回0 int farmer(int locat

5、ion) /判断农夫位置对0做与运算,还是原来的数字,用来判断位置return 0 != (location & 0x08); int wolf(int location) /判断狼位置 return 0 != (location & 0x04); int cabbage(int location) /判断白菜位置 return 0 != (location & 0x02); int goat(int location) /判断羊的位置return 0 !=(location & 0x01); int safe(int location) / 若状态安全则返回 true if (goat(lo

6、cation) = cabbage(location) & (goat(location) != farmer(location) ) return 0; if (goat(location) = wolf(location) & (goat(location) != farmer(location) return 0;return 1; /其他状态是安全的借助于位向量和按位运算符, 很容易描述过河动作, 这种问题表示的设计使得程序的实现比较容易。算法的基本思想: 利用队列moveto 记录可到的尚未向前探试的状态, 数组元素route i 记录状态i的路径 前一状态 , - 1 表示尚未访问

7、。则算法的高级抽象可描速为:初始状态出发点入队列;所有其他点状态标记为未访问;while ( ! isemptyqueue seq ( moveto) &( route 15 = - 1) )从moveto 取出一个状态;试探所有由这个状态出发可能到达的状态;if( 能到达的状态安全且未访问过)记录到它的路径;压入队列;精化上速算法得到问题的具体算法如下:void farmerproblem( ) int movers, i, location, newlocation; int route16; /记录已考虑的状态路径 int printmaxnum; pseqqueue moveto; m

8、oveto = createemptyqueue_seq( );/新的队列判断路径 enqueue_seq(moveto, 0x00); /初始状态为0 for (i = 0; i 16; i+) routei = -1; /-1表示没有记录过路径 route0=0; while (!isemptyqueue_seq(moveto)&(route15= -1)/队列不为空,路径未满时循环 location = frontqueue_seq(moveto); /从队头出队,location表示位置,0为北岸,1为南岸 dequeue_seq(moveto);/已出队的删除 for (movers

9、 = 1; movers = 8; movers= 1) /向左移位,movers分别0001,0010,0100,1000,也就是依次判断过河的可行性 if (0 != (location & 0x08) = (0 != (location & movers)/判断农夫和要移动的物品是否在同岸 newlocation = location(0x08|movers);/过岸 if (safe(newlocation) & (routenewlocation = -1)/判断是否安全,以及路径是否可用 routenewlocation = location; enqueue_seq(moveto

10、, newlocation);/记录路径并入队,位置改变4、运行与测试5、总结与心得“纸上得来终觉浅,绝知此事要躬行。”通过这两周的课程设计,使我对书上的的理论知识有了更深的理解,也使我对于团队合作有了新的认识,意识到团队的力量。课程设计是一个必须经历的过程,是我们理解书本知识、熟悉所学专业的一次很好实践。 在这次设计过程中,体现出自己单独设计程序的能力以及综合运用知识的能力,体会了学以致用、突出自己劳动成果的喜悦心情,从中发现自己平时学习的不足和薄弱环节,从而加以弥补。附录#include#include#define maxnum 20 typedef struct /顺序队列类型定义 i

11、nt f, r; /f表示头,r 表示尾int qmaxnum;/顺序队seqqueue ,*pseqqueue;pseqqueue createemptyqueue_seq( ) /创建队列 pseqqueue paqu = new seqqueue; if (paqu = null) coutout of space!f=paqu-r=0; return (paqu); int isemptyqueue_seq( pseqqueue paqu ) /判断 paqu 所指是否是空队列 return paqu-f=paqu-r; void enqueue_seq(pseqqueue paqu,

12、int x) /在队列中插入一元素 xif (paqu-r+1)%maxnum=paqu-f) cout队列已满.qpaqu-r=x;paqu-r=(paqu-r+1)%maxnum; void dequeue_seq(pseqqueue paqu) /删除队列头部元素 if( paqu-f=paqu-r) cout队列为空f=(paqu-f+1)%maxnum; int frontqueue_seq( pseqqueue paqu ) /对非空队列,求队列头部元素 return (paqu-qpaqu-f); int farmer(int location) /判断农夫位置对0做与运算,还是

13、原来的数字,用来判断位置return 0 != (location & 0x08); int wolf(int location) /判断狼位置 return 0 != (location & 0x04); int cabbage(int location) /判断白菜位置 return 0 != (location & 0x02); int goat(int location) /判断羊的位置return 0 !=(location & 0x01); int safe(int location) / 若状态安全则返回 true if (goat(location) = cabbage(loc

14、ation) & (goat(location) != farmer(location) ) return 0; if (goat(location) = wolf(location) & (goat(location) != farmer(location) return 0;return 1; /其他状态是安全的 void farmerproblem( ) int movers, i, location, newlocation; int route16; /记录已考虑的状态路径 int printmaxnum; pseqqueue moveto; moveto = createempty

15、queue_seq( );/新的队列判断路径 enqueue_seq(moveto, 0x00); /初始状态为0 for (i = 0; i 16; i+) routei = -1; /-1表示没有记录过路径 route0=0; while (!isemptyqueue_seq(moveto)&(route15= -1)/队列不为空,路径未满时循环 location = frontqueue_seq(moveto); /从队头出队,location表示位置,0为北岸,1为南岸 dequeue_seq(moveto);/已出队的删除 for (movers = 1; movers = 8; m

16、overs= 1) /向左移位,movers分别0001,0010,0100,1000,也就是依次判断过河的可行性 if (0 != (location & 0x08) = (0 != (location & movers)/判断农夫和要移动的物品是否在同岸 newlocation = location(0x08|movers);/过岸 if (safe(newlocation) & (routenewlocation = -1)/判断是否安全,以及路径是否可用 routenewlocation = location; enqueue_seq(moveto, newlocation);/记录路

17、径并入队,位置改变 /* 打印出路径 */ if(route15 != -1) cout过河步骤是 : = 0; location = routelocation) printi=location; i+; if (location = 0) break; int num=i-1; int temp204; int j; for(i=num;i=0;i-) for(j=3;j=0;j-) tempnum-ij=printi%2; printi/=2; temp0j=0; tempnum+1j=1; /* for(i=0;i=num;i+) for(j=0;j4;j+) couttempij ; coutendl; */ for(i=1;i=num;i+) couttttno . it; if(i%2=1) if(tempi3!=tempi-13) cout农夫带羊过南岸; if(tempi2!=tempi-12) cout农夫带白菜过南岸; if(tempi1!=tempi-11) cout农夫带狼过南岸; if(tempi3=tempi-13&tempi2=tempi-12&tempi1=tempi-11) cout农夫自己过南岸; else if(i%2=0) if(tempi3!=tempi-13) cout农夫带羊回北岸; if(tempi2

温馨提示

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

评论

0/150

提交评论