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

贪心算法之分数背包问题

一、问题本质与核心区别

1. 问题定义

分数背包问题是经典的资源优化类问题,核心要素与目标如下:

  • 输入条件:给定一组物品(每个物品含「重量」和「价值」两个属性)、一个固定容量的背包
  • 核心规则:允许将物品分割成任意比例装入背包,无需完整装入
  • 优化目标:在不超过背包容量的前提下,最大化背包内物品的总价值

2. 与 0-1 背包问题的关键差异

对比维度

分数背包问题

0-1 背包问题

物品装入规则

可分割,支持部分装入

不可分割,仅能完整装入或不装

适用算法

贪心算法(可获最优解)

动态规划(贪心算法无效)

决策逻辑复杂度

仅需按单位价值优先级选择

需考虑物品组合的整体价值

二、算法核心:贪心策略的原理与合理性

1. 贪心策略的核心逻辑

        解决分数背包问题的贪心策略可概括为:优先选择「单位价值最高」的物品,依次装入背包(能完整装则装,若装不下则装入部分)。

        其中,单位价值 的计算方式为:单位价值(ratio)= 物品价值(value)/ 物品重量(weight),代表每单位重量物品能带来的价值回报。

2. 策略合理性证明

该策略能确保得到最优解,核心原因有两点:

  • 单位价值越高的物品,“重量性价比” 越高,优先装入可在有限容量内快速积累高价值。
  • 由于允许物品分割,当遇到无法完整装入的高单位价值物品时,可装入剩余容量对应的比例,避免容量浪费,实现 “物尽其用”,最终总价值达到最大。

三、数据结构设计与关键变量

1. 核心数据结构:物品结构体(Item)

通过结构体封装物品的三个关键属性,便于统一存储和处理:

struct Item {int weight; // 物品重量int value; // 物品价值double ratio; // 单位价值
};

2. 关键变量说明

  • items[M]:存储所有物品的数组,M为预设的最大容量
  • n:用户输入的实际物品数量。
  • capacity:用户输入的背包最大容量。
  • totalValue:累加存储背包内物品的总价值。
  • remaining:记录背包剩余容量。

四、核心算法实现(代码解析)

1. 第一步:物品排序函数(cmp)

        需先对所有物品按「单位价值(ratio)」降序排序,为后续贪心选择铺路,排序函数作为 sort函数的比较器使用:

// 按单位价值降序排序,单位价值高的物品排在前面
bool cmp(Item a, Item b) {return a.ratio > b.ratio;
}
  • 排序后,物品列表的优先级顺序为:单位价值从高到低,确保后续遍历能优先处理高价值密度的物品。

2. 第二步:贪心选择算法(maxValue 函数)

该函数是核心计算模块,实现物品的选择与价值累加,具体逻辑如下:

double maxValue(Item items[], int n, int capacity) {double totalValue = 0.0; // 初始化总价值为0int remaining = capacity; // 初始化剩余容量为背包总容量// 遍历排序后的物品数组(从单位价值最高的开始)for (int i = 0; i < n; i++) {// 情况1:当前物品可完整装入背包if (items[i].weight <= remaining) {totalValue += items[i].value; // 累加物品全部价值remaining -= items[i].weight; // 减少相应剩余容量}// 情况2:当前物品无法完整装入,装入剩余容量对应的部分else {// 部分物品的价值 = 剩余容量 / 物品总重量 * 物品总价值totalValue += (double)remaining / items[i].weight * items[i].value;remaining = 0; // 剩余容量耗尽,背包装满break; // 无需继续遍历,退出循环}}return totalValue; // 返回最终的最大总价值
}

五、完整流程与示例分析

1. 完整执行流程

整个问题的解决流程分为「输入 → 处理 → 输出」三阶段,逻辑清晰:

  1. 输入阶段

  • 用户输入物品数量 n 和背包容量 capacity(如输入 “3 50”,代表 3 个物品、背包容量 50kg)
  • 依次输入每个物品的「重量」和「价值」(如输入 “10 60” “20 100” “30 120”)
  • 计算每个物品的单位价值ratio(如第一个物品的 ratio = 60 / 10 = 6)
  2. 处理阶段
  • 调用 sort(items, items + n, cmp),按单位价值降序排序物品。
  • 调用 maxValue(items, n, capacity),计算最大总价值。
  3. 输出阶段:打印最终结果

2. 示例分步解析

