搜索解决方案类问题的通用解法
这类问题有下面的特点:
1、有初始状态,例如3只狼和3只羊需要过河,意味着刚开始3只狼和3只羊都在河的一个岸边。
2、有目标状态,例如3只狼和3只羊要到达河的对岸,意味着最后3只狼和3只羊都要和的对岸。
3、通过一些规则可以使状态发生变化,例如可以用船把2只狼运送到和的对岸,这时候的状态就是河的一边有3只羊和1只狼,河的另一边有2只浪(当然可以根据一边的数字推算出另一边的数字,因为要么在这边要么在那边)。
人是如何来解决这类问题的呢?看下面的图:
首先考虑3只狼3只羊在左边,船只能装两只动物,所以有5种方案,然后看看每一种方案产生的结果是不是想要的结果,如果不是,继续看有哪些情况,上面的图展示了这个过程。图中的右表示把动物运送到对岸,左表示船再回来。
程序如何来实现这个过程呢?
程序的实现过程是对人思考问题的模拟。有两种方式,一种方式按照层来找,初始状态下,考虑5种可能,然后对5种可能进行分析,然后对每一种情况的可能变化情况再考虑,直到找到目标状态,或者不能再变化,称为广度优先搜索。另一种方式是先考虑5种情况中的一种,考虑完之后考虑这一种情况能够转移成哪些状态,然后再考虑其中一个,称为深度优先搜索。之前给出的参考答案采用的是深度优先搜索。
例如下图,如果按照广度优先:则每个状态处理的顺序为:1(第一层) 2 3(第二层) 4 5 6(第三层) 7 8 9 10(第四层)
如果按照深度优先:则每个状态的处理顺序为:1 2 4 7 3 5 8 9 6 10,2下面的情况处理完再处理3下面的情况,同样5下面的情况处理完才处理6下面的情况。
算法的关键部分如下:
1、需要定义1个结构来表示状态,包括初始状态、中间状态和目标状态。我的参考代码中使用了int state[]表示状态。
2、要明确初始状态和目标状态。代码中初始状态为[3,3]表示岸上有3只狼和3只羊,目标状态为[0,0]表示狼和羊都过河了。
3、要明确状态转换的规则,通常每个规则可以定义为方法,方法的输入是一种状态,而输出是另一种状态。代码中move方法完成了这个功能,只是我把多个规则写在了同一个方法中。
4、编写主程序,从初始状态开始,不断地进行状态转换直到结束。有两种处理方式,方法的递归调用,和循环。
可能存在的问题:
1、死循环,最直观的例子,让一只狼到对岸,然后再回来,然后再过去,然后再回来...,永远不会有结束的时候,对于这个问题需要进行控制,有效的方式是记录走过的状态,如果发现重复,放弃这个方案。程序中有两个地方进行了控制。
2、解的空间可能会非常大,如果不采取措施可能永远也运行不完。例如下象棋,大家都知道谁想的远,谁就可能赢,如果让电脑把100步之后的情况都考虑到,我想人可能很难赢,但是让电脑考虑100步需要太大的计算量,如果考虑每一步有20种走法,则需要考虑20的100次方,可以想象这个数字有多大。对于这个问题,通常会采用启发式搜索以及剪枝等。感兴趣的同学可以参考相关书籍。
--------------------------------------------------------------------------------
三、关键代码分析
完整代码参考:Java编程能力强化——狼羊过河问题
关键点分析:
1、public void next(int state[],StringBuffer str)
递归调用的方法,处理指定的状态下面的所有状态。
2、
对初始状态进行处理,也可以合并在下面的代码中,如果合并需要判断str是否为空。另外,这里的return不能省略。
3、
表示得到目标状态,处理结束。
4、
注意:new StringBuffer(str).insert(0,"-2-0")不能写成str.insert(0,"-2-0")
另外!str.substring(0,4).equals("+2+0")的作用防止去和回船上的动物是一样的。
5、 public int[] move(int state[],String info){
注意:try语句的使用,因为+3转换为数字的时候出现异常
另外不能直接修改state的元素值然后把state返回。
6、public boolean check(int state[]){
判定羊的个数不能小于狼的个数。
7、public boolean hasExist(StringBuffer str){
判断是否有死循环。
8、public void printResult(StringBuffer str){
输出结果方案。
大家可以试着使用广度优先的方式实现代码,可以不用递归的方式进行处理(如果递归的层数比较多,会出现堆栈溢出问题)。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/JavaEETeacher/archive/2011/01/28/6167453.aspx