# CP-SAT Solver

OR-Tools provides two solvers for constraint programming:

The CP-SAT solver is technologically superior to the original CP solver and should be preferred in almost all situations. The exceptions are small problems for which solutions can be found quickly using either solver. In those cases you may find that the original CP solver outperforms CP-SAT.

## Example: finding a feasible solution

The following sections present several examples that illustrate how to use the CP-SAT solver. Let's start with a simple example problem in which there are:

• Three variables, x, y, and z, each of which can take on the values: 0, 1, or 2.
• One constraint: x ≠ y

We'll start by showing how to use the CP-SAT solver to find a single feasible solution in all four of the supported languages (Python, C++, Java, and C#). While finding a feasible solution is trivial in this case, in more complex constraint programming problems it can be very difficult to determine whether there is a feasible solution.

### Declare the model

The following code declares the CP-SAT model.

### Python

`    model = cp_model.CpModel()`

### C++

`  CpModelBuilder cp_model;`

### Java

`    CpModel model = new CpModel();`

### C#

`    CpModel model = new CpModel();`

### Create the variables

The following code creates the variables for the problem.

### Python

```    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')```

### C++

```  const Domain domain(0, 2);
const IntVar x = cp_model.NewIntVar(domain).WithName("x");
const IntVar y = cp_model.NewIntVar(domain).WithName("y");
const IntVar z = cp_model.NewIntVar(domain).WithName("z");```

### Java

```    int numVals = 3;

IntVar x = model.newIntVar(0, numVals - 1, "x");
IntVar y = model.newIntVar(0, numVals - 1, "y");
IntVar z = model.newIntVar(0, numVals - 1, "z");```

### C#

```    int num_vals = 3;

IntVar x = model.NewIntVar(0, num_vals - 1, "x");
IntVar y = model.NewIntVar(0, num_vals - 1, "y");
IntVar z = model.NewIntVar(0, num_vals - 1, "z");```

The solver creates three variables, x, y, and z, each of which can take on the values 0, 1, or 2.

### Create the constraint

The following code creates the constraint xy.

### Python

`    model.Add(x != y)`

### C++

`  cp_model.AddNotEqual(x, y);`

### Java

`    model.addDifferent(x, y);`

### C#

`    model.Add(x != y);`

### Call the solver

The following code calls the solver.

### Python

```    solver = cp_model.CpSolver()
status = solver.Solve(model)```

### C++

```  const CpSolverResponse response = Solve(cp_model.Build());
LOG(INFO) << CpSolverResponseStats(response);```

### Java

```    CpSolver solver = new CpSolver();
CpSolverStatus status = solver.solve(model);```

### C#

```    CpSolver solver = new CpSolver();
CpSolverStatus status = solver.Solve(model);```

The CP-SAT solver returns one of the status values shown in the table below. In this example, the value returned is `OPTIMAL`

Status Description
`OPTIMAL` An optimal feasible solution was found.
`FEASIBLE` A feasible solution was found, but we don't know if it's optimal.
`INFEASIBLE` The problem was proven infeasible.
`MODEL_INVALID` The given CpModelProto didn't pass the validation step. You can get a detailed error by calling `ValidateCpModel(model_proto)`.
`UNKNOWN` The status of the model is unknown because a search limit was reached.

### Display the first solution

The following code displays the first feasible solution found by the solver. Note that the code checks whether the value of the `status` is `FEASIBLE`.

### Python

```if status == cp_model.FEASIBLE:
print('x = %i' % solver.Value(x))
print('y = %i' % solver.Value(y))
print('z = %i' % solver.Value(z))```

### C++

```if (response.status() == CpSolverStatus::FEASIBLE) {
// Get the value of x in the solution.
LOG(INFO) << "x = " << SolutionIntegerValue(response, x);
LOG(INFO) << "y = " << SolutionIntegerValue(response, y);
LOG(INFO) << "z = " << SolutionIntegerValue(response, z);
}```

### Java

```if (status == CpSolverStatus.FEASIBLE) {
System.out.println("x = " + solver.value(x));
System.out.println("y = " + solver.value(y));
System.out.println("z = " + solver.value(z));
}```

### C#

```if (status == CpSolverStatus.Feasible)
{
Console.WriteLine("x = " + solver.Value(x));
Console.WriteLine("y = " + solver.Value(y));
Console.WriteLine("z = " + solver.Value(z));
}```