以输入 “3 50;10 60;20 100;30 120” 为例,详细拆解处理过程:

  • 步骤 1:排序后物品顺序

物品 1(ratio=6)→ 物品 2(ratio=5)→ 物品 3(ratio=4)(单位价值从高到低)。

  • 步骤 2:依次装入物品
  1. 装入物品 1:总价值 = 60,剩余容量为 50-10=40;
  2. 装入物品 2:总价值 = 60+100=160,剩余容量为 40-20=20;
  3. 装入物品 3 的部分:剩余容量 20kg,可装入 20/30 的物品 3,价值增加 20/30*120=80,总价值 = 160+80=240,剩余容量 = 0,停止装入。
  • 最终结果:总价值 240,与输出一致。

六、复杂度分析

1. 时间复杂度

整体时间复杂度由「排序操作」主导,具体如下:

  • 排序操作:使用标准库sort函数(基于快速排序优化版本),时间复杂度为O(n log n)
  • 贪心选择遍历:遍历n个物品,时间复杂度为O(n)
  • 总时间复杂度:O(n log n)(因为排序耗时远大于遍历,可忽略O(n)项),适用于中等规模数据(如n≤10^5)

2. 空间复杂度

空间复杂度主要来自物品存储,为O(n):

  • 仅需一个数组 items 存储 n 个物品的属性,无额外复杂数据结构,空间利用率高。

七、适用场景与局限性

1. 适用场景

该算法适用于满足「可分割」和「追求单位资源效益最大化」的场景,典型案例包括:

  • 资源分配问题(如将有限资金按 “单位收益” 分配给不同项目,允许部分投资)
  • 材料切割问题(如将固定长度的钢材按 “单位长度价值” 切割,最大化总价值)
  • 能源分配问题(如将有限电力按 “单位功率收益” 分配给不同设备)

2. 局限性

该算法并非万能,存在以下适用边界:

  • 不适用于「物品不可分割」的场景,此时需改用动态规划解决 0-1 背包问题。
  • 无法处理「物品存在依赖关系」的场景(如选择 A 物品后才能选择 B 物品,或 A、B 物品不能同时选择),需结合图论或其他算法优化。
  • 若存在 “重量为 0” 或 “价值为 0” 的异常物品,需在输入阶段增加验证逻辑,避免计算错误。
http://www.dtcms.com/a/398435.html

相关文章:

  • LLMs之AgentDevP:FastGPT的简介、安装和使用方法、案例应用之详细攻略
  • 贪心算法之船舶装载问题
  • 面试_常见大厂面试题
  • 网站地图怎么建设wordpress文章页样式修改
  • 网站如何做交互热门seo推广排名稳定
  • 【第29话:路径规划】自动驾驶启发式搜索算法(A星搜索算法( A* 搜索算法))详解及代码举例说明
  • React学习教程,从入门到精通,React Router 语法知识点及使用方法详解(28)
  • Docker Compose 从入门到实践
  • D3.js 与数据可视化
  • RNA-seq分析之最佳cutoff(TCGA版)
  • 浏览器直接进入网站的注意事项钢筋网片价格
  • scrapy-redis项目:爬取某网站图书信息
  • (论文速读)DiffBlender:可组合和通用的多模态文本到图像扩散模型
  • 第三方网站测试工具:【Postman使用基础指南】
  • Pytest+requests进行接口自动化测试5.0(5种assert断言的封装 + pymysql)
  • C# MVC 模型绑定全解析:从基础机制到自定义绑定器实战指南
  • 企业网站网页设计专业的团队网站建设
  • 网站建设可上传视频的wordpress 数据库类型
  • 广州南沙区建设和交通局网站个人建立网站要多少钱
  • Vue3 》》vite》》vite-plugin-mock mock 模拟数据 ,loadEnv
  • 宝塔面板搭建RustDesk教程:告别命令行,一键拥有私有远程桌面
  • Docker + IDEA 一键部署!
  • Rust开源HyperSwitch实战指南
  • Chrome性能优化指南
  • Chrome高危类型混淆0-Day漏洞(CVE-2025-10585)技术分析
  • 教做面点的网站广州百度竞价托管
  • 网站推广方案合肥房产网安居客
  • 【算法专题训练】24、单调栈
  • 【开题答辩全过程】以 IRWT考试预约系统为例,包含答辩的问题和答案
  • 在字典和列表相互嵌套的结构体中搜索指定元素