hello-algo 分数背包问题:贪心策略、代码实现与正确性证明
教程文档示例工程教育【免费下载链接】hello-algo《Hello 算法》动画图解、一键运行的数据结构与算法教程。支持简中、繁中、English、日本語提供 Python, Java, C, C, C#, JS, Go, Swift, Rust, Ruby, Kotlin, TS, Dart 等代码实现项目地址https://gitcode.com/GitHub_Trending/he/hello-algo点击查看免费下载分数背包Fractional Knapsack是《Hello 算法》贪心章节中最适合入门贪心思想的经典优化问题与 0-1 背包不同它允许将物品切分后按重量比例装取价值从而让“每轮选择单位价值最高的物品”这一贪心策略天然成立。本文以仓库中的 Python 代码 为骨架逐行拆解算法实现并补充复杂度分析、反证法正确性证明、多语言实现对照与运行验证方式帮助你完整掌握这一贪心算法范式。问题定义允许切分的背包给定 $n$ 个物品第 $i$ 个物品的重量为 $wgt[i-1]$、价值为 $val[i-1]$以及一个容量为 $cap$ 的背包。每个物品只能选择一次但可以选择物品的一部分价值根据选择的重量比例计算问在限定背包容量下背包中物品的最大价值。下图给出了仓库文档中使用的示例数据在该示例中5 个物品的重量与价值分别为 $wgt [10, 20, 30, 40, 50]$、$val [50, 120, 150, 210, 240]$背包容量 $cap 50$。完整问题描述可参见 docs/chapter_greedy/fractional_knapsack_problem.md。与 0-1 背包问题的区别分数背包问题和 0-1 背包问题整体上非常相似状态都包含当前物品 $i$ 和剩余容量 $c$目标都是求限定背包容量下的最大价值。关键不同点在于本题允许只选择物品的一部分——可以对物品任意切分并按照重量比例计算相应价值对于物品 $i$它在单位重量下的价值为 $val[i-1] / wgt[i-1]$简称单位价值value density也称性价比假设放入一部分物品 $i$重量为 $w$则背包增加的价值为 $w \times val[i-1] / wgt[i-1]$。正是“可切分”这一性质让分数背包拥有了与 0-1 背包截然不同的求解路径0-1 背包需要动态规划在“取 / 不取”之间做权衡而分数背包可以直接向单位价值最高的物品“敞口装取”直至背包装满。贪心策略按单位价值从高到低选取最大化背包内物品总价值本质上是最大化单位重量下的物品价值。由此可以推理出分数背包的贪心策略共三步将物品按照单位价值从高到低进行排序遍历所有物品每轮贪心地选择单位价值最高的物品若剩余背包容量不足则使用当前物品的一部分填满背包。从图中可以看到先取单位价值最高6.0的 20kg / 120 元物品再取单位价值次高5.25的 40kg / 210 元物品但此时剩余容量只剩 30kg不足以整件装入于是按比例只装入 30kg 的部分获得 $210 \times 30 / 40 157.5$ 的价值最终总价值为 $120 157.5 277.5$。代码实现与逐行解析仓库中该算法的 Python 实现位于 codes/python/chapter_greedy/fractional_knapsack.py同时 codes/pythontutor/chapter_greedy/fractional_knapsack.md 内嵌了这段代码的逐行可视化执行链接可配合学习class Item: 物品 def __init__(self, w: int, v: int): self.w w # 物品重量 self.v v # 物品价值 def fractional_knapsack(wgt: list[int], val: list[int], cap: int) - int: 分数背包贪心 # 创建物品列表包含两个属性重量、价值 items [Item(w, v) for w, v in zip(wgt, val)] # 按照单位价值 item.v / item.w 从高到低进行排序 items.sort(keylambda item: item.v / item.w, reverseTrue) # 循环贪心选择 res 0 for item in items: if item.w cap: # 若剩余容量充足则将当前物品整个装进背包 res item.v cap - item.w else: # 若剩余容量不足则将当前物品的一部分装进背包 res (item.v / item.w) * cap # 已无剩余容量因此跳出循环 break return res Driver Code if __name__ __main__: wgt [10, 20, 30, 40, 50] val [50, 120, 150, 210, 240] cap 50 n len(wgt) # 贪心算法 res fractional_knapsack(wgt, val, cap) print(f不超过背包容量的最大物品价值为 {res})逐段理解这段代码物品建模定义Item类封装重量w与价值v两个属性这是为了后续排序时能同时携带重量与价值信息避免索引错位构造物品列表zip(wgt, val)将重量数组与价值数组按位置配对列表推导式一次性生成全部Item对象核心贪心排序items.sort(keylambda item: item.v / item.w, reverseTrue)以单位价值为键降序排序将性价比最高的物品排在最前。这一步是贪心策略的直接体现循环装取遍历排序后的物品若item.w cap说明剩余容量充足整件装入并累加价值、扣减容量否则只装入剩余容量对应的一部分价值(item.v / item.w) * cap并立即break——因为背包装满后不可能再放入任何物品结果返回累加值res即为限定容量下的最大物品价值。运行上述 Driver Code控制台将输出不超过背包容量的最大物品价值为 277.5复杂度分析对代码进行复杂度拆解排序阶段内置排序算法的时间复杂度通常为 $O(n \log n)$其中 $n$ 为物品数量贪心遍历阶段除排序之外最差情况下需要遍历整个物品列表因此时间复杂度为 $O(n)$综合时间复杂度$O(n \log n)$主导项来自排序空间复杂度由于初始化了一个Item对象列表需要 $O(n)$ 的额外空间排序本身的辅助空间为 $O(\log n)$ 或 $O(n)$取决于具体语言实现但物品列表的 $O(n)$ 已是主导项。作为对比贪心算法章节总览 指出相比动态规划贪心算法通常拥有更低的时间复杂度这正是它的核心优势之一。正确性证明反证法与几何直觉贪心策略是否真的能得到最优解这需要严谨证明仓库文档给出了基于反证法的经典证明思路假设物品 $x$ 是单位价值最高的物品某个算法求得的最大价值为res但该解中不包含物品 $x$现在从背包中拿出单位重量的任意物品并替换为单位重量的物品 $x$。由于物品 $x$ 的单位价值最高替换后的总价值一定大于res这与“res是最优解”矛盾说明最优解中必须包含物品 $x$对于解中的其他物品也可以构建出同样的矛盾。总而言之单位价值更大的物品总是更优选择贪心策略由此被证明有效。此外docs/chapter_greedy/fractional_knapsack_problem.md 还给出了一个直观的几何类比将物品重量和物品单位价值分别看作二维图表的横轴与纵轴则分数背包问题可转化为“求在有限横轴区间下围成的最大面积”从几何角度看单位价值即柱状高度贪心策略等价于“每次取最高的柱”而可切分性保证每次都能把柱取到横轴区间耗尽为止——这从直观上解释了为何该策略不会“浪费”容量这也是它区别于 0-1 背包柱不可切分、可能取不到最优的本质原因。多语言实现对照仓库在 codes 目录下为分数背包提供了 13 种语言的实现各语言在“构造物品 按单位价值排序 贪心装取”的主干上完全一致差异主要体现在语法细节上语言实现文件排序方式返回类型Pythonfractional_knapsack.pylist.sort(keylambda item: item.v / item.w, reverseTrue)int累加后自动转为 floatCfractional_knapsack.cqsort 单位价值比较函数floatCfractional_knapsack.cppsort lambda 比较器doubleJavafractional_knapsack.javaArrays.sortComparator.comparingDoubledoubleGofractional_knapsack.gosort.Slice 闭包比较float64JavaScriptfractional_knapsack.jsArray.sort((a, b) b.v / b.w - a.v / a.w)numberTypeScriptfractional_knapsack.ts同 JavaScript带类型标注numberC#fractional_knapsack.csArray.Sort 比较器doubleSwiftfractional_knapsack.swiftitems.sort 闭包DoubleKotlinfractional_knapsack.ktitems.sortBy 取负单位价值DoubleRustfractional_knapsack.rssort_bypartial_cmpf64Dartfractional_knapsack.dartitems.sortcompareTodoubleRubyfractional_knapsack.rbitems.sort! 宇宙飞船运算符Integer/Float几个值得注意的语言特性C 语言使用qsort与结构体数组比较函数中通过(float)(t1-v) / t1-w (float)(t2-v) / t2-w判定密度大小并在循环结束后显式free(items)释放堆内存Rust因浮点数未实现Ord需用partial_cmp(...).unwrap()完成比较Go在 fractional_knapsack_test.go 中提供了TestFractionalKnapsack单元测试直接验证贪心结果C#的实现将算法封装为FractionalKnapsack实例方法并以[Test]标注的Test()方法驱动运行与项目的测试框架衔接。运行与验证方式你可以按以下方式在本地运行这些实现进行验证Python直接执行python3 fractional_knapsack.py输出“不超过背包容量的最大物品价值为 277.5”Ccodes/c/chapter_greedy/CMakeLists.txt中已声明add_executable(fractional_knapsack fractional_knapsack.c)可通过 CMake 构建后运行输出格式为%0.2f即277.50Go在codes/go目录下执行go test通过 测试文件 验证结果其他语言各文件均自带 Driver Code /main入口Swift 使用main枚举、Rust 使用fn main可直接编译运行。无论使用哪种语言只要贪心排序与装取逻辑一致得到的最大价值都应为 277.5——这与数学推导完全吻合可作为自检基准。小结分数背包问题清晰展示了贪心算法的完整解题范式分析问题特性可切分→ 确定贪心策略按单位价值降序装取→ 证明正确性反证法。通过仓库提供的 Python 逐行代码、PythonTutor 可视化、13 种语言实现与配套测试你可以快速上手并验证这一经典算法。在掌握分数背包之后不妨继续阅读 贪心算法章节总览 与 章节小结进一步理解贪心选择性质与最优子结构以及零钱兑换、最大容量、最大切分乘积等其他贪心经典问题。赞分享教程文档示例工程教育【免费下载链接】hello-algo《Hello 算法》动画图解、一键运行的数据结构与算法教程。支持简中、繁中、English、日本語提供 Python, Java, C, C, C#, JS, Go, Swift, Rust, Ruby, Kotlin, TS, Dart 等代码实现项目地址https://gitcode.com/GitHub_Trending/he/hello-algo点击查看免费下载相关推荐Hello 算法中的分数背包问题单位价值贪心策略的原理、实现与正确性证明Hello 算法中的分数背包问题单位价值贪心策略的原理、实现与正确性证明 本篇技术指南聚焦《Hello 算法》中分数背包问题Fractional Knaps教程文档示例工程教育Hello Algo 贪心算法章节总复习贪心选择性质、三步解题框架与三大经典贪心问题的正确性证明Hello Algo 贪心算法章节总复习贪心选择性质、三步解题框架与三大经典贪心问题的正确性证明 本文是对《Hello 算法》本仓库英文文档树 en/doc教程文档示例工程教育Hello 算法最大容量问题详解双指针贪心策略的推导、实现与正确性证明Hello 算法最大容量问题详解双指针贪心策略的推导、实现与正确性证明 在《Hello 算法》hello algo的贪心算法章节中最大容量问题是一个教程文档示例工程教育上一篇Salt 内核参数管理实战深入解析 salt.modules.linux_sysctl 执行模块下一篇阿里云Qwen3-Coder震撼开源4800亿参数重构AI编程生产力SWE-Bench评分比肩Claude4创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Pulse v6.4.0-rc.8 告警体系升级指南:持久化生命周期、精细路由与存储容量预测

