农夫过河实验报告

合集下载

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

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

数据结构课程设计报告(农夫过河)第一篇:数据结构课程设计报告(农夫过河)目录引言...................................................2 问题描述..............................................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.2设计一个算法求解农夫过河问题,并输出过河方案;概要设计3.1 数据结构的设计。

数据结构实验-农夫过河问题

数据结构实验-农夫过河问题

农夫过河问题一、实验目的掌握广度优先搜索策略,并用队列求解农夫过河问题二、实验内容问题描述:一农夫带着一只狼,一只羊和一颗白菜,身处河的南岸,他要把这些东西全部运到北岸,遗憾的是他只有一只小船,小船只能容下他和一件物品。

这里只能是农夫来撑船,同时因为狼吃羊、羊吃白菜、所以农夫不能留下羊和狼或羊和白菜在河的一边,而自己离开;好在狼属肉食动物,不吃白菜。

农夫怎么才能把所有的东西安全运过河呢?实验要求如下:(1)设计物品位置的表示方法和安全判断算法;(2)设计队列的存储结构并实现队列的基本操作(建立空队列、判空、入队、出队、取对头元素),也可以使用STL中的队列进行代码的编写;(3)采用广度优先策略设计可行的过河算法;(4)输出要求:按照顺序输出一种可行的过河方案;提示:可以使用STL中的队列进行代码编写。

程序运行结果:二进制表示:1111011011100010101100011001,0000三、农夫过河算法流程⏹Step1:初始状态0000入队⏹Step2:当队列不空且没有到达结束状态1111时,循环以下操作:⏹队头状态出队⏹按照农夫一个人走、农夫分别带上三个物品走,循环以下操作:⏹农夫和物品如果在同一岸,则计算新的状态⏹如果新状态是安全的并且是没有处理过的,则更新path[ ],并将新状态入队⏹当状态为1111时,逆向输出path[ ]数组附录一:STL中队列的使用注:队列,可直接用标准模板库(STL)中的队列。

需要#include<queue>STL中的queue,里面的一些成员函数如下(具体可以查找msdn,搜索queue class):front:Returns a reference to the first element at the front of the queue.pop:Removes an element from the front of the queuepush:Adds an element to the back of the queueempty:Tests if the queue is empty三、实验代码FarmerRiver.H#ifndef FARMERRIVER_H#define FARMERRIVER_Hint FarmerOnRight(int status); //农夫,在北岸返回1,否则返回0int WorfOnRight(int status); //狼int CabbageOnRight(int status); //白菜int GoatOnRight(int status); //羊int IsSafe(int status); //判断状态是否安全,安全返回1,否则返回0void FarmerRiver();#endifSeqQueue.h#ifndef SEQQUEUE_H#define SEQQUEUE_Htypedef int DataType;struct Queue{int Max;int f;int r;DataType *elem;};typedef struct Queue *SeqQueue;SeqQueue SetNullQueue_seq(int m);int IsNullQueue_seq(SeqQueue squeue);void EnQueue_seq(SeqQueue squeue, DataType x);void DeQueue_seq(SeqQueue);DataType FrontQueue_seq(SeqQueue);#endifFarmerRiver.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"#include "FarmerRiver.h"int FarmerOnRight(int status) //判断当前状态下农夫是否在北岸{return (0!=(status & 0x08));}int WorfOnRight(int status){return (0!=(status & 0x04));}int CabbageOnRight(int status){return (0!=(status & 0x02));}int GoatOnRight(int status){return (0!=(status & 0x01));}int IsSafe(int status) //判断当前状态是否安全{if ((GoatOnRight(status)==CabbageOnRight(status)) &&(GoatOnRight(status)!=FarmerOnRight(status)))return (0); //羊吃白菜if ((GoatOnRight(status)==WorfOnRight(status)) && (GoatOnRight(status)!=FarmerOnRight(status))) return 0; //狼吃羊return 1; //其他状态是安全的}void FarmerRiver(){int i, movers, nowstatus, newstatus;int status[16]; //用于记录已考虑的状态路径SeqQueue moveTo;moveTo = SetNullQueue_seq(20); //创建空列队EnQueue_seq(moveTo, 0x00); //初始状态时所有物品在北岸,初始状态入队for (i=0; i<16; i++) //数组status初始化为-1{status[i] = -1;}status[0] = 0;//队列非空且没有到达结束状态while (!IsNullQueue_seq(moveTo) && (status[15]==-1)){nowstatus = FrontQueue_seq(moveTo); //取队头DeQueue_seq(moveTo);for (movers=1; movers<=8; movers<<=1)//考虑各种物品在同一侧if ((0!=(nowstatus & 0x08)) == (0!=(nowstatus & movers)))//农夫与移动的物品在同一侧{newstatus = nowstatus ^ (0x08 | movers); //计算新状态//如果新状态是安全的且之前没有出现过if (IsSafe(newstatus)&&(status[newstatus] == -1)){status[newstatus] = nowstatus; //记录新状态EnQueue_seq(moveTo, newstatus); //新状态入队}}}//输出经过的状态路径if (status[15]!=-1){printf("The reverse path is: \n");for (nowstatus=15; nowstatus>=0; nowstatus=status[nowstatus]){printf("The nowstatus is: %d\n", nowstatus);if (nowstatus == 0)return;}}elseprintf("No solution.\n");}Sequeue.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"SeqQueue SetNullQueue_seq(int m){SeqQueue squeue;squeue = (SeqQueue)malloc(sizeof(struct Queue));if (squeue==NULL){printf("Alloc failure\n");return NULL;}squeue->elem = (int *)malloc(sizeof(DataType) * m);if (squeue->elem!=NULL){squeue->Max = m;squeue->f = 0;squeue->r = 0;return squeue;}else free(squeue);}int IsNullQueue_seq(SeqQueue squeue){return (squeue->f==squeue->r);}void EnQueue_seq(SeqQueue squeue, DataType x) //入队{if ((squeue->r+1) % squeue->Max==squeue->f) //是否满printf("It is FULL Queue!");else{squeue->elem[squeue->r] = x;squeue->r = (squeue->r+1) % (squeue->Max);}}void DeQueue_seq(SeqQueue squeue) //出队{if (IsNullQueue_seq(squeue))printf("It is empty queue!\n");elsesqueue->f = (squeue->f+1) % (squeue->Max); }DataType FrontQueue_seq(SeqQueue squeue) //求队列元素{if (squeue->f==squeue->r)printf("It is empty queue!\n");elsereturn (squeue->elem[squeue->f]);}main.c#include <stdio.h>#include <stdlib.h>#include "FarmerRiver.h"int main(void){FarmerRiver();return 0;}实验结果:四、实验总结。

小黄鸭过河实验报告

小黄鸭过河实验报告

一、实验目的1. 了解动物行为学的基本概念,观察动物在不同环境下的行为反应。

2. 探究小黄鸭在过河过程中的行为特点,分析其适应环境的能力。

3. 培养学生的观察、分析、总结能力。

二、实验原理动物行为学是研究动物在自然界中的行为规律和适应策略的学科。

