diff --git a/ortools/algorithms/BUILD b/ortools/algorithms/BUILD index e2956c67e3..4970c77cc3 100644 --- a/ortools/algorithms/BUILD +++ b/ortools/algorithms/BUILD @@ -14,7 +14,7 @@ cc_library( cc_test( name = "hungarian_test", - size = "small", + size = "medium", srcs = ["hungarian_test.cc"], copts = ["-Iexternal/gtest/include"], deps = [ diff --git a/ortools/algorithms/knapsack_solver_for_cuts.h b/ortools/algorithms/knapsack_solver_for_cuts.h index 2f5acb9ee9..df3a8e380d 100644 --- a/ortools/algorithms/knapsack_solver_for_cuts.h +++ b/ortools/algorithms/knapsack_solver_for_cuts.h @@ -368,7 +368,7 @@ class KnapsackSolverForCuts { int GetNextItemId() const { return propagator_.GetNextItemId(); } KnapsackPropagatorForCuts propagator_; - std::vector > search_nodes_; + std::vector> search_nodes_; KnapsackStateForCuts state_; double best_solution_profit_; std::vector best_solution_; diff --git a/ortools/algorithms/samples/Knapsack.java b/ortools/algorithms/samples/Knapsack.java index a676a4af63..a18a832e4b 100644 --- a/ortools/algorithms/samples/Knapsack.java +++ b/ortools/algorithms/samples/Knapsack.java @@ -19,7 +19,8 @@ import com.google.ortools.algorithms.KnapsackSolver; import java.util.ArrayList; // [END import] -/** Sample showing how to model using the knapsack solver. */ +/** Sample showing how to model using the knapsack solver. + */ public class Knapsack { private Knapsack() {} diff --git a/ortools/base/cleanup.h b/ortools/base/cleanup.h index a187fb09a6..80507f9f25 100644 --- a/ortools/base/cleanup.h +++ b/ortools/base/cleanup.h @@ -117,8 +117,8 @@ class ABSL_MUST_USE_RESULT Cleanup { }; template -absl::Cleanup > MakeCleanup(Callback&& callback) { - return absl::Cleanup >( +absl::Cleanup> MakeCleanup(Callback&& callback) { + return absl::Cleanup>( std::forward(callback)); } diff --git a/ortools/base/hash.h b/ortools/base/hash.h index 0fba40fbdd..f8e13c8893 100644 --- a/ortools/base/hash.h +++ b/ortools/base/hash.h @@ -110,7 +110,7 @@ inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) { // Support a few hash<> operators, in the hash namespace. namespace std { template -struct hash > { +struct hash> { size_t operator()(const std::pair& p) const { size_t h1 = hash()(p.first); size_t h2 = hash()(p.second); @@ -123,7 +123,7 @@ struct hash > { }; template -struct hash > { +struct hash> { public: size_t operator()(const std::array& t) const { uint64 current = 71; diff --git a/ortools/base/int_type.h b/ortools/base/int_type.h index b4da2ee40f..e333c95ce2 100644 --- a/ortools/base/int_type.h +++ b/ortools/base/int_type.h @@ -242,9 +242,9 @@ class IntType { constexpr const ThisType operator-() const { return ThisType(-value_); } constexpr const ThisType operator~() const { return ThisType(~value_); } -// -- ASSIGNMENT OPERATORS --------------------------------------------------- -// We support the following assignment operators: =, +=, -=, *=, /=, <<=, >>= -// and %= for both ThisType and ValueType. + // -- ASSIGNMENT OPERATORS --------------------------------------------------- + // We support the following assignment operators: =, +=, -=, *=, /=, <<=, >>= + // and %= for both ThisType and ValueType. #define INT_TYPE_ASSIGNMENT_OP(op) \ ThisType& operator op(const ThisType& arg_value) { \ value_ op arg_value.value(); \ diff --git a/ortools/base/protobuf_util.h b/ortools/base/protobuf_util.h index 5811654cb0..3ed4874aa7 100644 --- a/ortools/base/protobuf_util.h +++ b/ortools/base/protobuf_util.h @@ -36,7 +36,7 @@ inline void Truncate(RepeatedPtrField* array, int new_size) { // 1] where N is the number of elements in 'array', and RepeatedType must be // RepeatedField or RepeatedPtrField. // Returns number of elements erased. -template > +template > int RemoveAt(RepeatedType* array, const IndexContainer& indices) { if (indices.size() == 0) { return 0; diff --git a/ortools/base/threadpool.h b/ortools/base/threadpool.h index 5344562bc6..01bd65ff17 100644 --- a/ortools/base/threadpool.h +++ b/ortools/base/threadpool.h @@ -35,7 +35,7 @@ class ThreadPool { private: const int num_workers_; - std::list > tasks_; + std::list> tasks_; std::mutex mutex_; std::condition_variable condition_; std::condition_variable capacity_condition_; diff --git a/ortools/bop/BUILD b/ortools/bop/BUILD index 8916a866a1..76e5c13018 100644 --- a/ortools/bop/BUILD +++ b/ortools/bop/BUILD @@ -168,7 +168,6 @@ cc_library( ":bop_solution", ":bop_types", ":bop_util", - "@com_google_absl//absl/status:statusor", "//ortools/base", "//ortools/base:hash", "//ortools/base:int_type", @@ -177,6 +176,7 @@ cc_library( "//ortools/sat:boolean_problem", "//ortools/sat:boolean_problem_cc_proto", "//ortools/sat:sat_solver", + "@com_google_absl//absl/status:statusor", ], ) @@ -194,11 +194,11 @@ cc_library( ":bop_types", ":bop_util", ":complete_optimizer", - "@com_google_absl//absl/status:statusor", "//ortools/base", "//ortools/base:hash", "//ortools/base:int_type", "//ortools/base:int_type_indexed_vector", + "@com_google_absl//absl/status:statusor", "//ortools/base:stl_util", "//ortools/glop:lp_solver", #"//ortools/glop", diff --git a/ortools/bop/bop_lns.h b/ortools/bop/bop_lns.h index a2ccd00e47..b69a5e693b 100644 --- a/ortools/bop/bop_lns.h +++ b/ortools/bop/bop_lns.h @@ -174,7 +174,7 @@ class RelationGraphBasedNeighborhood : public NeighborhoodGenerator { // TODO(user): reuse by_variable_matrix_ from the LS? Note however than we // don't need the coefficients here. - gtl::ITIVector > columns_; + gtl::ITIVector> columns_; MTRandom* random_; }; diff --git a/ortools/bop/bop_ls.h b/ortools/bop/bop_ls.h index 62176b7d7c..72fce52bee 100644 --- a/ortools/bop/bop_ls.h +++ b/ortools/bop/bop_ls.h @@ -388,7 +388,7 @@ class AssignmentAndConstraintFeasibilityMaintainer { int64 weight; }; - gtl::ITIVector > + gtl::ITIVector> by_variable_matrix_; gtl::ITIVector constraint_lower_bounds_; gtl::ITIVector constraint_upper_bounds_; @@ -408,7 +408,7 @@ class AssignmentAndConstraintFeasibilityMaintainer { // Members used by PotentialOneFlipRepairs(). std::vector tmp_potential_repairs_; NonOrderedSetHasher constraint_set_hasher_; - absl::flat_hash_map > + absl::flat_hash_map> hash_to_potential_repairs_; DISALLOW_COPY_AND_ASSIGN(AssignmentAndConstraintFeasibilityMaintainer); @@ -485,7 +485,7 @@ class OneFlipConstraintRepairer { // on most promising variables first. void SortTermsOfEachConstraints(int num_variables); - gtl::ITIVector > + gtl::ITIVector> by_constraint_matrix_; const AssignmentAndConstraintFeasibilityMaintainer& maintainer_; const sat::VariablesAssignment& sat_assignment_; @@ -616,7 +616,7 @@ class LocalSearchAssignmentIterator { // Ideally, this should be related to the maximum number of decision in the // LS, but that requires templating the whole LS optimizer. bool use_transposition_table_; - absl::flat_hash_set > + absl::flat_hash_set> transposition_table_; bool use_potential_one_flip_repairs_; diff --git a/ortools/constraint_solver/BUILD b/ortools/constraint_solver/BUILD index 22a657d768..1ca739667b 100644 --- a/ortools/constraint_solver/BUILD +++ b/ortools/constraint_solver/BUILD @@ -149,17 +149,17 @@ cc_library( "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", -# "//third_party/zlib:zlibonly", + # "//zlib:zlibonly", "//ortools/base:bitmap", "//ortools/base:int_type", "//ortools/base:int_type_indexed_vector", "//ortools/base:iterator_adaptors", "//ortools/base:map_util", "//ortools/base:stl_util", -# "//util/gzip:gzipstring", + # "//util/gzip:gzipstring", "//ortools/base:hash", -# "//util/hash:jenkins", -# "//util/math:fastmath", + # "//util/hash:jenkins", + # "//util/math:fastmath", "//ortools/base:mathutil", "//ortools/graph:hamiltonian_path", "//ortools/util:bitset", @@ -173,11 +173,11 @@ cc_library( "//ortools/util:tuple_set", "//ortools/util:vector_map", "//ortools/base:random", -# "//util/regexp/re2", + # "//util/regexp/re2", "@com_google_absl//absl/status", -# "//util/textprogressbar", + # "//util/textprogressbar", "//ortools/base:timer", -# "//util/zippy", + # "//util/zippy", ], ) @@ -323,7 +323,7 @@ cc_library( "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/time", -# "//third_party/kdtree", + # "//kdtree", "//ortools/graph", "//ortools/base:int_type_indexed_vector", "//ortools/base:map_util", diff --git a/ortools/constraint_solver/doc/CP.md b/ortools/constraint_solver/doc/CP.md index f8e0a0da14..828b8cce12 100644 --- a/ortools/constraint_solver/doc/CP.md +++ b/ortools/constraint_solver/doc/CP.md @@ -113,6 +113,7 @@ if __name__ == '__main__': ```java package com.google.ortools.constraintsolver.samples; +import com.google.ortools.Loader; import com.google.ortools.constraintsolver.DecisionBuilder; import com.google.ortools.constraintsolver.IntVar; import com.google.ortools.constraintsolver.Solver; @@ -120,12 +121,12 @@ import java.util.logging.Logger; /** Simple CP Program.*/ public class SimpleCpProgram { - static { System.loadLibrary("jniortools"); } private SimpleCpProgram() {} private static final Logger logger = Logger.getLogger(SimpleCpProgram.class.getName()); public static void main(String[] args) throws Exception { + Loader.loadNativeLibraries(); // Instantiate the solver. Solver solver = new Solver("CpSimple"); diff --git a/ortools/constraint_solver/doc/ROUTING.md b/ortools/constraint_solver/doc/ROUTING.md index 36a966d97e..e8f3ee93e9 100644 --- a/ortools/constraint_solver/doc/ROUTING.md +++ b/ortools/constraint_solver/doc/ROUTING.md @@ -154,6 +154,7 @@ if __name__ == '__main__': package com.google.ortools.constraintsolver.samples; import static java.lang.Math.abs; +import com.google.ortools.Loader; import com.google.ortools.constraintsolver.FirstSolutionStrategy; import com.google.ortools.constraintsolver.RoutingSearchParameters; import com.google.ortools.constraintsolver.Assignment; @@ -164,12 +165,11 @@ import java.util.logging.Logger; /** Minimal Routing example to showcase calling the solver.*/ public class SimpleRoutingProgram { - static { System.loadLibrary("jniortools"); } - private static final Logger logger = Logger.getLogger(SimpleRoutingProgram.class.getName()); public static void main(String[] args) throws Exception { + Loader.loadNativeLibraries(); // Instantiate the data problem. final int numLocation = 5; final int numVehicles = 1; diff --git a/ortools/constraint_solver/local_search.cc b/ortools/constraint_solver/local_search.cc index f1f0f0d5ab..96138b9358 100644 --- a/ortools/constraint_solver/local_search.cc +++ b/ortools/constraint_solver/local_search.cc @@ -108,9 +108,8 @@ bool BaseLns::MakeOneNeighbor() { Deactivate(candidate); } return true; - } else { - return false; } + return false; } void BaseLns::OnStart() { InitFragments(); } @@ -154,9 +153,8 @@ bool SimpleLns::NextFragment() { } ++index_; return true; - } else { - return false; } + return false; } // ----- Random Large Neighborhood Search operator ----- @@ -405,10 +403,9 @@ bool PathOperator::SkipUnchanged(int index) const { if (index < number_of_nexts_) { int path_index = index + number_of_nexts_; return Value(path_index) == OldValue(path_index); - } else { - int next_index = index - number_of_nexts_; - return Value(next_index) == OldValue(next_index); } + int next_index = index - number_of_nexts_; + return Value(next_index) == OldValue(next_index); } bool PathOperator::MoveChain(int64 before_chain, int64 chain_end, @@ -463,9 +460,8 @@ bool PathOperator::MakeActive(int64 node, int64 destination) { SetNext(node, Next(destination), destination_path); SetNext(destination, node, destination_path); return true; - } else { - return false; } + return false; } bool PathOperator::MakeChainInactive(int64 before_chain, int64 chain_end) { @@ -513,9 +509,8 @@ bool PathOperator::IncrementPosition() { alternative_sets_[sibling_alternative_index].size() - 1) { ++base_sibling_alternatives_[i]; break; - } else { - base_sibling_alternatives_[i] = 0; } + base_sibling_alternatives_[i] = 0; } // Iterate on base alternatives. const int alternative_index = alternative_index_[base_nodes_[i]]; @@ -524,10 +519,9 @@ bool PathOperator::IncrementPosition() { alternative_sets_[alternative_index].size() - 1) { ++base_alternatives_[i]; break; - } else { - base_alternatives_[i] = 0; - base_sibling_alternatives_[i] = 0; } + base_alternatives_[i] = 0; + base_sibling_alternatives_[i] = 0; } } base_alternatives_[i] = 0; @@ -687,11 +681,8 @@ void PathOperator::InitializePathStarts() { if (!has_prevs[i]) { if (use_empty_path_symmetry_breaker && IsPathEnd(OldNext(i))) { if (start_empty_path_class_ != nullptr) { - if (empty_found[start_empty_path_class_(i)]) { - continue; - } else { - empty_found[start_empty_path_class_(i)] = true; - } + if (empty_found[start_empty_path_class_(i)]) continue; + empty_found[start_empty_path_class_(i)] = true; } } new_path_starts.push_back(i); @@ -917,15 +908,13 @@ bool TwoOpt::MakeNeighbor() { // single node is a NOP). && last_ != chain_last) { return true; - } else { - last_ = -1; - return false; } - } else { - const int64 to_move = Next(last_); - DCHECK_EQ(Next(to_move), BaseNode(1)); - return MoveChain(last_, to_move, BaseNode(0)); + last_ = -1; + return false; } + const int64 to_move = Next(last_); + DCHECK_EQ(Next(to_move), BaseNode(1)); + return MoveChain(last_, to_move, BaseNode(0)); } // ----- Relocate ----- @@ -1072,11 +1061,9 @@ bool Cross::MakeNeighbor() { return false; } return MoveChain(start0, node0, start1) && MoveChain(node0, node1, start0); - } else if (!IsPathEnd(node0)) { - return MoveChain(start0, node0, start1); - } else if (!IsPathEnd(node1)) { - return MoveChain(start1, node1, start0); } + if (!IsPathEnd(node0)) return MoveChain(start0, node0, start1); + if (!IsPathEnd(node1)) return MoveChain(start1, node1, start0); return false; } @@ -1307,11 +1294,7 @@ class MakeChainInactiveOperator : public PathOperator { int64 GetBaseNodeRestartPosition(int base_index) override { // Base node 1 must be after base node 0. - if (base_index == 0) { - return StartNode(base_index); - } else { - return BaseNode(base_index - 1); - } + return (base_index == 0) ? StartNode(base_index) : BaseNode(base_index - 1); } }; @@ -1529,10 +1512,7 @@ bool TSPLns::MakeNeighbor() { breaks_set.insert(base_node); CHECK(!nodes.empty()); // Should have been caught earlier. while (breaks_set.size() < tsp_size_) { - const int64 one_break = nodes[absl::Uniform(rand_, 0, nodes.size())]; - if (!gtl::ContainsKey(breaks_set, one_break)) { - breaks_set.insert(one_break); - } + breaks_set.insert(nodes[absl::Uniform(rand_, 0, nodes.size())]); } CHECK_EQ(breaks_set.size(), tsp_size_); // Setup break node indexing and internal meta-node cost (cost of partial @@ -2023,11 +2003,8 @@ bool CompoundOperator::MakeNextNeighbor(Assignment* delta, int64 CompoundOperatorNoRestart(int size, int active_index, int operator_index) { - if (operator_index < active_index) { - return size + operator_index - active_index; - } else { - return operator_index - active_index; - } + return (operator_index < active_index) ? size + operator_index - active_index + : operator_index - active_index; } int64 CompoundOperatorRestart(int active_index, int operator_index) { @@ -2045,12 +2022,11 @@ LocalSearchOperator* Solver::ConcatenateOperators( if (restart) { std::function eval = CompoundOperatorRestart; return ConcatenateOperators(ops, eval); - } else { - const int size = ops.size(); - return ConcatenateOperators(ops, [size](int i, int j) { - return CompoundOperatorNoRestart(size, i, j); - }); } + const int size = ops.size(); + return ConcatenateOperators(ops, [size](int i, int j) { + return CompoundOperatorNoRestart(size, i, j); + }); } LocalSearchOperator* Solver::ConcatenateOperators( @@ -2632,35 +2608,53 @@ PathState::NodeRange PathState::Nodes(int path) const { committed_nodes_.data()); } -void PathState::CutChains() { - if (is_invalid_) return; - // Filter out unchanged arcs from changed_arcs_, - // translate changed arcs to changed arc indices. - // Fill changed_paths_ while we hold node_path. - DCHECK_EQ(chains_.size(), num_paths_ + 1); // One per path + sentinel. - DCHECK(changed_paths_.empty()); - tail_head_indices_.clear(); - int num_changed_arcs = 0; - for (const auto& arc : changed_arcs_) { - int node, next; - std::tie(node, next) = arc; - const int node_index = committed_index_[node]; - const int next_index = committed_index_[next]; - const int node_path = committed_nodes_[node_index].path; - if (next != node && - (next_index != node_index + 1 || node_path == -1)) { // New arc. - tail_head_indices_.push_back({node_index, next_index}); - changed_arcs_[num_changed_arcs++] = {node, next}; - if (node_path != -1 && !path_has_changed_[node_path]) { - path_has_changed_[node_path] = true; - changed_paths_.push_back(node_path); +void PathState::MakeChainsFromChangedPathsAndArcsWithSelectionAlgorithm() { + int num_visited_changed_arcs = 0; + const int num_changed_arcs = tail_head_indices_.size(); + const int num_committed_nodes = committed_nodes_.size(); + // For every path, find all its chains. + for (const int path : changed_paths_) { + const int old_chain_size = chains_.size(); + const ChainBounds bounds = chains_[paths_[path].begin_index]; + const int start_index = bounds.begin_index; + const int end_index = bounds.end_index - 1; + int current_index = start_index; + while (true) { + // Look for smallest non-visited tail_index that is no smaller than + // current_index. + int selected_arc = -1; + int selected_tail_index = num_committed_nodes; + for (int i = num_visited_changed_arcs; i < num_changed_arcs; ++i) { + const int tail_index = tail_head_indices_[i].tail_index; + if (current_index <= tail_index && tail_index < selected_tail_index) { + selected_arc = i; + selected_tail_index = tail_index; + } + } + // If there is no such tail index, or more generally if the next chain + // would be cut by end of path, + // stack {current_index, end_index + 1} in chains_, and go to next path. + // Otherwise, stack {current_index, tail_index+1} in chains_, + // set current_index = head_index, set pair to visited. + if (start_index <= current_index && current_index <= end_index && + end_index < selected_tail_index) { + chains_.emplace_back(current_index, end_index + 1); + break; + } else { + chains_.emplace_back(current_index, selected_tail_index + 1); + current_index = tail_head_indices_[selected_arc].head_index; + std::swap(tail_head_indices_[num_visited_changed_arcs], + tail_head_indices_[selected_arc]); + ++num_visited_changed_arcs; } - } else if (node == next && node_path != -1) { // New loop. - changed_arcs_[num_changed_arcs++] = {node, node}; } + const int new_chain_size = chains_.size(); + paths_[path] = {old_chain_size, new_chain_size}; } - changed_arcs_.resize(num_changed_arcs); + chains_.emplace_back(0, 0); // Sentinel. +} +void PathState::MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm() { // TRICKY: For each changed path, we want to generate a sequence of chains // that represents the path in the changed state. // First, notice that if we add a fake end->start arc for each changed path, @@ -2719,6 +2713,42 @@ void PathState::CutChains() { chains_.emplace_back(0, 0); // Sentinel. } +void PathState::CutChains() { + if (is_invalid_) return; + // Filter out unchanged arcs from changed_arcs_, + // translate changed arcs to changed arc indices. + // Fill changed_paths_ while we hold node_path. + DCHECK_EQ(chains_.size(), num_paths_ + 1); // One per path + sentinel. + DCHECK(changed_paths_.empty()); + tail_head_indices_.clear(); + int num_changed_arcs = 0; + for (const auto& arc : changed_arcs_) { + int node, next; + std::tie(node, next) = arc; + const int node_index = committed_index_[node]; + const int next_index = committed_index_[next]; + const int node_path = committed_nodes_[node_index].path; + if (next != node && + (next_index != node_index + 1 || node_path == -1)) { // New arc. + tail_head_indices_.push_back({node_index, next_index}); + changed_arcs_[num_changed_arcs++] = {node, next}; + if (node_path != -1 && !path_has_changed_[node_path]) { + path_has_changed_[node_path] = true; + changed_paths_.push_back(node_path); + } + } else if (node == next && node_path != -1) { // New loop. + changed_arcs_[num_changed_arcs++] = {node, node}; + } + } + changed_arcs_.resize(num_changed_arcs); + + if (tail_head_indices_.size() + changed_paths_.size() <= 8) { + MakeChainsFromChangedPathsAndArcsWithSelectionAlgorithm(); + } else { + MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm(); + } +} + void PathState::Commit() { DCHECK(!IsInvalid()); if (committed_nodes_.size() < num_nodes_threshold_) { @@ -3419,12 +3449,11 @@ class BinaryObjectiveFilter : public SumObjectiveFilter { if (element.Activated()) { *new_cost = value_evaluator_(index, element.Value()); return true; - } else { - const IntVar* var = element.Var(); - if (var->Bound()) { - *new_cost = value_evaluator_(index, var->Min()); - return true; - } + } + const IntVar* var = element.Var(); + if (var->Bound()) { + *new_cost = value_evaluator_(index, var->Min()); + return true; } *new_cost = 0; return false; @@ -3476,12 +3505,11 @@ class TernaryObjectiveFilter : public SumObjectiveFilter { container.Element(secondary_var).Value()); } return true; - } else { - const IntVar* var = element.Var(); - if (var->Bound() && secondary_var->Bound()) { - *new_cost = value_evaluator_(index, var->Min(), secondary_var->Min()); - return true; - } + } + const IntVar* var = element.Var(); + if (var->Bound() && secondary_var->Bound()) { + *new_cost = value_evaluator_(index, var->Min(), secondary_var->Min()); + return true; } *new_cost = 0; return false; @@ -3806,9 +3834,8 @@ void InstallLocalSearchProfiler(LocalSearchProfiler* monitor) { LocalSearchProfiler* BuildLocalSearchProfiler(Solver* solver) { if (solver->IsLocalSearchProfilingEnabled()) { return new LocalSearchProfiler(solver); - } else { - return nullptr; } + return nullptr; } void DeleteLocalSearchProfiler(LocalSearchProfiler* monitor) { delete monitor; } @@ -4171,25 +4198,24 @@ Decision* FindOneNeighbor::Next(Solver* const solver) { neighbor_found_ = true; has_checked_assignment_ = true; return nullptr; - } else { - solver->SetSearchContext(solver->ActiveSearch(), - ls_operator_->DebugString()); - assignment_->CopyIntersection(assignment_copy); - assignment_->SetObjectiveValue( - filter_manager_ ? filter_manager_->GetAcceptedObjectiveValue() - : 0); - // Advancing local search to the current solution without - // checking. - // TODO(user): support the case were limit_ accepts more than - // one solution (e.g. best accept). - AcceptUncheckedNeighbor(solver->ParentSearch()); - solver->IncrementUncheckedSolutionCounter(); - pool_->RegisterNewSolution(assignment_); - SynchronizeAll(solver); - // NOTE: SynchronizeAll() sets neighbor_found_ to false, force it - // back to true when skipping checks. - neighbor_found_ = true; } + solver->SetSearchContext(solver->ActiveSearch(), + ls_operator_->DebugString()); + assignment_->CopyIntersection(assignment_copy); + assignment_->SetObjectiveValue( + filter_manager_ ? filter_manager_->GetAcceptedObjectiveValue() + : 0); + // Advancing local search to the current solution without + // checking. + // TODO(user): support the case were limit_ accepts more than + // one solution (e.g. best accept). + AcceptUncheckedNeighbor(solver->ParentSearch()); + solver->IncrementUncheckedSolutionCounter(); + pool_->RegisterNewSolution(assignment_); + SynchronizeAll(solver); + // NOTE: SynchronizeAll() sets neighbor_found_ to false, force it + // back to true when skipping checks. + neighbor_found_ = true; } else { if (filter_manager_ != nullptr) filter_manager_->Revert(); if (check_period_ > 1 && has_checked_assignment_) { @@ -4649,7 +4675,8 @@ Decision* LocalSearch::Next(Solver* const solver) { const int depth = solver->SearchDepth(); if (depth < kLocalSearchBalancedTreeDepth) { return solver->balancing_decision(); - } else if (depth > kLocalSearchBalancedTreeDepth) { + } + if (depth > kLocalSearchBalancedTreeDepth) { solver->Fail(); } return decision; diff --git a/ortools/constraint_solver/python/pywrapcp_util.h b/ortools/constraint_solver/python/pywrapcp_util.h index 78454a0e8b..783020bcfb 100644 --- a/ortools/constraint_solver/python/pywrapcp_util.h +++ b/ortools/constraint_solver/python/pywrapcp_util.h @@ -92,4 +92,5 @@ class CallPyDecisionBuilder : public operations_research::DecisionBuilder { PyObject* str_func_; }; + #endif // OR_TOOLS_CONSTRAINT_SOLVER_PYTHON_PYWRAPCP_UTIL_H_ diff --git a/ortools/constraint_solver/routing.cc b/ortools/constraint_solver/routing.cc index d1d9aeda1a..89320149aa 100644 --- a/ortools/constraint_solver/routing.cc +++ b/ortools/constraint_solver/routing.cc @@ -2114,6 +2114,52 @@ class RoutingModelInspector : public ModelVisitor { std::vector ends_argument_; }; +void RoutingModel::DetectImplicitPickupAndDeliveries() { + std::vector non_pickup_delivery_nodes; + for (int node = 0; node < Size(); ++node) { + if (!IsStart(node) && GetPickupIndexPairs(node).empty() && + GetDeliveryIndexPairs(node).empty()) { + non_pickup_delivery_nodes.push_back(node); + } + } + // Needs to be sorted for stability. + std::set> implicit_pickup_deliveries; + for (const RoutingDimension* const dimension : dimensions_) { + if (dimension->class_evaluators_.size() != 1) { + continue; + } + const TransitCallback1& transit = + UnaryTransitCallbackOrNull(dimension->class_evaluators_[0]); + if (transit == nullptr) continue; + absl::flat_hash_map> nodes_by_positive_demand; + absl::flat_hash_map> nodes_by_negative_demand; + for (int node : non_pickup_delivery_nodes) { + const int64 demand = transit(node); + if (demand > 0) { + nodes_by_positive_demand[demand].push_back(node); + } else if (demand < 0) { + nodes_by_negative_demand[-demand].push_back(node); + } + } + for (const auto& [demand, positive_nodes] : nodes_by_positive_demand) { + const std::vector* const negative_nodes = + gtl::FindOrNull(nodes_by_negative_demand, demand); + if (negative_nodes != nullptr) { + for (int64 positive_node : positive_nodes) { + for (int64 negative_node : *negative_nodes) { + implicit_pickup_deliveries.insert({positive_node, negative_node}); + } + } + } + } + } + implicit_pickup_delivery_pairs_without_alternatives_.clear(); + for (auto [pickup, delivery] : implicit_pickup_deliveries) { + implicit_pickup_delivery_pairs_without_alternatives_.emplace_back( + std::vector({pickup}), std::vector({delivery})); + } +} + void RoutingModel::CloseModelWithParameters( const RoutingSearchParameters& parameters) { std::string error = FindErrorInRoutingSearchParameters(parameters); @@ -2494,6 +2540,8 @@ void RoutingModel::CloseModelWithParameters( } } + DetectImplicitPickupAndDeliveries(); + // Store the local/global cumul optimizers, along with their offsets. StoreDimensionCumulOptimizers(parameters); @@ -4461,6 +4509,15 @@ LocalSearchOperator* RoutingModel::CreateInsertionOperator() { vehicle_start_class_callback_, pickup_delivery_pairs_), insertion_operator}); } + if (!implicit_pickup_delivery_pairs_without_alternatives_.empty()) { + insertion_operator = solver_->ConcatenateOperators( + {MakePairActive( + solver_.get(), nexts_, + CostsAreHomogeneousAcrossVehicles() ? empty : vehicle_vars_, + vehicle_start_class_callback_, + implicit_pickup_delivery_pairs_without_alternatives_), + insertion_operator}); + } return insertion_operator; } diff --git a/ortools/constraint_solver/routing.h b/ortools/constraint_solver/routing.h index a63ab50a34..0d606f767c 100644 --- a/ortools/constraint_solver/routing.h +++ b/ortools/constraint_solver/routing.h @@ -737,6 +737,14 @@ class RoutingModel { GetPickupAndDeliveryDisjunctions() const { return pickup_delivery_disjunctions_; } + /// Returns implicit pickup and delivery pairs currently in the model. + /// Pairs are implicit if they are not linked by a pickup and delivery + /// constraint but that for a given unary dimension, the first element of the + /// pair has a positive demand d, and the second element has a demand of -d. + const IndexPairs& GetImplicitUniquePickupAndDeliveryPairs() const { + DCHECK(closed_); + return implicit_pickup_delivery_pairs_without_alternatives_; + } #endif // SWIG /// Set the node visit types and incompatibilities/requirements between the /// types (see below). @@ -1654,6 +1662,12 @@ class RoutingModel { const RoutingSearchParameters& search_parameters) const; GetTabuVarsCallback tabu_var_callback_; + // Detects implicit pickup delivery pairs. These pairs are + // non-pickup/delivery pairs for which there exists a unary dimension such + // that the demand d of the implicit pickup is positive and the demand of the + // implicit delivery is equal to -d. + void DetectImplicitPickupAndDeliveries(); + int GetVehicleStartClass(int64 start) const; void InitSameVehicleGroups(int number_of_groups) { @@ -1744,6 +1758,7 @@ class RoutingModel { #endif // SWIG /// Pickup and delivery IndexPairs pickup_delivery_pairs_; + IndexPairs implicit_pickup_delivery_pairs_without_alternatives_; std::vector > pickup_delivery_disjunctions_; // clang-format off @@ -3040,6 +3055,11 @@ class RoutingFilteredHeuristic : public IntVarFilteredHeuristic { void MakeDisjunctionNodesUnperformed(int64 node); /// Make all unassigned nodes unperformed. void MakeUnassignedNodesUnperformed(); + /// Make all partially performed pickup and delivery pairs unperformed. A + /// pair is partially unperformed if one element of the pair has one of its + /// alternatives performed in the solution and the other has no alternatives + /// in the solution or none performed. + void MakePartiallyPerformedPairsUnperformed(); protected: bool StopSearch() override { return model_->CheckLimit(); } diff --git a/ortools/constraint_solver/routing_lp_scheduling.h b/ortools/constraint_solver/routing_lp_scheduling.h index ffd6ea93fa..27c21ab4fb 100644 --- a/ortools/constraint_solver/routing_lp_scheduling.h +++ b/ortools/constraint_solver/routing_lp_scheduling.h @@ -341,6 +341,7 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { parameters_.set_max_presolve_iterations(0); parameters_.set_catch_sigint_signal(false); parameters_.set_mip_max_bound(1e8); + parameters_.set_search_branching(sat::SatParameters::LP_SEARCH); } ~RoutingCPSatWrapper() override {} void Clear() override { diff --git a/ortools/constraint_solver/routing_search.cc b/ortools/constraint_solver/routing_search.cc index b015a76465..31314ff351 100644 --- a/ortools/constraint_solver/routing_search.cc +++ b/ortools/constraint_solver/routing_search.cc @@ -3028,6 +3028,45 @@ void RoutingFilteredHeuristic::MakeUnassignedNodesUnperformed() { } } +void RoutingFilteredHeuristic::MakePartiallyPerformedPairsUnperformed() { + std::vector to_make_unperformed(Size(), false); + for (const auto& [pickups, deliveries] : + model()->GetPickupAndDeliveryPairs()) { + int64 performed_pickup = -1; + for (int64 pickup : pickups) { + if (Contains(pickup) && Value(pickup) != pickup) { + performed_pickup = pickup; + break; + } + } + int64 performed_delivery = -1; + for (int64 delivery : deliveries) { + if (Contains(delivery) && Value(delivery) != delivery) { + performed_delivery = delivery; + break; + } + } + if ((performed_pickup == -1) != (performed_delivery == -1)) { + if (performed_pickup != -1) { + to_make_unperformed[performed_pickup] = true; + } + if (performed_delivery != -1) { + to_make_unperformed[performed_delivery] = true; + } + } + } + for (int index = 0; index < Size(); ++index) { + if (to_make_unperformed[index] || !Contains(index)) continue; + int64 next = Value(index); + while (next < Size() && to_make_unperformed[next]) { + const int64 next_of_next = Value(next); + SetValue(index, next_of_next); + SetValue(next, next); + next = next_of_next; + } + } +} + // CheapestInsertionFilteredHeuristic CheapestInsertionFilteredHeuristic::CheapestInsertionFilteredHeuristic( @@ -5060,6 +5099,8 @@ bool SavingsFilteredHeuristic::BuildSolutionInternal() { // Free all the space used to store the Savings in the container. savings_container_.reset(); MakeUnassignedNodesUnperformed(); + if (!Commit()) return false; + MakePartiallyPerformedPairsUnperformed(); return Commit(); } diff --git a/ortools/data/set_covering_data.h b/ortools/data/set_covering_data.h index a98950b97d..9d0566d10f 100644 --- a/ortools/data/set_covering_data.h +++ b/ortools/data/set_covering_data.h @@ -28,11 +28,11 @@ class ScpData { int num_rows() const { return columns_per_row_.size(); } int num_columns() const { return rows_per_column_.size(); } // columns_per_row[i][j] returns the index of the jth column covering row i. - const std::vector >& columns_per_row() const { + const std::vector>& columns_per_row() const { return columns_per_row_; } // rows_per_column[i][j] returns the index of the jth row covering column i. - const std::vector >& rows_per_column() const { + const std::vector>& rows_per_column() const { return rows_per_column_; } const std::vector& column_costs() const { return column_costs_; } @@ -47,8 +47,8 @@ class ScpData { void AddRowInColumn(int row, int column); private: - std::vector > columns_per_row_; - std::vector > rows_per_column_; + std::vector> columns_per_row_; + std::vector> rows_per_column_; std::vector column_costs_; bool is_set_partitioning_; }; diff --git a/ortools/dotnet/Google.OrTools.sln b/ortools/dotnet/Google.OrTools.sln index bb55223852..98ffe9c3f7 100644 --- a/ortools/dotnet/Google.OrTools.sln +++ b/ortools/dotnet/Google.OrTools.sln @@ -11,29 +11,29 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.OrTools.FSharp", " Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.OrTools.FSharp.Tests", "Google.OrTools.FSharp.Tests\Google.OrTools.FSharp.Tests.fsproj", "{FC646C34-8541-427D-B9F6-1247798F4574}" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x64.ActiveCfg = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x64.Build.0 = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x86.ActiveCfg = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x86.Build.0 = Debug|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|Any CPU.Build.0 = Release|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|x64.ActiveCfg = Release|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|x64.Build.0 = Release|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|x86.ActiveCfg = Release|Any CPU - {FC646C34-8541-427D-B9F6-1247798F4574}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection +GlobalSection(SolutionConfigurationPlatforms) = preSolution +Debug|Any CPU = Debug|Any CPU +Debug|x64 = Debug|x64 +Debug|x86 = Debug|x86 +Release|Any CPU = Release|Any CPU +Release|x64 = Release|x64 +Release|x86 = Release|x86 +EndGlobalSection +GlobalSection(SolutionProperties) = preSolution +HideSolutionNode = FALSE +EndGlobalSection +GlobalSection(ProjectConfigurationPlatforms) = postSolution +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|Any CPU.Build.0 = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x64.ActiveCfg = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x64.Build.0 = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x86.ActiveCfg = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Debug|x86.Build.0 = Debug|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|Any CPU.ActiveCfg = Release|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|Any CPU.Build.0 = Release|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|x64.ActiveCfg = Release|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|x64.Build.0 = Release|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|x86.ActiveCfg = Release|Any CPU +{FC646C34-8541-427D-B9F6-1247798F4574}.Release|x86.Build.0 = Release|Any CPU +EndGlobalSection EndGlobal diff --git a/ortools/flatzinc/model.h b/ortools/flatzinc/model.h index c04f5b2787..2f0c2d3381 100644 --- a/ortools/flatzinc/model.h +++ b/ortools/flatzinc/model.h @@ -398,8 +398,8 @@ class ModelStatistics { private: const Model& model_; - std::map > constraints_per_type_; - absl::flat_hash_map > + std::map> constraints_per_type_; + absl::flat_hash_map> constraints_per_variables_; }; diff --git a/ortools/flatzinc/parser_util.h b/ortools/flatzinc/parser_util.h index 4f3c64ca95..baf29e23fa 100644 --- a/ortools/flatzinc/parser_util.h +++ b/ortools/flatzinc/parser_util.h @@ -28,14 +28,14 @@ namespace fz { // This is the context used during parsing. struct ParserContext { absl::flat_hash_map integer_map; - absl::flat_hash_map > integer_array_map; + absl::flat_hash_map> integer_array_map; absl::flat_hash_map float_map; - absl::flat_hash_map > float_array_map; + absl::flat_hash_map> float_array_map; absl::flat_hash_map variable_map; - absl::flat_hash_map > + absl::flat_hash_map> variable_array_map; absl::flat_hash_map domain_map; - absl::flat_hash_map > domain_array_map; + absl::flat_hash_map> domain_array_map; }; // An optional reference to a variable, or an integer value, used in diff --git a/ortools/glop/markowitz.h b/ortools/glop/markowitz.h index bd9d66e000..94d22ff139 100644 --- a/ortools/glop/markowitz.h +++ b/ortools/glop/markowitz.h @@ -186,7 +186,7 @@ class MatrixNonZeroPattern { // // TODO(user): We could be even more efficient since a size of int32 is enough // for us and we could store in common the inlined/not-inlined size. - gtl::ITIVector > row_non_zero_; + gtl::ITIVector> row_non_zero_; StrictITIVector row_degree_; StrictITIVector col_degree_; DenseBooleanRow deleted_columns_; @@ -223,7 +223,7 @@ class ColumnPriorityQueue { private: StrictITIVector col_index_; StrictITIVector col_degree_; - std::vector > col_by_degree_; + std::vector> col_by_degree_; int32 min_degree_; DISALLOW_COPY_AND_ASSIGN(ColumnPriorityQueue); }; diff --git a/ortools/glop/preprocessor.h b/ortools/glop/preprocessor.h index df17415759..aac06d7071 100644 --- a/ortools/glop/preprocessor.h +++ b/ortools/glop/preprocessor.h @@ -122,7 +122,7 @@ class MainLpPreprocessor : public Preprocessor { // TODO(user): This is mutable so that the preprocessor can be freed as soon // as their RecoverSolution() is called. Make RecoverSolution() non-const or // remove this optimization? - mutable std::vector > preprocessors_; + mutable std::vector> preprocessors_; // Initial dimension of the lp given to Run(), for displaying purpose. EntryIndex initial_num_entries_; diff --git a/ortools/graph/one_tree_lower_bound.h b/ortools/graph/one_tree_lower_bound.h index 4d1fd4b941..921c4eb3eb 100644 --- a/ortools/graph/one_tree_lower_bound.h +++ b/ortools/graph/one_tree_lower_bound.h @@ -259,13 +259,13 @@ class HeldWolfeCrowderEvaluator { // nearest neighbors as well as all the nodes for which i is a nearest // neighbor. template -std::set > NearestNeighbors(int number_of_nodes, - int number_of_neighbors, - const CostFunction& cost) { +std::set> NearestNeighbors(int number_of_nodes, + int number_of_neighbors, + const CostFunction& cost) { using CostType = decltype(cost(0, 0)); - std::set > nearest; + std::set> nearest; for (int i = 0; i < number_of_nodes; ++i) { - std::vector > neighbors; + std::vector> neighbors; neighbors.reserve(number_of_nodes - 1); for (int j = 0; j < number_of_nodes; ++j) { if (i != j) { @@ -292,7 +292,7 @@ std::set > NearestNeighbors(int number_of_nodes, template void AddArcsFromMinimumSpanningTree(int number_of_nodes, const CostFunction& cost, - std::set >* arcs) { + std::set>* arcs) { util::CompleteGraph graph(number_of_nodes); const std::vector mst = BuildPrimMinimumSpanningTree(graph, [&cost, &graph](int arc) { diff --git a/ortools/gscip/gscip.h b/ortools/gscip/gscip.h index f8eacbaf4c..850ff2ef22 100644 --- a/ortools/gscip/gscip.h +++ b/ortools/gscip/gscip.h @@ -121,7 +121,7 @@ class GScip { public: // Create a new GScip (the constructor is private). The default objective // direction is minimization. - static absl::StatusOr > Create( + static absl::StatusOr> Create( const std::string& problem_name); ~GScip(); static std::string ScipVersion(); diff --git a/ortools/java/com/google/ortools/sat/CpModel.java b/ortools/java/com/google/ortools/sat/CpModel.java index c2f7ea9be6..cfea396749 100644 --- a/ortools/java/com/google/ortools/sat/CpModel.java +++ b/ortools/java/com/google/ortools/sat/CpModel.java @@ -592,8 +592,7 @@ public final class CpModel { for (IntVar var : actives) { reservoir.addActives(var.getIndex()); } - reservoir.setMinLevel(minLevel); - reservoir.setMaxLevel(maxLevel); + reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel); return ct; } diff --git a/ortools/linear_solver/model_validator.h b/ortools/linear_solver/model_validator.h index 89cabe3cc3..330ee32505 100644 --- a/ortools/linear_solver/model_validator.h +++ b/ortools/linear_solver/model_validator.h @@ -45,7 +45,7 @@ std::string FindErrorInMPModelDeltaProto(const MPModelDeltaProto& delta, * If the model is valid and non-empty, returns it (possibly after extracting * the model_delta). If invalid or empty, updates `response` and returns null. */ -absl::optional > +absl::optional> ExtractValidMPModelOrPopulateResponseStatus(const MPModelRequest& request, MPSolutionResponse* response); diff --git a/ortools/linear_solver/sat_solver_utils.h b/ortools/linear_solver/sat_solver_utils.h index 8cb7dbf3a0..f5bf95db8a 100644 --- a/ortools/linear_solver/sat_solver_utils.h +++ b/ortools/linear_solver/sat_solver_utils.h @@ -30,7 +30,7 @@ namespace operations_research { // might be INFEASIBLE if there is some trivial infeasiblity in the model. MPSolverResponseStatus ApplyMipPresolveSteps( bool log_info, const glop::GlopParameters& glop_params, MPModelProto* model, - std::vector >* for_postsolve); + std::vector>* for_postsolve); } // namespace operations_research #endif // OR_TOOLS_LINEAR_SOLVER_SAT_SOLVER_UTILS_H_ diff --git a/ortools/linear_solver/scip_callback.h b/ortools/linear_solver/scip_callback.h index 91a49a0bd5..e4e3f529ab 100644 --- a/ortools/linear_solver/scip_callback.h +++ b/ortools/linear_solver/scip_callback.h @@ -256,7 +256,7 @@ void RegisterConstraintHandler(ScipConstraintHandler* handler, SCIP* scip) { internal::AddConstraintHandlerImpl( handler->description(), - absl::make_unique >( + absl::make_unique>( handler), scip); } diff --git a/ortools/lp_data/lp_decomposer.h b/ortools/lp_data/lp_decomposer.h index ed1327b327..26730cca24 100644 --- a/ortools/lp_data/lp_decomposer.h +++ b/ortools/lp_data/lp_decomposer.h @@ -81,7 +81,7 @@ class LPDecomposer { private: const LinearProgram* original_problem_; - std::vector > clusters_; + std::vector> clusters_; mutable absl::Mutex mutex_; diff --git a/ortools/lp_data/scattered_vector.h b/ortools/lp_data/scattered_vector.h index d02781365b..8b928cfa7c 100644 --- a/ortools/lp_data/scattered_vector.h +++ b/ortools/lp_data/scattered_vector.h @@ -53,7 +53,7 @@ class ScatteredVectorEntry { // A simple struct that contains a DenseVector and its non-zero indices. // TODO(user): This should be changed from struct to class. template > > + typename Iterator = VectorIterator>> struct ScatteredVector { StrictITIVector values; diff --git a/ortools/lp_data/sparse.h b/ortools/lp_data/sparse.h index 9f054e1979..3d54e43444 100644 --- a/ortools/lp_data/sparse.h +++ b/ortools/lp_data/sparse.h @@ -62,14 +62,14 @@ class SparseMatrix { public: SparseMatrix(); -// Useful for testing. This makes it possible to write: -// SparseMatrix matrix { -// {1, 2, 3}, -// {4, 5, 6}, -// {7, 8, 9}}; + // Useful for testing. This makes it possible to write: + // SparseMatrix matrix { + // {1, 2, 3}, + // {4, 5, 6}, + // {7, 8, 9}}; #if (!defined(_MSC_VER) || _MSC_VER >= 1800) SparseMatrix( - std::initializer_list > init_list); + std::initializer_list> init_list); #endif // Clears internal data structure, i.e. erases all the columns and set // the number of rows to zero. diff --git a/ortools/python/README.md b/ortools/python/README.md index 4ff19537bc..5959464697 100644 --- a/ortools/python/README.md +++ b/ortools/python/README.md @@ -1,5 +1,5 @@ # Introduction -This is the documentation page for the Python 3.5+ wrapper of OR-Tools. +This is the documentation page for the Python 3.6+ wrapper of OR-Tools. This project aim to explain how you build a Python native wheel package using [`setup.py`](https://packaging.python.org/tutorials/packaging-projects/). diff --git a/ortools/sat/all_different.h b/ortools/sat/all_different.h index b969812092..66286addd4 100644 --- a/ortools/sat/all_different.h +++ b/ortools/sat/all_different.h @@ -93,13 +93,13 @@ class AllDifferentConstraint : PropagatorInterface { int64 num_all_values_; std::vector variable_min_value_; std::vector variable_max_value_; - std::vector > variable_literal_index_; + std::vector> variable_literal_index_; // Internal state of MakeAugmentingPath(). // value_to_variable_ and variable_to_value_ represent the current assignment; // -1 means not assigned. Otherwise, // variable_to_value_[var] = value <=> value_to_variable_[value] = var. - std::vector > successor_; + std::vector> successor_; std::vector value_visited_; std::vector variable_visited_; std::vector value_to_variable_; @@ -124,7 +124,7 @@ class AllDifferentConstraint : PropagatorInterface { // part in the alternating cycle, and filter with only the SCC decomposition. // When num_variables_ == num_all_values_, the dummy node is useless, // we add it anyway to simplify the code. - std::vector > residual_graph_successors_; + std::vector> residual_graph_successors_; std::vector component_number_; Trail* trail_; diff --git a/ortools/sat/boolean_problem.h b/ortools/sat/boolean_problem.h index 2835638c32..ebac8e78de 100644 --- a/ortools/sat/boolean_problem.h +++ b/ortools/sat/boolean_problem.h @@ -119,7 +119,7 @@ void MakeAllLiteralsPositive(LinearBooleanProblem* problem); // representation of the) problem literals. void FindLinearBooleanProblemSymmetries( const LinearBooleanProblem& problem, - std::vector >* generators); + std::vector>* generators); // Maps all the literals of the problem. Note that this converts the cost of a // variable correctly, that is if a variable with cost is mapped to another, the diff --git a/ortools/sat/circuit.h b/ortools/sat/circuit.h index 736ef3aba4..5db1755d1a 100644 --- a/ortools/sat/circuit.h +++ b/ortools/sat/circuit.h @@ -90,7 +90,7 @@ class CircuitPropagator : PropagatorInterface, ReversibleInterface { int head; }; std::vector watch_index_to_literal_; - std::vector > watch_index_to_arcs_; + std::vector> watch_index_to_arcs_; // Index in trail_ up to which we propagated all the assigned Literals. int propagation_trail_index_ = 0; @@ -130,7 +130,7 @@ class CircuitPropagator : PropagatorInterface, ReversibleInterface { // so this can be used for facility location problems. class CircuitCoveringPropagator : PropagatorInterface, ReversibleInterface { public: - CircuitCoveringPropagator(std::vector > graph, + CircuitCoveringPropagator(std::vector> graph, const std::vector& distinguished_nodes, Model* model); @@ -146,14 +146,14 @@ class CircuitCoveringPropagator : PropagatorInterface, ReversibleInterface { void FillFixedPathInReason(int start, int end, std::vector* reason); // Input data. - const std::vector > graph_; + const std::vector> graph_; const int num_nodes_; std::vector node_is_distinguished_; // SAT incremental state. Trail* trail_; - std::vector > watch_index_to_arc_; - std::vector > fixed_arcs_; + std::vector> watch_index_to_arc_; + std::vector> fixed_arcs_; std::vector level_ends_; // Used in Propagate() to represent paths and circuits. @@ -181,9 +181,9 @@ std::function SubcircuitConstraint( // TODO(user): Change to a sparse API like for the function above. std::function ExactlyOnePerRowAndPerColumn( - const std::vector >& graph); + const std::vector>& graph); std::function CircuitCovering( - const std::vector >& graph, + const std::vector>& graph, const std::vector& distinguished_nodes); } // namespace sat diff --git a/ortools/sat/cp_model_lns.h b/ortools/sat/cp_model_lns.h index 489f2f3f10..a1102705e6 100644 --- a/ortools/sat/cp_model_lns.h +++ b/ortools/sat/cp_model_lns.h @@ -107,10 +107,10 @@ class NeighborhoodGeneratorHelper : public SubSolver { // Constraints <-> Variables graph. // Note that only non-constant variable are listed here. - const std::vector >& ConstraintToVar() const { + const std::vector>& ConstraintToVar() const { return constraint_to_var_; } - const std::vector >& VarToConstraint() const { + const std::vector>& VarToConstraint() const { return var_to_constraint_; } @@ -164,11 +164,11 @@ class NeighborhoodGeneratorHelper : public SubSolver { mutable absl::Mutex mutex_; // Constraints by types. - std::vector > type_to_constraints_; + std::vector> type_to_constraints_; // Variable-Constraint graph. - std::vector > constraint_to_var_; - std::vector > var_to_constraint_; + std::vector> constraint_to_var_; + std::vector> var_to_constraint_; // The set of active variables, that is the list of non constant variables if // parameters_.focus_on_decision_variables() is false, or the list of non @@ -501,7 +501,7 @@ class WeightedRandomRelaxationNeighborhoodGenerator int num_removable_constraints_ = 0; // Indices of the removed constraints per generated neighborhood. - absl::flat_hash_map > removed_constraints_ + absl::flat_hash_map> removed_constraints_ ABSL_GUARDED_BY(mutex_); // TODO(user): Move this to parent class if other generators start using diff --git a/ortools/sat/cp_model_loader.h b/ortools/sat/cp_model_loader.h index c8d66473c3..90bc26c7af 100644 --- a/ortools/sat/cp_model_loader.h +++ b/ortools/sat/cp_model_loader.h @@ -223,7 +223,7 @@ class CpModelMapping { absl::flat_hash_set already_loaded_ct_; absl::flat_hash_set is_half_encoding_ct_; - absl::flat_hash_map > + absl::flat_hash_map> variables_to_encoded_values_; const absl::flat_hash_set empty_set_; }; diff --git a/ortools/sat/cp_model_symmetries.h b/ortools/sat/cp_model_symmetries.h index ae0e580eb7..17f7e8cbef 100644 --- a/ortools/sat/cp_model_symmetries.h +++ b/ortools/sat/cp_model_symmetries.h @@ -30,7 +30,7 @@ namespace sat { // representation of the) problem variables. void FindCpModelSymmetries( const CpModelProto& problem, - std::vector >* generators, + std::vector>* generators, double time_limit_seconds = std::numeric_limits::infinity()); } // namespace sat diff --git a/ortools/sat/cuts.h b/ortools/sat/cuts.h index aeb8069711..6395417fd1 100644 --- a/ortools/sat/cuts.h +++ b/ortools/sat/cuts.h @@ -75,7 +75,7 @@ class ImpliedBoundsProcessor { // generation and substitute it back later. struct SlackInfo { // This slack is equal to sum of terms + offset. - std::vector > terms; + std::vector> terms; IntegerValue offset; // The slack bounds and current lp_value. @@ -137,7 +137,7 @@ class ImpliedBoundsProcessor { ImpliedBounds* implied_bounds_; // Temporary memory used by ProcessUpperBoundedConstraint(). - mutable std::vector > tmp_terms_; + mutable std::vector> tmp_terms_; }; // Visible for testing. Returns a function f on integers such that: @@ -225,14 +225,14 @@ class IntegerRoundingCutHelper { std::vector relevant_coeffs_; std::vector relevant_bound_diffs_; std::vector divisors_; - std::vector > adjusted_coeffs_; + std::vector> adjusted_coeffs_; std::vector remainders_; std::vector change_sign_at_postprocessing_; std::vector rs_; std::vector best_rs_; int num_lifted_booleans_ = 0; - std::vector > tmp_terms_; + std::vector> tmp_terms_; }; // Helper to find knapsack or flow cover cuts (not yet implemented). diff --git a/ortools/sat/diffn.h b/ortools/sat/diffn.h index 06d1b4a1e0..992a4697dc 100644 --- a/ortools/sat/diffn.h +++ b/ortools/sat/diffn.h @@ -52,8 +52,8 @@ class NonOverlappingRectanglesEnergyPropagator : public PropagatorInterface { SchedulingConstraintHelper& x_; SchedulingConstraintHelper& y_; - std::vector > x_split_; - std::vector > y_split_; + std::vector> x_split_; + std::vector> y_split_; std::vector active_boxes_; std::vector cached_areas_; @@ -122,11 +122,11 @@ class NonOverlappingRectanglesDisjunctivePropagator std::vector active_boxes_; std::vector events_time_; - std::vector > events_overlapping_boxes_; + std::vector> events_overlapping_boxes_; - absl::flat_hash_set > reduced_overlapping_boxes_; - std::vector > boxes_to_propagate_; - std::vector > disjoint_boxes_; + absl::flat_hash_set> reduced_overlapping_boxes_; + std::vector> boxes_to_propagate_; + std::vector> disjoint_boxes_; DisjunctiveOverloadChecker overload_checker_; DisjunctiveDetectablePrecedences forward_detectable_precedences_; diff --git a/ortools/sat/disjunctive.h b/ortools/sat/disjunctive.h index d91a7f558f..4de5080e0f 100644 --- a/ortools/sat/disjunctive.h +++ b/ortools/sat/disjunctive.h @@ -204,7 +204,7 @@ class CombinedDisjunctive : public PropagatorInterface { private: AllIntervalsHelper* helper_; - std::vector > task_to_disjunctives_; + std::vector> task_to_disjunctives_; std::vector task_is_added_; std::vector task_sets_; std::vector end_mins_; diff --git a/ortools/sat/doc/README.md b/ortools/sat/doc/README.md index 88e8ff75b9..570b3b3a9a 100644 --- a/ortools/sat/doc/README.md +++ b/ortools/sat/doc/README.md @@ -162,7 +162,7 @@ public class SimpleSatProgram { CpSolver solver = new CpSolver(); CpSolverStatus status = solver.solve(model); - if (status == CpSolverStatus.FEASIBLE) { + if (status == CpSolverStatus.OPTIMAL) { System.out.println("x = " + solver.value(x)); System.out.println("y = " + solver.value(y)); System.out.println("z = " + solver.value(z)); diff --git a/ortools/sat/doc/integer_arithmetic.md b/ortools/sat/doc/integer_arithmetic.md index d17ab10f60..3af9da5bae 100644 --- a/ortools/sat/doc/integer_arithmetic.md +++ b/ortools/sat/doc/integer_arithmetic.md @@ -250,7 +250,7 @@ public class RabbitsAndPheasantsSat { CpSolver solver = new CpSolver(); CpSolverStatus status = solver.solve(model); - if (status == CpSolverStatus.FEASIBLE) { + if (status == CpSolverStatus.OPTIMAL) { System.out.println(solver.value(r) + " rabbits, and " + solver.value(p) + " pheasants"); } } diff --git a/ortools/sat/doc/solver.md b/ortools/sat/doc/solver.md index 0f32cad618..1e838e89aa 100644 --- a/ortools/sat/doc/solver.md +++ b/ortools/sat/doc/solver.md @@ -158,7 +158,7 @@ public class SolveWithTimeLimitSampleSat { solver.getParameters().setMaxTimeInSeconds(10.0); CpSolverStatus status = solver.solve(model); - if (status == CpSolverStatus.FEASIBLE) { + if (status == CpSolverStatus.OPTIMAL) { System.out.println("x = " + solver.value(x)); System.out.println("y = " + solver.value(y)); System.out.println("z = " + solver.value(z)); diff --git a/ortools/sat/drat_checker.h b/ortools/sat/drat_checker.h index 80895498e9..b266dffa6f 100644 --- a/ortools/sat/drat_checker.h +++ b/ortools/sat/drat_checker.h @@ -83,11 +83,11 @@ class DratChecker { // Returns a subproblem of the original problem that is already UNSAT. The // result is undefined if Check() was not previously called, or did not return // true. - std::vector > GetUnsatSubProblem() const; + std::vector> GetUnsatSubProblem() const; // Returns a DRAT proof that GetUnsatSubProblem() is UNSAT. The result is // undefined if Check() was not previously called, or did not return true. - std::vector > GetOptimizedProof() const; + std::vector> GetOptimizedProof() const; private: // A problem or infered clause. The literals are specified as a subrange of @@ -213,7 +213,7 @@ class DratChecker { // Returns the clauses whose index is in [begin,end) which are needed for the // proof. The result is undefined if Check() was not previously called, or did // not return true. - std::vector > GetClausesNeededForProof( + std::vector> GetClausesNeededForProof( ClauseIndex begin, ClauseIndex end) const; void LogStatistics(int64 duration_nanos) const; @@ -273,7 +273,7 @@ class DratChecker { // satisfied (in more details: if a clause c is contained in // 'watched_literals_[l]' for literal l, then either c is satisfied with // 'assignment_', or l is unassigned or assigned to true). - gtl::ITIVector > watched_literals_; + gtl::ITIVector> watched_literals_; // The list of clauses with only one literal. This is needed for boolean // constraint propagation, in addition to watched literals, because watched @@ -331,7 +331,7 @@ enum SatFormat { // Prints the given clauses in the file at the given path, using the given file // format. Returns true iff the file was successfully written. bool PrintClauses(const std::string& file_path, SatFormat format, - const std::vector >& clauses, + const std::vector>& clauses, int num_variables); } // namespace sat diff --git a/ortools/sat/implied_bounds.h b/ortools/sat/implied_bounds.h index 9054a14119..58b554f7c5 100644 --- a/ortools/sat/implied_bounds.h +++ b/ortools/sat/implied_bounds.h @@ -145,7 +145,7 @@ class ImpliedBounds { // // TODO(user): Use inlined vectors. std::vector empty_implied_bounds_; - gtl::ITIVector > + gtl::ITIVector> var_to_bounds_; // Track the list of variables with some implied bounds. diff --git a/ortools/sat/linear_constraint.h b/ortools/sat/linear_constraint.h index c128569d2b..b8d365701b 100644 --- a/ortools/sat/linear_constraint.h +++ b/ortools/sat/linear_constraint.h @@ -120,7 +120,7 @@ class LinearConstraintBuilder { // Initially we push all AddTerm() here, and during Build() we merge terms // on the same variable. - std::vector > terms_; + std::vector> terms_; }; // Returns the activity of the given constraint. That is the current value of @@ -155,7 +155,7 @@ void MakeAllVariablesPositive(LinearConstraint* constraint); // Sorts and merges duplicate IntegerVariable in the given "terms". // Fills the given LinearConstraint with the result. void CleanTermsAndFillConstraint( - std::vector >* terms, + std::vector>* terms, LinearConstraint* constraint); // Sorts the terms and makes all IntegerVariable positive. This assumes that a diff --git a/ortools/sat/linear_relaxation.h b/ortools/sat/linear_relaxation.h index 6cfe8379db..b417fd4a16 100644 --- a/ortools/sat/linear_relaxation.h +++ b/ortools/sat/linear_relaxation.h @@ -27,7 +27,7 @@ namespace sat { struct LinearRelaxation { std::vector linear_constraints; - std::vector > at_most_ones; + std::vector> at_most_ones; std::vector cut_generators; }; diff --git a/ortools/sat/model.h b/ortools/sat/model.h index ce613e2c2f..c6914f2293 100644 --- a/ortools/sat/model.h +++ b/ortools/sat/model.h @@ -212,7 +212,7 @@ class Model { // TODO(user): I don't think we need the two layers of unique_ptr, but we // don't care too much about efficiency here and this was easier to get // working. - std::vector > cleanup_list_; + std::vector> cleanup_list_; DISALLOW_COPY_AND_ASSIGN(Model); }; diff --git a/ortools/sat/pb_constraint.h b/ortools/sat/pb_constraint.h index 328aefc8d4..cc5c2ef278 100644 --- a/ortools/sat/pb_constraint.h +++ b/ortools/sat/pb_constraint.h @@ -163,7 +163,7 @@ class CanonicalBooleanLinearProblem { Coefficient max_value, Coefficient rhs); std::vector rhs_; - std::vector > constraints_; + std::vector> constraints_; DISALLOW_COPY_AND_ASSIGN(CanonicalBooleanLinearProblem); }; @@ -636,14 +636,14 @@ class PbConstraints : public SatPropagator { }; // The set of all pseudo-boolean constraint managed by this class. - std::vector > constraints_; + std::vector> constraints_; // The current value of the threshold for each constraints. gtl::ITIVector thresholds_; // For each literal, the list of all the constraints that contains it together // with the literal coefficient in these constraints. - gtl::ITIVector > + gtl::ITIVector> to_update_; // Bitset used to optimize the Untrail() function. @@ -651,7 +651,7 @@ class PbConstraints : public SatPropagator { // Pointers to the constraints grouped by their hash. // This is used to find duplicate constraints by AddConstraint(). - absl::flat_hash_map > + absl::flat_hash_map> possible_duplicates_; // Helper to enqueue propagated literals on the trail and store their reasons. diff --git a/ortools/sat/presolve_util.h b/ortools/sat/presolve_util.h index eaa97c377b..7f0d5c4573 100644 --- a/ortools/sat/presolve_util.h +++ b/ortools/sat/presolve_util.h @@ -58,7 +58,7 @@ class DomainDeductions { // TODO(user): We could probably be even more efficient. We could also // compute exactly what clauses need to be "waked up" as new deductions are // added. - std::vector > ProcessClause( + std::vector> ProcessClause( absl::Span clause); // Optimization. Any following ProcessClause() will be fast if no more @@ -79,7 +79,7 @@ class DomainDeductions { std::vector tmp_num_occurrences_; SparseBitset something_changed_; - gtl::ITIVector > enforcement_to_vars_; + gtl::ITIVector> enforcement_to_vars_; absl::flat_hash_map, Domain> deductions_; }; diff --git a/ortools/sat/sat_base.h b/ortools/sat/sat_base.h index 01cd988394..ad0e8d0789 100644 --- a/ortools/sat/sat_base.h +++ b/ortools/sat/sat_base.h @@ -430,8 +430,8 @@ class Trail { // Note that we use a deque for the reason repository so that if we add // variables, the memory address of the vectors (kept in reasons_) are still // valid. - mutable std::deque > reasons_repository_; - mutable gtl::ITIVector > reasons_; + mutable std::deque> reasons_repository_; + mutable gtl::ITIVector> reasons_; mutable gtl::ITIVector old_type_; // This is used by RegisterPropagator() and Reason(). diff --git a/ortools/sat/sat_decision.h b/ortools/sat/sat_decision.h index e5f017861b..9751c15605 100644 --- a/ortools/sat/sat_decision.h +++ b/ortools/sat/sat_decision.h @@ -99,7 +99,7 @@ class SatDecisionPolicy { void SetAssignmentPreference(Literal literal, double weight); // Returns the vector of the current assignment preferences. - std::vector > AllPreferences() const; + std::vector> AllPreferences() const; private: // Computes an initial variable ordering. diff --git a/ortools/sat/sat_inprocessing.h b/ortools/sat/sat_inprocessing.h index 3c63358ebb..6735dae353 100644 --- a/ortools/sat/sat_inprocessing.h +++ b/ortools/sat/sat_inprocessing.h @@ -43,7 +43,7 @@ struct PostsolveClauses { void AddClauseWithSpecialLiteral(Literal literal, absl::Span clause); - std::deque > clauses; + std::deque> clauses; }; class StampingSimplifier; @@ -284,7 +284,7 @@ class BlockedClauseSimplifier { // and we do not shrink it as we remove blocked clauses. DEFINE_INT_TYPE(ClauseIndex, int32); gtl::ITIVector clauses_; - gtl::ITIVector > literal_to_clauses_; + gtl::ITIVector> literal_to_clauses_; }; class BoundedVariableElimination { @@ -366,7 +366,7 @@ class BoundedVariableElimination { // clauses. DEFINE_INT_TYPE(ClauseIndex, int32); gtl::ITIVector clauses_; - gtl::ITIVector > literal_to_clauses_; + gtl::ITIVector> literal_to_clauses_; gtl::ITIVector literal_to_num_clauses_; }; diff --git a/ortools/sat/simplification.h b/ortools/sat/simplification.h index 459161d551..f3e3449948 100644 --- a/ortools/sat/simplification.h +++ b/ortools/sat/simplification.h @@ -325,7 +325,7 @@ class SatPresolver { std::set m_lit_; std::vector m_cls_; gtl::ITIVector literal_to_p_size_; - std::vector > flattened_p_; + std::vector> flattened_p_; std::vector tmp_new_clause_; // List of clauses on which we need to call ProcessClauseToSimplifyOthers(). @@ -335,7 +335,7 @@ class SatPresolver { // The set of all clauses. // An empty clause means that it has been removed. - std::vector > clauses_; // Indexed by ClauseIndex + std::vector> clauses_; // Indexed by ClauseIndex // The cached value of ComputeSignatureOfClauseVariables() for each clause. std::vector signatures_; // Indexed by ClauseIndex @@ -344,7 +344,7 @@ class SatPresolver { // Occurrence list. For each literal, contains the ClauseIndex of the clause // that contains it (ordered by clause index). - gtl::ITIVector > literal_to_clauses_; + gtl::ITIVector> literal_to_clauses_; // Because we only lazily clean the occurrence list after clause deletions, // we keep the size of the occurrence list (without the deleted clause) here. diff --git a/ortools/sat/symmetry.h b/ortools/sat/symmetry.h index 515150ae6d..25ff003a5d 100644 --- a/ortools/sat/symmetry.h +++ b/ortools/sat/symmetry.h @@ -101,7 +101,7 @@ class SymmetryPropagator : public SatPropagator { // The permutations. // The index of a permutation is its position in this vector. - std::vector > permutations_; + std::vector> permutations_; // Reverse mapping (source literal) -> list of (permutation_index, image). struct ImageInfo { @@ -110,7 +110,7 @@ class SymmetryPropagator : public SatPropagator { int permutation_index; Literal image; }; - gtl::ITIVector > images_; + gtl::ITIVector> images_; // For each permutation p, we maintain the list of all assigned literals // affected by p whose trail index is < propagation_trail_index_; sorted by @@ -130,7 +130,7 @@ class SymmetryPropagator : public SatPropagator { // AssignedLiteralInfo's literal was assigned (i.e. earlier in the trail). int first_non_symmetric_info_index_so_far; }; - std::vector > permutation_trails_; + std::vector> permutation_trails_; // Adds an AssignedLiteralInfo to the given permutation trail. // Returns false if there is a non-symmetric literal in this trail with its diff --git a/ortools/sat/synchronization.h b/ortools/sat/synchronization.h index ce2e7cd20c..4ab5f39bd1 100644 --- a/ortools/sat/synchronization.h +++ b/ortools/sat/synchronization.h @@ -157,7 +157,7 @@ class SharedIncompleteSolutionManager { private: // New solutions are added and removed from the back. - std::vector > solutions_; + std::vector> solutions_; mutable absl::Mutex mutex_; }; @@ -321,7 +321,7 @@ class SharedResponseManager { double last_primal_integral_time_stamp_ ABSL_GUARDED_BY(mutex_) = 0.0; int next_callback_id_ ABSL_GUARDED_BY(mutex_) = 0; - std::vector > > + std::vector>> callbacks_ ABSL_GUARDED_BY(mutex_); // Dump prefix. @@ -373,7 +373,7 @@ class SharedBoundsManager { // These are only updated on Synchronize(). std::vector synchronized_lower_bounds_ ABSL_GUARDED_BY(mutex_); std::vector synchronized_upper_bounds_ ABSL_GUARDED_BY(mutex_); - std::deque > id_to_changed_variables_ + std::deque> id_to_changed_variables_ ABSL_GUARDED_BY(mutex_); }; diff --git a/ortools/sat/table.h b/ortools/sat/table.h index 1fcc99cccf..3b8d07c8f5 100644 --- a/ortools/sat/table.h +++ b/ortools/sat/table.h @@ -30,14 +30,14 @@ namespace sat { // tuples. All the tuples must have the same size as var.size(), this is // Checked. void AddTableConstraint(absl::Span vars, - std::vector > tuples, Model* model); + std::vector> tuples, Model* model); // Enforces that none of the given tuple appear. // // TODO(user): we could propagate more than what we currently do which is simply // adding one clause per tuples. void AddNegatedTableConstraint(absl::Span vars, - std::vector > tuples, + std::vector> tuples, Model* model); // Enforces that exactly one literal in line_literals is true, and that @@ -45,7 +45,7 @@ void AddNegatedTableConstraint(absl::Span vars, // This constraint assumes that exactly one literal per column of the // literal_tuples matrix is true. std::function LiteralTableConstraint( - const std::vector >& literal_tuples, + const std::vector>& literal_tuples, const std::vector& line_literals); // Given an automaton defined by a set of 3-tuples: @@ -62,7 +62,7 @@ std::function LiteralTableConstraint( // See the test for some examples. std::function TransitionConstraint( const std::vector& vars, - const std::vector >& automaton, int64 initial_state, + const std::vector>& automaton, int64 initial_state, const std::vector& final_states); } // namespace sat diff --git a/ortools/sat/util.h b/ortools/sat/util.h index 4cccdf9879..b7b1b2bcd8 100644 --- a/ortools/sat/util.h +++ b/ortools/sat/util.h @@ -91,7 +91,7 @@ inline void RandomizeDecisionHeuristic(URBG* random, polarity_d->value(absl::Uniform(*random, 0, polarity_d->value_count())) ->number())); #endif // __PORTABLE_PLATFORM__ - // Other random parameters. + // Other random parameters. parameters->set_use_phase_saving(absl::Bernoulli(*random, 0.5)); parameters->set_random_polarity_ratio(absl::Bernoulli(*random, 0.5) ? 0.01 : 0.0); @@ -179,7 +179,7 @@ class Percentile { // // This method is exposed for testing purposes. void CompressTuples(absl::Span domain_sizes, int64 any_value, - std::vector >* tuples); + std::vector>* tuples); } // namespace sat } // namespace operations_research diff --git a/ortools/sat/zero_half_cuts.h b/ortools/sat/zero_half_cuts.h index 803d3038f6..9c5ce1db13 100644 --- a/ortools/sat/zero_half_cuts.h +++ b/ortools/sat/zero_half_cuts.h @@ -48,9 +48,9 @@ class ZeroHalfCutHelper { const std::vector& upper_bounds); void AddOneConstraint( glop::RowIndex, - const std::vector >& terms, + const std::vector>& terms, IntegerValue lb, IntegerValue ub); - std::vector > > + std::vector>> InterestingCandidates(ModelRandomGenerator* random); // Visible for testing. @@ -63,7 +63,7 @@ class ZeroHalfCutHelper { // coefficient modulo 2, so only the positions of the ones. struct CombinationOfRows { // How this row was formed from the initial problem constraints. - std::vector > multipliers; + std::vector> multipliers; // The index of the odd coefficient of this combination. std::vector cols; @@ -119,7 +119,7 @@ class ZeroHalfCutHelper { // Note that as we combine rows, we never move their indices. So after initial // creation rows_ will always have the same size. std::vector rows_; - std::vector > col_to_rows_; + std::vector> col_to_rows_; std::vector singleton_cols_; // Temporary vector used by SymmetricDifference(). diff --git a/ortools/util/integer_pq.h b/ortools/util/integer_pq.h index 6caff56dc2..6211610927 100644 --- a/ortools/util/integer_pq.h +++ b/ortools/util/integer_pq.h @@ -33,7 +33,7 @@ namespace operations_research { // Classic asjustable priority queue implementation. It behaves exactly the same // as AdjustablePriorityQueue regarding identical elements, but it uses less // memory and is in general slightly faster. -template > +template > class IntegerPriorityQueue { public: // Starts with an empty queue and reserve space for n elements. diff --git a/ortools/util/range_minimum_query.h b/ortools/util/range_minimum_query.h index 9bf8407781..e8acabcd02 100644 --- a/ortools/util/range_minimum_query.h +++ b/ortools/util/range_minimum_query.h @@ -42,7 +42,7 @@ #include "ortools/util/bitset.h" namespace operations_research { -template > +template > class RangeMinimumQuery { public: explicit RangeMinimumQuery(std::vector array); @@ -56,7 +56,7 @@ class RangeMinimumQuery { private: // cache_[k][i] = min(arr, i, i+2^k). - std::vector > cache_; + std::vector> cache_; Compare cmp_; DISALLOW_COPY_AND_ASSIGN(RangeMinimumQuery); @@ -64,7 +64,7 @@ class RangeMinimumQuery { // RangeMinimumIndexQuery is similar to RangeMinimumQuery, but // GetMinimumIndexFromRange returns the index for which the minimum is attained. -template > +template > class RangeMinimumIndexQuery { public: explicit RangeMinimumIndexQuery(std::vector array); diff --git a/ortools/util/rev.h b/ortools/util/rev.h index d6ab57c27d..aec57a3cd4 100644 --- a/ortools/util/rev.h +++ b/ortools/util/rev.h @@ -80,7 +80,7 @@ class RevRepository : public ReversibleInterface { // TODO(user): If we ever see this in any cpu profile, consider using two // vectors for a better memory packing in case sizeof(T) is not sizeof(T*). - std::vector > stack_; + std::vector> stack_; }; // A basic reversible vector implementation. @@ -126,7 +126,7 @@ class RevVector : public ReversibleInterface { private: std::vector end_of_level_; // In stack_. - std::vector > stack_; + std::vector> stack_; gtl::ITIVector vector_; }; @@ -267,7 +267,7 @@ class RevGrowingMultiMap : ReversibleInterface { // TODO(user): use inlined vectors. Another datastructure that may be more // efficient is to use a linked list inside added_keys_ for the values sharing // the same key. - absl::flat_hash_map > map_; + absl::flat_hash_map> map_; // Backtracking data. std::vector added_keys_; diff --git a/ortools/util/sort.h b/ortools/util/sort.h index 594ceab445..08ee70fd8b 100644 --- a/ortools/util/sort.h +++ b/ortools/util/sort.h @@ -42,7 +42,7 @@ using value_type_t = typename std::iterator_traits::value_type; // // The first two steps of this algorithm are inspired by the ones recommended // in Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. -template > > +template >> void IncrementalSort(int max_comparisons, Iterator begin, Iterator end, Compare comp = Compare{}, bool is_stable = false) { // Ranges of at most one element are already sorted. @@ -91,7 +91,7 @@ void IncrementalSort(int max_comparisons, Iterator begin, Iterator end, // // This algorithm is inspired by the ones recommended in Algorithms, 4th Edition // by Robert Sedgewick and Kevin Wayne. -template > > +template >> void InsertionSort(Iterator begin, Iterator end, Compare comp = Compare{}) { // Ranges of at most one element are already sorted. if (std::distance(begin, end) <= 1) return; @@ -125,7 +125,7 @@ void InsertionSort(Iterator begin, Iterator end, Compare comp = Compare{}) { // // This function performs well if the elements in the range [begin, end) are // almost sorted. -template > > +template >> void IncrementalSort(Iterator begin, Iterator end, Compare comp = Compare{}, bool is_stable = false) { const int size = std::distance(begin, end); diff --git a/ortools/util/vector_or_function.h b/ortools/util/vector_or_function.h index d8ba264bf3..ff1abd9f81 100644 --- a/ortools/util/vector_or_function.h +++ b/ortools/util/vector_or_function.h @@ -37,7 +37,7 @@ class VectorOrFunction { // Specialization for vectors. template -class VectorOrFunction > { +class VectorOrFunction> { public: explicit VectorOrFunction(std::vector values) : values_(std::move(values)) {} @@ -65,12 +65,12 @@ class MatrixOrFunction { // Specialization for vector-based matrices. template -class MatrixOrFunction >, +class MatrixOrFunction>, square> { public: - explicit MatrixOrFunction(std::vector > matrix) + explicit MatrixOrFunction(std::vector> matrix) : matrix_(std::move(matrix)) {} - void Reset(std::vector > matrix) { + void Reset(std::vector> matrix) { matrix_ = std::move(matrix); } ScalarType operator()(int i, int j) const { return matrix_[i][j]; } @@ -88,7 +88,7 @@ class MatrixOrFunction >, } private: - std::vector > matrix_; + std::vector> matrix_; }; } // namespace operations_research