IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 人工智能 DFS 分啤酒问题 Java -> 正文阅读

[数据结构与算法]人工智能 DFS 分啤酒问题 Java


一、问题描述

现有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<WaterState> 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、运行结果

在这里插入图片描述


总结

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

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:45:58  更:2022-07-21 21:48:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:11:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码