前言

这个问题的抛出,是几个星期之前的算法课程。老师分析了半天,最后的结论是:其实就是图的遍历。那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问题,现在就来好好研究清楚。

问题描述:

一个农夫在河边要过河,但是他带着一匹狼、一只羊和一颗白菜。他需要用船将这三样东西运至对岸,然而,这艘船的空间有限,只容得下他自己和另一样东西(或狼或羊或白菜)。若他不在场看管的话,狼就会吃羊,羊就会去吃白菜。此人如何才能过河。

问题分析:

抛开算法,把这个题当成是一个简单的逻辑题的话还是挺好解的,你过不了多久你就会发现几个关键的问题:

1.你要时刻注意农夫的位置,因为农夫不在地时候狼会吃羊,羊会吃菜

2.第一步只能把羊带走

3.最后一步只能是把羊从河对岸带过来

你会发现羊其实是问题的关键,只要保证羊和狼和白菜隔离开来,那么就很容易解这个问题。下面是这道题的答案:

①把羊带到河对岸 -> 把狼带到河对岸,再把羊带回来 -> 把白菜带到河对岸 -> 把羊带到河对岸

②把羊带到河对岸 -> 把白菜带到河对岸,再把羊带回来 -> 把狼带到河对岸 -> 把羊带到河对岸

算法分析:

过河问题,其实质就是一种状态的改变,就像这个问题说的,农夫狼羊菜都要从河的这边到对岸去,也就对应了两个状态,一个是没过河的状态,一个是过了河的状态。

状态的改变

所以很自然的联想到了用0和1来表示他们的状态,并且每时每刻,农夫狼羊菜的状态都对应一个特定的状态,比如没过河的状态是0000,四个都没有过河,而过河的状态是1111。这样做的好处是将问题抽象成了计算机能够处理的数据。

你当然可以选择暴力穷举法,列出所有可能并找出合理的,这是屡试不爽而且行之有效(对于自己来说)的方法。

但这并不是聪明的做法。如果学习数据结构学习得好的同学(不包括我),会想到用图的V来描述每一种状态,用E来描述状态之间的对应关系,最后进行图的遍历就能找到答案了。反正当时我是想不到的..

图形简单回顾

图是一种很重要的数据结构,这里就简单用相邻矩阵表示法来简单回顾并描述一下图吧。

1.下图是一个无向图,有五个顶点,所以我们使用5x5的数组存放图形。

无向图

2.在上图中,先找和①相邻的顶点有哪些,把和①相邻的顶点2和顶点5的坐标填入1:

找和①相邻的顶点

3.其他顶点以此类推可以得到相邻矩阵:

相邻矩阵

至此我们就利用一个二维数组来描述了一个图形,0表示没有边连接,1表示有边。

继续分析问题

上面提到可以用0,1来表示某一时刻特定的状态,很简单的分析可以得到只存在以下10种情况(右边表示河对岸):

农夫狼羊菜 | (空)

农夫羊菜 | 狼_________农夫狼菜 | 羊_________农夫狼羊 | 菜

狼菜 | 农夫羊_________农夫羊 | 狼菜

狼 | 农夫羊菜_________羊 | 农夫狼菜_________菜 | 农夫狼羊

(空) | 农夫狼羊菜

所以抽象成01可以这样表示:

0000

0100_________0010_________0001

1010_________0101

1011_________1101_________1110

1111

这样就得到了我们的顶点集合,这些顶点包含了各个对象的状态,所以我们需要创建一个Vertex类来表示顶点,里面或许会要再需要一个ObjState类来描述对象各自的状态。然后我们需要一个二维数组来表示相邻矩阵。

再思考

思考:我们现在有了:

一个顶点类,里面包含了描述各个对象状态的ObjState类。

一个用来描述边集的空的二维数组(里面还没有数据)

我们程序的最终目的,是要找到过河的方案,至少得要输出整个过程吧,因为Vertex本身描述的就是一个特定的状态,所以可以加入一个String类型的字符串来描述这样的状态,例如:0000描述为“最开始的状态",0100描述为”农夫羊菜 | 狼“。

顶点连通的条件

我们有了这样的一些拥有自身状态信息的顶点,还需要判断他们的连通性,也就是找“边”。仔细思考一下你就会发现,其实两个状态的连通就只有两个条件:

1.man的状态不一样:

这是因为要保证完成过河的动作,因为过河的这个动作保证了行动的进行,只有过河才能改变现在的状态到下一个状态,这是过程进行的必然条件。

2.最多只有一个其他对象的状态不一样:

除了保证man的状态不一样,也要保证狼羊菜这三个对象中,最多只有1个对象的状态不一样。

所以我们只要判断两两点之间,是否满足以上状态,如果满足,则把相邻矩阵的对应位置置为1即可。

遍历图的条件

我们现在有了描述顶点的Vertex类,有了一个表示边集的二维数组,那么就要遍历图来寻找满足条件的路径了。

我们需要注意的是,如何防止路径的重复查找,也就是在一条路上走来走去的情况,我们需要引入一个额外的描述当前点是否访问过的一维数组visited[],默认的值应该小于等于0,如果该点访问了,则把对应的visited置为访问该点的点的编号,例如点2访问点5,那么visited[4] = 2,这样做的好处是,输出的时候就能很方便的遍历出相应的路径。

要多多分析问题

