数据结构课程设计报告(农夫过河) 联系客服

发布时间 : 星期日 文章数据结构课程设计报告(农夫过河)更新完毕开始阅读1c9c3d9f51e79b89680226f5

目录

引言 ................................................... 2

1 问题描述 .............................................. 3 基本要求 ................................................ 3

2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性; ........ 3 2.2设计一个算法求解农夫过河问题,并输出过河方案; ...................... 3

3 概要设计 ............................................. 3

3.1 数据结构的设计。 .................................................... 3

3.1.1农夫过河问题的模型化 ............................................. 3 3.1.2 算法的设计 ...................................................... 4

4、运行与测试 .......................................... 6 5、总结与心得 .......................................... 7 附录 ................................................... 7 参考文献 .............................................. 13

1

引言

所谓农夫过河问题是指农夫带一只狼、一只羊和一棵白菜在河南岸, 需要安全运到北岸。一条小船只能容下他和一件物品, 只有农夫能撑船。问农夫怎么能安全过河, 当然狼吃羊, 羊吃白菜, 农夫不能将这两种或三种物品单独放在河的一侧, 因为没有农夫的照看, 狼就要吃羊, 而羊可能要吃白菜? 这类问题的实质是系统的状态问题, 要寻求的是从初始状态经一系列的安全状态到达系统的终止状态的一条路径。

2

1 问题描述

一个农夫带一只狼、一棵白菜和一只羊要从一条河的南岸过到北岸,农夫每次只能带一样东西过河,但是任意时刻如果农夫不在场时,狼要吃羊、羊要吃白菜,请为农夫设计过河方案。

基本要求

2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性; 2.2设计一个算法求解农夫过河问题,并输出过河方案;

3 概要设计

3.1 数据结构的设计。

3.1.1农夫过河问题的模型化 分析这类问题会发现以下特征:

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

图1 系统状态转换图

其中双向的箭头表示状态可逆, 即农夫可以带

着某种东西过去, 也可以带着该东西回来。箭头上的字母表示农夫所携带的东西: f( farmer) , w(wolf) , g(goat) , c( cabbage) 分别表示农夫自己、农夫携带狼、农夫携带羊、农夫携带菜过河。现在的问题转化为: 找一条合法路径( 相邻状态之间的转移合法) , 从开始状态到某个结束状态, 途中不经过不安全状态。

3

3.1.2 算法的设计

求农夫、狼、白菜和羊的当前状态的函数为每一种状态做测试, 状态安全则返回0, 否则返回1。安全性判断函数, 若状态安全则返回0

int farmer(int location) //判断农夫位置对0做与运算,还是原来的数字,用来判断位置 {

return 0 != (location & 0x08); }

int wolf(int location) //判断狼位置 { }

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(location)) && (goat(location) !=

return 0;

farmer(location)) )

if ((goat(location) == wolf(location)) && (goat(location) !=

return 0;

return 0 != (location & 0x04);

farmer(location)))

return 1; //其他状态是安全的

借助于位向量和按位运算符, 很容易描述过河动作, 这种问题表示的设计使得程序的实现比较容易。算法的基本思想: 利用队列moveTo 记录可到的尚未向前探试的状态, 数组元素route [ i] 记录状态i的路径[ 前一状态] , - 1 表示尚未访问。则算法的高级抽象可描速为: {

4