### Run the program

The complete programs are shown the next section. When you run a program, it returns the first solution found by the solver:

```x = 1
y = 0
z = 0```

### Complete programs

The complete programs are shown below.

### Python

```from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

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.

# 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()```

### C++

```#include "ortools/sat/cp_model.h"

namespace operations_research {
namespace sat {

void SimpleSatProgram() {
CpModelBuilder cp_model;

const Domain domain(0, 2);
const IntVar x = cp_model.NewIntVar(domain).WithName("x");
const IntVar y = cp_model.NewIntVar(domain).WithName("y");
const IntVar z = cp_model.NewIntVar(domain).WithName("z");

// Solving part.
const CpSolverResponse response = Solve(cp_model.Build());
LOG(INFO) << CpSolverResponseStats(response);

if (response.status() == CpSolverStatus::FEASIBLE) {
// Get the value of x in the solution.
LOG(INFO) << "x = " << SolutionIntegerValue(response, x);
LOG(INFO) << "y = " << SolutionIntegerValue(response, y);
LOG(INFO) << "z = " << SolutionIntegerValue(response, z);
}
}

}  // namespace sat
}  // namespace operations_research

int main() {
operations_research::sat::SimpleSatProgram();

return EXIT_SUCCESS;
}```

### Java

```import com.google.ortools.sat.CpModel;

/** Minimal CP-SAT example to showcase calling the solver. */
public class SimpleSatProgram {
static {
}

public static void main(String[] args) throws Exception {
// Create the model.
CpModel model = new CpModel();

// Create the variables.
int numVals = 3;

IntVar x = model.newIntVar(0, numVals - 1, "x");
IntVar y = model.newIntVar(0, numVals - 1, "y");
IntVar z = model.newIntVar(0, numVals - 1, "z");

// Create the constraints.

// Create a solver and solve the model.
CpSolver solver = new CpSolver();
CpSolverStatus status = solver.solve(model);

if (status == CpSolverStatus.FEASIBLE) {
System.out.println("x = " + solver.value(x));
System.out.println("y = " + solver.value(y));
System.out.println("z = " + solver.value(z));
}
}
}```

### C#

```using System;

public class SimpleSatProgram
{
static void Main()
{
// Creates the model.
CpModel model = new CpModel();

// Creates the variables.
int num_vals = 3;

IntVar x = model.NewIntVar(0, num_vals - 1, "x");
IntVar y = model.NewIntVar(0, num_vals - 1, "y");
IntVar z = model.NewIntVar(0, num_vals - 1, "z");

// Creates the constraints.

// Creates a solver and solves the model.
CpSolver solver = new CpSolver();
CpSolverStatus status = solver.Solve(model);

if (status == CpSolverStatus.Feasible)
{
Console.WriteLine("x = " + solver.Value(x));
Console.WriteLine("y = " + solver.Value(y));
Console.WriteLine("z = " + solver.Value(z));
}
}
}```

## Finding an optimal solution

Next, we'll show how to find an optimal solution to the problem in the previous section, with the additional objective: maximize x + 2y + 3z.

To create the objective function, add the following line of code after the constraint in the previous example.

### Python

`  model.Maximize(x + 2 * y + 3 * z)`

### C++

`  maximize({x, y, z}, {1, 2, 3});`

### Java

`  model.maximizeScalProd(new IntVar[] {x, y, z}, new int[] {1, 2, 3});`

### C#

`  model.Maximize(x + 2 * y + 3 * z);`

Next, modify the code that displays solutions as shown below.

### Python

```  if status == cp_model.OPTIMAL:
print('x = %i' % solver.Value(x))
print('y = %i' % solver.Value(y))
print('z = %i' % solver.Value(z))```

### C++

```  if (response.status() == CpSolverStatus::OPTIMAL) {
// Get the values of x, y, and z in the solution.
const int64 value_x = response.solution(x);
const int64 value_y = response.solution(y);
const int64 value_z = response.solution(z)

LOG(INFO) << "x = " << value_x;
LOG(INFO) << "y = " << value_y;
LOG(INFO) << "z = " << value_z;
}```

### Java

