类背包多维度近似物品组合求解问题咨询
多维度近似背包问题(强制每种物品至少1件)
问题概述
你需要解决的是多维度近似匹配的类背包问题,核心规则:
- 给定若干种物品,每种必须至少购买1件
- 目标是确定每种物品的购买数量,让总重量、总价格、总卡路里这三个维度的数值尽可能贴近预设目标值(允许高于或低于目标,取整体最接近的组合)
需求与物品示例
- 预设目标:
- 重量:20 kg
- 价格:20 usd
- 卡路里:300 kcal
- 物品参数:
- Item_1:
weight=1kg, price=0.5usd, calories=0kcal - Item_2:
weight=3kg, price=3usd, calories=70kcal
- Item_1:
- 已知最优解:6件Item_2 + 4件Item_1,总参数为
weight=22kg, price=20usd, calories=420kcal,是当前场景下最贴近目标的组合。
与经典背包/装箱问题的核心差异
- 强制最低购买量:经典背包是0-1选择或无限次选择,这里要求每种物品至少买1件,需要先处理初始分配再做优化。
- 多维度近似目标:经典背包是单维度约束(如不超过重量上限),这里没有严格的约束,目标是让总维度与预设值的差距最小化,而非最大化/最小化某个单一指标。
解法方案
1. 先消除“至少1件”的约束
第一步先给每种物品预购1件,计算初始总参数:
初始总重量 = Σ(每件物品的weight) 初始总价格 = Σ(每件物品的price) 初始总卡路里 = Σ(每件物品的calories)
之后问题转化为:在剩余的购买量(每种物品可买0件及以上)中,调整数量使得调整后的总参数与目标值的差距最小。
2. 量化“差距”的标准
要判断哪个组合最接近,必须先定义差距的计算方式,常用两种:
- 加权平方差(欧氏距离变种):给三个维度分配优先级权重,计算整体偏差:
比如如果价格必须严格匹配,可将w2设为远大于w1、w3的数值。总差距 = w1*(总重量-目标重量)² + w2*(总价格-目标价格)² + w3*(总卡路里-目标卡路里)² - 加权绝对值差(曼哈顿距离):
这种方式对偏差的惩罚是线性的,适合不需要放大极端偏差的场景。总差距 = w1*|总重量-目标重量| + w2*|总价格-目标价格| + w3*|总卡路里-目标卡路里|
3. 动态规划(DP)实现思路
针对多维度的近似问题,用DP记录各维度累计值对应的最小差距:
- 状态定义:
dp[w][p][c] = 当前总重量w、总价格p、总卡路里c对应的最小总差距 - 状态转移:遍历每种物品,对现有DP状态,尝试增加k件该物品(k≥0),计算新的总维度值,更新
dp[新w][新p][新c]为更小的差距值。 - 精度优化:如果维度包含小数(如0.5usd),先将所有数值乘以整数倍数转为整数(比如价格乘2),避免浮点运算的精度误差。
4. 暴力枚举(小场景快速解法)
如果物品种类少(比如≤3种),且每种物品的最大可能购买量可估算(比如根据目标值,每种最多买10件),直接枚举所有可能的数量组合,计算每种组合的总参数和总差距,选差距最小的即可。
示例验证
以题目中的场景为例:
- 先买1件Item_1和1件Item_2,初始总参数:
weight=4kg, price=3.5usd, calories=70kcal - 剩余需要调整的目标:
weight=16kg, price=16.5usd, calories=230kcal - 额外购买3件Item_1和5件Item_2,调整后的总参数:
weight=3*1+5*3=18kg, price=3*0.5+5*3=16.5usd, calories=3*0+5*70=350kcal - 最终总参数:
4+18=22kg, 3.5+16.5=20usd,70+350=420kcal,价格完全匹配目标,其他维度偏差最小,符合最优解。
内容的提问来源于stack exchange,提问作者Taha Boud
相关产品推荐
相关产品推荐

