|
对于程序员而言,研究算法是很有趣的工作。
下面列举一个以前看到的算法题,如下:
有3个水桶,编号为1#、2#、3#。其中,1#水桶的容积为3升,2#水桶的容积为5升,3#水桶的容积为8升。目前的情况是3#水桶中装满了水,1#和2#水桶是空的。三个水桶都没有体积刻度,现在需要将3#水桶中的8升水均分成两份,即每份水为4升,要求只能使用1#、2#、3#水桶来完成这个工作。
怎么办呢?
实现步骤如下:
【现状】
水桶: 1# 2# 3#
水量: 0 0 8
步骤1:3#向2#倒入5升水(0 5 3)
步骤2:2#向1#倒入3升水(3 2 3)
步骤3:1#向3#倒入3升水(0 2 6)
步骤4:2#向1#倒入2升水(2 0 6)
步骤5:3#向2#倒入5升水(2 5 1)
步骤6:2#向1#倒入1升水(3 4 1)
步骤7:1#向3#倒入3升水(0 4 4)
从而完成了8升水均分成两份的工作。
【算法实现】
我们采用长度为3的一维向量描述这个状态,这组向量的三个值分别是容积为8升的桶中的水量、容积为5升的桶中的水量和容积为3升的桶中的水量。因此算法的初始状态就可以描述为[8, 0, 0],则终止状态为[4, 4, 0]。
倒水动作与静止状态的结合就产生了状态变化,持续的状态变化就产生了一棵状态树,这个状态树上的所有状态就构成了穷举算法的解空间。以初始状态[8, 0, 0]为例,如果与“倒5升水到5升水桶”动作相结合,就得到了一个新状态[3, 5, 0],同样,如果与“倒3升水到3升水桶”动作相结合,就得到了另一个新状态[5, 0, 3]。以此类推,可以得到
|
|