简体   繁体   English

生成数字列表的所有组合,其中组合的总和<= N.

[英]Generating all combinations of list of numbers where the sum of the combination is <= N

I have ArrayList<int> that contains all numbers that can be used in the combinations. 我有ArrayList<int> ,其中包含可以在组合中使用的所有数字。 I want to generate all possible combinations of these numbers of different length (number of integers), but all must have sum closest to N, but <= N (N is a input number). 我想生成这些不同长度(整数个数)的所有可能组合,但所有都必须具有最接近N的和,但是<= N(N是输入数)。 All numbers of the list have to be used (and only) once. 列表的所有数字都必须使用(并且仅)一次。

EXAMPLE

N = 10
list = {1, 5, 4, 3, 6, 9, 7, 4, 3, 8, 2, 1, 6, 3, 7}

One combination will be (1, 5, 4), (3, 6), (9), (7), (4, 3), (8, 2), (1, 6, 3), (7) 一种组合将是(1,5,4),(3,6),(9),(7),(4,3),(8,2),(1,6,3),(7)

Can anyone help me with the solution? 任何人都可以帮我解决这个问题吗? I'm thinking of some recursive implementation. 我正在考虑一些递归实现。 Am I on the right track? 我是在正确的轨道上吗?

EDIT 编辑

OK, because I can't explain this problem exactly as I want :) let's make it simpler. 好的,因为我无法完全按照我的要求解释这个问题:)让它变得更简单。 How to generate all sub-lists that have sum <= N, and can contain each number of the list only once. 如何生成总和<= N的所有子列表,并且只能包含列表的每个数字一次。 I'll do the rest of the work myself. 我会自己完成剩下的工作。

A simple k-combination of a finite set S is a subset of k distinct elements of S. Specifying a subset does not arrange them in a particular order. 有限集S的简单k-组合是S的k个不同元素的子集。指定子集不以特定顺序排列它们。

You can use the CombinatoricsLib. 您可以使用CombinatoricsLib。 CombinatoricsLib is a java library for generating combinatorial objects. CombinatoricsLib是一个用于生成组合对象的java库。 https://code.google.com/p/combinatoricslib/ https://code.google.com/p/combinatoricslib/

Using this: 使用这个:

    public static void main(String[] args) {

           // Create the initial vector
           ICombinatoricsVector<Integer> initialVector = Factory.createVector(
              new Integer[]  {1, 5, 4, 3, 6, 9, 7, 4, 3, 8, 2, 1, 6, 3, 7} );          

           int subsetMaxSize = 5;
           int upperLimit = 10;  
           int lowerLimit = 8;
           for(int i = 1; i <= subsetMaxSize; i++)
           {
               Generator<Integer> gen = Factory.createSimpleCombinationGenerator(initialVector, i);
               for (ICombinatoricsVector<Integer> combination : gen)
               {
                   int sum = vectorSum(combination);
                   if(validateSum(sum, lowerLimit, upperLimit))
                       printVector(combination);
               }   
           }
    }

    public static boolean validateSum(Integer value, Integer lowerLimit, Integer upperLimit)
    {
        if(value <= upperLimit && value > lowerLimit)   
            return true;
        return false;           
    }

    public static Integer vectorSum(ICombinatoricsVector<Integer> vect)
    {
        Integer sum = 0;    
        for(int i = 0; i < vect.getSize(); i++) 
            sum += vect.getValue(i);
        return sum;
    }

    public static void printVector(ICombinatoricsVector<Integer> vect)
    {
        String output = ""; 
        for(int i = 0; i < vect.getSize(); i++)
            output += vect.getValue(i) + ", ";
        System.out.println(output);
    }

will return the output 将返回输出

9, 
1, 9, 
1, 8, 
5, 4, 
5, 4, 
4, 6, 
4, 6, 
3, 6, 
3, 7, 
3, 6, 
3, 7, 
6, 4, 
6, 3, 
6, 3, 
9, 1, 
7, 3, 
7, 2, 
7, 3, 
4, 6, 
3, 6, 
3, 7, 
8, 2, 
8, 1, 
2, 7, 
6, 3, 
3, 7, 
1, 5, 4, 
1, 5, 3, 
1, 5, 4, 
1, 5, 3, 
1, 5, 3, 
1, 4, 4, 
1, 3, 6, 
1, 3, 6, 
1, 6, 3, 
1, 6, 2, 
1, 6, 3, 
1, 7, 2, 
1, 7, 1, 
1, 3, 6, 
1, 8, 1, 
1, 2, 6, 
1, 2, 7, 
1, 1, 7, 
1, 6, 3, 
5, 4, 1, 
5, 3, 2, 
5, 3, 1, 
5, 4, 1, 
5, 3, 2, 
5, 3, 1, 
5, 2, 3, 
5, 1, 3, 
4, 3, 3, 
4, 3, 2, 
4, 3, 3, 
4, 4, 2, 
4, 4, 1, 
4, 3, 2, 
4, 3, 3, 
4, 2, 3, 
3, 6, 1, 
3, 4, 3, 
3, 4, 2, 
3, 4, 3, 
3, 3, 3, 
3, 1, 6, 
6, 3, 1, 
6, 2, 1, 
6, 1, 3, 
7, 2, 1, 
4, 3, 2, 
4, 3, 3, 
4, 2, 3, 
3, 1, 6, 
2, 1, 6, 
2, 1, 7, 
1, 6, 3, 
1, 5, 3, 1, 
1, 5, 3, 1, 
1, 5, 2, 1, 
1, 5, 1, 3, 
1, 4, 3, 2, 
1, 4, 3, 1, 
1, 4, 4, 1, 
1, 4, 3, 2, 
1, 4, 3, 1, 
1, 4, 2, 3, 
1, 4, 1, 3, 
1, 3, 4, 2, 
1, 3, 4, 1, 
1, 3, 3, 2, 
1, 3, 3, 3, 
1, 3, 2, 3, 
1, 6, 2, 1, 
1, 4, 3, 2, 
1, 4, 3, 1, 
1, 4, 2, 3, 
1, 4, 1, 3, 
1, 3, 2, 3, 
1, 2, 1, 6, 
4, 3, 2, 1, 
4, 3, 2, 1, 
4, 2, 1, 3, 
3, 4, 2, 1, 
3, 3, 2, 1, 
3, 3, 1, 3, 
3, 2, 1, 3, 
4, 3, 2, 1, 
4, 2, 1, 3, 
3, 2, 1, 3, 
1, 3, 3, 2, 1, 
1, 3, 2, 1, 3, 
1, 3, 2, 1, 3, 

You can use recursion, however if you will tell what is your original problem and the constraints, then there could be a better solution. 您可以使用递归,但是如果您将告诉您原始问题和约束是什么,那么可以有更好的解决方案。 For recursion it will be something like this: 对于递归,它将是这样的:

list = {1, 5, 4, 3, 6, 9, 7, 4, 3, 8, 2, 1, 6, 3, 7};
result = {};

function rec(index, max_sum) {
    if(index >= list.length) {
        print result;
        return;
    }
    for each list[i] where i >= index {
        // Case 1 - we take current element and go further
        if(list[i] <= max_sum) {
            result.insert(list[i]);
            rec(index + 1, max_sum - list[i]);
            result.remove(list[i]);
        }

        // Case 2 - we skip current element
        rec(index + 1, max_sum);
    }
}

N = 10;
rec(0, N);

This will just generate all possible combinations of numbers sum of which doesn't exceed N. 这将生成所有可能的数字总和不超过N的组合。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM