当前位置: 首页 > article >正文

算法中的背包问题详解:部分背包与0-1背包

1. 背包问题概述

背包问题是组合优化中的经典问题,其核心目标是:在给定容量的背包中装入一组物品,使得物品的总价值最大化。根据物品是否可分割或重复选择,背包问题分为多个变种,其中最常见的两种是:

  • 部分背包问题(Fractional Knapsack)

  • 0-1背包问题(0-1 Knapsack)

其他变种包括完全背包、多重背包、分组背包等,本文重点讨论前两者。

2. 部分背包问题(Fractional Knapsack)

2.1 定义与特点

  • 问题描述:给定一个容量为 WW 的背包和 nn 件物品,每件物品有重量 wiwi​ 和价值 vivi​。允许选择物品的任意比例(例如取物品的50%),求背包能容纳的最大总价值。

  • 关键特点

    • 物品可分割(如液体、粉末)。

    • 贪心算法可获得最优解。

2.2 贪心算法解决策略

由于物品可分割,最优策略是优先选择单位重量价值最高的物品。步骤如下:

  1. 计算每件物品的价值密度:viwiwi​vi​​。

  2. 按价值密度降序排列所有物品。

  3. 依次装入物品,若当前物品可完整放入,则全取;否则取部分填满背包。

伪代码示例:
Sort items by v_i/w_i in descending order
total_value = 0
remaining_capacity = Wfor each item in sorted list:if remaining_capacity >= item.weight:total_value += item.valueremaining_capacity -= item.weightelse:fraction = remaining_capacity / item.weighttotal_value += fraction * item.valuebreak
return total_value

2.3 实例分析

示例:背包容量 W=50W=50,物品如下:

物品重量价值
A1060
B20100
C30120
  1. 计算价值密度:

    • A: 66, B: 55, C: 44

  2. 按降序排列:A → B → C

  3. 装入过程:

    • 装入A(10→剩余40,价值+60)

    • 装入B(20→剩余20,价值+100)

    • 剩余容量20,装入C的 20303020​,价值+80

    • 总价值:60+100+80=24060+100+80=240

2.4 复杂度分析

  • 时间复杂度:O(nlog⁡n)O(nlogn)(排序占主导)。

  • 空间复杂度:O(1)O(1)(原地排序)。

2.5 应用场景

  • 资源切割(如木材、金属)。

  • 时间分配(如任务调度中选择收益最高的部分任务)。

  • 物流运输中装载可分割货物。


3. 0-1背包问题(0-1 Knapsack)

3.1 定义与特点

  • 问题描述:给定容量为 WW 的背包和 nn 件物品,每件物品只能选择放入(1)或不放入(0),求最大总价值。

  • 关键特点

    • 物品不可分割。

    • 动态规划是经典解法,贪心算法无法保证最优。

3.2 动态规划解决策略

动态规划通过构建二维表记录子问题的最优解,核心思想是状态转移

状态定义

设 dp[i][j]dp[i][j] 表示前 ii 件物品在容量 jj 下的最大价值。

状态转移方程

dp[i][j]={dp[i−1][j]if wi>jmax⁡(dp[i−1][j],dp[i−1][j−wi]+vi)otherwisedp[i][j]={dp[i−1][j]max(dp[i−1][j],dp[i−1][j−wi​]+vi​)​if wi​>jotherwise​

伪代码示例:
Initialize dp[n+1][W+1] with zerosfor i from 1 to n:for j from 1 to W:if w[i-1] > j:dp[i][j] = dp[i-1][j]else:dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i-1]] + v[i-1])
return dp[n][W]

3.3 空间优化技巧

二维数组可优化为一维数组,通过逆序更新避免覆盖旧值:

dp = [0] * (W + 1)
for i in range(n):for j in range(W, w[i]-1, -1):dp[j] = max(dp[j], dp[j - w[i]] + v[i])
return dp[W]

3.4 实例分析

