You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现N个水壶通用倒水谜题的最优路径求解算法

任意N水壶谜题最短路径求解方案

你之前实现的双水壶求解逻辑是双水壶场景下的特化贪心流程,依托贝祖数的性质设计了固定操作循环,天然无法适配N≥3的场景。通用场景下的最快求解本质是无权图最短路径搜索问题,用广度优先搜索(BFS)就可以实现,BFS的层序遍历特性天然保证首次触达目标状态时的操作步数就是全局最小值,适配任意N≥2的水壶数量。

核心实现逻辑

1. 基础定义

  • 状态表示:用长度为N的整数序列表示当前所有水壶的盛水量,序列第i位对应第i个水壶的当前水量,初始状态为全0序列[0, 0, ..., 0]
  • 边的定义:每个状态可以通过三类合法操作跳转到下一个相邻状态,所有合法操作全部枚举即可:
    • 装满操作:遍历每个水壶,若当前水壶未装满,生成新状态:将该水壶的水量设为其额定容量,其余水壶水量不变
    • 排空操作:遍历每个水壶,若当前水壶有水,生成新状态:将该水壶的水量设为0,其余水壶水量不变
    • 倒水操作:遍历所有有序水壶对(源壶i, 目标壶j)(i≠j),若源壶有水、目标壶未装满,计算实际可转移水量:转移量 = min(源壶当前水量, 目标壶剩余容量 = 目标壶额定容量 - 目标壶当前水量),生成新状态:源壶水量减转移量,目标壶水量加转移量,其余水壶水量不变
  • 去重机制:维护一个已访问状态集合,每生成一个新状态先校验是否已存在于集合中,已存在的状态直接跳过,避免循环搜索和重复计算。

2. 搜索流程

  1. 初始化队列,将初始状态入队,标记初始状态为已访问
  2. 逐层出队队列中的状态,每次出队后首先校验:当前状态是否存在任意一个水壶的水量等于目标值,如果是则终止搜索,回溯还原操作路径
  3. 对当前状态枚举所有合法操作生成新状态,将未访问过的新状态标记为已访问、记录其前驱状态和对应操作,并入队
  4. 若队列为空仍未找到目标状态,判定谜题无解。

3. 路径还原

队列中存储的元素不能只包含当前状态,需要额外记录该状态的前驱节点、到达该状态执行的操作,搜索到目标状态后,沿着前驱指针从目标状态反向回溯到初始状态,再将路径逆序即可得到从初始状态到目标状态的完整操作步骤。

优化技巧(针对N较大的场景提速)

  • 前置可行性剪枝:如果目标水量大于所有水壶的最大额定容量,直接判定无解;如果目标水量不能被所有水壶额定容量的最大公约数(GCD)整除,直接判定无解,无需启动搜索
  • 状态存储优化:C#中不要直接用数组作为哈希集合的键(数组默认是引用相等判断,内容相同的不同数组会被判定为不同对象),可以将状态转为值类型元组,或者将每个水壶的水量按固定比特位编码为一个长整数,大幅提升哈希查询速度
  • 无效操作剪枝:装满已经满的水壶、排空已经空的水壶、从空壶倒水、向满壶倒水这类操作直接跳过,不生成对应状态。

以你举的3升、5升水壶凑4升水的场景为例,BFS搜索到第6层时会首次触达[3,4]的目标状态,对应的路径和你给出的最优解完全一致。


内容的提问来源于stack exchange,提问作者Hathors

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:06:26