通过观察小黄鸭过河的行为,可以了解其在不同环境下的适应能力,以及动物行为与环境因素之间的关系。

三、实验材料与工具1. 实验材料:小黄鸭、水桶、河岸、摄像机、记录表等。

2. 实验工具:摄像机、录音笔、计时器等。

四、实验方法1. 实验分组:将小黄鸭分为实验组和对照组,实验组过河,对照组在河岸观察。

2. 实验步骤:(1)将小黄鸭放入水桶中,观察其在水中的行为;(2)将水桶移至河岸,模拟小黄鸭过河的过程;(3)记录小黄鸭过河的时间、速度、路线等行为特点;(4)观察小黄鸭在过河过程中的适应能力,如游泳、潜水、攀爬等;(5)对实验数据进行统计分析。

五、实验结果与分析1. 实验结果(1)实验组小黄鸭过河的时间平均为10秒;(2)对照组小黄鸭在河岸观察的时间平均为15秒;(3)实验组小黄鸭在过河过程中,游泳、潜水、攀爬等行为均有出现。

2. 实验分析(1)实验组小黄鸭过河的时间较短,说明其具有较强的适应能力;(2)对照组小黄鸭在河岸观察的时间较长,说明其对过河环境不熟悉,适应能力较弱;(3)实验组小黄鸭在过河过程中,游泳、潜水、攀爬等行为的出现,表明其具有较强的适应环境的能力。

六、实验结论1. 小黄鸭在过河过程中具有较强的适应能力,能够通过游泳、潜水、攀爬等方式应对环境变化;2. 观察动物行为有助于了解其在自然界中的生存策略,为动物保护提供参考。

七、实验讨论1. 本实验结果表明,小黄鸭在过河过程中具有较好的适应能力,这与其在自然界中的生存环境密切相关;2. 实验过程中,对照组小黄鸭在河岸观察的时间较长,说明其在过河前需要一定的时间来熟悉环境,提高适应能力;3. 本实验为动物行为学研究提供了新的思路,有助于进一步了解动物在自然界中的生存策略。

农夫过河C语言课程设计

农夫过河C语言课程设计

农夫过河C语言课程设计一、课程目标知识目标:1. 理解C语言中基本的数据类型和语法结构;2. 学会使用C语言进行逻辑判断和循环控制;3. 掌握C语言中的函数定义和调用方法;4. 了解“农夫过河”问题的背景和解决方案。

技能目标:1. 能够运用C语言编写出解决“农夫过河”问题的程序;2. 培养逻辑思维和问题分析能力,将实际问题转化为程序代码;3. 提高编程实践能力,学会调试和修改代码,解决程序中的错误。

情感态度价值观目标:1. 激发学生对编程的兴趣,培养计算机科学素养;2. 培养学生面对问题积极思考、勇于探索的精神;3. 强调团队合作,学会与他人共同解决问题,培养沟通与协作能力。

分析课程性质、学生特点和教学要求:本课程为C语言编程课程,旨在让学生掌握C语言的基本知识,并通过解决实际问题,提高编程能力。

学生为初中生,具有一定的逻辑思维能力和数学基础。

教学要求注重实践,将理论教学与实际操作相结合,引导学生主动参与,培养其独立思考和解决问题的能力。

课程目标分解:1. 知识目标:通过讲解和实例演示,让学生掌握C语言的基本知识;2. 技能目标:通过编写“农夫过河”程序,提高学生的编程实践能力;3. 情感态度价值观目标:通过课程教学,激发学生对编程的兴趣,培养其积极思考、勇于探索的精神,以及团队合作能力。

二、教学内容1. C语言基础知识回顾:- 数据类型、变量、常量- 运算符、表达式、语句- 选择结构(if-else)- 循环结构(for、while、do-while)2. 函数定义与调用:- 函数的概念和作用- 函数的定义、声明和调用- 递归函数的原理和应用3. “农夫过河”问题分析:- 问题的描述和规则- 状态表示和状态空间- 搜索策略(深度优先、广度优先)4. 编程实践:- 设计“农夫过河”问题的算法- 编写C语言程序实现算法- 调试和优化程序5. 教学内容安排与进度:- 第一课时:C语言基础知识回顾,引入“农夫过河”问题- 第二课时:函数定义与调用,分析问题并设计算法- 第三课时:编写程序,实现“农夫过河”算法- 第四课时:调试优化程序,总结经验,展示成果教学内容关联教材章节:- 《C语言程序设计》第一章:C语言概述- 《C语言程序设计》第二章:数据类型与运算符- 《C语言程序设计》第三章:控制结构- 《C语言程序设计》第四章:函数- 《C语言程序设计》第十章:算法与程序设计实例教学内容注重科学性和系统性,结合教材章节,使学生能够在掌握C语言基础知识的基础上,学会解决实际问题,提高编程能力。

数据结构实验-农夫过河问题

数据结构实验-农夫过河问题

农夫过河问题一、实验目的掌握广度优先搜索策略,并用队列求解农夫过河问题二、实验内容问题描述:一农夫带着一只狼,一只羊和一颗白菜,身处河的南岸,他要把这些东西全部运到北岸,遗憾的是他只有一只小船,小船只能容下他和一件物品。

这里只能是农夫来撑船,同时因为狼吃羊、羊吃白菜、所以农夫不能留下羊和狼或羊和白菜在河的一边,而自己离开;好在狼属肉食动物,不吃白菜。

农夫怎么才能把所有的东西安全运过河呢?实验要求如下:(1)设计物品位置的表示方法和安全判断算法;(2)设计队列的存储结构并实现队列的基本操作(建立空队列、判空、入队、出队、取对头元素),也可以使用STL中的队列进行代码的编写;(3)采用广度优先策略设计可行的过河算法;(4)输出要求:按照顺序输出一种可行的过河方案;提示:可以使用STL中的队列进行代码编写。

程序运行结果:二进制表示:1111011011100010101100011001,0000三、农夫过河算法流程⏹Step1:初始状态0000入队⏹Step2:当队列不空且没有到达结束状态1111时,循环以下操作:⏹队头状态出队⏹按照农夫一个人走、农夫分别带上三个物品走,循环以下操作:⏹农夫和物品如果在同一岸,则计算新的状态⏹如果新状态是安全的并且是没有处理过的,则更新path[ ],并将新状态入队⏹当状态为1111时,逆向输出path[ ]数组附录一:STL中队列的使用注:队列,可直接用标准模板库(STL)中的队列。

需要#include<queue>STL中的queue,里面的一些成员函数如下(具体可以查找msdn,搜索queue class):front:Returns a reference to the first element at the front of the queue.pop:Removes an element from the front of the queuepush:Adds an element to the back of the queueempty:Tests if the queue is empty三、实验代码FarmerRiver.H#ifndef FARMERRIVER_H#define FARMERRIVER_Hint FarmerOnRight(int status); //农夫,在北岸返回1,否则返回0int WorfOnRight(int status); //狼int CabbageOnRight(int status); //白菜int GoatOnRight(int status); //羊int IsSafe(int status); //判断状态是否安全,安全返回1,否则返回0void FarmerRiver();#endifSeqQueue.h#ifndef SEQQUEUE_H#define SEQQUEUE_Htypedef int DataType;struct Queue{int Max;int f;int r;DataType *elem;};typedef struct Queue *SeqQueue;SeqQueue SetNullQueue_seq(int m);int IsNullQueue_seq(SeqQueue squeue);void EnQueue_seq(SeqQueue squeue, DataType x);void DeQueue_seq(SeqQueue);DataType FrontQueue_seq(SeqQueue);#endifFarmerRiver.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"#include "FarmerRiver.h"int FarmerOnRight(int status) //判断当前状态下农夫是否在北岸{return (0!=(status & 0x08));}int WorfOnRight(int status){return (0!=(status & 0x04));}int CabbageOnRight(int status){return (0!=(status & 0x02));}int GoatOnRight(int status){return (0!=(status & 0x01));}int IsSafe(int status) //判断当前状态是否安全{if ((GoatOnRight(status)==CabbageOnRight(status)) && (GoatOnRight(status)!=FarmerOnRight(status)))return (0); //羊吃白菜if ((GoatOnRight(status)==WorfOnRight(status)) && (GoatOnRight(status)!=FarmerOnRight(status))) return 0; //狼吃羊return 1; //其他状态是安全的}void FarmerRiver(){int i, movers, nowstatus, newstatus;int status[16]; //用于记录已考虑的状态路径SeqQueue moveTo;moveTo = SetNullQueue_seq(20); //创建空列队EnQueue_seq(moveTo, 0x00); //初始状态时所有物品在北岸,初始状态入队for (i=0; i<16; i++) //数组status初始化为-1{status[i] = -1;}status[0] = 0;//队列非空且没有到达结束状态while (!IsNullQueue_seq(moveTo) && (status[15]==-1)){nowstatus = FrontQueue_seq(moveTo); //取队头DeQueue_seq(moveTo);for (movers=1; movers<=8; movers<<=1)//考虑各种物品在同一侧if ((0!=(nowstatus & 0x08)) == (0!=(nowstatus & movers)))//农夫与移动的物品在同一侧{newstatus = nowstatus ^ (0x08 | movers); //计算新状态//如果新状态是安全的且之前没有出现过if (IsSafe(newstatus)&&(status[newstatus] == -1)){status[newstatus] = nowstatus; //记录新状态EnQueue_seq(moveTo, newstatus); //新状态入队}}}//输出经过的状态路径if (status[15]!=-1){printf("The reverse path is: \n");for (nowstatus=15; nowstatus>=0; nowstatus=status[nowstatus]){printf("The nowstatus is: %d\n", nowstatus);if (nowstatus == 0)return;}}elseprintf("No solution.\n");}Sequeue.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"SeqQueue SetNullQueue_seq(int m){SeqQueue squeue;squeue = (SeqQueue)malloc(sizeof(struct Queue));if (squeue==NULL){printf("Alloc failure\n");return NULL;}squeue->elem = (int *)malloc(sizeof(DataType) * m);if (squeue->elem!=NULL){squeue->Max = m;squeue->f = 0;squeue->r = 0;return squeue;}else free(squeue);}int IsNullQueue_seq(SeqQueue squeue){return (squeue->f==squeue->r);}void EnQueue_seq(SeqQueue squeue, DataType x) //入队{if ((squeue->r+1) % squeue->Max==squeue->f) //是否满printf("It is FULL Queue!");else{squeue->elem[squeue->r] = x;squeue->r = (squeue->r+1) % (squeue->Max);}}void DeQueue_seq(SeqQueue squeue) //出队{if (IsNullQueue_seq(squeue))printf("It is empty queue!\n");elsesqueue->f = (squeue->f+1) % (squeue->Max); }DataType FrontQueue_seq(SeqQueue squeue) //求队列元素{if (squeue->f==squeue->r)printf("It is empty queue!\n");elsereturn (squeue->elem[squeue->f]);}main.c#include <stdio.h>#include <stdlib.h>#include "FarmerRiver.h"int main(void){FarmerRiver();return 0;}实验结果:四、实验总结。

数据结构农夫过河项目课报告

数据结构农夫过河项目课报告

数据结构农夫过河项目课报告数据结构-农夫过河项目课报告-计算机四班第七组项目名称:农夫过河算法与数据结构设计专业班级:计算机科学与技术四班学生姓名:王喆指导教师: 完成日期:2015年12月28日数据结构-农夫过河项目课报告-计算机四班第七组农夫过河算法与数据结构设计摘要农夫过河问题即一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸,他需要把这些东西全部运到河的北岸。

而他只有一条小船,且这只小船小到只能容下他和一件物品,另外只有农夫能撑船。

农夫不能留下狼和羊自己离开,也不能留下白菜和羊自己离开,更不能留下狼,羊和白菜而独自离开,因为没有农夫的照看,狼就要吃掉羊,而羊又要吃掉白菜。

好在狼是是肉动物,它不吃白菜,问农夫应该采取什么方案才能将所有的东西安全地从河的南岸运到北岸,这类农夫问题是一个传统的数据结构问题,农夫过河问题根据图求解的搜索过程可采用两种不同的策略:一种是图的深度优先遍历搜索,另外一种是广度优先遍历搜索。

如果采用深度优先遍历搜索,则需要采用递归的方式来编写程序,而这种程序的系统的开销比较大,如果采用广度优先搜索,则可以借助队列的方式,这种方式开销较小。

关键字:农夫过河,广度优先遍历搜索,队列,深度优先遍历搜索,递归。

2数据结构-农夫过河项目课报告-计算机四班第七组目录1.前言…………………………………………………………42.设计任务与技术要求………………………………………43.总体设计方案………………………………………………44.数据结构和算法的设计……………………………………55.程序测试与调试(一)……………………………………7 6.程序测试与调试(二)..........................................9 7.程序出现的问题及修改情况....................................14 8.心得与体会.........................................................14 参考文献 (15)3数据结构-农夫过河项目课报告-计算机四班第七组1.前言课程研究项目是《数据结构》课程学习的重要方式之一,也是《数据结构》课程学习的重要组成部分之一。

农夫过河问题的求解

