Add AssignmentMIP samples

This commit is contained in:
Corentin Le Molgat
2020-06-04 17:15:34 +02:00
committed by Mizux Seiha
parent b58a4607b4
commit bcc6bd70a1
9 changed files with 473 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
// Copyright 2010-2018 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using Google.OrTools.LinearSolver;
public class AssignmentMip
{
static void Main()
{
// Data.
// [START data_model]
int[,] costs = {
{90, 80, 75, 70},
{35, 85, 55, 65},
{125, 95, 90, 95},
{45, 110, 95, 115},
{50, 100, 90, 100},
};
int numWorkers = costs.GetLength(0);
int numTasks = costs.GetLength(1);
// [END data_model]
// Model.
// [START model]
Solver solver = Solver.CreateSolver("AssignmentMip", "CBC_MIXED_INTEGER_PROGRAMMING");
// [END model]
// Variables.
// [START 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[data.NumItems, data.NumBins];
for (int i = 0; i < numWorkers; ++i)
{
for (int j = 0; j < numTasks; ++j)
{
x[i, j] = solver.MakeIntVar(0, 1, $"worker_{i}_task_{j}");
}
}
// [END variables]
// Constraints
// [START constraints]
// Each worker is assigned to at most one task.
for (int i = 0; i < numWorkers; ++i)
{
Constraint constraint = solver.MakeConstraint(0, 1, "");
for (int j = 0; j < numTasks; ++j)
{
constraint.SetCoefficient(x[i, j], 1);
}
}
// Each task is assigned to exactly one worker.
for (int j = 0; j < numTasks; ++j)
{
Constraint constraint = solver.MakeConstraint(1, 1, "");
for (int i = 0; i < numWorkers; ++i)
{
constraint.SetCoefficient(x[i, j], 1);
}
}
// [END constraints]
// Objective
// [START objective]
Objective objective = solver.Objective();
for (int i = 0; i < numWorkers; ++i)
{
for (int j = 0; j < numTasks; ++j)
{
objective.SetCoefficient(x[i, j], 1);
}
}
objective.SetMinimization();
// [END objective]
// Solve
// [START solve]
Solver.ResultStatus resultStatus = solver.Solve();
// [END solve]
// Print solution.
// [START print_solution]
// Check that the problem has a feasible solution.
if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible)
{
Console.WriteLine($"Total cost: {solver.ObjectiveValue}\n");
for (int i = 0; i < numWorkers; ++i)
{
for (int j = 0; j < numTasks; ++j)
{
// Test if x[i, j] is 0 or 1 (with tolerance for floating point
// arithmetic).
if (x[i, j].SolutionValue() > 0.5)
{
Console.WriteLine($"Worker {i} assigned to task {j}. Cost: {costs[i, j]}");
}
}
}
} else {
Console.WriteLine("No solution found.");
}
// [END print_solution]
}
}

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
<!-- see https://github.com/dotnet/docs/issues/12237 -->
<RollForward>LatestMajor</RollForward>
<RestoreSources>../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources>
<AssemblyName>Google.OrTools.AssignmentMip</AssemblyName>
<IsPackable>true</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<GenerateTailCalls>true</GenerateTailCalls>
</PropertyGroup>
<ItemGroup>
<Compile Include="AssignmentMip.cs" />
<PackageReference Include="Google.OrTools" Version="7.7.*" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,120 @@
// Copyright 2010-2018 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [START program]
package com.google.ortools.linearsolver.samples;
// [START import]
import com.google.ortools.linearsolver.MPConstraint;
import com.google.ortools.linearsolver.MPObjective;
import com.google.ortools.linearsolver.MPSolver;
import com.google.ortools.linearsolver.MPVariable;
// [END import]
/** MIP example that solves an assignment problem. */
public class AssignmentMip {
static {
System.loadLibrary("jniortools");
}
public static void main(String[] args) {
// Data
// [START data_model]
double[][] costs = {
{90, 80, 75, 70},
{35, 85, 55, 65},
{125, 95, 90, 95},
{45, 110, 95, 115},
{50, 100, 90, 100},
};
int numWorkers = costs.length;
int numTasks = costs[0].length;
// [END data_model]
// Solver
// [START solver]
// Create the linear solver with the CBC backend.
MPSolver solver = new MPSolver(
"AssignmentMip", MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
// [END solver]
// Variables
// [START variables]
// x[i][j] is an array of 0-1 variables, which will be 1
// if worker i is assigned to task j.
MPVariable[][] x = new MPVariable[numWorkers][numTasks];
for (int i = 0; i < numWorkers; ++i) {
for (int j = 0; j < numTasks; ++j) {
x[i][j] = solver.makeIntVar(0, 1, "");
}
}
// [END variables]
// Constraints
// [START constraints]
// Each worker is assigned to at most one task.
for (int i = 0; i < numWorkers; ++i) {
MPConstraint constraint = solver.makeConstraint(0, 1, "");
for (int j = 0; j < numTasks; ++j) {
constraint.setCoefficient(x[i][j], 1);
}
}
// Each task is assigned to exactly one worker.
for (int j = 0; j < numTasks; ++j) {
MPConstraint constraint = solver.makeConstraint(1, 1, "");
for (int i = 0; i < numWorkers; ++i) {
constraint.setCoefficient(x[i][j], 1);
}
}
// [END constraints]
// Objective
// [START objective]
MPObjective objective = solver.objective();
for (int i = 0; i < numWorkers; ++i) {
for (int j = 0; j < numTasks; ++j) {
objective.setCoefficient(x[i][j], costs[i][j]);
}
}
objective.setMinimization();
// [END objective]
// Solve
// [START solve]
MPSolver.ResultStatus resultStatus = solver.solve();
// [END solve]
// Print solution.
// [START 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 i = 0; i < numWorkers; ++i) {
for (int j = 0; j < numTasks; ++j) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
if (x[i][j].solutionValue() > 0.5) {
System.out.println(
"Worker " + i + " assigned to task " + j + ". Cost = " + costs[i][j]);
}
}
}
} else {
System.err.println("No solution found.");
}
// [END print_solution]
}
private AssignmentMip() {}
}
// [END program]

