简体   繁体   English

给定一组整数L和整数K,请选择L的最小子集S,以使SUM(S)> = K

[英]Given a set of integers L and an integer K, select a minimal subset S of L such that SUM(S) >= K

Problem was a little too long for the title, so here is the exact definition: 问题对标题来说太长了,所以这里是确切的定义:

Input 输入项

Set of integers, L 整数集L

Integer, K 整数,K

Output 输出量

A subset of L such that: L的子集,使得:

  • The sum of the subset is >= K 子集的总和> = K
  • The number of elements in the subset is minimized 子集中的元素数量最小化
  • If multiple subsets both meet the above criteria, the subset with the lowest maximum value is preferred. 如果多个子集均满足上述条件,则优先选择具有最低最大值的子集。
  • If multiple subsets are still tied, the one with the lowest sum is preferred. 如果仍然有多个子集,则首选总和最低的子集。

eg 例如

Input 输入项

L = { 4, 2, 3, 1 } L = {4,2,3,1}

K = 5 K = 5

The first two criteria would yield {4, 2}, {4, 3}, {4, 1}, and {2, 3}. 前两个条件将产生{4,2},{4,3},{4,1}和{2,3}。 We would prefer {2, 3} since its maximum value (3) is least of those. 我们更喜欢{2,3},因为它的最大值(3)是其中的最小值。

Return null or throw and exception if there is no subset that meets the criteria. 如果没有满足条件的子集,则返回null或throw和exception。

I'm a little worried that this problem is too related to the subset-sum problem and might be NP-complete. 我有点担心此问题与子集和问题过于相关,并且可能是NP完全的。

A solution might be the following: 解决方案可能是以下几种:

(1) Sort L to get l_1, l_2, ..., l_n , with l_1 > l_2 > ... > l_n . (1)排序L以获得l_1, l_2, ..., l_n ,其中l_1 > l_2 > ... > l_n

(2) For k=1,2,...,n , check whether (l_1+...+l_k) >= K , stop for the smallest k. (2)对于k=1,2,...,n ,检查(l_1+...+l_k) >= K停止最小的k。

Now you have the minimal number of elements required to meet the first criteria, and an example set {l_1,...,l_k}. 现在,您具有满足第一个条件所需的最少元素数,并具有示例集{l_1,...,l_k}.

(3) Now we have to find a set with k elements that satisfies the rest. (3)现在我们必须找到一个包含k个元素的集合,该集合可以满足其余条件。 You could eg start by summing up 您可以例如从总结开始

l_n + l_(n-1) + ... + l_(n-k), then 
l_(n+1) + l_n + ... + l_(n-k+1), then 
l_(n+2) + l_n + ... + l_(n-k+2), ...

and stop whenever one of these sums exceeds or is equal to K. 当这些总和之一超过或等于K时停止。

(1) can be done in O(n*log(n)) time, (2) can be done in O(n) time. (1)可以在O(n*log(n))时间完成,(2)可以在O(n)时间完成。 (3) can be done in O(n*k) = O(n^2) time. (3)可以在O(n*k) = O(n^2)时间内完成。 However, this can be improved by using a "telescope sum": 但是,可以通过使用“望远镜总和”来改善此问题:

  • Compute x := l_n + l_(n-1) + ... + l_(nk) . 计算x := l_n + l_(n-1) + ... + l_(nk)
  • If x < K , then compute x := x - l_n + l_(n-k+1) 如果x < K ,则计算x := x - l_n + l_(n-k+1)
  • If x < K , then compute x := x - l_(n-1) + l_(n-k+2) etc. 如果x < K ,则计算x := x - l_(n-1) + l_(n-k+2)

So (3) can be done in O(n) , as it seems. 因此,看起来(3)可以在O(n)完成。

So in total, O(n*log(n)) seems possible for this task. 因此,总的来说, O(n*log(n))似乎可以完成此任务。