Pulse v6.4.0-rc.8 告警体系升级指南:持久化生命周期、精细路由与存储容量预测

可观测性运维后端 【免费下载链接】Pulse Real-time monitoring dashboard for Proxmox VE, PBS, Docker, Kubernetes, TrueNAS and vSphere. Self-hosted, with smart alerts and AI patrols that catch silent failures. 项目地址: https://gitcode.com/gh_mirror…

2026/10/10 15:58:46 阅读更多 →
Ant Design Blazor Carousel 渐显切换效果(Fade)实战与源码解析

Ant Design Blazor Carousel 渐显切换效果(Fade)实战与源码解析

UI组件前端 【免费下载链接】ant-design-blazor 🌈A rich set of enterprise-class UI components based on Ant Design and Blazor. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-blazor 点击查看 免费下载 导读 本文围绕 Ant Design Bla…

2026/10/10 15:58:46 阅读更多 →
Cursor 中安装 Augment 插件:从 vsix 到 TaoToken 的完整配置指南

Cursor 中安装 Augment 插件:从 vsix 到 TaoToken 的完整配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 15:58:46 阅读更多 →

最新新闻

impeccable:一款面向OpenAPI契约的Python自动化校验工具

impeccable:一款面向OpenAPI契约的Python自动化校验工具