农夫过河问题的求解
void ListTraverse(LinkType p, status(*visit)(LinkType q));
//从p(P!=NULL)指示的结点开始,依次对每个结点调用函数visit
其中部分操作的伪码算法如下:
BOOL InitList(OrderdeList &L)
{
if(MakeNode(head,ˊˊ)){ //头结点的虚设元素为空格符ˊˊ
{
//分配由p指向的数据元素为e、后继为“空”的结点,并返回TRUE,
//若分配失败,则返回FALSE
p=(Link Type)malloc(sixeof(Node Type));
if(!p)return FALSE;
p->data=e;p->next=NULL; return TRUE;
}
void freeNode(LinkType &p)
//销毁有序链表L
bool Listempty(OrderedList L);
//若L不存在或为“空表”,则返回TRUE,否则返回FALSE
int ListLengty(OrderedList L);
//返回链表的长度
Linktype GetelemPos(OrderedList L, int pos);
构造有序集算法createset读入n个元素逐个用locateelem判定不在当前集合中及确定插入位置后才用insertafetr插入到有序集中所以时间复杂度是on求并集算法union利用集合的有序性将两个集合的个元素不重复地依次利用append插入到当前并集的末尾故可在omn时间内完成
实验报告
题目:编制一个演示农夫过河问题的求解的程序
per=L.head; p=pre->next;

数据结构课程设计-农夫过河-实验报告.

数据结构课程设计-农夫过河-实验报告.

一、需求分析描述1、针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,可定义一个结构体来实现对四个对象狼、羊、白菜和农夫的表示。

对于起始岸和目的岸,可以用0或者1来表示,以实现在程序设计中的简便性。

2、题目要求给出四种事物的过河步骤,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,进行下一步试探。

这就需要使用循环或者递归算法,避免随机盲目运算且保证每种情况均试探到。

3、题目要求求出农夫带一只羊,一条狼和一颗白菜过河的办法,所以依次成功返回运算结果后,需要继续运算,直至求出结果,即给出农夫的过河方案。

4、输出界面要求具有每一步中农夫所带对象及每步之后各岸的物体,需要定义不同的数组来分别存储上述内容,并使界面所示方案清晰简洁。

二、系统架构设计1.设计中首先涉及的就是数据类型的定义,首先,定义一个结构体用来存放农夫、狼、羊、白菜的信息。

具体定义为:struct Condition{int farmer;int wolf;int sheep;int cabbage;};定义了一个结构体数组Condition conditions[100],定义状态数组用来记录他们过河的状态0:起始岸;1:目的岸;程序中定义的char action100数组用来存放各个物件以及人过河或返回的说明语句。

2.程序中定义的子函数有:2.1 将狼带到目的岸以及带回起始岸的函数takeWolfOver()和takeWolfBack ();takeWolfOver()函数中将conditions[i+1].wolf=1,白菜、羊的状态不变,同时要有action[i]=" take wolf over."将狼带到目的岸语句;takeWolfBack()函数中将conditions[i+1].wolf=0,白菜、羊的状态不变,同时要有action[i]=" take wolf back."将狼带回起始岸语句。

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

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

目录引言 (2)1 问题描述 (2)基本要求 (2)2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性; (2)2.2设计一个算法求解农夫过河问题,并输出过河方案; (2)3 概要设计 (2)3.1数据结构的设计。

(2)3.1.1农夫过河问题的模型化 (2)3.1.2 算法的设计 (3)4、运行与测试 (5)5、总结与心得 (6)附录 (6)参考文献 (12)引言所谓农夫过河问题是指农夫带一只狼、一只羊和一棵白菜在河南岸, 需要安全运到北岸。

一条小船只能容下他和一件物品, 只有农夫能撑船。

问农夫怎么能安全过河, 当然狼吃羊, 羊吃白菜, 农夫不能将这两种或三种物品单独放在河的一侧, 因为没有农夫的照看, 狼就要吃羊, 而羊可能要吃白菜? 这类问题的实质是系统的状态问题, 要寻求的是从初始状态经一系列的安全状态到达系统的终止状态的一条路径。

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

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

3.1.1农夫过河问题的模型化分析这类问题会发现以下特征:有一组状态( 如农夫和羊在南, 狼和白菜在北) ; 从一个状态可合法地转到另外几个状态( 如农夫自己过河或农夫带着羊过河) ; 有些状态不安全( 如农夫在北, 其他东西在南) ; 有一个初始状态( 都在南) ; 结束状态集( 这里只有一个, 都在北) 。

问题表示: 需要表示问题中的状态, 农夫等位于南P北( 每个有两种可能) 。

可以采用位向量, 4 个二进制位的0P1 情况表示状态, 显而易见, 共24= 16种可能状态。

从高位到低位分别表示农夫、狼、白菜和羊。

趣味数学教案—农夫过河

趣味数学教案—农夫过河

趣味数学教案—农夫过河-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN农夫过河教学目标1、知识与能力:通过农夫过河的数学逻辑问的题,探讨研究找到解决问题的办法和养成自己动脑动手的解决问题的能力。

2、过程与方法:通过以角色扮演的形式让学生自己动脑动手寻找答案和探讨解决问题的方法。

3、态度价值观:知道数学有很多有趣的东西,培养爱科学的情感。

教师准备1. 数学课件。

2、做“狼、羊、白菜、农夫”头饰。

3、准备四张纸分别写上“狼、羊、白菜、农夫”。

教学过程一、谈话导入介绍我国著名的数学家华罗庚爷爷。

数学家华罗庚生平介绍,主要科学业绩,对数学的贡献等等。

介绍华罗庚爷爷的话。

“数学本身,也是无穷的美妙,认为数学枯燥,是不正确的,就像站在花园外面,说花园枯燥无味一样,只要你踏进大门,随时会发现数学有许多有趣的东西。

”数学并不是几个数字算来算去,它的学问大着呢。

下面这道题能引起你的兴趣吗?二、创设情境1、出示数学问题:有一个农夫带一匹狼、一只羊和一棵白菜过河(从河的东岸到西岸)。

如果没有农夫看管,则狼要吃羊,羊要吃白菜。

但是船很小,只够农夫带一样东西过河。

2、图片演示。

(一条河;一边是对岸;另一边是河岸,有农夫、狼、羊、白菜)三、探究学习1、以小组表演形式(演示出河的位置)和讨论形式解题第一步是什么必须是什么(农夫和羊先过河)第二步是什么(农夫自己回来)第三步是什么2、全班学生汇报交流问题的突破口在——狼与白菜能够共存!农夫、狼、羊、白菜和船组成了这个系统。

系统中各要素是一个整体,都依赖农夫过河;最大的问题是“船很小,只够农夫带一样东西过河”和“没有农夫看管,则狼要吃羊,羊要吃白菜”的冲突。

我们联系已知条件,做了一系列的分析实验,但是比较其他方案不能实现所有要素都安全过河。

最后得出以上方案。

具体描述如下:第一步:把羊带过河,坐船返回;第二步:把狼带过河,带羊返回;第三步:将羊放在这一岸后,带白菜过河;第四步:坐船返回,把羊带过河。

实验6:农夫、狼、羊和菜问题-推荐下载

实验6:农夫、狼、羊和菜问题-推荐下载
1,1,1,1)
(0,1,0,1)
(1,1,0,1)
/*定义图的顶点类型*/
/*最大顶点个数*/
int vexnum,e; VexType vex[VEX-NUM]; int adj[VEX-NUM][VEX-NUM];
}AdjGraph; 六、算法思想:
在这个问题中,首先需要自动生成图的邻接矩阵存储,具体方法是先生成各种 安全状态结点,存放在顶点向量中;再根据状态之间的转换关系形成顶点之间 的所有边,保存在邻接矩阵中。在建立了图的邻接矩阵存储结构后,利用深度 优先搜索思想求出从顶点(0,0,0,0)到顶点(1,1,1,1)的一条简单路 径。
(Farmer,Wolf,Sheep,Veget) (!Farmer,Wolf,!Sheep,Veget) (4)当农夫和菜在相同位置时,表示农夫带菜过河,即当 Farmer=Veget 时: (Farmer,Wolf,Sheep,Veget) (!Farmer,Wolf,Sheep,!Veget) 在这 16 种状态中,有些状态是不安全的,是不允许出现的,如(1,1,0,0) 表示农夫和狼在右岸,而羊和菜在左岸,这样羊会吃掉菜。如果从 16 种状态中 删去这些不安全状态,将剩余的安全状态之间根据上面的转换关系连接起来, 就得到如下图所示的图。
七、实验程序:
#include<stdio.h> #define VEX_NUM 10 typedef enum{FALSE,TRUE}Boolean; typedef struct { int Farmer,Wolf,Sheep,Veget; }VexType; typedef struct { int vexnum,e; VexType vexs[VEX_NUM]; int adj[VEX_NUM][VEX_NUM]; }AdjGraph; Boolean visited[VEX_NUM]; int path[VEX_NUM];

