diff --git a/ortools/linear_solver/samples/MultipleKnapsackMip.cs b/ortools/linear_solver/samples/MultipleKnapsackMip.cs index a98a596a3c..3f1f76b202 100644 --- a/ortools/linear_solver/samples/MultipleKnapsackMip.cs +++ b/ortools/linear_solver/samples/MultipleKnapsackMip.cs @@ -12,28 +12,28 @@ // limitations under the License. // [START program] +// Solve a multiple knapsack problem using a MIP solver. // [START import] using System; +using System.Collections.Generic; +using System.Linq; using Google.OrTools.LinearSolver; // [END import] public class MultipleKnapsackMip { - // [START data_model] - class DataModel - { - public static double[] Weights = { 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 }; - public static double[] Values = { 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 }; - public double[] BinCapacities = { 100, 100, 100, 100, 100 }; - public int NumItems = Weights.Length; - public int NumBins = 5; - } - // [END data_model] - public static void Main() { + // Instantiate the data problem. // [START data] - DataModel data = new DataModel(); + double[] Weights = { 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 }; + double[] Values = { 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 }; + int NumItems = Weights.Length; + int[] allItems = Enumerable.Range(0, NumItems).ToArray(); + + double[] BinCapacities = { 100, 100, 100, 100, 100 }; + int NumBins = BinCapacities.Length; + int[] allBins = Enumerable.Range(0, NumBins).ToArray(); // [END data] // [START solver] @@ -41,49 +41,49 @@ public class MultipleKnapsackMip Solver solver = Solver.CreateSolver("SCIP"); // [END solver] - // Variables + // Variables. // [START variables] - Variable[,] x = new Variable[data.NumItems, data.NumBins]; - for (int i = 0; i < data.NumItems; i++) + Variable[,] x = new Variable[NumItems, NumBins]; + foreach (int i in allItems) { - for (int b = 0; b < data.NumBins; b++) + foreach (int b in allBins) { x[i, b] = solver.MakeBoolVar($"x_{i}_{b}"); } } // [END variables] - // Constraints + // Constraints. // [START constraints] // Each item is assigned to at most one bin. - for (int i = 0; i < data.NumItems; ++i) + foreach (int i in allItems) { Constraint constraint = solver.MakeConstraint(0, 1, ""); - for (int b = 0; b < data.NumBins; ++b) + foreach (int b in allBins) { constraint.SetCoefficient(x[i, b], 1); } } // The amount packed in each bin cannot exceed its capacity. - for (int b = 0; b < data.NumBins; ++b) + foreach (int b in allBins) { - Constraint constraint = solver.MakeConstraint(0, data.BinCapacities[b], ""); - for (int i = 0; i < data.NumItems; ++i) + Constraint constraint = solver.MakeConstraint(0, BinCapacities[b], ""); + foreach (int i in allItems) { - constraint.SetCoefficient(x[i, b], DataModel.Weights[i]); + constraint.SetCoefficient(x[i, b], Weights[i]); } } // [END constraints] - // Objective + // Objective. // [START objective] Objective objective = solver.Objective(); - for (int i = 0; i < data.NumItems; ++i) + foreach (int i in allItems) { - for (int b = 0; b < data.NumBins; ++b) + foreach (int b in allBins) { - objective.SetCoefficient(x[i, b], DataModel.Values[i]); + objective.SetCoefficient(x[i, b], Values[i]); } } objective.SetMaximization(); @@ -99,18 +99,18 @@ public class MultipleKnapsackMip { Console.WriteLine($"Total packed value: {solver.Objective().Value()}"); double TotalWeight = 0.0; - for (int b = 0; b < data.NumBins; ++b) + foreach (int b in allBins) { double BinWeight = 0.0; double BinValue = 0.0; Console.WriteLine("Bin " + b); - for (int i = 0; i < data.NumItems; ++i) + foreach (int i in allItems) { if (x[i, b].SolutionValue() == 1) { - Console.WriteLine($"Item {i} weight: {DataModel.Weights[i]} values: {DataModel.Values[i]}"); - BinWeight += DataModel.Weights[i]; - BinValue += DataModel.Values[i]; + Console.WriteLine($"Item {i} weight: {Weights[i]} values: {Values[i]}"); + BinWeight += Weights[i]; + BinValue += Values[i]; } } Console.WriteLine("Packed bin weight: " + BinWeight); diff --git a/ortools/linear_solver/samples/MultipleKnapsackMip.java b/ortools/linear_solver/samples/MultipleKnapsackMip.java index dfe3a3e019..cec6261be8 100644 --- a/ortools/linear_solver/samples/MultipleKnapsackMip.java +++ b/ortools/linear_solver/samples/MultipleKnapsackMip.java @@ -12,7 +12,7 @@ // limitations under the License. // [START program] -// MIP example that solves a multiple knapsack problem. +// Solve a multiple knapsack problem using a MIP solver. package com.google.ortools.linearsolver.samples; // [START import] import com.google.ortools.Loader; @@ -20,24 +20,23 @@ import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; +import java.util.stream.IntStream; // [END import] /** Multiple knapsack problem. */ public class MultipleKnapsackMip { - // [START data_model] - static class DataModel { - public final double[] weights = {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}; - public final double[] values = {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}; - public final int numItems = weights.length; - public final int numBins = 5; - public final double[] binCapacities = {100, 100, 100, 100, 100}; - } - // [END data_model] - - public static void main(String[] args) throws Exception { + public static void main(String[] args) { Loader.loadNativeLibraries(); + // Instantiate the data problem. // [START data] - final DataModel data = new DataModel(); + final double[] weights = {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}; + final double[] values = {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}; + final int numItems = weights.length; + final int[] allItems = IntStream.range(0, numItems).toArray(); + + final double[] binCapacities = {100, 100, 100, 100, 100}; + final int numBins = binCapacities.length; + final int[] allBins = IntStream.range(0, numBins).toArray(); // [END data] // [START solver] @@ -51,9 +50,9 @@ public class MultipleKnapsackMip { // Variables. // [START variables] - MPVariable[][] x = new MPVariable[data.numItems][data.numBins]; - for (int i = 0; i < data.numItems; ++i) { - for (int b = 0; b < data.numBins; ++b) { + MPVariable[][] x = new MPVariable[numItems][numBins]; + for (int i : allItems) { + for (int b : allBins) { x[i][b] = solver.makeBoolVar("x_" + i + "_" + b); } } @@ -62,52 +61,52 @@ public class MultipleKnapsackMip { // Constraints. // [START constraints] // Each item is assigned to at most one bin. - for (int i = 0; i < data.numItems; ++i) { + for (int i : allItems) { MPConstraint constraint = solver.makeConstraint(0, 1, ""); - for (int b = 0; b < data.numBins; ++b) { + for (int b : allBins) { constraint.setCoefficient(x[i][b], 1); } } // The amount packed in each bin cannot exceed its capacity. - for (int b = 0; b < data.numBins; ++b) { - MPConstraint constraint = solver.makeConstraint(0, data.binCapacities[b], ""); - for (int i = 0; i < data.numItems; ++i) { - constraint.setCoefficient(x[i][b], data.weights[i]); + for (int b : allBins) { + MPConstraint constraint = solver.makeConstraint(0, binCapacities[b], ""); + for (int i : allItems) { + constraint.setCoefficient(x[i][b], weights[i]); } } // [END constraints] // Objective. // [START objective] + // Maximize total value of packed items. MPObjective objective = solver.objective(); - for (int i = 0; i < data.numItems; ++i) { - for (int b = 0; b < data.numBins; ++b) { - objective.setCoefficient(x[i][b], data.values[i]); + for (int i : allItems) { + for (int b : allBins) { + objective.setCoefficient(x[i][b], values[i]); } } objective.setMaximization(); // [END objective] // [START solve] - final MPSolver.ResultStatus resultStatus = solver.solve(); + final MPSolver.ResultStatus status = solver.solve(); // [END solve] // [START print_solution] // Check that the problem has an optimal solution. - if (resultStatus == MPSolver.ResultStatus.OPTIMAL) { + if (status == MPSolver.ResultStatus.OPTIMAL) { System.out.println("Total packed value: " + objective.value()); double totalWeight = 0; - for (int b = 0; b < data.numBins; ++b) { + for (int b : allBins) { double binWeight = 0; double binValue = 0; System.out.println("Bin " + b); - for (int i = 0; i < data.numItems; ++i) { + for (int i : allItems) { if (x[i][b].solutionValue() == 1) { - System.out.println( - "Item " + i + " weight: " + data.weights[i] + " value: " + data.values[i]); - binWeight += data.weights[i]; - binValue += data.values[i]; + System.out.println("Item " + i + " weight: " + weights[i] + " value: " + values[i]); + binWeight += weights[i]; + binValue += values[i]; } } System.out.println("Packed bin weight: " + binWeight); diff --git a/ortools/linear_solver/samples/multiple_knapsack_mip.cc b/ortools/linear_solver/samples/multiple_knapsack_mip.cc index b56166d619..5aa48fb511 100644 --- a/ortools/linear_solver/samples/multiple_knapsack_mip.cc +++ b/ortools/linear_solver/samples/multiple_knapsack_mip.cc @@ -57,8 +57,7 @@ void MultipleKnapsackMip() { num_items, std::vector(num_bins)); for (int i : all_items) { for (int b : all_bins) { - x[i][b] = solver->MakeBoolVar( - absl::StrFormat("x_%d_%d", i, b)); + x[i][b] = solver->MakeBoolVar(absl::StrFormat("x_%d_%d", i, b)); } } // [END variables] @@ -73,7 +72,6 @@ void MultipleKnapsackMip() { } solver->MakeRowConstraint(sum <= 1.0); } - // The amount packed in each bin cannot exceed its capacity. for (int b : all_bins) { LinearExpr bin_weight; @@ -111,9 +109,8 @@ void MultipleKnapsackMip() { double bin_value = 0.0; for (int i : all_items) { if (x[i][b]->solution_value() > 0) { - LOG(INFO) << "Item " << i - << " weight: " << weights[i] - << " value: " << values[i]; + LOG(INFO) << "Item " << i << " weight: " << weights[i] + << " value: " << values[i]; bin_weight += weights[i]; bin_value += values[i]; } diff --git a/ortools/linear_solver/samples/multiple_knapsack_mip.py b/ortools/linear_solver/samples/multiple_knapsack_mip.py index 6d5f272f01..3af7784cf6 100755 --- a/ortools/linear_solver/samples/multiple_knapsack_mip.py +++ b/ortools/linear_solver/samples/multiple_knapsack_mip.py @@ -18,31 +18,28 @@ from ortools.linear_solver import pywraplp # [END import] -# [START data_model] -def create_data_model(): - """Create the data for the example.""" +def main(): + # [START data] data = {} - data['weights'] = [48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36] - data['values'] = [10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25] + data['weights'] = [ + 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 + ] + data['values'] = [ + 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 + ] assert len(data['weights']) == len(data['values']) data['num_items'] = len(data['weights']) data['all_items'] = range(data['num_items']) + data['bin_capacities'] = [100, 100, 100, 100, 100] data['num_bins'] = len(data['bin_capacities']) data['all_bins'] = range(data['num_bins']) - return data -# [END data_model] - - -def main(): - # [START data] - data = create_data_model() # [END data] # Create the mip solver with the SCIP backend. # [START solver] solver = pywraplp.Solver.CreateSolver('SCIP') - if solver == None: + if solver is None: print('SCIP solver unavailable.') return # [END solver] @@ -93,7 +90,9 @@ def main(): bin_value = 0 for i in data['all_items']: if x[i, b].solution_value() > 0: - print(f"Item {i} weight: {data['weights'][i]} value: {data['values'][i]}") + print( + f"Item {i} weight: {data['weights'][i]} value: {data['values'][i]}" + ) bin_weight += data['weights'][i] bin_value += data['values'][i] print(f'Packed bin weight: {bin_weight}') diff --git a/ortools/sat/samples/MultipleKnapsackSat.cs b/ortools/sat/samples/MultipleKnapsackSat.cs index 408e2f874a..32796b7003 100644 --- a/ortools/sat/samples/MultipleKnapsackSat.cs +++ b/ortools/sat/samples/MultipleKnapsackSat.cs @@ -12,6 +12,7 @@ // limitations under the License. // [START program] +// Solves a multiple knapsack problem using the CP-SAT solver. // [START import] using System; using System.Collections.Generic; @@ -23,12 +24,14 @@ public class MultipleKnapsackSat { public static void Main(String[] args) { + // Instantiate the data problem. // [START data] - long[] Weights = { 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 }; - long[] Values = { 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 }; + int[] Weights = { 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 }; + int[] Values = { 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 }; int NumItems = Weights.Length; int[] allItems = Enumerable.Range(0, NumItems).ToArray(); - long[] BinCapacities = { 100, 100, 100, 100, 100 }; + + int[] BinCapacities = { 100, 100, 100, 100, 100 }; int NumBins = BinCapacities.Length; int[] allBins = Enumerable.Range(0, NumBins).ToArray(); // [END data] @@ -38,25 +41,25 @@ public class MultipleKnapsackSat CpModel model = new CpModel(); // [END model] - // Variables + // Variables. // [START variables] IntVar[,] x = new IntVar[NumItems, NumBins]; - for (int i = 0; i < NumItems; ++i) + foreach (int i in allItems) { - for (int j = 0; j < NumBins; ++j) + foreach (int b in allBins) { - x[i, j] = model.NewBoolVar($"x_{i}_{j}"); + x[i, b] = model.NewBoolVar($"x_{i}_{b}"); } } // [END variables] - // Constraints + // Constraints. // [START constraints] // Each item is assigned to at most one bin. - for (int i = 0; i < NumItems; ++i) + foreach (int i in allItems) { IntVar[] vars = new IntVar[NumBins]; - for (int b = 0; b < NumBins; ++b) + foreach (int b in allBins) { vars[b] = x[i, b]; } @@ -64,36 +67,35 @@ public class MultipleKnapsackSat } // The amount packed in each bin cannot exceed its capacity. - for (int b = 0; b < NumBins; ++b) + foreach (int b in allBins) { - LinearExpr[] exprs = new LinearExpr[NumItems]; - for (int i = 0; i < NumItems; ++i) + LinearExpr[] binWeights = new LinearExpr[NumItems]; + foreach (int i in allItems) { - exprs[i] = LinearExpr.Affine(x[i, b], /*coeff=*/Weights[i], /*offset=*/0); + binWeights[i] = LinearExpr.Term(x[i, b], /*coeff=*/Weights[i]); } - model.Add(LinearExpr.Sum(exprs) <= 1); + model.Add(LinearExpr.Sum(binWeights) <= 1); } // [END constraints] - // Objective + // Objective. // [START objective] - LinearExpr[] obj = new LinearExpr[NumItems * NumBins]; - for (int i = 0; i < NumItems; ++i) + LinearExpr[] objective = new LinearExpr[NumItems * NumBins]; + foreach (int i in allItems) { - for (int b = 0; b < NumBins; ++b) + foreach (int b in allBins) { int k = i * NumBins + b; - obj[i] = LinearExpr.Affine(x[i, b], /*coeff=*/Values[i], /*offset=*/0); + objective[k] = LinearExpr.Term(x[i, b], /*coeff=*/Values[i]); } } - model.Maximize(LinearExpr.Sum(obj)); + model.Maximize(LinearExpr.Sum(objective)); // [END objective] // Solve // [START solve] CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); - Console.WriteLine($"Solve status: {status}"); // [END solve] // Print solution. @@ -103,12 +105,12 @@ public class MultipleKnapsackSat { Console.WriteLine($"Total packed value: {solver.ObjectiveValue}"); double TotalWeight = 0.0; - for (int b = 0; b < NumBins; ++b) + foreach (int b in allBins) { double BinWeight = 0.0; double BinValue = 0.0; Console.WriteLine($"Bin {b}"); - for (int i = 0; i < NumItems; ++i) + foreach (int i in allItems) { if (solver.Value(x[i, b]) == 1) { @@ -137,5 +139,4 @@ public class MultipleKnapsackSat // [END statistics] } } - // [END program] diff --git a/ortools/sat/samples/MultipleKnapsackSat.java b/ortools/sat/samples/MultipleKnapsackSat.java index 9db6300f90..cd4e6f3689 100644 --- a/ortools/sat/samples/MultipleKnapsackSat.java +++ b/ortools/sat/samples/MultipleKnapsackSat.java @@ -12,6 +12,7 @@ // limitations under the License. // [START program] +// Solves a multiple knapsack problem using the CP-SAT solver. package com.google.ortools.sat.samples; // [START import] import com.google.ortools.Loader; @@ -20,118 +21,105 @@ import com.google.ortools.sat.CpSolver; import com.google.ortools.sat.CpSolverStatus; import com.google.ortools.sat.IntVar; import com.google.ortools.sat.LinearExpr; +import java.util.stream.IntStream; // [END import] /** Sample showing how to solve a multiple knapsack problem. */ public class MultipleKnapsackSat { - // [START data] - static class DataModel { - int[] items = new int[] {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}; - int[] values = new int[] {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}; - int[] binCapacities = new int[] {100, 100, 100, 100, 100}; - int numItems = items.length; - int numBins = 5; - } - // [END data] - - // [START solution_printer] - static void printSolution( - DataModel data, CpSolver solver, IntVar[][] x, IntVar[] load, IntVar[] value) { - System.out.printf("Optimal objective value: %f%n", solver.objectiveValue()); - System.out.println(); - long packedWeight = 0; - long packedValue = 0; - for (int b = 0; b < data.numBins; ++b) { - System.out.println("Bin " + b); - for (int i = 0; i < data.numItems; ++i) { - if (solver.value(x[i][b]) > 0) { - System.out.println( - "Item " + i + " - Weight: " + data.items[i] + " Value: " + data.values[i]); - } - } - System.out.println("Packed bin weight: " + solver.value(load[b])); - packedWeight = packedWeight + solver.value(load[b]); - System.out.println("Packed bin value: " + solver.value(value[b]) + "\n"); - packedValue = packedValue + solver.value(value[b]); - } - System.out.println("Total packed weight: " + packedWeight); - System.out.println("Total packed value: " + packedValue); - } - public static void main(String[] args) { Loader.loadNativeLibraries(); // Instantiate the data problem. // [START data] - final DataModel data = new DataModel(); + final int[] weights = {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}; + final int[] values = {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}; + final int numItems = weights.length; + final int[] allItems = IntStream.range(0, numItems).toArray(); + + final int[] binCapacities = {100, 100, 100, 100, 100}; + final int numBins = binCapacities.length; + final int[] allBins = IntStream.range(0, numBins).toArray(); // [END data] - int totalValue = 0; - for (int i = 0; i < data.numItems; ++i) { - totalValue = totalValue + data.values[i]; - } // [START model] CpModel model = new CpModel(); // [END model] + // Variables. // [START variables] - IntVar[][] x = new IntVar[data.numItems][data.numBins]; - for (int i = 0; i < data.numItems; ++i) { - for (int b = 0; b < data.numBins; ++b) { - x[i][b] = model.newIntVar(0, 1, "x_" + i + "_" + b); + IntVar[][] x = new IntVar[numItems][numBins]; + for (int i : allItems) { + for (int b : allBins) { + x[i][b] = model.newBoolVar("x_" + i + "_" + b); } } - // Main variables. - // Load and value variables. - IntVar[] load = new IntVar[data.numBins]; - IntVar[] value = new IntVar[data.numBins]; - for (int b = 0; b < data.numBins; ++b) { - load[b] = model.newIntVar(0, data.binCapacities[b], "load_" + b); - value[b] = model.newIntVar(0, totalValue, "value_" + b); - } - - // Links load and value with x. - int[] sizes = new int[data.numItems]; - for (int i = 0; i < data.numItems; ++i) { - sizes[i] = data.items[i]; - } - for (int b = 0; b < data.numBins; ++b) { - IntVar[] vars = new IntVar[data.numItems]; - for (int i = 0; i < data.numItems; ++i) { - vars[i] = x[i][b]; - } - model.addEquality(LinearExpr.scalProd(vars, data.items), load[b]); - model.addEquality(LinearExpr.scalProd(vars, data.values), value[b]); - } // [END variables] + // Constraints. // [START constraints] - // Each item can be in at most one bin. - // Place all items. - for (int i = 0; i < data.numItems; ++i) { - IntVar[] vars = new IntVar[data.numBins]; - for (int b = 0; b < data.numBins; ++b) { + // Each item is assigned to at most one bin. + for (int i : allItems) { + IntVar[] vars = new IntVar[numBins]; + for (int b : allBins) { vars[b] = x[i][b]; } model.addLessOrEqual(LinearExpr.sum(vars), 1); } + + // The amount packed in each bin cannot exceed its capacity. + for (int b : allBins) { + IntVar[] binWeights = new IntVar[numItems]; + for (int i : allItems) { + binWeights[i] = LinearExpr.term(x[i][b], weights[i]); + } + model.addLessOrEqual(LinearExpr.sum(binWeights), 1); + } // [END constraints] - // Maximize sum of load. + + // Objective. // [START objective] - model.maximize(LinearExpr.sum(value)); + // Maximize total value of packed items. + IntVar[] objective = new IntVar[numItems * numBins]; + for (int i : allItems) { + for (int b : allBins) { + int k = i * numBins + b; + objective[k] = LinearExpr.term(x[i][b], values[i]); + } + } + model.maximize(LinearExpr.sum(objective)); // [END objective] // [START solve] CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.solve(model); + final CpSolverStatus status = solver.solve(model); // [END solve] // [START print_solution] - System.out.println("Solve status: " + status); + // Check that the problem has an optimal solution. if (status == CpSolverStatus.OPTIMAL) { - printSolution(data, solver, x, load, value); + System.out.println("Total packed value: " + solver.objectiveValue()); + long totalWeight = 0; + for (int b : allBins) { + long binWeight = 0; + long binValue = 0; + System.out.println("Bin " + b); + for (int i : allItems) { + if (solver.value(x[i][b]) > 0) { + System.out.println("Item " + i + " weight: " + weights[i] + " value: " + values[i]); + binWeight += weights[i]; + binValue += values[i]; + } + } + System.out.println("Packed bin weight: " + binWeight); + System.out.println("Packed bin value: " + binValue); + totalWeight += binWeight; + } + System.out.println("Total packed weight: " + totalWeight); + } else { + System.err.println("The problem does not have an optimal solution."); } // [END print_solution] } private MultipleKnapsackSat() {} } +// [END program] diff --git a/ortools/sat/samples/multiple_knapsack_sat.cc b/ortools/sat/samples/multiple_knapsack_sat.cc index 8e8b161bdf..3fe0cd013e 100644 --- a/ortools/sat/samples/multiple_knapsack_sat.cc +++ b/ortools/sat/samples/multiple_knapsack_sat.cc @@ -12,6 +12,7 @@ // limitations under the License. // [START program] +// Solves a multiple knapsack problem using the CP-SAT solver. // [START import] #include #include @@ -31,13 +32,12 @@ void MultipleKnapsackSat() { {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}}; const std::vector values = { {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}}; - const int total_value = std::accumulate(values.begin(), values.end(), 0); - const int num_items = weights.size(); + const int num_items = static_cast(weights.size()); std::vector all_items(num_items); std::iota(all_items.begin(), all_items.end(), 0); const std::vector bin_capacities = {{100, 100, 100, 100, 100}}; - const int num_bins = bin_capacities.size(); + const int num_bins = static_cast(bin_capacities.size()); std::vector all_bins(num_bins); std::iota(all_bins.begin(), all_bins.end(), 0); // [END data] @@ -53,18 +53,9 @@ void MultipleKnapsackSat() { for (int i : all_items) { for (int b : all_bins) { auto key = std::make_tuple(i, b); - x[key] = cp_model.NewBoolVar().WithName( - absl::StrFormat("x_%d_%d", i, b)); + x[key] = cp_model.NewBoolVar().WithName(absl::StrFormat("x_%d_%d", i, b)); } } - - // Load variables. - std::vector load(num_bins); - std::vector value(num_bins); - for (int b : all_bins) { - load[b] = cp_model.NewIntVar({0, bin_capacities[b]}); - value[b] = cp_model.NewIntVar({0, total_value}); - } // [END variables] // Constraints. @@ -119,15 +110,14 @@ void MultipleKnapsackSat() { for (int i : all_items) { auto key = std::make_tuple(i, b); if (SolutionIntegerValue(response, x[key]) > 0) { - LOG(INFO) << "Item " << i - << " weight: " << weights[i] - << " value: " << values[i]; + LOG(INFO) << "Item " << i << " weight: " << weights[i] + << " value: " << values[i]; bin_weight += weights[i]; bin_value += values[i]; } } LOG(INFO) << "Packed bin weight: " << bin_weight; - LOG(INFO) << "Packed bin value: " << bin_value; + LOG(INFO) << "Packed bin value: " << bin_value; total_weight += bin_weight; } LOG(INFO) << "Total packed weight: " << total_weight; diff --git a/ortools/sat/samples/multiple_knapsack_sat.py b/ortools/sat/samples/multiple_knapsack_sat.py index a56e81a606..36166203b3 100755 --- a/ortools/sat/samples/multiple_knapsack_sat.py +++ b/ortools/sat/samples/multiple_knapsack_sat.py @@ -18,25 +18,22 @@ from ortools.sat.python import cp_model # [END import] -# [START data_model] -def create_data_model(): - """Create the data for the example.""" +def main(): + # [START data] data = {} - data['weights'] = [48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36] - data['values'] = [10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25] + data['weights'] = [ + 48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36 + ] + data['values'] = [ + 10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25 + ] assert len(data['weights']) == len(data['values']) data['num_items'] = len(data['weights']) data['all_items'] = range(data['num_items']) + data['bin_capacities'] = [100, 100, 100, 100, 100] data['num_bins'] = len(data['bin_capacities']) data['all_bins'] = range(data['num_bins']) - return data -# [END data_model] - - -def main(): - # [START data] - data = create_data_model() # [END data] # [START model] @@ -71,7 +68,8 @@ def main(): objective = [] for i in data['all_items']: for b in data['all_bins']: - objective.append(cp_model.LinearExpr.Term(x[i, b], data['values'][i])) + objective.append( + cp_model.LinearExpr.Term(x[i, b], data['values'][i])) model.Maximize(cp_model.LinearExpr.Sum(objective)) # [END objective] @@ -90,7 +88,9 @@ def main(): bin_value = 0 for i in data['all_items']: if solver.Value(x[i, b]) > 0: - print(f"Item {i} weight: {data['weights'][i]} value: {data['values'][i]}") + print( + f"Item {i} weight: {data['weights'][i]} value: {data['values'][i]}" + ) bin_weight += data['weights'][i] bin_value += data['values'][i] print(f'Packed bin weight: {bin_weight}')