Reputation: 2988
I want to use ortools to generate all the possible combinations of a simple problem as in the following program. In this case I want x and y to be multiplications of 5 and additionally if start is 7, then the values of the x should be 7, 10, 15, 20, 25 and so on. How can I change following code for this?
model = cp_model.CpModel()
start = 7
end = 20
x = model.NewIntVar(start , end - 1, "x")
y = model.NewIntVar(start , end - 1, "y")
# Create the constraints.
model.Add(x != y)
Upvotes: 0
Views: 3041
Reputation: 11014
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from ortools.sat.python import cp_model
class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, variables):
self.__variables = variables
self.__solution_count = 0
def NewSolution(self):
self.__solution_count += 1
for v in self.__variables:
print('%s=%i' % (v, self.Value(v)), end=' ')
print()
def SolutionCount(self):
return self.__solution_count
def mod_or_start():
model = cp_model.CpModel()
start = 7
end = 20
x = model.NewIntVar(start, end - 1, 'x') # 8..19
y = model.NewIntVar(start, end - 1, 'y') # 8..19
x_is_start = model.NewBoolVar('x_is_start')
y_is_start = model.NewBoolVar('y_is_start')
x_is_modulo_5 = model.NewBoolVar('x_is_modulo_5')
y_is_modulo_5 = model.NewBoolVar('y_is_modulo_5')
model.Add(x == start).OnlyEnforceIf(x_is_start)
model.Add(y == start).OnlyEnforceIf(y_is_start)
# Buggy.
# model.AddModuloEquality(0, x, 5).OnlyEnforceIf(x_is_modulo_5)
# model.AddModuloEquality(0, y, 5).OnlyEnforceIf(y_is_modulo_5)
# Workaround until the modulo code is fixed.
sub_x = model.NewIntVar(start // 5, end // 5, 'sub_x')
sub_y = model.NewIntVar(start // 5, end // 5, 'sub_y')
model.Add(x == 5 * sub_x).OnlyEnforceIf(x_is_modulo_5)
model.Add(y == 5 * sub_y).OnlyEnforceIf(y_is_modulo_5)
# Remove duplicate solutions
model.Add(sub_x == start // 5).OnlyEnforceIf(x_is_modulo_5.Not())
model.Add(sub_y == start // 5).OnlyEnforceIf(y_is_modulo_5.Not())
# At least one option is true.
model.AddBoolOr([x_is_start, x_is_modulo_5])
model.AddBoolOr([y_is_start, y_is_modulo_5])
# Create a solver and solve.
solver = cp_model.CpSolver()
solution_printer = VarArraySolutionPrinter([x, y])
status = solver.SearchForAllSolutions(model, solution_printer)
print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i' % solution_printer.SolutionCount())
mod_or_start()
Outputs:
x=15 y=15
x=15 y=7
x=10 y=7
x=7 y=7
x=7 y=15
x=7 y=10
x=10 y=15
x=10 y=10
x=15 y=10
Status = FEASIBLE
Number of solutions found: 9
Upvotes: 3