回溯法:0-1背包问题

news2024/9/24 18:28:00

问题描述

给定n种物品和一背包。 物品i的重量是w_i, 其价值为v_i,背包的容量为 c。 问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?注意物品不重复!

实例:物品价值V={12, 11, 9, 8}, 物品重量W={8, 6, 4, 3}, 背包容量c=13

结点:向量(x_1,x_2,...,x_k) ( 子集的部分特征向量)

搜索空间: 子集树2^n片树叶

其中两个可行解为:

<0,1,1,1>:x_1=0,x_2=1,x_3=1,x_4=1\\ <1,0,1,0>:x_1=1,x_2=0,x_3=1,x_4=0

回溯法模版回顾 

参考文章:代码随想录

回溯法解决的问题都可以抽象为树形结构,是的,我指的是所有回溯法的问题都可以抽象为树形结构!

因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度

递归就要有终止条件,所以必然是一棵高度有限的树(N叉树)。

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

实现代码

终止条件代码

public static void backtracking(int n,  int startIndex) {
    if (startIndex>=n){
        //此时startIndex越界了
        if (getPathSum()<=c){
            result.add(new ArrayList<>(path));
            return;
        }
        return;
    }
    //再加后面任意一个就肯定不够了
    if (getPathSum()<=c&&(getPathSum() + items_min_weight[startIndex]) > c) {
        //        if (getPathSum()<c) {
        result.add(new ArrayList<>(path));
        return;
    }
    for (int i = startIndex; i < n; i++) {
        path.add(i);
        backtracking(n,  i + 1);
        path.removeLast();
    }

最终代码(含注释)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class KnapsackProblem {
    static List<List<Integer>> result = new ArrayList<>();
    static LinkedList<Integer> path = new LinkedList<>();

    static int N = 4;
    //    static int[] items_weight = new int[N];
    static int[] items_weight = {8, 6, 4, 3};
    //    static int[] items_value = new int[N];
    static int[] items_value = {12, 11, 9, 8};
    //每个items_min_weight(对应下标为i)的值为min{items_weight[i],...,items_weight[N-1]}
    static int[] items_min_weight = new int[N];
    //c为背包的容量
    static int c=13;

    public static void main(String[] args) {
        items_min_weight[N - 1] = items_weight[N - 1];
        int min = items_min_weight[N - 1];
        for (int i = items_weight.length - 2; i >= 0; i--) {
            if (items_weight[i] < min) {
                min = items_weight[i];
            }
            items_min_weight[i] = min;
        }
        backtracking(N,  0);
        System.out.println("可行解有:");
        result.forEach(System.out::println);
        //要是想求最优解,直接对每个可行解对应重量求和,之后取最大一个就好啦
    }

    public static void backtracking(int n,  int startIndex) {
        if (startIndex>=n){
            //此时startIndex越界了
            if (getPathSum()<=c){
                result.add(new ArrayList<>(path));
                return;
            }
            return;
        }
        //再加后面任意一个就肯定不够了
        if (getPathSum()<=c&&(getPathSum() + items_min_weight[startIndex]) > c) {
            //        if (getPathSum()<c) {
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i < n; i++) {
            path.add(i);
            backtracking(n,  i + 1);
            path.removeLast();
        }
    }

    public static int getPathSum() {
        int sum = 0;
        for (int i = 0; i < path.size(); i++) {
            sum += items_weight[path.get(i)];
        }
        return sum;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1397183.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统-中断和异常(中断作用 类型 内外中断 中断机制原理)

文章目录 总览中断的作用中断类型内中断的例子外中断中断的分类中断机制的基本原理小结 总览 中断的作用 刚启动CPU上运行的是内核程序 中断类型 内中断的例子 当前执行指令非法是指参数有问题等其他原因 陷入指令是主动转换状态&#xff0c;但它并不是特权指令 外中断 时钟…

Docker(一)简介和基本概念:什么是 Docker?用它会带来什么样的好处?

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 一、简介 本章将带领你进入 Docker 的世界。 什么是 Docker&#xff1f; 用它会带来什么样的好处&#xff1f; 好吧&#xff0c;让我们带…

matplotlib从起点出发(12)_Tutorial_12_MultiAxes

在一个Figure中安排多个Axes 通常在一个图像中&#xff0c;需要同时呈现多于一个Axes&#xff0c;并且需要对齐到网格. Matplotlib有多种工具用于处理在本库历史中演变的Axes网格&#xff0c;我们将讨论我们认为用户最常使用的工具&#xff0c;支持Axes组织方式的工具&#xf…

记录自己 自学摸索 学习日语:新标日

新标日 几节课合成在一起太乱了 第四课会更新个集合 自学日语吧算是 摸索中&#xff01; 尽量一周一课 第一课 单词 ちゅうごくじん 中国人 中国人 にほんじん 日本人 日本人 あめりかじん アメリカ人 美国人 かんこくじん 韓国人 韩国人 ふらんすじん フラン…

uniApp H5使用JSSDK对接微信公众号问题

问题1 uni-app开发微信应用引用JSSDK后 wx.agentConfig is not a function (或 wx.config is not a function) 原因&#xff1a; 因为uni-app自动集成了 微信的 jweixin.js &#xff0c; 所以通过 在浏览器打开 然后保存下来js 文件 然后在项目中通过 import 引入就可以了 …

C++继承(万字详!!)

文章目录 继承的概念及定义继承的概念继承定义 基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数继承与友元继承与静态成员复杂的菱形继承及菱形虚拟继承菱形继承菱形虚拟继承 继承的总结和反思笔试面试题 继承的概念及定义 继承的概念 继承(inheritance) 机制是面…

【Linux】yum

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 yum 1. 什么是yum&#xff1f;2. Linux系统(Centos)的生态3. yum的相关操作4. yum的本地配置5. 如何安装软件 1. 什么是yum&#xff1f; yum是一个软件下载安装的一个客户端&a…

Qt/QML编程之路:QWidget和QOBJECT的不同之处(37)

开始使用Qt的工程师&#xff0c;要有个思想准备&#xff0c;标准的Application或者说Windows窗口类的工程和QML是不同的&#xff0c;很多控件在QML里面是不支持的。要了解QObject、QWidget、QMainWindow几个的不同。为何我会遇到这个问题呢&#xff1f;因为在做OpenGL想实现3D效…

Spark流式读取文件数据

流式读取文件数据 from pyspark.sql import SparkSession ss SparkSession.builder.getOrCreate() # todo 注意1&#xff1a;流式读取目录下的文件 --》一定一定要是目录&#xff0c;不是具体的文件&#xff0c;# 目录下产生新文件会进行读取# todo 注意点2&#xff1…

知识图谱的演进

目录 前言1 Memex&#xff1a;信息存储的雏形2 超文本和Web&#xff1a;链接的崛起3 Semantic Web&#xff1a;从文本链接到数据链接4 Linked Big Data&#xff1a;规范化的语义表示5 谷歌的知识图谱搜索引擎6 多种语义网/知识图谱项目结语 前言 随着人工智能和互联网的飞速发…

02.Spotless代码格式化工具

Spotless代码格式化工具 1.为什么需要 在一些大型项目或开源项目&#xff0c;由于开发人员太多&#xff0c;导致各个代码格式不统一。会让整体项目的代码可读性变差&#xff0c;那么如何可以统一代码格式呢&#xff1f; 使用Spotless就可以完成 2.是什么 Spotless 是支持多…

4456系列数字荧光示波器

4456系列数字荧光示波器 简述&#xff1a; 4456系列数字荧光示波器具有6个产品型号&#xff0c;带宽350MHz~1GHz&#xff0c;最高采样率5GSa/s&#xff0c;最大存储深度500Mpts/CH&#xff0c;最快波形捕获率100万个波形/秒&#xff0c;独创的Any Acquire Phosphor技术&#xf…

Docker安装MinIO以及Spring Boot 整合 MinIO 实现分布式文件服务

什么是MinIO&#xff1f; MinIO 是一个开源的对象存储服务器&#xff0c;旨在通过简化分布式存储架构的方式&#xff0c;提供高性能、高可用性的存储解决方案。它兼容 Amazon S3 API&#xff0c;因此可以无缝地替代或与 Amazon S3 兼容的应用程序集成。 下面是一些关于 MinIO…

LeetCode-67/104/1232/136

1.二进制求和&#xff08;67&#xff09; 题目描述&#xff1a; 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 思路&#xff1a; 第一种方法就是直接将字符串转为二进制数&#xff0c;然后相加返回结果&#xff0c;但是提交未通过&#xff…

(二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真

一、创建工作空间 mkdir catkin_ws cd catkin_ws mkdir src cd src 二、下载wpr_simulation源码 git clone https://github.com/6-robot/wpr_simulation.git 三、编译 ~/catkin_make 目录下catkin_makesource devel/setup.bash 四、运行 roslaunch wpr_simulation wpb_s…

SPI 动态服务发现机制

SPI&#xff08;Service Provier Interface&#xff09;是一种服务发现机制&#xff0c;通过ClassPath下的META—INF/services文件查找文件&#xff0c;自动加载文件中定义的类&#xff0c;再调用forName加载&#xff1b; spi可以很灵活的让接口和实现分离&#xff0c; 让API提…

Node+Express编写接口---前端

前端页面 vue_node_admin: 第一个以node后端,vue为前端的后台管理项目https://gitee.com/ah-ah-bao/vue_node_admin.git

SpringBoot 项目中后端实现跨域的5种方式!!!

文章目录 SpringBoot 项目中后端实现跨域的5种方式&#xff01;&#xff01;&#xff01;一、为什么会出现跨域问题二、什么是跨域三、非同源限制四、Java后端 实现 CORS 跨域请求的方式1、返回新的 CorsFilter(全局跨域)2、重写 WebMvcConfigurer(全局跨域)3、使用注解 (局部跨…

485.最大连续1的个数

前言 这两天突然发现力扣上还是有我能写出来的题的&#xff0c;虽说都是简单级别的&#xff08;以及一道中等的题&#xff09;&#xff0c;但是能写出来力扣真的太开心了&#xff0c;&#xff08;大佬把我这段话当个玩笑就行了&#xff09;&#xff0c;于是乎&#xff0c;我觉…

【Docker】实战多阶段构建 Laravel 镜像

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 本节适用于 PHP 开发者阅读。Laravel 基于 8.x 版本&#xff0c;各个版本的文件结构可能会有差异&#xff0c;请根据实际自行修改。 准备 新…