题目:怎么用一个容量为 3 公斤的桶和一个容量 5 公斤的桶称量出 4 公斤量的水?
分析
设两个桶分别为 A 和 B,容量分别为 M 和 N。目标为任一桶的当前盛水容量为 G。
开始状态: 两个桶均为空。
过程: 桶没有刻度,针对这两个桶每次所能完成的动作只能是以下 6 种之一:
- 把 A 桶的水清空;
- 把 B 桶的水清空;
- 把 A 装潢水;
- 把 B 装满水;
- 把 A 的水倒入 B;
- 把 B 的水倒入 A。
结束状态: 其中一个桶装入的水容量为 G。
完整过程: 从开始状态开始,每次可以选择一个动作之一,然后判断是否到达结束状态。
很显然,从开始到结束的这些状态,应该构成一个图。图的顶点就是各个状态,图的边就是动作之一。 我们要做的,就是从图的开始状态顶点找到所有能到达结束状态顶点的所有路径。我相信你的脑海里面已经构造出这个图了。
通常,我们把这种问题称作是关于图的状态空间搜索问题,而采用的算法则可以是广度优先搜索。
实现
下面开始写算法实现,不要忘记广度优先搜索算法怎么写就好。
Go Playground: https://play.golang.org/p/_xK0_vOvmQi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
|
运行输出结果:
(0,0) Initialize
(0,5) Fill B
(3,2) Fill A With B
(0,2) Clear A
(2,0) Fill A With B
(2,5) Fill B
(3,4) Fill A With B
(0,0) Initialize
(3,0) Fill A
(0,3) Fill B With A
(3,3) Fill A
(1,5) Fill B With A
(1,0) Clear B
(0,1) Fill B With A
(3,1) Fill A
(0,4) Fill B With A
Processed 16 states
可以看到,总共有 2 种答案。