示例1:
商店出售啤酒,可用套餐每包6个和10个单位。客户输入26和算法回复26,因为26 = 10 + 10 + 6。
示例2:
销售香料,可用包装是0.6,1.5和3.目标值= 5.算法返回值5.1,因为它是最接近目标的数字,可以用包(3,1.5,0.6)实现。
我需要一个建议使用数字的Java方法。
Simmilar算法在Bin packing problem中描述,但它不适合我。 我尝试了它,当它返回给我的数字小于目标时,我再次使用增加的目标数量运行它。但是当包装数量巨大时效率不高。
我需要几乎相同的算法,但是使用相同或更大的最接近的数字。
类似的问题:Find if a number is a possible sum of two or more numbers in a given set - python。
答案 0 :(得分:4)
首先让我们将这个问题简化为整数而不是实数,否则我们将无法获得快速优化算法。例如,让我们将所有数字乘以100,然后将其四舍五入为下一个整数。所以说我们有项目大小 x 1 ,...,x n 和目标大小 Y 。我们希望最小化值
k 1 x 1 + ... + k n x n - Y
条件
(1) k i 是所有n≥i≥1
的非正整数(2) k 1 x 1 + ... + k n x n - Y≥0
一个简单的算法就是提出一系列问题,比如
直到我们得到答案“是”。所有这些问题都是Knapsack问题的实例,权重设置等于项目的值。好消息是,如果我们可以为 z 建立上限,我们可以一次解决所有这些问题。除非所有 x i 都大于 Y ,否则很容易证明存在z≤Y的解决方案>,在这种情况下,解决方案只是选择最小的 x i 。
所以让我们使用pseudopolynomial dynamic programming approach来解决背包:让 f(i,j)为1,如果我们可以达到总项目大小 j i 项目(x 1 ,...,x i )。我们有复发
f(0,0) = 1
f(0,j) = 0 for all j > 0
f(i,j) = f(i - 1, j) or f(i - 1, j - x_i) or f(i - 1, j - 2 * x_i) ...
我们可以在 O(n * Y)时间和 O(Y)空间中解决此DP阵列。结果将是第一个j≥Y, f(n,j)= 1 。
有一些技术细节留给读者作为练习:
答案 1 :(得分:0)
你想解决整数规划问题min(ct)s.t。 ct> = T,c> = 0其中T是您的目标权重,c是非负整数向量,指定要购买的每个包的数量,t是指定每个包的权重的向量。您可以通过动态编程解决此问题,如另一个答案所指出的,或者,如果您的权重和目标权重太大,那么您可以使用通用整数编程求解器,这些求解器多年来经过高度优化,可在实践中提供良好的速度性能