农夫过河【数据结构实验报告】
数据结构实验报告
实验名称:实验三 农夫过河
学号:***
姓名:gnosed
实验日期:2017.10.30
一、实验目的
1、进一步掌握队列的使用
2、会使用队列进行农夫过河解的搜索
二、实验具体内容
1、实验题目1:
(1)题目
经典的农夫过河问题
一个农夫带着一只狼,一只羊和一颗白菜过河,从西岸到东岸。船太小,他每次过河只能携带一样东西,船只有农夫能撑。问题是狼会吃羊,羊会吃白菜,所以不能单独让狼和羊或者羊和白菜单独在河的一边,但狼不吃白菜。请问农夫采取什么方案,才能将所有东西安全运过河?
要求:使用广度优先搜索农夫过河解,并输出结果。
提示:可以使用STL中的队列进行代码编写。
(2)分析
首先对每件东西的位置进行描述,用4位二进制数顺序分别表示农夫、狼、羊和白菜的位置,0表示在东西河的西岸,1表示在东岸。例如1001表示农夫和白菜在东岸,狼和羊在西岸。
数据结构:
1. int location:用整型location表示位置状态,从初始化状态0(二进制为0000)到终结状态15(二进制为1111)。
2. queue<int> moves:用整型队列moves保存每一步所有可能达到的状态,队列每个元素表示一个安全的状态。按照队列先进先出的原则,只有在前一步的所有状态都处理完后,才开始处理后一步的各状态。
3. int route[16]:数组route有16种状态(0000~1111),用来记录已经被访问的各个状态,以及达到这些状态的前驱状态。做法是初始化元素值为-1,当往队列move入队一种安全状态时,将 以这个状态值作为下标的数组元素值(-1)改为达到这个状态的前驱状态的下标值。因此,当模拟完成时,利用route数组元素的值生成一个正确的状态路径。
状态判断:
1. 个体位置:根据 按位与&运算的性质,可使location与一个十六进制数相与,计算结果用来取某东西当前的位置。例如location & 0x08 ,结果为1表示农夫在西岸,否则在东岸。狼羊白菜的这个十六进制数分别为 0x04,0x02,0x01。
2. 安全:由四个东西的位置关系,判断该状态是否安全。不安全的状态只有两种,狼和羊,或者羊和白菜单独在河一侧。
状态翻转:
要从一种安全状态转换到另一种状态(过河),首先考虑各种物品的移动(通过左移<<运算),对于某些物品和农夫在同一侧的状态,就翻转状态判断其是否安全。因为农夫都必须改变状态,所以只有农夫被移动的东西(movers所表示)在同一岸时,农夫才可能将它带走。当然可以什么都不带,农夫可以直接过河。首先将movers和二进制0x00进行 按位或运算,确定需要翻转的位,再将这个结果与原来的状态location进行 异或运算,从而实现翻转,得到一个新的状态newlocation。具体细节看code。
模拟过程:
首先使初始状态0x00入队。
1)当队列不空且route[15]==-1(未被访问)时,取队头的状态location(出队),否则如果route[15]已被访问,输出方案,否则没有方案。
2)对于每个物品,判断其是否与农夫在河一侧,如全部物品都已判断,返回1)。
3)若是,则翻转当前状态location得到新的状态newlocation。
4)若newlocation安全而且新状态route[newlocation]没有被访问,将新状态入队,并记录新状态的前驱。返回2)。
(3)实验代码
源代码:
#include <iostream>
#include <queue>using namespace std;//判断各物品的位置
int famer(int location){return ((0x08 & location)!=0);
}
int wolf(int location){return ((0x04 & location)!=0);
}
int goat(int location){return ((0x02 & location)!=0);
}
int cabbage(int location){return ((0x01 & location)!=0);
}
//判断状态安全
int safe(int location){if(wolf(location)==goat(location)&&famer(location)!=wolf(location))return 0;if(goat(location)==cabbage(location)&&famer(location)!=goat(location))return 0;return 1;
}
void farmerProblem(){queue<int> moves;int route[16],location,newlocation;for(int i=0;i<16;i++) route[i]=-1;//赋初值moves.push(0x00);//初始状态入队route[0]=0;//记录while(!moves.empty()&&route[15]==-1){location=moves.front(); moves.pop();//取队头状态为当前状态for(int movers=1;movers<=8;movers<<=1){//考虑各种物品if(((location & movers)!=0)==((location & 0x08)!=0)){//农夫和物品在同一侧newlocation=location ^ (0x08 | movers);//到新状态if(safe(newlocation)&&route[newlocation]==-1){//新状态安全且其为处理moves.push(newlocation);//新状态入队route[newlocation]=location;//记录新状态的前驱}}}}if(route[15]!=-1){//到达最终状态cout<<"Path:\n";for(int i=15;i>=0;i=route[i]){cout<<i<<" ";if(!i) break;}}else cout<<"No solution\n";//问题无解
}
int main()
{farmerProblem();return 0;
}
测试结果:
Path:
15 5 13 1 11 2 10 0
三、实验小结
1. 实验中一个巧妙的方法是用位数来模拟物品的位置以及位置的处理,这涉及到位运算,自己重新总结了一下。http://blog.csdn.net/gnosed/article/details/78442571
2. 对BFS有更深一步理解,基本掌握队列的使用。
农夫过河【数据结构实验报告】相关推荐
- java数据结构 农夫过河,数据结构农夫过河
农夫过河问题(C++编写)_电子/电路_工程科技_专业资料.1.问题描述从前,一... 农夫过河的安全步骤: NO1:农夫,狼,羊,白菜都在河的左岸 NO2:农夫带羊到... 南阳理工学院 " ...
- java数据结构运动会分数统计,数据结构实验报告(运动会分数统计系)..doc
数据结构实验报告(运动会分数统计系). 运动会分数统计系统 问题描述: 参加运动会有n个学校,学校编号为1--n.比赛分成m个男子项目,和w个女子项目.项目编号为男子1--m,女子m+1--m+w.不 ...
- 桂电七院数据结构实验报告一
顺序表的基本操作 实验内容与步骤 实现顺序表上的插入.删除等操作.调试程序并对相应的输出作出分析:修改输入数据,预期输出并验证输出的结果.加深对有关算法的理解. 步骤: 第一步:定义顺序表的存储结构. ...
- 数据结构实验报告,二叉树的基本操作(C语言)
数据结构实验报告,二叉树的基本操作(C语言) 作者:命运之光 专栏:数据结构 目录 数据结构实验报告,二叉树的基本操作(C语言) 实验六 二叉树的基本操作 一.需求分析 二.概要设计 三.详细设计 四 ...
- C语言数据结构线性表上机实验报告,数据结构实验报告实验一线性表_图文
数据结构实验报告实验一线性表_图文 更新时间:2017/2/11 1:23:00 浏览量:763 手机版 数据结构实验报告 实验名称: 实验一 线性表 学生姓名: 班 级: 班内序号: 学 号: ...
- 数据结构实验报告—学生成绩管理系统(Java实现)
数据结构实验报告----学生成绩管理系统(Java实现) [具体下载链接]https://download.csdn.net/download/mmzian/10897535 部分代码展示 Test类 ...
- 数据结构实验报告(六)
数据结构实验报告(六) 一.实验名称 实验六 图的实验1--图的邻接矩阵存储实现 二. 实验目的 1. 熟练理解图的相关概念: 2. 掌握图的邻接矩阵的存储方法的实现: 3. 学会图的遍历算法 ...
- 北京理工大学计算机实验四报告表,北京理工大学数据结构实验报告实验四
北京理工大学数据结构实验报告实验四 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 <数据结构与算法设计>实验报告--实 ...
- 数据结构实验报告(一)
数据结构实验报告(一) 一.实验名称 实验一 线性表的基本操作实现及其应用 二.实验目的 1.熟练掌握线性表的结构特点,掌握顺序表的基本操作. 2.巩固 C++相关的程序设计方法与技术. 3.学会使 ...
最新文章
- Mysql性能优化方案
- 怎样使用Debussy+ModelSim快速查看前仿真波形
- 物理机与虚拟机IP互ping通,而互ping主机名不通
- 云炬Qtpy5开发与实战笔记 1开发第一个桌面应用Hello World
- 累计连续签到设计和实现
- hover时候缓慢切换两张图片
- ASP.NET调用Oracle分页存储过程并结合ASPnetpager分页控件 实现分页功能
- php如何增加字段,php如何增加字段
- 吉林大学java期末试卷_吉大18年9月《JAVA程序设计》作业考核试题-0001
- 浅谈:如何加快本本的开机时间
- 《Word 排版艺术》一书的人到此交流
- 关于maven仓库的配置步骤
- solr5.3 实现同义词 扩展词典 停止词典 功能介绍
- 学会这几个.你就能成为bat脚本小子了...(转来看看的)
- List.stream()常用的操作
- mne plot出错_MNE-Python 环境配置 | win 10
- python spacy 安装超时_安装spacy失败
- OpenGL放大缩小实现
- MFC ActiveX控件的3种调用方式
- 统计学习方法-感知机概括和补充