Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all combinations of a list of numbers with a given sum

I have a list of numbers, e.g.

numbers = [1, 2, 3, 7, 7, 9, 10] 

As you can see, numbers may appear more than once in this list.

I need to get all combinations of these numbers that have a given sum, e.g. 10.

The items in the combinations may not be repeated, but each item in numbers has to be treated uniquely, that means e.g. the two 7 in the list represent different items with the same value.

The order is unimportant, so that [1, 9] and [9, 1] are the same combination.

There are no length restrictions for the combinations, [10] is as valid as [1, 2, 7].

How can I create a list of all combinations meeting the criteria above?

In this example, it would be [[1,2,7], [1,2,7], [1,9], [3,7], [3,7], [10]]

like image 739
Byte Commander Avatar asked Dec 29 '15 19:12

Byte Commander


People also ask

Can Excel find combination numbers equal given sum?

Find cells combination that equal a given sum with Solver Add-in. If you are confused with above method, Excel contains a Solver Add-in feature, by using this add-in, you can also identify the numbers which total amount equals a given value.

How do you find all the combinations that equal a sum in Python?

First, we take an empty list 'res' and start a loop and traverse each element of the given list of integers. In each iteration, pop the element, store it in 'num', find remaining difference for sum K, and check if the difference exists in the given list or not.

How do you find all the possible combinations of numbers?

Remember, the formula to calculate combinations is nCr = n! / r! * (n - r)!, where n represents the number of items, and r represents the number of items being chosen at a time. Let's look at an example of how to calculate a combination.

How do you generate all possible combinations of one list?

Add a Custom Column to and name it List1. Enter the formula =List1. Expand out the new List1 column and then Close & Load the query to a table. The table will have all the combinations of items from both lists and we saved on making a custom column in List1 and avoided using a merge query altogether!


2 Answers

You could use itertools to iterate through every combination of every possible size, and filter out everything that doesn't sum to 10:

import itertools  numbers = [1, 2, 3, 7, 7, 9, 10] target = 10  result = [seq for i in range(len(numbers), 0, -1)           for seq in itertools.combinations(numbers, i)           if sum(seq) == target]  print(result) 

Result:

[(1, 2, 7), (1, 2, 7), (1, 9), (3, 7), (3, 7), (10,)] 

Unfortunately this is something like O(2^N) complexity, so it isn't suitable for input lists larger than, say, 20 elements.

like image 91
Kevin Avatar answered Sep 18 '22 20:09

Kevin


The solution @kgoodrick offered is great but I think it is more useful as a generator:

def subset_sum(numbers, target, partial=[], partial_sum=0):     if partial_sum == target:         yield partial     if partial_sum >= target:         return     for i, n in enumerate(numbers):         remaining = numbers[i + 1:]         yield from subset_sum(remaining, target, partial + [n], partial_sum + n) 

list(subset_sum([1, 2, 3, 7, 7, 9, 10], 10)) yields [[1, 2, 7], [1, 2, 7], [1, 9], [3, 7], [3, 7], [10]].

like image 39
Martin Valgur Avatar answered Sep 19 '22 20:09

Martin Valgur