View File

@@ -0,0 +1,118 @@
// Copyright 2010-2018 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [START program]
// [START import]
#include <vector>
#include "ortools/base/logging.h"
#include "ortools/linear_solver/linear_solver.h"
// [END import]
namespace operations_research {
void IntegerProgrammingExample() {
// Data
// [START data_model]
const std::vector<std::vector<double>> costs{
{90, 80, 75, 70}, {35, 85, 55, 65}, {125, 95, 90, 95},
{45, 110, 95, 115}, {50, 100, 90, 100},
};
const int num_workers = costs.size();
const int num_tasks = costs[0].size();
// [END data_model]
// Solver
// [START solver]
// Create the mip solver with the CBC backend.
MPSolver solver("simple_mip_program",
MPSolver::CBC_MIXED_INTEGER_PROGRAMMING);
// [END solver]
// Variables
// [START 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(
num_workers, std::vector<const MPVariable*>(num_tasks));
for (int i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
x[i][j] = solver.MakeIntVar(0, 1, "");
}
}
// [END variables]
// Constraints
// [START constraints]
// Each worker is assigned to at most one task.
for (int i = 0; i < num_workers; ++i) {
LinearExpr worker_sum;
for (int j = 0; j < num_tasks; ++j) {
worker_sum += x[i][j];
}
solver.MakeRowConstraint(worker_sum <= 1.0);
}
// Each task is assigned to exactly one worker.
for (int j = 0; j < num_tasks; ++j) {
LinearExpr task_sum;
for (int i = 0; i < num_workers; ++i) {
task_sum += x[i][j];
}
solver.MakeRowConstraint(task_sum == 1.0);
}
// [END constraints]
// Objective.
// [START objective]
MPObjective* const objective = solver.MutableObjective();
for (int i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
objective->SetCoefficient(x[i][j], costs[i][j]);
}
}
objective->SetMinimization();
// [END objective]
// Solve
// [START solve]
const MPSolver::ResultStatus result_status = solver.Solve();
// [END solve]
// Print solution.
// [START 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 i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
// Test if x[i][j] is 0 or 1 (with tolerance for floating point
// arithmetic).
if (x[i][j]->solution_value() > 0.5) {
LOG(INFO) << "Worker " << i << " assigned to task " << j
<< ". Cost = " << costs[i][j];
}
}
}
// [END print_solution]
}
} // namespace operations_research
int main(int argc, char** argv) {
operations_research::IntegerProgrammingExample();
return EXIT_SUCCESS;
}
// [END program]

View File

@@ -0,0 +1,91 @@
# Copyright 2010-2018 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""MIP example that solves an assignment problem."""
# [START program]
# [START import]
from ortools.linear_solver import pywraplp
# [END import]
def main():
# Data
# [START data_model]
costs = [
[90, 80, 75, 70],
[35, 85, 55, 65],
[125, 95, 90, 95],
[45, 110, 95, 115],
[50, 100, 90, 100],
]
num_workers = len(costs)
num_tasks = len(costs[0])
# [END data_model]
# Solver
# [START solver]
# Create the mip solver with the CBC backend.
solver = pywraplp.Solver('simple_mip_program',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
# [END solver]
# Variables
# [START 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 i in range(num_workers):
for j in range(num_tasks):
x[i, j] = solver.IntVar(0, 1, '')
# [END variables]
# Constraints
# [START constraints]
# Each worker is assigned to at most 1 task.
for i in range(num_workers):
solver.Add(solver.Sum([x[i, j] for j in range(num_tasks)]) <= 1)
# Each task is assigned to exactly one worker.
for j in range(num_tasks):
solver.Add(solver.Sum([x[i, j] for i in range(num_workers)]) == 1)
# [END constraints]
# Objective
# [START objective]
objective_terms = []
for i in range(num_workers):
for j in range(num_tasks):
objective_terms.append(costs[i][j] * x[i, j])
solver.Minimize(solver.Sum(objective_terms))
# [END objective]
# Solve
# [START solve]
status = solver.Solve()
# [END solve]
# Print solution.
# [START print_solution]
if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE:
print('Total cost = ', solver.Objective().Value(), '\n')
for i in range(num_workers):
for j in range(num_tasks):
# Test if x[i,j] is 1 (with tolerance for floating point arithmetic).
if x[i, j].solution_value() > 0.5:
print('Worker %d assigned to task %d. Cost = %d' %
(i, j, costs[i][j]))
# [END print_solution]
if __name__ == '__main__':
main()
# [END program]