Suppose sum(xi) = 10, 0<= xi <= 2, i = 1, 2, ..., 10. How to find all integer solutions for xi. thank you. I have read about Euclidean algorithm, but it looks like just for two unknown variables. What algorithms can be used here.
-
2There are so many solutions to your example that listing them all is probably not interesting. What are you really trying to solve? – Henry Apr 22 '16 at 11:53
-
1E.g., do you want to *find* the solutions or, perhaps, just *count* them? – Gareth McCaughan Apr 22 '16 at 11:56
-
I really need to find all combinations of the solutions. I am solving an optimization problem where the objective is hard to model and the constraints are hidden so I am getting all possible combinations and bruteforcefullly find the best. – daydayup Apr 22 '16 at 12:08
-
I just edited the question to make it a less scary case... thank you – daydayup Apr 22 '16 at 12:10
3 Answers
If you really want to have all solutions: recursively enumerate all possible variable assignments with some optimizations:
- The value of the last variable can be calculated from the sum constraint
- The search can be pruned, when you see that the partial assignment can no longer lead to a valid solution (e.g if the sum is already larger than 10 or if there are too few variables left to reach a sum of 10)

- 42,982
- 7
- 68
- 84
You are looking for the permutations of the integer partitions of the number 100, where each integer partition has
- at most 10 parts; and
- each part is at most 15.
There are certainly a lot of cases, but 10! of them are still manageable by computers.
Edit: OP has edited the question, so: the number 10 should be broken up into integer partitions with at most 10 parts, where each part is at most 2.

- 1,164
- 2
- 21
- 40
Recursion is best. Here is the natural Python solution with generators:
def solutions(variables, sum_left, max_value):
if 0 == variables:
if 0 == sum_left:
yield []
else:
for i in range(0, max_value + 1):
if sum_left < i:
break
else:
for partial_solution in solutions(variables - 1, sum_left - i,
max_value):
yield [i] + partial_solution
for x in solutions(10, 10, 2):
print(x)
The benefit of generators being that you don't have to build a long list in memory first. Here is an alternate solution which does not use generators and also avoids building up the list.
def do_something_for_solutions(variables, sum_left, max_value, known=None):
if known is None:
known = []
if 0 == variables:
if 0 == sum_left:
do_something(known)
else:
for i in range(0, max_value + 1):
if sum_left < i:
break
else:
do_something_for_solutions(variables - 1, sum_left - i,
max_value, known + [i])
def do_something(solution):
print(solution)
do_something_for_solutions(10, 10, 2)
If you choose to return solutions, that is possible as follows:
def solutions(variables, sum_left, max_value):
if 0 == variables:
if 0 == sum_left:
return [[]]
else:
return []
else:
answer = []
for i in range(0, max_value + 1):
if sum_left < i:
break
else:
for partial_solution in solutions(variables - 1, sum_left - i,
max_value):
answer.append([i] + partial_solution)
return answer
for x in solutions(10, 10, 2):
print(x)
(Be warned that if you change the parameters, that list can easily become huge...)

- 43,296
- 3
- 59
- 88