前几天女朋友复习人工智能的考试,看见了一道经典的狼、羊、白菜过河问题,题目如下:一个人带着一只羊,一条狼和一个白菜想过河,假设他每次只能带一只羊,或者一条狼,或者一棵白菜过河,并限定人不在场时,狼和羊,或羊和白菜不能单独在一起,试求出他带一只羊,一条狼,一个白菜过河的方法。
这样的题目小时候真的见过不少,虽然能够用笔头推导出来,但恰逢我最近在看算法之类的书,就想用这道题练练手,寻求其编程的解法。
首先第一步是把问题抽象化,我将白菜、羊、狼、人分别设为1、2、3、X。如果X不在的话,一旦出现两个数的差的绝对值为1的情况时,就说明发生了羊吃白菜或是狼吃羊的非法事件。这就是需要避免出现的。
然后我再来考虑解决的算法,一开始我考虑采用树状深度搜索的方法递归的向理想结果推进。在第n步的时候,枚举出全部的合法移动,分别向前递归出n+1的行动步骤。不过我发现遇到了一个问题,在不断向前递归的过程中可能会回到之前的某状态,从而造成死循环。而我当时没有想出排除已有路径前进的方法,边上的女朋友提醒我说可以从状态入手,我一想4个东西放左右,不过2^4=16种情况,的确比无休止的递归要简单多了,于是我就立刻转换了思路。
虽说一共有16种状态,其中还包括一些非法的状态,但它们直接的关系却是挺复杂的。比如{1、3、x}的状态可以变为{1}{3}{1、3}三种,而这些状态和状态的关系让我想起了我最近才看的图论,这不正是无向图嘛!
就这样我坚定了思路,开始了程序的第一步,获取全部的16种状态。这是一个求4个元素集合的全