图有节点和边。
节点意味着一种状态。也就是你所有容器的状态
边缘意味着状态之间的(有效)转换。
如果你可以枚举所有改变状态的方法,那么你可以枚举一个节点到其他节点的所有出边。
以容器为例:
状态:10升容器(里面有一些量)、7升容器(里面有一些量)和4升容器(里面有一些量)
状态转换函数:
- 将 4 升容器的内容物倒入 7 升容器中
- 将 7 升容器的内容物倒入 10 升容器中
- 将 4 升容器的内容物倒入 10 升容器中
- 将 7 升容器的内容物倒入 4 升容器中
- 将 10 升容器的内容物倒入 4 升容器中
- 将 10 升容器的内容物倒入 7 升容器中
对这些功能的约束:一个人倾倒直到倾倒容器是空的,或者接收容器是满的。
您有 n 个容器,并且可能(n 选择 2)这些容器之间的交互。
调用这些函数中的任何一个都可能将您转换到另一种状态。
您可以定义与每个边缘转换相关的成本。在像这样的简单问题中,所有边缘转换函数都具有相同的成本 (1),但在现实世界的示例中,例如在地图上的城市之间移动,成本可能是您必须沿着边缘移动的距离。
也许您想尽量减少倒出 4 升容器。您可以为涉及将 4 升容器倒入任何其他容器的所有边缘指定 2 而不是 1 的边缘权重。
现在我们已经根据节点和边定义了我们的图,我们可以搜索它!
也许你有一些像你提到的那样的起始状态(10 升容器是空的,7 和 4 升容器是满的)。并且您想进入其他状态(10 升容器已满,7 升容器为空,4 升容器有 1 升)。您可以从初始状态开始搜索图表,并在达到目标时停止搜索。
传统的图搜索技术有广度优先搜索(BFS)和深度优先搜索(DFS)。我会让你去维基百科学习它们。其他图搜索技术(如 A*)定义了一个启发式或经验法则,以尝试最快地到达目标状态。启发式方法涉及估计您在达到目标之前还有多长时间,并且有各种各样的研究来定义特定问题的启发式方法(提出启发式方法真的很难!)
实际生成您想要稍后搜索的图形可以通过前面描述的 BFS 或 DFS 方法完成。简单地说,创建一个描述你的初始条件的节点,然后在它上面应用你所有的状态转换函数来生成所有可达的节点。将这些节点放在一个列表中(这些是已生成但尚未展开的节点)。对于列表中的每个元素,以相同的方式展开它。将您已完成扩展的节点放入一个封闭列表中,这样您就可以确保您永远不会尝试两次生成相同的节点。