From 41771355367f1091b996e538f1b08acac17daed4 Mon Sep 17 00:00:00 2001 From: Corentin Le Molgat Date: Fri, 10 May 2019 22:51:10 +0200 Subject: [PATCH] Add knapsack sample --- makefiles/Makefile.cpp.mk | 1 + makefiles/Makefile.dotnet.mk | 3 +- makefiles/Makefile.java.mk | 4 +- makefiles/Makefile.python.mk | 3 +- ortools/algorithms/samples/Knapsack.cs | 57 +++++++++++++ ortools/algorithms/samples/Knapsack.csproj | 22 +++++ .../algorithms/samples}/Knapsack.java | 27 ++++-- ortools/algorithms/samples/knapsack.cc | 85 +++++++++++++++++++ .../algorithms/samples}/knapsack.py | 31 +++++-- 9 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 ortools/algorithms/samples/Knapsack.cs create mode 100644 ortools/algorithms/samples/Knapsack.csproj rename {examples/java => ortools/algorithms/samples}/Knapsack.java (70%) create mode 100644 ortools/algorithms/samples/knapsack.cc rename {examples/python => ortools/algorithms/samples}/knapsack.py (71%) diff --git a/makefiles/Makefile.cpp.mk b/makefiles/Makefile.cpp.mk index fc331aaa98..0826736a18 100755 --- a/makefiles/Makefile.cpp.mk +++ b/makefiles/Makefile.cpp.mk @@ -345,6 +345,7 @@ rcc_%: $(BIN_DIR)/%$E FORCE .PHONY: test_cc_algorithms_samples # Build and Run all C++ Algorithms Samples (located in ortools/algorithms/samples) test_cc_algorithms_samples: \ + rcc_knapsack \ rcc_simple_knapsack_program .PHONY: test_cc_graph_samples # Build and Run all C++ Graph Samples (located in ortools/graph/samples) diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk index d28ed4498c..3edcfff8e4 100644 --- a/makefiles/Makefile.dotnet.mk +++ b/makefiles/Makefile.dotnet.mk @@ -459,7 +459,8 @@ endif ## .NET Examples/Samples ## ############################# .PHONY: test_dotnet_algorithms_samples # Build and Run all .Net LP Samples (located in ortools/algorithms/samples) -test_dotnet_algorithms_samples: ; +test_dotnet_algorithms_samples: + $(MAKE) run SOURCE=ortools/algorithms/samples/Knapsack.cs .PHONY: test_dotnet_constraint_solver_samples # Build and Run all .Net CP Samples (located in ortools/constraint_solver/samples) test_dotnet_constraint_solver_samples: diff --git a/makefiles/Makefile.java.mk b/makefiles/Makefile.java.mk index d62bfbfb83..c26ba72ca8 100755 --- a/makefiles/Makefile.java.mk +++ b/makefiles/Makefile.java.mk @@ -396,6 +396,7 @@ rjava_%: $(LIB_DIR)/%$J FORCE .PHONY: test_java_algorithms_samples # Build and Run all Java Algorithms Samples (located in ortools/algorithms/samples) test_java_algorithms_samples: \ + rjava_Knapsack .PHONY: test_java_constraint_solver_samples # Build and Run all Java CP Samples (located in ortools/constraint_solver/samples) test_java_constraint_solver_samples: \ @@ -457,8 +458,7 @@ check_java_pimpl: \ test_java_sat_samples \ \ rjava_LinearProgramming \ - rjava_IntegerProgramming \ - rjava_Knapsack + rjava_IntegerProgramming .PHONY: test_java_tests # Build and Run all Java Tests (located in examples/tests) test_java_tests: \ diff --git a/makefiles/Makefile.python.mk b/makefiles/Makefile.python.mk index 2b548e0420..7cb57211c7 100755 --- a/makefiles/Makefile.python.mk +++ b/makefiles/Makefile.python.mk @@ -541,6 +541,7 @@ rpy_%: ortools/sat/samples/%.py $(PYTHON_OR_TOOLS_LIBS) FORCE .PHONY: test_python_algorithms_samples # Run all Python Algorithms Samples (located in ortools/algorithms/samples) test_python_algorithms_samples: \ + rpy_knapsack \ rpy_simple_knapsack_program .PHONY: test_python_constraint_solver_samples # Run all Python CP Samples (located in ortools/constraint_solver/samples) @@ -620,7 +621,6 @@ check_python_pimpl: \ # rpy_nqueens_cp \ # rpy_nqueens_sat \ # rpy_integer_programming \ -# rpy_knapsack \ # rpy_max_flow \ # rpy_min_cost_flow \ # rpy_assignment \ @@ -783,7 +783,6 @@ test_python_python: \ rpy_jobshop_ft06_distance_sat \ rpy_jobshop_ft06_sat \ rpy_jobshop_with_maintenance_sat \ - rpy_knapsack \ rpy_linear_assignment_api \ rpy_linear_programming \ rpy_magic_sequence_distribute \ diff --git a/ortools/algorithms/samples/Knapsack.cs b/ortools/algorithms/samples/Knapsack.cs new file mode 100644 index 0000000000..127b938094 --- /dev/null +++ b/ortools/algorithms/samples/Knapsack.cs @@ -0,0 +1,57 @@ +// 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] +using System; +using Google.OrTools.Algorithms; +// [END import] + +public class Knapsack +{ + static void Main() + { + // [START solver] + KnapsackSolver solver = new KnapsackSolver( + KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, "test"); + // [END solver] + + // [START data] + long[] values = { 360, 83, 59, 130, 431, 67, 230, 52, 93, + 125, 670, 892, 600, 38, 48, 147, 78, 256, + 63, 17, 120, 164, 432, 35, 92, 110, 22, + 42, 50, 323, 514, 28, 87, 73, 78, 15, + 26, 78, 210, 36, 85, 189, 274, 43, 33, + 10, 19, 389, 276, 312 }; + + long[,] weights = { { 7, 0, 30, 22, 80, 94, 11, 81, 70, + 64, 59, 18, 0, 36, 3, 8, 15, 42, + 9, 0, 42, 47, 52, 32, 26, 48, 55, + 6, 29, 84, 2, 4, 18, 56, 7, 29, + 93, 44, 71, 3, 86, 66, 31, 65, 0, + 79, 20, 65, 52, 13 } }; + + long[] capacities = { 850 }; + // [END data] + + // [START print_solution] + Console.WriteLine("Solving knapsack with " + values.Length + + " items, and " + weights.GetLength(0) + " dimension"); + solver.Init(values, weights, capacities); + long computedValue = solver.Solve(); + + Console.WriteLine("Optimal Value = " + computedValue); + // [END print_solution] + } +} +// [END program] diff --git a/ortools/algorithms/samples/Knapsack.csproj b/ortools/algorithms/samples/Knapsack.csproj new file mode 100644 index 0000000000..4750287526 --- /dev/null +++ b/ortools/algorithms/samples/Knapsack.csproj @@ -0,0 +1,22 @@ + + + Exe + 7.2 + netcoreapp2.1 + false + ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json + Google.OrTools.Knapsack + true + + + + full + true + true + + + + + + + diff --git a/examples/java/Knapsack.java b/ortools/algorithms/samples/Knapsack.java similarity index 70% rename from examples/java/Knapsack.java rename to ortools/algorithms/samples/Knapsack.java index aa23413b24..acdea5376c 100644 --- a/examples/java/Knapsack.java +++ b/ortools/algorithms/samples/Knapsack.java @@ -11,22 +11,30 @@ // See the License for the specific language governing permissions and // limitations under the License. +// [START program] +// [START import] +package com.google.ortools.samples; + import com.google.ortools.algorithms.KnapsackSolver; +// [END import] /** * Sample showing how to model using the knapsack solver. * */ - public class Knapsack { static { System.loadLibrary("jniortools"); } private static void solve() { + // [START solver] KnapsackSolver solver = new KnapsackSolver( KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, "test"); - final long[] profits = {360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, 38, 48, 147, + // [END solver] + + // [START data] + final long[] values = {360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, 38, 48, 147, 78, 256, 63, 17, 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, 514, 28, 87, 73, 78, 15, 26, 78, 210, 36, 85, 189, 274, 43, 33, 10, 19, 389, 276, 312}; @@ -35,18 +43,23 @@ public class Knapsack { 65, 0, 79, 20, 65, 52, 13}}; final long[] capacities = {850}; + // [END data] - final long optimalProfit = 7534; - System.out.println("Solving knapsack with " + profits.length + " items"); + // [START solve] + solver.init(values, weights, capacities); - solver.init(profits, weights, capacities); + final long computedValue = solver.solve(); + // [END solve] - final long computedProfit = solver.solve(); + // [START print_solution] + System.out.println("Solving knapsack with " + values.length + " items"); - System.out.println("Optimal_Profit = " + computedProfit + "/" + optimalProfit); + System.out.println("Optimal Value = " + computedValue); + // [END print_solution] } public static void main(String[] args) throws Exception { Knapsack.solve(); } } +// [END program] diff --git a/ortools/algorithms/samples/knapsack.cc b/ortools/algorithms/samples/knapsack.cc new file mode 100644 index 0000000000..9c398fd55d --- /dev/null +++ b/ortools/algorithms/samples/knapsack.cc @@ -0,0 +1,85 @@ +// 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 +#include +#include + +#include "ortools/algorithms/knapsack_solver.h" +// [END import] + +namespace operations_research { +void RunKnapsackExample() { + // Instantiate the solver. + // [START solver] + KnapsackSolver solver( + KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, + "KnapsackExample"); + // [END solver] + + // [START data] + std::vector values = { + 360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, + 38, 48, 147, 78, 256, 63, 17, 120, 164, 432, 35, 92, 110, + 22, 42, 50, 323, 514, 28, 87, 73, 78, 15, 26, 78, 210, + 36, 85, 189, 274, 43, 33, 10, 19, 389, 276, 312}; + + std::vector> weights = { + {7, 0, 30, 22, 80, 94, 11, 81, 70, 64, 59, 18, 0, 36, 3, 8, 15, + 42, 9, 0, 42, 47, 52, 32, 26, 48, 55, 6, 29, 84, 2, 4, 18, 56, + 7, 29, 93, 44, 71, 3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13}}; + + std::vector capacities = {850}; + // [START solve] + solver.Init(values, weights, capacities); + int64 computed_value = solver.Solve(); + // [END solve] + + // Print solution + // [START print_solution] + std::vector packed_items; + for (std::size_t i = 0; i < values.size(); ++i) { + if (solver.BestSolutionContains(i)) packed_items.push_back(i); + } + std::ostringstream packed_items_ss; + std::copy(packed_items.begin(), packed_items.end() - 1, + std::ostream_iterator(packed_items_ss, ", ")); + packed_items_ss << packed_items.back(); + + std::vector packed_weights; + packed_weights.reserve(packed_items.size()); + for (const auto &it : packed_items) { + packed_weights.push_back(weights[0][it]); + } + std::ostringstream packed_weights_ss; + std::copy(packed_weights.begin(), packed_weights.end() - 1, + std::ostream_iterator(packed_weights_ss, ", ")); + packed_weights_ss << packed_weights.back(); + + int64 total_weights = + std::accumulate(packed_weights.begin(), packed_weights.end(), 0LL); + + LOG(INFO) << "Total value: " << computed_value; + LOG(INFO) << "Packed items: {" << packed_items_ss.str() << "}"; + LOG(INFO) << "Total weight: " << total_weights; + LOG(INFO) << "Packed weights: {" << packed_weights_ss.str() << "}"; + // [END print_solution] +} +} // namespace operations_research + +int main(int argc, char **argv) { + operations_research::RunKnapsackExample(); + return EXIT_SUCCESS; +} diff --git a/examples/python/knapsack.py b/ortools/algorithms/samples/knapsack.py similarity index 71% rename from examples/python/knapsack.py rename to ortools/algorithms/samples/knapsack.py index cb4adaac07..b5656f09ae 100644 --- a/examples/python/knapsack.py +++ b/ortools/algorithms/samples/knapsack.py @@ -10,17 +10,25 @@ # 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. -"""Bi-dimensional knapsack problem.""" +# [START program] +"""A simple knapsack problem.""" +# [START import] +from __future__ import print_function from ortools.algorithms import pywrapknapsack_solver +# [END import] def main(): # Create the solver. + # [START solver] solver = pywrapknapsack_solver.KnapsackSolver( - pywrapknapsack_solver.KnapsackSolver. - KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, 'test') - profits = [ + pywrapknapsack_solver.KnapsackSolver.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, + 'KnapsackExample') + # [END solver] + + # [START data] + values = [ 360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, 38, 48, 147, 78, 256, 63, 17, 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, 514, 28, 87, 73, 78, 15, 26, 78, 210, 36, 85, 189, 274, 43, 33, 10, 19, 389, 276, @@ -32,13 +40,18 @@ def main(): 3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13 ]] capacities = [850] - optimal_profit = 7534 - solver.Init(profits, weights, capacities) - computed_profit = solver.Solve() + # [END data] - print(( - 'optimal profit = ' + str(computed_profit) + '/' + str(optimal_profit))) + # [START solver] + solver.Init(values, weights, capacities) + computed_profit = solver.Solve() + # [END solver] + + # [START solve] + print('optimal profit = ' + str(computed_profit)) + # [END solve] if __name__ == '__main__': main() +# [END program]