我无法基于当前输入生成符合要求的博文。原因如下:输入中仅提供了项目标题"impeccable",以及空置的“相关热搜词”“最新网络热词”和完全空白的搜索内容块(),未提供任何实质性的项目正文、关键词列表或摘要…

2026/10/10 21:47:36 阅读更多 →
X射线底片焊缝缺陷检测:2647张6类标注数据集,可直接喂给YOLO

X射线底片焊缝缺陷检测:2647张6类标注数据集,可直接喂给YOLO

简介:面向工业X射线底片焊缝缺陷检测的目标检测数据集,涵盖裂纹、未熔合、未渗透等6类焊缝缺陷,共2647张底片图像、4766个真实标注框,适合用于YOLO、Faster R-CNN等目标检测模型的训练与评测。数据采用VOC与YOLO双格式存储&#x…

2026/10/10 21:47:36 阅读更多 →
AI辅助软件测试实战:从脚本生成到日志分析的全流程经验

AI辅助软件测试实战:从脚本生成到日志分析的全流程经验

软件测试这行的工具形态,这几年变化比我入行前十年加起来都大。以前同行碰头聊提效,无非是自动化框架怎么搭、脚本怎么写更稳、CI怎么接;现在问得最多的变成了"你平时用哪个AI工具""Prompt怎么写的""AI生成的脚本你…