过河问题实验报告

过河问题实验报告

if(a[i][3]==0) printf("farmer ");
if(a[i][0]&&a[i][1]&&a[i][2]&&a[i][3]) printf("none");

printf("
");
printf("west: ");
if(a[i][0]==1) printf("wolf ");
if(a[i][1]==1) printf("goat ");
if (i == -1) { search(Step + 1); }
else if (a[Step][i] == a[Step][3]) {
a[Step + 1][i] = a[Step + 1][3]; search(Step + 1); } } 每次循环从-1 到 2 依次代表农夫渡河时为一人、带狼、带羊、带白菜通过, 利用语句 “b[Step] = i”分别记录每一步中农夫的渡河方式,“a[Step + 1][i] = a[Step + 1][3]”即利用赋值方式使该项与农夫一同到对岸或者回到本岸。若 渡河成功,则依次输出渡河方式。 “i <= 2”即递归操作的界限,当若 i=2 时 仍无符合条件的方式,则渡河失败。
east east east
east east
: farmer goat wolf cabbage west : none
The 1 time
: wolf cabbage
west : farmer goat
------ farmer
: farmer wolf cabbage

农夫过河问题

农夫过河问题

课程设计题目:农夫过河一.问题描述一个农夫带着一只狼、一只羊和一箩白菜,身处河的南岸。

他要把这些东西全部运到北岸。

他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。

过河有以下规则:(1) 农夫一次最多能带一样东西(或者是狼、或者是羊、或者是白菜)过河;(2) 当农夫不在场是狼会吃羊;(3) 当农夫不在场是羊会吃掉白菜。

现在要求为农夫想一个方案,能将3 样东西顺利地带过河。

从出事状态开始,农夫将羊带过河,然后农夫将羊待会来也是符合规则的,然后农夫将羊带过河仍然是符合规则的,但是如此这般往返,搜索过程便进入了死循环,因此,在这里,采用改进的搜索算法进行搜索。

二.基本要求(1) 为农夫过河问题抽象数据类型,体会数据模型在问题求解中的重要性;(2) 要求利用数据结构的方法以及C + +的编程思想来完成问题的综合设计;(3) 在问题的设计中,使用深度优先遍历搜索方式,避免死循环状态;(4) 设计一个算法求解农夫过河问题,并输出过河方案;(5) 分析算法的时间复杂度。

三.概要设计(1) 数据结构的设计typedef struct // 图的顶点{int farmer; // 农夫int wolf; // 狼int sheep; // 羊int veget; // 白菜}Vertex;设计Vertex 结构体的目的是为了存储农夫、狼、羊、白菜的信息,因为在遍历图的时候,他们的位置信息会发生变化,例如1111 说明他们都在河的北岸,而0000 说明他们都在河的南岸。

t ypedef struct{int vertexNum; // 图的当前顶点数Vertex vertex[VertexNum]; // 顶点向量(代表顶点)bool Edge[VertexNum][VertexNum]; // 邻接矩阵 . 用于存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关}AdjGraph; // 定义图的邻接矩阵存储结构存储图的方法是用邻接矩阵,所以设计一个简单的AdjGraph 结构体是为了储图的顶点数与边数,农夫过河问题我采用的是图的深度优先遍历思想。

商人过河实验报告

商人过河实验报告

数学模型实验—实验报告6学院:工商学院专业:电气二类(计算机)姓名:辛文辉尚磊张亨学号:___ 2012484019 2012484091 2012484055 ____ 实验时间:__ 3.18 ____ 实验地点:b3一、实验项目:Matlab程序设计安全渡河问题可以看成一个多步决策过程。

每一步,即船由此岸驶向彼岸或从彼岸驶回此岸,都要对船上的人员(商人随从各几人)作出决策,在保证安全的前提下(两岸的商人数都不比随从数少),在有限步内使人员全部过河。

用状态(变量)表示某一岸的人员状况,决策(变量)表示船上的人员状况,可以找出状态随决策变化的规律。

问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到渡河的目的。

此类智力问题经过思考,可以拼凑出一个可行方案。

但是,我们现在希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。

二、实验目的和要求a.了解Matlab程序设计有关基本操作b.掌握有关程序结构三、实验内容允许的状态向量0 00 10 20 30 40 50 60 70 80 90 100 111 12 23 34 45 56 67 78 89 910 1011 011 111 211 311 411 511 611 711 811 911 10允许的决策向量:0 10 20 30 40 50 61 01 12 02 12 23 03 13 23 34 04 14 25 05 16 0过河步骤:第1步:0商5仆过河,0商1仆返回第2步:5商1仆过河,1商1仆返回第3步:3商3仆过河,1商1仆返回第4步:3商3仆过河,1商1仆返回第5步:3商3仆过河,完成过河过程中状态变化:步骤此岸商此岸仆方向彼岸商彼岸仆1 11 6 ==> -8 -311 7 <== -8 -42 6 6 ==> -3 -37 7 <== -4 -43 4 4 ==> -1 -15 5 <== -2 -24 2 2 ==> 1 13 3 <== 0 05 0 0 ==> 3 3对于经典的3对商仆、小船容量为2人时的问题,运行程序求得结果如下11对商仆,小船容量为6人时,运行程序求得结果如下:图 3 11对商仆、小船容量为6时的求解结果事实上,11对商仆时的状态空间如图:图 4 12对商仆时的状态空间显然的船容量必须至少保证状态转移能够沿对角线方向向下移动,问题才会有解。

数据结构与算法专题实验实验报告-八皇后-背包问题的求解-农夫过河

数据结构与算法专题实验实验报告-八皇后-背包问题的求解-农夫过河

八皇后问题1.问题描述设在初始状态下在国际象棋的棋盘上没有任何棋子(这里的棋子指皇后棋子)。

然后顺序在第1行,第2行……第8行上布放棋子。

在每一行中共有8个可选择的位置,但在任一时刻棋盘的合法布局都必须满足3个限制条件(1)任意两个棋子不得放在同一行(2)任意两个棋子不得放在同一列上(3)任意棋子不得放在同一正斜线和反斜线上。

2.基本要求编写求解并输出此问题的一个合法布局的程序。

3、实现提示:在第i行布放棋子时,从第1列到第8列逐列考察。

当在第i行第j列布放棋子时,需要考察布放棋子后在行方向、列方向、正斜线和反斜线方向上的布局状态是否合法,若该棋子布放合法,再递归求解在第i+1行布放棋子;若该棋子布放不合法,移去这个棋子,恢复布放该棋子前的状态,然后再试探在第i行第j+1列布放棋子。

4 程序代码#include<iostream.h>#include<stdio.h>static char Queen[8][8];static int a[8];static int b[15];static int c[15];static int QueenNum=0;//记录总的棋盘状态数void qu(int i);//参数i代表行int main(){int Line,Column;//棋盘初始化,空格为*,放置皇后的地方为@ for(Line=0;Line<8;Line++){a[Line]=0; //列标记初始化,表示无列冲突for(Column=0;Column<8;Column++)Queen[Line][Column]='*';}//主、从对角线标记初始化,表示没有冲突for(Line=0;Line<15;Line++)b[Line]=c[Line]=0;qu(0);return 0;}void qu(int i){int Column;for(Column=0;Column<8;Column++){if(a[Column]==0&&b[i-Column+7]==0&&c[i+Column]==0) //如果无冲突{Queen[i][Column]='Q'; //放皇后a[Column]=1;//标记,下一次该列上不能放皇后b[i-Column+7]=1;//标记,下一次该主对角线上不能放皇后c[i+Column]=1;//标记,下一次该从对角线上不能放皇后if(i<7) qu(i+1); //如果行还没有遍历完,进入下一行else//否则输出{//输出棋盘状态int Line,Column;cout<<"第"<<++QueenNum<<"种状态为:"<<endl;for(Line=0;Line<8;Line++){for(Column=0;Column<8;Column++)cout<<Queen[Line][Column]<<" ";cout<<endl;}cout<<endl;getchar();}/*如果前次的皇后放置导致后面的放置无论如何都不能满足要求,则回溯,重置*/Queen[i][Column]='*';a[Column]=0;b[i-Column+7]=0;c[i+Column]=0;}}}5 程序结果题目2 背包问题的求解1.问题描述假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,…w n的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+w m=T,要求找出所有满足上述条件的解。

农夫狼羊实验报告(3篇)

农夫狼羊实验报告(3篇)

第1篇一、实验背景农夫狼羊实验是由美国心理学家所罗门·阿希(Solomon Asch)于1951年设计的一个心理学实验,旨在研究群体压力对个体判断的影响。

实验通过模拟一个农夫、狼和羊的情境,观察个体在面对群体一致性压力时的行为变化。

二、实验目的1. 探究群体压力对个体判断的影响程度。

2. 分析个体在群体中的从众心理。

3. 研究个体在群体压力下的心理变化。

三、实验材料1. 农夫、狼、羊的图片若干。

2. 实验指导语。

四、实验步骤1. 实验分组:将参与者随机分为若干小组,每组人数为5-7人。

2. 实验情境:向每个小组展示农夫、狼和羊的图片,并要求参与者判断狼和羊的数量。

3. 群体压力模拟:在小组讨论过程中,故意安排一名从众者,其判断与大多数人一致,但与真实判断不符。

4. 记录结果:记录每个参与者最终的判断结果。

五、实验结果与分析1. 实验结果显示,在群体压力下,约75%的参与者选择了从众,即接受了从众者的错误判断。

2. 从众者在群体中的地位越高,其判断结果对其他成员的影响越大。

3. 在群体压力下,个体的判断能力明显下降,容易受到他人观点的影响。

六、实验结论1. 群体压力对个体判断具有显著影响,个体在群体中容易产生从众心理。

2. 个体在群体压力下的判断能力下降,容易受到他人观点的影响。

3. 在现实生活中,我们应该学会独立思考,避免盲目从众。

七、实验启示1. 在面对群体压力时,要保持独立思考,坚持自己的判断。

2. 要学会倾听他人的意见,但不要盲目从众。

3. 在团队协作中,要尊重每个人的观点,共同探讨问题。

八、实验局限性1. 实验情境较为简单,可能与现实生活中的复杂情况存在差异。

2. 实验结果可能受到参与者个体差异的影响。

九、未来研究方向1. 研究不同文化背景下群体压力对个体判断的影响。

2. 探究群体压力对不同类型个体的影响差异。

3. 研究如何有效应对群体压力,提高个体判断能力。

十、总结农夫狼羊实验为我们揭示了群体压力对个体判断的影响,以及个体在群体中的从众心理。

农夫过河

农夫过河

数学与计算机学院数据结构实验报告本实验的目的是进一步理解顺序表和队列的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。

一、【问题描述】一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸。

他要把这些东西全部运到北岸。

他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。

如果农夫在场,则狼不能吃羊,羊不能吃白菜,否则狼会吃羊,羊会吃白菜,所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,而狼不吃白菜。

请求出农夫将所有的东西运过河的方案。

二、【数据结构设计】求解这个问题的简单的方法是一步一步进行试探,每一步搜索所有可能的选择,对前一步合适的选择再考虑下一步的各种方案。

要模拟农夫过河问题,首先需要对问题中每个角色的位置进行描述。

一个很方便的办法是用四位二进制数顺序分别表示农夫、狼、白菜和羊的位置。

用0表示农夫或者某东西在河的南岸,1表示在河的北岸。

例如整数5(其二进制表示为0101) 表示农夫和白菜在河的南岸,而狼和羊在北岸。

现在问题变成:从初始状态二进制0000(全部在河的南岸) 出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸)为最终目标,并且在序列中的每一个状态都可以从前一状态到达。

为避免瞎费功夫,要求在序列中不出现重复的状态。

实现上述求解的搜索过程可以采用两种不同的策略:一种是广度优先(breadth_first) 搜索,另一种是深度优先(depth_first) 搜索。

本书只介绍在广度优先搜索方法中采用的数据结构设计。

广度优先就是在搜索过程中总是首先搜索下面一步的所有可能状态,再进一步考虑更后面的各种情况。

要实现广度优先搜索,可以使用队列。

把下一步所有可能的状态都列举出来,放在队列中,再顺序取出来分别进行处理,处理过程中把再下一步的状态放在队列里……。

由于队列的操作遵循先进先出的原则,在这个处理过程中,只有在前一步的所有情况都处理完后,才能开始后面一步各情况的处理。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

“数据结构与算法综合实验”课程设计报告题目:农夫过河问题学院计算机科学技术年级2014级专业计算机科学与技术学号********姓名高晗日期2016年3月30日星期三成绩评语黑龙江大学计算机科学技术学院、软件学院《数据结构与算法综合实验》报告1.系统概述(1)一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸,他要把这些东西全部运到北岸。

他面前只有一只小船,船只能容下他和一件物品,另外只有农夫才能撑船。