```  if (status == CpSolverStatus.OPTIMAL) {
System.out.println("x = " + solver.value(x));
System.out.println("y = " + solver.value(y));
System.out.println("z = " + solver.value(z));
}```

### C#

```  if (status == CpSolverStatus.Optimal)
{
Console.WriteLine("x = " + solver.Value(x));
Console.WriteLine("y = " + solver.Value(y));
Console.WriteLine("z = " + solver.Value(z));
}```

Note that the code now prints a solution that is `OPTIMAL`, instead of `FEASIBLE`, as in the previous example.

### Run the program

When you make the changes above and run the program, it returns the following solution, which maximizes the objective function.

```x = 1
y = 2
z = 2```

## Display all solutions

Next, we'll show how to modify the program above, which displays the first feasible solution, so that it displays all feasible solutions.

Note: there is no objective function in this example.

The main addition to the program is a solution printer—a callback that you pass to the solver, which displays each solution as it is found.

The following code creates the solution printer.

### Python

```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```

### C++

```  Model model;

int num_solutions = 0;
LOG(INFO) << "Solution " << num_solutions;
LOG(INFO) << "  x = " << SolutionIntegerValue(r, x);
LOG(INFO) << "  y = " << SolutionIntegerValue(r, y);
LOG(INFO) << "  z = " << SolutionIntegerValue(r, z);
num_solutions++;
}));```

### Java

```  static class VarArraySolutionPrinter extends CpSolverSolutionCallback {
public VarArraySolutionPrinter(IntVar[] variables) {
variableArray = variables;
}

@Override
public void onSolutionCallback() {
System.out.printf("Solution #%d: time = %.02f s%n", solutionCount, wallTime());
for (IntVar v : variableArray) {
System.out.printf("  %s = %d%n", v.getName(), value(v));
}
solutionCount++;
}

public int getSolutionCount() {
return solutionCount;
}

private int solutionCount;
private final IntVar[] variableArray;
}```

### C#

```public class VarArraySolutionPrinter : CpSolverSolutionCallback
{
public VarArraySolutionPrinter(IntVar[] variables)
{
variables_ = variables;
}

public override void OnSolutionCallback()
{
{
Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s",
solution_count_, WallTime()));
foreach (IntVar v in variables_)
{
Console.WriteLine(
String.Format("  {0} = {1}", v.ShortString(), Value(v)));
}
solution_count_++;
}
}

public int SolutionCount()
{
return solution_count_;
}

private int solution_count_;
private IntVar[] variables_;
}```

### Call the solver

The following code calls the solver, and passes the solution printer to it.

### Python

```    solver = cp_model.CpSolver()
solution_printer = VarArraySolutionPrinter([x, y, z])
status = solver.SearchForAllSolutions(model, solution_printer)```

### C++

```  SatParameters parameters;
parameters.set_enumerate_all_solutions(true);
const CpSolverResponse response = SolveCpModel(cp_model.Build(), &model);```

### Java

```    CpSolver solver = new CpSolver();
VarArraySolutionPrinter cb = new VarArraySolutionPrinter(new IntVar[] {x, y, z});
solver.searchAllSolutions(model, cb);```

### C#

```    CpSolver solver = new CpSolver();
VarArraySolutionPrinter cb =
new VarArraySolutionPrinter(new IntVar[] { x, y, z });
solver.SearchAllSolutions(model, cb);```

### Run the program

The complete program is shown in the next section. When you run the program, it displays all 18 feasible solutions:

```x=1 y=0 z=0
x=2 y=0 z=0
x=2 y=1 z=0
x=2 y=1 z=1
x=2 y=1 z=2
x=2 y=0 z=2
x=2 y=0 z=1
x=1 y=0 z=1
x=0 y=1 z=1
x=0 y=1 z=2
x=0 y=2 z=2
x=1 y=2 z=2
x=1 y=2 z=1
x=1 y=2 z=0
x=0 y=2 z=0
x=0 y=1 z=0
x=0 y=2 z=1
x=1 y=0 z=2
Status = FEASIBLE```

### Complete programs

The complete programs are shown below.

### Python

```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):
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.

# 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()```

### C++