示例:背包容量 W=4W=4,物品如下:

物品重量价值
1115
2320
3430

动态规划表(简化版):

容量01234
物品0015151515
物品1015152035
物品2015152035

最优解:物品1(15) + 物品2(20) = 35。

3.5 复杂度分析

  • 时间复杂度:O(nW)O(nW)(伪多项式时间,与输入规模相关)。

  • 空间复杂度:O(W)O(W)(优化后)。

3.6 应用场景

  • 货物装载(如卡车运输不可拆分的货物)。

  • 投资决策(选择互斥项目)。

  • 密码学中的子集和问题。

4. 部分背包与0-1背包的对比

特征部分背包0-1背包
物品是否可分割
最优解算法贪心算法动态规划
时间复杂度O(nlog⁡n)O(nlogn)O(nW)O(nW)
适用场景可分割资源不可分割物品
是否总能得到最优解

5. 扩展:其他背包问题变种

  1. 完全背包:每件物品可无限次选择。

  2. 多重背包:每件物品有数量限制。

  3. 多维背包:背包有多个容量约束(如重量和体积)。

  4. 分组背包:物品分组,每组只能选一件。

6. 总结

部分背包问题和0-1背包问题在算法设计中具有重要地位。前者通过贪心算法高效解决,后者依赖动态规划处理更复杂的约束。理解它们的区别与联系,有助于在实际问题中选择合适的策略。未来可进一步探索其他变种问题,以适应更广泛的应用场景。

相关文章:

算法中的背包问题详解:部分背包与0-1背包

1. 背包问题概述 背包问题是组合优化中的经典问题,其核心目标是:在给定容量的背包中装入一组物品,使得物品的总价值最大化。根据物品是否可分割或重复选择,背包问题分为多个变种,其中最常见的两种是: 部分…...

【单片机通信技术】STM32 HAL库 SPI主从机通过串口发送数据

一、说明 使用STM32F103C8T6最小系统板,让板载SPI1与SPI2通信,通过串口收发数据。本文章说明了在配置与编写时遇到的一些问题,以及详细说明如何使用cubeMAX进行代码编写。 二、CubeMAX配置 1.时钟配置选择外部高速时钟 2.系统模式与时钟配…...

laravel中 添加公共/通用 方法/函数