如果农夫在场,则狼不能吃羊,羊不能吃白菜;否则狼会吃羊,羊会吃白菜。

所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,但是狼不吃白菜。

要求给出农夫将所有东西运过河的方案。

(2)为农夫过河问题抽象数据模型,体会数据模型在求解问题中的重要作用。

(3)掌握顺序表和队列的逻辑结构和存储结构。

2.系统需求分析(1)针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,可定义一个结构体来实现对四个对象狼、羊、白菜和农夫的表示。

对于起始岸和目的岸,可以用0或者1来表示,以实现在程序设计中的简便性。

(2)题目要求给出四种事物的过河步骤,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,进行下一步试探。

这就需要使用循环或者递归算法,避免随机盲目运算且保证每种情况均试探到,不接受非法输入。

(3)题目要求求出农夫带一只羊,一条狼和一颗白菜过河的办法,所以依次成功返回运算结果后,需要继续运算,直至求出结果,即给出农夫的过河方案。

输出界面要求具有每一步中农夫所带对象及每步之后各岸的物体,需要定义不同的数组来分别存储上述内容,并使界面所示方案清晰简洁。

(4)实验运行环境为VC++6.0.3.系统概要设计(1)数据结构设计要模拟农夫过河的问题,用四位二进制数顺序分别表示农夫,狼,羊,白菜的位置。

用0表示农夫或某种东西在河的南岸,1表示在河的北岸。

则问题的初始状态是整数(二进制数表示为0000);问题的终结状态是整数15(二进制表示为1111)。

用一个整数队列MoveTo把搜索过程中所有可能达到的状态都保存起来。

队列中的每一个元素表示一个可以到达的中间状态。

另外用一个整数数组route记录被访问过的状态,以及已经被发现的能够到达这些状态的前驱。

数组只需使用16个元素,每个元素的初始化值均为-1,每当队列中加入一个新状态时,数组中以该状态做下标的元素改为到达这一状态的前一状态的下标值。

所以数组的第i个元素不仅记录状态i是否被过,同时还保存该状态的前驱状态下标。

算法结束后可以利用route数组元素的值生成一个正确的状态路径。

系统状态转换结构如图1所示:图1系统状态转换结构图(2)软件结构设计农夫过河管理系统根据需求分析中的功能分析,可以提炼出主要有搜索功能,判断事物安全功能,输出过河方案功能。

而搜索功能又可以利用不同算法,如广度优先算法,深度优先算法等等。

判断事物安全功能需要将事物位置进行分析,通过位置分布的代码来判断当前状态是否安全,使用“与”位操作来考察狼和羊、羊和白菜是否在同一侧,且它们与农夫不一侧。

若是,该状态即为不安全状态,否则为安全状态。

若一个状态已经被访问过,或只有农夫一人从南岸过到北岸,则该状态被判为无效状态。

输出功能就是将过河方案在屏幕上进行显示。

系统软件结构如图1所示图1农夫过河管理系统软件模块结构图4.系统详细设计与实现(1)搜索算法设计搜索过程可利用广度优先搜索算法从初始状态二进制0000(全部在河的南岸)出发,寻找一种全部由安全状态构成的状态序列,它以二进制1111(全部到达河的北岸)为最终目标,并且在序列中的每一个状态都可以从前一个状态得到。

为避免重复,要求在序列中不出现重复的状态。

(2)确定状态的安全有效性的功能模块设计通过位置分布的代码来判断当前状态是否安全,使用“与”位操作来考察狼和羊、羊和白菜是否在同一侧,且它们与农夫不一侧。

若是,该状态即为不安全状态,否则为安全状态。

若一个状态已经被访问过,或只有农夫一人从南岸过到北岸,则该状态被判为无效状态。

若状态安全且有效,则返回1,否则返回0。

该模块算法流程图如图2所示。

图2 确定状态的安全有效性的功能模块设计算法流程图(3)输出模块设计输出农夫过河问题的可行性方案时,可从目标状态(1111)开始,将其记入队列(或栈)中,然后再找出其前驱,记入队列(或栈)中,然后在找其前驱,…,直到找到的是开始状态(0000)为止。

要求输出时根据位置分布代码(即4位二进制数)各个位置上的0、1代码所表示的含义输出容易理解的文字。

5.系统测试对于该程序而言并没有实际输入,需要观察的就是输出结果。

对于该程序的测试及其测试用例如表3所示。

表3输出测试用例测试内容测试用例预期结果实际结果输出过河方案具体步骤无第0步:南岸农夫狼白菜羊北岸第1步:南岸狼白菜北岸农夫羊第2步:南岸农夫狼白菜北岸羊第3步:南岸狼北岸农夫羊白菜第4步:南岸农夫狼羊北岸白菜第5步:南岸羊北岸农夫狼白菜第6步:南岸农夫羊北岸狼白菜第7步:南岸北岸农夫狼白菜羊与预期结果相同6.小结(1)通过这2周的程序设计使我了解到了自己在数据结构方面的不足,也坚定了我学好编程的信心。

(2)采用广度优先的算法,利用数组只能记寻前一个前驱,导致另一个路径的丢失,不是很令人满意,所以采用第二种算法,深度优先算法,利用栈来记录路径前驱。

