From fa6883d544e2fdbc00d1747622ca0a34aa8df436 Mon Sep 17 00:00:00 2001 From: Laurent Perron Date: Thu, 24 Aug 2023 14:52:54 +0200 Subject: [PATCH] mostly cleaning: remove integral_types.h and basictypes.h --- cmake/python.cmake | 4 +- examples/cpp/costas_array_sat.cc | 2 +- examples/cpp/cvrp_disjoint_tw.cc | 2 +- examples/cpp/cvrptw.cc | 2 +- examples/cpp/cvrptw_with_breaks.cc | 2 +- examples/cpp/cvrptw_with_refueling.cc | 2 +- examples/cpp/cvrptw_with_resources.cc | 2 +- .../cvrptw_with_stop_times_and_resources.cc | 2 +- examples/cpp/dobble_ls.cc | 2 +- examples/cpp/golomb_sat.cc | 2 +- examples/cpp/magic_sequence_sat.cc | 2 +- examples/cpp/magic_square_sat.cc | 2 +- examples/cpp/nqueens.cc | 2 +- examples/tests/remote/tsp.cc | 2 +- ortools/algorithms/set_cover_model.cc | 11 +- ortools/algorithms/set_cover_model.h | 1 + ortools/base/BUILD.bazel | 44 +-- ortools/base/adjustable_priority_queue.h | 2 +- ortools/base/base.i | 2 +- ortools/base/basictypes.h | 21 -- ortools/base/bitmap.cc | 2 +- ortools/base/bitmap.h | 2 +- ortools/base/container_logging.h | 2 +- ortools/base/file.h | 2 +- ortools/base/gzipfile.h | 2 +- ortools/base/hash.h | 2 +- ortools/base/integral_types.h | 19 -- ortools/base/mathutil.h | 4 +- ortools/base/stl_util.h | 2 +- ortools/base/sysinfo.h | 2 +- ortools/base/timer.h | 2 +- ortools/base/vlog.h | 2 +- ortools/base/vlog_is_on.h | 2 +- ortools/bop/bop_base.h | 2 +- ortools/bop/bop_fs.h | 2 +- ortools/bop/bop_lns.h | 2 +- ortools/bop/bop_solver.h | 2 +- ortools/bop/bop_types.h | 2 +- ortools/bop/bop_util.cc | 2 +- ortools/bop/bop_util.h | 2 +- .../csharp/constraint_solver.i | 2 +- .../java/constraint_solver.i | 2 +- ortools/constraint_solver/routing_filters.cc | 14 +- ortools/constraint_solver/routing_flags.h | 2 +- ortools/flatzinc/parser.yy.cc | 2 +- ortools/linear_solver/cplex_interface.cc | 2 +- .../linear_solver_natural_api.py | 265 ---------------- ortools/linear_solver/model_exporter.cc | 2 +- ortools/linear_solver/python/linear_solver.i | 20 +- .../python/linear_solver_natural_api.py | 283 ++++++++++++++++++ ortools/linear_solver/sat_interface.cc | 2 +- ortools/linear_solver/scip_interface.cc | 2 +- ortools/linear_solver/xpress_interface.cc | 2 +- ortools/lp_data/BUILD.bazel | 2 +- ortools/lp_data/scattered_vector.h | 2 +- ortools/math_opt/core/sparse_vector_view.h | 2 +- .../validators/model_parameters_validator.cc | 2 +- ortools/pdlp/quadratic_program_io.cc | 2 +- ortools/port/sysinfo.h | 2 +- ortools/routing/samples/cvrp_disjoint_tw.cc | 2 +- ortools/routing/samples/cvrptw.cc | 2 +- .../routing/samples/cvrptw_soft_capacity.cc | 2 +- ortools/routing/samples/cvrptw_with_breaks.cc | 2 +- .../samples/cvrptw_with_precedences.cc | 2 +- .../routing/samples/cvrptw_with_refueling.cc | 2 +- .../routing/samples/cvrptw_with_resources.cc | 2 +- .../cvrptw_with_stop_times_and_resources.cc | 2 +- .../cvrptw_with_time_dependent_costs.cc | 2 +- ortools/routing/solomon_parser.cc | 2 +- ortools/routing/solomon_parser.h | 2 +- ortools/routing/solomon_parser_test.cc | 2 +- ortools/routing/tsplib_parser.h | 2 +- ortools/routing/tsplib_parser_test.cc | 2 +- ortools/routing/tsptw_parser.h | 2 +- ortools/routing/tsptw_parser_test.cc | 2 +- ortools/sat/all_different.h | 2 +- ortools/sat/circuit.h | 2 +- ortools/sat/clause.h | 2 +- ortools/sat/cp_constraints.h | 2 +- ortools/sat/cp_model.proto | 9 +- ortools/sat/cp_model_checker.h | 2 +- ortools/sat/cp_model_expand.cc | 2 +- ortools/sat/cp_model_lns.h | 2 +- ortools/sat/cp_model_loader.cc | 3 +- ortools/sat/cp_model_loader.h | 2 +- ortools/sat/cp_model_mapping.h | 2 +- ortools/sat/cp_model_postsolve.h | 2 +- ortools/sat/cp_model_search.h | 2 +- ortools/sat/cp_model_solver.cc | 16 +- ortools/sat/cp_model_solver.h | 2 +- ortools/sat/cuts.cc | 11 +- ortools/sat/encoding.h | 2 +- ortools/sat/implied_bounds.h | 2 +- ortools/sat/integer.h | 10 +- ortools/sat/integer_expr.cc | 2 +- ortools/sat/integer_expr.h | 2 +- ortools/sat/integer_search.cc | 73 +---- ortools/sat/linear_programming_constraint.cc | 93 +++--- ortools/sat/linear_programming_constraint.h | 13 +- ortools/sat/parameters_validation.cc | 1 - ortools/sat/pb_constraint.h | 2 +- ortools/sat/precedences.h | 2 +- ortools/sat/presolve_util.h | 2 +- .../sat/samples/step_function_sample_sat.cc | 2 +- ortools/sat/sat_base.h | 2 +- ortools/sat/sat_decision.h | 2 +- ortools/sat/sat_parameters.proto | 13 +- ortools/sat/sat_solver.h | 2 +- ortools/sat/simplification.h | 2 +- ortools/util/BUILD.bazel | 4 +- ortools/util/adaptative_parameter_value.h | 2 +- ortools/util/bitset.h | 2 +- ortools/util/cached_log.h | 4 +- ortools/util/csharp/proto.i | 2 +- ortools/util/csharp/vector.i | 2 +- ortools/util/fp_utils.cc | 2 +- ortools/util/fp_utils.h | 2 +- ortools/util/functions_swig_helpers.h | 2 +- ortools/util/functions_swig_test_helpers.h | 2 +- ortools/util/java/functions.i | 2 +- ortools/util/java/proto.i | 2 +- ortools/util/java/sorted_interval_list.i | 2 +- ortools/util/java/tuple_set.i | 2 +- ortools/util/java/vector.i | 2 +- ortools/util/piecewise_linear_function.h | 4 +- ortools/util/python/proto.i | 2 +- ortools/util/python/vector.i | 2 +- ortools/util/range_query_function.cc | 2 +- ortools/util/range_query_function.h | 2 +- ortools/util/rational_approximation.h | 2 +- ortools/util/saturated_arithmetic.h | 2 +- ortools/util/sorted_interval_list.cc | 2 +- ortools/util/sorted_interval_list.h | 2 +- ortools/util/stats.cc | 2 +- ortools/util/tuple_set.h | 2 +- ortools/util/vector_or_function.h | 2 +- ortools/util/zvector.h | 2 +- 137 files changed, 530 insertions(+), 636 deletions(-) delete mode 100644 ortools/base/basictypes.h delete mode 100644 ortools/base/integral_types.h delete mode 100644 ortools/linear_solver/linear_solver_natural_api.py create mode 100644 ortools/linear_solver/python/linear_solver_natural_api.py diff --git a/cmake/python.cmake b/cmake/python.cmake index 4fb14ca6299..a198b96e9fd 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -272,8 +272,8 @@ file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/util/__init__.py CONTENT "") file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/util/python/__init__.py CONTENT "") file(COPY - ortools/linear_solver/linear_solver_natural_api.py - DESTINATION ${PYTHON_PROJECT_DIR}/linear_solver) + ortools/linear_solver/python/linear_solver_natural_api.py + DESTINATION ${PYTHON_PROJECT_DIR}/linear_solver/python) file(COPY ortools/linear_solver/python/model_builder.py ortools/linear_solver/python/model_builder_numbers.py diff --git a/examples/cpp/costas_array_sat.cc b/examples/cpp/costas_array_sat.cc index 74f51877a70..f69baa4cda6 100644 --- a/examples/cpp/costas_array_sat.cc +++ b/examples/cpp/costas_array_sat.cc @@ -32,7 +32,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/sat/cp_model.h" #include "ortools/sat/model.h" diff --git a/examples/cpp/cvrp_disjoint_tw.cc b/examples/cpp/cvrp_disjoint_tw.cc index 6d1e6de0c92..800b880df7f 100644 --- a/examples/cpp/cvrp_disjoint_tw.cc +++ b/examples/cpp/cvrp_disjoint_tw.cc @@ -30,7 +30,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/examples/cpp/cvrptw.cc b/examples/cpp/cvrptw.cc index c9aa53597fe..80d227cbeb3 100644 --- a/examples/cpp/cvrptw.cc +++ b/examples/cpp/cvrptw.cc @@ -29,7 +29,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/examples/cpp/cvrptw_with_breaks.cc b/examples/cpp/cvrptw_with_breaks.cc index 2e1083ddb4c..6a30b8bbaca 100644 --- a/examples/cpp/cvrptw_with_breaks.cc +++ b/examples/cpp/cvrptw_with_breaks.cc @@ -34,7 +34,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_enums.pb.h" diff --git a/examples/cpp/cvrptw_with_refueling.cc b/examples/cpp/cvrptw_with_refueling.cc index dcc54f12aa8..e9ba95ca521 100644 --- a/examples/cpp/cvrptw_with_refueling.cc +++ b/examples/cpp/cvrptw_with_refueling.cc @@ -27,7 +27,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/examples/cpp/cvrptw_with_resources.cc b/examples/cpp/cvrptw_with_resources.cc index bb651942fb7..eebc0602794 100644 --- a/examples/cpp/cvrptw_with_resources.cc +++ b/examples/cpp/cvrptw_with_resources.cc @@ -29,7 +29,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/examples/cpp/cvrptw_with_stop_times_and_resources.cc b/examples/cpp/cvrptw_with_stop_times_and_resources.cc index 50df1a5c5aa..d652fb22361 100644 --- a/examples/cpp/cvrptw_with_stop_times_and_resources.cc +++ b/examples/cpp/cvrptw_with_stop_times_and_resources.cc @@ -28,7 +28,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/examples/cpp/dobble_ls.cc b/examples/cpp/dobble_ls.cc index 82d017470dd..a1e5090fa0a 100644 --- a/examples/cpp/dobble_ls.cc +++ b/examples/cpp/dobble_ls.cc @@ -40,7 +40,7 @@ #include "absl/strings/str_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/map_util.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/util/bitset.h" diff --git a/examples/cpp/golomb_sat.cc b/examples/cpp/golomb_sat.cc index 51192639e3c..ba732e4ac4b 100644 --- a/examples/cpp/golomb_sat.cc +++ b/examples/cpp/golomb_sat.cc @@ -32,7 +32,7 @@ #include "absl/strings/str_format.h" #include "google/protobuf/text_format.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/sat/cp_model.h" #include "ortools/sat/model.h" diff --git a/examples/cpp/magic_sequence_sat.cc b/examples/cpp/magic_sequence_sat.cc index c32d63c87d7..0a7d82d163d 100644 --- a/examples/cpp/magic_sequence_sat.cc +++ b/examples/cpp/magic_sequence_sat.cc @@ -25,7 +25,7 @@ #include "absl/flags/flag.h" #include "absl/strings/str_format.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/sat/cp_model.h" diff --git a/examples/cpp/magic_square_sat.cc b/examples/cpp/magic_square_sat.cc index c1ee26e1c2a..8264b43870d 100644 --- a/examples/cpp/magic_square_sat.cc +++ b/examples/cpp/magic_square_sat.cc @@ -18,7 +18,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/sat/cp_model.h" #include "ortools/sat/model.h" diff --git a/examples/cpp/nqueens.cc b/examples/cpp/nqueens.cc index 7898f6e008b..546c725fb0c 100644 --- a/examples/cpp/nqueens.cc +++ b/examples/cpp/nqueens.cc @@ -26,7 +26,7 @@ #include "absl/strings/str_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/map_util.h" #include "ortools/constraint_solver/constraint_solveri.h" diff --git a/examples/tests/remote/tsp.cc b/examples/tests/remote/tsp.cc index 06b40ac71bd..0058fdec5d6 100644 --- a/examples/tests/remote/tsp.cc +++ b/examples/tests/remote/tsp.cc @@ -26,7 +26,7 @@ #include "base/callback.h" #include "base/commandlineflags.h" -#include "base/integral_types.h" +#include "base/types.h" #include "base/join.h" #include "base/random.h" #include "base/unique_ptr.h" diff --git a/ortools/algorithms/set_cover_model.cc b/ortools/algorithms/set_cover_model.cc index aa1ac0404ff..b9429fc16ca 100644 --- a/ortools/algorithms/set_cover_model.cc +++ b/ortools/algorithms/set_cover_model.cc @@ -25,13 +25,16 @@ void SetCoverModel::AddEmptySubset(Cost cost) { row_view_is_valid_ = false; } -void SetCoverModel::AddElementToLastSubset(int element) { - ElementIndex new_element(element); - columns_.back().push_back(new_element); - num_elements_ = std::max(num_elements_, new_element + 1); +void SetCoverModel::AddElementToLastSubset(ElementIndex element) { + columns_.back().push_back(element); + num_elements_ = std::max(num_elements_, element + 1); row_view_is_valid_ = false; } +void SetCoverModel::AddElementToLastSubset(int element) { + AddElementToLastSubset(ElementIndex(element)); +} + void SetCoverModel::SetSubsetCost(int subset, Cost cost) { const SubsetIndex subset_index(subset); const SubsetIndex size = std::max(columns_.size(), subset_index + 1); diff --git a/ortools/algorithms/set_cover_model.h b/ortools/algorithms/set_cover_model.h index 97e3a0c9df0..158a0913be6 100644 --- a/ortools/algorithms/set_cover_model.h +++ b/ortools/algorithms/set_cover_model.h @@ -101,6 +101,7 @@ class SetCoverModel { // Adds an element to the last subset created. In matrix terms, this adds a // 1 on row 'element' of the current last column of the matrix. void AddElementToLastSubset(int element); + void AddElementToLastSubset(ElementIndex element); // Sets 'cost' to an already existing 'subset'. void SetSubsetCost(int subset, Cost cost); diff --git a/ortools/base/BUILD.bazel b/ortools/base/BUILD.bazel index aa97698ab61..9e7ea78a8ba 100644 --- a/ortools/base/BUILD.bazel +++ b/ortools/base/BUILD.bazel @@ -44,10 +44,8 @@ cc_library( hdrs = [ "commandlineflags.h", "init_google.h", - "integral_types.h", "logging.h", "stl_logging.h", - "types.h", "version.h", ], copts = [ @@ -63,10 +61,9 @@ cc_library( }), deps = [ ":commandlineflags", - ":integral_types", + ":types", ":logging", ":macros", - ":types", "@com_google_absl//absl/base", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", @@ -95,24 +92,20 @@ cc_library( ], deps = [ ":base", - ":basictypes", + ":types", ], ) cc_library( - name = "basictypes", - hdrs = ["basictypes.h"], - deps = [ - ":integral_types", - ":logging", - ], + name = "types", + hdrs = ["types.h"], ) cc_library( name = "bitmap", srcs = ["bitmap.cc"], hdrs = ["bitmap.h"], - deps = [":integral_types"], + deps = [":types"], ) cc_library( @@ -242,7 +235,7 @@ cc_library( hdrs = ["gzipfile.h"], deps = [ ":base", - ":basictypes", + ":types", ":file", ":path", "@com_google_absl//absl/strings", @@ -268,7 +261,7 @@ cc_library( "hash.h", ], deps = [ - ":integral_types", + ":types", "@com_google_absl//absl/strings", ], ) @@ -279,12 +272,6 @@ cc_library( deps = [":base"], ) -cc_library( - name = "integral_types", - hdrs = ["integral_types.h"], - deps = [":types"], -) - cc_library( name = "intops", hdrs = ["strong_int.h"], @@ -330,11 +317,6 @@ cc_library( ], ) -cc_library( - name = "types", - hdrs = ["types.h"], -) - cc_library( name = "vlog", srcs = ["vlog_is_on.cc"], @@ -343,7 +325,7 @@ cc_library( "vlog_is_on.h", ], deps = [ - ":integral_types", + ":types", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/log", "@com_google_absl//absl/log:check", @@ -366,7 +348,7 @@ cc_library( hdrs = ["mathutil.h"], deps = [ ":base", - ":basictypes", + ":types", ], ) @@ -501,7 +483,7 @@ cc_library( srcs = ["strtoint.cc"], hdrs = ["strtoint.h"], deps = [ - ":integral_types", + ":types", "@com_google_absl//absl/log:check", "@com_google_absl//absl/strings", ], @@ -512,7 +494,7 @@ cc_library( srcs = ["sysinfo.cc"], hdrs = ["sysinfo.h"], deps = [ - ":integral_types", + ":types", "@com_google_absl//absl/strings", ], ) @@ -532,7 +514,7 @@ cc_library( srcs = ["timer.cc"], hdrs = ["timer.h"], deps = [ - ":integral_types", + ":types", ":macros", "@com_google_absl//absl/log:check", "@com_google_absl//absl/time", @@ -549,7 +531,7 @@ cc_library( srcs = ["zipfile.cc"], hdrs = ["zipfile.h"], deps = [ - ":basictypes", + ":types", ":file", ":path", ":stl_util", diff --git a/ortools/base/adjustable_priority_queue.h b/ortools/base/adjustable_priority_queue.h index 005c4f636cd..14a86bbb1e8 100644 --- a/ortools/base/adjustable_priority_queue.h +++ b/ortools/base/adjustable_priority_queue.h @@ -20,7 +20,7 @@ #include #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" diff --git a/ortools/base/base.i b/ortools/base/base.i index 2f99f454f1c..f28dbbcb285 100644 --- a/ortools/base/base.i +++ b/ortools/base/base.i @@ -16,7 +16,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" %} %include "typemaps.i" diff --git a/ortools/base/basictypes.h b/ortools/base/basictypes.h deleted file mode 100644 index 64356dd1d1b..00000000000 --- a/ortools/base/basictypes.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2010-2022 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. - -// Basic integer type definitions for various platforms -// -#ifndef OR_TOOLS_BASE_BASICTYPES_H_ -#define OR_TOOLS_BASE_BASICTYPES_H_ - -#include "ortools/base/integral_types.h" - -#endif // OR_TOOLS_BASE_BASICTYPES_H_ diff --git a/ortools/base/bitmap.cc b/ortools/base/bitmap.cc index 57276e20e94..981d6c9a918 100644 --- a/ortools/base/bitmap.cc +++ b/ortools/base/bitmap.cc @@ -15,7 +15,7 @@ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { diff --git a/ortools/base/bitmap.h b/ortools/base/bitmap.h index dae8bed1324..24318fb4ac5 100644 --- a/ortools/base/bitmap.h +++ b/ortools/base/bitmap.h @@ -17,7 +17,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { namespace internal { diff --git a/ortools/base/container_logging.h b/ortools/base/container_logging.h index cbe7a01c1de..078082b6b9c 100644 --- a/ortools/base/container_logging.h +++ b/ortools/base/container_logging.h @@ -41,7 +41,7 @@ #include #include "absl/base/port.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace gtl { diff --git a/ortools/base/file.h b/ortools/base/file.h index aac581ee632..c507032c08f 100644 --- a/ortools/base/file.h +++ b/ortools/base/file.h @@ -24,7 +24,7 @@ #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/message.h" #include "google/protobuf/text_format.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/status_macros.h" diff --git a/ortools/base/gzipfile.h b/ortools/base/gzipfile.h index 59696ea3e7e..0777c206a9f 100644 --- a/ortools/base/gzipfile.h +++ b/ortools/base/gzipfile.h @@ -15,7 +15,7 @@ #define OR_TOOLS_BASE_GZIPFILE_H_ #include "absl/strings/string_view.h" -#include "ortools/base/basictypes.h" // for Ownership enum +#include "ortools/base/types.h" // for Ownership enum #include "zlib.h" // for Z_DEFAULT_COMPRESSION class File; diff --git a/ortools/base/hash.h b/ortools/base/hash.h index 84022856474..6db76e7e8fa 100644 --- a/ortools/base/hash.h +++ b/ortools/base/hash.h @@ -18,7 +18,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" // In SWIG mode, we don't want anything besides these top-level includes. #if !defined(SWIG) diff --git a/ortools/base/integral_types.h b/ortools/base/integral_types.h deleted file mode 100644 index 78fe82ad8ef..00000000000 --- a/ortools/base/integral_types.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2010-2022 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. - -#ifndef OR_TOOLS_BASE_INTEGRAL_TYPES_H_ -#define OR_TOOLS_BASE_INTEGRAL_TYPES_H_ - -#include "ortools/base/types.h" - -#endif // OR_TOOLS_BASE_INTEGRAL_TYPES_H_ diff --git a/ortools/base/mathutil.h b/ortools/base/mathutil.h index d968e4bc404..ce6171b7112 100644 --- a/ortools/base/mathutil.h +++ b/ortools/base/mathutil.h @@ -20,8 +20,8 @@ #include #include "absl/base/casts.h" -#include "ortools/base/basictypes.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" diff --git a/ortools/base/stl_util.h b/ortools/base/stl_util.h index 67af655cd33..803f0085f56 100644 --- a/ortools/base/stl_util.h +++ b/ortools/base/stl_util.h @@ -32,7 +32,7 @@ #include "absl/meta/type_traits.h" #include "absl/strings/internal/resize_uninitialized.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/macros.h" namespace gtl { diff --git a/ortools/base/sysinfo.h b/ortools/base/sysinfo.h index c214bd900e7..d997e659683 100644 --- a/ortools/base/sysinfo.h +++ b/ortools/base/sysinfo.h @@ -14,7 +14,7 @@ #ifndef OR_TOOLS_BASE_SYSINFO_H_ #define OR_TOOLS_BASE_SYSINFO_H_ -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { // Returns the memory usage of the process. diff --git a/ortools/base/timer.h b/ortools/base/timer.h index ec9d46d8c9c..06b5f780e1d 100644 --- a/ortools/base/timer.h +++ b/ortools/base/timer.h @@ -17,7 +17,7 @@ #include "absl/log/check.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/macros.h" class WallTimer { diff --git a/ortools/base/vlog.h b/ortools/base/vlog.h index 4696d01c9f5..861af02d674 100644 --- a/ortools/base/vlog.h +++ b/ortools/base/vlog.h @@ -31,7 +31,7 @@ #include "absl/flags/flag.h" #include "absl/log/check.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/vlog_is_on.h" // Log only in verbose mode. diff --git a/ortools/base/vlog_is_on.h b/ortools/base/vlog_is_on.h index c83e12956fd..2742f860c9c 100644 --- a/ortools/base/vlog_is_on.h +++ b/ortools/base/vlog_is_on.h @@ -16,7 +16,7 @@ #include "absl/flags/declare.h" #include "absl/log/log.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" ABSL_DECLARE_FLAG(int, v); diff --git a/ortools/bop/bop_base.h b/ortools/bop/bop_base.h index c8cdeaeb1fb..314e11a5388 100644 --- a/ortools/bop/bop_base.h +++ b/ortools/bop/bop_base.h @@ -22,7 +22,7 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/strong_vector.h" #include "ortools/bop/bop_parameters.pb.h" #include "ortools/bop/bop_solution.h" diff --git a/ortools/bop/bop_fs.h b/ortools/bop/bop_fs.h index eac72984973..4e11df0041f 100644 --- a/ortools/bop/bop_fs.h +++ b/ortools/bop/bop_fs.h @@ -19,7 +19,7 @@ #include #include "absl/strings/string_view.h" -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/types.h" diff --git a/ortools/bop/bop_lns.h b/ortools/bop/bop_lns.h index 87c9cf189a2..475296e7ed2 100644 --- a/ortools/bop/bop_lns.h +++ b/ortools/bop/bop_lns.h @@ -20,7 +20,7 @@ #include #include "absl/strings/string_view.h" -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" diff --git a/ortools/bop/bop_solver.h b/ortools/bop/bop_solver.h index 30e49468640..70c1265f9e6 100644 --- a/ortools/bop/bop_solver.h +++ b/ortools/bop/bop_solver.h @@ -39,7 +39,7 @@ #include #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/types.h" diff --git a/ortools/bop/bop_types.h b/ortools/bop/bop_types.h index 12fca204ed7..64e45e79acf 100644 --- a/ortools/bop/bop_types.h +++ b/ortools/bop/bop_types.h @@ -18,7 +18,7 @@ #include #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/strong_vector.h" #include "ortools/util/strong_integers.h" diff --git a/ortools/bop/bop_util.cc b/ortools/bop/bop_util.cc index 92923116cca..eafd181e8aa 100644 --- a/ortools/bop/bop_util.cc +++ b/ortools/bop/bop_util.cc @@ -17,7 +17,7 @@ #include #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/types.h" #include "ortools/bop/bop_base.h" #include "ortools/bop/bop_solution.h" diff --git a/ortools/bop/bop_util.h b/ortools/bop/bop_util.h index c1cddfc1c61..69551d99fa9 100644 --- a/ortools/bop/bop_util.h +++ b/ortools/bop/bop_util.h @@ -16,7 +16,7 @@ #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/types.h" #include "ortools/bop/bop_base.h" #include "ortools/bop/bop_solution.h" diff --git a/ortools/constraint_solver/csharp/constraint_solver.i b/ortools/constraint_solver/csharp/constraint_solver.i index 87e41126616..9a5af25e4d9 100644 --- a/ortools/constraint_solver/csharp/constraint_solver.i +++ b/ortools/constraint_solver/csharp/constraint_solver.i @@ -49,7 +49,7 @@ class RegularLimitParameters; #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/search_limit.pb.h" diff --git a/ortools/constraint_solver/java/constraint_solver.i b/ortools/constraint_solver/java/constraint_solver.i index 9fb467ac17f..cba7f4eccc7 100644 --- a/ortools/constraint_solver/java/constraint_solver.i +++ b/ortools/constraint_solver/java/constraint_solver.i @@ -129,7 +129,7 @@ PROTECT_FROM_FAILURE(Solver::Fail(), arg1); #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" %} diff --git a/ortools/constraint_solver/routing_filters.cc b/ortools/constraint_solver/routing_filters.cc index 734ffc2e93d..0cf8048e9ba 100644 --- a/ortools/constraint_solver/routing_filters.cc +++ b/ortools/constraint_solver/routing_filters.cc @@ -1208,6 +1208,7 @@ class PathCumulFilter : public BasePathFilter { LocalDimensionCumulOptimizer* optimizer_; LocalDimensionCumulOptimizer* mp_optimizer_; + const std::function path_accessor_; const bool filter_objective_cost_; // This boolean indicates if the LP optimizer can be used if necessary to // optimize the dimension cumuls. @@ -1246,6 +1247,7 @@ PathCumulFilter::PathCumulFilter(const RoutingModel& routing_model, name_(dimension.name()), optimizer_(routing_model.GetMutableLocalCumulLPOptimizer(dimension)), mp_optimizer_(routing_model.GetMutableLocalCumulMPOptimizer(dimension)), + path_accessor_([this](int64_t node) { return GetNext(node); }), filter_objective_cost_(filter_objective_cost), can_use_lp_(can_use_lp), propagate_own_objective_value_(propagate_own_objective_value) { @@ -1509,8 +1511,7 @@ void PathCumulFilter::OnBeforeSynchronizePaths() { DCHECK(optimizer != nullptr); const DimensionSchedulingStatus status = optimizer->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64_t node) { return Value(node); }, - &lp_cumul_cost_value); + vehicle, path_accessor_, &lp_cumul_cost_value); switch (status) { case DimensionSchedulingStatus::INFEASIBLE: lp_cumul_cost_value = 0; @@ -1518,8 +1519,7 @@ void PathCumulFilter::OnBeforeSynchronizePaths() { case DimensionSchedulingStatus::RELAXED_OPTIMAL_ONLY: DCHECK(mp_optimizer_ != nullptr); if (mp_optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64_t node) { return Value(node); }, - &lp_cumul_cost_value) == + vehicle, path_accessor_, &lp_cumul_cost_value) == DimensionSchedulingStatus::INFEASIBLE) { lp_cumul_cost_value = 0; } @@ -1852,8 +1852,7 @@ bool PathCumulFilter::FinalizeAcceptPath(int64_t /*objective_min*/, int64_t path_delta_cost_with_lp = 0; const DimensionSchedulingStatus status = optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64_t node) { return GetNext(node); }, - &path_delta_cost_with_lp); + vehicle, path_accessor_, &path_delta_cost_with_lp); if (status == DimensionSchedulingStatus::INFEASIBLE) { return false; } @@ -1886,8 +1885,7 @@ bool PathCumulFilter::FinalizeAcceptPath(int64_t /*objective_min*/, const int vehicle = start_to_vehicle_[start]; int64_t path_delta_cost_with_mp = 0; if (mp_optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64_t node) { return GetNext(node); }, - &path_delta_cost_with_mp) == + vehicle, path_accessor_, &path_delta_cost_with_mp) == DimensionSchedulingStatus::INFEASIBLE) { return false; } diff --git a/ortools/constraint_solver/routing_flags.h b/ortools/constraint_solver/routing_flags.h index b08f83cbaeb..a5bd146a4dd 100644 --- a/ortools/constraint_solver/routing_flags.h +++ b/ortools/constraint_solver/routing_flags.h @@ -18,7 +18,7 @@ #include #include "ortools/base/commandlineflags.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/constraint_solver/routing_parameters.pb.h" /// Neighborhood activation/deactivation diff --git a/ortools/flatzinc/parser.yy.cc b/ortools/flatzinc/parser.yy.cc index 2839fb91900..1601ac04a93 100644 --- a/ortools/flatzinc/parser.yy.cc +++ b/ortools/flatzinc/parser.yy.cc @@ -712,7 +712,7 @@ static const flex_int32_t yy_rule_can_match_eol[32] = { #include #include "absl/strings/numbers.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/flatzinc/parser.tab.hh" #if defined(_MSC_VER) #define YY_NO_UNISTD_H diff --git a/ortools/linear_solver/cplex_interface.cc b/ortools/linear_solver/cplex_interface.cc index 46b5a730bbb..d0bdffd0fc7 100644 --- a/ortools/linear_solver/cplex_interface.cc +++ b/ortools/linear_solver/cplex_interface.cc @@ -19,7 +19,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/timer.h" #include "ortools/linear_solver/linear_solver.h" diff --git a/ortools/linear_solver/linear_solver_natural_api.py b/ortools/linear_solver/linear_solver_natural_api.py deleted file mode 100644 index bee3cbc2369..00000000000 --- a/ortools/linear_solver/linear_solver_natural_api.py +++ /dev/null @@ -1,265 +0,0 @@ -# Copyright 2010-2022 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. - -"""Patch to the python wrapper of ../linear_solver.h providing an algebraic API. - -This is directly imported, and use exclusively in ./linear_solver.i. See that -file. -For examples leveraging the code defined here, see ./pywraplp_test.py and -../../../python/linear_programming.py. -""" - -import collections -import numbers - -# The classes below allow linear expressions to be expressed naturally with the -# usual arithmetic operators +-*/ and with constant numbers, which makes the -# python API very intuitive. See the top-level comment for examples. - - -inf = float('inf') - - -class _FakeMPVariableRepresentingTheConstantOffset(object): - """A dummy class for a singleton instance used to represent the constant. - - To represent linear expressions, we store a dictionary - MPVariable->coefficient. To represent the constant offset of the expression, - we use this class as a substitute: its coefficient will be the offset. To - properly be evaluated, its solution_value() needs to be 1. - """ - - def solution_value(self): # pylint: disable=invalid-name - return 1 - - def __repr__(self): - return 'OFFSET_KEY' - - -OFFSET_KEY = _FakeMPVariableRepresentingTheConstantOffset() - - -def CastToLinExp(v): - if isinstance(v, numbers.Number): - return Constant(v) - else: - return v - - -class LinearExpr(object): - """Holds linear expressions. - - A linear expression is essentially an offset (floating-point value), and a - dictionary mapping MPVariable objects to their coefficient (which is also a - floating-point value). - """ - - OVERRIDDEN_OPERATOR_METHODS = [ - '__%s__' % opname - for opname in ['add', 'radd', 'sub', 'rsub', 'mul', 'rmul', 'div', - 'truediv', 'neg', 'eq', 'ge', 'le', 'gt', 'lt', 'ne'] - ] - - def solution_value(self): # pylint: disable=invalid-name - """Value of this linear expr, using the solution_value of its vars.""" - coeffs = self.GetCoeffs() - return sum(var.solution_value() * coeff for var, coeff in coeffs.items()) - - def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): - """Private function used by GetCoeffs() to delegate processing. - - Implementation must either update coeffs or push to the stack a - sub-expression and the accumulated multiplier that applies to it. - - Args: - coeffs: A dictionary of variables' coefficients. It is a defaultdict that - initializes the new values to 0 by default. - multiplier: The current accumulated multiplier to apply to this - expression. - stack: A list to append to if the current expression is composed of - sub-expressions. The elements of the stack are pair tuples - (multiplier, linear_expression). - """ - raise NotImplementedError - - def GetCoeffs(self): - coeffs = collections.defaultdict(float) - stack = [(1.0, self)] - while stack: - current_multiplier, current_expression = stack.pop() - current_expression.AddSelfToCoeffMapOrStack(coeffs, current_multiplier, - stack) - return coeffs - - def __add__(self, expr): - return Sum(self, expr) - - def __radd__(self, cst): - return Sum(self, cst) - - def __sub__(self, expr): - return Sum(self, -expr) - - def __rsub__(self, cst): - return Sum(-self, cst) - - def __mul__(self, cst): - return ProductCst(self, cst) - - def __rmul__(self, cst): - return ProductCst(self, cst) - - def __div__(self, cst): - return ProductCst(self, 1.0 / cst) - - def __truediv__(self, cst): - return ProductCst(self, 1.0 / cst) - - def __neg__(self): - return ProductCst(self, -1) - - def __eq__(self, arg): - if isinstance(arg, numbers.Number): - return LinearConstraint(self, arg, arg) - else: - return LinearConstraint(self - arg, 0.0, 0.0) - - def __ge__(self, arg): - if isinstance(arg, numbers.Number): - return LinearConstraint(self, arg, inf) - else: - return LinearConstraint(self - arg, 0.0, inf) - - def __le__(self, arg): - if isinstance(arg, numbers.Number): - return LinearConstraint(self, -inf, arg) - else: - return LinearConstraint(self - arg, -inf, 0.0) - - def __lt__(self, arg): - raise ValueError( - 'Operators "<" and ">" not supported with the linear solver') - - def __gt__(self, arg): - raise ValueError( - 'Operators "<" and ">" not supported with the linear solver') - - def __ne__(self, arg): - raise ValueError('Operator "!=" not supported with the linear solver') - - -class VariableExpr(LinearExpr): - """Represents a LinearExpr containing only a single variable.""" - - def __init__(self, mpvar): - self.__var = mpvar - - def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): - coeffs[self.__var] += multiplier - - -class ProductCst(LinearExpr): - """Represents the product of a LinearExpr by a constant.""" - - def __init__(self, expr, coef): - self.__expr = CastToLinExp(expr) - if isinstance(coef, numbers.Number): - self.__coef = coef - else: - raise TypeError - - def __str__(self): - if self.__coef == -1: - return '-' + str(self.__expr) - else: - return '(' + str(self.__coef) + ' * ' + str(self.__expr) + ')' - - def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): - current_multiplier = multiplier * self.__coef - if current_multiplier: - stack.append((current_multiplier, self.__expr)) - - -class Constant(LinearExpr): - - def __init__(self, val): - self.__val = val - - def __str__(self): - return str(self.__val) - - def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): - coeffs[OFFSET_KEY] += self.__val * multiplier - - -class SumArray(LinearExpr): - """Represents the sum of a list of LinearExpr.""" - - def __init__(self, array): - self.__array = [CastToLinExp(elem) for elem in array] - - def __str__(self): - return '({})'.format(' + '.join(map(str, self.__array))) - - def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): - # Append elements in reversed order so that the first popped from the stack - # in the next iteration of the evaluation loop will be the first item of the - # array. This keeps the end result of the floating point computation - # predictable from user perspective. - for arg in reversed(self.__array): - stack.append((multiplier, arg)) - - -def Sum(*args): - return SumArray(args) - -SumCst = Sum # pylint: disable=invalid-name - - -class LinearConstraint(object): - """Represents a linear constraint: LowerBound <= LinearExpr <= UpperBound.""" - - def __init__(self, expr, lb, ub): - self.__expr = expr - self.__lb = lb - self.__ub = ub - - def __str__(self): - if self.__lb > -inf and self.__ub < inf: - if self.__lb == self.__ub: - return str(self.__expr) + ' == ' + str(self.__lb) - else: - return (str(self.__lb) + ' <= ' + str(self.__expr) + - ' <= ' + str(self.__ub)) - elif self.__lb > -inf: - return str(self.__expr) + ' >= ' + str(self.__lb) - elif self.__ub < inf: - return str(self.__expr) + ' <= ' + str(self.__ub) - else: - return 'Trivial inequality (always true)' - - def Extract(self, solver, name=''): - """Performs the actual creation of the constraint object.""" - coeffs = self.__expr.GetCoeffs() - constant = coeffs.pop(OFFSET_KEY, 0.0) - lb = -solver.infinity() - ub = solver.infinity() - if self.__lb > -inf: - lb = self.__lb - constant - if self.__ub < inf: - ub = self.__ub - constant - - constraint = solver.RowConstraint(lb, ub, name) - for v, c, in coeffs.items(): - constraint.SetCoefficient(v, float(c)) - return constraint diff --git a/ortools/linear_solver/model_exporter.cc b/ortools/linear_solver/model_exporter.cc index 7630c565156..9644f23ebb8 100644 --- a/ortools/linear_solver/model_exporter.cc +++ b/ortools/linear_solver/model_exporter.cc @@ -29,7 +29,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "ortools/base/commandlineflags.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/map_util.h" #include "ortools/linear_solver/linear_solver.pb.h" diff --git a/ortools/linear_solver/python/linear_solver.i b/ortools/linear_solver/python/linear_solver.i index 9a409aa1d93..83a639a2544 100644 --- a/ortools/linear_solver/python/linear_solver.i +++ b/ortools/linear_solver/python/linear_solver.i @@ -24,7 +24,7 @@ // solver.Maximize(10 * x1 + 6 * x2) // // USAGE EXAMPLES: -// - examples/python/linear_programming.py +// - ortools/python/linear_programming.py // - ./pywraplp_test.py // // TODO(user): test all the APIs that are currently marked as 'untested'. @@ -56,15 +56,15 @@ class IISResponse; %pythoncode %{ import numbers -from ortools.linear_solver.linear_solver_natural_api import OFFSET_KEY -from ortools.linear_solver.linear_solver_natural_api import inf -from ortools.linear_solver.linear_solver_natural_api import LinearExpr -from ortools.linear_solver.linear_solver_natural_api import ProductCst -from ortools.linear_solver.linear_solver_natural_api import Sum -from ortools.linear_solver.linear_solver_natural_api import SumArray -from ortools.linear_solver.linear_solver_natural_api import SumCst -from ortools.linear_solver.linear_solver_natural_api import LinearConstraint -from ortools.linear_solver.linear_solver_natural_api import VariableExpr +from ortools.linear_solver.python.linear_solver_natural_api import OFFSET_KEY +from ortools.linear_solver.python.linear_solver_natural_api import inf +from ortools.linear_solver.python.linear_solver_natural_api import LinearExpr +from ortools.linear_solver.python.linear_solver_natural_api import ProductCst +from ortools.linear_solver.python.linear_solver_natural_api import Sum +from ortools.linear_solver.python.linear_solver_natural_api import SumArray +from ortools.linear_solver.python.linear_solver_natural_api import SumCst +from ortools.linear_solver.python.linear_solver_natural_api import LinearConstraint +from ortools.linear_solver.python.linear_solver_natural_api import VariableExpr %} // %pythoncode %extend operations_research::MPVariable { diff --git a/ortools/linear_solver/python/linear_solver_natural_api.py b/ortools/linear_solver/python/linear_solver_natural_api.py new file mode 100644 index 00000000000..72a45c19b6e --- /dev/null +++ b/ortools/linear_solver/python/linear_solver_natural_api.py @@ -0,0 +1,283 @@ +# Copyright 2010-2022 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. + +"""Patch to the python wrapper of ../linear_solver.h providing an algebraic API. + +This is directly imported, and use exclusively in ./linear_solver.i. See that +file. +For examples leveraging the code defined here, see ./pywraplp_test.py and +../../../python/linear_programming.py. +""" + +import collections +import numbers + +# The classes below allow linear expressions to be expressed naturally with the +# usual arithmetic operators +-*/ and with constant numbers, which makes the +# python API very intuitive. See the top-level comment for examples. + + +inf = float("inf") + + +class _FakeMPVariableRepresentingTheConstantOffset(object): + """A dummy class for a singleton instance used to represent the constant. + + To represent linear expressions, we store a dictionary + MPVariable->coefficient. To represent the constant offset of the expression, + we use this class as a substitute: its coefficient will be the offset. To + properly be evaluated, its solution_value() needs to be 1. + """ + + def solution_value(self): # pylint: disable=invalid-name + return 1 + + def __repr__(self): + return "OFFSET_KEY" + + +OFFSET_KEY = _FakeMPVariableRepresentingTheConstantOffset() + + +def CastToLinExp(v): + if isinstance(v, numbers.Number): + return Constant(v) + else: + return v + + +class LinearExpr(object): + """Holds linear expressions. + + A linear expression is essentially an offset (floating-point value), and a + dictionary mapping MPVariable objects to their coefficient (which is also a + floating-point value). + """ + + OVERRIDDEN_OPERATOR_METHODS = [ + "__%s__" % opname + for opname in [ + "add", + "radd", + "sub", + "rsub", + "mul", + "rmul", + "div", + "truediv", + "neg", + "eq", + "ge", + "le", + "gt", + "lt", + "ne", + ] + ] + + def solution_value(self): # pylint: disable=invalid-name + """Value of this linear expr, using the solution_value of its vars.""" + coeffs = self.GetCoeffs() + return sum(var.solution_value() * coeff for var, coeff in coeffs.items()) + + def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): + """Private function used by GetCoeffs() to delegate processing. + + Implementation must either update coeffs or push to the stack a + sub-expression and the accumulated multiplier that applies to it. + + Args: + coeffs: A dictionary of variables' coefficients. It is a defaultdict that + initializes the new values to 0 by default. + multiplier: The current accumulated multiplier to apply to this + expression. + stack: A list to append to if the current expression is composed of + sub-expressions. The elements of the stack are pair tuples + (multiplier, linear_expression). + """ + raise NotImplementedError + + def GetCoeffs(self): + coeffs = collections.defaultdict(float) + stack = [(1.0, self)] + while stack: + current_multiplier, current_expression = stack.pop() + current_expression.AddSelfToCoeffMapOrStack( + coeffs, current_multiplier, stack + ) + return coeffs + + def __add__(self, expr): + return Sum(self, expr) + + def __radd__(self, cst): + return Sum(self, cst) + + def __sub__(self, expr): + return Sum(self, -expr) + + def __rsub__(self, cst): + return Sum(-self, cst) + + def __mul__(self, cst): + return ProductCst(self, cst) + + def __rmul__(self, cst): + return ProductCst(self, cst) + + def __div__(self, cst): + return ProductCst(self, 1.0 / cst) + + def __truediv__(self, cst): + return ProductCst(self, 1.0 / cst) + + def __neg__(self): + return ProductCst(self, -1) + + def __eq__(self, arg): + if isinstance(arg, numbers.Number): + return LinearConstraint(self, arg, arg) + else: + return LinearConstraint(self - arg, 0.0, 0.0) + + def __ge__(self, arg): + if isinstance(arg, numbers.Number): + return LinearConstraint(self, arg, inf) + else: + return LinearConstraint(self - arg, 0.0, inf) + + def __le__(self, arg): + if isinstance(arg, numbers.Number): + return LinearConstraint(self, -inf, arg) + else: + return LinearConstraint(self - arg, -inf, 0.0) + + def __lt__(self, arg): + raise ValueError('Operators "<" and ">" not supported with the linear solver') + + def __gt__(self, arg): + raise ValueError('Operators "<" and ">" not supported with the linear solver') + + def __ne__(self, arg): + raise ValueError('Operator "!=" not supported with the linear solver') + + +class VariableExpr(LinearExpr): + """Represents a LinearExpr containing only a single variable.""" + + def __init__(self, mpvar): + self.__var = mpvar + + def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): + coeffs[self.__var] += multiplier + + +class ProductCst(LinearExpr): + """Represents the product of a LinearExpr by a constant.""" + + def __init__(self, expr, coef): + self.__expr = CastToLinExp(expr) + if isinstance(coef, numbers.Number): + self.__coef = coef + else: + raise TypeError + + def __str__(self): + if self.__coef == -1: + return "-" + str(self.__expr) + else: + return "(" + str(self.__coef) + " * " + str(self.__expr) + ")" + + def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): + current_multiplier = multiplier * self.__coef + if current_multiplier: + stack.append((current_multiplier, self.__expr)) + + +class Constant(LinearExpr): + def __init__(self, val): + self.__val = val + + def __str__(self): + return str(self.__val) + + def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): + coeffs[OFFSET_KEY] += self.__val * multiplier + + +class SumArray(LinearExpr): + """Represents the sum of a list of LinearExpr.""" + + def __init__(self, array): + self.__array = [CastToLinExp(elem) for elem in array] + + def __str__(self): + return "({})".format(" + ".join(map(str, self.__array))) + + def AddSelfToCoeffMapOrStack(self, coeffs, multiplier, stack): + # Append elements in reversed order so that the first popped from the stack + # in the next iteration of the evaluation loop will be the first item of the + # array. This keeps the end result of the floating point computation + # predictable from user perspective. + for arg in reversed(self.__array): + stack.append((multiplier, arg)) + + +def Sum(*args): + return SumArray(args) + + +SumCst = Sum # pylint: disable=invalid-name + + +class LinearConstraint(object): + """Represents a linear constraint: LowerBound <= LinearExpr <= UpperBound.""" + + def __init__(self, expr, lb, ub): + self.__expr = expr + self.__lb = lb + self.__ub = ub + + def __str__(self): + if self.__lb > -inf and self.__ub < inf: + if self.__lb == self.__ub: + return str(self.__expr) + " == " + str(self.__lb) + else: + return ( + str(self.__lb) + " <= " + str(self.__expr) + " <= " + str(self.__ub) + ) + elif self.__lb > -inf: + return str(self.__expr) + " >= " + str(self.__lb) + elif self.__ub < inf: + return str(self.__expr) + " <= " + str(self.__ub) + else: + return "Trivial inequality (always true)" + + def Extract(self, solver, name=""): + """Performs the actual creation of the constraint object.""" + coeffs = self.__expr.GetCoeffs() + constant = coeffs.pop(OFFSET_KEY, 0.0) + lb = -solver.infinity() + ub = solver.infinity() + if self.__lb > -inf: + lb = self.__lb - constant + if self.__ub < inf: + ub = self.__ub - constant + + constraint = solver.RowConstraint(lb, ub, name) + for ( + v, + c, + ) in coeffs.items(): + constraint.SetCoefficient(v, float(c)) + return constraint diff --git a/ortools/linear_solver/sat_interface.cc b/ortools/linear_solver/sat_interface.cc index 2c4a2228647..78dc79341d6 100644 --- a/ortools/linear_solver/sat_interface.cc +++ b/ortools/linear_solver/sat_interface.cc @@ -21,7 +21,7 @@ #include "absl/base/attributes.h" #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/linear_solver/linear_solver.h" #include "ortools/linear_solver/linear_solver.pb.h" diff --git a/ortools/linear_solver/scip_interface.cc b/ortools/linear_solver/scip_interface.cc index 0f9e53ae31c..41a76570b11 100644 --- a/ortools/linear_solver/scip_interface.cc +++ b/ortools/linear_solver/scip_interface.cc @@ -32,7 +32,7 @@ #include "ortools/base/cleanup.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/hash.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/status_macros.h" #include "ortools/base/timer.h" diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 122f0284614..7f3e68fe47b 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -25,7 +25,7 @@ #include #include "absl/strings/str_format.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/timer.h" #include "ortools/linear_solver/linear_solver.h" diff --git a/ortools/lp_data/BUILD.bazel b/ortools/lp_data/BUILD.bazel index 36ccd3e5120..f3f76adfc46 100644 --- a/ortools/lp_data/BUILD.bazel +++ b/ortools/lp_data/BUILD.bazel @@ -76,7 +76,7 @@ cc_library( deps = [ ":base", "//ortools/base", - "//ortools/base:basictypes", + "//ortools/base:types", "//ortools/base:strong_vector", "//ortools/util:bitset", "//ortools/util:strong_integers", diff --git a/ortools/lp_data/scattered_vector.h b/ortools/lp_data/scattered_vector.h index c89715966e9..03f28b169df 100644 --- a/ortools/lp_data/scattered_vector.h +++ b/ortools/lp_data/scattered_vector.h @@ -17,7 +17,7 @@ #include #include -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/lp_data/lp_types.h" #include "ortools/util/bitset.h" diff --git a/ortools/math_opt/core/sparse_vector_view.h b/ortools/math_opt/core/sparse_vector_view.h index e89376f8bb5..faf4995b446 100644 --- a/ortools/math_opt/core/sparse_vector_view.h +++ b/ortools/math_opt/core/sparse_vector_view.h @@ -54,7 +54,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/types/span.h" #include "google/protobuf/message.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/map_util.h" #include "ortools/math_opt/core/arrow_operator_proxy.h" // IWYU pragma: export diff --git a/ortools/math_opt/validators/model_parameters_validator.cc b/ortools/math_opt/validators/model_parameters_validator.cc index 6dd4acc74ee..52ff0780075 100644 --- a/ortools/math_opt/validators/model_parameters_validator.cc +++ b/ortools/math_opt/validators/model_parameters_validator.cc @@ -14,7 +14,7 @@ #include "ortools/math_opt/validators/model_parameters_validator.h" #include "absl/status/status.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/status_macros.h" #include "ortools/math_opt/core/model_summary.h" #include "ortools/math_opt/core/sparse_vector_view.h" diff --git a/ortools/pdlp/quadratic_program_io.cc b/ortools/pdlp/quadratic_program_io.cc index 67f0c7016d4..800900115db 100644 --- a/ortools/pdlp/quadratic_program_io.cc +++ b/ortools/pdlp/quadratic_program_io.cc @@ -32,7 +32,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "ortools/base/basictypes.h" +#include "ortools/base/types.h" #include "ortools/base/file.h" #include "ortools/base/helpers.h" #include "ortools/base/logging.h" diff --git a/ortools/port/sysinfo.h b/ortools/port/sysinfo.h index ec248164973..0506c6d221c 100644 --- a/ortools/port/sysinfo.h +++ b/ortools/port/sysinfo.h @@ -16,7 +16,7 @@ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { namespace sysinfo { diff --git a/ortools/routing/samples/cvrp_disjoint_tw.cc b/ortools/routing/samples/cvrp_disjoint_tw.cc index fc329d270f2..e3ac0f483da 100644 --- a/ortools/routing/samples/cvrp_disjoint_tw.cc +++ b/ortools/routing/samples/cvrp_disjoint_tw.cc @@ -31,7 +31,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw.cc b/ortools/routing/samples/cvrptw.cc index fca4ba8ba9d..6e4dba247ff 100644 --- a/ortools/routing/samples/cvrptw.cc +++ b/ortools/routing/samples/cvrptw.cc @@ -29,7 +29,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_soft_capacity.cc b/ortools/routing/samples/cvrptw_soft_capacity.cc index df1e125985a..26949634d86 100644 --- a/ortools/routing/samples/cvrptw_soft_capacity.cc +++ b/ortools/routing/samples/cvrptw_soft_capacity.cc @@ -28,7 +28,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_with_breaks.cc b/ortools/routing/samples/cvrptw_with_breaks.cc index bf3477505d9..eb28108c6e1 100644 --- a/ortools/routing/samples/cvrptw_with_breaks.cc +++ b/ortools/routing/samples/cvrptw_with_breaks.cc @@ -35,7 +35,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_enums.pb.h" diff --git a/ortools/routing/samples/cvrptw_with_precedences.cc b/ortools/routing/samples/cvrptw_with_precedences.cc index 494ad454652..37b029c4eb1 100644 --- a/ortools/routing/samples/cvrptw_with_precedences.cc +++ b/ortools/routing/samples/cvrptw_with_precedences.cc @@ -30,7 +30,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_with_refueling.cc b/ortools/routing/samples/cvrptw_with_refueling.cc index 05a7a62c623..e0a1673e56a 100644 --- a/ortools/routing/samples/cvrptw_with_refueling.cc +++ b/ortools/routing/samples/cvrptw_with_refueling.cc @@ -27,7 +27,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_with_resources.cc b/ortools/routing/samples/cvrptw_with_resources.cc index 61fec9704ae..6719f613cf0 100644 --- a/ortools/routing/samples/cvrptw_with_resources.cc +++ b/ortools/routing/samples/cvrptw_with_resources.cc @@ -29,7 +29,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_with_stop_times_and_resources.cc b/ortools/routing/samples/cvrptw_with_stop_times_and_resources.cc index d6ae1ad0a41..fb4de1d465a 100644 --- a/ortools/routing/samples/cvrptw_with_stop_times_and_resources.cc +++ b/ortools/routing/samples/cvrptw_with_stop_times_and_resources.cc @@ -28,7 +28,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/samples/cvrptw_with_time_dependent_costs.cc b/ortools/routing/samples/cvrptw_with_time_dependent_costs.cc index 06cb5ac2c13..fb1195d3858 100644 --- a/ortools/routing/samples/cvrptw_with_time_dependent_costs.cc +++ b/ortools/routing/samples/cvrptw_with_time_dependent_costs.cc @@ -27,7 +27,7 @@ #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/init_google.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_index_manager.h" diff --git a/ortools/routing/solomon_parser.cc b/ortools/routing/solomon_parser.cc index e2fc9a4d5ad..3adafb8ff9a 100644 --- a/ortools/routing/solomon_parser.cc +++ b/ortools/routing/solomon_parser.cc @@ -21,7 +21,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/map_util.h" #include "ortools/base/numbers.h" diff --git a/ortools/routing/solomon_parser.h b/ortools/routing/solomon_parser.h index 8852bc7d883..a12d586022c 100644 --- a/ortools/routing/solomon_parser.h +++ b/ortools/routing/solomon_parser.h @@ -50,7 +50,7 @@ #include #include "absl/strings/string_view.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/macros.h" #include "ortools/routing/simple_graph.h" diff --git a/ortools/routing/solomon_parser_test.cc b/ortools/routing/solomon_parser_test.cc index 0b71f8878fc..b3b6f50709c 100644 --- a/ortools/routing/solomon_parser_test.cc +++ b/ortools/routing/solomon_parser_test.cc @@ -20,7 +20,7 @@ #include "gtest/gtest.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/file.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/path.h" ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir"); diff --git a/ortools/routing/tsplib_parser.h b/ortools/routing/tsplib_parser.h index 8d79ffc94ba..ec17e599e4a 100644 --- a/ortools/routing/tsplib_parser.h +++ b/ortools/routing/tsplib_parser.h @@ -31,7 +31,7 @@ #include #include "absl/container/flat_hash_map.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/routing/simple_graph.h" namespace operations_research { diff --git a/ortools/routing/tsplib_parser_test.cc b/ortools/routing/tsplib_parser_test.cc index 1ae2cf52571..f1c1d5ec296 100644 --- a/ortools/routing/tsplib_parser_test.cc +++ b/ortools/routing/tsplib_parser_test.cc @@ -25,7 +25,7 @@ #include "gtest/gtest.h" #include "ortools/base/filesystem.h" #include "ortools/base/helpers.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/map_util.h" #include "ortools/base/memfile.h" #include "ortools/base/path.h" diff --git a/ortools/routing/tsptw_parser.h b/ortools/routing/tsptw_parser.h index 249b3d11747..4607477e720 100644 --- a/ortools/routing/tsptw_parser.h +++ b/ortools/routing/tsptw_parser.h @@ -25,7 +25,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/routing/simple_graph.h" namespace operations_research { diff --git a/ortools/routing/tsptw_parser_test.cc b/ortools/routing/tsptw_parser_test.cc index 892b61a02c2..8540440796e 100644 --- a/ortools/routing/tsptw_parser_test.cc +++ b/ortools/routing/tsptw_parser_test.cc @@ -18,7 +18,7 @@ #include "absl/flags/flag.h" #include "gtest/gtest.h" #include "ortools/base/helpers.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/path.h" #if defined(_MSC_VER) diff --git a/ortools/sat/all_different.h b/ortools/sat/all_different.h index 6216f1a7694..2752c53edb0 100644 --- a/ortools/sat/all_different.h +++ b/ortools/sat/all_different.h @@ -22,9 +22,9 @@ #include "absl/container/flat_hash_map.h" #include "absl/log/check.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/sat/integer.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_base.h" diff --git a/ortools/sat/circuit.h b/ortools/sat/circuit.h index 0147510008d..ba43a10453e 100644 --- a/ortools/sat/circuit.h +++ b/ortools/sat/circuit.h @@ -21,9 +21,9 @@ #include "absl/container/btree_set.h" #include "absl/container/flat_hash_map.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/graph/strongly_connected_components.h" #include "ortools/sat/integer.h" #include "ortools/sat/model.h" diff --git a/ortools/sat/clause.h b/ortools/sat/clause.h index f3a35c054dd..125a9c8bab1 100644 --- a/ortools/sat/clause.h +++ b/ortools/sat/clause.h @@ -31,10 +31,10 @@ #include "absl/random/bit_gen_ref.h" #include "absl/types/span.h" #include "ortools/base/hash.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/drat_proof_handler.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_base.h" diff --git a/ortools/sat/cp_constraints.h b/ortools/sat/cp_constraints.h index a945a64271b..0e6511c40e7 100644 --- a/ortools/sat/cp_constraints.h +++ b/ortools/sat/cp_constraints.h @@ -21,9 +21,9 @@ #include "absl/log/check.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/sat/integer.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_base.h" diff --git a/ortools/sat/cp_model.proto b/ortools/sat/cp_model.proto index b3425501031..676b161f99a 100644 --- a/ortools/sat/cp_model.proto +++ b/ortools/sat/cp_model.proto @@ -351,8 +351,13 @@ message ConstraintProto { BoolArgumentProto bool_xor = 5; // The int_div constraint forces the target to equal exprs[0] / exprs[1]. - // In particular, exprs[1] can never take the value 0. Also, as for now, we - // do not support exprs[1] spanning across 0. + // The division is "rounded" towards zero, so we can have for instance + // (2 = 12 / 5) or (-3 = -10 / 3). If you only want exact integer division, + // then you should use instead of t = a / b, the int_prod constraint + // a = b * t. + // + // Note that this forces exprs[1] to never take the value 0. + // Important: currently we do not support exprs[1] spanning across 0. LinearArgumentProto int_div = 7; // The int_mod constraint forces the target to equal exprs[0] % exprs[1]. diff --git a/ortools/sat/cp_model_checker.h b/ortools/sat/cp_model_checker.h index d97f01b54c3..c7c97cf635e 100644 --- a/ortools/sat/cp_model_checker.h +++ b/ortools/sat/cp_model_checker.h @@ -19,7 +19,7 @@ #include #include "absl/types/span.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/sat_parameters.pb.h" diff --git a/ortools/sat/cp_model_expand.cc b/ortools/sat/cp_model_expand.cc index d27772d5122..0745528f6a6 100644 --- a/ortools/sat/cp_model_expand.cc +++ b/ortools/sat/cp_model_expand.cc @@ -27,9 +27,9 @@ #include "absl/log/check.h" #include "absl/meta/type_traits.h" #include "absl/strings/str_cat.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/stl_util.h" +#include "ortools/base/types.h" #include "ortools/port/proto_utils.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/cp_model_utils.h" diff --git a/ortools/sat/cp_model_lns.h b/ortools/sat/cp_model_lns.h index 103f656508a..8bfcf97c07b 100644 --- a/ortools/sat/cp_model_lns.h +++ b/ortools/sat/cp_model_lns.h @@ -698,7 +698,7 @@ class RandomRectanglesPackingNeighborhoodGenerator // Only make sense for problems with no_overlap_2d constraints. This select a // random set of rectangles (i.e. a pair of intervals) of the problem according // to the difficulty. Then add all implied precedences from the current -// positions of the rectangles in this +// positions of the rectangles in this selected subset. class RandomPrecedencesPackingNeighborhoodGenerator : public NeighborhoodGenerator { public: diff --git a/ortools/sat/cp_model_loader.cc b/ortools/sat/cp_model_loader.cc index 5fc4c11c7c6..1473c45fc3e 100644 --- a/ortools/sat/cp_model_loader.cc +++ b/ortools/sat/cp_model_loader.cc @@ -1350,7 +1350,8 @@ void LoadLinearConstraint(const ConstraintProto& ct, Model* m) { // equal to the intermediate sum, independently of the enforcement. const bool pseudo_boolean = !HasEnforcementLiteral(ct) && ct.linear().domain_size() == 2 && all_booleans; - if (ct.linear().vars().size() > 100 && !pseudo_boolean) { + if (!pseudo_boolean && + ct.linear().vars().size() > params.linear_split_size()) { const auto& domain = ct.linear().domain(); SplitAndLoadIntermediateConstraints( domain.size() > 2 || min_sum < domain[0], diff --git a/ortools/sat/cp_model_loader.h b/ortools/sat/cp_model_loader.h index b1d99d39e14..6cbe1f336b4 100644 --- a/ortools/sat/cp_model_loader.h +++ b/ortools/sat/cp_model_loader.h @@ -19,9 +19,9 @@ #include #include "absl/container/flat_hash_set.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/cp_model_mapping.h" #include "ortools/sat/cp_model_utils.h" diff --git a/ortools/sat/cp_model_mapping.h b/ortools/sat/cp_model_mapping.h index c26bfd363ac..8ae518cfe18 100644 --- a/ortools/sat/cp_model_mapping.h +++ b/ortools/sat/cp_model_mapping.h @@ -22,9 +22,9 @@ #include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/meta/type_traits.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/cp_model_utils.h" #include "ortools/sat/integer.h" diff --git a/ortools/sat/cp_model_postsolve.h b/ortools/sat/cp_model_postsolve.h index 3089eeaed3c..7ee26d4001c 100644 --- a/ortools/sat/cp_model_postsolve.h +++ b/ortools/sat/cp_model_postsolve.h @@ -17,7 +17,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" namespace operations_research { diff --git a/ortools/sat/cp_model_search.h b/ortools/sat/cp_model_search.h index 93e03410919..8db7802bd3e 100644 --- a/ortools/sat/cp_model_search.h +++ b/ortools/sat/cp_model_search.h @@ -19,7 +19,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/cp_model_mapping.h" #include "ortools/sat/integer.h" diff --git a/ortools/sat/cp_model_solver.cc b/ortools/sat/cp_model_solver.cc index 62fab599bcd..edefc421425 100644 --- a/ortools/sat/cp_model_solver.cc +++ b/ortools/sat/cp_model_solver.cc @@ -907,8 +907,12 @@ IntegerVariable GetOrCreateVariableLinkedToSumOf( // We want == 0 or <= 0 if use_equality = false. const bool lb_required = use_equality; const bool ub_required = true; - SplitAndLoadIntermediateConstraints(lb_required, ub_required, &vars, &coeffs, - model); + + // Split if linear is large. + if (vars.size() > model->GetOrCreate()->linear_split_size()) { + SplitAndLoadIntermediateConstraints(lb_required, ub_required, &vars, + &coeffs, model); + } // Load the top-level constraint. if (lb_required) { @@ -3675,12 +3679,8 @@ void SolveCpModelParallel(const CpModelProto& model_proto, const bool has_no_overlap_or_cumulative = !helper->TypeToConstraints(ConstraintProto::kNoOverlap).empty() || !helper->TypeToConstraints(ConstraintProto::kCumulative).empty(); - const bool has_no_overlap2d = - !helper->TypeToConstraints(ConstraintProto::kNoOverlap2D).empty(); // Scheduling (no_overlap and cumulative) specific LNS. - const std::vector> intervals_in_constraints = - helper->GetUniqueIntervalSets(); if (has_no_overlap_or_cumulative) { subsolvers.push_back(std::make_unique( std::make_unique( @@ -3690,6 +3690,8 @@ void SolveCpModelParallel(const CpModelProto& model_proto, std::make_unique( helper, "scheduling_time_window_lns"), params, helper, &shared)); + const std::vector> intervals_in_constraints = + helper->GetUniqueIntervalSets(); if (intervals_in_constraints.size() > 2) { subsolvers.push_back(std::make_unique( std::make_unique( @@ -3700,6 +3702,8 @@ void SolveCpModelParallel(const CpModelProto& model_proto, } // Packing (no_overlap_2d) Specific LNS. + const bool has_no_overlap2d = + !helper->TypeToConstraints(ConstraintProto::kNoOverlap2D).empty(); if (has_no_overlap2d) { subsolvers.push_back(std::make_unique( std::make_unique( diff --git a/ortools/sat/cp_model_solver.h b/ortools/sat/cp_model_solver.h index 330f0b8106f..690e8c8f6c6 100644 --- a/ortools/sat/cp_model_solver.h +++ b/ortools/sat/cp_model_solver.h @@ -18,7 +18,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_parameters.pb.h" diff --git a/ortools/sat/cuts.cc b/ortools/sat/cuts.cc index 2083eeada35..2003ef4f885 100644 --- a/ortools/sat/cuts.cc +++ b/ortools/sat/cuts.cc @@ -1993,14 +1993,9 @@ FlowCoverCutHelper::~FlowCoverCutHelper() { } std::string SingleNodeFlow::DebugString() const { - return absl::StrCat( - "#in:", in_flow.size() - ," #out:", out_flow.size() - ," demand:", demand - ," #bool:", num_bool - ," #lb:", num_to_lb - ," #ub:", num_to_ub - ); + return absl::StrCat("#in:", in_flow.size(), " #out:", out_flow.size(), + " demand:", demand, " #bool:", num_bool, + " #lb:", num_to_lb, " #ub:", num_to_ub); } // The flow info of a linear term is always the same. diff --git a/ortools/sat/encoding.h b/ortools/sat/encoding.h index e002e2c8635..5a5f660f938 100644 --- a/ortools/sat/encoding.h +++ b/ortools/sat/encoding.h @@ -28,9 +28,9 @@ #include #include "absl/log/check.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/sat/boolean_problem.pb.h" #include "ortools/sat/pb_constraint.h" #include "ortools/sat/sat_base.h" diff --git a/ortools/sat/implied_bounds.h b/ortools/sat/implied_bounds.h index a523cb15ee0..55d4121f814 100644 --- a/ortools/sat/implied_bounds.h +++ b/ortools/sat/implied_bounds.h @@ -24,9 +24,9 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/clause.h" #include "ortools/sat/integer.h" #include "ortools/sat/linear_constraint.h" diff --git a/ortools/sat/integer.h b/ortools/sat/integer.h index a1acdec320c..2d8771158b9 100644 --- a/ortools/sat/integer.h +++ b/ortools/sat/integer.h @@ -36,10 +36,10 @@ #include "absl/strings/string_view.h" #include "absl/types/span.h" #include "ortools/base/hash.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/graph/iterators.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_base.h" @@ -1413,9 +1413,9 @@ class GenericLiteralWatcher : public SatPropagator { // No-op overload for "constant" IntegerVariable that are sometimes templated // as an IntegerValue. - void WatchLowerBound(IntegerValue i, int id) {} - void WatchUpperBound(IntegerValue i, int id) {} - void WatchIntegerVariable(IntegerValue v, int id) {} + void WatchLowerBound(IntegerValue /*i*/, int /*id*/) {} + void WatchUpperBound(IntegerValue /*i*/, int /*id*/) {} + void WatchIntegerVariable(IntegerValue /*v*/, int /*id*/) {} // Registers a reversible class with a given propagator. This class will be // changed to the correct state just before the propagator is called. @@ -1436,7 +1436,7 @@ class GenericLiteralWatcher : public SatPropagator { // Alternatively, one can directly get the underlying RevRepository with // a call to model.Get<>(), and use SaveWithStamp() before each modification // to have just a slight overhead per int updates. This later option is what - // is usually done in a CP solver at the cost of a sligthly more complex API. + // is usually done in a CP solver at the cost of a slightly more complex API. void RegisterReversibleInt(int id, int* rev); // Returns the number of registered propagators. diff --git a/ortools/sat/integer_expr.cc b/ortools/sat/integer_expr.cc index 0ac02b70284..b9b5b68cfec 100644 --- a/ortools/sat/integer_expr.cc +++ b/ortools/sat/integer_expr.cc @@ -25,10 +25,10 @@ #include "absl/log/check.h" #include "absl/numeric/int128.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/mathutil.h" #include "ortools/base/stl_util.h" +#include "ortools/base/types.h" #include "ortools/sat/integer.h" #include "ortools/sat/linear_constraint.h" #include "ortools/sat/model.h" diff --git a/ortools/sat/integer_expr.h b/ortools/sat/integer_expr.h index c059a787abd..46a2f886017 100644 --- a/ortools/sat/integer_expr.h +++ b/ortools/sat/integer_expr.h @@ -24,10 +24,10 @@ #include "absl/log/check.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/mathutil.h" +#include "ortools/base/types.h" #include "ortools/sat/integer.h" #include "ortools/sat/linear_constraint.h" #include "ortools/sat/linear_propagation.h" diff --git a/ortools/sat/integer_search.cc b/ortools/sat/integer_search.cc index 8ae5b34728d..4dfc5bc938e 100644 --- a/ortools/sat/integer_search.cc +++ b/ortools/sat/integer_search.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -337,69 +336,26 @@ std::function SatSolverHeuristic(Model* model) { // TODO(user): Do we need a mechanism to reduce the range of possible gaps // when nothing gets proven? This could be a parameter or some adaptative code. -std::function ShaveObjectiveLb( - Model* model, double focus_on_terms_probability) { +std::function ShaveObjectiveLb(Model* model) { auto* objective_definition = model->GetOrCreate(); const IntegerVariable obj_var = objective_definition->objective_var; auto* integer_trail = model->GetOrCreate(); auto* sat_solver = model->GetOrCreate(); auto* random = model->GetOrCreate(); - std::vector random_order; - if (objective_definition->vars.size() > 1) { - random_order.resize(objective_definition->vars.size()); - std::iota(random_order.begin(), random_order.end(), 0); - } - - const auto random_slack = [random](IntegerValue lb, IntegerValue ub) { - const IntegerValue mid = (ub - lb) / 2; - return absl::LogUniform(*random, 0, mid.value()); - }; - - return [obj_var, integer_trail, sat_solver, random, random_order, - objective_definition, random_slack, - focus_on_terms_probability]() mutable { + return [obj_var, integer_trail, sat_solver, random]() { BooleanOrIntegerLiteral result; const int level = sat_solver->CurrentDecisionLevel(); - if (random_order.empty() || - absl::Bernoulli(*random, 1.0 - focus_on_terms_probability)) { - if (level > 0 || obj_var == kNoIntegerVariable || - integer_trail->IsFixed(obj_var)) { - return result; - } - - const IntegerValue obj_lb = integer_trail->LowerBound(obj_var); - const IntegerValue obj_ub = integer_trail->UpperBound(obj_var); - const IntegerValue new_ub = obj_lb + random_slack(obj_lb, obj_ub); - result.integer_literal = IntegerLiteral::LowerOrEqual(obj_var, new_ub); - return result; - } + if (level > 0 || obj_var == kNoIntegerVariable) return result; - if (level == 0) { - VLOG(2) << "ShaveObjectiveLb: randomize " << random_order.size() - << " terms"; - DCHECK_EQ(random_order.size(), objective_definition->vars.size()); - std::shuffle(random_order.begin(), random_order.end(), *random); - } + const IntegerValue obj_lb = integer_trail->LowerBound(obj_var); + const IntegerValue obj_ub = integer_trail->UpperBound(obj_var); + if (obj_lb == obj_ub) return result; + const IntegerValue mid = (obj_ub - obj_lb) / 2; + const IntegerValue new_ub = + obj_lb + absl::LogUniform(*random, 0, mid.value()); - for (const int index : random_order) { - const IntegerVariable var = objective_definition->vars[index]; - const IntegerValue coeff = objective_definition->coeffs[index]; - if (integer_trail->IsFixed(var) || coeff == 0) continue; - - const IntegerValue lb = integer_trail->LowerBound(var); - const IntegerValue ub = integer_trail->UpperBound(var); - const IntegerValue slack = random_slack(lb, ub); - if (coeff > 0) { - result.integer_literal = IntegerLiteral::LowerOrEqual(var, lb + slack); - } else { - result.integer_literal = - IntegerLiteral::GreaterOrEqual(var, ub - slack); - } - return result; - } - - // Returns no-decision. + result.integer_literal = IntegerLiteral::LowerOrEqual(obj_var, new_ub); return result; }; } @@ -742,12 +698,8 @@ void ConfigureSearchHeuristics(Model* model) { SequentialSearch({decision_policy, heuristics.fixed_search}); decision_policy = IntegerValueSelectionHeuristic(decision_policy, model); if (parameters.use_objective_lb_search()) { - heuristics.decision_policies = {SequentialSearch( - {ShaveObjectiveLb( - model, - parameters - .focus_on_terms_in_objective_lb_search_probability()), - decision_policy})}; + heuristics.decision_policies = { + SequentialSearch({ShaveObjectiveLb(model), decision_policy})}; } else { heuristics.decision_policies = {decision_policy}; } @@ -1073,6 +1025,7 @@ SatSolver::Status IntegerSearchHelper::SolveIntegerProblem() { // We need to check after the probing that the literal is not fixed, // otherwise we just go to the next decision. if (sat_solver_->Assignment().LiteralIsAssigned(Literal(decision))) { + decision = kNoLiteralIndex; continue; } } diff --git a/ortools/sat/linear_programming_constraint.cc b/ortools/sat/linear_programming_constraint.cc index f58672813c8..9a8d4c8cee0 100644 --- a/ortools/sat/linear_programming_constraint.cc +++ b/ortools/sat/linear_programming_constraint.cc @@ -763,11 +763,10 @@ bool LinearProgrammingConstraint::AnalyzeLp() { // A dual-unbounded problem is infeasible. We use the dual ray reason. if (simplex_.GetProblemStatus() == glop::ProblemStatus::DUAL_UNBOUNDED) { if (parameters_.use_exact_lp_reason()) { - if (!FillExactDualRayReason()) return true; - } else { - FillReducedCostReasonIn(simplex_.GetDualRayRowCombination(), - &integer_reason_); + return PropagateExactDualRay(); } + FillReducedCostReasonIn(simplex_.GetDualRayRowCombination(), + &integer_reason_); return integer_trail_->ReportConflict(integer_reason_); } @@ -781,7 +780,7 @@ bool LinearProgrammingConstraint::AnalyzeLp() { // TODO(user): Maybe do a bit less computation when we cannot propagate // anything. if (parameters_.use_exact_lp_reason()) { - if (!ExactLpReasonning()) return false; + if (!PropagateExactLpReason()) return false; // Display when the inexact bound would have propagated more. if (VLOG_IS_ON(2)) { @@ -1888,32 +1887,6 @@ absl::int128 LinearProgrammingConstraint::GetImpliedLowerBound( return lower_bound; } -// TODO(user): combine this with RelaxLinearReason() to avoid the extra -// magnitude vector and the weird precondition of RelaxLinearReason(). -void LinearProgrammingConstraint::SetImpliedLowerBoundReason( - const LinearConstraint& terms, IntegerValue slack) { - integer_reason_.clear(); - std::vector magnitudes; - const int size = terms.vars.size(); - for (int i = 0; i < size; ++i) { - const IntegerVariable var = terms.vars[i]; - const IntegerValue coeff = terms.coeffs[i]; - CHECK_NE(coeff, 0); - if (coeff > 0) { - magnitudes.push_back(coeff); - integer_reason_.push_back(integer_trail_->LowerBoundAsLiteral(var)); - } else { - magnitudes.push_back(-coeff); - integer_reason_.push_back(integer_trail_->UpperBoundAsLiteral(var)); - } - } - CHECK_GE(slack, 0); - if (slack > 0) { - integer_trail_->RelaxLinearReason(slack, magnitudes, &integer_reason_); - } - integer_trail_->RemoveLevelZeroBounds(&integer_reason_); -} - bool LinearProgrammingConstraint::ScalingCanOverflow( int power, bool take_objective_into_account, const std::vector>& multipliers, @@ -2215,6 +2188,27 @@ void LinearProgrammingConstraint::AdjustNewLinearConstraint( if (adjusted) ++num_adjusts_; } +bool LinearProgrammingConstraint::PropagateLpConstraint( + const LinearConstraint& ct) { + DCHECK(constraint_manager_.DebugCheckConstraint(ct)); + if (ct.vars.empty()) { + if (ct.ub >= 0) return true; + return integer_trail_->ReportConflict({}); // Unsat. + } + + IntegerSumLE128* cp_constraint = + new IntegerSumLE128({}, ct.vars, ct.coeffs, ct.ub, model_); + if (trail_->CurrentDecisionLevel() == 0) { + // Since we will never ask the reason for a constraint at level 0, we just + // keep the last one. + optimal_constraints_.clear(); + } + optimal_constraints_.emplace_back(cp_constraint); + rev_optimal_constraints_size_ = optimal_constraints_.size(); + if (!cp_constraint->PropagateAtLevelZero()) return false; + return cp_constraint->Propagate(); +} + // The "exact" computation go as follow: // // Given any INTEGER linear combination of the LP constraints, we can create a @@ -2229,7 +2223,7 @@ void LinearProgrammingConstraint::AdjustNewLinearConstraint( // will get an EXACT objective lower bound that is more or less the same as the // inexact bound given by the LP relaxation. This allows to derive exact reasons // for any propagation done by this constraint. -bool LinearProgrammingConstraint::ExactLpReasonning() { +bool LinearProgrammingConstraint::PropagateExactLpReason() { // Clear old reason and deductions. integer_reason_.clear(); deductions_.clear(); @@ -2282,7 +2276,6 @@ bool LinearProgrammingConstraint::ExactLpReasonning() { tmp_constraint_.vars.push_back(objective_cp_); tmp_constraint_.coeffs.push_back(-obj_scale); DivideByGCD(&tmp_constraint_); - DCHECK(constraint_manager_.DebugCheckConstraint(tmp_constraint_)); // Corner case where prevent overflow removed all terms. if (tmp_constraint_.vars.empty()) { @@ -2290,21 +2283,10 @@ bool LinearProgrammingConstraint::ExactLpReasonning() { return tmp_constraint_.ub >= 0; } - IntegerSumLE128* cp_constraint = - new IntegerSumLE128({}, tmp_constraint_.vars, tmp_constraint_.coeffs, - tmp_constraint_.ub, model_); - if (trail_->CurrentDecisionLevel() == 0) { - // Since we will never ask the reason for a constraint at level 0, we just - // keep the last one. - optimal_constraints_.clear(); - } - optimal_constraints_.emplace_back(cp_constraint); - rev_optimal_constraints_size_ = optimal_constraints_.size(); - if (!cp_constraint->PropagateAtLevelZero()) return false; - return cp_constraint->Propagate(); + return PropagateLpConstraint(tmp_constraint_); } -bool LinearProgrammingConstraint::FillExactDualRayReason() { +bool LinearProgrammingConstraint::PropagateExactDualRay() { IntegerValue scaling; const glop::DenseColumn ray = simplex_.GetDualRay(); tmp_lp_multipliers_.clear(); @@ -2318,7 +2300,7 @@ bool LinearProgrammingConstraint::FillExactDualRayReason() { /*ignore_trivial_constraints=*/true, tmp_lp_multipliers_, &scaling); if (scaling == 0) { VLOG(1) << "Isse while computing the exact dual ray reason. Aborting."; - return false; + return true; } IntegerValue new_constraint_ub; @@ -2332,19 +2314,14 @@ bool LinearProgrammingConstraint::FillExactDualRayReason() { tmp_scattered_vector_.ConvertToLinearConstraint( integer_variables_, new_constraint_ub, &tmp_constraint_); DivideByGCD(&tmp_constraint_); - DCHECK(constraint_manager_.DebugCheckConstraint(tmp_constraint_)); + + // This should result in a conflict if the precision is good enough. + if (!PropagateLpConstraint(tmp_constraint_)) return false; const absl::int128 implied_lb = GetImpliedLowerBound(tmp_constraint_); - if (implied_lb <= absl::int128(tmp_constraint_.ub.value())) { - VLOG(1) << "LP exact dual ray not infeasible," - << " implied_lb: " << implied_lb - << " ub: " << tmp_constraint_.ub.value(); - return false; - } - const IntegerValue slack = static_cast( - std::min(absl::int128(std::numeric_limits::max() - 1), - (implied_lb - absl::int128(tmp_constraint_.ub.value())) - 1)); - SetImpliedLowerBoundReason(tmp_constraint_, slack); + VLOG(1) << "LP exact dual ray not infeasible," + << " implied_lb: " << implied_lb + << " ub: " << tmp_constraint_.ub.value(); return true; } diff --git a/ortools/sat/linear_programming_constraint.h b/ortools/sat/linear_programming_constraint.h index 6f69844fe2c..906865349de 100644 --- a/ortools/sat/linear_programming_constraint.h +++ b/ortools/sat/linear_programming_constraint.h @@ -305,12 +305,16 @@ class LinearProgrammingConstraint : public PropagatorInterface, // Use the dual optimal lp values to compute an EXACT lower bound on the // objective. Fills its reason and perform reduced cost strenghtening. // Returns false in case of conflict. - bool ExactLpReasonning(); + bool PropagateExactLpReason(); // Same as FillDualRayReason() but perform the computation EXACTLY. Returns // false in the case that the problem is not provably infeasible with exact // computations, true otherwise. - bool FillExactDualRayReason(); + bool PropagateExactDualRay(); + + // Called by PropagateExactLpReason() and PropagateExactDualRay() to finish + // propagation. + bool PropagateLpConstraint(const LinearConstraint& ct); // Returns number of non basic variables with zero reduced costs. int64_t CalculateDegeneracy(); @@ -368,11 +372,6 @@ class LinearProgrammingConstraint : public PropagatorInterface, // current variable bound. absl::int128 GetImpliedLowerBound(const LinearConstraint& terms) const; - // Fills integer_reason_ with the reason for the implied lower bound of the - // given linear expression. We relax the reason if we have some slack. - void SetImpliedLowerBoundReason(const LinearConstraint& terms, - IntegerValue slack); - // Fills the deductions vector with reduced cost deductions that can be made // from the current state of the LP solver. The given delta should be the // difference between the cp objective upper bound and lower bound given by diff --git a/ortools/sat/parameters_validation.cc b/ortools/sat/parameters_validation.cc index 765ca7ac693..57823cc0f3a 100644 --- a/ortools/sat/parameters_validation.cc +++ b/ortools/sat/parameters_validation.cc @@ -101,7 +101,6 @@ std::string ValidateParameters(const SatParameters& params) { TEST_IN_RANGE(min_num_lns_workers, 0, kMaxReasonableParallelism); TEST_IN_RANGE(shared_tree_num_workers, 0, kMaxReasonableParallelism); TEST_IN_RANGE(interleave_batch_size, 0, kMaxReasonableParallelism); - TEST_IN_RANGE(focus_on_terms_in_objective_lb_search_probability, 0.0, 1.0); // TODO(user): Consider using annotations directly in the proto for these // validation. It is however not open sourced. diff --git a/ortools/sat/pb_constraint.h b/ortools/sat/pb_constraint.h index 100d14fd5e7..6afe72b28eb 100644 --- a/ortools/sat/pb_constraint.h +++ b/ortools/sat/pb_constraint.h @@ -26,10 +26,10 @@ #include "absl/log/check.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/model.h" #include "ortools/sat/sat_base.h" #include "ortools/sat/sat_parameters.pb.h" diff --git a/ortools/sat/precedences.h b/ortools/sat/precedences.h index 41694f52eed..d5d4a788aed 100644 --- a/ortools/sat/precedences.h +++ b/ortools/sat/precedences.h @@ -22,9 +22,9 @@ #include "absl/container/inlined_vector.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/graph/graph.h" #include "ortools/sat/integer.h" #include "ortools/sat/model.h" diff --git a/ortools/sat/presolve_util.h b/ortools/sat/presolve_util.h index 1bf1812b820..77b7f261e68 100644 --- a/ortools/sat/presolve_util.h +++ b/ortools/sat/presolve_util.h @@ -26,9 +26,9 @@ #include "absl/random/random.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/cp_model.pb.h" #include "ortools/sat/cp_model_utils.h" #include "ortools/util/bitset.h" diff --git a/ortools/sat/samples/step_function_sample_sat.cc b/ortools/sat/samples/step_function_sample_sat.cc index 228369e96e7..f9eab7fcbdf 100644 --- a/ortools/sat/samples/step_function_sample_sat.cc +++ b/ortools/sat/samples/step_function_sample_sat.cc @@ -16,7 +16,7 @@ #include #include "absl/types/span.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/sat/cp_model.h" #include "ortools/sat/cp_model.pb.h" diff --git a/ortools/sat/sat_base.h b/ortools/sat/sat_base.h index e0113a385a6..24f403a7157 100644 --- a/ortools/sat/sat_base.h +++ b/ortools/sat/sat_base.h @@ -31,10 +31,10 @@ #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/model.h" #include "ortools/util/bitset.h" #include "ortools/util/strong_integers.h" diff --git a/ortools/sat/sat_decision.h b/ortools/sat/sat_decision.h index 9324b4dd7c7..53505d3ae88 100644 --- a/ortools/sat/sat_decision.h +++ b/ortools/sat/sat_decision.h @@ -18,8 +18,8 @@ #include #include -#include "ortools/base/integral_types.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/model.h" #include "ortools/sat/pb_constraint.h" #include "ortools/sat/sat_base.h" diff --git a/ortools/sat/sat_parameters.proto b/ortools/sat/sat_parameters.proto index 06d89a45b29..d23bf69be21 100644 --- a/ortools/sat/sat_parameters.proto +++ b/ortools/sat/sat_parameters.proto @@ -23,7 +23,7 @@ option csharp_namespace = "Google.OrTools.Sat"; // Contains the definitions for all the sat algorithm parameters and their // default values. // -// NEXT TAG: 256 +// NEXT TAG: 257 message SatParameters { // In some context, like in a portfolio of search, it makes sense to name a // given parameters set for logging purpose. @@ -1036,12 +1036,6 @@ message SatParameters { // minimizing) starting from the lower bound of the objective. optional bool use_objective_lb_search = 228 [default = false]; - // With the given probability, objective_lb_search will fix each terms of the - // objective following an random order computed each time search returns to - // the root node. - optional double focus_on_terms_in_objective_lb_search_probability = 231 - [default = 0.5]; - // This search differs from the previous search as it will not use assumptions // to bound the objective, and it will recreate a full model with the // hardcoded objective value. @@ -1336,6 +1330,11 @@ message SatParameters { // Experimental. Use new code to propagate linear constraint. optional bool new_linear_propagation = 224 [default = false]; + // Linear constraints that are not pseudo-Boolean and that are longer than + // this size will be split into sqrt(size) intermediate sums in order to have + // faster propation in the CP engine. + optional int32 linear_split_size = 256 [default = 100]; + // ========================================================================== // MIP -> CP-SAT (i.e. IP with integer coeff) conversion parameters that are // used by our automatic "scaling" algorithm. diff --git a/ortools/sat/sat_solver.h b/ortools/sat/sat_solver.h index 47f37fa3a02..7bdad8736d0 100644 --- a/ortools/sat/sat_solver.h +++ b/ortools/sat/sat_solver.h @@ -33,10 +33,10 @@ #include "absl/strings/string_view.h" #include "absl/types/span.h" #include "ortools/base/hash.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/timer.h" +#include "ortools/base/types.h" #include "ortools/sat/clause.h" #include "ortools/sat/drat_proof_handler.h" #include "ortools/sat/model.h" diff --git a/ortools/sat/simplification.h b/ortools/sat/simplification.h index fdce601688c..0a113bf8521 100644 --- a/ortools/sat/simplification.h +++ b/ortools/sat/simplification.h @@ -28,9 +28,9 @@ #include "absl/container/btree_set.h" #include "absl/types/span.h" #include "ortools/base/adjustable_priority_queue.h" -#include "ortools/base/integral_types.h" #include "ortools/base/macros.h" #include "ortools/base/strong_vector.h" +#include "ortools/base/types.h" #include "ortools/sat/drat_proof_handler.h" #include "ortools/sat/sat_base.h" #include "ortools/sat/sat_parameters.pb.h" diff --git a/ortools/util/BUILD.bazel b/ortools/util/BUILD.bazel index 44d84d3bc92..f0ad89da213 100644 --- a/ortools/util/BUILD.bazel +++ b/ortools/util/BUILD.bazel @@ -104,7 +104,7 @@ cc_library( hdrs = ["cached_log.h"], deps = [ "//ortools/base", - "//ortools/base:basictypes", + "//ortools/base:types", ], ) @@ -160,7 +160,7 @@ cc_library( deps = [ ":saturated_arithmetic", "//ortools/base", - "//ortools/base:basictypes", + "//ortools/base:types", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", diff --git a/ortools/util/adaptative_parameter_value.h b/ortools/util/adaptative_parameter_value.h index 503aee1b9ed..5a260bdee0c 100644 --- a/ortools/util/adaptative_parameter_value.h +++ b/ortools/util/adaptative_parameter_value.h @@ -18,7 +18,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { diff --git a/ortools/util/bitset.h b/ortools/util/bitset.h index b59dc646e6d..90ff980a5a6 100644 --- a/ortools/util/bitset.h +++ b/ortools/util/bitset.h @@ -22,7 +22,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" diff --git a/ortools/util/cached_log.h b/ortools/util/cached_log.h index 460b4a2756f..fd2be3f636e 100644 --- a/ortools/util/cached_log.h +++ b/ortools/util/cached_log.h @@ -18,8 +18,8 @@ #include -#include "ortools/base/basictypes.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" diff --git a/ortools/util/csharp/proto.i b/ortools/util/csharp/proto.i index 2f65b77fdda..19491b9f38c 100644 --- a/ortools/util/csharp/proto.i +++ b/ortools/util/csharp/proto.i @@ -16,7 +16,7 @@ %{ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" %} // SWIG macros to be used in generating C# wrappers for C++ protocol diff --git a/ortools/util/csharp/vector.i b/ortools/util/csharp/vector.i index b9db678ef24..2b9551d691a 100644 --- a/ortools/util/csharp/vector.i +++ b/ortools/util/csharp/vector.i @@ -16,7 +16,7 @@ %{ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" %} // Typemaps to represent arguments of types: diff --git a/ortools/util/fp_utils.cc b/ortools/util/fp_utils.cc index 1d00a33f67b..813305c3cf6 100644 --- a/ortools/util/fp_utils.cc +++ b/ortools/util/fp_utils.cc @@ -25,7 +25,7 @@ #include "absl/base/casts.h" #include "absl/base/internal/endian.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/logging.h" #include "ortools/util/bitset.h" diff --git a/ortools/util/fp_utils.h b/ortools/util/fp_utils.h index e9e05464491..9be99d77b4d 100644 --- a/ortools/util/fp_utils.h +++ b/ortools/util/fp_utils.h @@ -41,7 +41,7 @@ #include #endif -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #if defined(_MSC_VER) static inline double isnan(double value) { return _isnan(value); } diff --git a/ortools/util/functions_swig_helpers.h b/ortools/util/functions_swig_helpers.h index 8d785ad69c3..d090dd8b4e0 100644 --- a/ortools/util/functions_swig_helpers.h +++ b/ortools/util/functions_swig_helpers.h @@ -20,7 +20,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { namespace swig_util { diff --git a/ortools/util/functions_swig_test_helpers.h b/ortools/util/functions_swig_test_helpers.h index 1fd8b818ed4..a7e1f0722bd 100644 --- a/ortools/util/functions_swig_test_helpers.h +++ b/ortools/util/functions_swig_test_helpers.h @@ -25,7 +25,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { class FunctionSwigTestHelpers { diff --git a/ortools/util/java/functions.i b/ortools/util/java/functions.i index 0fde78478a4..6347bd30f80 100644 --- a/ortools/util/java/functions.i +++ b/ortools/util/java/functions.i @@ -27,7 +27,7 @@ %{ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/util/functions_swig_helpers.h" %} diff --git a/ortools/util/java/proto.i b/ortools/util/java/proto.i index a5e5899d736..36ec912fbb4 100644 --- a/ortools/util/java/proto.i +++ b/ortools/util/java/proto.i @@ -37,7 +37,7 @@ // @param param_name the parameter name %{ -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" %} %define PROTO_INPUT(CppProtoType, JavaProtoType, param_name) diff --git a/ortools/util/java/sorted_interval_list.i b/ortools/util/java/sorted_interval_list.i index 12bc9100318..a4a9c081949 100644 --- a/ortools/util/java/sorted_interval_list.i +++ b/ortools/util/java/sorted_interval_list.i @@ -17,7 +17,7 @@ %{ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/util/sorted_interval_list.h" %} diff --git a/ortools/util/java/tuple_set.i b/ortools/util/java/tuple_set.i index 2f64817094d..ee4cf87de4c 100644 --- a/ortools/util/java/tuple_set.i +++ b/ortools/util/java/tuple_set.i @@ -21,7 +21,7 @@ %{ // TODO(user): see if we can remove #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/util/tuple_set.h" %} diff --git a/ortools/util/java/vector.i b/ortools/util/java/vector.i index 57b59c42fe6..72fe0a03ed4 100644 --- a/ortools/util/java/vector.i +++ b/ortools/util/java/vector.i @@ -20,7 +20,7 @@ %{ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" %} // Typemaps to represents arguments of types "const std::vector&" or diff --git a/ortools/util/piecewise_linear_function.h b/ortools/util/piecewise_linear_function.h index 8d09d05bb4e..a56d9d6e476 100644 --- a/ortools/util/piecewise_linear_function.h +++ b/ortools/util/piecewise_linear_function.h @@ -27,9 +27,9 @@ #include #include -#include "ortools/base/basictypes.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/util/saturated_arithmetic.h" namespace operations_research { diff --git a/ortools/util/python/proto.i b/ortools/util/python/proto.i index 7bad6aa4590..136801184b9 100644 --- a/ortools/util/python/proto.i +++ b/ortools/util/python/proto.i @@ -13,7 +13,7 @@ %include "ortools/base/base.i" -%import "ortools/base/integral_types.h" +%import "ortools/base/types.h" namespace operations_research { %define PY_PROTO_TYPEMAP(PythonModule, PythonType, CppType) diff --git a/ortools/util/python/vector.i b/ortools/util/python/vector.i index 07d071c612e..9ea7d128b8c 100644 --- a/ortools/util/python/vector.i +++ b/ortools/util/python/vector.i @@ -14,7 +14,7 @@ // TODO(user): make this SWIG file comply with the SWIG style guide. %include "ortools/base/base.i" -%import "ortools/base/integral_types.h" +%import "ortools/base/types.h" // --------- std::vector wrapping ---------- diff --git a/ortools/util/range_query_function.cc b/ortools/util/range_query_function.cc index d387f005c7e..f2ac14e901d 100644 --- a/ortools/util/range_query_function.cc +++ b/ortools/util/range_query_function.cc @@ -19,9 +19,9 @@ #include #include -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" #include "ortools/util/range_minimum_query.h" namespace operations_research { diff --git a/ortools/util/range_query_function.h b/ortools/util/range_query_function.h index 8959d12501e..8e06ca569fd 100644 --- a/ortools/util/range_query_function.h +++ b/ortools/util/range_query_function.h @@ -20,7 +20,7 @@ #include #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { // RangeIntToIntFunction is an interface to int64_t->int64_t functions diff --git a/ortools/util/rational_approximation.h b/ortools/util/rational_approximation.h index b78cc6a9784..7d647755c8e 100644 --- a/ortools/util/rational_approximation.h +++ b/ortools/util/rational_approximation.h @@ -16,7 +16,7 @@ #include -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" namespace operations_research { diff --git a/ortools/util/saturated_arithmetic.h b/ortools/util/saturated_arithmetic.h index 986d902ded0..e324d6cce4b 100644 --- a/ortools/util/saturated_arithmetic.h +++ b/ortools/util/saturated_arithmetic.h @@ -18,7 +18,7 @@ #include #include "absl/base/casts.h" -#include "ortools/base/integral_types.h" +#include "ortools/base/types.h" #include "ortools/util/bitset.h" // This file contains implementations for saturated addition, subtraction and diff --git a/ortools/util/sorted_interval_list.cc b/ortools/util/sorted_interval_list.cc index b3ddb8d5723..bbee682f5fb 100644 --- a/ortools/util/sorted_interval_list.cc +++ b/ortools/util/sorted_interval_list.cc @@ -26,8 +26,8 @@ #include "absl/container/inlined_vector.h" #include "absl/strings/str_format.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" +#include "ortools/base/types.h" #include "ortools/util/saturated_arithmetic.h" namespace operations_research { diff --git a/ortools/util/sorted_interval_list.h b/ortools/util/sorted_interval_list.h index 8611c1a1606..2a1d958b3bd 100644 --- a/ortools/util/sorted_interval_list.h +++ b/ortools/util/sorted_interval_list.h @@ -23,8 +23,8 @@ #include "absl/container/inlined_vector.h" #include "absl/types/span.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" +#include "ortools/base/types.h" namespace operations_research { diff --git a/ortools/util/stats.cc b/ortools/util/stats.cc index a7cfb78cfd0..3de20ed8001 100644 --- a/ortools/util/stats.cc +++ b/ortools/util/stats.cc @@ -20,9 +20,9 @@ #include "absl/log/check.h" #include "absl/strings/str_format.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/stl_util.h" +#include "ortools/base/types.h" #include "ortools/port/sysinfo.h" #include "ortools/port/utf8.h" diff --git a/ortools/util/tuple_set.h b/ortools/util/tuple_set.h index 313f214b6d8..41e9f80dbac 100644 --- a/ortools/util/tuple_set.h +++ b/ortools/util/tuple_set.h @@ -39,9 +39,9 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "ortools/base/hash.h" -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" namespace operations_research { // ----- Main IntTupleSet class ----- diff --git a/ortools/util/vector_or_function.h b/ortools/util/vector_or_function.h index b3f087a96a3..edb4199ffd1 100644 --- a/ortools/util/vector_or_function.h +++ b/ortools/util/vector_or_function.h @@ -17,8 +17,8 @@ #include #include -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" +#include "ortools/base/types.h" namespace operations_research { diff --git a/ortools/util/zvector.h b/ortools/util/zvector.h index f039a2fdb54..25fb6701d9d 100644 --- a/ortools/util/zvector.h +++ b/ortools/util/zvector.h @@ -25,9 +25,9 @@ #include #include -#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" +#include "ortools/base/types.h" // An array class for storing arrays of integers. //