table of Contents
Note: Chinese non-direct translation in English, but after the Processing notes, only to learn English record their professional presentation.
Outline
Constraint optimization, or constraint programming (CP), constrained optimization (planning), used to find feasible solutions in a very large set of candidates, in which the problem can be modeled with any constraint.
CP feasibility (to find a feasible solution) rather than optimization (find the optimal solution) based, it is more concerned about the constraints and variables, rather than the objective function.
SP-SAT Solver
CP-SAT solver is technically superior to the conventional CP solvers.
The CP-SAT solver is technologically superior to the original CP solver and should be preferred in almost all situations.
To increase the operation speed, CP solver processing are integers.
If you have non-integer key constraint, it can take a first integer, so that it becomes integral term.
If you begin with a problem that has constraints with non-integer terms, you need to first multiply those constraints by a sufficiently large integer so that all terms are integers
Look at a simple example: find a feasible solution.
- Variables x, y, z, each value of 0,1 only.
- eg:
x = model.NewIntVar(0, num_vals - 1, 'x')
- eg:
- Constraints: x ≠ y
- eg:
model.Add(x != y)
- eg:
The core steps:
- Statement Model
- Creating Variables
- Creating Constraints
- Call solver
- The results show
from ortools.sat.python import cp_model
def SimpleSatProgram():
"""Minimal CP-SAT example to showcase calling the solver."""
# 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')
# Creates the constraints.
model.Add(x != y)
# Creates a solver and solves the model.
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.FEASIBLE:
print('x = %i' % solver.Value(x))
print('y = %i' % solver.Value(y))
print('z = %i' % solver.Value(z))
SimpleSatProgram()
Run
x = 1
y = 0
z = 0
status = solver.Solve(model)
Return value status Meaning:
- OPTIMAL find the optimal solution.
- FEASIBLE to find a feasible solution, but not necessarily the optimal solution.
- No feasible solution INFEASIBLE.
- MODEL_INVALID given CpModelProto not verified step. By calling
ValidateCpModel(model_proto)
for more mistakes. - UNKNOWN due to reaching a limit search, state model is unknown.
Plus the objective function to find the optimal solution
Assuming that the target seeking function is x + 2y + 3z
maximum, added before Solver
model.Maximize(x + 2 * y + 3 * z)
And replace the display conditions
if status == cp_model.OPTIMAL:
Run
x = 1
y = 2
z = 2
Plus a callback function, to show all feasible solutions
Remove the objective function, plus print callback function
from ortools.sat.python import cp_model
class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, variables):
cp_model.CpSolverSolutionCallback.__init__(self)
self.__variables = variables
self.__solution_count = 0
def on_solution_callback(self):
self.__solution_count += 1
for v in self.__variables:
print('%s=%i' % (v, self.Value(v)), end=' ')
print()
def solution_count(self):
return self.__solution_count
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()
solution_printer = VarArraySolutionPrinter([x, y, z])
status = solver.SearchForAllSolutions(model, solution_printer)
print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i' % solution_printer.solution_count())
SearchForAllSolutionsSampleSat()
Run
x=0 y=1 z=0
x=1 y=2 z=0
x=1 y=2 z=1
x=1 y=2 z=2
x=1 y=0 z=2
x=1 y=0 z=1
x=2 y=0 z=1
x=2 y=1 z=1
x=2 y=1 z=2
x=2 y=0 z=2
x=0 y=1 z=2
x=0 y=1 z=1
x=0 y=2 z=1
x=0 y=2 z=2
x=1 y=0 z=0
x=2 y=0 z=0
x=2 y=1 z=0
x=0 y=2 z=0
Status = OPTIMAL
Number of solutions found: 18
Show intermediate solutions
And to show the similarities and differences of all feasible solutions, mainly in:
- plus
model.Maximize(x + 2 * y + 3 * z)
- change
status = solver.SolveWithSolutionCallback(model, solution_printer)
The output is:
x=0 y=1 z=0
x=0 y=2 z=0
x=0 y=2 z=1
x=0 y=2 z=2
x=1 y=2 z=2
Status = OPTIMAL
Number of solutions found: 5
Net result is inconsistent with the official. https://developers.google.cn/optimization/cp/cp_solver?hl=es-419#run_intermediate_sol