2026/10/10 21:47:36 阅读更多 →
开源AI测试工具落地指南:从接口自动化到自愈定位器的实践选型

开源AI测试工具落地指南:从接口自动化到自愈定位器的实践选型

软件测试这个岗位,这两年的变化比过去十年加起来都大。我记得年初帮一个测试组做评审,同事把一份AI生成的接口用例贴出来,从覆盖路径到断言写法看着都像模像样,但一跑就发现大量断言是“凭空捏造”的——它把响应里根本不存在的字…

2026/10/10 21:47:36 阅读更多 →
Inno Setup自定义安装界面:ILSpy反编译+WinForms回调实践

Inno Setup自定义安装界面:ILSpy反编译+WinForms回调实践

简介:一套面向.NET应用开发者的Inno Setup自定义安装界面资源,用于解决安装包界面模板固化、动态配置繁琐的问题。资源基于Inno Setup增强版封装,内置对.NET Framework 4的依赖支持,并将界面逻辑集中在Code.iss脚本中,…

2026/10/10 21:47:36 阅读更多 →
【Claude Code】BMad-Method 多智能体协作实战:PRD 与架构文档一键生成,TaoToken 统一 Key 接入

【Claude Code】BMad-Method 多智能体协作实战:PRD 与架构文档一键生成,TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 21:46:35 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →