This section describes an assignment problem in which each task has a size, which represents how much time or effort the task requires. The total size of the tasks performed by each worker has a fixed bound.

We'll present Python programs that solve this problem using the CP-SAT solver and the MIP solver.

## CP-SAT solution

First, let's take a look at the CP-SAT solution to the problem.

### Import the libraries

The following code imports the required library.

### Python

`from ortools.sat.python import cp_model`

### C++

```#include <stdlib.h>

#include <cstdint>
#include <numeric>
#include <vector>

#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"
#include "ortools/sat/cp_model.h"
#include "ortools/sat/cp_model.pb.h"
#include "ortools/sat/cp_model_solver.h"
```

### Java

```import com.google.ortools.Loader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;```

### C#

```using System;
using System.Collections.Generic;
using System.Linq;

### Define the data

The following code creates the data for the program.

### Python

```costs = [
[90, 76, 75, 70, 50, 74, 12, 68],
[35, 85, 55, 65, 48, 101, 70, 83],
[125, 95, 90, 105, 59, 120, 36, 73],
[45, 110, 95, 115, 104, 83, 37, 71],
[60, 105, 80, 75, 59, 62, 93, 88],
[45, 65, 110, 95, 47, 31, 81, 34],
[38, 51, 107, 41, 69, 99, 115, 48],
[47, 85, 57, 71, 92, 77, 109, 36],
[39, 63, 97, 49, 118, 56, 92, 61],
[47, 101, 71, 60, 88, 109, 52, 90],
]
num_workers = len(costs)

task_sizes = [10, 7, 3, 12, 15, 4, 11, 5]
# Maximum total of task sizes for any worker
total_size_max = 15```

### C++

```const std::vector<std::vector<int>> costs = {{
{{90, 76, 75, 70, 50, 74, 12, 68}},
{{35, 85, 55, 65, 48, 101, 70, 83}},
{{125, 95, 90, 105, 59, 120, 36, 73}},
{{45, 110, 95, 115, 104, 83, 37, 71}},
{{60, 105, 80, 75, 59, 62, 93, 88}},
{{45, 65, 110, 95, 47, 31, 81, 34}},
{{38, 51, 107, 41, 69, 99, 115, 48}},
{{47, 85, 57, 71, 92, 77, 109, 36}},
{{39, 63, 97, 49, 118, 56, 92, 61}},
{{47, 101, 71, 60, 88, 109, 52, 90}},
}};
const int num_workers = static_cast<int>(costs.size());
std::vector<int> all_workers(num_workers);
std::iota(all_workers.begin(), all_workers.end(), 0);

const std::vector<int64_t> task_sizes = {{10, 7, 3, 12, 15, 4, 11, 5}};
// Maximum total of task sizes for any worker
const int total_size_max = 15;```

### Java

```int[][] costs = {
{90, 76, 75, 70, 50, 74, 12, 68},
{35, 85, 55, 65, 48, 101, 70, 83},
{125, 95, 90, 105, 59, 120, 36, 73},
{45, 110, 95, 115, 104, 83, 37, 71},
{60, 105, 80, 75, 59, 62, 93, 88},
{45, 65, 110, 95, 47, 31, 81, 34},
{38, 51, 107, 41, 69, 99, 115, 48},
{47, 85, 57, 71, 92, 77, 109, 36},
{39, 63, 97, 49, 118, 56, 92, 61},
{47, 101, 71, 60, 88, 109, 52, 90},
};
final int numWorkers = costs.length;

final int[] allWorkers = IntStream.range(0, numWorkers).toArray();

final int[] taskSizes = {10, 7, 3, 12, 15, 4, 11, 5};
// Maximum total of task sizes for any worker
final int totalSizeMax = 15;```

### C#

```int[,] costs = {
{ 90, 76, 75, 70, 50, 74, 12, 68 },    { 35, 85, 55, 65, 48, 101, 70, 83 },
{ 125, 95, 90, 105, 59, 120, 36, 73 }, { 45, 110, 95, 115, 104, 83, 37, 71 },
{ 60, 105, 80, 75, 59, 62, 93, 88 },   { 45, 65, 110, 95, 47, 31, 81, 34 },
{ 38, 51, 107, 41, 69, 99, 115, 48 },  { 47, 85, 57, 71, 92, 77, 109, 36 },
{ 39, 63, 97, 49, 118, 56, 92, 61 },   { 47, 101, 71, 60, 88, 109, 52, 90 },
};
int numWorkers = costs.GetLength(0);

int[] allWorkers = Enumerable.Range(0, numWorkers).ToArray();

int[] taskSizes = { 10, 7, 3, 12, 15, 4, 11, 5 };
// Maximum total of task sizes for any worker
int totalSizeMax = 15;```

As in previous examples, the cost matrix gives the cost for worker `i` to perform task `j`. The `sizes` vector gives the size of each task. `total_size_max` is the upper bound on the total size of the tasks performed by any single worker.

### Create the model

The following code creates the 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 an array of variables for the problem.

### Python

```x = {}
for worker in range(num_workers):

### C++

```// x[i][j] is an array of Boolean variables. x[i][j] is true
// if worker i is assigned to task j.
std::vector<std::vector<BoolVar>> x(num_workers,
for (int worker : all_workers) {
}
}```

### Java

```Literal[][] x = new Literal[numWorkers][numTasks];
for (int worker : allWorkers) {
}
}```

### C#

```BoolVar[,] x = new BoolVar[numWorkers, numTasks];
foreach (int worker in allWorkers)
{
{
}
}```

The following code creates the constraints for the program.

### Python

```# Each worker is assigned to at most one task.
for worker in range(num_workers):
<= total_size_max
)

# Each task is assigned to exactly one worker.

### C++

```// Each worker is assigned to at most one task.
for (int worker : all_workers) {
}
}
// Each task is assigned to exactly one worker.
for (int worker : all_workers) {
}
}```

### Java

```// Each worker has a maximum capacity.
for (int worker : allWorkers) {
LinearExprBuilder expr = LinearExpr.newBuilder();
}
}

// Each task is assigned to exactly one worker.
List<Literal> workers = new ArrayList<>();
for (int worker : allWorkers) {
}
}```

### C#

```// Each worker is assigned to at most max task size.
foreach (int worker in allWorkers)
{
{
}
}

// Each task is assigned to exactly one worker.
{
List<ILiteral> workers = new List<ILiteral>();
foreach (int worker in allWorkers)
{
}
}```

### Create the objective

The following code creates the objective function.

### Python

```objective_terms = []
for worker in range(num_workers):
model.minimize(sum(objective_terms))```

### C++

```LinearExpr total_cost;
for (int worker : all_workers) {
}
}
cp_model.Minimize(total_cost);```

### Java

```LinearExprBuilder obj = LinearExpr.newBuilder();
for (int worker : allWorkers) {
}
}
model.minimize(obj);```

### C#

```LinearExprBuilder obj = LinearExpr.NewBuilder();
foreach (int worker in allWorkers)
{
{
}
}
model.Minimize(obj);```

### Invoke the solver

The following code invokes the solver.

### Python

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

### C++

`const CpSolverResponse response = Solve(cp_model.Build());`

### Java

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

### C#

```CpSolver solver = new CpSolver();
CpSolverStatus status = solver.Solve(model);
Console.WriteLine(\$"Solve status: {status}");```

### Display the results

Now, we can print the solution.

### Python

```if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print(f"Total cost = {solver.objective_value}\n")
for worker in range(num_workers):
print(
)
else:
print("No solution found.")```

### C++

```if (response.status() == CpSolverStatus::INFEASIBLE) {
LOG(FATAL) << "No solution found.";
}
LOG(INFO) << "Total cost: " << response.objective_value();
LOG(INFO);
for (int worker : all_workers) {
LOG(INFO) << "Worker " << worker << " assigned to task " << task
<< ".  Cost: " << costs[worker][task];
}
}
}```

### Java

```// Check that the problem has a feasible solution.
if (status == CpSolverStatus.OPTIMAL || status == CpSolverStatus.FEASIBLE) {
System.out.println("Total cost: " + solver.objectiveValue() + "\n");
for (int worker : allWorkers) {
System.out.println("Worker " + worker + " assigned to task " + task
+ ".  Cost: " + costs[worker][task]);
}
}
}
} else {
System.err.println("No solution found.");
}```

### C#

```// Check that the problem has a feasible solution.
if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible)
{
Console.WriteLine(\$"Total cost: {solver.ObjectiveValue}\n");
foreach (int worker in allWorkers)
{
{
{
}
}
}
}
else
{
Console.WriteLine("No solution found.");
}```

Here's the output of the program.

```Minimum cost: 326
Worker  0  assigned to task  6   Cost =  12
Worker  1  assigned to task  0   Cost =  35
Worker  1  assigned to task  2   Cost =  55
Worker  2  assigned to task  4   Cost =  59
Worker  5  assigned to task  5   Cost =  31
Worker  5  assigned to task  7   Cost =  34
Worker  6  assigned to task  1   Cost =  51
Worker  8  assigned to task  3   Cost =  49

Time =  2.2198 seconds```

### The entire program

Here is the entire program.

### Python

```"""Solves a simple assignment problem."""
from ortools.sat.python import cp_model