It seems pretty easy. 看起来很容易。 Sort L and find the first n elements of L that add up to K . 排序L并找到第一n的元素L加起来K That's it. 而已。 Finding any elements beyond the nth element is not any better, though you might be able to trim off the first few elements. 找到nth元素之外的任何元素都不会更好,尽管您可以删除前几个元素。 If SUM(L) is less than K , then return null or throw an exception. 如果SUM(L)小于K ,则返回null或引发异常。

Finding the size of the subset is trivial, you can sort the values in reverse order and then find the first partial sum which is greater than or equal to K. This is bounded by the sorting time, which is O(n log n). 查找子集的大小是微不足道的,您可以按相反的顺序对值进行排序,然后找到大于或等于K的第一个部分和。这受排序时间的限制,即O(n log n)。

In your "greater than or equal to" variant of the subset sum problem, once you find a solution with sum S, you still need to ask "does there exist a subset of length n which has a sum between K and S?" 在子集总和问题的“大于或等于”变体中,一旦找到了总和为S的解决方案,您仍然需要问“是否存在长度为n的子集,其总和介于K和S之间?” Applying this repeatedly will eventually yield the question "does there exist a subset of length n which has a sum of K?" 反复应用这一点将最终产生一个问题“是否存在长度为n的子集,其总和为K?” You can't say that your solution is optimal without answering this question. 您不能不回答这个问题就说您的解决方案是最佳的。

The fixed-size subset sum decision problem is NP-complete (since there are only n possible lengths and if this sub-problem was not NP-complete, neither would be the subset sum decision problem). 固定大小的子集和决策问题是NP完全的(因为只有n个可能的长度,并且如果此子问题不是NP完全的,那么子集和决策问题也不是)。

Here is an algorythm: 这是一个算法:

  1. Sort L in reverse order. 以相反的顺序对L进行排序。
  2. Use recursive function to iterate over every possible combination 使用递归函数迭代所有可能的组合
  3. Stop recursion if sum is greater than or equals to K 如果sum大于或等于K,则停止递归
  4. Iterate over resulting subsets and select one with the maximum sum of elemets 遍历结果子集并选择具有最大元素总数的子集

Recursion is as follows in Java 递归在Java中如下

private List<Integer> numbers = Arrays.asList(5, 4, 3, 2, 1);
private List<List<Integer>> combinations = new ArrayList<>();

public void selectCombinations(int position, List<Integer> currentCombination) {
    if (position >= numbers.size()) {
        return;
    }
    //next number
    selectCombination(position + 1, currentCombination);

    List<Integer> newCombination = new ArrayList<>(currentCombination);
    newCombination.add(numbers.get(position));
    int sum = ...;//sum of copy
    if (sum >= K) {
        combinations.add(newCombination);
    } else {
         selectCombination(position + 1, newCombination);
    }
}

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

相关问题 精确k个整数的子集和? - Subset sum for exactly k integers? 给定一个整数数组,找到最接近 K 的子集和 - Given an array of integers, find the subset sum closest to K 如何按字典顺序生成由`k``0&#39;s`和`l``1&#39;组成的集合的所有排列? - How to generate all permutations of set consisting from `k` `0's` and `l` `1's` in lexicographical order? 给定集合S,找到其总和&lt;= k的所有最大子集 - Given a set S, find all the maximal subsets whose sum <= k 给定一组64个整数,我必须找到总和&lt;= k的所有8个整数子集 - Given a set of 64 integers, I must find all 8-integer subsets whose sum <= k 给定一个正整数数组,找到长度为 L 的连续子序列的起始索引,它们的总和等于 S - Given a positive integer array, find starting indexes of contiguous subsequences of length L that their sum equals to S 给定一组n个整数,列出所有可能的子集,其中sum&gt; = k - Given a set of n integers, list all possible subsets with sum>=k 给定一组n个整数,列出所有可能的子集,其中k1 &lt;= sum &lt;= k2,k1和k2浮点数 - Given a set of n integers, list all possible subsets with k1<= sum <=k2 , k1 and k2 floating numbers 将数字表示为子集S中K个数字之和的方式数量 - Number of ways to represent a number as a sum of K numbers in subset S 数字为 sum s 的 k 位整数数组 - Array of k-digit integers with digits of sum s
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM