diff --git a/examples/dotnet/csintegerprogramming.cs b/examples/dotnet/csintegerprogramming.cs index d813f3f800..c8e2181f39 100644 --- a/examples/dotnet/csintegerprogramming.cs +++ b/examples/dotnet/csintegerprogramming.cs @@ -39,10 +39,10 @@ public class CsIntegerProgramming ct.SetCoefficient(x1, 3); ct.SetCoefficient(x2, 2); - int resultStatus = solver.Solve(); + Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.OPTIMAL) + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; @@ -78,10 +78,10 @@ public class CsIntegerProgramming solver.Minimize(x1 + 2 * x2); solver.Add(2 * x2 + 3 * x1 >= 17); - int resultStatus = solver.Solve(); + Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.OPTIMAL) + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; diff --git a/examples/dotnet/cslinearprogramming.cs b/examples/dotnet/cslinearprogramming.cs index b88900cd92..28b2128d68 100644 --- a/examples/dotnet/cslinearprogramming.cs +++ b/examples/dotnet/cslinearprogramming.cs @@ -57,10 +57,10 @@ public class CsLinearProgramming Console.WriteLine("Number of variables = " + solver.NumVariables()); Console.WriteLine("Number of constraints = " + solver.NumConstraints()); - int resultStatus = solver.Solve(); + Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.OPTIMAL) { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } @@ -120,10 +120,10 @@ public class CsLinearProgramming Console.WriteLine(model); } - int resultStatus = solver.Solve(); + Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.OPTIMAL) { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } diff --git a/examples/tests/testlp.cs b/examples/tests/testlp.cs index 12cf38e711..41c6a44a6a 100644 --- a/examples/tests/testlp.cs +++ b/examples/tests/testlp.cs @@ -41,7 +41,7 @@ public class CsTestLp { Console.WriteLine("Running TestVarOperator"); Solver solver = new Solver("TestVarOperator", - Solver.CLP_LINEAR_PROGRAMMING); + Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Constraint ct1 = solver.Add(x >= 1); Constraint ct2 = solver.Add(x <= 1); @@ -73,7 +73,7 @@ public class CsTestLp { Console.WriteLine("Running TestVarAddition"); Solver solver = new Solver("TestVarAddition", - Solver.CLP_LINEAR_PROGRAMMING); + Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(x + y == 1); @@ -95,7 +95,7 @@ public class CsTestLp { Console.WriteLine("Running TestVarMultiplication"); Solver solver = new Solver("TestVarMultiplication", - Solver.CLP_LINEAR_PROGRAMMING); + Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(3 * x == 1); @@ -121,7 +121,7 @@ public class CsTestLp { Console.WriteLine("Running TestBinaryOperations"); Solver solver = new Solver("TestBinaryOperations", - Solver.CLP_LINEAR_PROGRAMMING); + Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(x == y); @@ -147,7 +147,7 @@ public class CsTestLp { Console.WriteLine("Running TestInequalities"); Solver solver = new Solver("TestInequalities", - Solver.CLP_LINEAR_PROGRAMMING); + Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(2 * (x + 3) + 5 * (y + x -1) >= 3); @@ -175,7 +175,7 @@ public class CsTestLp static void TestSumArray() { Console.WriteLine("Running TestSumArray"); - Solver solver = new Solver("TestSumArray", Solver.CLP_LINEAR_PROGRAMMING); + Solver solver = new Solver("TestSumArray", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable[] x = solver.MakeBoolVarArray(10, "x"); Constraint ct1 = solver.Add(x.Sum() == 3); CheckDoubleEq(ct1.GetCoefficient(x[0]), 1.0, "test1"); @@ -191,7 +191,7 @@ public class CsTestLp static void TestObjective() { Console.WriteLine("Running TestObjective"); - Solver solver = new Solver("TestObjective", Solver.CLP_LINEAR_PROGRAMMING); + Solver solver = new Solver("TestObjective", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); solver.Maximize(x); diff --git a/ortools/algorithms/csharp/knapsack_solver.i b/ortools/algorithms/csharp/knapsack_solver.i index a0a9c928df..a0110399ad 100644 --- a/ortools/algorithms/csharp/knapsack_solver.i +++ b/ortools/algorithms/csharp/knapsack_solver.i @@ -13,8 +13,9 @@ // TODO(user): Refactor this file to adhere to the SWIG style guide. -%include -%include +%include "enums.swg" +%include "stdint.i" +%include "std_vector.i" %include "ortools/base/base.i" diff --git a/ortools/algorithms/java/knapsack_solver.i b/ortools/algorithms/java/knapsack_solver.i index 6102827a2f..6053e49925 100644 --- a/ortools/algorithms/java/knapsack_solver.i +++ b/ortools/algorithms/java/knapsack_solver.i @@ -18,8 +18,8 @@ // // TODO(user): test all lines marked "untested". -%include -%include +%include "enums.swg" +%include "stdint.i" %include "ortools/base/base.i" %import "ortools/util/java/vector.i" diff --git a/ortools/algorithms/python/knapsack_solver.i b/ortools/algorithms/python/knapsack_solver.i index 8ae50164d5..a51f8d68c0 100644 --- a/ortools/algorithms/python/knapsack_solver.i +++ b/ortools/algorithms/python/knapsack_solver.i @@ -17,7 +17,7 @@ // - examples/python/knapsack.py // - ./pywrapknapsack_solver_test.py -%include +%include "stdint.i" %include "ortools/base/base.i" %import "ortools/util/python/vector.i" diff --git a/ortools/base/base.i b/ortools/base/base.i index a65f939bc2..c15f46a327 100644 --- a/ortools/base/base.i +++ b/ortools/base/base.i @@ -23,17 +23,14 @@ // rename. For example, an operator< in a class without a rename. // 362 is similar to 503 but for operator=. -%include -%include -%include -%include +%include "typemaps.i" +%include "exception.i" +%include "stdint.i" +%include "std_string.i" %{ #include -#include -#include #include -#include #include #include "ortools/base/basictypes.h" @@ -67,50 +64,24 @@ COPY_TYPEMAPS(uint64_t, uint64); #endif // SWIGPYTHON -#ifdef SWIGJAVA +#if defined(SWIGJAVA) || defined(SWIGCSHARP) %{ #include -#include -#include #include -#include #include #include "ortools/base/basictypes.h" %} -%include -%include +%include "stdint.i" +%include "std_string.i" typedef int int32; typedef unsigned int uint32; typedef int64_t int64; typedef uint64_t uint64; -#endif // SWIGJAVA - -#ifdef SWIGCSHARP -%include "enumsimple.swg" -%{ -#include -#include -#include -#include -#include -#include - -#include "ortools/base/basictypes.h" -%} - -%include -%include - -typedef int int32; -typedef unsigned int uint32; -typedef int64_t int64; -typedef uint64_t uint64; - -#endif // SWIGCSHARP +#endif // defined(SWIGJAVA) || defined(SWIGCSHARP) // SWIG macros for explicit API declaration. // Usage: diff --git a/ortools/base/integral_types.h b/ortools/base/integral_types.h index 33c97ffa12..b7d4ee7030 100644 --- a/ortools/base/integral_types.h +++ b/ortools/base/integral_types.h @@ -41,7 +41,6 @@ typedef uint64_t uint64; // and different size specifiers in format strings #undef GG_LONGLONG #undef GG_ULONGLONG -#undef GG_LL_FORMAT #define GG_LONGLONG(x) INT64_C(x) #define GG_ULONGLONG(x) UINT64_C(x) diff --git a/ortools/base/python/callbacks.i b/ortools/base/python/callbacks.i deleted file mode 100644 index f9ad9317f0..0000000000 --- a/ortools/base/python/callbacks.i +++ /dev/null @@ -1,145 +0,0 @@ -// 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. - -// SWIG wrapping of some Callbacks in python. -// This doesn't directly expose a C++ API; rather it provides typemaps that can -// be used by other .i files to easily expose APIs that use callbacks. -// See its usage in ../../constraint_solver/python/constraint_solver.i. -// -// TODO(user): Nuke this file and use the callback wrapping code in -// base/swig/python/... when it is available. - -%include "ortools/base/base.i" - -%import "ortools/base/callback.h" - -%{ -static std::string PyCallbackString(PyObject* pyfunc) { - PyObject* pyresult = PyObject_CallFunctionObjArgs(pyfunc, nullptr); - std::string result; - if (!pyresult) { - PyErr_SetString(PyExc_RuntimeError, - "ResultCallback invocation failed."); - } else { - result = PyString_AsString(pyresult); - Py_DECREF(pyresult); - } - return result; -} -%} - -%typemap(in) ResultCallback* { - if (!PyCallable_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - SWIG_fail; - } - $1 = NewPermanentCallback(&PyCallbackString, $input); -} - -%{ -static int64 PyCallback1Int64Int64(PyObject* pyfunc, int64 i) { - // () needed to force creation of one-element tuple - PyObject* pyresult = PyEval_CallFunction(pyfunc, "(l)", static_cast(i)); - int64 result = 0; - if (!pyresult) { - PyErr_SetString(PyExc_RuntimeError, - "ResultCallback1 invocation failed."); - } else { - result = PyInt_AsLong(pyresult); - Py_DECREF(pyresult); - } - return result; -} -%} - -%typemap(in) ResultCallback1* { - if (!PyCallable_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - SWIG_fail; - } - $1 = NewPermanentCallback(&PyCallback1Int64Int64, $input); -} - -%{ -static int64 PyCallback2Int64Int64Int64(PyObject* pyfunc, int64 i, int64 j) { - PyObject* pyresult = PyEval_CallFunction(pyfunc, "ll", static_cast(i), - static_cast(j)); - int64 result = 0; - if (!pyresult) { - PyErr_SetString(PyExc_RuntimeError, - "ResultCallback2 invocation failed."); - } else { - result = PyInt_AsLong(pyresult); - Py_DECREF(pyresult); - } - return result; -} -%} - -%typemap(in) ResultCallback2* { - if (!PyCallable_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - SWIG_fail; - } - $1 = NewPermanentCallback(&PyCallback2Int64Int64Int64, $input); -} - -%{ -static int64 PyCallback3Int64Int64Int64Int64(PyObject* pyfunc, - int64 i, int64 j, int64 k) { - PyObject* pyresult = PyEval_CallFunction(pyfunc, "lll", static_cast(i), - static_cast(j), - static_cast(k)); - int64 result = 0; - if (!pyresult) { - PyErr_SetString( - PyExc_RuntimeError, - "ResultCallback3 invocation failed."); - } else { - result = PyInt_AsLong(pyresult); - Py_DECREF(pyresult); - } - return result; -} -%} - -%typemap(in) ResultCallback3* { - if (!PyCallable_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - SWIG_fail; - } - $1 = NewPermanentCallback(&PyCallback3Int64Int64Int64Int64, $input); -} - -%{ -static bool PyCallbackBool(PyObject* pyfunc) { - PyObject* pyresult = PyObject_CallFunctionObjArgs(pyfunc, nullptr); - bool result = false; - if (!pyresult) { - PyErr_SetString(PyExc_RuntimeError, - "ResultCallback invocation failed."); - } else { - result = PyObject_IsTrue(pyresult); - Py_DECREF(pyresult); - } - return result; -} -%} - -%typemap(in) ResultCallback* { - if (!PyCallable_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - SWIG_fail; - } - $1 = NewPermanentCallback(&PyCallbackBool, $input); -} diff --git a/ortools/constraint_solver/csharp/constraint_solver.i b/ortools/constraint_solver/csharp/constraint_solver.i index b47b0d0ce3..a7d2edc896 100644 --- a/ortools/constraint_solver/csharp/constraint_solver.i +++ b/ortools/constraint_solver/csharp/constraint_solver.i @@ -19,16 +19,16 @@ using System.Runtime.InteropServices; using System.Collections; %} -%include -%include -%include +%include "enumsimple.swg" +%include "stdint.i" +%include "exception.i" +%include "std_vector.i" %include "ortools/base/base.i" %include "ortools/util/csharp/tuple_set.i" %include "ortools/util/csharp/functions.i" %include "ortools/util/csharp/proto.i" - // We need to forward-declare the proto here, so that PROTO_INPUT involving it // works correctly. The order matters very much: this declaration needs to be // before the %{ #include ".../constraint_solver.h" %}. @@ -58,7 +58,6 @@ class SearchLimitParameters; #include #include -#include "ortools/base/callback.h" #include "ortools/base/integral_types.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" diff --git a/ortools/constraint_solver/java/constraint_solver.i b/ortools/constraint_solver/java/constraint_solver.i index 6b53c06741..462dcecdf2 100644 --- a/ortools/constraint_solver/java/constraint_solver.i +++ b/ortools/constraint_solver/java/constraint_solver.i @@ -13,9 +13,9 @@ // TODO(user): Refactor this file to adhere to the SWIG style guide. -%include -%include -%include +%include "enumsimple.swg" +%include "exception.i" +%include "stdint.i" %include "ortools/base/base.i" %include "ortools/util/java/tuple_set.i" diff --git a/ortools/constraint_solver/python/constraint_solver.i b/ortools/constraint_solver/python/constraint_solver.i index 65df0690af..617d55dc08 100644 --- a/ortools/constraint_solver/python/constraint_solver.i +++ b/ortools/constraint_solver/python/constraint_solver.i @@ -31,7 +31,7 @@ // - examples/python/sudoku.py // - examples/python/zebra.py -%include +%include "stdint.i" %include "ortools/base/base.i" %include "ortools/util/python/proto.i" @@ -2240,3 +2240,4 @@ class PyConstraint(Constraint): } // %pythoncode + diff --git a/ortools/constraint_solver/python/routing.i b/ortools/constraint_solver/python/routing.i index be6e9776a8..7e4f328bf7 100644 --- a/ortools/constraint_solver/python/routing.i +++ b/ortools/constraint_solver/python/routing.i @@ -13,7 +13,6 @@ // TODO(user): Refactor this file to adhere to the SWIG style guide. -%include %include "ortools/base/base.i" %include "ortools/constraint_solver/python/constraint_solver.i" diff --git a/ortools/constraint_solver/search.cc b/ortools/constraint_solver/search.cc index 65d7a27662..a9b9a6e1b9 100644 --- a/ortools/constraint_solver/search.cc +++ b/ortools/constraint_solver/search.cc @@ -1489,7 +1489,7 @@ int64 StaticEvaluatorSelector::ChooseVariable() { } // Sort is stable here given the tie-breaking rules in comp_. std::sort(elements_.begin(), elements_.end(), comp_); - solver_->SaveAndSetValue(&first_, GG_LONGLONG(0)); + solver_->SaveAndSetValue(&first_, 0); } for (int64 i = first_; i < elements_.size(); ++i) { const Element& element = elements_[i]; diff --git a/ortools/dotnet/Google.OrTools.FSharp/OrTools.fs b/ortools/dotnet/Google.OrTools.FSharp/OrTools.fs index 570dba052b..0d42c2d1aa 100644 --- a/ortools/dotnet/Google.OrTools.FSharp/OrTools.fs +++ b/ortools/dotnet/Google.OrTools.FSharp/OrTools.fs @@ -150,7 +150,7 @@ module FSharp = | MultidimensionSCIP -> MultidimensionSCIP.Id - let solver = new KnapsackSolver(algorithm, name) + let solver = new KnapsackSolver(enum(algorithm), name) // transform lists to compatible structures for C++ Solver let profits = new KInt64Vector( List.toArray profits ) @@ -234,7 +234,9 @@ module FSharp = | LP lp -> lp.Id | IP ip -> ip.Id - let solver = new Solver(solverOptions.SolverName, algorithm) + let solverType = enum(algorithm) + + let solver = new Solver(solverOptions.SolverName, solverType) // Detect errors on required parameters if (solverOptions.ConstraintMatrix.IsNone && solverOptions.ConstraintVectorUpperBound.IsNone && solverOptions.ConstraintVectorLowerBound.IsNone) @@ -343,7 +345,7 @@ module FSharp = let resultStatus = solver.Solve(); match resultStatus with - | status when status <> Solver.OPTIMAL -> + | status when status <> Solver.ResultStatus.OPTIMAL -> printfn "The problem does not have an optimal solution!" exit 0 | _ -> @@ -355,4 +357,3 @@ module FSharp = printfn "%-10s: %f " (sprintf "var[%i]" i) ((solver.LookupVariableOrNull(sprintf "var[%i]" i)).SolutionValue()) solver - diff --git a/ortools/graph/csharp/graph.i b/ortools/graph/csharp/graph.i index 67f16a694c..fc8197f254 100644 --- a/ortools/graph/csharp/graph.i +++ b/ortools/graph/csharp/graph.i @@ -22,7 +22,8 @@ // - examples/csharp/assignment.cs // - examples/csharp/csflow.cs -%include +%include "enums.swg" +%include "stdint.i" %include "ortools/base/base.i" diff --git a/ortools/graph/java/graph.i b/ortools/graph/java/graph.i index cd3e0c3e10..b1e80e25b9 100644 --- a/ortools/graph/java/graph.i +++ b/ortools/graph/java/graph.i @@ -29,7 +29,8 @@ // // TODO(user): test all the APIs that are currently marked as 'untested'. -%include +%include "enums.swg" +%include "stdint.i" %include "ortools/base/base.i" diff --git a/ortools/graph/python/graph.i b/ortools/graph/python/graph.i index 4949c98532..3cc3cb495f 100644 --- a/ortools/graph/python/graph.i +++ b/ortools/graph/python/graph.i @@ -26,11 +26,11 @@ // // TODO(user): test all the APIs that are currently marked as 'untested'. -%include +%include "stdint.i" %include "ortools/base/base.i" -%include "ortools/util/python/vector.i" +%import "ortools/util/python/vector.i" %import "ortools/graph/ebert_graph.h" diff --git a/ortools/graph/samples/SimpleMaxFlowProgram.cs b/ortools/graph/samples/SimpleMaxFlowProgram.cs index 117e9eaf56..ed1360fc30 100644 --- a/ortools/graph/samples/SimpleMaxFlowProgram.cs +++ b/ortools/graph/samples/SimpleMaxFlowProgram.cs @@ -45,11 +45,11 @@ public class SimpleMaxFlowProgram // [START solve] // Find the maximum flow between node 0 and node 4. - int solveStatus = maxFlow.Solve(0, 4); + MaxFlow.Status solveStatus = maxFlow.Solve(0, 4); // [END solve] // [START print_solution] - if (solveStatus == MaxFlow.OPTIMAL) + if (solveStatus == MaxFlow.Status.OPTIMAL) { Console.WriteLine("Max. flow: " + maxFlow.OptimalFlow()); Console.WriteLine(""); diff --git a/ortools/graph/samples/SimpleMinCostFlowProgram.cs b/ortools/graph/samples/SimpleMinCostFlowProgram.cs index ef98b30c04..254e3a7fa2 100644 --- a/ortools/graph/samples/SimpleMinCostFlowProgram.cs +++ b/ortools/graph/samples/SimpleMinCostFlowProgram.cs @@ -57,11 +57,11 @@ public class SimpleMinCostFlowProgram // [START solve] // Find the min cost flow. - int solveStatus = minCostFlow.Solve(); + MinCostFlow.Status solveStatus = minCostFlow.Solve(); // [END solve] // [START print_solution] - if (solveStatus == MinCostFlow.OPTIMAL) + if (solveStatus == MinCostFlow.Status.OPTIMAL) { Console.WriteLine("Minimum cost: " + minCostFlow.OptimalCost()); Console.WriteLine(""); diff --git a/ortools/linear_solver/csharp/SolverHelper.cs b/ortools/linear_solver/csharp/SolverHelper.cs index 139e977283..af46970860 100644 --- a/ortools/linear_solver/csharp/SolverHelper.cs +++ b/ortools/linear_solver/csharp/SolverHelper.cs @@ -191,10 +191,10 @@ public partial class Solver { } public static Solver CreateSolver(String name, String type) { - System.Reflection.FieldInfo fieldInfo = - typeof(Solver).GetField(type); - if (fieldInfo != null) { - return new Solver(name, (int)fieldInfo.GetValue(null)); + Solver.OptimizationProblemType solver_type = + Solver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING; + if (Enum.TryParse(type, true, out solver_type)) { + return new Solver(name, solver_type); } else { return null; } diff --git a/ortools/linear_solver/csharp/linear_solver.i b/ortools/linear_solver/csharp/linear_solver.i index 30589db909..94836668d5 100644 --- a/ortools/linear_solver/csharp/linear_solver.i +++ b/ortools/linear_solver/csharp/linear_solver.i @@ -28,9 +28,9 @@ // - examples/csharp/cslinearprogramming.cs // - examples/csharp/csintegerprogramming.cs - -%include -%include +%include "enums.swg" +%include "stdint.i" +%include "std_vector.i" %include "ortools/base/base.i" diff --git a/ortools/linear_solver/java/linear_solver.i b/ortools/linear_solver/java/linear_solver.i index 6277387e2c..0fc54717c7 100644 --- a/ortools/linear_solver/java/linear_solver.i +++ b/ortools/linear_solver/java/linear_solver.i @@ -25,15 +25,16 @@ // // TODO(user): unit test all the APIs that are currently marked with 'no test'. -%include // For native Java enum support. -%include +%include "enums.swg" // For native Java enum support. +%include "stdint.i" %include "ortools/base/base.i" // We prefer our in-house vector wrapper to std_vector.i, because it // converts to and from native java arrays. -%include "ortools/util/java/vector.i" +%import "ortools/util/java/vector.i" +%include "ortools/util/java/proto.i" // We need to forward-declare the proto here, so that the PROTO_* macros // involving them work correctly. The order matters very much: this declaration @@ -55,6 +56,7 @@ typedef uint64_t uint64; import java.lang.reflect.*; %} + %extend operations_research::MPSolver { std::string exportModelAsLpFormat(bool obfuscated) { std::string output; diff --git a/ortools/linear_solver/python/linear_solver.i b/ortools/linear_solver/python/linear_solver.i index 5986f42420..6d092fc047 100644 --- a/ortools/linear_solver/python/linear_solver.i +++ b/ortools/linear_solver/python/linear_solver.i @@ -28,10 +28,12 @@ // // TODO(user): test all the APIs that are currently marked as 'untested'. -%include +%include "stdint.i" %include "ortools/base/base.i" -%include "ortools/util/python/vector.i" +%import "ortools/util/python/vector.i" + +%include "ortools/util/python/proto.i" // We need to forward-declare the proto here, so that the PROTO_* macros // involving them work correctly. The order matters very much: this declaration diff --git a/ortools/linear_solver/samples/SimpleMipProgram.cs b/ortools/linear_solver/samples/SimpleMipProgram.cs index 83aa03866e..29f7dd1512 100644 --- a/ortools/linear_solver/samples/SimpleMipProgram.cs +++ b/ortools/linear_solver/samples/SimpleMipProgram.cs @@ -48,9 +48,9 @@ public class SimpleMipProgram // [END objective] // [START solve] - int resultStatus = solver.Solve(); + Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.OPTIMAL) + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; diff --git a/ortools/sat/cp_model_presolve.cc b/ortools/sat/cp_model_presolve.cc index c514d5b2a4..cd98d05ebb 100644 --- a/ortools/sat/cp_model_presolve.cc +++ b/ortools/sat/cp_model_presolve.cc @@ -1125,7 +1125,7 @@ void ExtractEnforcementLiteralFromLinearConstraint(ConstraintProto* ct, for (int i = 0; i < arg.vars_size(); ++i) { // Only work with binary variables. // - // TODO(user): This could be generalized to non-binary variable + // TODO(user,user): This could be generalized to non-binary variable // but that would require introducing the encoding "literal <=> integer // variable at is min/max" and using this literal in the enforcement list. // It is thus a bit more involved, and might not be as useful. diff --git a/ortools/sat/csharp/sat.i b/ortools/sat/csharp/sat.i index 005c54bff0..766b6c76d6 100644 --- a/ortools/sat/csharp/sat.i +++ b/ortools/sat/csharp/sat.i @@ -17,7 +17,7 @@ using System.Runtime.InteropServices; using System.Collections; %} -%include +%include "stdint.i" %include "ortools/base/base.i" %include "ortools/util/csharp/proto.i" diff --git a/ortools/sat/java/sat.i b/ortools/sat/java/sat.i index 24695a2b91..42db3e97d2 100644 --- a/ortools/sat/java/sat.i +++ b/ortools/sat/java/sat.i @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +%include "stdint.i" + %include "ortools/base/base.i" %include "ortools/util/java/proto.i" @@ -21,6 +23,9 @@ #include "ortools/sat/swig_helper.h" %} +typedef int64_t int64; +typedef uint64_t uint64; + %module(directors="1") operations_research_sat PROTO_INPUT(operations_research::sat::CpModelProto, diff --git a/ortools/sat/linear_programming_constraint.cc b/ortools/sat/linear_programming_constraint.cc index eb9902e9a5..cfc3e810a8 100644 --- a/ortools/sat/linear_programming_constraint.cc +++ b/ortools/sat/linear_programming_constraint.cc @@ -641,6 +641,7 @@ bool LinearProgrammingConstraint::ComputeNewLinearConstraint( // Scale the lp_multipliers to the CP world (still Fractional though). std::vector> cp_multipliers; + Fractional max_cp_multi = 0.0; Fractional min_cp_multi = glop::kInfinity; const Fractional global_scaling = bound_scaling_factor_ / lp_data_.objective_scaling_factor(); @@ -663,6 +664,7 @@ bool LinearProgrammingConstraint::ComputeNewLinearConstraint( (1e6 / magnitude_diff) / std::abs(cp_multi); *scaling = std::max(*scaling, wanted_scaling); + max_cp_multi = std::max(std::abs(cp_multi), max_cp_multi); min_cp_multi = std::min(std::abs(cp_multi), min_cp_multi); cp_multipliers.push_back({row, cp_multi}); } @@ -673,6 +675,11 @@ bool LinearProgrammingConstraint::ComputeNewLinearConstraint( *scaling = std::max(*scaling, 1e6 / lp_multipliers_norm); } + // Make sure the scaled coeff are not too big. + if (max_cp_multi > 0.0) { + *scaling = std::min(*scaling, 1e12 / max_cp_multi); + } + // Scale the multipliers by *scaling. // // TODO(user): Maybe use int128 to avoid overflow? @@ -759,6 +766,9 @@ IntegerValue LinearProgrammingConstraint::ExactLpReasonning() { // The "objective constraint" behave like if the unscaled cp multiplier was // 1.0, so we will multiply it by this number and add it to reduced_costs. const IntegerValue obj_scale(std::round(scaling)); + if (obj_scale == 0) { + return kMinIntegerValue; // Overflow. + } if (!AddLinearExpressionMultiple(obj_scale, integer_objective_, &reduced_costs)) { return kMinIntegerValue; // Overflow. diff --git a/ortools/sat/python/sat.i b/ortools/sat/python/sat.i index e1fe24e399..ac00d5313f 100644 --- a/ortools/sat/python/sat.i +++ b/ortools/sat/python/sat.i @@ -13,7 +13,7 @@ // This .i file exposes the sat cp_model API. -%include +%include "stdint.i" %include "ortools/base/base.i" %include "ortools/util/python/proto.i" @@ -32,7 +32,6 @@ typedef uint64_t uint64; %module(directors="1") operations_research_sat - PY_PROTO_TYPEMAP(ortools.sat.cp_model_pb2, CpModelProto, operations_research::sat::CpModelProto); @@ -92,3 +91,4 @@ PY_PROTO_TYPEMAP(ortools.sat.sat_parameters_pb2, %include "ortools/sat/swig_helper.h" %unignoreall + diff --git a/ortools/sat/sat_solver.cc b/ortools/sat/sat_solver.cc index c1d4faae00..3d42aea9e5 100644 --- a/ortools/sat/sat_solver.cc +++ b/ortools/sat/sat_solver.cc @@ -74,8 +74,12 @@ void SatSolver::SetNumVariables(int num_variables) { trail_->Resize(num_variables); decision_policy_->IncreaseNumVariables(num_variables); pb_constraints_.Resize(num_variables); - decisions_.resize(num_variables); same_reason_identifier_.Resize(num_variables); + + // The +1 is a bit tricky, it is because in + // EnqueueDecisionAndBacktrackOnConflict() we artificially enqueue the + // decision before checking if it is not already assigned. + decisions_.resize(num_variables + 1); } int64 SatSolver::num_branches() const { return counters_.num_branches; } @@ -815,6 +819,7 @@ int SatSolver::EnqueueDecisionAndBacktrackOnConflict(Literal true_literal) { CHECK(PropagationIsDone()); if (is_model_unsat_) return kUnsatTrailIndex; + DCHECK_LT(CurrentDecisionLevel(), decisions_.size()); decisions_[CurrentDecisionLevel()].literal = true_literal; int first_propagation_index = trail_->Index(); ReapplyDecisionsUpTo(CurrentDecisionLevel(), &first_propagation_index); @@ -1472,8 +1477,8 @@ std::string SatSolver::StatusString(Status status) const { std::string SatSolver::RunningStatisticsString() const { const double time_in_s = timer_.Get(); return absl::StrFormat( - "%6.2fs, mem:%s, fails:%d, " - "depth:%d, clauses:%d, tmp:%d, bin:%u, restarts:%d, vars:%d", + "%6.2fs, mem:%s, fails:%d, depth:%d, clauses:%d, tmp:%d, bin:%u, " + "restarts:%d, vars:%d", time_in_s, MemoryUsage(), counters_.num_failures, CurrentDecisionLevel(), clauses_propagator_.num_clauses() - clauses_propagator_.num_removable_clauses(), diff --git a/ortools/util/csharp/vector.i b/ortools/util/csharp/vector.i index f78b30a46a..39243407bb 100644 --- a/ortools/util/csharp/vector.i +++ b/ortools/util/csharp/vector.i @@ -17,8 +17,8 @@ // Normally we'd simply use %include "std_vector.i" with the %template // directive (see http://www.swig.org/Doc1.3/Library.html#Library_nn15), but // in google3 we can't, because exceptions are forbidden. -// -// TODO(user): move to base/swig/java. + +%include "stdint.i" %include "ortools/base/base.i" @@ -27,6 +27,9 @@ #include "ortools/base/integral_types.h" %} +typedef int64_t int64; +typedef uint64_t uint64; + %define VECTOR_AS_CSHARP_ARRAY(TYPE, CTYPE, CSHARPTYPE) %typemap(ctype) const std::vector& %{ int length$argnum, CTYPE* %} %typemap(imtype) const std::vector& %{ int length$argnum, CSHARPTYPE[] %} diff --git a/ortools/util/java/vector.i b/ortools/util/java/vector.i index badeb665e4..844a161ebc 100644 --- a/ortools/util/java/vector.i +++ b/ortools/util/java/vector.i @@ -20,7 +20,8 @@ // // TODO(user): move to base/swig/java. -%include +%include "stdint.i" + %include "ortools/base/base.i" %{ diff --git a/ortools/util/python/proto.i b/ortools/util/python/proto.i index 70d2331950..43ca643310 100644 --- a/ortools/util/python/proto.i +++ b/ortools/util/python/proto.i @@ -1,4 +1,4 @@ -// Copyright 2010-2014 Google +// 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 @@ -11,7 +11,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// TODO(user): make this SWIG file comply with the SWIG style guide. %include "ortools/base/base.i" %import "ortools/base/integral_types.h" diff --git a/ortools/util/python/vector.i b/ortools/util/python/vector.i index 17d31c57cd..fc9bd0e8ba 100644 --- a/ortools/util/python/vector.i +++ b/ortools/util/python/vector.i @@ -29,11 +29,7 @@ // Note(user): for an unknown reason, using the (handy) method PyObjAs() // defined in base/swig/python-swig.cc seems to cause issues, so we can't // use a generic, templated type checker. - // Get const std::vector& "in" typemap. -%include "python/std_vector.i" -%include "python/std_map.i" -%include "python/std_set.i" -%include "python/std_list.i" + // Get const std::vector& "in" typemap. %define PY_LIST_OUTPUT_TYPEMAP(type, checker, py_converter) %typecheck(SWIG_TYPECHECK_POINTER) const std::vector&, @@ -71,14 +67,12 @@ } %typemap(in,numinputs=0) std::vector* OUTPUT (std::vector temp), - std::unordered_set* OUTPUT (std::unordered_set temp), std::set* OUTPUT (std::set temp) { $1 = &temp; } %typemap(argout) std::vector* OUTPUT, - std::set* OUTPUT, - std::unordered_set* OUTPUT { + std::set* OUTPUT { %append_output(list_output_helper($1, &py_converter)); } %typemap(out) std::vector { @@ -88,9 +82,6 @@ $result = vector_output_helper($1, &py_converter); } -%apply std::vector* OUTPUT { std::vector* OUTPUT } -%apply std::set* OUTPUT { std::set* OUTPUT } - %enddef // PY_LIST_OUTPUT_TYPEMAP PY_LIST_OUTPUT_TYPEMAP(int, PyInt_Check, PyInt_FromLong); @@ -164,9 +155,6 @@ PY_LIST_OUTPUT_TYPEMAP(double, PyFloat_Check, PyFloat_FromDouble); } } -%apply const std::vector >& { - const std::vector >& -} %enddef // PY_LIST_LIST_INPUT_TYPEMAP PY_LIST_LIST_INPUT_TYPEMAP(int64, SwigPyIntOrLong_Check);