def main() -> None:
# Data
costs = [
[90, 76, 75, 70, 50, 74, 12, 68],
[35, 85, 55, 65, 48, 101, 70, 83],
[125, 95, 90, 105, 59, 120, 36, 73],
[45, 110, 95, 115, 104, 83, 37, 71],
[60, 105, 80, 75, 59, 62, 93, 88],
[45, 65, 110, 95, 47, 31, 81, 34],
[38, 51, 107, 41, 69, 99, 115, 48],
[47, 85, 57, 71, 92, 77, 109, 36],
[39, 63, 97, 49, 118, 56, 92, 61],
[47, 101, 71, 60, 88, 109, 52, 90],
]
num_workers = len(costs)

task_sizes = [10, 7, 3, 12, 15, 4, 11, 5]
# Maximum total of task sizes for any worker
total_size_max = 15

# Model
model = cp_model.CpModel()

# Variables
x = {}
for worker in range(num_workers):

# Constraints
# Each worker is assigned to at most one task.
for worker in range(num_workers):
<= total_size_max
)

# Each task is assigned to exactly one worker.

# Objective
objective_terms = []
for worker in range(num_workers):
model.minimize(sum(objective_terms))

# Solve
solver = cp_model.CpSolver()
status = solver.solve(model)

# Print solution.
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print(f"Total cost = {solver.objective_value}\n")
for worker in range(num_workers):
print(
)
else:
print("No solution found.")

if __name__ == "__main__":
main()```

### C++

```// Solve assignment problem.
#include <stdlib.h>

#include <cstdint>
#include <numeric>
#include <vector>

#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"
#include "ortools/sat/cp_model.h"
#include "ortools/sat/cp_model.pb.h"
#include "ortools/sat/cp_model_solver.h"

namespace operations_research {
namespace sat {

// Data
const std::vector<std::vector<int>> costs = {{
{{90, 76, 75, 70, 50, 74, 12, 68}},
{{35, 85, 55, 65, 48, 101, 70, 83}},
{{125, 95, 90, 105, 59, 120, 36, 73}},
{{45, 110, 95, 115, 104, 83, 37, 71}},
{{60, 105, 80, 75, 59, 62, 93, 88}},
{{45, 65, 110, 95, 47, 31, 81, 34}},
{{38, 51, 107, 41, 69, 99, 115, 48}},
{{47, 85, 57, 71, 92, 77, 109, 36}},
{{39, 63, 97, 49, 118, 56, 92, 61}},
{{47, 101, 71, 60, 88, 109, 52, 90}},
}};
const int num_workers = static_cast<int>(costs.size());
std::vector<int> all_workers(num_workers);
std::iota(all_workers.begin(), all_workers.end(), 0);

const std::vector<int64_t> task_sizes = {{10, 7, 3, 12, 15, 4, 11, 5}};
// Maximum total of task sizes for any worker
const int total_size_max = 15;

// Model
CpModelBuilder cp_model;

// Variables
// x[i][j] is an array of Boolean variables. x[i][j] is true
// if worker i is assigned to task j.
std::vector<std::vector<BoolVar>> x(num_workers,
for (int worker : all_workers) {
}
}

// Constraints
// Each worker is assigned to at most one task.
for (int worker : all_workers) {
}
}
// Each task is assigned to exactly one worker.
for (int worker : all_workers) {
}
}

// Objective
LinearExpr total_cost;
for (int worker : all_workers) {
}
}
cp_model.Minimize(total_cost);

// Solve
const CpSolverResponse response = Solve(cp_model.Build());

// Print solution.
if (response.status() == CpSolverStatus::INFEASIBLE) {
LOG(FATAL) << "No solution found.";
}
LOG(INFO) << "Total cost: " << response.objective_value();
LOG(INFO);
for (int worker : all_workers) {
LOG(INFO) << "Worker " << worker << " assigned to task " << task
<< ".  Cost: " << costs[worker][task];
}
}
}
}
}  // namespace sat
}  // namespace operations_research

int main(int argc, char** argv) {
return EXIT_SUCCESS;
}```

### Java

```// CP-SAT example that solves an assignment problem.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/** Assignment problem. */
public static void main(String[] args) {
// Data
int[][] costs = {
{90, 76, 75, 70, 50, 74, 12, 68},
{35, 85, 55, 65, 48, 101, 70, 83},
{125, 95, 90, 105, 59, 120, 36, 73},
{45, 110, 95, 115, 104, 83, 37, 71},
{60, 105, 80, 75, 59, 62, 93, 88},
{45, 65, 110, 95, 47, 31, 81, 34},
{38, 51, 107, 41, 69, 99, 115, 48},
{47, 85, 57, 71, 92, 77, 109, 36},
{39, 63, 97, 49, 118, 56, 92, 61},
{47, 101, 71, 60, 88, 109, 52, 90},
};
final int numWorkers = costs.length;

final int[] allWorkers = IntStream.range(0, numWorkers).toArray();

final int[] taskSizes = {10, 7, 3, 12, 15, 4, 11, 5};
// Maximum total of task sizes for any worker
final int totalSizeMax = 15;

// Model
CpModel model = new CpModel();

// Variables
for (int worker : allWorkers) {
}
}

// Constraints
// Each worker has a maximum capacity.
for (int worker : allWorkers) {
LinearExprBuilder expr = LinearExpr.newBuilder();
}
}

// Each task is assigned to exactly one worker.
List<Literal> workers = new ArrayList<>();
for (int worker : allWorkers) {
}
}

// Objective
LinearExprBuilder obj = LinearExpr.newBuilder();
for (int worker : allWorkers) {
}
}
model.minimize(obj);

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

// Print solution.
// Check that the problem has a feasible solution.
if (status == CpSolverStatus.OPTIMAL || status == CpSolverStatus.FEASIBLE) {
System.out.println("Total cost: " + solver.objectiveValue() + "\n");
for (int worker : allWorkers) {
System.out.println("Worker " + worker + " assigned to task " + task
+ ".  Cost: " + costs[worker][task]);
}
}
}
} else {
System.err.println("No solution found.");
}
}

}
```

### C#

```using System;
using System.Collections.Generic;
using System.Linq;

{
public static void Main(String[] args)
{
// Data.
int[,] costs = {
{ 90, 76, 75, 70, 50, 74, 12, 68 },    { 35, 85, 55, 65, 48, 101, 70, 83 },
{ 125, 95, 90, 105, 59, 120, 36, 73 }, { 45, 110, 95, 115, 104, 83, 37, 71 },
{ 60, 105, 80, 75, 59, 62, 93, 88 },   { 45, 65, 110, 95, 47, 31, 81, 34 },
{ 38, 51, 107, 41, 69, 99, 115, 48 },  { 47, 85, 57, 71, 92, 77, 109, 36 },
{ 39, 63, 97, 49, 118, 56, 92, 61 },   { 47, 101, 71, 60, 88, 109, 52, 90 },
};
int numWorkers = costs.GetLength(0);

int[] allWorkers = Enumerable.Range(0, numWorkers).ToArray();

int[] taskSizes = { 10, 7, 3, 12, 15, 4, 11, 5 };
// Maximum total of task sizes for any worker
int totalSizeMax = 15;

// Model.
CpModel model = new CpModel();

// Variables.
BoolVar[,] x = new BoolVar[numWorkers, numTasks];
foreach (int worker in allWorkers)
{
{
}
}

// Constraints
// Each worker is assigned to at most max task size.
foreach (int worker in allWorkers)
{
{
}
}

// Each task is assigned to exactly one worker.
{
List<ILiteral> workers = new List<ILiteral>();
foreach (int worker in allWorkers)
{
}
}

// Objective
LinearExprBuilder obj = LinearExpr.NewBuilder();
foreach (int worker in allWorkers)
{
{
}
}
model.Minimize(obj);

// Solve
CpSolver solver = new CpSolver();
CpSolverStatus status = solver.Solve(model);
Console.WriteLine(\$"Solve status: {status}");

// Print solution.
// Check that the problem has a feasible solution.
if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible)
{
Console.WriteLine(\$"Total cost: {solver.ObjectiveValue}\n");
foreach (int worker in allWorkers)
{
{
{
}
}
}
}
else
{
Console.WriteLine("No solution found.");
}

Console.WriteLine("Statistics");
Console.WriteLine(\$"  - conflicts : {solver.NumConflicts()}");
Console.WriteLine(\$"  - branches  : {solver.NumBranches()}");
Console.WriteLine(\$"  - wall time : {solver.WallTime()}s");
}
}```

## MIP solution

Next, we describe a solution to the assignment problem using the MIP solver.

### Import the libraries

The following code imports the required library.

### Python

`from ortools.linear_solver import pywraplp`

### C++

```#include <cstdint>
#include <memory>
#include <numeric>
#include <vector>

#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"
#include "ortools/linear_solver/linear_solver.h"```

### Java

```import com.google.ortools.Loader;
import java.util.stream.IntStream;```

### C#

```using System;
using System.Collections.Generic;
using System.Linq;

### Define the data

The following code creates the data for the program.

### Python

```costs = [
[90, 76, 75, 70, 50, 74, 12, 68],
[35, 85, 55, 65, 48, 101, 70, 83],
[125, 95, 90, 105, 59, 120, 36, 73],
[45, 110, 95, 115, 104, 83, 37, 71],
[60, 105, 80, 75, 59, 62, 93, 88],
[45, 65, 110, 95, 47, 31, 81, 34],
[38, 51, 107, 41, 69, 99, 115, 48],
[47, 85, 57, 71, 92, 77, 109, 36],
[39, 63, 97, 49, 118, 56, 92, 61],
[47, 101, 71, 60, 88, 109, 52, 90],
]
num_workers = len(costs)

task_sizes = [10, 7, 3, 12, 15, 4, 11, 5]
# Maximum total of task sizes for any worker
total_size_max = 15```

### C++

```const std::vector<std::vector<int64_t>> costs = {{
{{90, 76, 75, 70, 50, 74, 12, 68}},
{{35, 85, 55, 65, 48, 101, 70, 83}},
{{125, 95, 90, 105, 59, 120, 36, 73}},
{{45, 110, 95, 115, 104, 83, 37, 71}},
{{60, 105, 80, 75, 59, 62, 93, 88}},
{{45, 65, 110, 95, 47, 31, 81, 34}},
{{38, 51, 107, 41, 69, 99, 115, 48}},
{{47, 85, 57, 71, 92, 77, 109, 36}},
{{39, 63, 97, 49, 118, 56, 92, 61}},
{{47, 101, 71, 60, 88, 109, 52, 90}},
}};
const int num_workers = costs.size();
std::vector<int> all_workers(num_workers);
std::iota(all_workers.begin(), all_workers.end(), 0);

const std::vector<int64_t> task_sizes = {{10, 7, 3, 12, 15, 4, 11, 5}};
// Maximum total of task sizes for any worker
const int total_size_max = 15;```

### Java

```double[][] costs = {
{90, 76, 75, 70, 50, 74, 12, 68},
{35, 85, 55, 65, 48, 101, 70, 83},
{125, 95, 90, 105, 59, 120, 36, 73},
{45, 110, 95, 115, 104, 83, 37, 71},
{60, 105, 80, 75, 59, 62, 93, 88},
{45, 65, 110, 95, 47, 31, 81, 34},
{38, 51, 107, 41, 69, 99, 115, 48},
{47, 85, 57, 71, 92, 77, 109, 36},
{39, 63, 97, 49, 118, 56, 92, 61},
{47, 101, 71, 60, 88, 109, 52, 90},
};
int numWorkers = costs.length;

final int[] allWorkers = IntStream.range(0, numWorkers).toArray();

final int[] taskSizes = {10, 7, 3, 12, 15, 4, 11, 5};
// Maximum total of task sizes for any worker
final int totalSizeMax = 15;```

### C#

```int[,] costs = {
{ 90, 76, 75, 70, 50, 74, 12, 68 },    { 35, 85, 55, 65, 48, 101, 70, 83 },
{ 125, 95, 90, 105, 59, 120, 36, 73 }, { 45, 110, 95, 115, 104, 83, 37, 71 },
{ 60, 105, 80, 75, 59, 62, 93, 88 },   { 45, 65, 110, 95, 47, 31, 81, 34 },
{ 38, 51, 107, 41, 69, 99, 115, 48 },  { 47, 85, 57, 71, 92, 77, 109, 36 },
{ 39, 63, 97, 49, 118, 56, 92, 61 },   { 47, 101, 71, 60, 88, 109, 52, 90 },
};
int numWorkers = costs.GetLength(0);

int[] allWorkers = Enumerable.Range(0, numWorkers).ToArray();

int[] taskSizes = { 10, 7, 3, 12, 15, 4, 11, 5 };
// Maximum total of task sizes for any worker
int totalSizeMax = 15;```

### Declare the solver

The following code creates the solver.

### Python

```# Create the mip solver with the SCIP backend.
solver = pywraplp.Solver.CreateSolver("SCIP")

if not solver:
return```

### C++

```// Create the mip solver with the SCIP backend.
std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("SCIP"));
if (!solver) {
LOG(WARNING) << "SCIP solver unavailable.";
return;
}```

### Java

```// Create the linear solver with the SCIP backend.
MPSolver solver = MPSolver.createSolver("SCIP");
if (solver == null) {
System.out.println("Could not create solver SCIP");
return;
}```

### C#

```Solver solver = Solver.CreateSolver("SCIP");
if (solver is null)
{
return;
}```

### Create the variables

The following code creates an array of variables for the problem.

### Python

```# x[i, j] is an array of 0-1 variables, which will be 1
# if worker i is assigned to task j.
x = {}
for worker in range(num_workers):

### C++

```// x[i][j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
std::vector<std::vector<const MPVariable*>> x(
for (int worker : all_workers) {
}
}```

### Java

```// x[i][j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
for (int worker : allWorkers) {
}
}```

### C#

```// x[i, j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
Variable[,] x = new Variable[numWorkers, numTasks];
foreach (int worker in allWorkers)
{
{
}
}```

The following code creates the constraints for the program.

### Python

```# The total size of the tasks each worker takes on is at most total_size_max.
for worker in range(num_workers):
solver.Sum(
)
<= total_size_max
)

# Each task is assigned to exactly one worker.

### C++

```// Each worker is assigned to at most one task.
for (int worker : all_workers) {
LinearExpr worker_sum;
}
solver->MakeRowConstraint(worker_sum <= total_size_max);
}
// Each task is assigned to exactly one worker.
for (int worker : all_workers) {
}
}```

### Java

```// Each worker is assigned to at most max task size.
for (int worker : allWorkers) {
MPConstraint constraint = solver.makeConstraint(0, totalSizeMax, "");
}
}
// Each task is assigned to exactly one worker.
MPConstraint constraint = solver.makeConstraint(1, 1, "");
for (int worker : allWorkers) {
}
}```

### C#

```// Each worker is assigned to at most max task size.
foreach (int worker in allWorkers)
{
Constraint constraint = solver.MakeConstraint(0, totalSizeMax, "");
{
}
}
// Each task is assigned to exactly one worker.
{
Constraint constraint = solver.MakeConstraint(1, 1, "");
foreach (int worker in allWorkers)
{
}
}```

### Create the objective

The following code creates the objective function.

### Python

```objective_terms = []
for worker in range(num_workers):
solver.Minimize(solver.Sum(objective_terms))```

### C++

```MPObjective* const objective = solver->MutableObjective();
for (int worker : all_workers) {
}
}
objective->SetMinimization();```

### Java

```MPObjective objective = solver.objective();
for (int worker : allWorkers) {
}
}
objective.setMinimization();```

### C#

```Objective objective = solver.Objective();
foreach (int worker in allWorkers)
{
{
}
}
objective.SetMinimization();```

### Invoke the solver

The following code invokes the solver and displays the results.

### Python

```print(f"Solving with {solver.SolverVersion()}")
status = solver.Solve()```

### C++

`const MPSolver::ResultStatus result_status = solver->Solve();`

### Java

`MPSolver.ResultStatus resultStatus = solver.solve();`

### C#

`Solver.ResultStatus resultStatus = solver.Solve();`

### Display the results

Now, we can print the solution.

### Python

```if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE:
print(f"Total cost = {solver.Objective().Value()}\n")
for worker in range(num_workers):
print(
)
else:
print("No solution found.")```

### C++

```// Check that the problem has a feasible solution.
if (result_status != MPSolver::OPTIMAL &&
result_status != MPSolver::FEASIBLE) {
LOG(FATAL) << "No solution found.";
}
LOG(INFO) << "Total cost = " << objective->Value() << "\n\n";
for (int worker : all_workers) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
LOG(INFO) << "Worker " << worker << " assigned to task " << task
<< ".  Cost: " << costs[worker][task];
}
}
}```

### Java

```// Check that the problem has a feasible solution.
if (resultStatus == MPSolver.ResultStatus.OPTIMAL
|| resultStatus == MPSolver.ResultStatus.FEASIBLE) {
System.out.println("Total cost: " + objective.value() + "\n");
for (int worker : allWorkers) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
System.out.println("Worker " + worker + " assigned to task " + task
+ ".  Cost: " + costs[worker][task]);
}
}
}
} else {
System.err.println("No solution found.");
}```

### C#

```// Check that the problem has a feasible solution.
if (resultStatus == Solver.ResultStatus.OPTIMAL || resultStatus == Solver.ResultStatus.FEASIBLE)
{
Console.WriteLine(\$"Total cost: {solver.Objective().Value()}\n");
foreach (int worker in allWorkers)
{
{
// Test if x[i, j] is 0 or 1 (with tolerance for floating point
// arithmetic).
{
}
}
}
}
else
{
Console.WriteLine("No solution found.");
}```

Here is the output of the program.

```Minimum cost =  326.0

Worker 0  assigned to task 6   Cost =  12
Worker 1  assigned to task 0   Cost =  35
Worker 1  assigned to task 2   Cost =  55
Worker 4  assigned to task 4   Cost =  59
Worker 5  assigned to task 5   Cost =  31
Worker 5  assigned to task 7   Cost =  34
Worker 6  assigned to task 1   Cost =  51
Worker 8  assigned to task 3   Cost =  49

Time =  0.0167 seconds```

### The entire program

Here is the entire program.

### Python

```"""MIP example that solves an assignment problem."""
from ortools.linear_solver import pywraplp

def main():
# Data
costs = [
[90, 76, 75, 70, 50, 74, 12, 68],
[35, 85, 55, 65, 48, 101, 70, 83],
[125, 95, 90, 105, 59, 120, 36, 73],
[45, 110, 95, 115, 104, 83, 37, 71],
[60, 105, 80, 75, 59, 62, 93, 88],
[45, 65, 110, 95, 47, 31, 81, 34],
[38, 51, 107, 41, 69, 99, 115, 48],
[47, 85, 57, 71, 92, 77, 109, 36],
[39, 63, 97, 49, 118, 56, 92, 61],
[47, 101, 71, 60, 88, 109, 52, 90],
]
num_workers = len(costs)

task_sizes = [10, 7, 3, 12, 15, 4, 11, 5]
# Maximum total of task sizes for any worker
total_size_max = 15

# Solver
# Create the mip solver with the SCIP backend.
solver = pywraplp.Solver.CreateSolver("SCIP")

if not solver:
return

# Variables
# x[i, j] is an array of 0-1 variables, which will be 1
# if worker i is assigned to task j.
x = {}
for worker in range(num_workers):

# Constraints
# The total size of the tasks each worker takes on is at most total_size_max.
for worker in range(num_workers):
solver.Sum(
)
<= total_size_max
)

# Each task is assigned to exactly one worker.

# Objective
objective_terms = []
for worker in range(num_workers):
solver.Minimize(solver.Sum(objective_terms))

# Solve
print(f"Solving with {solver.SolverVersion()}")
status = solver.Solve()

# Print solution.
if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE:
print(f"Total cost = {solver.Objective().Value()}\n")
for worker in range(num_workers):
print(
)
else:
print("No solution found.")

if __name__ == "__main__":
main()```

### C++

```// Solve a simple assignment problem.
#include <cstdint>
#include <memory>
#include <numeric>
#include <vector>

#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"
#include "ortools/linear_solver/linear_solver.h"

namespace operations_research {
void AssignmentTeamsMip() {
// Data
const std::vector<std::vector<int64_t>> costs = {{
{{90, 76, 75, 70, 50, 74, 12, 68}},
{{35, 85, 55, 65, 48, 101, 70, 83}},
{{125, 95, 90, 105, 59, 120, 36, 73}},
{{45, 110, 95, 115, 104, 83, 37, 71}},
{{60, 105, 80, 75, 59, 62, 93, 88}},
{{45, 65, 110, 95, 47, 31, 81, 34}},
{{38, 51, 107, 41, 69, 99, 115, 48}},
{{47, 85, 57, 71, 92, 77, 109, 36}},
{{39, 63, 97, 49, 118, 56, 92, 61}},
{{47, 101, 71, 60, 88, 109, 52, 90}},
}};
const int num_workers = costs.size();
std::vector<int> all_workers(num_workers);
std::iota(all_workers.begin(), all_workers.end(), 0);

const std::vector<int64_t> task_sizes = {{10, 7, 3, 12, 15, 4, 11, 5}};
// Maximum total of task sizes for any worker
const int total_size_max = 15;

// Solver
// Create the mip solver with the SCIP backend.
std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("SCIP"));
if (!solver) {
LOG(WARNING) << "SCIP solver unavailable.";
return;
}

// Variables
// x[i][j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
std::vector<std::vector<const MPVariable*>> x(
for (int worker : all_workers) {
}
}

// Constraints
// Each worker is assigned to at most one task.
for (int worker : all_workers) {
LinearExpr worker_sum;
}
solver->MakeRowConstraint(worker_sum <= total_size_max);
}
// Each task is assigned to exactly one worker.
for (int worker : all_workers) {
}
}

// Objective.
MPObjective* const objective = solver->MutableObjective();
for (int worker : all_workers) {
}
}
objective->SetMinimization();

// Solve
const MPSolver::ResultStatus result_status = solver->Solve();

// Print solution.
// Check that the problem has a feasible solution.
if (result_status != MPSolver::OPTIMAL &&
result_status != MPSolver::FEASIBLE) {
LOG(FATAL) << "No solution found.";
}
LOG(INFO) << "Total cost = " << objective->Value() << "\n\n";
for (int worker : all_workers) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
LOG(INFO) << "Worker " << worker << " assigned to task " << task
<< ".  Cost: " << costs[worker][task];
}
}
}
}
}  // namespace operations_research

int main(int argc, char** argv) {
operations_research::AssignmentTeamsMip();
return EXIT_SUCCESS;
}```

### Java

```package com.google.ortools.linearsolver.samples;
import java.util.stream.IntStream;

