Add AssignemntSAT samples

This commit is contained in:
Corentin Le Molgat
2020-06-04 17:15:49 +02:00
committed by Mizux Seiha
parent bcc6bd70a1
commit 7e09eaf857
6 changed files with 323 additions and 0 deletions

View File

@@ -370,6 +370,7 @@ test_cc_constraint_solver_samples: \
.PHONY: test_cc_sat_samples # Build and Run all C++ Sat Samples (located in ortools/sat/samples)
test_cc_sat_samples: \
rcc_assignment_sat \
rcc_binpacking_problem_sat \
rcc_bool_or_sample_sat \
rcc_channeling_sample_sat \

View File

@@ -471,6 +471,7 @@ test_java_linear_solver_samples: \
.PHONY: test_java_sat_samples # Build and Run all Java SAT Samples (located in ortools/sat/samples)
test_java_sat_samples: \
rjava_AssignmentSat \
rjava_BinPackingProblemSat \
rjava_BoolOrSampleSat \
rjava_ChannelingSampleSat \

View File

@@ -602,6 +602,7 @@ test_python_linear_solver_samples: \
.PHONY: test_python_sat_samples # Run all Python Sat Samples (located in ortools/sat/samples)
test_python_sat_samples: \
rpy_assignment_sat \
rpy_binpacking_problem_sat \
rpy_bool_or_sample_sat \
rpy_channeling_sample_sat \

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.
// CP-SAT example that solves an assignment problem.
// [START program]
package com.google.ortools.sat.samples;
// [START import]
import com.google.ortools.sat.CpModel;
import com.google.ortools.sat.CpSolver;
import com.google.ortools.sat.CpSolverStatus;
import com.google.ortools.sat.IntVar;
import com.google.ortools.sat.LinearExpr;
// [END import]
/** Assignment problem. */
public class AssignmentSat {
static {
System.loadLibrary("jniortools");
}
public static void main(String[] args) {
// 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},
};
final int numWorkers = costs.length;
final int numTasks = costs[0].length;
// [END data_model]
// Model
// [START model]
CpModel model = new CpModel();
// [END model]
// Variables
// [START variables]
IntVar[][] x = new IntVar[numWorkers][numTasks];
// Variables in a 1-dim array.
IntVar[] xFlat = new IntVar[numWorkers * numTasks];
int[] costsFlat = new int[numWorkers * numTasks];
for (int i = 0; i < numWorkers; ++i) {
for (int j = 0; j < numTasks; ++j) {
x[i][j] = model.newIntVar(0, 1, "");
int k = i * numTasks + j;
xFlat[k] = x[i][j];
costsFlat[k] = costs[i][j];
}
}
// [END variables]
// Constraints
// [START constraints]
// Each worker is assigned to at most one task.
for (int i = 0; i < numWorkers; ++i) {
IntVar[] vars = new IntVar[numTasks];
for (int j = 0; j < numTasks; ++j) {
vars[j] = x[i][j];
}
model.addLessOrEqual(LinearExpr.sum(vars), 1);
}
// Each task is assigned to exactly one worker.
for (int j = 0; j < numTasks; ++j) {
// LinearExpr taskSum;
IntVar[] vars = new IntVar[numWorkers];
for (int i = 0; i < numWorkers; ++i) {
vars[i] = x[i][j];
}
model.addEquality(LinearExpr.sum(vars), 1);
}
// [END constraints]
// Objective
// [START objective]
model.minimize(LinearExpr.scalProd(xFlat, costsFlat));
// [END objective]
// Solve
// [START solve]
CpSolver solver = new CpSolver();
CpSolverStatus status = solver.solve(model);
// [END solve]
// Print solution.
// [START 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 i = 0; i < numWorkers; ++i) {
for (int j = 0; j < numTasks; ++j) {
if (solver.value(x[i][j]) == 1) {
System.out.println(
"Worker " + i + " assigned to task " + j + ". Cost: " + costs[i][j]);
}
}
}
} else {
System.err.println("No solution found.");
}
// [END print_solution]
}
private AssignmentSat() {}
}

View File

@@ -0,0 +1,110 @@
// 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 "ortools/sat/cp_model.h"
// [END import]
namespace operations_research {
namespace sat {
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]
// Model
// [START model]
CpModelBuilder cp_model;
// [END model]
// Variables
// [START 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,
std::vector<BoolVar>(num_tasks));
for (int i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
x[i][j] = cp_model.NewBoolVar();
}
}
// [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.AddTerm(x[i][j], 1);
}
cp_model.AddLessOrEqual(worker_sum, 1);
}
// 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.AddTerm(x[i][j], 1);
}
cp_model.AddEquality(task_sum, 1);
}
// [END constraints]
// Objective
// [START objective]
LinearExpr total_cost;
for (int i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
total_cost.AddTerm(x[i][j], costs[i][j]);
}
}
cp_model.Minimize(total_cost);
// [END objective]
// Solve
// [START solve]
const CpSolverResponse response = Solve(cp_model.Build());
// [END solve]
// Print solution.
// [START print_solution]
if (response.status() == CpSolverStatus::INFEASIBLE) {
LOG(FATAL) << "No solution found.";
}
LOG(INFO) << "Total cost: " << response.objective_value();
LOG(INFO);
for (int i = 0; i < num_workers; ++i) {
for (int j = 0; j < num_tasks; ++j) {
if (SolutionBooleanValue(response, x[i][j])) {
LOG(INFO) << "Task " << i << " assigned to worker " << j
<< ". Cost: " << costs[i][j];
}
}
}
// [END print_solution]
}
} // namespace sat
} // namespace operations_research
int main(int argc, char** argv) {
operations_research::sat::IntegerProgrammingExample();
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,92 @@
# 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.
"""Solve a simple assignment problem."""
# [START program]
# [START import]
from ortools.sat.python import cp_model
# [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]
# Model
# [START model]
model = cp_model.CpModel()
# [END model]
# Variables
# [START variables]
x = []
for i in range(num_workers):
t = []
for j in range(num_tasks):
t.append(model.NewBoolVar('x[%i,%i]' % (i, j)))
x.append(t)
# [END variables]
# Constraints
# [START constraints]
# Each worker is assigned to at most one task.
for i in range(num_workers):
model.Add(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):
model.Add(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])
model.Minimize(sum(objective_terms))
# [END objective]
# Solve
# [START solve]
solver = cp_model.CpSolver()
status = solver.Solve(model)
# [END solve]
# Print solution.
# [START print_solution]
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
print('Total cost = %i' % solver.ObjectiveValue())
print()
for i in range(num_workers):
for j in range(num_tasks):
if solver.BooleanValue(x[i][j]):
print('Worker ', i, ' assigned to task ', j, ' Cost = ',
costs[i][j])
else:
print('No solution found.')
# [END print_solution]
if __name__ == '__main__':
main()
# [END program]