三个水桶等分8升水的Java语言求解

题目:有三个容积分别是8升、5升和3升的水桶,其中容积为8升的水桶中有8升水,其它两个水桶是空的。三个水桶都没有刻度,问如何在不借助其它工具的情况下只使用这三个桶把8升水等分。

思路:把某一时刻三个水桶的水量称之为一个状态,则初始状态为{8, 0, 0},结束状态为{4, 4, 0}。可以使用穷举法,从初始状态开始,根据状态变化的可能性(引起状态变化的操作)遍历所有可能的状态,每当找到一个从初始状态到最终状态的路径,即可认为找到了一个解。对于引起状态变化的操作,在本例中也就是倒水的动作,可以使用一个动作来建模,它包含三个要素:从哪个水桶倒水,倒进哪个水桶,以及倒了多少水。对于每个状态来说,总共有3x3种倒水的方式(包含一些不合理的倒水,比如向自己倒水),因此对于每个状态仅需要循环这3x3种可能性然后递归地从下个状态进行搜索即可,这在理论上来说是一个深度优先搜索。

剪枝:深度优先搜索可能会遇到重复状态引起的环路,比如上一个步骤从1向2倒了5升水,下一个步骤就从2向1倒了5升水,还可能有一些比较复杂的环路,所以需要把已经搜索过的状态添加到一个集合中去,在搜索一个状态前先看看是否已经搜索过,如果已经搜索过或者正在搜索则直接跳过即可。

代码:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

public class SplitWaterTo2x4 {

    Set<State> states = new HashSet<>();    //用于存储已经搜索过的状态的集合
    Stack<State> order = new Stack<>();     //用于存储已经搜索过的状态的顺序,用于最后输出
    Stack<Action> actions = new Stack<>();  //用于存储已经进行过的操作

    //水桶的状态,分别对应8L、5L和3L的水桶
    Bucket[] buckets = {
  new Bucket(8), new Bucket(5), new Bucket(3)};

    public void search(final State s) {
        if (isFinalState(s)) {
            printAction();
            printOrder();
            return;
        }

        states.add(s);
        order.push(s);

        //遍历所有可
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值