/** MIP example that solves an assignment problem. */
public static void main(String[] args) {
// Data
double[][] costs = {
{90, 76, 75, 70, 50, 74, 12, 68},
{35, 85, 55, 65, 48, 101, 70, 83},
{125, 95, 90, 105, 59, 120, 36, 73},
{45, 110, 95, 115, 104, 83, 37, 71},
{60, 105, 80, 75, 59, 62, 93, 88},
{45, 65, 110, 95, 47, 31, 81, 34},
{38, 51, 107, 41, 69, 99, 115, 48},
{47, 85, 57, 71, 92, 77, 109, 36},
{39, 63, 97, 49, 118, 56, 92, 61},
{47, 101, 71, 60, 88, 109, 52, 90},
};
int numWorkers = costs.length;

final int[] allWorkers = IntStream.range(0, numWorkers).toArray();

final int[] taskSizes = {10, 7, 3, 12, 15, 4, 11, 5};
// Maximum total of task sizes for any worker
final int totalSizeMax = 15;

// Solver
// Create the linear solver with the SCIP backend.
MPSolver solver = MPSolver.createSolver("SCIP");
if (solver == null) {
System.out.println("Could not create solver SCIP");
return;
}

// Variables
// x[i][j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
for (int worker : allWorkers) {
}
}

// Constraints
// Each worker is assigned to at most max task size.
for (int worker : allWorkers) {
MPConstraint constraint = solver.makeConstraint(0, totalSizeMax, "");
}
}
// Each task is assigned to exactly one worker.
MPConstraint constraint = solver.makeConstraint(1, 1, "");
for (int worker : allWorkers) {
}
}

// Objective
MPObjective objective = solver.objective();
for (int worker : allWorkers) {
}
}
objective.setMinimization();

// Solve
MPSolver.ResultStatus resultStatus = solver.solve();

// Print solution.
// Check that the problem has a feasible solution.
if (resultStatus == MPSolver.ResultStatus.OPTIMAL
|| resultStatus == MPSolver.ResultStatus.FEASIBLE) {
System.out.println("Total cost: " + objective.value() + "\n");
for (int worker : allWorkers) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
System.out.println("Worker " + worker + " assigned to task " + task
+ ".  Cost: " + costs[worker][task]);
}
}
}
} else {
System.err.println("No solution found.");
}
}

}```

### C#

```using System;
using System.Collections.Generic;
using System.Linq;

{
static void Main()
{
// Data.
int[,] costs = {
{ 90, 76, 75, 70, 50, 74, 12, 68 },    { 35, 85, 55, 65, 48, 101, 70, 83 },
{ 125, 95, 90, 105, 59, 120, 36, 73 }, { 45, 110, 95, 115, 104, 83, 37, 71 },
{ 60, 105, 80, 75, 59, 62, 93, 88 },   { 45, 65, 110, 95, 47, 31, 81, 34 },
{ 38, 51, 107, 41, 69, 99, 115, 48 },  { 47, 85, 57, 71, 92, 77, 109, 36 },
{ 39, 63, 97, 49, 118, 56, 92, 61 },   { 47, 101, 71, 60, 88, 109, 52, 90 },
};
int numWorkers = costs.GetLength(0);

int[] allWorkers = Enumerable.Range(0, numWorkers).ToArray();

int[] taskSizes = { 10, 7, 3, 12, 15, 4, 11, 5 };
// Maximum total of task sizes for any worker
int totalSizeMax = 15;

// Solver.
Solver solver = Solver.CreateSolver("SCIP");
if (solver is null)
{
return;
}

// Variables.
// x[i, j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
Variable[,] x = new Variable[numWorkers, numTasks];
foreach (int worker in allWorkers)
{
{
}
}

// Constraints
// Each worker is assigned to at most max task size.
foreach (int worker in allWorkers)
{
Constraint constraint = solver.MakeConstraint(0, totalSizeMax, "");
{
}
}
// Each task is assigned to exactly one worker.
{
Constraint constraint = solver.MakeConstraint(1, 1, "");
foreach (int worker in allWorkers)
{
}
}

// Objective
Objective objective = solver.Objective();
foreach (int worker in allWorkers)
{
{
}
}
objective.SetMinimization();

// Solve
Solver.ResultStatus resultStatus = solver.Solve();

// Print solution.
// Check that the problem has a feasible solution.
if (resultStatus == Solver.ResultStatus.OPTIMAL || resultStatus == Solver.ResultStatus.FEASIBLE)
{
Console.WriteLine(\$"Total cost: {solver.Objective().Value()}\n");
foreach (int worker in allWorkers)
{
{
// Test if x[i, j] is 0 or 1 (with tolerance for floating point
// arithmetic).
{