```#include "ortools/sat/cp_model.h"
#include "ortools/sat/model.h"
#include "ortools/sat/sat_parameters.pb.h"

namespace operations_research {
namespace sat {

void SearchAllSolutionsSampleSat() {
CpModelBuilder cp_model;

const Domain domain(0, 2);
const IntVar x = cp_model.NewIntVar(domain).WithName("x");
const IntVar y = cp_model.NewIntVar(domain).WithName("y");
const IntVar z = cp_model.NewIntVar(domain).WithName("z");

Model model;

int num_solutions = 0;
LOG(INFO) << "Solution " << num_solutions;
LOG(INFO) << "  x = " << SolutionIntegerValue(r, x);
LOG(INFO) << "  y = " << SolutionIntegerValue(r, y);
LOG(INFO) << "  z = " << SolutionIntegerValue(r, z);
num_solutions++;
}));

// Tell the solver to enumerate all solutions.
SatParameters parameters;
parameters.set_enumerate_all_solutions(true);
const CpSolverResponse response = SolveCpModel(cp_model.Build(), &model);

LOG(INFO) << "Number of solutions found: " << num_solutions;
}

}  // namespace sat
}  // namespace operations_research

int main() {
operations_research::sat::SearchAllSolutionsSampleSat();

return EXIT_SUCCESS;
}```

### Java

```import com.google.ortools.sat.CpModel;

/** Code sample that solves a model and displays all solutions. */
public class SearchForAllSolutionsSampleSat {
static {
}

static class VarArraySolutionPrinter extends CpSolverSolutionCallback {
public VarArraySolutionPrinter(IntVar[] variables) {
variableArray = variables;
}

@Override
public void onSolutionCallback() {
System.out.printf("Solution #%d: time = %.02f s%n", solutionCount, wallTime());
for (IntVar v : variableArray) {
System.out.printf("  %s = %d%n", v.getName(), value(v));
}
solutionCount++;
}

public int getSolutionCount() {
return solutionCount;
}

private int solutionCount;
private final IntVar[] variableArray;
}

public static void main(String[] args) throws Exception {
// Create the model.
CpModel model = new CpModel();

// Create the variables.
int numVals = 3;

IntVar x = model.newIntVar(0, numVals - 1, "x");
IntVar y = model.newIntVar(0, numVals - 1, "y");
IntVar z = model.newIntVar(0, numVals - 1, "z");

// Create the constraints.

// Create a solver and solve the model.
CpSolver solver = new CpSolver();
VarArraySolutionPrinter cb = new VarArraySolutionPrinter(new IntVar[] {x, y, z});
solver.searchAllSolutions(model, cb);

System.out.println(cb.getSolutionCount() + " solutions found.");
}
}```

### C#

```using System;

public class VarArraySolutionPrinter : CpSolverSolutionCallback
{
public VarArraySolutionPrinter(IntVar[] variables)
{
variables_ = variables;
}

public override void OnSolutionCallback()
{
{
Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s",
solution_count_, WallTime()));
foreach (IntVar v in variables_)
{
Console.WriteLine(
String.Format("  {0} = {1}", v.ShortString(), Value(v)));
}
solution_count_++;
}
}

public int SolutionCount()
{
return solution_count_;
}

private int solution_count_;
private IntVar[] variables_;
}

public class SearchForAllSolutionsSampleSat
{
static void Main()
{
// Creates the model.
CpModel model = new CpModel();

// Creates the variables.
int num_vals = 3;

IntVar x = model.NewIntVar(0, num_vals - 1, "x");
IntVar y = model.NewIntVar(0, num_vals - 1, "y");
IntVar z = model.NewIntVar(0, num_vals - 1, "z");

// Creates a solver and solves the model.
CpSolver solver = new CpSolver();
VarArraySolutionPrinter cb =
new VarArraySolutionPrinter(new IntVar[] { x, y, z });
solver.SearchAllSolutions(model, cb);

Console.WriteLine(String.Format("Number of solutions found: {0}",
cb.SolutionCount()));
}
}```

## Display intermediate solutions

This section shows how to display all the intermediate solutions found by the solver while it searches for an optimal solution.

As in the section Finding an optimal solution, we create an objective function by adding the following line of code, after the constraint.

### Python

`    model.Maximize(x + 2 * y + 3 * z)`

### C++

`  cp_model.Maximize(LinearExpr::ScalProd({x, y, z}, {1, 2, 3}));`

### Java

`    model.maximize(LinearExpr.scalProd(new IntVar[] {x, y, z}, new int[] {1, 2, 3}));`

