Q: I am wondering why is this check enforced? In python, list append is a thread-safe operation. In other languages, it would be left to the user to make sure that the callback has the necessary mutexes and performs thread-safe operations.
An alternative way to bypass this issue is to start the search of different threads and merge the results/solutions.
Q: What is the correct way to specify a seed for the random number generator used within ortools?
As far as I can see, the solver.Phrase() and SolutionCollector() are for the old solvers. Is there an equivalent for CP-SAT as to specify only the variables that we are interested in (e.g. ignore temp bool variables used for channelling) and collection of solutions?
Bonus Q: Is there a list of all of the parameters that can be set to the model?
Thanks,
Daniel
Minimal example:
from ortools.sat.python import cp_model
class VarArraySolutionAggregator(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, variables):
cp_model.CpSolverSolutionCallback.__init__(self)
self.__variables = variables
self.__solution_count = 0
self.__solutions = []
def on_solution_callback(self):
self.__solution_count += 1
s = tuple([self.Value(v) for v in self.__variables])
self.__solutions.append(s)
print(s)
@property
def solution_count(self):
return self.__solution_count
@property
def solutions(self):
return self.__solutions
def SearchForAllSolutionsSampleSat():
"""Showcases calling the solver to search for all solutions."""
# Creates the model.
model = cp_model.CpModel()
# Creates the variables.
num_vals = 3
x = model.NewIntVar(0, num_vals - 1, 'x')
y = model.NewIntVar(0, num_vals - 1, 'y')
z = model.NewIntVar(0, num_vals - 1, 'z')
# Create the constraints.
model.Add(x != y)
# Create a solver and solve.
solver = cp_model.CpSolver()
# Works ok
solver.parameters.num_search_workers = 1
# Fails
solver.parameters.num_search_workers = 10
solver.parameters.max_time_in_seconds = 1.
solution_aggregator = VarArraySolutionAggregator([x, y, z])
status = solver.SearchForAllSolutions(model, solution_aggregator)
print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i in %0.2fs' % (solution_aggregator.solution_count, solver.WallTime()))
print(len(solution_aggregator.solutions))
SearchForAllSolutionsSampleSat()