I have an algorithm that finds the set of all unique sums of the combinations of k tuples drawn with replacement from of a list of tuples. Each tuple contains n positive integers, the order of these integers matters, and the sum of the tuples is defined as element-wise addition. e.g. (1, 2, 3) + (4, 5, 6) = (5, 7, 9)
Simple example for k=2 and n=3:
input = [(1,0,0), (2,1,1), (3,3,2)]
solution = [(1,0,0)+(2,1,1), (1,0,0)+(3,3,2), (2,1,1)+(3,3,2), (1,0,0)+(1,0,0), (2,1,1)+(2,1,1), (3,3,2)+(3,3,2)]
solution = [(3,1,1), (4,3,2), (5,4,3), (2,0,0), (4,2,2), (6,6,4)]
In practice the integers in the tuples range from 0 to 50 (in some positions it may be a lot more constraint, like [0:2]), k goes up to 4 combinations, and the length of the tuples goes up to 5. The number of tuples to draw from goes up to a thousand.
The algorithm I currently have is an adaptation of an algorithm proposed in a related question, it's more efficient then enumerating all combinations with itertools (if we're drawing 4 tuples out of 1000, there are billions of combinations, but the number of sums will be orders of magnitude less), but I don't see how to apply bitsets for example to this problem.
# example where length of tuples n = 3:
lst = []
for x in range(0,50,2):
for y in range(0, 20, 1):
for z in range(0, 3, 1):
lst.append((x,y,z))
# this function works for any k and n
def unique_combination_sums(lst, k):
n = len(lst[0])
sums = {tuple(0 for _ in range(n))} # initialize with tuple of zeros
for _ in range(k):
sums = {tuple(s[i]+x[i] for i in range(n)) for s in sums for x in lst}
return sums
unique_combination_sums(lst, 4)
solution
last sum is(6,6,4)
not(6,6,2)
. – Baresark