参考文献[1] 严蔚敏,李冬梅,吴伟民. 数据结构(C语言版)[M]. 北京:人民邮电出版社,2011:54-110.1.广度优先算法#include<iostream>#include<cstdlib>#define MAXNUM 20using namespace std;typedef struct //顺序队列类型定义{int f, r; //f表示头,r 表示尾int q[MAXNUM];//顺序队}SqQueue ,*SqQueuePtr;SqQueuePtr createEmptySQueue()//创建空队列{SqQueuePtr squeue = new SqQueue;if(squeue == NULL){cout<<"申请内存失败"<<endl;exit(0);}squeue->f=squeue->r=0;return squeue;}bool isEmptyQueue(SqQueuePtr squeue)//判断是否空队列{return (squeue->f==squeue->r);}void enQueue(SqQueuePtr squeue,int x)//向队列中插入元素x {if((squeue->r+1)%MAXNUM==squeue->f){cout<<"队列已满"<<endl;}elsesqueue->q[squeue->r]=x;squeue->r=(squeue->r+1)%MAXNUM;}}void deQueue(SqQueuePtr squeue)//出对{if(isEmptyQueue(squeue))cout<<"对列为空"<<endl;elsesqueue->f=(squeue->f+1)%MAXNUM;}int getHead(SqQueuePtr squeue)//对非空队列,求队列头部元素{if(squeue->f != squeue->r)return squeue->q[squeue->f];}bool farmerLocation(int location) //判断农夫位置对0做与运算,还是原来的数字,用来判断位置{return 0 != (location & 0x08);}bool wolfLocation(int location) //判断狼位置{return 0 != (location & 0x04);}bool cabbageLocation(int location) //判断白菜位置{return 0 != (location & 0x02);}bool goatLocation(int location) //判断羊的位置{return 0 !=(location & 0x01);}/* 其中一共有两种状态是不安全的:狼和羊单独在一起;羊和白菜单独在一起*/bool isSafe(int location) // 若状态安全则返回true{if ((goatLocation(location) == cabbageLocation(location)) //羊和白菜单独在一起&& (goatLocation(location) !=farmerLocation(location)) )return 0;if ((goatLocation(location) == wolfLocation(location))&& (goatLocation(location) !=farmerLocation(location)))//狼和羊单独在一起return 0;return 1; //其他状态是安全的}void farmerProblem(){int movers, i, location, newlocation;int route[16]; //记录已考虑的状态路径int print[MAXNUM];SqQueuePtr moveTo;moveTo = createEmptySQueue();//新的队列判断路径enQueue(moveTo, 0x00); //初始状态为0for (i = 0; i < 16; i++)route[i] = -1; //-1表示没有记录过路径route[0]=0;while (!isEmptyQueue(moveTo)&&(route[15]== -1))//队列不为空,路径未满时循环{location = getHead(moveTo); //从队头出队,location表示位置,0为北岸,1为南岸deQueue(moveTo);//已出队的删除for (movers = 1; movers <= 8; movers<<= 1)//向左移位,movers分别0001,0010,0100,1000, //也就是依次判断过河的可行性{if ((0 != (location & 0x08)) == (0 != (location & movers)))//判断农夫和要移动的物品是否在同岸{newlocation = location^(0x08|movers);//过岸if (isSafe(newlocation) && (route[newlocation] == -1))//判断是否安全,以及路径是否可用{route[newlocation] = location;enQueue(moveTo, newlocation);//记录路径并入队,位置改变}}}}/* 打印路径*/if(route[15] != -1){cout<<"过河步骤是: "<<endl;cout<<"\t\t南岸\t\t\t北岸"<<endl;i=7;for(location = 15; location >= 0; location = route[location]){print[i]=location;i--;if (location == 0)break;}for(int j=i+1;j<=7;j++){cout<<"第"<<j<<"步:";switch(print[j]){case 0: cout<<"\t\t农夫狼白菜羊\t\t\t"<<endl;break;case 1: cout<<"\t\t农夫狼白菜\t\t羊"<<endl;break;case 2: cout<<"\t\t农夫狼羊\t\t白菜"<<endl;break;case 4: cout<<"\t\t农夫白菜羊\t\t\t狼"<<endl;break;case 6: cout<<"\t\t农夫羊\t\t狼白菜"<<endl;break;case 9: cout<<"\t\t狼白菜\t\t\t农夫羊"<<endl;break;case 11: cout<<"\t\t狼\t\t\t农夫羊白菜"<<endl;break;case 13: cout<<"\t\t白菜\t\t\t农夫狼羊"<<endl;break;case 14: cout<<"\t\t羊\t\t\t农夫狼白菜"<<endl;break;case 15: cout<<"\t\t\t\t\t农夫狼羊白菜"<<endl;break;}}}}int main(){farmerProblem();return 0;}2.深度优先算法#include<iostream>#include<cstdlib>#define MAXNUM 20using namespace std;int solutionCout=0;typedef struct{int *base;//栈底指针int *top;//栈顶指针int stacksize;//栈可用的最大容量}SqStack;void createEmptyStack(SqStack &S)//构造一个空栈S{S.base=new int[MAXNUM];if(!S.base){cout<<"申请内存失败"<<endl;exit(0);}S.top=S.base;//初始为空栈S.stacksize = MAXNUM;}void Push(SqStack &S,int x)//插入一个元素x {if(S.top-S.base==S.stacksize)//栈满{cout<<"栈满";}*S.top++=x;}void Pop(SqStack &S)//出栈{if(S.top==S.base)//栈空{cout<<"栈空";}--S.top;}int getTop(SqStack S)//取栈顶元素{return *(S.top-1);}void print(SqStack S)//打印路径{int *p=S.base;solutionCout++;int print[MAXNUM];int i=0;while(!(p==S.top)){print[i]=*p;i++;p++;}cout<<"方案"<<solutionCout<<"过河步骤是: "<<endl;cout<<"\t\t南岸\t\t\t北岸"<<endl;for(int j=0;j<i;j++){cout<<"第"<<j<<"步:";switch(print[j]){case 0: cout<<"\t\t农夫狼白菜羊\t\t\t"<<endl;break;case 1: cout<<"\t\t农夫狼白菜\t\t羊"<<endl;break;case 2: cout<<"\t\t农夫狼羊\t\t白菜"<<endl;break;case 4: cout<<"\t\t农夫白菜羊\t\t狼"<<endl;break;case 6: cout<<"\t\t农夫羊\t\t狼白菜"<<endl;break;case 9: cout<<"\t\t狼白菜\t\t\t农夫羊"<<endl;break;case 11: cout<<"\t\t狼\t\t\t农夫羊白菜"<<endl;break;case 13: cout<<"\t\t白菜\t\t\t农夫狼羊"<<endl;break;case 14: cout<<"\t\t羊\t\t\t农夫狼白菜"<<endl;break;case 15: cout<<"\t\t\t\t\t农夫狼羊白菜"<<endl;break;}}}bool farmerLocation(int location) //判断农夫位置对0做与运算,还是原来的数字,用来判断位置{return 0 != (location & 0x08);}bool wolfLocation(int location) //判断狼位置{return 0 != (location & 0x04);}bool cabbageLocation(int location) //判断白菜位置{return 0 != (location & 0x02);}bool goatLocation(int location) //判断羊的位置{return 0 !=(location & 0x01);}/* 其中一共有两种状态是不安全的:狼和羊单独在一起;羊和白菜单独在一起*/bool isSafe(int location) // 若状态安全则返回true{if ((goatLocation(location) == cabbageLocation(location)) //羊和白菜单独在一起&& (goatLocation(location) !=farmerLocation(location)) )return 0;if ((goatLocation(location) == wolfLocation(location))&& (goatLocation(location) !=farmerLocation(location)))//狼和羊单独在一起return 0;return 1; //其他状态是安全的}int isAppeared(SqStack S,int location)//判断路径是否出现过,出现返回0;没有出现返回1{int *p=S.base;while (!(p==S.top)){if(*p==location)return 0;p++;}}void farmerProblem(SqStack S,int location){if(location == 15){print(S);return;}int newlocation,movers;for (movers = 1; movers <= 8; movers<<= 1)//向左移位,movers分别0001,0010,0100,1000,//也就是依次判断过河的可行性{if ((0 != (location & 0x08)) == (0 != (location & movers)))//判断农夫和要移动的物品是否在同岸{newlocation = location^(0x08|movers);//过岸if (isSafe(newlocation) && isAppeared(S,newlocation))//判断是否安全,以及路径是否可用{Push(S,newlocation);//新路径入栈farmerProblem(S,newlocation);//以新路径为当前状态递归寻找下一可行路径Pop(S);//已找到的可行路径出战}}}}int main(){SqStack S;int location=0;createEmptyStack(S);//创建辅助空栈Push(S,location);//首先将0000压入栈farmerProblem(S,location);}。

相关文档
最新文档