diff --git a/makefiles/Makefile.cpp.mk b/makefiles/Makefile.cpp.mk index 1ab3e147a7..6491b33119 100755 --- a/makefiles/Makefile.cpp.mk +++ b/makefiles/Makefile.cpp.mk @@ -429,7 +429,8 @@ test_cc_graph_samples: \ .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_lp_program \ + rcc_simple_mip_program .PHONY: test_cc_sat_samples # Build and Run all C++ Sat Samples (located in ortools/sat/samples) test_cc_sat_samples: \ diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk index 119d0ff436..30e1d4482f 100644 --- a/makefiles/Makefile.dotnet.mk +++ b/makefiles/Makefile.dotnet.mk @@ -503,7 +503,8 @@ test_dotnet_graph_samples: \ .PHONY: test_dotnet_linear_solver_samples # Build and Run all .Net LP Samples (located in ortools/linear_solver/samples) test_dotnet_linear_solver_samples: \ - rdotnet_SimpleLpProgram.cs + rdotnet_SimpleLpProgram.cs \ + rdotnet_SimpleMipProgram.cs .PHONY: test_dotnet_sat_samples # Build and Run all .Net SAT Samples (located in ortools/sat/samples) test_dotnet_sat_samples: \ diff --git a/makefiles/Makefile.java.mk b/makefiles/Makefile.java.mk index 61af4eb4f5..b816fef89b 100755 --- a/makefiles/Makefile.java.mk +++ b/makefiles/Makefile.java.mk @@ -355,7 +355,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_SimpleLpProgram \ + rjava_SimpleMipProgram .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 cc0bf73986..e0fdbf4cef 100755 --- a/makefiles/Makefile.python.mk +++ b/makefiles/Makefile.python.mk @@ -499,7 +499,8 @@ test_python_graph_samples: \ .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_lp_program \ + rpy_simple_mip_program .PHONY: test_python_sat_samples # Run all Python Sat Samples (located in ortools/sat/samples) test_python_sat_samples: \ diff --git a/ortools/linear_solver/samples/SimpleMipProgram.cs b/ortools/linear_solver/samples/SimpleMipProgram.cs new file mode 100644 index 0000000000..83aa03866e --- /dev/null +++ b/ortools/linear_solver/samples/SimpleMipProgram.cs @@ -0,0 +1,75 @@ +// 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.LinearSolver; + +public class SimpleMipProgram +{ + static void Main() + { + // [START solver] + // Create the linear solver with the CBC backend. + Solver solver = Solver.CreateSolver("SimpleMipProgram", "CBC_MIXED_INTEGER_PROGRAMMING"); + // [END solver] + + // [START variables] + // x and y are integer non-negative variables. + Variable x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x"); + Variable y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y"); + + Console.WriteLine("Number of variables = " + solver.NumVariables()); + // [END variables] + + // [START constraints] + // x + 7 * y <= 17.5. + solver.Add(x + 7 * y <= 17.5); + + // x <= 3.5. + solver.Add(x <= 3.5); + + Console.WriteLine("Number of constraints = " + solver.NumConstraints()); + // [END constraints] + + // [START objective] + // Maximize x + 10 * y. + solver.Maximize(x + 10 * y); + // [END objective] + + // [START solve] + int resultStatus = solver.Solve(); + // Check that the problem has an optimal solution. + if (resultStatus != Solver.OPTIMAL) + { + Console.WriteLine("The problem does not have an optimal solution!"); + return; + } + // [END solve] + + // [START print_solution] + Console.WriteLine("Solution:"); + Console.WriteLine("Objective value = " + solver.Objective().Value()); + Console.WriteLine("x = " + x.SolutionValue()); + Console.WriteLine("y = " + y.SolutionValue()); + // [END print_solution] + + // [START advanced] + Console.WriteLine("\nAdvanced usage:"); + Console.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds"); + Console.WriteLine("Problem solved in " + solver.Iterations() + " iterations"); + Console.WriteLine("Problem solved in " + solver.Nodes() + " branch-and-bound nodes"); + // [END advanced] + } +} +// [END program] diff --git a/ortools/linear_solver/samples/SimpleMipProgram.csproj b/ortools/linear_solver/samples/SimpleMipProgram.csproj new file mode 100644 index 0000000000..493bed29c9 --- /dev/null +++ b/ortools/linear_solver/samples/SimpleMipProgram.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/linear_solver/samples/SimpleMipProgram.java b/ortools/linear_solver/samples/SimpleMipProgram.java new file mode 100644 index 0000000000..333978cd16 --- /dev/null +++ b/ortools/linear_solver/samples/SimpleMipProgram.java @@ -0,0 +1,95 @@ +// 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. + +// Minimal example to call the MIP solver. +// [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; + +public class SimpleMipProgram { + static { + System.loadLibrary("jniortools"); + } + + 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")); + // [END solver] + + // [START variables] + double infinity = MPSolver.infinity(); + // x and y are integer non-negative variables. + MPVariable x = solver.makeIntVar(0.0, infinity, "x"); + MPVariable y = solver.makeIntVar(0.0, infinity, "y"); + + System.out.println("Number of variables = " + solver.numVariables()); + // [END variables] + + // [START constraints] + // x + 7 * y <= 17.5. + MPConstraint c0 = solver.makeConstraint(-infinity, 17.5, "c0"); + c0.setCoefficient(x, 1); + c0.setCoefficient(y, 7); + + // x <= 3.5. + MPConstraint c1 = solver.makeConstraint(-infinity, 3.5, "c1"); + c1.setCoefficient(x, 1); + c1.setCoefficient(y, 0); + + System.out.println("Number of constraints = " + solver.numConstraints()); + // [END constraints] + + // [START objective] + // Maximize x + 10 * y. + MPObjective objective = solver.objective(); + objective.setCoefficient(x, 1); + objective.setCoefficient(y, 10); + 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; + } + // Verify that the solution satisfies all constraints (when using solvers + // others than GLOP_LINEAR_PROGRAMMING, this is highly recommended!). + if (!solver.verifySolution(/*tolerance=*/1e-7, /*log_errors=*/true)) { + System.err.println("The solution returned by the solver violated the" + + " problem constraints by at least 1e-7"); + return; + } + // [END solve] + + // [START print_solution] + System.out.println("Solution:"); + System.out.println("Objective value = " + objective.value()); + System.out.println("x = " + x.solutionValue()); + System.out.println("y = " + y.solutionValue()); + // [END print_solution] + + // [START advanced] + System.out.println("\nAdvanced usage:"); + System.out.println("Problem solved in " + solver.wallTime() + " milliseconds"); + System.out.println("Problem solved in " + solver.iterations() + " iterations"); + System.out.println("Problem solved in " + solver.nodes() + " branch-and-bound nodes"); + // [END advanced] + } +} +// [END program] diff --git a/ortools/linear_solver/samples/simple_mip_program.cc b/ortools/linear_solver/samples/simple_mip_program.cc new file mode 100644 index 0000000000..7f6dffc869 --- /dev/null +++ b/ortools/linear_solver/samples/simple_mip_program.cc @@ -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. + +// Mixed Integer programming example that shows how to use the API. +// [START program] +#include "ortools/linear_solver/linear_solver.h" + +namespace operations_research { +void simple_mip_program() { + // [START solver] + // Create the mip solver with the CBC backend. + MPSolver solver("simple_mip_program", + MPSolver::CBC_MIXED_INTEGER_PROGRAMMING); + // [END solver] + + // [START variables] + const double infinity = solver.infinity(); + // x and y are integer non-negative variables. + MPVariable* const x = solver.MakeIntVar(0.0, infinity, "x"); + MPVariable* const y = solver.MakeIntVar(0.0, infinity, "y"); + + LOG(INFO) << "Number of variables = " << solver.NumVariables(); + // [END variables] + + // [START constraints] + // x + 7 * y <= 17.5. + MPConstraint* const c0 = solver.MakeRowConstraint(-infinity, 17.5, "c0"); + c0->SetCoefficient(x, 1); + c0->SetCoefficient(y, 7); + + // x <= 3.5. + MPConstraint* const c1 = solver.MakeRowConstraint(-infinity, 3.5, "c1"); + c1->SetCoefficient(x, 1); + c1->SetCoefficient(y, 0); + + LOG(INFO) << "Number of constraints = " << solver.NumConstraints(); + // [END constraints] + + // [START objective] + // Maximize x + 10 * y. + MPObjective* const objective = solver.MutableObjective(); + objective->SetCoefficient(x, 1); + objective->SetCoefficient(y, 10); + 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) << "x = " << x->solution_value(); + LOG(INFO) << "y = " << y->solution_value(); + LOG(INFO) << "Optimal objective value = " << objective->Value(); + // [END print_solution] + + // [START advanced] + LOG(INFO) << "\nAdvanced usage:"; + LOG(INFO) << "Problem solved in " << solver.wall_time() << " milliseconds"; + LOG(INFO) << "Problem solved in " << solver.iterations() << " iterations"; + LOG(INFO) << "Problem solved in " << solver.nodes() + << " branch-and-bound nodes"; + // [END advanced] +} +} // namespace operations_research + +int main(int argc, char** argv) { + operations_research::simple_mip_program(); + return EXIT_SUCCESS; +} +// [END program] diff --git a/ortools/linear_solver/samples/simple_mip_program.py b/ortools/linear_solver/samples/simple_mip_program.py new file mode 100644 index 0000000000..046805a288 --- /dev/null +++ b/ortools/linear_solver/samples/simple_mip_program.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. +"""Integer programming examples that show how to use the APIs.""" +# [START program] +from __future__ import print_function +from ortools.linear_solver import pywraplp + + +def main(): + # [START solver] + # Create the mip solver with the CBC backend. + solver = pywraplp.Solver('simple_mip_program', + pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING) + # [END solver] + + # [START variables] + infinity = solver.infinity() + # x and y are integer non-negative variables. + x = solver.IntVar(0.0, infinity, 'x') + y = solver.IntVar(0.0, infinity, 'y') + + print(('Number of variables = %d' % solver.NumVariables())) + # [END variables] + + # [START constraints] + + # [END constraints] + # x + 7 * y <= 17.5. + solver.Add(x + 7 * y <= 17.5) + + # x <= 3.5. + solver.Add(x <= 3.5) + + print(('Number of constraints = ', solver.NumConstraints())) + # [END constraints] + + # [START objective] + # Maximize x + 10 * y. + solver.Maximize(x + 10 * y) + # [END objective] + + # [START solve] + result_status = solver.Solve() + # The problem has an optimal solution. + assert result_status == pywraplp.Solver.OPTIMAL + + # The solution looks legit (when using solvers others than + # GLOP_LINEAR_PROGRAMMING, verifying the solution is highly recommended!). + assert solver.VerifySolution(1e-7, True) + # [END solve] + + # [START print_solution] + print('Solution:') + print('Objective value = ', solver.Objective().Value()) + print('x = ', x.solution_value()) + print('y = ', y.solution_value()) + # [END print_solution] + + # [START advanced] + print('\nAdvanced usage:') + print('Problem solved in %f milliseconds' % solver.wall_time()) + print('Problem solved in %d iterations' % solver.iterations()) + print('Problem solved in %d branch-and-bound nodes' % solver.nodes()) + # [END advanced] + + +if __name__ == '__main__': + main() +# [END program]