一,现在app 下面创建Common目录,然后在创建Common.php 文件 二,修改composer.json文件 添加这个到autoload 中 "files": ["app/Common/Common.php"]"autoload": {"psr-4": {"App\\": &quo…...

Jetpack Compose — 入门实践

一、项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose。 开发工具: Android Studio 1.1 创建支持 Compose 新应用 新版 Android Studio 默认创建新项目即为 Compose 项目。 注意:在 Language 下拉菜单中,Kotlin 是唯一可…...

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集 or Set--lower_bound()的解法!!!

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集 题目 并查集解析代码【并查集解】 Set 解法解析lower_bound代码 题目 并查集解析 首先先让所有的f(i)i,即每个人最开始的祖先都是自己,然后就每一次都让轮到那个数的父亲1&#xff08…...

应用案例 | 精准控制,高效运行—宏集智能控制系统助力SCARA机器人极致性能

概述 随着工业4.0的深入推进,制造业对自动化和智能化的需求日益增长。传统生产线面临空间不足、效率低下、灵活性差等问题,尤其在现有工厂改造项目中,如何在有限空间内实现高效自动化成为一大挑战。 此次项目的客户需要在现有工厂基础上进行…...

Greenplum6.19集群搭建

一,安装说明 1.1环境说明 1、首先确定部署的环境,确定下服务器的端口,一般默认是22的端口; 2、当前这份文档是服务器处于10022端口下部署的(现场生产环境要求,22端口在生产环境存在安全隐患)&…...

sqlserver中的锁模式 | SQL SERVER如何开启MVCC(使用row-versioning)【启用行版本控制减少锁争用】

文章目录 引言锁和隔离级别的关系锁模式之间兼容性I 隔离级别SQLServer默认的隔离级别为:“read commited” (已提交读)在SQLServer2005引入了基于行版本控制的隔离级别。SQL SERVER如何开启MVCC(使用row-versioning)sqlserver开启MVCC后的锁II sqlserver中的锁模式**1、共享…...

胜软科技冲刺北交所一年多转港股:由盈转亏,毛利率大幅下滑

《港湾商业观察》施子夫 近期,山东胜软科技股份有限公司(以下简称,胜软科技)递表港交所获受理,独家保荐机构为广发证券(香港)。 在赴港上市之前,胜软科技还曾谋求过A股上市&#x…...

Java零基础入门笔记:多线程

前言 本笔记是学习狂神的java教程,建议配合视频,学习体验更佳。 【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili 第1-2章:Java零基础入门笔记:(1-2)入门(简介、基础知识)-CSDN博客 第3章…...

Django 中,Form 和 ModelForm的用法和区别

在 Django 中,Form 和 ModelForm 是用于处理表单数据的两种主要方式。它们的主要区别在于是否与模型(Model)直接关联。以下是它们的用法、区别以及高级用法的详细说明: 一、Form 的使用 1. 基本用法 Form 是一个独立的表单类,不与任何模型直接关联。适用于需要手动定义字…...

tcp udp区别

TCP(传输控制协议) 和 UDP(用户数据报协议) 是两种常用的传输层协议,它们在数据传输方式、可靠性和应用场景等方面有显著区别。以下是它们的主要区别: 1. 连接方式 TCP:面向连接的协议。通信前需…...

数据类设计_图片类设计之1_矩阵类设计(前端架构基础)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 图形在底层是怎么表示的,用C来表示 认识图片 图片是个风景,动物,还是其他内容,人是可以看出来的.那么计算机是怎么看懂的呢?在有自主意识的人工智能被设计出来…...

C++:入门详解(关于C与C++基本差别)

目录 一.C的第一个程序 二.命名空间(namespace) 1.命名空间的定义与使用: (1)命名空间里可以定义变量,函数,结构体等多种类型 (2)命名空间调用(&#xf…...

GC安全点导致停顿时间过长的案例

GC安全点导致停顿时间过长的案例 前言安全点的概念案例分析解决方法如有需要收藏的看官,顺便也用发财的小手点点赞哈,如有错漏,也欢迎各位在评论区评论! 前言 前段时间在使用G1垃圾收集时,因服务读写压力过大&#xf…...

linux下 jq 截取json文件信息

背景:通过‘登录名‘ 获取该对象的其他个人信息如名字。 环境准备:麒麟操作系统V10 jq安装包 jq安装包获取方式:yum install jq 或 使用附件中的rpm 或 git自行下载 https://github.com/stedolan/jq/releases/download/ 实现过程介绍&am…...

git lfs使用方法指南【在github保存100M以上大文件】

为了在 GitHub 仓库中存储超过 100MB 的大文件并避免推送失败,使用 Git LFS(Large File Storage) 是最佳解决方案。以下是详细步骤: 一、安装 Git LFS 下载并安装 Git LFS: 访问 Git LFS 官网 下载对应系统的安装包。或…...

躲藏博弈:概率论与博弈论视角下的最优策略选择

躲藏博弈:概率论与博弈论视角下的最优策略选择 1. 问题引入 想象这样一个场景:你在厕所里藏了一部手机,一周过去了,它仍未被发现。现在你面临一个决策: 选项A:继续将手机留在原处选项B:将手机…...

类加载器加载过程

今天我们就来深入了解一下Java中的类加载器以及它的加载过程。 一、什么是类加载器? 在Java中,类加载器(Class Loader)是一个非常重要的概念。它负责将类的字节码文件(.class文件)加载到Java虚拟机&#x…...

Python中dump、dumps和load、loads的异同

Python中dump、dumps和load、loads的异同 Python中dump、dumps和load、loads的异同 1. json.dump()和json.dumps() 1.1 json.dump()1.1 json.dumps() 2. json.load()和json.loads() 2.1 json.load()2.2. json.loads() 3. 总结对比4. 区分5. 完整代码 1. json.dump()和json.dum…...

Spring Boot整合ArangoDB教程

精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、环境准备 JDK 17Maven 3.8Spring Boot 3.2ArangoDB 3.11(本地安装或Docker运行) Docker启动ArangoDB docker run -d --name ar…...

vue3框架的响应式依赖追踪机制

当存在一个响应式变量于视图中发生改变时会更新当前组件的所以视图显示,但是没有视图中不写这个响应式变量就就算修改该变量也不会修改视图,这是为什么?我们能否可以理解宽泛的理解为vue组件的更新就是视图的更新,单当视图中不存在…...

软件工程:软件需求之需求分析方法

目录 前言 需求分析方法 工具和方法 具体分析方法 对运行环境的影响 ​编辑 前言 本文重点介绍开展软件需求分析的方法。 需求分析方法 工具和方法 软件需求可以维护在ALM系统中,譬如:doors,codeBeamer等,JIRA适合互联网行…...

【网络编程】WSAAsyncSelect 模型

十、基于I/O模型的网络开发 接着上次的博客继续分享:select模型 10.8 异步选择模型WSAAsyncSelect 10.8.1 基本概念 WSAAsyncSelect模型是Windows socket的一个异步I/O 模型,利用这个模型,应用程序 可在一个套接字上接收以Windows 消息为基…...

视觉-语言模型-出发点CLIP--(精读论文)

阅读建议:配合这个源码分析阅读效果更加 研究背景和目的 介绍当前计算机视觉系统依赖固定类别标签训练的局限性,以及自然语言监督作为一种有潜力替代方式的研究现状。强调论文旨在探索从自然语言监督中学习可迁移视觉模型,实现零样本学习&a…...

docker本地部署RagFlow

1.安装 克隆仓库 git clone https://github.com/infiniflow/ragflow.git构建预建的Docker映像并启动服务器 cd ragflow/docker chmod x ./entrypoint.sh docker compose -f docker-compose.yml -p ragflow up -d修改ragflow/docker/.env文件 #RAGFLOW_IMAGEinfiniflow/ragfl…...

机器学习数学基础:44.多元线性回归

一、文字内容详解 1. 多重共线性的判断——皮尔逊相关系数 皮尔逊相关系数用于衡量自变量间的线性相关程度,取值范围为 ([-1, 1]): 绝对值越接近 (1),变量间线性相关性越强;越接近 (0),相关性越弱。在多重共线性判断…...

GetWindowLongPtr函数分析

第一部分: #ifdef UNICODE FUNCLOG2(LOG_GENERAL, LONG_PTR, APIENTRY, GetWindowLongPtrW, HWND, hwnd, int, nIndex) #else FUNCLOG2(LOG_GENERAL, LONG_PTR, APIENTRY, GetWindowLongPtrA, HWND, hwnd, int, nIndex) #endif // UNICODE LONG_PTR APIENTRY GetWin…...

大语言模型(LLM)和嵌入模型的统一调用接口

ChatModelFactory、EmbeddingModelFactory 讲解代码:import os from dotenv import load_dotenv, find_dotenv_ load_dotenv(find_dotenv())from langchain_openai import ChatOpenAI, OpenAIEmbeddings, AzureChatOpenAI, AzureOpenAIEmbeddingsclass ChatModelF…...

大白话html语义化标签优势与应用场景

大白话html语义化标签优势与应用场景 大白话解释 语义化标签就是那些名字能让人一看就大概知道它是用来做什么的标签。以前我们经常用<div>来做各种布局&#xff0c;但是<div>本身没有什么实际的含义&#xff0c;就像一个没有名字的盒子。而语义化标签就像是有名…...