简体   繁体   English

仅使用集合中的数字找到等于或大于给定目标的总和

[英]Find a sum equal or greater than given target using only numbers from set

Example 1: 范例1:

Shop selling beer, available packages are 6 and 10 units per package. 商店出售啤酒,可用包装为6件和10件/包。 Customer inputs 26 and algorithm replies 26, because 26 = 10 + 10 + 6. 客户输入26和算法答复26,因为26 = 10 + 10 + 6。

Example 2: 范例2:

Selling spices, available packages are 0.6, 1.5 and 3. Target value = 5. Algorithm returns value 5.1, because it is the nearest greater number than target possible to achieve with packages (3, 1.5, 0.6). 销售香料,可用包装为0.6、1.5和3。目标值=5。算法返回值5.1,因为它是与包装(3、1.5、0.6)可能达到的目标最接近的数字。

I need a Java method that will suggest that number. 我需要一个可以提示该数字的Java方法。

Simmilar algorithm is described in Bin packing problem , but it doesn't suit me. Simmilar算法已在Bin装箱问题中进行了介绍 ,但不适合我。 I tried it and when it returned me the number smaller than target I was runnig it once again with increased target number. 我尝试了一下,当它返回的数值小于目标值时,我又跑了一下,目标编号又增加了。 But it is not efficient when number of packages is huge. 但是,当软件包数量巨大时,效率不高。

I need almost the same algorithm, but with the equal or greater nearest number. 我需要几乎相同的算法,但是具有相等或更大的最近数。

Similar question: Find if a number is a possible sum of two or more numbers in a given set - python . 相似的问题: 查找一个数字是否是给定集合python中两个或多个数字的可能和

First let's reduce this problem to integers rather than real numbers, otherwise we won't get a fast optimal algorithm out of this. 首先,让我们将此问题简化为整数而不是实数,否则我们将无法从中获得快速的最佳算法。 For example, let's multiply all numbers by 100 and then just round it to the next integer. 例如,让我们将所有数字乘以100,然后将其舍入到下一个整数。 So say we have item sizes x 1 , ..., x n and target size Y . 假设我们有项目大小x 1 ,...,x n和目标大小Y。 We want to minimize the value 我们想使价值最小化

k 1 x 1 + ... + k n x n - Y k 1 x 1 + ... + k n x n -Y

under the conditions 在条件下

(1) k i is a non-positive integer for all n ≥ i ≥ 1 (1)K i是对所有的n≥I≥1所述的非正整数

(2) k 1 x 1 + ... + k n x n - Y ≥ 0 (2) k 1 x 1 + ... + k n x n -Y≥0

One simple algorithm for this would be to ask a series of questions like 一个简单的算法是问一系列问题,例如

  1. Can we achieve k 1 x 1 + ... + k n x n = Y + 0 ? 我们可以达到k 1 x 1 + ... + k n x n = Y + 0吗?
  2. Can we achieve k 1 x 1 + ... + k n x n = Y + 1 ? 我们可以达到k 1 x 1 + ... + k n x n = Y + 1吗?
  3. Can we achieve k 1 x 1 + ... + k n x n = Y + z ? 我们可以达到k 1 x 1 + ... + k n x n = Y + z吗?
  4. etc. with increasing z 等随着z的增加

until we get the answer "Yes". 直到我们得到答案“是”。 All of these problems are instances of the Knapsack problem with the weights set equal to the values of the items. 所有这些问题都是背包问题的实例,其权重设置为等于项目的值。 The good news is that we can solve all those at once, if we can establish an upper bound for z . 好消息是,如果我们可以确定z的上限,那么我们可以立即解决所有这些问题。 It's easy to show that there is a solution with z ≤ Y , unless all the x i are larger than Y , in which case the solution is just to pick the smallest x i . 很容易证明存在一个z≤Y的解,除非所有x i都大于Y ,在这种情况下,该解决方案只是选择最小的x i

So let's use the pseudopolynomial dynamic programming approach to solve Knapsack: Let f(i,j) be 1 iif we can reach total item size j with the first i items (x 1 , ..., x i ). 因此,让我们使用伪多项式动态规划方法来解决背包问题:如果f(i,j)为1,前提是我们可以用前i个项(x 1 ,...,x i )达到总项大小j We have the recurrence 我们有复发

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) ...

We can solve this DP array in O(n * Y) time and O(Y) space. 我们可以在O(n * Y)时间和O(Y)空间中求解该DP阵列。 The result will be the first j ≥ Y with f(n, j) = 1 . 结果将是第一个j≥Y且 f(n,j)= 1

There are a few technical details that are left as an exercise to the reader: 剩下的一些技术细节可供练习:

  • How to implement this in Java 如何用Java实现
  • How to reconstruct the solution if needed. 如果需要,如何重建解决方案。 This can be done in O(n) time using the DP array (but then we need O(n * Y) space to remember the whole thing). 可以使用DP数组在O(n)时间内完成此操作(但随后我们需要O(n * Y)空间来记住整个事情)。

You want to solve the integer programming problem min(ct) st ct >= T, c >= 0 where T is your target weight, and c is a non-negative integer vector specifying how much of each package to purchase, and t is the vector specifying the weight of each package. 您想解决整数编程问题min(ct)st ct> = T,c> = 0,其中T是您的目标体重,c是一个非负整数,指定要购买的每个包装的数量,t是指定每个包装重量的向量。 You can either solve this with dynamic programming as pointed out by another answer, or, if your weights and target weight are too large then you can use general integer programming solvers, which have been highly optimized over the years to give good speed performance in practice. 您可以使用另一个答案指出的动态编程来解决此问题,或者,如果您的权重和目标权重太大,则可以使用经过多年高度优化以在实践中提供出色速度性能的通用整数编程求解器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 回溯 - 给定一组数字,找到总和等于 M 的所有子集(给定 M) - Backtracking - Given a set of numbers, find all the subsets with a sum equal to M (M is given) 打印小于或等于56且数字总和大于10的两位数 JAVA - print two digit numbers which are less than or equal to 56 and the sum of digits is greater than 10 JAVA 与数据结构有关。 查找所有大于或等于给定输入的数组元素 - Datastructure related. Find all arrays elements greater than or equal to given input 如何转换字符串,使其只包含出现次数大于或等于给定值的元音? - How to transform a string such that it only contains vowels which have occurences equal or greater than their given values? 等于给定数字的两个数字之和 - Sum of two numbers equal to the given number 如何找到产品大于总和的货币对 - How to find pairs with product greater than sum 在Java中使用double大于或等于 - greater than or equal to in java using double 如何找到总和等于或小于给定数量的元组数? - How to find number of tuples whose sum is equal or less than a given number? 给定数字n,我们必须找出小于或等于n的正好有3个除数的数字 - given a number n , we have to find out such numbers that are less than or equal to n, that have exactly 3 divisors 查找数组中两个数字的总和是否等于 k - Find if sum of two numbers in an array is equal to k
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM