diff --git a/ortools/algorithms/BUILD.bazel b/ortools/algorithms/BUILD.bazel index a2956585b7..3494c5022d 100644 --- a/ortools/algorithms/BUILD.bazel +++ b/ortools/algorithms/BUILD.bazel @@ -11,9 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_proto//proto:defs.bzl", "proto_library") -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library") load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") package(default_visibility = ["//visibility:public"]) diff --git a/ortools/algorithms/python/BUILD.bazel b/ortools/algorithms/python/BUILD.bazel index f18af25005..f4ddbd6baa 100644 --- a/ortools/algorithms/python/BUILD.bazel +++ b/ortools/algorithms/python/BUILD.bazel @@ -11,12 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + # Python wrapper for .. load("@pip_deps//:requirements.bzl", "requirement") load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") -load("@rules_python//python:defs.bzl", "py_test") -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") load("@rules_cc//cc:defs.bzl", "cc_library") +load("@rules_python//python:defs.bzl", "py_test") # OSS solvers bool_flag( diff --git a/ortools/base/file.cc b/ortools/base/file.cc index 0642e0bc1b..a5c298506c 100644 --- a/ortools/base/file.cc +++ b/ortools/base/file.cc @@ -240,7 +240,8 @@ namespace { class NoOpErrorCollector : public google::protobuf::io::ErrorCollector { public: ~NoOpErrorCollector() override = default; - void RecordError(int line, int column, absl::string_view message) override {} + void RecordError(int /*line*/, int /*column*/, + absl::string_view /*message*/) override {} }; } // namespace diff --git a/ortools/graph/BUILD.bazel b/ortools/graph/BUILD.bazel index 67d996bbc4..bf5b28d80c 100644 --- a/ortools/graph/BUILD.bazel +++ b/ortools/graph/BUILD.bazel @@ -11,8 +11,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") package(default_visibility = ["//visibility:public"]) @@ -397,6 +397,7 @@ cc_library( ":dag_shortest_path", ":graph", ":topologicalsorter", + "//ortools/base:threadpool", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:log_severity", "@com_google_absl//absl/log:check", diff --git a/ortools/graph/java/BUILD.bazel b/ortools/graph/java/BUILD.bazel index 6d957193cc..a160d1d3b5 100644 --- a/ortools/graph/java/BUILD.bazel +++ b/ortools/graph/java/BUILD.bazel @@ -13,9 +13,9 @@ # Description: java wrapping of the C++ code at ../ -load("//bazel:swig_java.bzl", "ortools_java_wrap_cc") -load("@rules_jvm_external//:defs.bzl", "artifact") load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") +load("@rules_jvm_external//:defs.bzl", "artifact") +load("//bazel:swig_java.bzl", "ortools_java_wrap_cc") ortools_java_wrap_cc( name = "graph", diff --git a/ortools/graph/max_flow.h b/ortools/graph/max_flow.h index d56249df12..750cdba1ae 100644 --- a/ortools/graph/max_flow.h +++ b/ortools/graph/max_flow.h @@ -247,7 +247,7 @@ class SimpleMaxFlow { // instance that uses it. typedef ::util::ReverseArcStaticGraph Graph; std::unique_ptr underlying_graph_; - std::unique_ptr > underlying_max_flow_; + std::unique_ptr> underlying_max_flow_; }; // Specific but efficient priority queue implementation. The priority type must @@ -294,13 +294,13 @@ class PriorityQueueWithRestrictedPush { private: // Helper function to get the last element of a vector and pop it. - Element PopBack(std::vector >* queue); + Element PopBack(std::vector>* queue); // This is the heart of the algorithm. basically we split the elements by // parity of their priority and the precondition on the Push() ensures that // both vectors are always sorted by increasing priority. - std::vector > even_queue_; - std::vector > odd_queue_; + std::vector> even_queue_; + std::vector> odd_queue_; }; // We want an enum for the Status of a max flow run, and we want this @@ -660,6 +660,26 @@ class GenericMaxFlow : public MaxFlowStatusClass { #if !SWIG +// Note: SWIG does not seem to understand explicit template specialization and +// instantiation declarations. + +template <> +const FlowQuantity GenericMaxFlow::kMaxFlowQuantity; +template <> +const FlowQuantity + GenericMaxFlow<::util::ReverseArcListGraph<>>::kMaxFlowQuantity; +template <> +const FlowQuantity + GenericMaxFlow<::util::ReverseArcStaticGraph<>>::kMaxFlowQuantity; +template <> +const FlowQuantity + GenericMaxFlow<::util::ReverseArcMixedGraph<>>::kMaxFlowQuantity; + +extern template class GenericMaxFlow; +extern template class GenericMaxFlow<::util::ReverseArcListGraph<>>; +extern template class GenericMaxFlow<::util::ReverseArcStaticGraph<>>; +extern template class GenericMaxFlow<::util::ReverseArcMixedGraph<>>; + // Default instance MaxFlow that uses StarGraph. Note that we cannot just use a // typedef because of dependent code expecting MaxFlow to be a real class. // TODO(user): Modify this code and remove it. @@ -716,7 +736,7 @@ Element PriorityQueueWithRestrictedPush::Pop() { template Element PriorityQueueWithRestrictedPush::PopBack( - std::vector >* queue) { + std::vector>* queue) { DCHECK(!queue->empty()); Element element = queue->back().first; queue->pop_back(); @@ -724,4 +744,5 @@ Element PriorityQueueWithRestrictedPush::PopBack( } } // namespace operations_research + #endif // OR_TOOLS_GRAPH_MAX_FLOW_H_ diff --git a/ortools/graph/min_cost_flow.h b/ortools/graph/min_cost_flow.h index 681cc2d0b0..3664bda5fb 100644 --- a/ortools/graph/min_cost_flow.h +++ b/ortools/graph/min_cost_flow.h @@ -673,6 +673,22 @@ class GenericMinCostFlow : public MinCostFlowBase { #if !SWIG +// Note: SWIG does not seem to understand explicit template specialization and +// instantiation declarations. + +extern template class GenericMinCostFlow; +extern template class GenericMinCostFlow<::util::ReverseArcListGraph<>>; +extern template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>; +extern template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>; +extern template class GenericMinCostFlow< + ::util::ReverseArcStaticGraph>; +extern template class GenericMinCostFlow< + ::util::ReverseArcListGraph, int64_t, int64_t>; +extern template class GenericMinCostFlow< + ::util::ReverseArcStaticGraph, + /*ArcFlowType=*/int16_t, + /*ArcScaledCostType=*/int32_t>; + // Default MinCostFlow instance that uses StarGraph. // New clients should use SimpleMinCostFlow if they can. class MinCostFlow : public GenericMinCostFlow { diff --git a/ortools/graph/samples/assignment_min_flow.py b/ortools/graph/samples/assignment_min_flow.py index 42d775c3e8..22f9cd8e18 100755 --- a/ortools/graph/samples/assignment_min_flow.py +++ b/ortools/graph/samples/assignment_min_flow.py @@ -72,6 +72,7 @@ def main(): for arc in range(smcf.num_arcs()): # Can ignore arcs leading out of source or into sink. if smcf.tail(arc) != source and smcf.head(arc) != sink: + # Arcs in the solution have a flow value of 1. Their start and end nodes # give an assignment of worker to task. if smcf.flow(arc) > 0: diff --git a/ortools/graph/samples/balance_min_flow.py b/ortools/graph/samples/balance_min_flow.py index 8a0c97a2e2..3c13128949 100755 --- a/ortools/graph/samples/balance_min_flow.py +++ b/ortools/graph/samples/balance_min_flow.py @@ -103,6 +103,7 @@ def main(): and smcf.tail(arc) != 12 and smcf.head(arc) != sink ): + # Arcs in the solution will have a flow value of 1. # There start and end nodes give an assignment of worker to task. if smcf.flow(arc) > 0: diff --git a/ortools/graph/solve_flow_model.cc b/ortools/graph/solve_flow_model.cc index f057b7e019..7d3118bd86 100644 --- a/ortools/graph/solve_flow_model.cc +++ b/ortools/graph/solve_flow_model.cc @@ -30,6 +30,7 @@ #include "absl/status/status.h" #include "absl/strings/match.h" #include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/file.h" #include "ortools/base/filesystem.h" @@ -98,7 +99,7 @@ void ConvertFlowModelToDimacs(const FlowModelProto& flow_model, // Note(user): Going from Dimacs to flow adds an extra copy, but for now we // don't really care of the Dimacs file reading performance. // Returns true if the file was converted correctly. -bool ConvertDimacsToFlowModel(const std::string& file, +bool ConvertDimacsToFlowModel(absl::string_view file, FlowModelProto* flow_model) { flow_model->Clear(); FlowModelProto::ProblemType problem_type; diff --git a/ortools/packing/binpacking_2d_parser.cc b/ortools/packing/binpacking_2d_parser.cc index e58cbed75c..beff9dfd50 100644 --- a/ortools/packing/binpacking_2d_parser.cc +++ b/ortools/packing/binpacking_2d_parser.cc @@ -18,6 +18,7 @@ #include "absl/strings/numbers.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "ortools/base/logging.h" #include "ortools/util/filelineiter.h" @@ -30,7 +31,7 @@ BinPacking2dParser::BinPacking2dParser() num_items_(0), instances_seen_(0) {} -bool BinPacking2dParser::Load2BPFile(const std::string& file_name, +bool BinPacking2dParser::Load2BPFile(absl::string_view file_name, int instance) { if (load_status_ != NOT_STARTED) { return false; diff --git a/ortools/packing/binpacking_2d_parser.h b/ortools/packing/binpacking_2d_parser.h index a30f3a89a3..8fc82b37c5 100644 --- a/ortools/packing/binpacking_2d_parser.h +++ b/ortools/packing/binpacking_2d_parser.h @@ -17,6 +17,7 @@ #include #include +#include "absl/strings/string_view.h" #include "ortools/base/types.h" #include "ortools/packing/multiple_dimensions_bin_packing.pb.h" @@ -50,7 +51,7 @@ class BinPacking2dParser { // file. The instance are 1 based (first is 1). // Only one call to a Load*() function is supported. All the subsequent // calls will do nothing and return false. - bool Load2BPFile(const std::string& file_name, int instance); + bool Load2BPFile(absl::string_view file_name, int instance); MultipleDimensionsBinPackingProblem problem() const { return problem_; } private: diff --git a/ortools/pdlp/primal_dual_hybrid_gradient.cc b/ortools/pdlp/primal_dual_hybrid_gradient.cc index 05af624274..7b2a8013aa 100644 --- a/ortools/pdlp/primal_dual_hybrid_gradient.cc +++ b/ortools/pdlp/primal_dual_hybrid_gradient.cc @@ -992,6 +992,9 @@ SolverResult PreprocessSolver::PreprocessAndSolve( WallTimer timer; timer.Start(); SolveLog solve_log; + if (params.verbosity_level() >= 1) { + SOLVER_LOG(&logger_, "Solving with PDLP parameters: ", params); + } if (Qp().problem_name.has_value()) { solve_log.set_instance_name(*Qp().problem_name); } diff --git a/ortools/pdlp/python/BUILD.bazel b/ortools/pdlp/python/BUILD.bazel index 58d4d2a703..270920aa98 100644 --- a/ortools/pdlp/python/BUILD.bazel +++ b/ortools/pdlp/python/BUILD.bazel @@ -13,9 +13,9 @@ # Python wrapper for pdlp libraries. +load("@pip_deps//:requirements.bzl", "requirement") load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") load("@rules_python//python:defs.bzl", "py_test") -load("@pip_deps//:requirements.bzl", "requirement") pybind_extension( name = "pdlp", diff --git a/ortools/pdlp/python/pdlp_test.py b/ortools/pdlp/python/pdlp_test.py index a7a87524ed..db5ef2a567 100644 --- a/ortools/pdlp/python/pdlp_test.py +++ b/ortools/pdlp/python/pdlp_test.py @@ -76,6 +76,7 @@ def small_proto_qp(): class QuadraticProgramTest(absltest.TestCase): + def test_validate_quadratic_program_dimensions_for_empty_qp(self): qp = pdlp.QuadraticProgram() qp.resize_and_initialize(3, 2) @@ -189,6 +190,7 @@ def test_lp(): class PrimalDualHybridGradientTest(absltest.TestCase): + def test_iteration_limit(self): params = solvers_pb2.PrimalDualHybridGradientParams() params.termination_criteria.iteration_limit = 1 diff --git a/ortools/util/parse_proto.cc b/ortools/util/parse_proto.cc index 6bbcf508ba..118881ed6f 100644 --- a/ortools/util/parse_proto.cc +++ b/ortools/util/parse_proto.cc @@ -36,11 +36,16 @@ class TextFormatErrorCollector : public google::protobuf::io::ErrorCollector { TextFormatErrorCollector() = default; ~TextFormatErrorCollector() override = default; - void RecordError(int line, int column, absl::string_view message) override { - collected_errors_.push_back({false, line, column, std::string(message)}); + void RecordError(const int line, const int column, + absl::string_view message) override { + collected_errors_.push_back( + {/*warning=*/false, line, column, std::string(message)}); } - void RecordWarning(int line, int column, absl::string_view message) override { - collected_errors_.push_back({true, line, column, std::string(message)}); + + void RecordWarning(const int line, const int column, + absl::string_view message) override { + collected_errors_.push_back( + {/*warning=*/true, line, column, std::string(message)}); } // Returns a string listing each collected error. When an error is associated @@ -80,7 +85,7 @@ bool ParseTextProtoForFlag(const absl::string_view text, TextFormatErrorCollector errors; google::protobuf::TextFormat::Parser parser; parser.RecordErrorsTo(&errors); - const bool success = parser.ParseFromString(text, message_out); + const bool success = parser.ParseFromString(std::string(text), message_out); *error_out = errors.RenderErrorMessage(text); return success; }