From 0948ef9a3fb8034967dfafd9db5897f59b8ee18e Mon Sep 17 00:00:00 2001 From: Driss Lahlou Date: Fri, 5 Aug 2016 15:38:20 +0200 Subject: [PATCH] sync code --- makefiles/Makefile.test.unix | 18 +++--- makefiles/Makefile.test.win | 14 +++-- src/constraint_solver/constraint_solver.h | 32 ++++++---- src/constraint_solver/csharp/routing.swig | 1 - src/constraint_solver/expr_cst.cc | 62 +++++++++---------- src/constraint_solver/interval.cc | 22 +++---- src/constraint_solver/local_search.cc | 1 - src/flatzinc/mznlib/cumulative.mzn | 31 +++++++++- src/linear_solver/java/linear_solver.swig | 1 - src/ortools/__init__.py | 13 ++++ src/ortools/algorithms/__init__.py | 12 ++++ src/ortools/constraint_solver/__init__.py | 12 ++++ src/ortools/graph/__init__.py | 12 ++++ src/ortools/linear_solver/__init__.py | 12 ++++ .../linear_solver_natural_api.py | 2 +- 15 files changed, 170 insertions(+), 75 deletions(-) diff --git a/makefiles/Makefile.test.unix b/makefiles/Makefile.test.unix index 08bcfd1673..bb5524e211 100755 --- a/makefiles/Makefile.test.unix +++ b/makefiles/Makefile.test.unix @@ -1,3 +1,5 @@ +TESTPYTHONPATH = $(OR_ROOT_FULL)$Ssrc:$(OR_ROOT_FULL)$Sdependencies$Ssources$Sprotobuf-$(PROTOBUF_TAG)$Spython + .PHONY : test test: test_cc test_python test_java test_csharp @@ -9,14 +11,14 @@ test_cc: cc $(BIN_DIR)/integer_programming test_python: python - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/hidato_table.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/tsp.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/pyflow_example.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/knapsack.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/linear_programming.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/python/integer_programming.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/tests/test_cp_api.py - PYTHONPATH=$(OR_ROOT_FULL)/src python$(PYTHON_VERSION) $(EX_DIR)/tests/test_lp_api.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/hidato_table.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/tsp.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/pyflow_example.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/knapsack.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/linear_programming.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/python/integer_programming.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/tests/test_cp_api.py + PYTHONPATH=$(TESTPYTHONPATH) python$(PYTHON_VERSION) $(EX_DIR)/tests/test_lp_api.py test_java: java run_RabbitsPheasants run_FlowExample run_Tsp run_LinearProgramming run_IntegerProgramming run_Knapsack run_MultiThreadIntegerProgramming diff --git a/makefiles/Makefile.test.win b/makefiles/Makefile.test.win index 76c10c5574..8ca606dcf1 100755 --- a/makefiles/Makefile.test.win +++ b/makefiles/Makefile.test.win @@ -1,3 +1,5 @@ +TESTPYTHONPATH = $(OR_ROOT_FULL)$Ssrc;$(OR_ROOT_FULL)$Sdependencies$Ssources$Sprotobuf-$(PROTOBUF_TAG)$Spython + test: test_cc test_python test_java test_csharp test_cc: cc @@ -9,12 +11,12 @@ test_cc: cc $(BIN_DIR)\\tsp.exe test_python: python - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\hidato_table.py - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\tsp.py - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\pyflow_example.py - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\knapsack.py - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\linear_programming.py - set PYTHONPATH=$(OR_ROOT_FULL)\\src && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\python\\integer_programming.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\hidato_table.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\tsp.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\pyflow_example.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\knapsack.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\\python\\linear_programming.py + set PYTHONPATH=$(TESTPYTHONPATH) && $(WINDOWS_PYTHON_PATH)\\python $(EX_DIR)\python\\integer_programming.py test_java: java run_RabbitsPheasants run_FlowExample run_Tsp run_LinearProgramming run_IntegerProgramming run_Knapsack run_MultiThreadIntegerProgramming diff --git a/src/constraint_solver/constraint_solver.h b/src/constraint_solver/constraint_solver.h index 9e04f3dda0..aa371b2302 100644 --- a/src/constraint_solver/constraint_solver.h +++ b/src/constraint_solver/constraint_solver.h @@ -1419,10 +1419,15 @@ class Solver { // Creates a demon from a closure. Demon* MakeClosureDemon(Closure closure); - // (l <= b <= u) + // ----- Between and related constraints ----- + + // (l <= v <= u) Constraint* MakeBetweenCt(IntExpr* const v, int64 l, int64 u); - // (b < l || b > u) + // (v < l || v > u) + // This constraint is lazy as it will not make holes in the domain of + // variables. It will propagate only when expr->Min() >= l + // or expr->Max() <= u. Constraint* MakeNotBetweenCt(IntExpr* const v, int64 l, int64 u); // b == (l <= v <= u) @@ -1430,23 +1435,16 @@ class Solver { IntVar* const b); IntVar* MakeIsBetweenVar(IntExpr* const v, int64 l, int64 u); - // b == (v in set) - Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, - IntVar* const b); - Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, - IntVar* const b); - IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); - IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); + // ----- Member and related constraints ----- + // v in set. Propagation is lazy, i.e. this constraint does not // creates holes in the domain of the variable. Constraint* MakeMemberCt(IntExpr* const v, const std::vector& values); Constraint* MakeMemberCt(IntExpr* const v, const std::vector& values); // v not in set. - Constraint* MakeNotMemberCt(IntExpr* const v, - const std::vector& values); - Constraint* MakeNotMemberCt(IntExpr* const v, - const std::vector& values); + Constraint* MakeNotMemberCt(IntExpr* const v, const std::vector& values); + Constraint* MakeNotMemberCt(IntExpr* const v, const std::vector& values); // v should not be in the list of forbidden intervals [start[i]..end[i]]. Constraint* MakeNotMemberCt(IntExpr* const v, std::vector starts, @@ -1459,6 +1457,14 @@ class Solver { Constraint* MakeNotMemberCt(IntExpr* v, SortedDisjointIntervalList intervals); #endif // !defined(SWIG) + // b == (v in set) + Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, + IntVar* const b); + Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, + IntVar* const b); + IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); + IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); + // |{i | v[i] == value}| == count Constraint* MakeCount(const std::vector& v, int64 value, int64 count); // |{i | v[i] == value}| == count diff --git a/src/constraint_solver/csharp/routing.swig b/src/constraint_solver/csharp/routing.swig index 5e1f4bc3b8..78e966b1dd 100644 --- a/src/constraint_solver/csharp/routing.swig +++ b/src/constraint_solver/csharp/routing.swig @@ -111,7 +111,6 @@ CS_TYPEMAP_STDVECTOR(operations_research::RoutingModel::NodeIndex, int, int); actualIndex++; } } - $1 = &result; %} diff --git a/src/constraint_solver/expr_cst.cc b/src/constraint_solver/expr_cst.cc index 86b3554374..35a78c67b8 100644 --- a/src/constraint_solver/expr_cst.cc +++ b/src/constraint_solver/expr_cst.cc @@ -856,6 +856,8 @@ class BetweenCt : public Constraint { Demon* demon_; }; +// ----- NonMember constraint ----- + class NotBetweenCt : public Constraint { public: NotBetweenCt(Solver* const s, IntExpr* const v, int64 l, int64 u) @@ -882,8 +884,8 @@ class NotBetweenCt : public Constraint { } std::string DebugString() const override { - return StringPrintf("NotBetweenCt(%s, %" GG_LL_FORMAT "d, %" - GG_LL_FORMAT "d)", + return StringPrintf("NotBetweenCt(%s, %" GG_LL_FORMAT "d, %" GG_LL_FORMAT + "d)", expr_->DebugString().c_str(), min_, max_); } @@ -1183,15 +1185,14 @@ Constraint* Solver::MakeMemberCt(IntExpr* expr, const std::vector& values copied_values.resize(num_kept); } // Filter out the values that are outside the [Min, Max] interval. - { - int num_kept = 0; - const int64 min = expr->Min(); - const int64 max = expr->Max(); - for (const int64 v : copied_values) { - if (v >= min && v <= max) copied_values[num_kept++] = v; - } - copied_values.resize(num_kept); + int num_kept = 0; + int64 emin; + int64 emax; + expr->Range(&emin, &emax); + for (const int64 v : copied_values) { + if (v >= emin && v <= emax) copied_values[num_kept++] = v; } + copied_values.resize(num_kept); // Catch empty set. if (copied_values.empty()) return MakeFalseConstraint(); // Sort and remove duplicates. @@ -1207,15 +1208,15 @@ Constraint* Solver::MakeMemberCt(IntExpr* expr, const std::vector& values // If the set of values in [expr.Min(), expr.Max()] that are *not* in // "values" is smaller than "values", then it's more efficient to use // NotMemberCt. Catch that case here. - const int64 min = expr->Min(); - const int64 max = expr->Max(); - if (max - min < 2 * copied_values.size()) { + if (emax - emin < 2 * copied_values.size()) { // Convert "copied_values" to list the values *not* allowed. - std::vector is_among_input_values(max - min + 1, false); - for (const int64 v : copied_values) is_among_input_values[v - min] = true; + std::vector is_among_input_values(emax - emin + 1, false); + for (const int64 v : copied_values) is_among_input_values[v - emin] = true; + // We use the zero valued indices of is_among_input_values to build the + // complement of copied_values. copied_values.clear(); for (int64 v_off = 0; v_off < is_among_input_values.size(); ++v_off) { - if (!is_among_input_values[v_off]) copied_values.push_back(v_off + min); + if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin); } // The empty' case (all values in range [expr.Min(), expr.Max()] are in the // "values" input) was caught earlier, by the "contiguous interval" case. @@ -1253,15 +1254,14 @@ Constraint* Solver::MakeNotMemberCt(IntExpr* expr, copied_values.resize(num_kept); } // Filter out the values that are outside the [Min, Max] interval. - { - int num_kept = 0; - const int64 min = expr->Min(); - const int64 max = expr->Max(); - for (const int64 v : copied_values) { - if (v >= min && v <= max) copied_values[num_kept++] = v; - } - copied_values.resize(num_kept); + int num_kept = 0; + int64 emin; + int64 emax; + expr->Range(&emin, &emax); + for (const int64 v : copied_values) { + if (v >= emin && v <= emax) copied_values[num_kept++] = v; } + copied_values.resize(num_kept); // Catch empty set. if (copied_values.empty()) return MakeTrueConstraint(); // Sort and remove duplicates. @@ -1276,15 +1276,15 @@ Constraint* Solver::MakeNotMemberCt(IntExpr* expr, // If the set of values in [expr.Min(), expr.Max()] that are *not* in // "values" is smaller than "values", then it's more efficient to use // MemberCt. Catch that case here. - const int64 min = expr->Min(); - const int64 max = expr->Max(); - if (max - min < 2 * copied_values.size()) { - // Convert "copied_values" to list the values *not* allowed. - std::vector is_among_input_values(max - min + 1, false); - for (const int64 v : copied_values) is_among_input_values[v - min] = true; + if (emax - emin < 2 * copied_values.size()) { + // Convert "copied_values" to a dense boolean vector. + std::vector is_among_input_values(emax - emin + 1, false); + for (const int64 v : copied_values) is_among_input_values[v - emin] = true; + // Use zero valued indices for is_among_input_values to build the + // complement of copied_values. copied_values.clear(); for (int64 v_off = 0; v_off < is_among_input_values.size(); ++v_off) { - if (!is_among_input_values[v_off]) copied_values.push_back(v_off + min); + if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin); } // The empty' case (all values in range [expr.Min(), expr.Max()] are in the // "values" input) was caught earlier, by the "contiguous interval" case. diff --git a/src/constraint_solver/interval.cc b/src/constraint_solver/interval.cc index 0d91739829..35c4cdcc42 100644 --- a/src/constraint_solver/interval.cc +++ b/src/constraint_solver/interval.cc @@ -1280,15 +1280,15 @@ int64 StartVarPerformedIntervalVar::EndMax() const { } void StartVarPerformedIntervalVar::SetEndMin(int64 m) { - SetStartMin(m - duration_); + SetStartMin(CapSub(m, duration_)); } void StartVarPerformedIntervalVar::SetEndMax(int64 m) { - SetStartMax(m - duration_); + SetStartMax(CapSub(m, duration_)); } void StartVarPerformedIntervalVar::SetEndRange(int64 mi, int64 ma) { - SetStartRange(mi - duration_, ma - duration_); + SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } void StartVarPerformedIntervalVar::SetDurationRange(int64 mi, int64 ma) { @@ -1751,12 +1751,12 @@ class VariableDurationIntervalVar : public BaseIntervalVar { int64 end_min, int64 end_max, bool optional, const std::string& name) : BaseIntervalVar(s, name), - start_(s, this, std::max(start_min, end_min - duration_max), - std::min(start_max, end_max - duration_min)), - duration_(s, this, std::max(duration_min, end_min - start_max), - std::min(duration_max, end_max - start_min)), - end_(s, this, std::max(end_min, start_min + duration_min), - std::min(end_max, start_max + duration_max)), + start_(s, this, std::max(start_min, CapSub(end_min, duration_max)), + std::min(start_max, CapSub(end_max, duration_min))), + duration_(s, this, std::max(duration_min, CapSub(end_min, start_max)), + std::min(duration_max, CapSub(end_max, start_min))), + end_(s, this, std::max(end_min, CapAdd(start_min, duration_min)), + std::min(end_max, CapAdd(start_max, duration_max))), performed_(s, this, optional) {} ~VariableDurationIntervalVar() override {} @@ -2414,13 +2414,13 @@ IntervalVar* Solver::MakeFixedDurationEndSyncedOnStartIntervalVar( IntervalVar* const interval_var, int64 duration, int64 offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart( - interval_var, duration, offset - duration))); + interval_var, duration, CapSub(offset, duration)))); } IntervalVar* Solver::MakeFixedDurationEndSyncedOnEndIntervalVar( IntervalVar* const interval_var, int64 duration, int64 offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd( - interval_var, duration, offset - duration))); + interval_var, duration, CapSub(offset, duration)))); } } // namespace operations_research diff --git a/src/constraint_solver/local_search.cc b/src/constraint_solver/local_search.cc index ec2de7276a..1b2686ce68 100644 --- a/src/constraint_solver/local_search.cc +++ b/src/constraint_solver/local_search.cc @@ -2589,7 +2589,6 @@ class LocalSearchProfiler : public LocalSearchMonitor { int accepted_neighbors = 0; double seconds = 0; }; - WallTimer timer_; std::string last_operator_; std::map operator_stats_; diff --git a/src/flatzinc/mznlib/cumulative.mzn b/src/flatzinc/mznlib/cumulative.mzn index c062b47fc2..e659f21f00 100644 --- a/src/flatzinc/mznlib/cumulative.mzn +++ b/src/flatzinc/mznlib/cumulative.mzn @@ -5,8 +5,35 @@ % Assumptions: % - forall i, d[i] >= 0 and r[i] >= 0 %-----------------------------------------------------------------------------% +predicate fixed_cumulative(array[int] of var int: s, + array[int] of int: d, + array[int] of int: r, + int: b); + +predicate var_cumulative(array[int] of var int: s, + array[int] of int: d, + array[int] of int: r, + var int: b); + +predicate variable_cumulative(array[int] of var int: s, + array[int] of var int: d, + array[int] of var int: r, + var int: b); + +predicate cumulative(array[int] of var int: s, + array[int] of int: d, + array[int] of int: r, + int: b) = + fixed_cumulative(s, d, r, b); + +predicate cumulative(array[int] of var int: s, + array[int] of int: d, + array[int] of int: r, + var int: b) = + var_cumulative(s, d, r, b); + predicate cumulative(array[int] of var int: s, array[int] of var int: d, array[int] of var int: r, - var int: b); - + var int: b) = + variable_cumulative(s, d, r, b); diff --git a/src/linear_solver/java/linear_solver.swig b/src/linear_solver/java/linear_solver.swig index 28db0fa70b..c562f3ca72 100644 --- a/src/linear_solver/java/linear_solver.swig +++ b/src/linear_solver/java/linear_solver.swig @@ -70,7 +70,6 @@ import java.lang.reflect.*; // Add java code on MPSolver. %typemap(javacode) operations_research::MPSolver %{ - public MPVariable[] makeVarArray(int count, double lb, double ub, boolean integer) { MPVariable[] array = new MPVariable[count]; for (int i = 0; i < count; ++i) { diff --git a/src/ortools/__init__.py b/src/ortools/__init__.py index 57741abe3d..8fe4794541 100644 --- a/src/ortools/__init__.py +++ b/src/ortools/__init__.py @@ -1 +1,14 @@ +# Copyright 2010-2014 Google +# 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. + __version__ = "VVVV" \ No newline at end of file diff --git a/src/ortools/algorithms/__init__.py b/src/ortools/algorithms/__init__.py index c4e25e6d8d..fd06bdbd52 100644 --- a/src/ortools/algorithms/__init__.py +++ b/src/ortools/algorithms/__init__.py @@ -1,3 +1,15 @@ +# Copyright 2010-2014 Google +# 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. import os as _os __path__.append(_os.path.join(__path__[0], '..', '..', 'gen', 'ortools', 'algorithms')) __path__.append(_os.path.join(__path__[0], '..', '..', '..', 'lib')) diff --git a/src/ortools/constraint_solver/__init__.py b/src/ortools/constraint_solver/__init__.py index 362e77d8df..caea6898ff 100644 --- a/src/ortools/constraint_solver/__init__.py +++ b/src/ortools/constraint_solver/__init__.py @@ -1,3 +1,15 @@ +# Copyright 2010-2014 Google +# 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. import os as _os __path__.append(_os.path.join(__path__[0], '..', '..', 'gen', 'ortools', 'constraint_solver')) __path__.append(_os.path.join(__path__[0], '..', '..', '..', 'lib')) diff --git a/src/ortools/graph/__init__.py b/src/ortools/graph/__init__.py index c0dd3b1db2..8f2def565f 100644 --- a/src/ortools/graph/__init__.py +++ b/src/ortools/graph/__init__.py @@ -1,3 +1,15 @@ +# Copyright 2010-2014 Google +# 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. import os as _os __path__.append(_os.path.join(__path__[0], '..', '..', 'gen', 'ortools', 'graph')) __path__.append(_os.path.join(__path__[0], '..', '..', '..', 'lib')) diff --git a/src/ortools/linear_solver/__init__.py b/src/ortools/linear_solver/__init__.py index 2d0db96333..58ec63a061 100644 --- a/src/ortools/linear_solver/__init__.py +++ b/src/ortools/linear_solver/__init__.py @@ -1,3 +1,15 @@ +# Copyright 2010-2014 Google +# 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. import os as _os __path__.append(_os.path.join(__path__[0], '..', '..', 'gen', 'ortools', 'linear_solver')) __path__.append(_os.path.join(__path__[0], '..', '..', '..', 'lib')) diff --git a/src/ortools/linear_solver/linear_solver_natural_api.py b/src/ortools/linear_solver/linear_solver_natural_api.py index e263a03ae2..0c44b330d7 100644 --- a/src/ortools/linear_solver/linear_solver_natural_api.py +++ b/src/ortools/linear_solver/linear_solver_natural_api.py @@ -225,6 +225,6 @@ class LinearConstraint(object): ub = self.__ub - constant constraint = solver.RowConstraint(lb, ub, name) - for v, c, in sorted(coeffs.items()): + for v, c, in coeffs.iteritems(): constraint.SetCoefficient(v, float(c)) return constraint