栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

人工智能 DFS 分啤酒问题 Java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

人工智能 DFS 分啤酒问题 Java

分啤酒问题(求解所有解决方案)
  • 一、问题描述
  • 二、解决方法
    • 1.定义状态空间
    • 2.确定一组操作
    • 3.搜索过程
  • 三、代码实现
    • 1.关键代码
    • 2.全部代码
  • 4、运行结果
  • 总结


一、问题描述

现有8升、5升、3升的容器各一个,均无任何度量标记,其中8升的容器装满啤酒,其他两个为空。要求用上述容器倒来倒去,分成两份4升的啤酒。

二、解决方法 1.定义状态空间

用(x,y,z)三个有序整数表示状态空间的一个状态,
x表示8L瓶中的酒量,x∈[0,8];
y表示5L瓶中的酒量,y∈[0,5];
z表示3L瓶中的酒量,z∈[0,3];
起始状态为:(8,0,0),目标状态为(4,4,0)

2.确定一组操作

①x倒入y
②x倒入z
③y倒入x
④y倒入z
⑤z倒入x
⑥z倒入y

3.搜索过程

和水壶问题一样,先初始化状态空间,设置第一个节点的状态为已访问,将此节点加入栈中
随后开始深度优先搜索,以当前节点为父节点,遍历其所有的子节点,若该节点没有被访问过则把该节点的状态加入栈中,并且设为已访问,直到寻找到满足最终状态的节点,输出路径
之后重复这个步骤,直到遍历完所有的路径,递归结束

三、代码实现 1.关键代码

实现深度优先搜索

    private void solve(int a, int b, int c) {
        //判断是否为目标状态
        if (a == 4 && b == 4) {
            print(pos);
            pos++;
        } else {
            for (int i = 1; i <= 6; i++) {
                //依次进行六种操作,并返回操作后的状态
                WaterState news = operate(a, b, c, i);
                //判断是否访问过
                if (checkRepeat(news.a, news.b) == 0) {
                    pathStack.push(news);//入栈
                    space[news.a][news.b] = 1;//设置为已访问
                    solve(news.a, news.b, news.c);//递归
                    pathStack.pop();//出战
                    space[news.a][news.b] = 0;//状态重置
                }
            }
        }
    }
2.全部代码
import java.util.Stack;

public class Beer {
    private int pos = 1;
    //因为三个杯子的总量是确定的,所以可以用一个二维数组来记录
    private int[][] space = new int[9][6];//通过0,1判断状态访问情况
    private Stack pathStack = new Stack();

    public static void main(String[] args) {
        Beer beer = new Beer();
    }

    public Beer() {
        initSpace();//状态空间初始化
        int a = 8;//8L的容器
        int b = 0;//5L的容器
        int c = 0;//3L的容器
        pathStack.push(new WaterState(8, 0, 0));//入栈
        solve(a, b, c);//递归
    }

    //输出
    private void print(int pos) {
        System.out.println("结果" + pos + ":");
        int i = 0;
        int l = pathStack.size();//栈的长度
        while (l > 0) {
            System.out.println(pathStack.get(i).a + "     " + pathStack.get(i).b + "     " + pathStack.get(i).c);
            i++;
            l--;
        }
        System.out.println("操作次数:" + i);
        System.out.println();
    }

    //深度优先搜索
    private void solve(int a, int b, int c) {
        //判断是否为目标状态
        if (a == 4 && b == 4) {
            print(pos);
            pos++;
        } else {
            for (int i = 1; i <= 6; i++) {
                //依次进行六种操作,并返回操作后的状态
                WaterState news = operate(a, b, c, i);
                //判断是否访问过
                if (checkRepeat(news.a, news.b) == 0) {
                    pathStack.push(news);//入栈
                    space[news.a][news.b] = 1;//设置为已访问
                    solve(news.a, news.b, news.c);//递归
                    pathStack.pop();//出战
                    space[news.a][news.b] = 0;//状态重置
                }
            }
        }
    }
    //实现六种操作
    private WaterState operate(int a, int b, int c, int i) {
        switch (i) {
            case 1://a->b
                if (a + b >= 5) {
                    a = a + b - 5;
                    b = 5;
                } else {
                    b = a + b;
                    a = 0;
                }
                break;
            case 2://b->c
                if (b + c >= 3) {
                    b = b + c - 3;
                    c = 3;
                } else {
                    c = b + c;
                    b = 0;
                }
                break;
            case 3://c->a
                a = a + c;
                c = 0;
                break;
            case 4://a->c
                if (a + c >= 3) {
                    a = a + c - 3;
                    c = 3;
                } else {
                    c = a + c;
                    a = 0;
                }
                break;
            case 5://b->a
                a = a + b;
                b = 0;
                break;
            case 6://c->b
                if (b + c >= 5) {
                    c = b + c - 5;
                    b = 5;
                } else {
                    b = b + c;
                    c = 0;
                }
                break;
        }
        return new WaterState(a, b, c);
    }
    //查重
    private int checkRepeat(int a, int b) {
        if (space[a][b] == 1) {
            return 1;
        }
        return 0;
    }
    //状态空间初始化
    private void initSpace() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 6; j++) {
                space[i][j] = 0;
            }
        }
        space[8][0] = 1;
    }
    //内部类,记录状态
    static class WaterState {
        int a, b, c;

        WaterState(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }
}


4、运行结果


总结

在水壶问题的基础上进行修改,整体思路差差不多
希望对你有所帮助

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021455.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号