From 0f7551551ff408fcabbabf7a615821ce829852dd Mon Sep 17 00:00:00 2001 From: Corentin Le Molgat Date: Mon, 26 Nov 2018 17:30:10 +0100 Subject: [PATCH] Add Samples from g3 --- makefiles/Makefile.cpp.mk | 7 +- makefiles/Makefile.dotnet.mk | 2 + makefiles/Makefile.java.mk | 3 +- makefiles/Makefile.python.mk | 7 +- .../samples/simple_knapsack_program.cc | 81 +++++++++++++++++ .../samples/simple_knapsack_program.py | 58 ++++++++++++ ortools/graph/samples/SimpleMaxFlowProgram.cs | 73 +++++++++++++++ .../graph/samples/SimpleMaxFlowProgram.csproj | 20 ++++ .../graph/samples/SimpleMinCostFlowProgram.cs | 87 ++++++++++++++++++ .../samples/SimpleMinCostFlowProgram.csproj | 20 ++++ .../graph/samples/simple_max_flow_program.cc | 70 ++++++++++++++ .../graph/samples/simple_max_flow_program.py | 62 +++++++++++++ .../samples/simple_min_cost_flow_program.cc | 82 +++++++++++++++++ .../samples/simple_min_cost_flow_program.py | 74 +++++++++++++++ .../samples/LinearProgrammingExample.java | 86 ++++++++++++++++++ .../samples/SimpleLpProgram.java | 5 +- .../samples/SimpleMipProgram.java | 5 +- .../samples/integer_programming_example.cc | 91 +++++++++++++++++++ .../samples/integer_programming_example.py | 79 ++++++++++++++++ .../samples/linear_programming_example.cc | 81 +++++++++++++++++ .../samples/linear_programming_example.py | 79 ++++++++++++++++ 21 files changed, 1065 insertions(+), 7 deletions(-) create mode 100644 ortools/algorithms/samples/simple_knapsack_program.cc create mode 100644 ortools/algorithms/samples/simple_knapsack_program.py create mode 100644 ortools/graph/samples/SimpleMaxFlowProgram.cs create mode 100644 ortools/graph/samples/SimpleMaxFlowProgram.csproj create mode 100644 ortools/graph/samples/SimpleMinCostFlowProgram.cs create mode 100644 ortools/graph/samples/SimpleMinCostFlowProgram.csproj create mode 100644 ortools/graph/samples/simple_max_flow_program.cc create mode 100644 ortools/graph/samples/simple_max_flow_program.py create mode 100644 ortools/graph/samples/simple_min_cost_flow_program.cc create mode 100644 ortools/graph/samples/simple_min_cost_flow_program.py create mode 100644 ortools/linear_solver/samples/LinearProgrammingExample.java create mode 100644 ortools/linear_solver/samples/integer_programming_example.cc create mode 100644 ortools/linear_solver/samples/integer_programming_example.py create mode 100644 ortools/linear_solver/samples/linear_programming_example.cc create mode 100644 ortools/linear_solver/samples/linear_programming_example.py diff --git a/makefiles/Makefile.cpp.mk b/makefiles/Makefile.cpp.mk index b548a41360..04968bf85f 100755 --- a/makefiles/Makefile.cpp.mk +++ b/makefiles/Makefile.cpp.mk @@ -328,14 +328,19 @@ 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_simple_knapsack_program .PHONY: test_cc_graph_samples # Build and Run all C++ Graph Samples (located in ortools/graph/samples) test_cc_graph_samples: \ + rcc_simple_max_flow_program \ + rcc_simple_min_cost_flow_program .PHONY: test_cc_linear_solver_samples # Build and Run all C++ LP Samples (located in ortools/linear_solver/samples) test_cc_linear_solver_samples: \ rcc_simple_lp_program \ - rcc_simple_mip_program + rcc_simple_mip_program \ + rcc_linear_programming_example \ + rcc_integer_programming_example .PHONY: test_cc_constraint_solver_samples # Build and Run all C++ CP Samples (located in ortools/constraint_solver/samples) test_cc_constraint_solver_samples: \ diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk index 97ad7b8184..154f675ae1 100644 --- a/makefiles/Makefile.dotnet.mk +++ b/makefiles/Makefile.dotnet.mk @@ -500,6 +500,8 @@ test_dotnet_algorithms_samples: ; .PHONY: test_dotnet_graph_samples # Build and Run all .Net LP Samples (located in ortools/graph/samples) test_dotnet_graph_samples: ; + $(MAKE) run SOURCE=ortools/graph/samples/SimpleMaxFlowProgram.cs + $(MAKE) run SOURCE=ortools/graph/samples/SimpleMinCostFlowProgram.cs .PHONY: test_dotnet_linear_solver_samples # Build and Run all .Net LP Samples (located in ortools/linear_solver/samples) test_dotnet_linear_solver_samples: diff --git a/makefiles/Makefile.java.mk b/makefiles/Makefile.java.mk index b816fef89b..c5f400a933 100755 --- a/makefiles/Makefile.java.mk +++ b/makefiles/Makefile.java.mk @@ -356,7 +356,8 @@ test_java_graph_samples: \ .PHONY: test_java_linear_solver_samples # Build and Run all Java LP Samples (located in ortools/linear_solver/samples) test_java_linear_solver_samples: \ rjava_SimpleLpProgram \ - rjava_SimpleMipProgram + rjava_SimpleMipProgram \ + rjava_LinearProgrammingExample .PHONY: test_java_sat_samples # Build and Run all Java SAT Samples (located in ortools/sat/samples) test_java_sat_samples: \ diff --git a/makefiles/Makefile.python.mk b/makefiles/Makefile.python.mk index e0fdbf4cef..60b1c1d86a 100755 --- a/makefiles/Makefile.python.mk +++ b/makefiles/Makefile.python.mk @@ -493,14 +493,19 @@ 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_simple_knapsack_program .PHONY: test_python_graph_samples # Run all Python Graph Samples (located in ortools/graph/samples) test_python_graph_samples: \ + rpy_simple_max_flow_program \ + rpy_simple_min_cost_flow_program .PHONY: test_python_linear_solver_samples # Run all Python LP Samples (located in ortools/linear_solver/samples) test_python_linear_solver_samples: \ rpy_simple_lp_program \ - rpy_simple_mip_program + rpy_simple_mip_program \ + rpy_linear_programming_example \ + rpy_integer_programming_example .PHONY: test_python_sat_samples # Run all Python Sat Samples (located in ortools/sat/samples) test_python_sat_samples: \ diff --git a/ortools/algorithms/samples/simple_knapsack_program.cc b/ortools/algorithms/samples/simple_knapsack_program.cc new file mode 100644 index 0000000000..56f2382bb9 --- /dev/null +++ b/ortools/algorithms/samples/simple_knapsack_program.cc @@ -0,0 +1,81 @@ +// 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 { +namespace algorithms { + +void SimpleKnapsackProgram() { + // [START solver] + KnapsackSolver solver(KnapsackSolver::KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER, + "SimpleKnapsackExample"); + // [END solver] + + // [START data] + std::vector> weights = {{565, 406, 194, 130, 435, 367, 230, + 315, 393, 125, 670, 892, 600, 293, + 712, 147, 421, 255}}; + std::vector capacities = {850}; + std::vector values = weights[0]; + // [END data] + + // [START solve] + solver.Init(values, weights, capacities); + int64 computed_value = solver.Solve(); + // [END solve] + + // [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 algorithms +} // namespace operations_research + +int main() { + operations_research::algorithms::SimpleKnapsackProgram(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/algorithms/samples/simple_knapsack_program.py b/ortools/algorithms/samples/simple_knapsack_program.py new file mode 100644 index 0000000000..15b00f862f --- /dev/null +++ b/ortools/algorithms/samples/simple_knapsack_program.py @@ -0,0 +1,58 @@ +# 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] +"""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_DYNAMIC_PROGRAMMING_SOLVER, "test") + # [END solver] + + # [START data] + weights = [[ + 565, 406, 194, 130, 435, 367, 230, 315, 393, 125, 670, 892, 600, 293, + 712, 147, 421, 255 + ]] + capacities = [850] + values = weights[0] + # [END data] + + # [START solve] + solver.Init(values, weights, capacities) + computed_value = solver.Solve() + # [END solve] + + # [START print_solution] + packed_items = [ + x for x in range(0, len(weights[0])) if solver.BestSolutionContains(x) + ] + packed_weights = [weights[0][i] for i in packed_items] + + print("Packed items: ", packed_items) + print("Packed weights: ", packed_weights) + print("Total weight (same as total value): ", computed_value) + # [END print_solution] + + +if __name__ == "__main__": + main() +# [END program] diff --git a/ortools/graph/samples/SimpleMaxFlowProgram.cs b/ortools/graph/samples/SimpleMaxFlowProgram.cs new file mode 100644 index 0000000000..117e9eaf56 --- /dev/null +++ b/ortools/graph/samples/SimpleMaxFlowProgram.cs @@ -0,0 +1,73 @@ +// 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] +using System; +using Google.OrTools.Graph; + +public class SimpleMaxFlowProgram +{ + static void Main() + { + // [START data] + // Define three parallel arrays: start_nodes, end_nodes, and the capacities + // between each pair. For instance, the arc from node 0 to node 1 has a + // capacity of 20. + // From Taha's 'Introduction to Operations Research', + // example 6.4-2. + int[] startNodes = {0, 0, 0, 1, 1, 2, 2, 3, 3}; + int[] endNodes = {1, 2, 3, 2, 4, 3, 4, 2, 4}; + int[] capacities = {20, 30, 10, 40, 30, 10, 20, 5, 20}; + // [END data] + + // [START constraints] + // Instantiate a SimpleMaxFlow solver. + MaxFlow maxFlow = new MaxFlow(); + + // Add each arc. + for (int i = 0; i < startNodes.Length; ++i) + { + int arc = maxFlow.AddArcWithCapacity(startNodes[i], endNodes[i], + capacities[i]); + if (arc != i) throw new Exception("Internal error"); + } + // [END constraints] + + // [START solve] + // Find the maximum flow between node 0 and node 4. + int solveStatus = maxFlow.Solve(0, 4); + // [END solve] + + // [START print_solution] + if (solveStatus == MaxFlow.OPTIMAL) + { + Console.WriteLine("Max. flow: " + maxFlow.OptimalFlow()); + Console.WriteLine(""); + Console.WriteLine(" Arc Flow / Capacity"); + for (int i = 0; i < maxFlow.NumArcs(); ++i) + { + Console.WriteLine(maxFlow.Tail(i) + " -> " + + maxFlow.Head(i) + " " + + string.Format("{0,3}", maxFlow.Flow(i)) + " / " + + string.Format("{0,3}", maxFlow.Capacity(i))); + } + } + else + { + Console.WriteLine("Solving the max flow problem failed. Solver status: " + + solveStatus); + } + // [END print_solution] + } +} +// [END program] diff --git a/ortools/graph/samples/SimpleMaxFlowProgram.csproj b/ortools/graph/samples/SimpleMaxFlowProgram.csproj new file mode 100644 index 0000000000..63eda95d4b --- /dev/null +++ b/ortools/graph/samples/SimpleMaxFlowProgram.csproj @@ -0,0 +1,20 @@ + + + Exe + 7.2 + netcoreapp2.1 + false + ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json + + + + full + true + true + + + + + + + diff --git a/ortools/graph/samples/SimpleMinCostFlowProgram.cs b/ortools/graph/samples/SimpleMinCostFlowProgram.cs new file mode 100644 index 0000000000..ef98b30c04 --- /dev/null +++ b/ortools/graph/samples/SimpleMinCostFlowProgram.cs @@ -0,0 +1,87 @@ +// 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. + +// """From Bradley, Hax, and Magnanti, 'Applied Mathematical Programming', figure 8.1.""" +// [START program] +using System; +using Google.OrTools.Graph; + +public class SimpleMinCostFlowProgram +{ + static void Main() + { + // [START data] + // Define four parallel arrays: sources, destinations, capacities, and unit costs + // between each pair. For instance, the arc from node 0 to node 1 has a + // capacity of 15. + // Problem taken From Taha's 'Introduction to Operations Research', + // example 6.4-2. + int[] startNodes = {0, 0, 1, 1, 1, 2, 2, 3, 4}; + int[] endNodes = {1, 2, 2, 3, 4, 3, 4, 4, 2}; + int[] capacities = {15, 8, 20, 4, 10, 15, 4, 20, 5}; + int[] unitCosts = {4, 4, 2, 2, 6, 1, 3, 2, 3}; + + // Define an array of supplies at each node. + int[] supplies = {20, 0, 0, -5, -15}; + // [END data] + + // [START constraints] + // Instantiate a SimpleMinCostFlow solver. + MinCostFlow minCostFlow = new MinCostFlow(); + + // Add each arc. + for (int i = 0; i < startNodes.Length; ++i) + { + int arc = minCostFlow.AddArcWithCapacityAndUnitCost(startNodes[i], endNodes[i], + capacities[i], unitCosts[i]); + if (arc != i) throw new Exception("Internal error"); + } + + // Add node supplies. + for (int i = 0; i < supplies.Length; ++i) + { + minCostFlow.SetNodeSupply(i, supplies[i]); + } + + // [END constraints] + + // [START solve] + // Find the min cost flow. + int solveStatus = minCostFlow.Solve(); + // [END solve] + + // [START print_solution] + if (solveStatus == MinCostFlow.OPTIMAL) + { + Console.WriteLine("Minimum cost: " + minCostFlow.OptimalCost()); + Console.WriteLine(""); + Console.WriteLine(" Edge Flow / Capacity Cost"); + for (int i = 0; i < minCostFlow.NumArcs(); ++i) + { + long cost = minCostFlow.Flow(i) * minCostFlow.UnitCost(i); + Console.WriteLine(minCostFlow.Tail(i) + " -> " + + minCostFlow.Head(i) + " " + + string.Format("{0,3}", minCostFlow.Flow(i)) + " / " + + string.Format ("{0,3}", minCostFlow.Capacity(i)) + " " + + string.Format ("{0,3}", cost)); + } + } + else + { + Console.WriteLine("Solving the min cost flow problem failed. Solver status: " + + solveStatus); + } + // [END print_solution] + } +} +// [END program] diff --git a/ortools/graph/samples/SimpleMinCostFlowProgram.csproj b/ortools/graph/samples/SimpleMinCostFlowProgram.csproj new file mode 100644 index 0000000000..ea0323aa00 --- /dev/null +++ b/ortools/graph/samples/SimpleMinCostFlowProgram.csproj @@ -0,0 +1,20 @@ + + + Exe + 7.2 + netcoreapp2.1 + false + ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json + + + + full + true + true + + + + + + + diff --git a/ortools/graph/samples/simple_max_flow_program.cc b/ortools/graph/samples/simple_max_flow_program.cc new file mode 100644 index 0000000000..11df9cbf43 --- /dev/null +++ b/ortools/graph/samples/simple_max_flow_program.cc @@ -0,0 +1,70 @@ +// 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] +// From Taha 'Introduction to Operations Research', example 6.4-2.""" +// [START import] +#include "ortools/graph/max_flow.h" +// [END import] + +namespace operations_research { + +// MaxFlow simple interface example. +void SimpleMaxFlowProgram() { + // [START data] + // Define three parallel arrays: start_nodes, end_nodes, and the capacities + // between each pair. For instance, the arc from node 0 to node 1 has a + // capacity of 20. + std::vector start_nodes = {0, 0, 0, 1, 1, 2, 2, 3, 3}; + std::vector end_nodes = {1, 2, 3, 2, 4, 3, 4, 2, 4}; + std::vector capacities = {20, 30, 10, 40, 30, 10, 20, 5, 20}; + // [END data] + + // [START constraints] + // Instantiate a SimpleMaxFlow solver. + SimpleMaxFlow max_flow; + + // Add each arc. + for (int i = 0; i < start_nodes.size(); ++i) { + max_flow.AddArcWithCapacity(start_nodes[i], end_nodes[i], capacities[i]); + } + // [END constraints] + + // [START solve] + // Find the maximum flow between node 0 and node 4. + int solve_status = max_flow.Solve(0, 4); + // [END solve] + + // [START print_solution] + if (solve_status == MaxFlow::OPTIMAL) { + LOG(INFO) << "Max flow: " << max_flow.OptimalFlow(); + LOG(INFO) << ""; + LOG(INFO) << " Arc Flow / Capacity"; + for (std::size_t i = 0; i < max_flow.NumArcs(); ++i) { + LOG(INFO) << max_flow.Tail(i) << " -> " << max_flow.Head(i) << " " + << max_flow.Flow(i) << " / " << max_flow.Capacity(i); + } + } else { + LOG(INFO) << "Solving the max flow problem failed. Solver status: " + << solve_status; + } + // [END print_solution] +} + +} // namespace operations_research + +int main() { + operations_research::SimpleMaxFlowProgram(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/graph/samples/simple_max_flow_program.py b/ortools/graph/samples/simple_max_flow_program.py new file mode 100644 index 0000000000..bb7fd095f3 --- /dev/null +++ b/ortools/graph/samples/simple_max_flow_program.py @@ -0,0 +1,62 @@ +# 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] +"""From Taha 'Introduction to Operations Research', example 6.4-2.""" +# [START import] +from __future__ import print_function +from ortools.graph import pywrapgraph + +# [END import] + + +def main(): + """MaxFlow simple interface example.""" + + # [START data] + # Define three parallel arrays: start_nodes, end_nodes, and the capacities + # between each pair. For instance, the arc from node 0 to node 1 has a + # capacity of 20. + + start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] + end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] + capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20] + # [END data] + + # Instantiate a SimpleMaxFlow solver. + # [START constraints] + max_flow = pywrapgraph.SimpleMaxFlow() + # Add each arc. + for arc in zip(start_nodes, end_nodes, capacities): + max_flow.AddArcWithCapacity(arc[0], arc[1], arc[2]) + # [END constraints] + + # [START solve] + # Find the maximum flow between node 0 and node 4. + if max_flow.Solve(0, 4) == max_flow.OPTIMAL: + print('Max flow:', max_flow.OptimalFlow()) + print('') + print(' Arc Flow / Capacity') + for i in range(max_flow.NumArcs()): + print('%1s -> %1s %3s / %3s' % + (max_flow.Tail(i), max_flow.Head(i), max_flow.Flow(i), + max_flow.Capacity(i))) + print('Source side min-cut:', max_flow.GetSourceSideMinCut()) + print('Sink side min-cut:', max_flow.GetSinkSideMinCut()) + else: + print('There was an issue with the max flow input.') + # [END solve] + + +if __name__ == '__main__': + main() +# [END program] diff --git a/ortools/graph/samples/simple_min_cost_flow_program.cc b/ortools/graph/samples/simple_min_cost_flow_program.cc new file mode 100644 index 0000000000..62995c783f --- /dev/null +++ b/ortools/graph/samples/simple_min_cost_flow_program.cc @@ -0,0 +1,82 @@ +// 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] +// From Bradley, H., and M., 'Applied Mathematical Programming', figure 8.1. +// [START import] +#include "ortools/graph/min_cost_flow.h" +// [END import] + +namespace operations_research { + +void SimpleMinCostFlowProgram() { + // [START data] + // Define four parallel arrays: sources, destinations, capacities, + // and unit costs between each pair. For instance, the arc from node 0 + // to node 1 has a capacity of 15. + std::vector start_nodes = {0, 0, 1, 1, 1, 2, 2, 3, 4}; + std::vector end_nodes = {1, 2, 2, 3, 4, 3, 4, 4, 2}; + std::vector capacities = {15, 8, 20, 4, 10, 15, 4, 20, 5}; + std::vector unit_costs = {4, 4, 2, 2, 6, 1, 3, 2, 3}; + + // Define an array of supplies at each node. + std::vector supplies = {20, 0, 0, -5, -15}; + // [END data] + + // [START constraints] + // Instantiate a SimpleMinCostFlow solver. + SimpleMinCostFlow min_cost_flow; + + // Add each arc. + for (int i = 0; i < start_nodes.size(); ++i) { + int arc = min_cost_flow.AddArcWithCapacityAndUnitCost( + start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]); + if (arc != i) LOG(FATAL) << "Internal error"; + } + + // Add node supplies. + for (int i = 0; i < supplies.size(); ++i) { + min_cost_flow.SetNodeSupply(i, supplies[i]); + } + // [END constraints] + + // [START solve] + // Find the min cost flow. + int solve_status = min_cost_flow.Solve(); + // [END solve] + + // [START print_solution] + if (solve_status == MinCostFlow::OPTIMAL) { + LOG(INFO) << "Minimum cost flow: " << min_cost_flow.OptimalCost(); + LOG(INFO) << ""; + LOG(INFO) << " Arc Flow / Capacity Cost"; + for (std::size_t i = 0; i < min_cost_flow.NumArcs(); ++i) { + int64 cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i); + LOG(INFO) << min_cost_flow.Tail(i) << " -> " << min_cost_flow.Head(i) + << " " << min_cost_flow.Flow(i) << " / " + << min_cost_flow.Capacity(i) << " " << cost; + } + } else { + LOG(INFO) << "Solving the min cost flow problem failed. Solver status: " + << solve_status; + } + // [END print_solution] +} + +} // namespace operations_research + +int main() { + operations_research::SimpleMinCostFlowProgram(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/graph/samples/simple_min_cost_flow_program.py b/ortools/graph/samples/simple_min_cost_flow_program.py new file mode 100644 index 0000000000..d146def02c --- /dev/null +++ b/ortools/graph/samples/simple_min_cost_flow_program.py @@ -0,0 +1,74 @@ +# 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] +"""From Bradley, H. and M., 'Applied Mathematical Programming', figure 8.1.""" +# [START import] +from __future__ import print_function +from ortools.graph import pywrapgraph + +# [END import] + + +def main(): + """MinCostFlow simple interface example.""" + # [START data] + # Define four parallel arrays: sources, destinations, capacities, + # and unit costs between each pair. For instance, the arc from node 0 + # to node 1 has a capacity of 15. + start_nodes = [0, 0, 1, 1, 1, 2, 2, 3, 4] + end_nodes = [1, 2, 2, 3, 4, 3, 4, 4, 2] + capacities = [15, 8, 20, 4, 10, 15, 4, 20, 5] + unit_costs = [4, 4, 2, 2, 6, 1, 3, 2, 3] + + # Define an array of supplies at each node. + supplies = [20, 0, 0, -5, -15] + # [END data] + + # [START constraints] + # Instantiate a SimpleMinCostFlow solver. + min_cost_flow = pywrapgraph.SimpleMinCostFlow() + + # Add each arc. + for arc in zip(start_nodes, end_nodes, capacities, unit_costs): + min_cost_flow.AddArcWithCapacityAndUnitCost(arc[0], arc[1], arc[2], + arc[3]) + + # Add node supplies. + for count, supply in enumerate(supplies): + min_cost_flow.SetNodeSupply(count, supply) + # [END constraints] + + # [START solve] + # Find the min cost flow. + solve_status = min_cost_flow.Solve() + # [END solve] + + # [START print_solution] + if solve_status == min_cost_flow.OPTIMAL: + print('Minimum cost: ', min_cost_flow.OptimalCost()) + print('') + print(' Arc Flow / Capacity Cost') + for i in range(min_cost_flow.NumArcs()): + cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i) + print('%1s -> %1s %3s / %3s %3s' % + (min_cost_flow.Tail(i), min_cost_flow.Head(i), + min_cost_flow.Flow(i), min_cost_flow.Capacity(i), cost)) + else: + print('Solving the min cost flow problem failed. Solver status: ', + solve_status) + # [END print_solution] + + +if __name__ == '__main__': + main() +# [END program] diff --git a/ortools/linear_solver/samples/LinearProgrammingExample.java b/ortools/linear_solver/samples/LinearProgrammingExample.java new file mode 100644 index 0000000000..8f0ab6bb28 --- /dev/null +++ b/ortools/linear_solver/samples/LinearProgrammingExample.java @@ -0,0 +1,86 @@ +// 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] +import com.google.ortools.linearsolver.MPConstraint; +import com.google.ortools.linearsolver.MPObjective; +import com.google.ortools.linearsolver.MPSolver; +import com.google.ortools.linearsolver.MPVariable; + +/** Simple linear programming example.*/ +public class LinearProgrammingExample { + static { + System.loadLibrary("jniortools"); + } + + public static void main(String[] args) throws Exception { + // [START solver] + MPSolver solver = new MPSolver( + "LinearProgrammingExample", MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING); + // [END solver] + + // [START variables] + double infinity = MPSolver.infinity(); + // x and y are continuous non-negative variables. + MPVariable x = solver.makeNumVar(0.0, infinity, "x"); + MPVariable y = solver.makeNumVar(0.0, infinity, "y"); + System.out.println("Number of variables = " + solver.numVariables()); + // [END variables] + + // [START constraints] + // x + 2*y <= 14. + MPConstraint c0 = solver.makeConstraint(-infinity, 14.0, "c0"); + c0.setCoefficient(x, 1); + c0.setCoefficient(y, 2); + + // 3*x - y >= 0. + MPConstraint c1 = solver.makeConstraint(0.0, infinity, "c1"); + c1.setCoefficient(x, 3); + c1.setCoefficient(y, -1); + + // x - y <= 2. + MPConstraint c2 = solver.makeConstraint(-infinity, 2.0, "c2"); + c2.setCoefficient(x, 1); + c2.setCoefficient(y, -1); + System.out.println("Number of constraints = " + solver.numConstraints()); + // [END constraints] + + // [START objective] + // Maximize 3 * x + 4 * y. + MPObjective objective = solver.objective(); + objective.setCoefficient(x, 3); + objective.setCoefficient(y, 4); + objective.setMaximization(); + // [END objective] + + // [START solve] + final MPSolver.ResultStatus resultStatus = solver.solve(); + // Check that the problem has an optimal solution. + if (resultStatus != MPSolver.ResultStatus.OPTIMAL) { + System.err.println("The problem does not have an optimal solution!"); + return; + } + // [END solve] + + // [START print_solution] + // The value of each variable in the solution. + System.out.println("Solution"); + System.out.println("x = " + x.solutionValue()); + System.out.println("y = " + y.solutionValue()); + + // The objective value of the solution. + System.out.println("Optimal objective value = " + solver.objective().value()); + // [END print_solution] + } +} +// [END program] diff --git a/ortools/linear_solver/samples/SimpleLpProgram.java b/ortools/linear_solver/samples/SimpleLpProgram.java index d7b5e6ab1b..087667d4cf 100644 --- a/ortools/linear_solver/samples/SimpleLpProgram.java +++ b/ortools/linear_solver/samples/SimpleLpProgram.java @@ -18,6 +18,7 @@ import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; +/** Minimal Linear Programming example to showcase calling the solver.*/ public class SimpleLpProgram { static { System.loadLibrary("jniortools"); @@ -25,8 +26,8 @@ public class SimpleLpProgram { public static void main(String[] args) throws Exception { // Create the linear solver with the GLOP backend. - MPSolver solver = new MPSolver( - "SimpleLpProgram", MPSolver.OptimizationProblemType.valueOf("GLOP_LINEAR_PROGRAMMING")); + MPSolver solver = + new MPSolver("SimpleLpProgram", MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING); // Create the variables x and y. MPVariable x = solver.makeNumVar(0.0, 1.0, "x"); diff --git a/ortools/linear_solver/samples/SimpleMipProgram.java b/ortools/linear_solver/samples/SimpleMipProgram.java index 333978cd16..4e6cd296df 100644 --- a/ortools/linear_solver/samples/SimpleMipProgram.java +++ b/ortools/linear_solver/samples/SimpleMipProgram.java @@ -18,6 +18,7 @@ import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; +/** Minimal Mixed Integer Programming example to showcase calling the solver. */ public class SimpleMipProgram { static { System.loadLibrary("jniortools"); @@ -26,8 +27,8 @@ public class SimpleMipProgram { public static void main(String[] args) throws Exception { // [START solver] // Create the linear solver with the CBC backend. - MPSolver solver = new MPSolver("SimpleMipProgram", - MPSolver.OptimizationProblemType.valueOf("CBC_MIXED_INTEGER_PROGRAMMING")); + MPSolver solver = new MPSolver( + "SimpleMipProgram", MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING); // [END solver] // [START variables] diff --git a/ortools/linear_solver/samples/integer_programming_example.cc b/ortools/linear_solver/samples/integer_programming_example.cc new file mode 100644 index 0000000000..ef7e38e718 --- /dev/null +++ b/ortools/linear_solver/samples/integer_programming_example.cc @@ -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. + +// [START program] +// [START import] +#include +#include "ortools/linear_solver/linear_solver.h" +// [END import] + +namespace operations_research { +void IntegerProgrammingExample() { + // [START solver] + // Create the mip solver with the CBC backend. + MPSolver solver("IntegerExample", + MPSolver::CBC_MIXED_INTEGER_PROGRAMMING); + // [END solver] + + // [START variables] + // x, y, and z are non-negative integer variables. + MPVariable* const x = solver.MakeIntVar(0.0, solver.infinity(), "x"); + MPVariable* const y = solver.MakeIntVar(0.0, solver.infinity(), "y"); + MPVariable* const z = solver.MakeIntVar(0.0, solver.infinity(), "z"); + LOG(INFO) << "Number of variables = " << solver.NumVariables(); + // [END variables] + + // [START constraints] + // 2*x + 7*y + 3*z <= 50 + MPConstraint* const constraint0 = + solver.MakeRowConstraint(-solver.infinity(), 50); + constraint0->SetCoefficient(x, 2); + constraint0->SetCoefficient(y, 7); + constraint0->SetCoefficient(z, 3); + + // 3*x - 5*y + 7*z <= 45 + MPConstraint* const constraint1 = + solver.MakeRowConstraint(-solver.infinity(), 45); + constraint1->SetCoefficient(x, 3); + constraint1->SetCoefficient(y, -5); + constraint1->SetCoefficient(z, 7); + + // 5*x + 2*y - 6*z <= 37 + MPConstraint* const constraint2 = + solver.MakeRowConstraint(-solver.infinity(), 37); + constraint2->SetCoefficient(x, 5); + constraint2->SetCoefficient(y, 2); + constraint2->SetCoefficient(z, -6); + LOG(INFO) << "Number of constraints = " << solver.NumConstraints(); + // [END constraints] + + // [START objective] + // Maximize 2*x + 2*y + 3*z + MPObjective* const objective = solver.MutableObjective(); + objective->SetCoefficient(x, 2); + objective->SetCoefficient(y, 2); + objective->SetCoefficient(z, 3); + objective->SetMaximization(); + // [END objective] + + // [START solve] + const MPSolver::ResultStatus result_status = solver.Solve(); + // Check that the problem has an optimal solution. + if (result_status != MPSolver::OPTIMAL) { + LOG(FATAL) << "The problem does not have an optimal solution!"; + } + // [END solve] + + // [START print_solution] + LOG(INFO) << "Solution:"; + LOG(INFO) << "Optimal objective value = " << objective->Value(); + LOG(INFO) << x->name() << " = " << x->solution_value(); + LOG(INFO) << y->name() << " = " << y->solution_value(); + LOG(INFO) << z->name() << " = " << z->solution_value(); + // [END print_solution] +} +} // namespace operations_research + +int main(int argc, char** argv) { + operations_research::IntegerProgrammingExample(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/linear_solver/samples/integer_programming_example.py b/ortools/linear_solver/samples/integer_programming_example.py new file mode 100644 index 0000000000..bc8d4f68c8 --- /dev/null +++ b/ortools/linear_solver/samples/integer_programming_example.py @@ -0,0 +1,79 @@ +# 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. +"""Small example to illustrate solving a MIP problem.""" +# [START program] +from __future__ import print_function +# [START import] +from ortools.linear_solver import pywraplp + +# [END import] + + +def IntegerProgrammingExample(): + """Integer programming sample.""" + # [START solver] + # Create the mip solver with the CBC backend. + solver = pywraplp.Solver('IntegerProgrammingExample', + pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING) + # [END solver] + + # [START variables] + # x, y, and z are non-negative integer variables. + x = solver.IntVar(0.0, solver.infinity(), 'x') + y = solver.IntVar(0.0, solver.infinity(), 'y') + z = solver.IntVar(0.0, solver.infinity(), 'z') + # [END variables] + + # [START constraints] + # 2*x + 7*y + 3*z <= 50 + constraint0 = solver.Constraint(-solver.infinity(), 50) + constraint0.SetCoefficient(x, 2) + constraint0.SetCoefficient(y, 7) + constraint0.SetCoefficient(z, 3) + + # 3*x - 5*y + 7*z <= 45 + constraint1 = solver.Constraint(-solver.infinity(), 45) + constraint1.SetCoefficient(x, 3) + constraint1.SetCoefficient(y, -5) + constraint1.SetCoefficient(z, 7) + + # 5*x + 2*y - 6*z <= 37 + constraint2 = solver.Constraint(-solver.infinity(), 37) + constraint2.SetCoefficient(x, 5) + constraint2.SetCoefficient(y, 2) + constraint2.SetCoefficient(z, -6) + # [END constraints] + + # [START objective] + # Maximize 2*x + 2*y + 3*z + objective = solver.Objective() + objective.SetCoefficient(x, 2) + objective.SetCoefficient(y, 2) + objective.SetCoefficient(z, 3) + objective.SetMaximization() + # [END objective] + + # Solve the problem and print the solution. + # [START print_solution] + solver.Solve() + # Print the objective value of the solution. + print('Maximum objective function value = %d' % solver.Objective().Value()) + print() + # Print the value of each variable in the solution. + for variable in [x, y, z]: + print('%s = %d' % (variable.name(), variable.solution_value())) + # [END print_solution] + + +IntegerProgrammingExample() +# [END program] diff --git a/ortools/linear_solver/samples/linear_programming_example.cc b/ortools/linear_solver/samples/linear_programming_example.cc new file mode 100644 index 0000000000..688eb77375 --- /dev/null +++ b/ortools/linear_solver/samples/linear_programming_example.cc @@ -0,0 +1,81 @@ +// 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 "ortools/linear_solver/linear_solver.h" +// [END import] + +namespace operations_research { +void LinearProgrammingExample() { + // [START solver] + MPSolver solver("LinearExample", MPSolver::GLOP_LINEAR_PROGRAMMING); + // [END solver] + + // [START variables] + const double infinity = solver.infinity(); + // x and y are non-negative variables. + MPVariable* const x = solver.MakeNumVar(0.0, infinity, "x"); + MPVariable* const y = solver.MakeNumVar(0.0, infinity, "y"); + LOG(INFO) << "Number of variables = " << solver.NumVariables(); + // [END variables] + + // [START constraints] + // x + 2*y <= 14. + MPConstraint* const c0 = solver.MakeRowConstraint(-infinity, 14.0); + c0->SetCoefficient(x, 1); + c0->SetCoefficient(y, 2); + + // 3*x - y >= 0. + MPConstraint* const c1 = solver.MakeRowConstraint(0.0, infinity); + c1->SetCoefficient(x, 3); + c1->SetCoefficient(y, -1); + + // x - y <= 2. + MPConstraint* const c2 = solver.MakeRowConstraint(-infinity, 2.0); + c2->SetCoefficient(x, 1); + c2->SetCoefficient(y, -1); + LOG(INFO) << "Number of constraints = " << solver.NumConstraints(); + // [END constraints] + + // [START objective] + // Objective function: 3x + 4y. + MPObjective* const objective = solver.MutableObjective(); + objective->SetCoefficient(x, 3); + objective->SetCoefficient(y, 4); + objective->SetMaximization(); + // [END objective] + + // [START solve] + const MPSolver::ResultStatus result_status = solver.Solve(); + // Check that the problem has an optimal solution. + if (result_status != MPSolver::OPTIMAL) { + LOG(FATAL) << "The problem does not have an optimal solution!"; + } + // [END solve] + + // [START print_solution] + LOG(INFO) << "Solution:"; + LOG(INFO) << "Optimal objective value = " << objective->Value(); + LOG(INFO) << x->name() << " = " << x->solution_value(); + LOG(INFO) << y->name() << " = " << y->solution_value(); + // [END print_solution] +} +} // namespace operations_research + +int main(int argc, char** argv) { + operations_research::LinearProgrammingExample(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/linear_solver/samples/linear_programming_example.py b/ortools/linear_solver/samples/linear_programming_example.py new file mode 100644 index 0000000000..ca48569c13 --- /dev/null +++ b/ortools/linear_solver/samples/linear_programming_example.py @@ -0,0 +1,79 @@ +# 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. +"""Linear optimization example.""" +# [START program] +from __future__ import print_function +# [START import] +from ortools.linear_solver import pywraplp + +# [END import] + + +def LinearProgrammingExample(): + """Linear programming sample.""" + # Instantiate a Glop solver, naming it LinearExample. + # [START solver] + solver = pywraplp.Solver('LinearProgrammingExample', + pywraplp.Solver.GLOP_LINEAR_PROGRAMMING) + # [END solver] + + # Create the two variables and let them take on any value. + # [START variables] + x = solver.NumVar(-solver.infinity(), solver.infinity(), 'x') + y = solver.NumVar(-solver.infinity(), solver.infinity(), 'y') + # [END variables] + + # [START constraints] + # Constraint 0: x + 2y <= 14. + constraint0 = solver.Constraint(-solver.infinity(), 14) + constraint0.SetCoefficient(x, 1) + constraint0.SetCoefficient(y, 2) + + # Constraint 1: 3x - y >= 0. + constraint1 = solver.Constraint(0, solver.infinity()) + constraint1.SetCoefficient(x, 3) + constraint1.SetCoefficient(y, -1) + + # Constraint 2: x - y <= 2. + constraint2 = solver.Constraint(-solver.infinity(), 2) + constraint2.SetCoefficient(x, 1) + constraint2.SetCoefficient(y, -1) + # [END constraints] + + # [START objective] + # Objective function: 3x + 4y. + objective = solver.Objective() + objective.SetCoefficient(x, 3) + objective.SetCoefficient(y, 4) + objective.SetMaximization() + # [END objective] + + # Solve the system. + # [START solve] + solver.Solve() + # [END solve] + # [START print_solution] + opt_solution = 3 * x.solution_value() + 4 * y.solution_value() + print('Number of variables =', solver.NumVariables()) + print('Number of constraints =', solver.NumConstraints()) + # The value of each variable in the solution. + print('Solution:') + print('x = ', x.solution_value()) + print('y = ', y.solution_value()) + # The objective value of the solution. + print('Optimal objective value =', opt_solution) + # [END print_solution] + + +LinearProgrammingExample() +# [END program]