diff --git a/ortools/linear_solver/samples/AssignmentMb.cs b/ortools/linear_solver/samples/AssignmentMb.cs new file mode 100644 index 0000000000..a1213c7ff0 --- /dev/null +++ b/ortools/linear_solver/samples/AssignmentMb.cs @@ -0,0 +1,129 @@ +// Copyright 2010-2022 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] +using System; +using Google.OrTools.ModelBuilder; +// [END import] + +public class AssignmentMb +{ + 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] + + // [START model] + ModelBuilder model = new ModelBuilder(); + // [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[numWorkers, numTasks]; + for (int i = 0; i < numWorkers; ++i) + { + for (int j = 0; j < numTasks; ++j) + { + x[i, j] = model.NewBoolVar($"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) + { + var assignedWork = LinearExpr.NewBuilder(); + for (int j = 0; j < numTasks; ++j) + { + assignedWork.Add(x[i, j]); + } + model.Add(assignedWork <= 1); + } + + // Each task is assigned to exactly one worker. + for (int j = 0; j < numTasks; ++j) + { + var assignedWorker = LinearExpr.NewBuilder(); + for (int i = 0; i < numWorkers; ++i) + { + assignedWorker.Add(x[i, j]); + } + model.Add(assignedWorker == 1); + } + // [END constraints] + + // Objective + // [START objective] + var objective = LinearExpr.NewBuilder(); + for (int i = 0; i < numWorkers; ++i) + { + for (int j = 0; j < numTasks; ++j) + { + objective.AddTerm(x[i, j], costs[i, j]); + } + } + model.Minimize(objective); + // [END objective] + + // [START solver] + // Create the model solver with the SCIP backend. + ModelSolver solver = new ModelSolver("SCIP"); + if (!solver.SolverIsSupported()) + { + return; + } + // [END solver] + + // Solve + // [START solve] + SolveStatus resultStatus = solver.Solve(model); + // [END solve] + + // Print solution. + // [START print_solution] + // Check that the problem has a feasible solution. + if (resultStatus == SolverStatus.OPTIMAL || resultStatus == SolverStatus.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 (solver.Value(x[i, j]) > 0.9) + { + Console.WriteLine($"Worker {i} assigned to task {j}. Cost: {costs[i, j]}"); + } + } + } + } + else + { + Console.WriteLine("No solution found."); + } + // [END print_solution] + } +} +// [END program] diff --git a/ortools/linear_solver/samples/BinPackingMb.cs b/ortools/linear_solver/samples/BinPackingMb.cs new file mode 100644 index 0000000000..31fa1a6d4b --- /dev/null +++ b/ortools/linear_solver/samples/BinPackingMb.cs @@ -0,0 +1,131 @@ +// Copyright 2010-2022 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] +using System; +using Google.OrTools.ModelBuilder; +// [END import] + +// [START program_part1] +public class BinPackingMb +{ + // [START data_model] + class DataModel + { + public static double[] Weights = { 48, 30, 19, 36, 36, 27, 42, 42, 36, 24, 30 }; + public int NumItems = Weights.Length; + public int NumBins = Weights.Length; + public double BinCapacity = 100.0; + } + // [END data_model] + public static void Main() + { + // [START data] + DataModel data = new DataModel(); + // [END data] + // [END program_part1] + + // [START model] + ModelBuilder model = new ModelBuilder(); + // [END model] + + // [START program_part2] + // [START variables] + Variable[,] x = new Variable[data.NumItems, data.NumBins]; + for (int i = 0; i < data.NumItems; i++) + { + for (int j = 0; j < data.NumBins; j++) + { + x[i, j] = model.NewBoolVar($"x_{i}_{j}"); + } + } + Variable[] y = new Variable[data.NumBins]; + for (int j = 0; j < data.NumBins; j++) + { + y[j] = model.NewBoolVar($"y_{j}"); + } + // [END variables] + + // [START constraints] + for (int i = 0; i < data.NumItems; ++i) + { + var assignedWork = LinearExpr.NewBuilder(); + for (int j = 0; j < data.NumBins; ++j) + { + assignedWork.Add(x[i, j]); + } + model.Add(assignedWork == 1); + } + + for (int j = 0; j < data.NumBins; ++j) + { + var load = LinearExpr.NewBuilder(); + for (int i = 0; i < data.NumItems; ++i) + { + load.AddTerm(x[i, j], DataModel.Weights[i]); + } + model.Add(y[j] * data.BinCapacity >= load); + } + // [END constraints] + + // [START objective] + model.Minimize(LinearExpr.Sum(y)); + // [END objective] + + // [START solver] + // Create the model solver with the SCIP backend. + ModelSolver solver = new ModelSolver("SCIP"); + if (!solver.SolverIsSupported()) + { + return; + } + // [END solver] + + // [START solve] + SolveStatus resultStatus = solver.Solve(model); + // [END solve] + + // [START print_solution] + // Check that the problem has an optimal solution. + if (resultStatus != SolveStatus.OPTIMAL) + { + Console.WriteLine("The problem does not have an optimal solution!"); + return; + } + Console.WriteLine($"Number of bins used: {solver.ObjectiveValue}"); + double TotalWeight = 0.0; + for (int j = 0; j < data.NumBins; ++j) + { + double BinWeight = 0.0; + if (solver.Value(y[j]) == 1) + { + Console.WriteLine($"Bin {j}"); + for (int i = 0; i < data.NumItems; ++i) + { + if (solver.Value(x[i, j]) == 1) + { + Console.WriteLine($"Item {i} weight: {DataModel.Weights[i]}"); + BinWeight += DataModel.Weights[i]; + } + } + Console.WriteLine($"Packed bin weight: {BinWeight}"); + TotalWeight += BinWeight; + } + } + Console.WriteLine($"Total packed weight: {TotalWeight}"); + // [END print_solution] + } +} +// [END program_part2] +// [END program] diff --git a/ortools/linear_solver/samples/SimpleMipProgramMb.cs b/ortools/linear_solver/samples/SimpleMipProgramMb.cs index fe0a81ac43..b0f87cb6b5 100644 --- a/ortools/linear_solver/samples/SimpleMipProgramMb.cs +++ b/ortools/linear_solver/samples/SimpleMipProgramMb.cs @@ -51,7 +51,7 @@ public class SimpleMipProgramMb // [END objective] // [START solver] - // Create the model solver with the GLOP backend. + // Create the model solver with the SCIP backend. ModelSolver solver = new ModelSolver("SCIP"); if (!solver.SolverIsSupported()) {