多多分析问题,更能帮助我们分析清楚问题,也能帮助我们找到比较好的编程实现方法,会少走许多弯路,总之就是要多多分析问题,对于编程来说,这是比磨刀不误砍柴工还要高上几个级别的事。

总之就是要多分析问题,再开始写代码。

写代码:

ObjState类:

首先创建一个描述对象属性的类:

class ObjState{

// 对象类,保存了对象的状态

public int man;

public int wolf ;

public int sheep;

public int vegetable;

}

其中定义了int类型的四种对象(其实就是四个变量,来简单模拟四个对象)。

初始化的工作可以交给Vertex类:

Vertex类:

顶点类,包含了ObjState类,保存了顶点对象的状态以及输出时的信息。

class Vertex {

ObjState objState = new ObjState();     // 对象状态信息

String outputMessage;                   // 输出时要显示的信息

public Vertex(int manState, int wolfState, int sheepState,

int vegetableState, String outputMessage){

// 初始化工作

objState.man = manState;

objState.wolf = wolfState;

objState.sheep = sheepState;

objState.vegetable = vegetableState;

this.outputMessage = outputMessage;

}

}

21/212>

java狼羊草过河_狼羊菜过河问题深入学习分析——Java语言描述版相关推荐

  1. 算法之狼羊菜过河问题

    算法之狼羊菜过河问题 1.带羊再带狼 回来时把羊带上 然后把白菜带到对岸 最后把羊带过去 2..带羊再带菜 回来时把羊带上 然后把狼带到对岸 最后把羊带过去 关键点在于羊和两个都有联系,而狼不吃菜,

  2. 狼羊菜过河问题c语言算法,算法系列之十四:狼、羊、菜和农夫过河问题

    题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种方法,让农夫能够 ...

  3. 狼羊菜过河(C实现)

            题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种 ...

  4. *python解决狼羊菜过河问题

    python解决狼羊菜过河问题 A岸有菜,羊,狼,农夫农夫必须将他们都送到B岸每次只能送一个,在保证他们不会被吃的前提下,完成任务,并得出步骤. 代码: A=[["狼",1],[& ...

  5. 基于深度优先搜索回溯法的人狼羊菜过河模型

    基于深度优先搜索回溯法的人狼羊菜过河模型 本文介绍一个农夫过河的小模型,算法 Python 实现,感觉还挺有趣的,因原为笔者课程作业论文改版而来,所以文章内容比起其他博客文章可能会比较严肃与严谨.期待 ...

  6. 算法谜题1----狼羊菜过河

    狼羊菜过河 一个人在河边,带着一匹狼.一只羊和一颗卷心菜.他需要用船将这三样东西运至对岸,然而,这艘船的空间有限,只容得下他自己和另一样东西(或狼或羊或卷心菜).若他不在场看管的话,狼就会吃羊,羊就会 ...

  7. java狼羊草过河_狼羊菜过河

    思路:用0/1代表所处位置,农夫.狼.羊.菜过河就是0000->1111,一共是16种状态,去掉其中的不可能的状态如0011(羊和菜单独一起)是10种. 可以用图的方式表示: 或者用树的方式表示 ...

  8. 狼羊菜过河问题深入学习分析——Java语言描述版

    前言 这个问题的抛出,是几个星期之前的算法课程.老师分析了半天,最后的结论是:其实就是图的遍历.那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问 ...

  9. 算法谜题1,狼羊菜过河

    问题描述 农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种方法,让农夫能够 ...

最新文章

  1. @EnableConfigurationProperties 注解和@ConfigurationProperties注解实现配置绑定
  2. [Redux/Mobx] 为什么redux能做到局部渲染呢?
  3. 在 ASP.NET Core 5.0 中访问 HttpContext
  4. mac下安装mysql-pyhon_mac下安装MySQL-python模块
  5. pgsql merge方法
  6. 虚函数、C++类、结构体、父类与子类的继承性
  7. zepto 操作 cookie
  8. 华为面试题:一头牛重 800 公斤,一座桥承重 700 公斤,请问牛怎么过桥?
  9. 在制作Windows虚拟机模板时的常用技巧
  10. 条件概率和正则概率(完)
  11. 银联 php hex2bin,银联支付
  12. Java学习1——计算机基础知识
  13. “番茄工作法” 工欲善其事必先利其器
  14. Flutter访问webservice
  15. 径向基函数模型matlab,径向基函数RBF.ppt
  16. uestc 1903
  17. 云计算技术基础期末复习
  18. CRM对接企业微信日程快速实现提醒功能
  19. JSP九大内置对象:
  20. 计算机专业先考研先上班,如何准备考研工作?

热门文章

  1. ENVI自带地物波谱库文件说明和查看(以ENVI5.3为例)
  2. 打印魔方阵(C语言) 所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。
  3. KOB1与KOB2的区别
  4. 树莓派组装成linux电脑,可放进口袋基于树莓派的GNU/Linux电脑
  5. 计算机技术应用广泛以下属于科学计算的是,计算机技术应用广泛,以下属于科学计算方面的是( )。...
  6. HttpEntity接口的详细解释与应用
  7. 63岁雅虎女掌门巴茨:爱爆粗口铁娘子
  8. python3语法基础知识_Python语法笔记 - 基础知识
  9. Java IDEA中输出语句变红报错分析
  10. 汇编程序 JNZ(或JNE)(Jump if not zero,or not equal)