今天继续看了状态树搜索算法,问题是三个和尚三个妖怪过河,无论是过河前还是过河后,和尚的数目都不能小于妖怪的数目,不然就会被吃掉。
题目的初始条件是三个和尚和妖怪都在河的一边,然后每次只能够坐上两个上船,然后到达另一边,其中一个再坐船回去。
其实这个就跟我前几天做的那个状态树搜索算法,三个水桶平分水问题一样,都是搜索状态树,解决这个问题需要找到一条从初始状态变换到终止状态的路径,使用穷举法,遍历所有由妖怪、和尚和小船位置构成的空间状态,寻找从初始状态到最终状态的变换路径。
建立数学模型,描述问题的数据结构,问题的状态模型不仅要描述静止状态,也要描述转换动作,因为这对算法设计至关重要。
状态的数学模型与状态树,三个和尚与三个妖怪和一个小船,7个属性,但是有效的空间状态其实只有5个,过河前的和尚妖怪数目,小船位置,过河后的妖怪和尚数目。
所以我们只要记录这五个属性就可以了,我用的是字符串备忘录,前面4个字符记录过河前后的和尚妖怪数目,最后几个英文是小船的状态,然后比较状态就是字符串的匹配问题了。
作者用C++做,他用到了结构体和枚举变量,
在java中有个枚举类,所以我是用枚举类来实现的。
搜索算法,状态树的遍历,状态树的遍历里面暗含了状态树生产的过程,促使上一个状态向下一个状态转换驱动。
动作模型里面定义了10个动作,10个动作是这个问题游戏中所有可能出现的过河动作,但是并不是所有的动作状态都符合问题要求,所以必须加上判断条件。
剪枝和重复状态判断:
判断一个状态是否适用于当前状态,要有判断合法的算法。
还要有判断是否重复,避免出现死循环,否则,算法可能无法跳出当前状态,java中会出现栈溢出,所以要实现剪枝操作&#