### C#

`    model.Maximize(x + 2 * y + 3 * z);`

The following code creates the solution printer, which is similar to the one in the preceding section, but also prints the value of the objective function.

### Python

```class VarArrayAndObjectiveSolutionPrinter(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):
print('Solution %i' % self.__solution_count)
print('  objective value = %i' % self.ObjectiveValue())
for v in self.__variables:
print('  %s = %i' % (v, self.Value(v)), end=' ')
print()
self.__solution_count += 1

def solution_count(self):
return self.__solution_count```

### C++

```  Model model;
int num_solutions = 0;
LOG(INFO) << "Solution " << num_solutions;
LOG(INFO) << "  objective value = " << r.objective_value();
LOG(INFO) << "  x = " << SolutionIntegerValue(r, x);
LOG(INFO) << "  y = " << SolutionIntegerValue(r, y);
LOG(INFO) << "  z = " << SolutionIntegerValue(r, z);
num_solutions++;
}));```

### Java

```  static class VarArraySolutionPrinterWithObjective extends CpSolverSolutionCallback {
public VarArraySolutionPrinterWithObjective(IntVar[] variables) {
variableArray = variables;
}

@Override
public void onSolutionCallback() {
System.out.printf("Solution #%d: time = %.02f s%n", solutionCount, wallTime());
System.out.printf("  objective value = %f%n", objectiveValue());
for (IntVar v : variableArray) {
System.out.printf("  %s = %d%n", v.getName(), value(v));
}
solutionCount++;
}

public int getSolutionCount() {
return solutionCount;
}

private int solutionCount;
private final IntVar[] variableArray;
}```

### C#

```public class VarArraySolutionPrinterWithObjective : CpSolverSolutionCallback
{
public VarArraySolutionPrinterWithObjective(IntVar[] variables)
{
variables_ = variables;
}

public override void OnSolutionCallback()
{
Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s",
solution_count_, WallTime()));
Console.WriteLine(
String.Format("  objective value = {0}", ObjectiveValue()));
foreach (IntVar v in variables_)
{
Console.WriteLine(
String.Format("  {0} = {1}", v.ShortString(), Value(v)));
}
solution_count_++;
}

public int SolutionCount()
{
return solution_count_;
}

private int solution_count_;
private IntVar[] variables_;
}```

### Run the program

The complete programs are shown in the next section. When you run a program, it displays the following output.

```Solution 0
objective value = 1
x = 1   y = 0   z = 0
Solution 1
objective value = 2
x = 2   y = 0   z = 0
Solution 2
objective value = 4
x = 2   y = 1   z = 0
Solution 3
objective value = 5
x = 1   y = 2   z = 0
Solution 4
objective value = 8
x = 0   y = 1   z = 2
Solution 5
objective value = 10
x = 0   y = 2   z = 2
Solution 6
objective value = 11
x = 1   y = 2   z = 2
Status = OPTIMAL
Number of solutions found: 7```

### Complete programs

The complete programs are shown below.

### Python

```from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from ortools.sat.python import cp_model

# You need to subclass the cp_model.CpSolverSolutionCallback class.
class VarArrayAndObjectiveSolutionPrinter(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):
print('Solution %i' % self.__solution_count)
print('  objective value = %i' % self.ObjectiveValue())
for v in self.__variables:
print('  %s = %i' % (v, self.Value(v)), end=' ')
print()
self.__solution_count += 1

def solution_count(self):
return self.__solution_count

def SolveAndPrintIntermediateSolutionsSampleSat():
"""Showcases printing intermediate solutions found during search."""
# 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.Maximize(x + 2 * y + 3 * z)

# Creates a solver and solves.
solver = cp_model.CpSolver()
solution_printer = VarArrayAndObjectiveSolutionPrinter([x, y, z])
status = solver.SolveWithSolutionCallback(model, solution_printer)

print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i' % solution_printer.solution_count())

SolveAndPrintIntermediateSolutionsSampleSat()```

### C++

```#include "ortools/sat/cp_model.h"
#include "ortools/sat/model.h"

namespace operations_research {
namespace sat {

void SolveAndPrintIntermediateSolutionsSampleSat() {
CpModelBuilder cp_model;

const Domain domain(0, 2);
const IntVar x = cp_model.NewIntVar(domain).WithName("x");
const IntVar y = cp_model.NewIntVar(domain).WithName("y");
const IntVar z = cp_model.NewIntVar(domain).WithName("z");

cp_model.Maximize(LinearExpr::ScalProd({x, y, z}, {1, 2, 3}));

Model model;
int num_solutions = 0;
LOG(INFO) << "Solution " << num_solutions;
LOG(INFO) << "  objective value = " << r.objective_value();
LOG(INFO) << "  x = " << SolutionIntegerValue(r, x);
LOG(INFO) << "  y = " << SolutionIntegerValue(r, y);
LOG(INFO) << "  z = " << SolutionIntegerValue(r, z);
num_solutions++;
}));

const CpSolverResponse response = SolveCpModel(cp_model.Build(), &model);

LOG(INFO) << "Number of solutions found: " << num_solutions;
}

}  // namespace sat
}  // namespace operations_research

int main() {
operations_research::sat::SolveAndPrintIntermediateSolutionsSampleSat();

return EXIT_SUCCESS;
}```

### Java

```import com.google.ortools.sat.CpModel;

/** Solves an optimization problem and displays all intermediate solutions. */
public class SolveAndPrintIntermediateSolutionsSampleSat {
static {
}

static class VarArraySolutionPrinterWithObjective extends CpSolverSolutionCallback {
public VarArraySolutionPrinterWithObjective(IntVar[] variables) {
variableArray = variables;
}

@Override
public void onSolutionCallback() {
System.out.printf("Solution #%d: time = %.02f s%n", solutionCount, wallTime());
System.out.printf("  objective value = %f%n", objectiveValue());
for (IntVar v : variableArray) {
System.out.printf("  %s = %d%n", v.getName(), value(v));
}
solutionCount++;
}

public int getSolutionCount() {
return solutionCount;
}

private int solutionCount;
private final IntVar[] variableArray;
}

public static void main(String[] args) throws Exception {
// Create the model.
CpModel model = new CpModel();

// Create the variables.
int numVals = 3;

IntVar x = model.newIntVar(0, numVals - 1, "x");
IntVar y = model.newIntVar(0, numVals - 1, "y");
IntVar z = model.newIntVar(0, numVals - 1, "z");

// Create the constraint.

// Maximize a linear combination of variables.
model.maximize(LinearExpr.scalProd(new IntVar[] {x, y, z}, new int[] {1, 2, 3}));

// Create a solver and solve the model.
CpSolver solver = new CpSolver();
VarArraySolutionPrinterWithObjective cb =
new VarArraySolutionPrinterWithObjective(new IntVar[] {x, y, z});
solver.solveWithSolutionCallback(model, cb);

System.out.println(cb.getSolutionCount() + " solutions found.");
}
}```

### C#

```using System;

public class VarArraySolutionPrinterWithObjective : CpSolverSolutionCallback
{
public VarArraySolutionPrinterWithObjective(IntVar[] variables)
{
variables_ = variables;
}

public override void OnSolutionCallback()
{
Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s",
solution_count_, WallTime()));
Console.WriteLine(
String.Format("  objective value = {0}", ObjectiveValue()));
foreach (IntVar v in variables_)
{
Console.WriteLine(
String.Format("  {0} = {1}", v.ShortString(), Value(v)));
}
solution_count_++;
}

public int SolutionCount()
{
return solution_count_;
}

private int solution_count_;
private IntVar[] variables_;
}

public class SolveAndPrintIntermediateSolutionsSampleSat
{
static void Main()
{
// Creates the model.
CpModel model = new CpModel();

// Creates the variables.
int num_vals = 3;

IntVar x = model.NewIntVar(0, num_vals - 1, "x");
IntVar y = model.NewIntVar(0, num_vals - 1, "y");
IntVar z = model.NewIntVar(0, num_vals - 1, "z");

// Maximizes a linear combination of variables.
model.Maximize(x + 2 * y + 3 * z);

// Creates a solver and solves the model.
CpSolver solver = new CpSolver();
VarArraySolutionPrinterWithObjective cb =
new VarArraySolutionPrinterWithObjective(new IntVar[] { x, y, z });
solver.SolveWithSolutionCallback(model, cb);

Console.WriteLine(String.Format("Number of solutions found: {0}",
cb.SolutionCount()));
}
}```