diff --git a/ortools/algorithms/csharp/knapsack_solver.i b/ortools/algorithms/csharp/knapsack_solver.i index 00a1263804..a85fd10ed5 100644 --- a/ortools/algorithms/csharp/knapsack_solver.i +++ b/ortools/algorithms/csharp/knapsack_solver.i @@ -23,9 +23,9 @@ #include "ortools/algorithms/knapsack_solver.h" %} -// by default vector> is mapped to a jagged array i.e. .Net type long[][] +// by default vector> is mapped to a jagged array i.e. .Net type long[][] // but here we want a regular matrix i.e. .Net type long[,] -REGULAR_MATRIX_AS_CSHARP_ARRAY(int64, int64, long, Int64VectorVector); +REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector); %rename (UseReduction) operations_research::KnapsackSolver::use_reduction; %rename (SetUseReduction) operations_research::KnapsackSolver::set_use_reduction; diff --git a/ortools/algorithms/knapsack_solver.cc b/ortools/algorithms/knapsack_solver.cc index ce37565e7f..f43a57504f 100644 --- a/ortools/algorithms/knapsack_solver.cc +++ b/ortools/algorithms/knapsack_solver.cc @@ -68,12 +68,12 @@ typedef std::priority_queue< CompareKnapsackSearchNodePtrInDecreasingUpperBoundOrder> SearchQueue; -// Returns true when value_1 * value_2 may overflow int64. +// Returns true when value_1 * value_2 may overflow int64_t. inline bool WillProductOverflow(int64_t value_1, int64_t value_2) { const int MostSignificantBitPosition1 = MostSignificantBitPosition64(value_1); const int MostSignificantBitPosition2 = MostSignificantBitPosition64(value_2); // The sum should be less than 61 to be safe as we are only considering the - // most significant bit and dealing with int64 instead of uint64. + // most significant bit and dealing with int64_t instead of uint64_t. const int kOverflow = 61; return MostSignificantBitPosition1 + MostSignificantBitPosition2 > kOverflow; } diff --git a/ortools/algorithms/knapsack_solver.h b/ortools/algorithms/knapsack_solver.h index 2edfe029fe..7cd9f34eb7 100644 --- a/ortools/algorithms/knapsack_solver.h +++ b/ortools/algorithms/knapsack_solver.h @@ -86,17 +86,17 @@ class BaseKnapsackSolver; \b C++: \code{.cpp} - const std::vector profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::vector> weights = + const std::vector profits = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::vector> weights = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - const std::vector capacities = { 34, 4 }; + const std::vector capacities = { 34, 4 }; KnapsackSolver solver( KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, "Multi-dimensional solver"); solver.Init(profits, weights, capacities); - const int64 profit = solver.Solve(); + const int64_t profit = solver.Solve(); \endcode \b Java: @@ -197,14 +197,14 @@ class KnapsackSolver { /** * Initializes the solver and enters the problem to be solved. */ - void Init(const std::vector& profits, - const std::vector >& weights, - const std::vector& capacities); + void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities); /** * Solves the problem and returns the profit of the optimal solution. */ - int64 Solve(); + int64_t Solve(); /** * Returns true if the item 'item_id' is packed in the optimal knapsack. @@ -233,15 +233,15 @@ class KnapsackSolver { // Trivial reduction of capacity constraints when the capacity is higher than // the sum of the weights of the items. Returns the number of reduced items. int ReduceCapacities(int num_items, - const std::vector >& weights, - const std::vector& capacities, - std::vector >* reduced_weights, - std::vector* reduced_capacities); + const std::vector >& weights, + const std::vector& capacities, + std::vector >* reduced_weights, + std::vector* reduced_capacities); int ReduceProblem(int num_items); - void ComputeAdditionalProfit(const std::vector& profits); - void InitReducedProblem(const std::vector& profits, - const std::vector >& weights, - const std::vector& capacities); + void ComputeAdditionalProfit(const std::vector& profits); + void InitReducedProblem(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities); std::unique_ptr solver_; std::vector known_value_; @@ -249,7 +249,7 @@ class KnapsackSolver { bool is_solution_optimal_ = false; std::vector mapping_reduced_item_id_; bool is_problem_solved_; - int64 additional_profit_; + int64_t additional_profit_; bool use_reduction_; double time_limit_seconds_; std::unique_ptr time_limit_; @@ -304,9 +304,9 @@ struct KnapsackAssignment { // As there usually are only few dimensions, the overhead should not be an // issue. struct KnapsackItem { - KnapsackItem(int _id, int64 _weight, int64 _profit) + KnapsackItem(int _id, int64_t _weight, int64_t _profit) : id(_id), weight(_weight), profit(_profit) {} - double GetEfficiency(int64 profit_max) const { + double GetEfficiency(int64_t profit_max) const { return (weight > 0) ? static_cast(profit) / static_cast(weight) : static_cast(profit_max); @@ -315,8 +315,8 @@ struct KnapsackItem { // The 'id' field is used to retrieve the initial item in order to // communicate with other propagators and state. const int id; - const int64 weight; - const int64 profit; + const int64_t weight; + const int64_t profit; }; typedef KnapsackItem* KnapsackItemPtr; @@ -336,11 +336,11 @@ class KnapsackSearchNode { const KnapsackSearchNode* const parent() const { return parent_; } const KnapsackAssignment& assignment() const { return assignment_; } - int64 current_profit() const { return current_profit_; } - void set_current_profit(int64 profit) { current_profit_ = profit; } + int64_t current_profit() const { return current_profit_; } + void set_current_profit(int64_t profit) { current_profit_ = profit; } - int64 profit_upper_bound() const { return profit_upper_bound_; } - void set_profit_upper_bound(int64 profit) { profit_upper_bound_ = profit; } + int64_t profit_upper_bound() const { return profit_upper_bound_; } + void set_profit_upper_bound(int64_t profit) { profit_upper_bound_ = profit; } int next_item_id() const { return next_item_id_; } void set_next_item_id(int id) { next_item_id_ = id; } @@ -356,8 +356,8 @@ class KnapsackSearchNode { // nodes using a priority queue. That allows to pop the node with the best // upper bound, and more importantly to stop the search when optimality is // proved. - int64 current_profit_; - int64 profit_upper_bound_; + int64_t current_profit_; + int64_t profit_upper_bound_; // 'next_item_id' field allows to avoid an O(number_of_items) scan to find // next item to select. This is done for free by the upper bound computation. @@ -443,8 +443,8 @@ class KnapsackPropagator { virtual ~KnapsackPropagator(); // Initializes data structure and then calls InitPropagator. - void Init(const std::vector& profits, - const std::vector& weights); + void Init(const std::vector& profits, + const std::vector& weights); // Updates data structure and then calls UpdatePropagator. // Returns false when failure. @@ -456,9 +456,9 @@ class KnapsackPropagator { // Returns kNoSelection when all items are bound. virtual int GetNextItemId() const = 0; - int64 current_profit() const { return current_profit_; } - int64 profit_lower_bound() const { return profit_lower_bound_; } - int64 profit_upper_bound() const { return profit_upper_bound_; } + int64_t current_profit() const { return current_profit_; } + int64_t profit_lower_bound() const { return profit_lower_bound_; } + int64_t profit_upper_bound() const { return profit_upper_bound_; } // Copies the current state into 'solution'. // All unbound items are set to false (i.e. not in the knapsack). @@ -490,14 +490,14 @@ class KnapsackPropagator { const KnapsackState& state() const { return state_; } const std::vector& items() const { return items_; } - void set_profit_lower_bound(int64 profit) { profit_lower_bound_ = profit; } - void set_profit_upper_bound(int64 profit) { profit_upper_bound_ = profit; } + void set_profit_lower_bound(int64_t profit) { profit_lower_bound_ = profit; } + void set_profit_upper_bound(int64_t profit) { profit_upper_bound_ = profit; } private: std::vector items_; - int64 current_profit_; - int64 profit_lower_bound_; - int64 profit_upper_bound_; + int64_t current_profit_; + int64_t profit_lower_bound_; + int64_t profit_upper_bound_; const KnapsackState& state_; DISALLOW_COPY_AND_ASSIGN(KnapsackPropagator); @@ -525,7 +525,7 @@ class KnapsackPropagator { // the reason why the item vector has to be duplicated 'sorted_items_'. class KnapsackCapacityPropagator : public KnapsackPropagator { public: - KnapsackCapacityPropagator(const KnapsackState& state, int64 capacity); + KnapsackCapacityPropagator(const KnapsackState& state, int64_t capacity); ~KnapsackCapacityPropagator() override; void ComputeProfitBounds() override; int GetNextItemId() const override { return break_item_id_; } @@ -550,13 +550,13 @@ class KnapsackCapacityPropagator : public KnapsackPropagator { // So basically the linear relaxation is done on the item before the break // item, or the one after the break item. // This is what GetAdditionalProfit method implements. - int64 GetAdditionalProfit(int64 remaining_capacity, int break_item_id) const; + int64_t GetAdditionalProfit(int64_t remaining_capacity, int break_item_id) const; - const int64 capacity_; - int64 consumed_capacity_; + const int64_t capacity_; + int64_t consumed_capacity_; int break_item_id_; std::vector sorted_items_; - int64 profit_max_; + int64_t profit_max_; DISALLOW_COPY_AND_ASSIGN(KnapsackCapacityPropagator); }; @@ -570,19 +570,19 @@ class BaseKnapsackSolver { virtual ~BaseKnapsackSolver() {} // Initializes the solver and enters the problem to be solved. - virtual void Init(const std::vector& profits, - const std::vector >& weights, - const std::vector& capacities) = 0; + virtual void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities) = 0; // Gets the lower and upper bound when the item is in or out of the knapsack. // To ensure objects are correctly initialized, this method should not be // called before ::Init. virtual void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, - int64* lower_bound, - int64* upper_bound); + int64_t* lower_bound, + int64_t* upper_bound); // Solves the problem and returns the profit of the optimal solution. - virtual int64 Solve(TimeLimit* time_limit, bool* is_solution_optimal) = 0; + virtual int64_t Solve(TimeLimit* time_limit, bool* is_solution_optimal) = 0; // Returns true if the item 'item_id' is packed in the optimal knapsack. virtual bool best_solution(int item_id) const = 0; @@ -608,13 +608,13 @@ class KnapsackGenericSolver : public BaseKnapsackSolver { ~KnapsackGenericSolver() override; // Initializes the solver and enters the problem to be solved. - void Init(const std::vector& profits, - const std::vector >& weights, - const std::vector& capacities) override; + void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities) override; int GetNumberOfItems() const { return state_.GetNumberOfItems(); } void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, - int64* lower_bound, - int64* upper_bound) override; + int64_t* lower_bound, + int64_t* upper_bound) override; // Sets which propagator should be used to guide the search. // 'master_propagator_id' should be in 0..p-1 with p the number of @@ -624,7 +624,7 @@ class KnapsackGenericSolver : public BaseKnapsackSolver { } // Solves the problem and returns the profit of the optimal solution. - int64 Solve(TimeLimit* time_limit, bool* is_solution_optimal) override; + int64_t Solve(TimeLimit* time_limit, bool* is_solution_optimal) override; // Returns true if the item 'item_id' is packed in the optimal knapsack. bool best_solution(int item_id) const override { return best_solution_.at(item_id); @@ -650,12 +650,12 @@ class KnapsackGenericSolver : public BaseKnapsackSolver { bool MakeNewNode(const KnapsackSearchNode& node, bool is_in); // Gets the aggregated (min) profit upper bound among all propagators. - int64 GetAggregatedProfitUpperBound() const; + int64_t GetAggregatedProfitUpperBound() const; bool HasOnePropagator() const { return propagators_.size() == 1; } - int64 GetCurrentProfit() const { + int64_t GetCurrentProfit() const { return propagators_.at(master_propagator_id_)->current_profit(); } - int64 GetNextItemId() const { + int64_t GetNextItemId() const { return propagators_.at(master_propagator_id_)->GetNextItemId(); } @@ -663,7 +663,7 @@ class KnapsackGenericSolver : public BaseKnapsackSolver { int master_propagator_id_; std::vector search_nodes_; KnapsackState state_; - int64 best_solution_profit_; + int64_t best_solution_profit_; std::vector best_solution_; DISALLOW_COPY_AND_ASSIGN(KnapsackGenericSolver); diff --git a/ortools/algorithms/knapsack_solver_for_cuts.h b/ortools/algorithms/knapsack_solver_for_cuts.h index 0f881a7b28..a1391c1751 100644 --- a/ortools/algorithms/knapsack_solver_for_cuts.h +++ b/ortools/algorithms/knapsack_solver_for_cuts.h @@ -13,7 +13,7 @@ // This library solves 0-1 one-dimensional knapsack problems with fractional // profits and weights using the branch and bound algorithm. Note that -// algorithms/knapsack_solver uses 'int64' for the profits and the weights. +// algorithms/knapsack_solver uses 'int64_t' for the profits and the weights. // TODO(user): Merge this code with algorithms/knapsack_solver. // // Given n items, each with a profit and a weight and a knapsack of diff --git a/ortools/base/bitmap.cc b/ortools/base/bitmap.cc index 4834528a2d..e1e3eadd1d 100644 --- a/ortools/base/bitmap.cc +++ b/ortools/base/bitmap.cc @@ -28,7 +28,7 @@ void Bitmap::Resize(uint32 size, bool fill) { const uint32 old_array_size = array_size_; array_size_ = new_array_size; max_size_ = size; - uint64* new_map = new uint64[array_size_]; + uint64_t* new_map = new uint64_t[array_size_]; memcpy(new_map, map_, old_array_size * sizeof(*map_)); delete[] map_; map_ = new_map; diff --git a/ortools/base/bitmap.h b/ortools/base/bitmap.h index 06a3e86372..a1f0718f7b 100644 --- a/ortools/base/bitmap.h +++ b/ortools/base/bitmap.h @@ -20,17 +20,17 @@ namespace operations_research { namespace internal { -inline uint64 OneBit64(int pos) { return uint64_t{1} << pos; } -inline uint64 BitPos64(uint64 pos) { return (pos & 63); } -inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); } -inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); } -inline bool IsBitSet64(const uint64* const bitset, uint64 pos) { +inline uint64_t OneBit64(int pos) { return uint64_t{1} << pos; } +inline uint64_t BitPos64(uint64_t pos) { return (pos & 63); } +inline uint64_t BitOffset64(uint64_t pos) { return (pos >> 6); } +inline uint64_t BitLength64(uint64_t size) { return ((size + 63) >> 6); } +inline bool IsBitSet64(const uint64_t* const bitset, uint64_t pos) { return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos))); } -inline void SetBit64(uint64* const bitset, uint64 pos) { +inline void SetBit64(uint64_t* const bitset, uint64_t pos) { bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos)); } -inline void ClearBit64(uint64* const bitset, uint64 pos) { +inline void ClearBit64(uint64_t* const bitset, uint64_t pos) { bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos)); } } // namespace internal @@ -42,7 +42,7 @@ class Bitmap { explicit Bitmap(uint32 size, bool fill = false) : max_size_(size), array_size_(internal::BitLength64(size)), - map_(new uint64[array_size_]) { + map_(new uint64_t[array_size_]) { // initialize all of the bits SetAll(fill); } @@ -79,7 +79,7 @@ class Bitmap { private: uint32 max_size_; // the upper bound of the bitmap uint32 array_size_; - uint64* map_; // the bitmap + uint64_t* map_; // the bitmap }; } // namespace operations_research diff --git a/ortools/base/container_logging.h b/ortools/base/container_logging.h index 6b56165580..f9fe83febc 100644 --- a/ortools/base/container_logging.h +++ b/ortools/base/container_logging.h @@ -64,7 +64,7 @@ namespace gtl { // void LogSeparator(ostream &out) const; // // Returns the maximum number of elements to print: -// int64 MaxElements() const; +// int64_t MaxElements() const; // // Called to print an indication that MaximumElements() was reached: // void LogEllipsis(ostream &out) const; @@ -107,18 +107,18 @@ struct LogLegacyBase : public LogBase { // LogShort uses [] braces and separates items with comma-spaces. For // example "[1, 2, 3]". struct LogShort : public internal::LogShortBase { - int64 MaxElements() const { return std::numeric_limits::max(); } + int64_t MaxElements() const { return std::numeric_limits::max(); } }; // LogShortUpToN(max_elements) formats the same as LogShort but prints no more // than the max_elements elements. class LogShortUpToN : public internal::LogShortBase { public: - explicit LogShortUpToN(int64 max_elements) : max_elements_(max_elements) {} - int64 MaxElements() const { return max_elements_; } + explicit LogShortUpToN(int64_t max_elements) : max_elements_(max_elements) {} + int64_t MaxElements() const { return max_elements_; } private: - int64 max_elements_; + int64_t max_elements_; }; // LogShortUpTo100 formats the same as LogShort but prints no more @@ -134,19 +134,19 @@ struct LogShortUpTo100 : public LogShortUpToN { // 3 // ]". struct LogMultiline : public internal::LogMultilineBase { - int64 MaxElements() const { return std::numeric_limits::max(); } + int64_t MaxElements() const { return std::numeric_limits::max(); } }; // LogMultilineUpToN(max_elements) formats the same as LogMultiline but // prints no more than max_elements elements. class LogMultilineUpToN : public internal::LogMultilineBase { public: - explicit LogMultilineUpToN(int64 max_elements) + explicit LogMultilineUpToN(int64_t max_elements) : max_elements_(max_elements) {} - int64 MaxElements() const { return max_elements_; } + int64_t MaxElements() const { return max_elements_; } private: - int64 max_elements_; + int64_t max_elements_; }; // LogMultilineUpTo100 formats the same as LogMultiline but @@ -158,10 +158,10 @@ struct LogMultilineUpTo100 : public LogMultilineUpToN { // The legacy behavior of LogSequence() does not use braces and // separates items with spaces. For example "1 2 3". struct LogLegacyUpTo100 : public internal::LogLegacyBase { - int64 MaxElements() const { return 100; } + int64_t MaxElements() const { return 100; } }; struct LogLegacy : public internal::LogLegacyBase { - int64 MaxElements() const { return std::numeric_limits::max(); } + int64_t MaxElements() const { return std::numeric_limits::max(); } }; // The default policy for new code. @@ -174,7 +174,7 @@ inline void LogRangeToStream(std::ostream& out, // NOLINT IteratorT begin, IteratorT end, const PolicyT& policy) { policy.LogOpening(out); - for (int64 i = 0; begin != end && i < policy.MaxElements(); ++i, ++begin) { + for (int64_t i = 0; begin != end && i < policy.MaxElements(); ++i, ++begin) { if (i == 0) { policy.LogFirstSeparator(out); } else { diff --git a/ortools/base/file.cc b/ortools/base/file.cc index 89753deb72..90a455d7ec 100644 --- a/ortools/base/file.cc +++ b/ortools/base/file.cc @@ -95,22 +95,22 @@ File* File::Open(const char* const name, const char* const flag) { return f; } -char* File::ReadLine(char* const output, uint64 max_length) { +char* File::ReadLine(char* const output, uint64_t max_length) { return fgets(output, max_length, f_); } -int64 File::ReadToString(std::string* const output, uint64 max_length) { +int64_t File::ReadToString(std::string* const output, uint64_t max_length) { CHECK(output != nullptr); output->clear(); if (max_length == 0) return 0; - int64 needed = max_length; + int64_t needed = max_length; int bufsize = (needed < (2 << 20) ? needed : (2 << 20)); std::unique_ptr buf(new char[bufsize]); - int64 nread = 0; + int64_t nread = 0; while (needed > 0) { nread = Read(buf.get(), (bufsize < needed ? bufsize : needed)); if (nread > 0) { @@ -120,7 +120,7 @@ int64 File::ReadToString(std::string* const output, uint64 max_length) { break; } } - return (nread >= 0 ? static_cast(output->size()) : -1); + return (nread >= 0 ? static_cast(output->size()) : -1); } size_t File::WriteString(const std::string& line) { @@ -165,14 +165,14 @@ absl::Status GetContents(const absl::string_view& filename, std::string* output, if (flags == Defaults()) { File* file = File::Open(filename, "r"); if (file != NULL) { - const int64 size = file->Size(); + const int64_t size = file->Size(); if (file->ReadToString(output, size) == size) return absl::OkStatus(); #if defined(_MSC_VER) // On windows, binary files needs to be opened with the "rb" flags. file->Close(); // Retry in binary mode. File* file = File::Open(filename, "rb"); - const int64 b_size = file->Size(); + const int64_t b_size = file->Size(); if (file->ReadToString(output, b_size) == b_size) return absl::OkStatus(); #endif // _MSC_VER } diff --git a/ortools/base/file.h b/ortools/base/file.h index 9a9a71b86a..0706270a7c 100644 --- a/ortools/base/file.h +++ b/ortools/base/file.h @@ -62,11 +62,11 @@ class File { // Reads a line from file to a string. // Each line must be no more than max_length bytes. - char* ReadLine(char* const output, uint64 max_length); + char* ReadLine(char* const output, uint64_t max_length); // Reads the whole file to a string, with a maximum length of 'max_length'. // Returns the number of bytes read. - int64 ReadToString(std::string* const line, uint64 max_length); + int64_t ReadToString(std::string* const line, uint64_t max_length); // Writes "size" bytes of buff to file, buff should be pre-allocated. size_t Write(const void* const buff, size_t size); diff --git a/ortools/base/filelineiter.h b/ortools/base/filelineiter.h index 7a6c02f3fb..5d83a4ff02 100644 --- a/ortools/base/filelineiter.h +++ b/ortools/base/filelineiter.h @@ -106,7 +106,7 @@ class FileLineIterator { static constexpr int kBufferSize = 5 * 1024; char buffer_[kBufferSize]; int next_position_after_eol_; - int64 buffer_size_; + int64_t buffer_size_; File* file_; std::string line_; const int options_; diff --git a/ortools/base/hash.h b/ortools/base/hash.h index 7577090896..c3da770340 100644 --- a/ortools/base/hash.h +++ b/ortools/base/hash.h @@ -56,7 +56,7 @@ static inline void mix(uint32& a, uint32& b, uint32& c) { // NOLINT } // 64 bit version. -static inline void mix(uint64& a, uint64& b, uint64& c) { // NOLINT +static inline void mix(uint64_t& a, uint64_t& b, uint64_t& c) { // NOLINT a -= b; a -= c; a ^= (c >> 43); @@ -100,8 +100,8 @@ inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) { return c; } -inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) { - uint64 b = uint64_t{0xe08c1d668b756f82}; // More of the golden ratio. +inline uint64_t Hash64NumWithSeed(uint64_t num, uint64_t c) { + uint64_t b = uint64_t{0xe08c1d668b756f82}; // More of the golden ratio. operations_research::mix(num, b, c); return c; } @@ -126,10 +126,10 @@ template struct hash> { public: size_t operator()(const std::array& t) const { - uint64 current = 71; + uint64_t current = 71; for (int index = 0; index < N; ++index) { const T& elem = t[index]; - const uint64 new_hash = hash()(elem); + const uint64_t new_hash = hash()(elem); current = operations_research::Hash64NumWithSeed(current, new_hash); } return current; @@ -147,13 +147,13 @@ struct hash> { namespace util_hash { -inline uint64 Hash(uint64 num, uint64 c) { - uint64 b = uint64_t{0xe08c1d668b756f82}; // More of the golden ratio. +inline uint64_t Hash(uint64_t num, uint64_t c) { + uint64_t b = uint64_t{0xe08c1d668b756f82}; // More of the golden ratio. operations_research::mix(num, b, c); return c; } -inline uint64 Hash(uint64 a, uint64 b, uint64 c) { +inline uint64_t Hash(uint64_t a, uint64_t b, uint64_t c) { operations_research::mix(a, b, c); return c; } diff --git a/ortools/base/int_type.h b/ortools/base/int_type.h index e333c95ce2..0d0097ace6 100644 --- a/ortools/base/int_type.h +++ b/ortools/base/int_type.h @@ -40,8 +40,8 @@ // DISALLOWED OPERATIONS / TYPE-SAFETY ENFORCEMENT ----------------------------- // // Consider these definitions and variable declarations: -// DEFINE_INT_TYPE(GlobalDocID, int64); -// DEFINE_INT_TYPE(LocalDocID, int64); +// DEFINE_INT_TYPE(GlobalDocID, int64_t); +// DEFINE_INT_TYPE(LocalDocID, int64_t); // GlobalDocID global; // LocalDocID local; // @@ -63,7 +63,7 @@ // // 3) Implicit conversion from an IntType to a native integer type. // -// void GetGlobalDoc(int64 global) { ... +// void GetGlobalDoc(int64_t global) { ... // GetGlobalDoc(global); <-- Fails to compile! // GetGlobalDoc(local); <-- Fails to compile! // @@ -98,7 +98,7 @@ // // EXAMPLES -------------------------------------------------------------------- // -// DEFINE_INT_TYPE(GlobalDocID, int64); +// DEFINE_INT_TYPE(GlobalDocID, int64_t); // GlobalDocID global = 3; // std::cout << global; <-- Prints 3 to stdout. // @@ -106,7 +106,7 @@ // std::cout << i; // } <-- Print(ln)s 0 1 2 to stdout // -// DEFINE_INT_TYPE(LocalDocID, int64); +// DEFINE_INT_TYPE(LocalDocID, int64_t); // LocalDocID local; // std::cout << local; <-- Prints 0 to stdout it // default @@ -129,8 +129,8 @@ // class is to prevent *accidental* mingling of similar logical integer types -- // and not type casting from one type to another. // -// DEFINE_INT_TYPE(GlobalDocID, int64); -// DEFINE_INT_TYPE(LocalDocID, int64); +// DEFINE_INT_TYPE(GlobalDocID, int64_t); +// DEFINE_INT_TYPE(LocalDocID, int64_t); // GlobalDocID global; // LocalDocID local; // @@ -139,7 +139,7 @@ // void GetGlobalDoc(GlobalDocID global) { ... // GetGlobalDoc(local.value()); <-- Compiles fine. // -// void GetGlobalDoc(int64 global) { ... +// void GetGlobalDoc(int64_t global) { ... // GetGlobalDoc(local.value()); <-- Compiles fine. #ifndef OR_TOOLS_BASE_INT_TYPE_H_ diff --git a/ortools/base/logging.cc b/ortools/base/logging.cc index 046df14325..f39c2ddf61 100644 --- a/ortools/base/logging.cc +++ b/ortools/base/logging.cc @@ -350,7 +350,7 @@ struct LogMessage::LogMessageData { static absl::Mutex log_mutex; // Number of messages sent at each severity. Under log_mutex. -int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; +int64_t LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; // Globally disable log writing (if disk is full) static bool stop_writing = false; @@ -413,7 +413,7 @@ class LogFileObject : public base::Logger { uint32 dropped_mem_length_; uint32 file_length_; unsigned int rollover_attempt_; - int64 next_flush_time_; // cycle count at which to flush log + int64_t next_flush_time_; // cycle count at which to flush log // Actually create a logfile using the value of base_filename_ and the // supplied argument time_pid_string @@ -813,8 +813,8 @@ void LogFileObject::FlushUnlocked() { bytes_since_flush_ = 0; } // Figure out when we are due for another flush. - const int64 next = (absl::GetFlag(FLAGS_logbufsecs) * - static_cast(1000000)); // in usec + const int64_t next = (absl::GetFlag(FLAGS_logbufsecs) * + static_cast(1000000)); // in usec next_flush_time_ = logging_internal::CycleClock_Now() + logging_internal::UsecToCycles(next); } @@ -1471,7 +1471,7 @@ void base::SetLogger(LogSeverity severity, base::Logger* logger) { } // L < log_mutex. Acquires and releases absl::Mutex_. -int64 LogMessage::num_messages(int severity) { +int64_t LogMessage::num_messages(int severity) { absl::MutexLock l(&log_mutex); return num_messages_[severity]; } diff --git a/ortools/base/logging.h b/ortools/base/logging.h index dc0fd34551..c941e6dd49 100644 --- a/ortools/base/logging.h +++ b/ortools/base/logging.h @@ -524,8 +524,8 @@ inline int16 GetReferenceableValue(int16 t) { return t; } inline uint16 GetReferenceableValue(uint16 t) { return t; } inline int GetReferenceableValue(int t) { return t; } inline unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline int64 GetReferenceableValue(int64 t) { return t; } -inline uint64 GetReferenceableValue(uint64 t) { return t; } +inline int64_t GetReferenceableValue(int64_t t) { return t; } +inline uint64_t GetReferenceableValue(uint64_t t) { return t; } // This is a dummy class to define the following operator. struct DummyClassToDefineOperator {}; @@ -1129,7 +1129,7 @@ class GOOGLE_GLOG_DLL_DECL LogMessage { int preserved_errno() const; // Must be called without the log_mutex held. (L < log_mutex) - static int64 num_messages(int severity); + static int64_t num_messages(int severity); struct LogMessageData; @@ -1150,7 +1150,7 @@ class GOOGLE_GLOG_DLL_DECL LogMessage { void RecordCrashReason(logging_internal::CrashReason* reason); // Counts of messages sent at each priority: - static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex + static int64_t num_messages_[NUM_SEVERITIES]; // under log_mutex // We keep the data in a separate struct so that each instance of // LogMessage uses less stack space. diff --git a/ortools/base/logging_utilities.cc b/ortools/base/logging_utilities.cc index 9bd2ac4f3b..8f6db6eaad 100644 --- a/ortools/base/logging_utilities.cc +++ b/ortools/base/logging_utilities.cc @@ -228,9 +228,9 @@ unsigned int GetTID() { return static_cast(absl::base_internal::GetTID()); } -int64 CycleClock_Now() { return absl::ToUnixMicros(absl::Now()); } +int64_t CycleClock_Now() { return absl::ToUnixMicros(absl::Now()); } -int64 UsecToCycles(int64 usec) { return usec; } +int64_t UsecToCycles(int64_t usec) { return usec; } static int32 g_main_thread_pid = getpid(); int32 GetMainThreadPid() { return g_main_thread_pid; } diff --git a/ortools/base/logging_utilities.h b/ortools/base/logging_utilities.h index a501eca968..1941e63c04 100644 --- a/ortools/base/logging_utilities.h +++ b/ortools/base/logging_utilities.h @@ -28,9 +28,9 @@ const char* ProgramInvocationShortName(); bool IsGoogleLoggingInitialized(); -int64 CycleClock_Now(); +int64_t CycleClock_Now(); -int64 UsecToCycles(int64 usec); +int64_t UsecToCycles(int64_t usec); int32 GetMainThreadPid(); diff --git a/ortools/base/mathutil.h b/ortools/base/mathutil.h index 71032eee34..31e48d8ddd 100644 --- a/ortools/base/mathutil.h +++ b/ortools/base/mathutil.h @@ -104,11 +104,11 @@ class MathUtil { // Euclid's Algorithm. // Returns: the greatest common divisor of two unsigned integers x and y. - static int64 GCD64(int64 x, int64 y) { + static int64_t GCD64(int64_t x, int64_t y) { DCHECK_GE(x, 0); DCHECK_GE(y, 0); while (y != 0) { - int64 r = x % y; + int64_t r = x % y; x = y; y = r; } @@ -135,7 +135,7 @@ class MathUtil { return static_cast(x < 0 ? (x - 0.5) : (x + 0.5)); } - static int64 FastInt64Round(double x) { return Round(x); } + static int64_t FastInt64Round(double x) { return Round(x); } }; } // namespace operations_research diff --git a/ortools/base/murmur.h b/ortools/base/murmur.h index 3ea56138ac..704e3aeb4c 100644 --- a/ortools/base/murmur.h +++ b/ortools/base/murmur.h @@ -20,7 +20,7 @@ namespace util_hash { // In the or-tools project, MurmurHash64 is just a redirection towards // ThoroughHash. Ideally, it is meant to be using the murmurhash // algorithm described in http://murmurhash.googlepages.com. -inline uint64 MurmurHash64(const char* buf, const size_t len) { +inline uint64_t MurmurHash64(const char* buf, const size_t len) { return ::operations_research::ThoroughHash(buf, len); } } // namespace util_hash diff --git a/ortools/base/protoutil.h b/ortools/base/protoutil.h index 36af71590f..951cc3dac4 100644 --- a/ortools/base/protoutil.h +++ b/ortools/base/protoutil.h @@ -14,6 +14,8 @@ #ifndef OR_TOOLS_BASE_PROTOUTIL_H_ #define OR_TOOLS_BASE_PROTOUTIL_H_ +#include + #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/time/clock.h" @@ -25,8 +27,8 @@ namespace util_time { inline ::absl::StatusOr EncodeGoogleApiProto( absl::Duration d) { google::protobuf::Duration proto; - const int64 d_in_nano = ToInt64Nanoseconds(d); - proto.set_seconds(static_cast(d_in_nano / 1000000000)); + const int64_t d_in_nano = ToInt64Nanoseconds(d); + proto.set_seconds(static_cast(d_in_nano / 1000000000)); proto.set_nanos(static_cast(d_in_nano % 1000000000)); return proto; } diff --git a/ortools/base/python-swig.h b/ortools/base/python-swig.h index 7b41e5a4f7..7e7912e90d 100644 --- a/ortools/base/python-swig.h +++ b/ortools/base/python-swig.h @@ -131,8 +131,8 @@ inline bool PyObjAs(PyObject* py, unsigned int* c) { } template <> -inline bool PyObjAs(PyObject* py, int64* c) { // NOLINT - int64 i; // NOLINT +inline bool PyObjAs(PyObject* py, int64_t* c) { // NOLINT + int64_t i; // NOLINT #if PY_MAJOR_VERSION < 3 if (PyInt_Check(py)) { i = PyInt_AsLong(py); @@ -149,8 +149,8 @@ inline bool PyObjAs(PyObject* py, int64* c) { // NOLINT } template <> -inline bool PyObjAs(PyObject* py, uint64* c) { // NOLINT - uint64 i; // NOLINT +inline bool PyObjAs(PyObject* py, uint64_t* c) { // NOLINT + uint64_t i; // NOLINT #if PY_MAJOR_VERSION < 3 if (PyInt_Check(py)) { i = PyInt_AsUnsignedLongLongMask(py); @@ -159,7 +159,7 @@ inline bool PyObjAs(PyObject* py, uint64* c) { // NOLINT { if (!PyLong_Check(py)) return false; // Not a Python long. i = PyLong_AsUnsignedLongLong(py); - if (i == (uint64)-1 && PyErr_Occurred()) // NOLINT + if (i == (uint64_t)-1 && PyErr_Occurred()) // NOLINT return false; } if (c) *c = i; diff --git a/ortools/base/random.cc b/ortools/base/random.cc index 6f4621aae2..71a79abef1 100644 --- a/ortools/base/random.cc +++ b/ortools/base/random.cc @@ -39,11 +39,11 @@ uint32 ACMRandom::Next() { uint32 ACMRandom::Uniform(uint32 n) { return n == 0 ? 0 : Next() % n; } -uint64 ACMRandom::Next64() { - return absl::uniform_int_distribution(0, kuint64max)(generator_); +uint64_t ACMRandom::Next64() { + return absl::uniform_int_distribution(0, kuint64max)(generator_); } -uint64 ACMRandom::operator()(uint64 val_max) { +uint64_t ACMRandom::operator()(uint64_t val_max) { return val_max == 0 ? 0 : Next64() % val_max; } diff --git a/ortools/base/random.h b/ortools/base/random.h index 888d3d65f3..2113b5a7ff 100644 --- a/ortools/base/random.h +++ b/ortools/base/random.h @@ -29,13 +29,13 @@ class ACMRandom { // Unbounded generators. uint32 Next(); - uint64 Next64(); - uint64 Rand64() { return Next64(); } - uint64 operator()() { return Next64(); } + uint64_t Next64(); + uint64_t Rand64() { return Next64(); } + uint64_t operator()() { return Next64(); } // Bounded generators. uint32 Uniform(uint32 n); - uint64 operator()(uint64 val_max); + uint64_t operator()(uint64_t val_max); // Seed management. void Reset(int32 seed) { generator_.seed(seed); } @@ -43,8 +43,8 @@ class ACMRandom { static int32 DeterministicSeed(); // C++11 goodies. - typedef int64 difference_type; - typedef uint64 result_type; + typedef int64_t difference_type; + typedef uint64_t result_type; static constexpr result_type min() { return 0; } static constexpr result_type max() { return kuint32max; } diff --git a/ortools/base/recordio.cc b/ortools/base/recordio.cc index cf9835cf24..479950d912 100644 --- a/ortools/base/recordio.cc +++ b/ortools/base/recordio.cc @@ -53,9 +53,9 @@ RecordReader::RecordReader(File* const file) : file_(file) {} bool RecordReader::Close() { return file_->Close(); } -void RecordReader::Uncompress(const char* const source, uint64 source_size, +void RecordReader::Uncompress(const char* const source, uint64_t source_size, char* const output_buffer, - uint64 output_size) const { + uint64_t output_size) const { unsigned long result_size = output_size; // NOLINT // Use uncompress() from zlib.h const int result = diff --git a/ortools/base/recordio.h b/ortools/base/recordio.h index de6a61017e..9a847a682a 100644 --- a/ortools/base/recordio.h +++ b/ortools/base/recordio.h @@ -41,10 +41,10 @@ class RecordWriter { bool WriteProtocolMessage(const P& proto) { std::string uncompressed_buffer; proto.SerializeToString(&uncompressed_buffer); - const uint64 uncompressed_size = uncompressed_buffer.size(); + const uint64_t uncompressed_size = uncompressed_buffer.size(); const std::string compressed_buffer = use_compression_ ? Compress(uncompressed_buffer) : ""; - const uint64 compressed_size = compressed_buffer.size(); + const uint64_t compressed_size = compressed_buffer.size(); if (file_->Write(&kMagicNumber, sizeof(kMagicNumber)) != sizeof(kMagicNumber)) { return false; @@ -89,8 +89,8 @@ class RecordReader { template bool ReadProtocolMessage(P* const proto) { - uint64 usize = 0; - uint64 csize = 0; + uint64_t usize = 0; + uint64_t csize = 0; int magic_number = 0; if (file_->Read(&magic_number, sizeof(magic_number)) != sizeof(magic_number)) { @@ -126,8 +126,8 @@ class RecordReader { bool Close(); private: - void Uncompress(const char* const source, uint64 source_size, - char* const output_buffer, uint64 output_size) const; + void Uncompress(const char* const source, uint64_t source_size, + char* const output_buffer, uint64_t output_size) const; File* const file_; }; diff --git a/ortools/base/stl_util.h b/ortools/base/stl_util.h index 969c6d6a7b..eae1c58776 100644 --- a/ortools/base/stl_util.h +++ b/ortools/base/stl_util.h @@ -901,7 +901,7 @@ bool SortedContainersHaveIntersection(const In1& in1, const In2& in2) { // // Example: // using MyAlloc = STLCountingAllocator; -// int64 bytes = 0; +// int64_t bytes = 0; // std::vector v(MyAlloc(&bytes)); // v.push_back("hi"); // LOG(INFO) << "Bytes allocated " << bytes; @@ -914,7 +914,7 @@ class STLCountingAllocator : public Alloc { using size_type = typename Alloc::size_type; STLCountingAllocator() : bytes_used_(nullptr) {} - explicit STLCountingAllocator(int64* b) : bytes_used_(b) {} + explicit STLCountingAllocator(int64_t* b) : bytes_used_(b) {} // Constructor used for rebinding template @@ -943,17 +943,17 @@ class STLCountingAllocator : public Alloc { using other = STLCountingAllocator; }; - int64* bytes_used() const { return bytes_used_; } + int64_t* bytes_used() const { return bytes_used_; } private: - int64* bytes_used_; + int64_t* bytes_used_; }; template class STLCountingAllocator : public A { public: STLCountingAllocator() : bytes_used_(nullptr) {} - explicit STLCountingAllocator(int64* b) : bytes_used_(b) {} + explicit STLCountingAllocator(int64_t* b) : bytes_used_(b) {} // Constructor used for rebinding template @@ -967,10 +967,10 @@ class STLCountingAllocator : public A { public: using other = STLCountingAllocator; }; - int64* bytes_used() const { return bytes_used_; } + int64_t* bytes_used() const { return bytes_used_; } private: - int64* bytes_used_; + int64_t* bytes_used_; }; template diff --git a/ortools/base/strong_vector.h b/ortools/base/strong_vector.h index c60639f9aa..9abeb8129a 100644 --- a/ortools/base/strong_vector.h +++ b/ortools/base/strong_vector.h @@ -27,7 +27,7 @@ // // where IntTypeName is the desired name for the "logical" integer-like type // and the ValueType is a supported native integer type such as int or -// uint64 (see int_type.h for details). +// uint64_t (see int_type.h for details). // // The wrapper exposes all public methods of STL vector and behaves mostly as // pass-through. The only method modified to ensure type-safety is the operator diff --git a/ortools/base/sysinfo.cc b/ortools/base/sysinfo.cc index 2c6a443fba..07235eccea 100644 --- a/ortools/base/sysinfo.cc +++ b/ortools/base/sysinfo.cc @@ -35,7 +35,7 @@ namespace operations_research { // GetProcessMemoryUsage #if defined(__APPLE__) && defined(__GNUC__) // Mac OS X -int64 GetProcessMemoryUsage() { +int64_t GetProcessMemoryUsage() { task_t task = MACH_PORT_NULL; struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; @@ -44,11 +44,11 @@ int64 GetProcessMemoryUsage() { (task_info_t)&t_info, &t_info_count)) { return -1; } - int64 resident_memory = t_info.resident_size; + int64_t resident_memory = t_info.resident_size; return resident_memory; } #elif defined(__GNUC__) && !defined(__FreeBSD__) // LINUX -int64 GetProcessMemoryUsage() { +int64_t GetProcessMemoryUsage() { unsigned size = 0; char buf[30]; snprintf(buf, sizeof(buf), "/proc/%u/statm", (unsigned)getpid()); @@ -57,22 +57,22 @@ int64 GetProcessMemoryUsage() { if (fscanf(pf, "%u", &size) != 1) return 0; } fclose(pf); - return size * int64{1024}; + return size * int64_t{1024}; } #elif defined(__FreeBSD__) // FreeBSD -int64 GetProcessMemoryUsage() { +int64_t GetProcessMemoryUsage() { int who = RUSAGE_SELF; struct rusage rusage; getrusage(who, &rusage); - return (int64)(rusage.ru_maxrss * int64{1024}); + return (int64_t)(rusage.ru_maxrss * int64_t{1024}); } #elif defined(_MSC_VER) // WINDOWS -int64 GetProcessMemoryUsage() { +int64_t GetProcessMemoryUsage() { HANDLE hProcess; PROCESS_MEMORY_COUNTERS pmc; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); - int64 memory = 0; + int64_t memory = 0; if (hProcess) { if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { memory = pmc.WorkingSetSize; @@ -82,7 +82,7 @@ int64 GetProcessMemoryUsage() { return memory; } #else // Unknown, returning 0. -int64 GetProcessMemoryUsage() { return 0; } +int64_t GetProcessMemoryUsage() { return 0; } #endif } // namespace operations_research diff --git a/ortools/base/sysinfo.h b/ortools/base/sysinfo.h index c625d0015e..b5258989d6 100644 --- a/ortools/base/sysinfo.h +++ b/ortools/base/sysinfo.h @@ -18,10 +18,10 @@ namespace operations_research { // Returns the memory usage of the process. -int64 GetProcessMemoryUsage(); +int64_t GetProcessMemoryUsage(); } // namespace operations_research -inline int64 MemoryUsage(int unused) { +inline int64_t MemoryUsage(int unused) { return operations_research::GetProcessMemoryUsage(); } diff --git a/ortools/base/thorough_hash.h b/ortools/base/thorough_hash.h index 50fca0cd95..35fefc3d35 100644 --- a/ortools/base/thorough_hash.h +++ b/ortools/base/thorough_hash.h @@ -17,11 +17,11 @@ #include "ortools/base/integral_types.h" namespace operations_research { -inline uint64 MixTwoUInt64(uint64 fp1, uint64 fp2) { +inline uint64_t MixTwoUInt64(uint64_t fp1, uint64_t fp2) { // Two big prime numbers. - const uint64 kMul1 = 0xc6a4a7935bd1e995ULL; - const uint64 kMul2 = 0x228876a7198b743ULL; - uint64 a = fp1 * kMul1 + fp2 * kMul2; + const uint64_t kMul1 = 0xc6a4a7935bd1e995ULL; + const uint64_t kMul2 = 0x228876a7198b743ULL; + uint64_t a = fp1 * kMul1 + fp2 * kMul2; // Note: The following line also makes sure we never return 0 or 1, because we // will only add something to 'a' if there are any MSBs (the remaining bits // after the shift) being 0, in which case wrapping around would not happen. @@ -30,17 +30,17 @@ inline uint64 MixTwoUInt64(uint64 fp1, uint64 fp2) { // This should be better (collision-wise) than the default hash, without // being much slower. It never returns 0 or 1. -inline uint64 ThoroughHash(const char* bytes, size_t len) { +inline uint64_t ThoroughHash(const char* bytes, size_t len) { // Some big prime numer. - uint64 fp = 0xa5b85c5e198ed849ULL; + uint64_t fp = 0xa5b85c5e198ed849ULL; const char* end = bytes + len; while (bytes + 8 <= end) { - fp = MixTwoUInt64(fp, *(reinterpret_cast(bytes))); + fp = MixTwoUInt64(fp, *(reinterpret_cast(bytes))); bytes += 8; } // Note: we don't care about "consistency" (little or big endian) between // the bulk and the suffix of the message. - uint64 last_bytes = 0; + uint64_t last_bytes = 0; while (bytes < end) { last_bytes += *bytes; last_bytes <<= 8; diff --git a/ortools/base/timer.h b/ortools/base/timer.h index 95cc51a1b2..2c94f9f502 100644 --- a/ortools/base/timer.h +++ b/ortools/base/timer.h @@ -43,21 +43,21 @@ class WallTimer { } } double Get() const { return GetNanos() * 1e-9; } - int64 GetInMs() const { return GetNanos() / 1000000; } - int64 GetInUsec() const { return GetNanos() / 1000; } + int64_t GetInMs() const { return GetNanos() / 1000000; } + int64_t GetInUsec() const { return GetNanos() / 1000; } inline absl::Duration GetDuration() const { return absl::Nanoseconds(GetNanos()); } protected: - int64 GetNanos() const { + int64_t GetNanos() const { return running_ ? absl::GetCurrentTimeNanos() - start_ + sum_ : sum_; } private: bool running_; - int64 start_; - int64 sum_; + int64_t start_; + int64_t sum_; }; // This is meant to measure the actual CPU usage time. @@ -73,7 +73,7 @@ class CycleTimer : public WallTimer { public: // This actually returns a number of nanoseconds instead of the number // of CPU cycles. - int64 GetCycles() const { return GetNanos(); } + int64_t GetCycles() const { return GetNanos(); } }; typedef CycleTimer SimpleCycleTimer; @@ -81,10 +81,10 @@ typedef CycleTimer SimpleCycleTimer; // Conversion routines between CycleTimer::GetCycles and actual times. class CycleTimerBase { public: - static int64 SecondsToCycles(double s) { return static_cast(s * 1e9); } - static double CyclesToSeconds(int64 c) { return c * 1e-9; } - static int64 CyclesToMs(int64 c) { return c / 1000000; } - static int64 CyclesToUsec(int64 c) { return c / 1000; } + static int64_t SecondsToCycles(double s) { return static_cast(s * 1e9); } + static double CyclesToSeconds(int64_t c) { return c * 1e-9; } + static int64_t CyclesToMs(int64_t c) { return c / 1000000; } + static int64_t CyclesToUsec(int64_t c) { return c / 1000; } }; typedef CycleTimerBase CycleTimerInstance; diff --git a/ortools/bop/integral_solver.cc b/ortools/bop/integral_solver.cc index 4817a0439b..66d84d90ea 100644 --- a/ortools/bop/integral_solver.cc +++ b/ortools/bop/integral_solver.cc @@ -396,7 +396,7 @@ class IntegralProblemConverter { // t is a constraint or the objective. // Returns the bound error due to the scaling. // The weight is scaled using: - // static_cast(round(weight * scaling_factor)) / gcd; + // static_cast(round(weight * scaling_factor)) / gcd; template double ScaleAndSparsifyWeights( double scaling_factor, int64_t gcd, diff --git a/ortools/constraint_solver/alldiff_cst.cc b/ortools/constraint_solver/alldiff_cst.cc index 1eec9ae4c8..b68d7cc720 100644 --- a/ortools/constraint_solver/alldiff_cst.cc +++ b/ortools/constraint_solver/alldiff_cst.cc @@ -15,6 +15,7 @@ // AllDifferent constraints #include +#include #include #include #include @@ -41,7 +42,7 @@ class BaseAllDifferent : public Constraint { protected: const std::vector vars_; - int64 size() const { return vars_.size(); } + int64_t size() const { return vars_.size(); } }; //----------------------------------------------------------------------------- @@ -92,7 +93,7 @@ void ValueAllDifferent::InitialPropagate() { void ValueAllDifferent::OneMove(int index) { if (!AllMoves()) { - const int64 val = vars_[index]->Value(); + const int64_t val = vars_[index]->Value(); for (int j = 0; j < size(); ++j) { if (index != j) { if (vars_[j]->Size() < 0xFFFFFF) { @@ -114,7 +115,7 @@ bool ValueAllDifferent::AllMoves() { return false; } } - std::unique_ptr values(new int64[size()]); + std::unique_ptr values(new int64_t[size()]); for (int i = 0; i < size(); ++i) { values[i] = vars_[i]->Value(); } @@ -135,8 +136,8 @@ bool ValueAllDifferent::AllMoves() { class RangeBipartiteMatching { public: struct Interval { - int64 min; - int64 max; + int64_t min; + int64_t max; int min_rank; int max_rank; }; @@ -147,9 +148,9 @@ class RangeBipartiteMatching { intervals_(new Interval[size + 1]), min_sorted_(new Interval*[size]), max_sorted_(new Interval*[size]), - bounds_(new int64[2 * size + 2]), + bounds_(new int64_t[2 * size + 2]), tree_(new int[2 * size + 2]), - diff_(new int64[2 * size + 2]), + diff_(new int64_t[2 * size + 2]), hall_(new int[2 * size + 2]), active_size_(0) { for (int i = 0; i < size; ++i) { @@ -158,7 +159,7 @@ class RangeBipartiteMatching { } } - void SetRange(int index, int64 imin, int64 imax) { + void SetRange(int index, int64_t imin, int64_t imax) { intervals_[index].min = imin; intervals_[index].max = imax; } @@ -171,9 +172,9 @@ class RangeBipartiteMatching { return modified1 || modified2; } - int64 Min(int index) const { return intervals_[index].min; } + int64_t Min(int index) const { return intervals_[index].min; } - int64 Max(int index) const { return intervals_[index].max; } + int64_t Max(int index) const { return intervals_[index].max; } private: // This method sorts the min_sorted_ and max_sorted_ arrays and fill @@ -184,9 +185,9 @@ class RangeBipartiteMatching { std::sort(max_sorted_.get(), max_sorted_.get() + size_, CompareIntervalMax()); - int64 min = min_sorted_[0]->min; - int64 max = max_sorted_[0]->max + 1; - int64 last = min - 2; + int64_t min = min_sorted_[0]->min; + int64_t max = max_sorted_[0]->max + 1; + int64_t last = min - 2; bounds_[0] = last; int i = 0; @@ -343,10 +344,10 @@ class RangeBipartiteMatching { std::unique_ptr max_sorted_; // bounds_[1..active_size_] hold set of min & max in the n intervals_ // while bounds_[0] and bounds_[active_size_ + 1] allow sentinels. - std::unique_ptr bounds_; - std::unique_ptr tree_; // tree links. - std::unique_ptr diff_; // diffs between critical capacities. - std::unique_ptr hall_; // hall interval links. + std::unique_ptr bounds_; + std::unique_ptr tree_; // tree links. + std::unique_ptr diff_; // diffs between critical capacities. + std::unique_ptr hall_; // hall interval links. int active_size_; }; @@ -393,7 +394,7 @@ class BoundsAllDifferent : public BaseAllDifferent { } void PropagateValue(int index) { - const int64 to_remove = vars_[index]->Value(); + const int64_t to_remove = vars_[index]->Value(); for (int j = 0; j < index; j++) { if (vars_[j]->Size() < 0xFFFFFF) { vars_[j]->RemoveValue(to_remove); @@ -451,8 +452,8 @@ class SortConstraint : public Constraint { void InitialPropagate() override { for (int i = 0; i < size(); ++i) { - int64 vmin = 0; - int64 vmax = 0; + int64_t vmin = 0; + int64_t vmax = 0; ovars_[i]->Range(&vmin, &vmax); mins_[i] = vmin; maxs_[i] = vmax; @@ -472,15 +473,15 @@ class SortConstraint : public Constraint { } // Reverse propagation. for (int i = 0; i < size(); ++i) { - int64 imin = 0; - int64 imax = 0; + int64_t imin = 0; + int64_t imax = 0; FindIntersectionRange(i, &imin, &imax); matching_.SetRange(i, imin, imax); } matching_.Propagate(); for (int i = 0; i < size(); ++i) { - const int64 vmin = svars_[matching_.Min(i)]->Min(); - const int64 vmax = svars_[matching_.Max(i)]->Max(); + const int64_t vmin = svars_[matching_.Min(i)]->Min(); + const int64_t vmax = svars_[matching_.Max(i)]->Max(); ovars_[i]->SetRange(vmin, vmax); } } @@ -500,20 +501,20 @@ class SortConstraint : public Constraint { } private: - int64 size() const { return ovars_.size(); } + int64_t size() const { return ovars_.size(); } - void FindIntersectionRange(int index, int64* const range_min, - int64* const range_max) const { + void FindIntersectionRange(int index, int64_t* const range_min, + int64_t* const range_max) const { // Naive version. // TODO(user): Implement log(n) version. - int64 imin = 0; + int64_t imin = 0; while (imin < size() && NotIntersect(index, imin)) { imin++; } if (imin == size()) { solver()->Fail(); } - int64 imax = size() - 1; + int64_t imax = size() - 1; while (imax > imin && NotIntersect(index, imax)) { imax--; } @@ -528,8 +529,8 @@ class SortConstraint : public Constraint { const std::vector ovars_; const std::vector svars_; - std::vector mins_; - std::vector maxs_; + std::vector mins_; + std::vector maxs_; RangeBipartiteMatching matching_; }; @@ -538,7 +539,7 @@ class SortConstraint : public Constraint { class AllDifferentExcept : public Constraint { public: AllDifferentExcept(Solver* const s, std::vector vars, - int64 escape_value) + int64_t escape_value) : Constraint(s), vars_(std::move(vars)), escape_value_(escape_value) {} ~AllDifferentExcept() override {} @@ -561,7 +562,7 @@ class AllDifferentExcept : public Constraint { } void Propagate(int index) { - const int64 val = vars_[index]->Value(); + const int64_t val = vars_[index]->Value(); if (val != escape_value_) { for (int j = 0; j < vars_.size(); ++j) { if (index != j) { @@ -586,7 +587,7 @@ class AllDifferentExcept : public Constraint { private: std::vector vars_; - const int64 escape_value_; + const int64_t escape_value_; }; // Creates a constraint that states that all variables in the first @@ -597,7 +598,8 @@ class AllDifferentExcept : public Constraint { class NullIntersectArrayExcept : public Constraint { public: NullIntersectArrayExcept(Solver* const s, std::vector first_vars, - std::vector second_vars, int64 escape_value) + std::vector second_vars, + int64_t escape_value) : Constraint(s), first_vars_(std::move(first_vars)), second_vars_(std::move(second_vars)), @@ -645,7 +647,7 @@ class NullIntersectArrayExcept : public Constraint { } void PropagateFirst(int index) { - const int64 val = first_vars_[index]->Value(); + const int64_t val = first_vars_[index]->Value(); if (!has_escape_value_ || val != escape_value_) { for (int j = 0; j < second_vars_.size(); ++j) { second_vars_[j]->RemoveValue(val); @@ -654,7 +656,7 @@ class NullIntersectArrayExcept : public Constraint { } void PropagateSecond(int index) { - const int64 val = second_vars_[index]->Value(); + const int64_t val = second_vars_[index]->Value(); if (!has_escape_value_ || val != escape_value_) { for (int j = 0; j < first_vars_.size(); ++j) { first_vars_[j]->RemoveValue(val); @@ -682,7 +684,7 @@ class NullIntersectArrayExcept : public Constraint { private: std::vector first_vars_; std::vector second_vars_; - const int64 escape_value_; + const int64_t escape_value_; const bool has_escape_value_; }; } // namespace @@ -718,7 +720,7 @@ Constraint* Solver::MakeSortingConstraint(const std::vector& vars, } Constraint* Solver::MakeAllDifferentExcept(const std::vector& vars, - int64 escape_value) { + int64_t escape_value) { int escape_candidates = 0; for (int i = 0; i < vars.size(); ++i) { escape_candidates += (vars[i]->Contains(escape_value)); @@ -737,7 +739,7 @@ Constraint* Solver::MakeNullIntersect(const std::vector& first_vars, Constraint* Solver::MakeNullIntersectExcept( const std::vector& first_vars, - const std::vector& second_vars, int64 escape_value) { + const std::vector& second_vars, int64_t escape_value) { int first_escape_candidates = 0; for (int i = 0; i < first_vars.size(); ++i) { first_escape_candidates += (first_vars[i]->Contains(escape_value)); diff --git a/ortools/constraint_solver/assignment.cc b/ortools/constraint_solver/assignment.cc index 8b521b849f..772cd94d69 100644 --- a/ortools/constraint_solver/assignment.cc +++ b/ortools/constraint_solver/assignment.cc @@ -13,6 +13,8 @@ #include +#include +#include #include #include @@ -40,8 +42,8 @@ IntVarElement::IntVarElement(IntVar* const var) { Reset(var); } void IntVarElement::Reset(IntVar* const var) { var_ = var; - min_ = kint64min; - max_ = kint64max; + min_ = std::numeric_limits::min(); + max_ = std::numeric_limits::max(); } IntVarElement* IntVarElement::Clone() { @@ -114,12 +116,12 @@ IntervalVarElement::IntervalVarElement(IntervalVar* const var) { Reset(var); } void IntervalVarElement::Reset(IntervalVar* const var) { var_ = var; - start_min_ = kint64min; - start_max_ = kint64max; - duration_min_ = kint64min; - duration_max_ = kint64max; - end_min_ = kint64min; - end_max_ = kint64max; + start_min_ = std::numeric_limits::min(); + start_max_ = std::numeric_limits::max(); + duration_min_ = std::numeric_limits::min(); + duration_max_ = std::numeric_limits::max(); + end_min_ = std::numeric_limits::min(); + end_max_ = std::numeric_limits::max(); performed_min_ = 0; performed_max_ = 1; } @@ -144,8 +146,8 @@ void IntervalVarElement::Copy(const IntervalVarElement& element) { } void IntervalVarElement::Store() { - performed_min_ = static_cast(var_->MustBePerformed()); - performed_max_ = static_cast(var_->MayBePerformed()); + performed_min_ = static_cast(var_->MustBePerformed()); + performed_max_ = static_cast(var_->MayBePerformed()); if (performed_max_ != 0LL) { start_min_ = var_->StartMin(); start_max_ = var_->StartMax(); @@ -281,15 +283,16 @@ void SequenceVarElement::Restore() { void SequenceVarElement::LoadFromProto( const SequenceVarAssignment& sequence_var_assignment_proto) { - for (const int32 forward_sequence : + for (const int32_t forward_sequence : sequence_var_assignment_proto.forward_sequence()) { forward_sequence_.push_back(forward_sequence); } - for (const int32 backward_sequence : + for (const int32_t backward_sequence : sequence_var_assignment_proto.backward_sequence()) { backward_sequence_.push_back(backward_sequence); } - for (const int32 unperformed : sequence_var_assignment_proto.unperformed()) { + for (const int32_t unperformed : + sequence_var_assignment_proto.unperformed()) { unperformed_.push_back(unperformed); } if (sequence_var_assignment_proto.active()) { @@ -542,8 +545,8 @@ void Assignment::Load(const AssignmentProto& assignment_proto) { const std::string& objective_id = objective.var_id(); CHECK(!objective_id.empty()); if (HasObjective() && objective_id == Objective()->name()) { - const int64 obj_min = objective.min(); - const int64 obj_max = objective.max(); + const int64_t obj_min = objective.min(); + const int64_t obj_max = objective.max(); SetObjectiveRange(obj_min, obj_max); if (objective.active()) { ActivateObjective(); @@ -601,8 +604,8 @@ void Assignment::Save(AssignmentProto* const assignment_proto) const { if (!name.empty()) { IntVarAssignment* objective = assignment_proto->mutable_objective(); objective->set_var_id(name); - const int64 obj_min = ObjectiveMin(); - const int64 obj_max = ObjectiveMax(); + const int64_t obj_min = ObjectiveMin(); + const int64_t obj_max = ObjectiveMax(); objective->set_min(obj_min); objective->set_max(obj_max); objective->set_active(ActivatedObjective()); @@ -648,15 +651,15 @@ IntVarElement* Assignment::FastAdd(IntVar* const var) { return int_var_container_.FastAdd(var); } -int64 Assignment::Min(const IntVar* const var) const { +int64_t Assignment::Min(const IntVar* const var) const { return int_var_container_.Element(var).Min(); } -int64 Assignment::Max(const IntVar* const var) const { +int64_t Assignment::Max(const IntVar* const var) const { return int_var_container_.Element(var).Max(); } -int64 Assignment::Value(const IntVar* const var) const { +int64_t Assignment::Value(const IntVar* const var) const { return int_var_container_.Element(var).Value(); } @@ -664,19 +667,19 @@ bool Assignment::Bound(const IntVar* const var) const { return int_var_container_.Element(var).Bound(); } -void Assignment::SetMin(const IntVar* const var, int64 m) { +void Assignment::SetMin(const IntVar* const var, int64_t m) { int_var_container_.MutableElement(var)->SetMin(m); } -void Assignment::SetMax(const IntVar* const var, int64 m) { +void Assignment::SetMax(const IntVar* const var, int64_t m) { int_var_container_.MutableElement(var)->SetMax(m); } -void Assignment::SetRange(const IntVar* const var, int64 l, int64 u) { +void Assignment::SetRange(const IntVar* const var, int64_t l, int64_t u) { int_var_container_.MutableElement(var)->SetRange(l, u); } -void Assignment::SetValue(const IntVar* const var, int64 value) { +void Assignment::SetValue(const IntVar* const var, int64_t value) { int_var_container_.MutableElement(var)->SetValue(value); } @@ -696,118 +699,120 @@ IntervalVarElement* Assignment::FastAdd(IntervalVar* const var) { return interval_var_container_.FastAdd(var); } -int64 Assignment::StartMin(const IntervalVar* const var) const { +int64_t Assignment::StartMin(const IntervalVar* const var) const { return interval_var_container_.Element(var).StartMin(); } -int64 Assignment::StartMax(const IntervalVar* const var) const { +int64_t Assignment::StartMax(const IntervalVar* const var) const { return interval_var_container_.Element(var).StartMax(); } -int64 Assignment::StartValue(const IntervalVar* const var) const { +int64_t Assignment::StartValue(const IntervalVar* const var) const { return interval_var_container_.Element(var).StartValue(); } -int64 Assignment::DurationMin(const IntervalVar* const var) const { +int64_t Assignment::DurationMin(const IntervalVar* const var) const { return interval_var_container_.Element(var).DurationMin(); } -int64 Assignment::DurationMax(const IntervalVar* const var) const { +int64_t Assignment::DurationMax(const IntervalVar* const var) const { return interval_var_container_.Element(var).DurationMax(); } -int64 Assignment::DurationValue(const IntervalVar* const var) const { +int64_t Assignment::DurationValue(const IntervalVar* const var) const { return interval_var_container_.Element(var).DurationValue(); } -int64 Assignment::EndMin(const IntervalVar* const var) const { +int64_t Assignment::EndMin(const IntervalVar* const var) const { return interval_var_container_.Element(var).EndMin(); } -int64 Assignment::EndMax(const IntervalVar* const var) const { +int64_t Assignment::EndMax(const IntervalVar* const var) const { return interval_var_container_.Element(var).EndMax(); } -int64 Assignment::EndValue(const IntervalVar* const var) const { +int64_t Assignment::EndValue(const IntervalVar* const var) const { return interval_var_container_.Element(var).EndValue(); } -int64 Assignment::PerformedMin(const IntervalVar* const var) const { +int64_t Assignment::PerformedMin(const IntervalVar* const var) const { return interval_var_container_.Element(var).PerformedMin(); } -int64 Assignment::PerformedMax(const IntervalVar* const var) const { +int64_t Assignment::PerformedMax(const IntervalVar* const var) const { return interval_var_container_.Element(var).PerformedMax(); } -int64 Assignment::PerformedValue(const IntervalVar* const var) const { +int64_t Assignment::PerformedValue(const IntervalVar* const var) const { return interval_var_container_.Element(var).PerformedValue(); } -void Assignment::SetStartMin(const IntervalVar* const var, int64 m) { +void Assignment::SetStartMin(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetStartMin(m); } -void Assignment::SetStartMax(const IntervalVar* const var, int64 m) { +void Assignment::SetStartMax(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetStartMax(m); } -void Assignment::SetStartRange(const IntervalVar* const var, int64 mi, - int64 ma) { +void Assignment::SetStartRange(const IntervalVar* const var, int64_t mi, + int64_t ma) { interval_var_container_.MutableElement(var)->SetStartRange(mi, ma); } -void Assignment::SetStartValue(const IntervalVar* const var, int64 value) { +void Assignment::SetStartValue(const IntervalVar* const var, int64_t value) { interval_var_container_.MutableElement(var)->SetStartValue(value); } -void Assignment::SetDurationMin(const IntervalVar* const var, int64 m) { +void Assignment::SetDurationMin(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetDurationMin(m); } -void Assignment::SetDurationMax(const IntervalVar* const var, int64 m) { +void Assignment::SetDurationMax(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetDurationMax(m); } -void Assignment::SetDurationRange(const IntervalVar* const var, int64 mi, - int64 ma) { +void Assignment::SetDurationRange(const IntervalVar* const var, int64_t mi, + int64_t ma) { interval_var_container_.MutableElement(var)->SetDurationRange(mi, ma); } -void Assignment::SetDurationValue(const IntervalVar* const var, int64 value) { +void Assignment::SetDurationValue(const IntervalVar* const var, int64_t value) { interval_var_container_.MutableElement(var)->SetDurationValue(value); } -void Assignment::SetEndMin(const IntervalVar* const var, int64 m) { +void Assignment::SetEndMin(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetEndMin(m); } -void Assignment::SetEndMax(const IntervalVar* const var, int64 m) { +void Assignment::SetEndMax(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetEndMax(m); } -void Assignment::SetEndRange(const IntervalVar* const var, int64 mi, int64 ma) { +void Assignment::SetEndRange(const IntervalVar* const var, int64_t mi, + int64_t ma) { interval_var_container_.MutableElement(var)->SetEndRange(mi, ma); } -void Assignment::SetEndValue(const IntervalVar* const var, int64 value) { +void Assignment::SetEndValue(const IntervalVar* const var, int64_t value) { interval_var_container_.MutableElement(var)->SetEndValue(value); } -void Assignment::SetPerformedMin(const IntervalVar* const var, int64 m) { +void Assignment::SetPerformedMin(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetPerformedMin(m); } -void Assignment::SetPerformedMax(const IntervalVar* const var, int64 m) { +void Assignment::SetPerformedMax(const IntervalVar* const var, int64_t m) { interval_var_container_.MutableElement(var)->SetPerformedMax(m); } -void Assignment::SetPerformedRange(const IntervalVar* const var, int64 mi, - int64 ma) { +void Assignment::SetPerformedRange(const IntervalVar* const var, int64_t mi, + int64_t ma) { interval_var_container_.MutableElement(var)->SetPerformedRange(mi, ma); } -void Assignment::SetPerformedValue(const IntervalVar* const var, int64 value) { +void Assignment::SetPerformedValue(const IntervalVar* const var, + int64_t value) { interval_var_container_.MutableElement(var)->SetPerformedValue(value); } @@ -877,21 +882,21 @@ void Assignment::AddObjective(IntVar* const v) { IntVar* Assignment::Objective() const { return objective_element_.Var(); } -int64 Assignment::ObjectiveMin() const { +int64_t Assignment::ObjectiveMin() const { if (HasObjective()) { return objective_element_.Min(); } return 0; } -int64 Assignment::ObjectiveMax() const { +int64_t Assignment::ObjectiveMax() const { if (HasObjective()) { return objective_element_.Max(); } return 0; } -int64 Assignment::ObjectiveValue() const { +int64_t Assignment::ObjectiveValue() const { if (HasObjective()) { return objective_element_.Value(); } @@ -905,25 +910,25 @@ bool Assignment::ObjectiveBound() const { return true; } -void Assignment::SetObjectiveMin(int64 m) { +void Assignment::SetObjectiveMin(int64_t m) { if (HasObjective()) { objective_element_.SetMin(m); } } -void Assignment::SetObjectiveMax(int64 m) { +void Assignment::SetObjectiveMax(int64_t m) { if (HasObjective()) { objective_element_.SetMax(m); } } -void Assignment::SetObjectiveRange(int64 l, int64 u) { +void Assignment::SetObjectiveRange(int64_t l, int64_t u) { if (HasObjective()) { objective_element_.SetRange(l, u); } } -void Assignment::SetObjectiveValue(int64 value) { +void Assignment::SetObjectiveValue(int64_t value) { if (HasObjective()) { objective_element_.SetValue(value); } diff --git a/ortools/constraint_solver/constraint_solver.cc b/ortools/constraint_solver/constraint_solver.cc index 08d4a170b8..d8c53cbbb0 100644 --- a/ortools/constraint_solver/constraint_solver.cc +++ b/ortools/constraint_solver/constraint_solver.cc @@ -18,8 +18,10 @@ #include "ortools/constraint_solver/constraint_solver.h" #include +#include #include #include +#include #include #include #include @@ -35,6 +37,7 @@ #include "ortools/base/map_util.h" #include "ortools/base/recordio.h" #include "ortools/base/stl_util.h" +#include "ortools/base/sysinfo.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/util/tuple_set.h" #include "zlib.h" @@ -87,7 +90,7 @@ ABSL_FLAG(bool, cp_use_element_rmq, true, ABSL_FLAG(int, cp_check_solution_period, 1, "Number of solutions explored between two solution checks during " "local search."); -ABSL_FLAG(int64, cp_random_seed, 12345, +ABSL_FLAG(int64_t, cp_random_seed, 12345, "Random seed used in several (but not all) random number " "generators used by the CP solver. Use -1 to auto-generate an" "undeterministic random seed."); @@ -197,13 +200,13 @@ Solver::DemonPriority Demon::priority() const { std::string Demon::DebugString() const { return "Demon"; } void Demon::inhibit(Solver* const s) { - if (stamp_ < kuint64max) { - s->SaveAndSetValue(&stamp_, kuint64max); + if (stamp_ < std::numeric_limits::max()) { + s->SaveAndSetValue(&stamp_, std::numeric_limits::max()); } } void Demon::desinhibit(Solver* const s) { - if (stamp_ == kuint64max) { + if (stamp_ == std::numeric_limits::max()) { s->SaveAndSetValue(&stamp_, s->stamp() - 1); } } @@ -214,7 +217,7 @@ extern void CleanVariableOnFail(IntVar* const var); class Queue { public: - static constexpr int64 kTestPeriod = 10000; + static constexpr int64_t kTestPeriod = 10000; explicit Queue(Solver* const s) : solver_(s), @@ -356,7 +359,7 @@ class Queue { void increase_stamp() { stamp_++; } - uint64 stamp() const { return stamp_; } + uint64_t stamp() const { return stamp_; } void set_action_on_fail(Solver::Action a) { DCHECK(clean_variable_ == nullptr); @@ -398,10 +401,10 @@ class Queue { Solver* const solver_; std::deque var_queue_; std::deque delayed_queue_; - uint64 stamp_; + uint64_t stamp_; // The number of nested freeze levels. The queue is frozen if and only if // freeze_level_ > 0. - uint32 freeze_level_; + uint32_t freeze_level_; bool in_process_; Solver::Action clean_action_; IntVar* clean_variable_; @@ -582,7 +585,7 @@ class ZlibTrailPacker : public TrailPacker { } private: - const uint64 tmp_size_; + const uint64_t tmp_size_; std::unique_ptr tmp_block_; DISALLOW_COPY_AND_ASSIGN(ZlibTrailPacker); }; @@ -666,7 +669,7 @@ class CompressedTrail { ++current_; ++size_; } - int64 size() const { return size_; } + int64_t size() const { return size_; } private: struct Block { @@ -722,15 +725,15 @@ extern void RestoreBoolValue(IntVar* const var); struct Trail { CompressedTrail rev_ints_; - CompressedTrail rev_int64s_; - CompressedTrail rev_uint64s_; + CompressedTrail rev_int64s_; + CompressedTrail rev_uint64s_; CompressedTrail rev_doubles_; CompressedTrail rev_ptrs_; std::vector rev_boolvar_list_; std::vector rev_bools_; std::vector rev_bool_value_; std::vector rev_int_memory_; - std::vector rev_int64_memory_; + std::vector rev_int64_memory_; std::vector rev_double_memory_; std::vector rev_object_memory_; std::vector rev_object_array_memory_; @@ -756,7 +759,7 @@ struct Trail { // Incorrect trail size after backtrack. target = m->rev_int64_index_; for (int curr = rev_int64s_.size(); curr > target; --curr) { - const addrval& cell = rev_int64s_.Back(); + const addrval& cell = rev_int64s_.Back(); cell.restore(); rev_int64s_.PopBack(); } @@ -764,7 +767,7 @@ struct Trail { // Incorrect trail size after backtrack. target = m->rev_uint64_index_; for (int curr = rev_uint64s_.size(); curr > target; --curr) { - const addrval& cell = rev_uint64s_.Back(); + const addrval& cell = rev_uint64s_.Back(); cell.restore(); rev_uint64s_.PopBack(); } @@ -857,12 +860,12 @@ void Solver::InternalSaveValue(int* valptr) { trail_->rev_ints_.PushBack(addrval(valptr)); } -void Solver::InternalSaveValue(int64* valptr) { - trail_->rev_int64s_.PushBack(addrval(valptr)); +void Solver::InternalSaveValue(int64_t* valptr) { + trail_->rev_int64s_.PushBack(addrval(valptr)); } -void Solver::InternalSaveValue(uint64* valptr) { - trail_->rev_uint64s_.PushBack(addrval(valptr)); +void Solver::InternalSaveValue(uint64_t* valptr) { + trail_->rev_uint64s_.PushBack(addrval(valptr)); } void Solver::InternalSaveValue(double* valptr) { @@ -893,7 +896,7 @@ int* Solver::SafeRevAllocArray(int* ptr) { return ptr; } -int64* Solver::SafeRevAllocArray(int64* ptr) { +int64_t* Solver::SafeRevAllocArray(int64_t* ptr) { check_alloc_state(); trail_->rev_int64_memory_.push_back(ptr); return ptr; @@ -905,9 +908,9 @@ double* Solver::SafeRevAllocArray(double* ptr) { return ptr; } -uint64* Solver::SafeRevAllocArray(uint64* ptr) { +uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) { check_alloc_state(); - trail_->rev_int64_memory_.push_back(reinterpret_cast(ptr)); + trail_->rev_int64_memory_.push_back(reinterpret_cast(ptr)); return ptr; } @@ -1015,9 +1018,9 @@ class Search { void push_monitor(SearchMonitor* const m); void Clear(); void IncrementSolutionCounter() { ++solution_counter_; } - int64 solution_counter() const { return solution_counter_; } + int64_t solution_counter() const { return solution_counter_; } void IncrementUncheckedSolutionCounter() { ++unchecked_solution_counter_; } - int64 unchecked_solution_counter() const { + int64_t unchecked_solution_counter() const { return unchecked_solution_counter_; } void set_decision_builder(DecisionBuilder* const db) { @@ -1070,8 +1073,8 @@ class Search { std::vector marker_stack_; std::vector monitors_; jmp_buf fail_buffer_; - int64 solution_counter_; - int64 unchecked_solution_counter_; + int64_t solution_counter_; + int64_t unchecked_solution_counter_; DecisionBuilder* decision_builder_; bool created_by_solve_; Solver::BranchSelector selector_; @@ -1515,9 +1518,9 @@ std::string Solver::DebugString() const { return out; } -int64 Solver::MemoryUsage() { return GetProcessMemoryUsage(); } +int64_t Solver::MemoryUsage() { return GetProcessMemoryUsage(); } -int64 Solver::wall_time() const { +int64_t Solver::wall_time() const { return absl::ToInt64Milliseconds(timer_->GetDuration()); } @@ -1525,9 +1528,11 @@ absl::Time Solver::Now() const { return absl::FromUnixSeconds(0) + timer_->GetDuration(); } -int64 Solver::solutions() const { return TopLevelSearch()->solution_counter(); } +int64_t Solver::solutions() const { + return TopLevelSearch()->solution_counter(); +} -int64 Solver::unchecked_solutions() const { +int64_t Solver::unchecked_solutions() const { return TopLevelSearch()->unchecked_solution_counter(); } @@ -1640,9 +1645,9 @@ void Solver::EnqueueAll(const SimpleRevFIFO& demons) { queue_->EnqueueAll(demons); } -uint64 Solver::stamp() const { return queue_->stamp(); } +uint64_t Solver::stamp() const { return queue_->stamp(); } -uint64 Solver::fail_stamp() const { return fail_stamp_; } +uint64_t Solver::fail_stamp() const { return fail_stamp_; } void Solver::set_action_on_fail(Action a) { queue_->set_action_on_fail(std::move(a)); @@ -2537,14 +2542,14 @@ void Decision::Accept(DecisionVisitor* const visitor) const { visitor->VisitUnknownDecision(); } -void DecisionVisitor::VisitSetVariableValue(IntVar* const var, int64 value) {} -void DecisionVisitor::VisitSplitVariableDomain(IntVar* const var, int64 value, +void DecisionVisitor::VisitSetVariableValue(IntVar* const var, int64_t value) {} +void DecisionVisitor::VisitSplitVariableDomain(IntVar* const var, int64_t value, bool lower) {} void DecisionVisitor::VisitUnknownDecision() {} void DecisionVisitor::VisitScheduleOrPostpone(IntervalVar* const var, - int64 est) {} + int64_t est) {} void DecisionVisitor::VisitScheduleOrExpedite(IntervalVar* const var, - int64 est) {} + int64_t est) {} void DecisionVisitor::VisitRankFirstInterval(SequenceVar* const sequence, int index) {} @@ -2756,7 +2761,7 @@ void ModelVisitor::VisitIntegerVariable(const IntVar* const variable, void ModelVisitor::VisitIntegerVariable(const IntVar* const variable, const std::string& operation, - int64 value, IntVar* const delegate) { + int64_t value, IntVar* const delegate) { if (delegate != nullptr) { delegate->Accept(this); } @@ -2764,7 +2769,7 @@ void ModelVisitor::VisitIntegerVariable(const IntVar* const variable, void ModelVisitor::VisitIntervalVariable(const IntervalVar* const variable, const std::string& operation, - int64 value, + int64_t value, IntervalVar* const delegate) { if (delegate != nullptr) { delegate->Accept(this); @@ -2778,11 +2783,10 @@ void ModelVisitor::VisitSequenceVariable(const SequenceVar* const variable) { } void ModelVisitor::VisitIntegerArgument(const std::string& arg_name, - int64 value) {} + int64_t value) {} -void ModelVisitor::VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) { -} +void ModelVisitor::VisitIntegerArrayArgument( + const std::string& arg_name, const std::vector& values) {} void ModelVisitor::VisitIntegerMatrixArgument(const std::string& arg_name, const IntTupleSet& tuples) {} @@ -2823,9 +2827,10 @@ void ModelVisitor::VisitSequenceArrayArgument( // ----- Helpers ----- void ModelVisitor::VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, - int64 index_min, int64 index_max) { + int64_t index_min, + int64_t index_max) { if (filter != nullptr) { - std::vector cached_results; + std::vector cached_results; for (int i = index_min; i <= index_max; ++i) { cached_results.push_back(filter(i)); } @@ -2838,9 +2843,9 @@ void ModelVisitor::VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, } void ModelVisitor::VisitInt64ToInt64Extension( - const Solver::IndexEvaluator1& eval, int64 index_min, int64 index_max) { + const Solver::IndexEvaluator1& eval, int64_t index_min, int64_t index_max) { CHECK(eval != nullptr); - std::vector cached_results; + std::vector cached_results; for (int i = index_min; i <= index_max; ++i) { cached_results.push_back(eval(i)); } @@ -2853,9 +2858,9 @@ void ModelVisitor::VisitInt64ToInt64Extension( void ModelVisitor::VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1& eval, const std::string& arg_name, - int64 index_max) { + int64_t index_max) { CHECK(eval != nullptr); - std::vector cached_results; + std::vector cached_results; for (int i = 0; i <= index_max; ++i) { cached_results.push_back(eval(i)); } @@ -2980,102 +2985,104 @@ class Trace : public PropagationMonitor { } // IntExpr modifiers. - void SetMin(IntExpr* const expr, int64 new_min) override { + void SetMin(IntExpr* const expr, int64_t new_min) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetMin(expr, new_min); } } - void SetMax(IntExpr* const expr, int64 new_max) override { + void SetMax(IntExpr* const expr, int64_t new_max) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetMax(expr, new_max); } } - void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) override { + void SetRange(IntExpr* const expr, int64_t new_min, + int64_t new_max) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetRange(expr, new_min, new_max); } } // IntVar modifiers. - void SetMin(IntVar* const var, int64 new_min) override { + void SetMin(IntVar* const var, int64_t new_min) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetMin(var, new_min); } } - void SetMax(IntVar* const var, int64 new_max) override { + void SetMax(IntVar* const var, int64_t new_max) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetMax(var, new_max); } } - void SetRange(IntVar* const var, int64 new_min, int64 new_max) override { + void SetRange(IntVar* const var, int64_t new_min, int64_t new_max) override { for (PropagationMonitor* const monitor : monitors_) { monitor->SetRange(var, new_min, new_max); } } - void RemoveValue(IntVar* const var, int64 value) override { + void RemoveValue(IntVar* const var, int64_t value) override { ForAll(monitors_, &PropagationMonitor::RemoveValue, var, value); } - void SetValue(IntVar* const var, int64 value) override { + void SetValue(IntVar* const var, int64_t value) override { ForAll(monitors_, &PropagationMonitor::SetValue, var, value); } - void RemoveInterval(IntVar* const var, int64 imin, int64 imax) override { + void RemoveInterval(IntVar* const var, int64_t imin, int64_t imax) override { ForAll(monitors_, &PropagationMonitor::RemoveInterval, var, imin, imax); } - void SetValues(IntVar* const var, const std::vector& values) override { + void SetValues(IntVar* const var, + const std::vector& values) override { ForAll(monitors_, &PropagationMonitor::SetValues, var, values); } void RemoveValues(IntVar* const var, - const std::vector& values) override { + const std::vector& values) override { ForAll(monitors_, &PropagationMonitor::RemoveValues, var, values); } // IntervalVar modifiers. - void SetStartMin(IntervalVar* const var, int64 new_min) override { + void SetStartMin(IntervalVar* const var, int64_t new_min) override { ForAll(monitors_, &PropagationMonitor::SetStartMin, var, new_min); } - void SetStartMax(IntervalVar* const var, int64 new_max) override { + void SetStartMax(IntervalVar* const var, int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetStartMax, var, new_max); } - void SetStartRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetStartRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetStartRange, var, new_min, new_max); } - void SetEndMin(IntervalVar* const var, int64 new_min) override { + void SetEndMin(IntervalVar* const var, int64_t new_min) override { ForAll(monitors_, &PropagationMonitor::SetEndMin, var, new_min); } - void SetEndMax(IntervalVar* const var, int64 new_max) override { + void SetEndMax(IntervalVar* const var, int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetEndMax, var, new_max); } - void SetEndRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetEndRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetEndRange, var, new_min, new_max); } - void SetDurationMin(IntervalVar* const var, int64 new_min) override { + void SetDurationMin(IntervalVar* const var, int64_t new_min) override { ForAll(monitors_, &PropagationMonitor::SetDurationMin, var, new_min); } - void SetDurationMax(IntervalVar* const var, int64 new_max) override { + void SetDurationMax(IntervalVar* const var, int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetDurationMax, var, new_max); } - void SetDurationRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetDurationRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { ForAll(monitors_, &PropagationMonitor::SetDurationRange, var, new_min, new_max); } diff --git a/ortools/constraint_solver/constraint_solver.h b/ortools/constraint_solver/constraint_solver.h index d5b492685b..200c316984 100644 --- a/ortools/constraint_solver/constraint_solver.h +++ b/ortools/constraint_solver/constraint_solver.h @@ -68,29 +68,31 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_ +#include +#include + +#include #include -#include #include #include #include +#include #include #include -#include "absl/base/macros.h" +#include "absl/base/log_severity.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" -#include "absl/random/distributions.h" +#include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/random/random.h" #include "absl/strings/str_format.h" -#include "ortools/base/commandlineflags.h" -#include "ortools/base/hash.h" +#include "absl/time/time.h" #include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" #include "ortools/base/map_util.h" -#include "ortools/base/sysinfo.h" #include "ortools/base/timer.h" -#include "ortools/constraint_solver/routing_parameters.pb.h" #include "ortools/constraint_solver/search_stats.pb.h" #include "ortools/constraint_solver/solver_parameters.pb.h" #include "ortools/util/piecewise_linear_function.h" @@ -98,7 +100,7 @@ #include "ortools/util/tuple_set.h" #if !defined(SWIG) -ABSL_DECLARE_FLAG(int64, cp_random_seed); +ABSL_DECLARE_FLAG(int64_t, cp_random_seed); #endif // !defined(SWIG) class File; @@ -108,11 +110,6 @@ namespace operations_research { class Assignment; class AssignmentProto; class BaseObject; -class CpArgument; -class CpConstraint; -class CpIntegerExpression; -class CpIntervalVariable; -class CpSequenceVariable; class CastConstraint; class Constraint; class Decision; @@ -120,54 +117,47 @@ class DecisionBuilder; class DecisionVisitor; class Demon; class DemonProfiler; -class LocalSearchProfiler; class Dimension; class DisjunctiveConstraint; -class ExpressionCache; +class ImprovementSearchLimit; class IntExpr; -class IntTupleSet; class IntVar; class IntVarAssignment; -class IntVarElement; +class IntVarLocalSearchFilter; class IntervalVar; class IntervalVarAssignment; -class IntervalVarElement; -class IntVarLocalSearchFilter; class LocalSearchFilter; class LocalSearchFilterManager; +class LocalSearchMonitor; class LocalSearchOperator; class LocalSearchPhaseParameters; +class LocalSearchProfiler; class ModelCache; class ModelVisitor; class OptimizeVar; class Pack; class PropagationBaseObject; class PropagationMonitor; -class LocalSearchMonitor; class Queue; -class RevBitMatrix; -class RevBitSet; class RegularLimit; class RegularLimitParameters; +class RevBitMatrix; class Search; -class ImprovementSearchLimit; class SearchLimit; class SearchMonitor; class SequenceVar; class SequenceVarAssignment; class SolutionCollector; class SolutionPool; -class Solver; -class ConstraintSolverParameters; class SymmetryBreaker; struct StateInfo; struct Trail; template class SimpleRevFIFO; -inline int64 CpRandomSeed() { +inline int64_t CpRandomSeed() { return absl::GetFlag(FLAGS_cp_random_seed) == -1 - ? absl::Uniform(absl::BitGen(), 0, kint64max) + ? absl::Uniform(absl::BitGen(), 0, kint64max) : absl::GetFlag(FLAGS_cp_random_seed); } @@ -740,20 +730,20 @@ class Solver { enum OptimizationDirection { NOT_SET, MAXIMIZATION, MINIMIZATION }; /// Callback typedefs - typedef std::function IndexEvaluator1; - typedef std::function IndexEvaluator2; - typedef std::function IndexEvaluator3; + typedef std::function IndexEvaluator1; + typedef std::function IndexEvaluator2; + typedef std::function IndexEvaluator3; - typedef std::function IndexFilter1; + typedef std::function IndexFilter1; - typedef std::function Int64ToIntVar; + typedef std::function Int64ToIntVar; - typedef std::function& vars, - int64 first_unbound, int64 last_unbound)> + typedef std::function& vars, + int64_t first_unbound, int64_t last_unbound)> VariableIndexSelector; - typedef std::function VariableValueSelector; - typedef std::function VariableValueComparator; + typedef std::function VariableValueSelector; + typedef std::function VariableValueComparator; typedef std::function BranchSelector; // TODO(user): wrap in swig. typedef std::function Action; @@ -801,7 +791,7 @@ class Solver { /// must have been allocated with the new[] operator. The entire array /// will be deleted when backtracking out of the current state. /// - /// This method is valid for arrays of int, int64, uint64, bool, + /// This method is valid for arrays of int, int64_t, uint64_t, bool, /// BaseObject*, IntVar*, IntExpr*, and Constraint*. template T* RevAllocArray(T* object) { @@ -971,7 +961,7 @@ class Solver { std::string DebugString() const; /// Current memory usage in bytes - static int64 MemoryUsage(); + static int64_t MemoryUsage(); /// The 'absolute time' as seen by the solver. Unless a user-provided clock /// was injected via SetClock() (eg. for unit tests), this is a real walltime, @@ -981,38 +971,38 @@ class Solver { /// DEPRECATED: Use Now() instead. /// Time elapsed, in ms since the creation of the solver. - int64 wall_time() const; + int64_t wall_time() const; /// The number of branches explored since the creation of the solver. - int64 branches() const { return branches_; } + int64_t branches() const { return branches_; } /// The number of solutions found since the start of the search. - int64 solutions() const; + int64_t solutions() const; /// The number of unchecked solutions found by local search. - int64 unchecked_solutions() const; + int64_t unchecked_solutions() const; /// The number of demons executed during search for a given priority. - int64 demon_runs(DemonPriority p) const { return demon_runs_[p]; } + int64_t demon_runs(DemonPriority p) const { return demon_runs_[p]; } /// The number of failures encountered since the creation of the solver. - int64 failures() const { return fails_; } + int64_t failures() const { return fails_; } /// The number of neighbors created. - int64 neighbors() const { return neighbors_; } + int64_t neighbors() const { return neighbors_; } /// The number of filtered neighbors (neighbors accepted by filters). - int64 filtered_neighbors() const { return filtered_neighbors_; } + int64_t filtered_neighbors() const { return filtered_neighbors_; } /// The number of accepted neighbors. - int64 accepted_neighbors() const { return accepted_neighbors_; } + int64_t accepted_neighbors() const { return accepted_neighbors_; } /// The stamp indicates how many moves in the search tree we have performed. /// It is useful to detect if we need to update same lazy structures. - uint64 stamp() const; + uint64_t stamp() const; /// The fail_stamp() is incremented after each backtrack. - uint64 fail_stamp() const; + uint64_t fail_stamp() const; /// The direction of optimization, getter and setter. OptimizationDirection optimization_direction() const { @@ -1031,19 +1021,19 @@ class Solver { // ----- Int Variables and Constants ----- /// MakeIntVar will create the best range based int var for the bounds given. - IntVar* MakeIntVar(int64 min, int64 max, const std::string& name); + IntVar* MakeIntVar(int64_t min, int64_t max, const std::string& name); /// MakeIntVar will create a variable with the given sparse domain. - IntVar* MakeIntVar(const std::vector& values, const std::string& name); + IntVar* MakeIntVar(const std::vector& values, const std::string& name); /// MakeIntVar will create a variable with the given sparse domain. IntVar* MakeIntVar(const std::vector& values, const std::string& name); /// MakeIntVar will create the best range based int var for the bounds given. - IntVar* MakeIntVar(int64 min, int64 max); + IntVar* MakeIntVar(int64_t min, int64_t max); /// MakeIntVar will create a variable with the given sparse domain. - IntVar* MakeIntVar(const std::vector& values); + IntVar* MakeIntVar(const std::vector& values); /// MakeIntVar will create a variable with the given sparse domain. IntVar* MakeIntVar(const std::vector& values); @@ -1055,22 +1045,22 @@ class Solver { IntVar* MakeBoolVar(); /// IntConst will create a constant expression. - IntVar* MakeIntConst(int64 val, const std::string& name); + IntVar* MakeIntConst(int64_t val, const std::string& name); /// IntConst will create a constant expression. - IntVar* MakeIntConst(int64 val); + IntVar* MakeIntConst(int64_t val); /// This method will append the vector vars with 'var_count' variables /// having bounds vmin and vmax and having name "name" where is /// the index of the variable. - void MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string& name, std::vector* vars); /// This method will append the vector vars with 'var_count' variables /// having bounds vmin and vmax and having no names. - void MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, std::vector* vars); /// Same but allocates an array and returns it. - IntVar** MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + IntVar** MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string& name); /// This method will append the vector vars with 'var_count' boolean @@ -1089,13 +1079,13 @@ class Solver { /// left + right. IntExpr* MakeSum(IntExpr* const left, IntExpr* const right); /// expr + value. - IntExpr* MakeSum(IntExpr* const expr, int64 value); + IntExpr* MakeSum(IntExpr* const expr, int64_t value); /// sum of all vars. IntExpr* MakeSum(const std::vector& vars); /// scalar product IntExpr* MakeScalProd(const std::vector& vars, - const std::vector& coefs); + const std::vector& coefs); /// scalar product IntExpr* MakeScalProd(const std::vector& vars, const std::vector& coefs); @@ -1103,17 +1093,17 @@ class Solver { /// left - right IntExpr* MakeDifference(IntExpr* const left, IntExpr* const right); /// value - expr - IntExpr* MakeDifference(int64 value, IntExpr* const expr); + IntExpr* MakeDifference(int64_t value, IntExpr* const expr); /// -expr IntExpr* MakeOpposite(IntExpr* const expr); /// left * right IntExpr* MakeProd(IntExpr* const left, IntExpr* const right); /// expr * value - IntExpr* MakeProd(IntExpr* const expr, int64 value); + IntExpr* MakeProd(IntExpr* const expr, int64_t value); /// expr / value (integer division) - IntExpr* MakeDiv(IntExpr* const expr, int64 value); + IntExpr* MakeDiv(IntExpr* const expr, int64_t value); /// numerator / denominator (integer division). Terms need to be positive. IntExpr* MakeDiv(IntExpr* const numerator, IntExpr* const denominator); @@ -1122,10 +1112,10 @@ class Solver { /// expr * expr IntExpr* MakeSquare(IntExpr* const expr); /// expr ^ n (n > 0) - IntExpr* MakePower(IntExpr* const expr, int64 n); + IntExpr* MakePower(IntExpr* const expr, int64_t n); /// values[index] - IntExpr* MakeElement(const std::vector& values, IntVar* const index); + IntExpr* MakeElement(const std::vector& values, IntVar* const index); /// values[index] IntExpr* MakeElement(const std::vector& values, IntVar* const index); @@ -1150,13 +1140,13 @@ class Solver { #if !defined(SWIG) /// vars(argument) - IntExpr* MakeElement(Int64ToIntVar vars, int64 range_start, int64 range_end, + IntExpr* MakeElement(Int64ToIntVar vars, int64_t range_start, int64_t range_end, IntVar* argument); #endif // SWIG /// Returns the expression expr such that vars[expr] == value. /// It assumes that vars are all different. - IntExpr* MakeIndexExpression(const std::vector& vars, int64 value); + IntExpr* MakeIndexExpression(const std::vector& vars, int64_t value); /// Special cases with arrays of size two. Constraint* MakeIfThenElseCt(IntVar* const condition, @@ -1169,7 +1159,7 @@ class Solver { /// std::min (left, right) IntExpr* MakeMin(IntExpr* const left, IntExpr* const right); /// std::min(expr, value) - IntExpr* MakeMin(IntExpr* const expr, int64 value); + IntExpr* MakeMin(IntExpr* const expr, int64_t value); /// std::min(expr, value) IntExpr* MakeMin(IntExpr* const expr, int value); @@ -1178,19 +1168,19 @@ class Solver { /// std::max(left, right) IntExpr* MakeMax(IntExpr* const left, IntExpr* const right); /// std::max(expr, value) - IntExpr* MakeMax(IntExpr* const expr, int64 value); + IntExpr* MakeMax(IntExpr* const expr, int64_t value); /// std::max(expr, value) IntExpr* MakeMax(IntExpr* const expr, int value); /// Convex piecewise function. - IntExpr* MakeConvexPiecewiseExpr(IntExpr* expr, int64 early_cost, - int64 early_date, int64 late_date, - int64 late_cost); + IntExpr* MakeConvexPiecewiseExpr(IntExpr* expr, int64_t early_cost, + int64_t early_date, int64_t late_date, + int64_t late_cost); /// Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) /// a >= 0 and b >= 0 - IntExpr* MakeSemiContinuousExpr(IntExpr* const expr, int64 fixed_charge, - int64 step); + IntExpr* MakeSemiContinuousExpr(IntExpr* const expr, int64_t fixed_charge, + int64_t step); /// General piecewise-linear function expression, built from f(x) where f is /// piecewise-linear. The resulting expression is f(expr). @@ -1202,7 +1192,7 @@ class Solver { #endif /// Modulo expression x % mod (with the python convention for modulo). - IntExpr* MakeModulo(IntExpr* const x, int64 mod); + IntExpr* MakeModulo(IntExpr* const x, int64_t mod); /// Modulo expression x % mod (with the python convention for modulo). IntExpr* MakeModulo(IntExpr* const x, IntExpr* const mod); @@ -1210,7 +1200,7 @@ class Solver { /// Conditional Expr condition ? expr : unperformed_value IntExpr* MakeConditionalExpression(IntVar* const condition, IntExpr* const expr, - int64 unperformed_value); + int64_t unperformed_value); /// This constraint always succeeds. Constraint* MakeTrueConstraint(); @@ -1219,10 +1209,10 @@ class Solver { Constraint* MakeFalseConstraint(const std::string& explanation); /// boolvar == (var == value) - Constraint* MakeIsEqualCstCt(IntExpr* const var, int64 value, + Constraint* MakeIsEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar); /// status var of (var == value) - IntVar* MakeIsEqualCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsEqualCstVar(IntExpr* const var, int64_t value); /// b == (v1 == v2) Constraint* MakeIsEqualCt(IntExpr* const v1, IntExpr* v2, IntVar* const b); /// status var of (v1 == v2) @@ -1230,15 +1220,15 @@ class Solver { /// left == right Constraint* MakeEquality(IntExpr* const left, IntExpr* const right); /// expr == value - Constraint* MakeEquality(IntExpr* const expr, int64 value); + Constraint* MakeEquality(IntExpr* const expr, int64_t value); /// expr == value Constraint* MakeEquality(IntExpr* const expr, int value); /// boolvar == (var != value) - Constraint* MakeIsDifferentCstCt(IntExpr* const var, int64 value, + Constraint* MakeIsDifferentCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar); /// status var of (var != value) - IntVar* MakeIsDifferentCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsDifferentCstVar(IntExpr* const var, int64_t value); /// status var of (v1 != v2) IntVar* MakeIsDifferentVar(IntExpr* const v1, IntExpr* const v2); /// b == (v1 != v2) @@ -1247,15 +1237,15 @@ class Solver { /// left != right Constraint* MakeNonEquality(IntExpr* const left, IntExpr* const right); /// expr != value - Constraint* MakeNonEquality(IntExpr* const expr, int64 value); + Constraint* MakeNonEquality(IntExpr* const expr, int64_t value); /// expr != value Constraint* MakeNonEquality(IntExpr* const expr, int value); /// boolvar == (var <= value) - Constraint* MakeIsLessOrEqualCstCt(IntExpr* const var, int64 value, + Constraint* MakeIsLessOrEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar); /// status var of (var <= value) - IntVar* MakeIsLessOrEqualCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsLessOrEqualCstVar(IntExpr* const var, int64_t value); /// status var of (left <= right) IntVar* MakeIsLessOrEqualVar(IntExpr* const left, IntExpr* const right); /// b == (left <= right) @@ -1264,15 +1254,15 @@ class Solver { /// left <= right Constraint* MakeLessOrEqual(IntExpr* const left, IntExpr* const right); /// expr <= value - Constraint* MakeLessOrEqual(IntExpr* const expr, int64 value); + Constraint* MakeLessOrEqual(IntExpr* const expr, int64_t value); /// expr <= value Constraint* MakeLessOrEqual(IntExpr* const expr, int value); /// boolvar == (var >= value) - Constraint* MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64 value, + Constraint* MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar); /// status var of (var >= value) - IntVar* MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64_t value); /// status var of (left >= right) IntVar* MakeIsGreaterOrEqualVar(IntExpr* const left, IntExpr* const right); /// b == (left >= right) @@ -1281,14 +1271,14 @@ class Solver { /// left >= right Constraint* MakeGreaterOrEqual(IntExpr* const left, IntExpr* const right); /// expr >= value - Constraint* MakeGreaterOrEqual(IntExpr* const expr, int64 value); + Constraint* MakeGreaterOrEqual(IntExpr* const expr, int64_t value); /// expr >= value Constraint* MakeGreaterOrEqual(IntExpr* const expr, int value); /// b == (v > c) - Constraint* MakeIsGreaterCstCt(IntExpr* const v, int64 c, IntVar* const b); + Constraint* MakeIsGreaterCstCt(IntExpr* const v, int64_t c, IntVar* const b); /// status var of (var > value) - IntVar* MakeIsGreaterCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsGreaterCstVar(IntExpr* const var, int64_t value); /// status var of (left > right) IntVar* MakeIsGreaterVar(IntExpr* const left, IntExpr* const right); /// b == (left > right) @@ -1297,14 +1287,14 @@ class Solver { /// left > right Constraint* MakeGreater(IntExpr* const left, IntExpr* const right); /// expr > value - Constraint* MakeGreater(IntExpr* const expr, int64 value); + Constraint* MakeGreater(IntExpr* const expr, int64_t value); /// expr > value Constraint* MakeGreater(IntExpr* const expr, int value); /// b == (v < c) - Constraint* MakeIsLessCstCt(IntExpr* const v, int64 c, IntVar* const b); + Constraint* MakeIsLessCstCt(IntExpr* const v, int64_t c, IntVar* const b); /// status var of (var < value) - IntVar* MakeIsLessCstVar(IntExpr* const var, int64 value); + IntVar* MakeIsLessCstVar(IntExpr* const var, int64_t value); /// status var of (left < right) IntVar* MakeIsLessVar(IntExpr* const left, IntExpr* const right); /// b == (left < right) @@ -1313,55 +1303,55 @@ class Solver { /// left < right Constraint* MakeLess(IntExpr* const left, IntExpr* const right); /// expr < value - Constraint* MakeLess(IntExpr* const expr, int64 value); + Constraint* MakeLess(IntExpr* const expr, int64_t value); /// expr < value Constraint* MakeLess(IntExpr* const expr, int value); /// Variation on arrays. - Constraint* MakeSumLessOrEqual(const std::vector& vars, int64 cst); + Constraint* MakeSumLessOrEqual(const std::vector& vars, int64_t cst); Constraint* MakeSumGreaterOrEqual(const std::vector& vars, - int64 cst); - Constraint* MakeSumEquality(const std::vector& vars, int64 cst); + int64_t cst); + Constraint* MakeSumEquality(const std::vector& vars, int64_t cst); Constraint* MakeSumEquality(const std::vector& vars, IntVar* const var); Constraint* MakeScalProdEquality(const std::vector& vars, - const std::vector& coefficients, - int64 cst); + const std::vector& coefficients, + int64_t cst); Constraint* MakeScalProdEquality(const std::vector& vars, const std::vector& coefficients, - int64 cst); + int64_t cst); Constraint* MakeScalProdEquality(const std::vector& vars, - const std::vector& coefficients, + const std::vector& coefficients, IntVar* const target); Constraint* MakeScalProdEquality(const std::vector& vars, const std::vector& coefficients, IntVar* const target); Constraint* MakeScalProdGreaterOrEqual(const std::vector& vars, - const std::vector& coeffs, - int64 cst); + const std::vector& coeffs, + int64_t cst); Constraint* MakeScalProdGreaterOrEqual(const std::vector& vars, const std::vector& coeffs, - int64 cst); + int64_t cst); Constraint* MakeScalProdLessOrEqual(const std::vector& vars, - const std::vector& coefficients, - int64 cst); + const std::vector& coefficients, + int64_t cst); Constraint* MakeScalProdLessOrEqual(const std::vector& vars, const std::vector& coefficients, - int64 cst); + int64_t cst); Constraint* MakeMinEquality(const std::vector& vars, IntVar* const min_var); Constraint* MakeMaxEquality(const std::vector& vars, IntVar* const max_var); - Constraint* MakeElementEquality(const std::vector& vals, + Constraint* MakeElementEquality(const std::vector& vals, IntVar* const index, IntVar* const target); Constraint* MakeElementEquality(const std::vector& vals, IntVar* const index, IntVar* const target); Constraint* MakeElementEquality(const std::vector& vars, IntVar* const index, IntVar* const target); Constraint* MakeElementEquality(const std::vector& vars, - IntVar* const index, int64 target); + IntVar* const index, int64_t target); /// Creates the constraint abs(var) == abs_var. Constraint* MakeAbsEquality(IntVar* const var, IntVar* const abs_var); /// This constraint is a special case of the element constraint with @@ -1369,7 +1359,7 @@ class Solver { /// different and the index variable is constrained such that /// vars[index] == target. Constraint* MakeIndexOfConstraint(const std::vector& vars, - IntVar* const index, int64 target); + IntVar* const index, int64_t target); /// This method is a specialized case of the MakeConstraintDemon /// method to call the InitiatePropagate of the constraint 'ct'. @@ -1388,36 +1378,36 @@ class Solver { // ----- Between and related constraints ----- /// (l <= expr <= u) - Constraint* MakeBetweenCt(IntExpr* const expr, int64 l, int64 u); + Constraint* MakeBetweenCt(IntExpr* const expr, int64_t l, int64_t u); /// (expr < l || expr > u) /// This constraint is lazy as it will not make holes in the domain of /// variables. It will propagate only when expr->Min() >= l /// or expr->Max() <= u. - Constraint* MakeNotBetweenCt(IntExpr* const expr, int64 l, int64 u); + Constraint* MakeNotBetweenCt(IntExpr* const expr, int64_t l, int64_t u); /// b == (l <= expr <= u) - Constraint* MakeIsBetweenCt(IntExpr* const expr, int64 l, int64 u, + Constraint* MakeIsBetweenCt(IntExpr* const expr, int64_t l, int64_t u, IntVar* const b); - IntVar* MakeIsBetweenVar(IntExpr* const v, int64 l, int64 u); + IntVar* MakeIsBetweenVar(IntExpr* const v, int64_t l, int64_t u); // ----- Member and related constraints ----- /// expr in set. Propagation is lazy, i.e. this constraint does not /// creates holes in the domain of the variable. Constraint* MakeMemberCt(IntExpr* const expr, - const std::vector& values); + const std::vector& values); Constraint* MakeMemberCt(IntExpr* const expr, const std::vector& values); /// expr not in set. Constraint* MakeNotMemberCt(IntExpr* const expr, - const std::vector& values); + const std::vector& values); Constraint* MakeNotMemberCt(IntExpr* const expr, const std::vector& values); /// expr should not be in the list of forbidden intervals [start[i]..end[i]]. - Constraint* MakeNotMemberCt(IntExpr* const expr, std::vector starts, - std::vector ends); + Constraint* MakeNotMemberCt(IntExpr* const expr, std::vector starts, + std::vector ends); /// expr should not be in the list of forbidden intervals [start[i]..end[i]]. Constraint* MakeNotMemberCt(IntExpr* const expr, std::vector starts, std::vector ends); @@ -1429,28 +1419,28 @@ class Solver { /// boolvar == (expr in set) Constraint* MakeIsMemberCt(IntExpr* const expr, - const std::vector& values, + const std::vector& values, IntVar* const boolvar); Constraint* MakeIsMemberCt(IntExpr* const expr, const std::vector& values, IntVar* const boolvar); IntVar* MakeIsMemberVar(IntExpr* const expr, - const std::vector& values); + const std::vector& values); IntVar* MakeIsMemberVar(IntExpr* const expr, const std::vector& values); /// |{i | vars[i] == value}| <= max_count - Constraint* MakeAtMost(std::vector vars, int64 value, - int64 max_count); + Constraint* MakeAtMost(std::vector vars, int64_t value, + int64_t max_count); /// |{i | vars[i] == value}| == max_count - Constraint* MakeCount(const std::vector& vars, int64 value, - int64 max_count); + Constraint* MakeCount(const std::vector& vars, int64_t value, + int64_t max_count); /// |{i | vars[i] == value}| == max_count - Constraint* MakeCount(const std::vector& vars, int64 value, + Constraint* MakeCount(const std::vector& vars, int64_t value, IntVar* const max_count); /// Aggregated version of count: |{i | v[i] == values[j]}| == cards[j] Constraint* MakeDistribute(const std::vector& vars, - const std::vector& values, + const std::vector& values, const std::vector& cards); /// Aggregated version of count: |{i | v[i] == values[j]}| == cards[j] Constraint* MakeDistribute(const std::vector& vars, @@ -1461,14 +1451,14 @@ class Solver { const std::vector& cards); /// Aggregated version of count with bounded cardinalities: /// forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max - Constraint* MakeDistribute(const std::vector& vars, int64 card_min, - int64 card_max, int64 card_size); + Constraint* MakeDistribute(const std::vector& vars, int64_t card_min, + int64_t card_max, int64_t card_size); /// Aggregated version of count with bounded cardinalities: /// forall j in 0 .. card_size - 1: /// card_min[j] <= |{i | v[i] == j}| <= card_max[j] Constraint* MakeDistribute(const std::vector& vars, - const std::vector& card_min, - const std::vector& card_max); + const std::vector& card_min, + const std::vector& card_max); /// Aggregated version of count with bounded cardinalities: /// forall j in 0 .. card_size - 1: /// card_min[j] <= |{i | v[i] == j}| <= card_max[j] @@ -1479,9 +1469,9 @@ class Solver { /// forall j in 0 .. card_size - 1: /// card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] Constraint* MakeDistribute(const std::vector& vars, - const std::vector& values, - const std::vector& card_min, - const std::vector& card_max); + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); /// Aggregated version of count with bounded cardinalities: /// forall j in 0 .. card_size - 1: /// card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] @@ -1495,7 +1485,7 @@ class Solver { /// sum_i vars[i] == total_sum /// n = #vars Constraint* MakeDeviation(const std::vector& vars, - IntVar* const deviation_var, int64 total_sum); + IntVar* const deviation_var, int64_t total_sum); /// All variables are pairwise different. This corresponds to the /// stronger version of the propagation algorithm. @@ -1510,7 +1500,7 @@ class Solver { /// All variables are pairwise different, unless they are assigned to /// the escape value. Constraint* MakeAllDifferentExcept(const std::vector& vars, - int64 escape_value); + int64_t escape_value); // TODO(user): Do we need a version with an array of escape values. /// Creates a constraint binding the arrays of variables "vars" and @@ -1575,7 +1565,7 @@ class Solver { /// intersect with the set of values in the second vector. Constraint* MakeNullIntersectExcept(const std::vector& first_vars, const std::vector& second_vars, - int64 escape_value); + int64_t escape_value); // TODO(user): Implement MakeAllNullIntersect taking an array of // variable vectors. @@ -1645,8 +1635,8 @@ class Solver { // TODO(user): Only does checking on WhenBound events on next variables. /// Check whether more propagation is needed. Constraint* MakePathConnected(std::vector nexts, - std::vector sources, - std::vector sinks, + std::vector sources, + std::vector sinks, std::vector status); #ifndef SWIG /// Contraint enforcing, for each pair (i,j) in precedences, i to be before j @@ -1698,8 +1688,8 @@ class Solver { /// Only the transitions (i.e. the variables) are visible. Constraint* MakeTransitionConstraint(const std::vector& vars, const IntTupleSet& transition_table, - int64 initial_state, - const std::vector& final_states); + int64_t initial_state, + const std::vector& final_states); /// This constraint create a finite automaton that will check the /// sequence of variables vars. It uses a transition table called @@ -1710,14 +1700,14 @@ class Solver { /// Only the transitions (i.e. the variables) are visible. Constraint* MakeTransitionConstraint(const std::vector& vars, const IntTupleSet& transition_table, - int64 initial_state, + int64_t initial_state, const std::vector& final_states); #if defined(SWIGPYTHON) /// Compatibility layer for Python API. Constraint* MakeAllowedAssignments( const std::vector& vars, - const std::vector /*keep for swig*/>& raw_tuples) { + const std::vector /*keep for swig*/>& raw_tuples) { IntTupleSet tuples(vars.size()); tuples.InsertAll(raw_tuples); return MakeAllowedAssignments(vars, tuples); @@ -1725,8 +1715,8 @@ class Solver { Constraint* MakeTransitionConstraint( const std::vector& vars, - const std::vector /*keep for swig*/>& raw_transitions, - int64 initial_state, const std::vector& final_states) { + const std::vector /*keep for swig*/>& raw_transitions, + int64_t initial_state, const std::vector& final_states) { IntTupleSet transitions(3); transitions.InsertAll(raw_transitions); return MakeTransitionConstraint(vars, transitions, initial_state, @@ -1747,7 +1737,7 @@ class Solver { const std::vector& x_size, const std::vector& y_size); Constraint* MakeNonOverlappingBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, - const std::vector& x_size, const std::vector& y_size); + const std::vector& x_size, const std::vector& y_size); Constraint* MakeNonOverlappingBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, const std::vector& x_size, const std::vector& y_size); @@ -1765,7 +1755,7 @@ class Solver { const std::vector& x_size, const std::vector& y_size); Constraint* MakeNonOverlappingNonStrictBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, - const std::vector& x_size, const std::vector& y_size); + const std::vector& x_size, const std::vector& y_size); Constraint* MakeNonOverlappingNonStrictBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, const std::vector& x_size, const std::vector& y_size); @@ -1781,41 +1771,41 @@ class Solver { /// be greater than 0. If optional is true, then the interval can be /// performed or unperformed. If optional is false, then the interval /// is always performed. - IntervalVar* MakeFixedDurationIntervalVar(int64 start_min, int64 start_max, - int64 duration, bool optional, + IntervalVar* MakeFixedDurationIntervalVar(int64_t start_min, int64_t start_max, + int64_t duration, bool optional, const std::string& name); /// This method fills the vector with 'count' interval variables built with /// the corresponding parameters. void MakeFixedDurationIntervalVarArray( - int count, int64 start_min, int64 start_max, int64 duration, + int count, int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string& name, std::vector* const array); /// Creates a performed interval var with a fixed duration. The duration must /// be greater than 0. IntervalVar* MakeFixedDurationIntervalVar(IntVar* const start_variable, - int64 duration, + int64_t duration, const std::string& name); /// Creates an interval var with a fixed duration, and performed_variable. /// The duration must be greater than 0. IntervalVar* MakeFixedDurationIntervalVar(IntVar* const start_variable, - int64 duration, + int64_t duration, IntVar* const performed_variable, const std::string& name); /// This method fills the vector with 'count' interval var built with /// the corresponding start variables. void MakeFixedDurationIntervalVarArray( - const std::vector& start_variables, int64 duration, + const std::vector& start_variables, int64_t duration, const std::string& name, std::vector* const array); /// This method fills the vector with interval variables built with /// the corresponding start variables. void MakeFixedDurationIntervalVarArray( const std::vector& start_variables, - const std::vector& durations, const std::string& name, + const std::vector& durations, const std::string& name, std::vector* const array); /// This method fills the vector with interval variables built with /// the corresponding start variables. @@ -1828,7 +1818,7 @@ class Solver { /// the corresponding start and performed variables. void MakeFixedDurationIntervalVarArray( const std::vector& start_variables, - const std::vector& durations, + const std::vector& durations, const std::vector& performed_variables, const std::string& name, std::vector* const array); @@ -1841,21 +1831,21 @@ class Solver { std::vector* const array); /// Creates a fixed and performed interval. - IntervalVar* MakeFixedInterval(int64 start, int64 duration, + IntervalVar* MakeFixedInterval(int64_t start, int64_t duration, const std::string& name); /// Creates an interval var by specifying the bounds on start, /// duration, and end. - IntervalVar* MakeIntervalVar(int64 start_min, int64 start_max, - int64 duration_min, int64 duration_max, - int64 end_min, int64 end_max, bool optional, + IntervalVar* MakeIntervalVar(int64_t start_min, int64_t start_max, + int64_t duration_min, int64_t duration_max, + int64_t end_min, int64_t end_max, bool optional, const std::string& name); /// This method fills the vector with 'count' interval var built with /// the corresponding parameters. - void MakeIntervalVarArray(int count, int64 start_min, int64 start_max, - int64 duration_min, int64 duration_max, - int64 end_min, int64 end_max, bool optional, + void MakeIntervalVarArray(int count, int64_t start_min, int64_t start_max, + int64_t duration_min, int64_t duration_max, + int64_t end_min, int64_t end_max, bool optional, const std::string& name, std::vector* const array); @@ -1868,28 +1858,28 @@ class Solver { /// offset. The performed status is also in sync with the performed /// status of the given interval variable. IntervalVar* MakeFixedDurationStartSyncedOnStartIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset); + IntervalVar* const interval_var, int64_t duration, int64_t offset); /// Creates an interval var with a fixed duration whose start is /// synchronized with the end of another interval, with a given /// offset. The performed status is also in sync with the performed /// status of the given interval variable. IntervalVar* MakeFixedDurationStartSyncedOnEndIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset); + IntervalVar* const interval_var, int64_t duration, int64_t offset); /// Creates an interval var with a fixed duration whose end is /// synchronized with the start of another interval, with a given /// offset. The performed status is also in sync with the performed /// status of the given interval variable. IntervalVar* MakeFixedDurationEndSyncedOnStartIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset); + IntervalVar* const interval_var, int64_t duration, int64_t offset); /// Creates an interval var with a fixed duration whose end is /// synchronized with the end of another interval, with a given /// offset. The performed status is also in sync with the performed /// status of the given interval variable. IntervalVar* MakeFixedDurationEndSyncedOnEndIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset); + IntervalVar* const interval_var, int64_t duration, int64_t offset); /// Creates and returns an interval variable that wraps around the given one, /// relaxing the min start and end. Relaxing means making unbounded when @@ -1932,7 +1922,7 @@ class Solver { /// This method creates a relation between an interval var and a /// date. Constraint* MakeIntervalVarRelation(IntervalVar* const t, - UnaryIntervalRelation r, int64 d); + UnaryIntervalRelation r, int64_t d); /// This method creates a relation between two interval vars. Constraint* MakeIntervalVarRelation(IntervalVar* const t1, @@ -1946,7 +1936,7 @@ class Solver { Constraint* MakeIntervalVarRelationWithDelay(IntervalVar* const t1, BinaryIntervalRelation r, IntervalVar* const t2, - int64 delay); + int64_t delay); /// This constraint implements a temporal disjunction between two /// interval vars t1 and t2. 'alt' indicates which alternative was @@ -1980,7 +1970,7 @@ class Solver { /// supported, and the corresponding intervals are filtered out, as they /// neither impact nor are impacted by this constraint. Constraint* MakeCumulative(const std::vector& intervals, - const std::vector& demands, int64 capacity, + const std::vector& demands, int64_t capacity, const std::string& name); /// This constraint forces that, for any integer t, the sum of the demands @@ -1993,7 +1983,7 @@ class Solver { /// supported, and the corresponding intervals are filtered out, as they /// neither impact nor are impacted by this constraint. Constraint* MakeCumulative(const std::vector& intervals, - const std::vector& demands, int64 capacity, + const std::vector& demands, int64_t capacity, const std::string& name); /// This constraint forces that, for any integer t, the sum of the demands @@ -2006,7 +1996,7 @@ class Solver { /// supported, and the corresponding intervals are filtered out, as they /// neither impact nor are impacted by this constraint. Constraint* MakeCumulative(const std::vector& intervals, - const std::vector& demands, + const std::vector& demands, IntVar* const capacity, const std::string& name); /// This constraint enforces that, for any integer t, the sum of the demands @@ -2031,7 +2021,7 @@ class Solver { /// Demands should be positive. Constraint* MakeCumulative(const std::vector& intervals, const std::vector& demands, - int64 capacity, const std::string& name); + int64_t capacity, const std::string& name); /// This constraint enforces that, for any integer t, the sum of demands /// corresponding to an interval containing t does not exceed the given @@ -2104,47 +2094,47 @@ class Solver { SolutionCollector* MakeAllSolutionCollector(); /// Creates a minimization objective. - OptimizeVar* MakeMinimize(IntVar* const v, int64 step); + OptimizeVar* MakeMinimize(IntVar* const v, int64_t step); /// Creates a maximization objective. - OptimizeVar* MakeMaximize(IntVar* const v, int64 step); + OptimizeVar* MakeMaximize(IntVar* const v, int64_t step); /// Creates a objective with a given sense (true = maximization). - OptimizeVar* MakeOptimize(bool maximize, IntVar* const v, int64 step); + OptimizeVar* MakeOptimize(bool maximize, IntVar* const v, int64_t step); /// Creates a minimization weighted objective. The actual objective is /// scalar_prod(sub_objectives, weights). OptimizeVar* MakeWeightedMinimize(const std::vector& sub_objectives, - const std::vector& weights, - int64 step); + const std::vector& weights, + int64_t step); /// Creates a minimization weighted objective. The actual objective is /// scalar_prod(sub_objectives, weights). OptimizeVar* MakeWeightedMinimize(const std::vector& sub_objectives, const std::vector& weights, - int64 step); + int64_t step); /// Creates a maximization weigthed objective. OptimizeVar* MakeWeightedMaximize(const std::vector& sub_objectives, - const std::vector& weights, - int64 step); + const std::vector& weights, + int64_t step); /// Creates a maximization weigthed objective. OptimizeVar* MakeWeightedMaximize(const std::vector& sub_objectives, const std::vector& weights, - int64 step); + int64_t step); /// Creates a weighted objective with a given sense (true = maximization). OptimizeVar* MakeWeightedOptimize(bool maximize, const std::vector& sub_objectives, - const std::vector& weights, - int64 step); + const std::vector& weights, + int64_t step); /// Creates a weighted objective with a given sense (true = maximization). OptimizeVar* MakeWeightedOptimize(bool maximize, const std::vector& sub_objectives, const std::vector& weights, - int64 step); + int64_t step); /// MetaHeuristics which try to get the search out of local optima. @@ -2164,33 +2154,33 @@ class Solver { /// of "tabu" violations which is tolerated; a factor of 1 means no violations /// allowed; a factor of 0 means all violations are allowed. - SearchMonitor* MakeTabuSearch(bool maximize, IntVar* const v, int64 step, + SearchMonitor* MakeTabuSearch(bool maximize, IntVar* const v, int64_t step, const std::vector& vars, - int64 keep_tenure, int64 forbid_tenure, + int64_t keep_tenure, int64_t forbid_tenure, double tabu_factor); /// Creates a Tabu Search based on the vars |vars|. /// A solution is "tabu" if all the vars in |vars| keep their value. SearchMonitor* MakeGenericTabuSearch(bool maximize, IntVar* const v, - int64 step, + int64_t step, const std::vector& tabu_vars, - int64 forbid_tenure); + int64_t forbid_tenure); /// Creates a Simulated Annealing monitor. // TODO(user): document behavior SearchMonitor* MakeSimulatedAnnealing(bool maximize, IntVar* const v, - int64 step, int64 initial_temperature); + int64_t step, int64_t initial_temperature); /// Creates a Guided Local Search monitor. /// Description here: http://en.wikipedia.org/wiki/Guided_Local_Search SearchMonitor* MakeGuidedLocalSearch(bool maximize, IntVar* const objective, IndexEvaluator2 objective_function, - int64 step, + int64_t step, const std::vector& vars, double penalty_factor); SearchMonitor* MakeGuidedLocalSearch( bool maximize, IntVar* const objective, - IndexEvaluator3 objective_function, int64 step, + IndexEvaluator3 objective_function, int64_t step, const std::vector& vars, const std::vector& secondary_vars, double penalty_factor); @@ -2208,7 +2198,7 @@ class Solver { #if !defined(SWIG) ABSL_DEPRECATED("Use the version taking absl::Duration() as argument") #endif // !defined(SWIG) - RegularLimit* MakeTimeLimit(int64 time_in_ms) { + RegularLimit* MakeTimeLimit(int64_t time_in_ms) { return MakeTimeLimit(time_in_ms == kint64max ? absl::InfiniteDuration() : absl::Milliseconds(time_in_ms)); @@ -2216,22 +2206,22 @@ class Solver { /// Creates a search limit that constrains the number of branches /// explored in the search tree. - RegularLimit* MakeBranchesLimit(int64 branches); + RegularLimit* MakeBranchesLimit(int64_t branches); /// Creates a search limit that constrains the number of failures /// that can happen when exploring the search tree. - RegularLimit* MakeFailuresLimit(int64 failures); + RegularLimit* MakeFailuresLimit(int64_t failures); /// Creates a search limit that constrains the number of solutions found /// during the search. - RegularLimit* MakeSolutionsLimit(int64 solutions); + RegularLimit* MakeSolutionsLimit(int64_t solutions); /// Limits the search with the 'time', 'branches', 'failures' and /// 'solutions' limits. 'smart_time_check' reduces the calls to the wall // timer by estimating the number of remaining calls, and 'cumulative' means // that the limit applies cumulatively, instead of search-by-search. - RegularLimit* MakeLimit(absl::Duration time, int64 branches, int64 failures, - int64 solutions, bool smart_time_check = false, + RegularLimit* MakeLimit(absl::Duration time, int64_t branches, int64_t failures, + int64_t solutions, bool smart_time_check = false, bool cumulative = false); /// Creates a search limit from its protobuf description RegularLimit* MakeLimit(const RegularLimitParameters& proto); @@ -2239,8 +2229,8 @@ class Solver { #if !defined(SWIG) ABSL_DEPRECATED("Use other MakeLimit() versions") #endif // !defined(SWIG) - RegularLimit* MakeLimit(int64 time, int64 branches, int64 failures, - int64 solutions, bool smart_time_check = false, + RegularLimit* MakeLimit(int64_t time, int64_t branches, int64_t failures, + int64_t solutions, bool smart_time_check = false, bool cumulative = false); /// Creates a regular limit proto containing default values. @@ -2351,15 +2341,15 @@ class Solver { SymmetryBreaker* const v4); /// Decisions. - Decision* MakeAssignVariableValue(IntVar* const var, int64 val); - Decision* MakeVariableLessOrEqualValue(IntVar* const var, int64 value); - Decision* MakeVariableGreaterOrEqualValue(IntVar* const var, int64 value); - Decision* MakeSplitVariableDomain(IntVar* const var, int64 val, + Decision* MakeAssignVariableValue(IntVar* const var, int64_t val); + Decision* MakeVariableLessOrEqualValue(IntVar* const var, int64_t value); + Decision* MakeVariableGreaterOrEqualValue(IntVar* const var, int64_t value); + Decision* MakeSplitVariableDomain(IntVar* const var, int64_t val, bool start_with_lower_half); - Decision* MakeAssignVariableValueOrFail(IntVar* const var, int64 value); - Decision* MakeAssignVariableValueOrDoNothing(IntVar* const var, int64 value); + Decision* MakeAssignVariableValueOrFail(IntVar* const var, int64_t value); + Decision* MakeAssignVariableValueOrDoNothing(IntVar* const var, int64_t value); Decision* MakeAssignVariablesValues(const std::vector& vars, - const std::vector& values); + const std::vector& values); Decision* MakeFailDecision(); Decision* MakeDecision(Action apply, Action refute); @@ -2459,16 +2449,16 @@ class Solver { /// its start to 'est'. On the Refute branch, it will just update the /// 'marker' to 'est' + 1. This decision is used in the /// INTERVAL_SET_TIMES_FORWARD strategy. - Decision* MakeScheduleOrPostpone(IntervalVar* const var, int64 est, - int64* const marker); + Decision* MakeScheduleOrPostpone(IntervalVar* const var, int64_t est, + int64_t* const marker); /// Returns a decision that tries to schedule a task at a given time. /// On the Apply branch, it will set that interval var as performed and set /// its end to 'est'. On the Refute branch, it will just update the /// 'marker' to 'est' - 1. This decision is used in the /// INTERVAL_SET_TIMES_BACKWARD strategy. - Decision* MakeScheduleOrExpedite(IntervalVar* const var, int64 est, - int64* const marker); + Decision* MakeScheduleOrExpedite(IntervalVar* const var, int64_t est, + int64_t* const marker); /// Returns a decision that tries to rank first the ith interval var /// in the sequence variable. @@ -2545,29 +2535,29 @@ class Solver { /// to this solution, and return nullptr. DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step); + int64_t step); DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, + int64_t step, SearchMonitor* const monitor1); DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, SearchMonitor* const monitor1, + int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2); DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, SearchMonitor* const monitor1, + int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2, SearchMonitor* const monitor3); DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, SearchMonitor* const monitor1, + int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2, SearchMonitor* const monitor3, SearchMonitor* const monitor4); DecisionBuilder* MakeNestedOptimize( DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, const std::vector& monitors); + int64_t step, const std::vector& monitors); /// Returns a DecisionBuilder which restores an Assignment /// (calls void Assignment::Restore()) @@ -2604,7 +2594,7 @@ class Solver { int number_of_variables); LocalSearchOperator* MakeRandomLnsOperator(const std::vector& vars, int number_of_variables, - int32 seed); + int32_t seed); /// Creates a local search operator that tries to move the assignment of some /// variables toward a target. The target is given as an Assignment. This @@ -2621,7 +2611,7 @@ class Solver { /// variable that belongs to the given vector is set to its target value. LocalSearchOperator* MakeMoveTowardTargetOperator( const std::vector& variables, - const std::vector& target_values); + const std::vector& target_values); /// Creates a local search operator which concatenates a vector of operators. /// Each operator from the vector is called sequentially. By default, when a @@ -2640,7 +2630,7 @@ class Solver { /// Example: /// /// const int kPriorities = {10, 100, 10, 0}; - /// int64 Evaluate(int active_operator, int current_operator) { + /// int64_t Evaluate(int active_operator, int current_operator) { /// return kPriorities[current_operator]; /// } /// @@ -2659,7 +2649,7 @@ class Solver { const std::vector& ops, bool restart); LocalSearchOperator* ConcatenateOperators( const std::vector& ops, - std::function evaluator); + std::function evaluator); /// Randomized version of local search concatenator; calls a random operator /// at each call to MakeNextNeighbor(). LocalSearchOperator* RandomConcatenateOperators( @@ -2669,7 +2659,7 @@ class Solver { /// at each call to MakeNextNeighbor(). The provided seed is used to /// initialize the random number generator. LocalSearchOperator* RandomConcatenateOperators( - const std::vector& ops, int32 seed); + const std::vector& ops, int32_t seed); /// Creates a local search operator which concatenates a vector of operators. /// Uses Multi-Armed Bandit approach for choosing the next operator to use. @@ -2688,7 +2678,7 @@ class Solver { /// to Start()). When this limit is reached, MakeNextNeighbor() /// returns false. The counter is cleared when Start() is called. LocalSearchOperator* MakeNeighborhoodLimit(LocalSearchOperator* const op, - int64 limit); + int64_t limit); /// Local Search decision builders factories. /// Local search is used to improve a given solution. This initial solution @@ -2825,19 +2815,19 @@ class Solver { } /// Returns a random value between 0 and 'size' - 1; - int64 Rand64(int64 size) { + int64_t Rand64(int64_t size) { DCHECK_GT(size, 0); - return absl::Uniform(random_, 0, size); + return absl::Uniform(random_, 0, size); } /// Returns a random value between 0 and 'size' - 1; - int32 Rand32(int32 size) { + int32_t Rand32(int32_t size) { DCHECK_GT(size, 0); - return absl::Uniform(random_, 0, size); + return absl::Uniform(random_, 0, size); } /// Reseed the solver random generator. - void ReSeed(int32 seed) { random_.seed(seed); } + void ReSeed(int32_t seed) { random_.seed(seed); } /// Exports the profiling information in a human readable overview. /// The parameter profile_level used to create the solver must be @@ -2937,7 +2927,7 @@ class Solver { /// that need storage and that may fail. See IntVar::SetValues() for /// instance. It is not locked; do not use in a multi-threaded or reentrant /// setup. - std::vector tmp_vector_; + std::vector tmp_vector_; friend class BaseIntExpr; friend class Constraint; @@ -2969,7 +2959,7 @@ class Solver { /// constant. In that case, it fills inner_expr and coefficient with /// these, and returns true. In the other case, it fills inner_expr /// with expr, coefficient with 1, and returns false. - bool IsProduct(IntExpr* const expr, IntExpr** inner_expr, int64* coefficient); + bool IsProduct(IntExpr* const expr, IntExpr** inner_expr, int64_t* coefficient); #endif /// !defined(SWIG) /// Internal. If the variables is the result of expr->Var(), this @@ -3013,20 +3003,20 @@ class Solver { bool IsUncheckedSolutionLimitReached(); void InternalSaveValue(int* valptr); - void InternalSaveValue(int64* valptr); - void InternalSaveValue(uint64* valptr); + void InternalSaveValue(int64_t* valptr); + void InternalSaveValue(uint64_t* valptr); void InternalSaveValue(double* valptr); void InternalSaveValue(bool* valptr); void InternalSaveValue(void** valptr); - void InternalSaveValue(int64** valptr) { + void InternalSaveValue(int64_t** valptr) { InternalSaveValue(reinterpret_cast(valptr)); } BaseObject* SafeRevAlloc(BaseObject* ptr); int* SafeRevAllocArray(int* ptr); - int64* SafeRevAllocArray(int64* ptr); - uint64* SafeRevAllocArray(uint64* ptr); + int64_t* SafeRevAllocArray(int64_t* ptr); + uint64_t* SafeRevAllocArray(uint64_t* ptr); double* SafeRevAllocArray(double* ptr); BaseObject** SafeRevAllocArray(BaseObject** ptr); IntVar** SafeRevAllocArray(IntVar** ptr); @@ -3089,18 +3079,18 @@ class Solver { std::vector additional_constraints_list_; std::vector additional_constraints_parent_list_; SolverState state_; - int64 branches_; - int64 fails_; - int64 decisions_; - int64 demon_runs_[kNumPriorities]; - int64 neighbors_; - int64 filtered_neighbors_; - int64 accepted_neighbors_; + int64_t branches_; + int64_t fails_; + int64_t decisions_; + int64_t demon_runs_[kNumPriorities]; + int64_t neighbors_; + int64_t filtered_neighbors_; + int64_t accepted_neighbors_; OptimizationDirection optimization_direction_; std::unique_ptr timer_; std::vector searches_; std::mt19937 random_; - uint64 fail_stamp_; + uint64_t fail_stamp_; std::unique_ptr balancing_decision_; /// intercept failures std::function fail_intercept_; @@ -3141,10 +3131,10 @@ std::ostream& operator<<(std::ostream& out, const Solver* const s); /// NOLINT /// This method returns 0. It is useful when 0 can be cast either as /// a pointer or as an integer value and thus lead to an ambiguous /// function call. -inline int64 Zero() { return 0; } +inline int64_t Zero() { return 0; } /// This method returns 1 -inline int64 One() { return 1; } +inline int64_t One() { return 1; } /// A BaseObject is the root of all reversibly allocated objects. /// A DebugString method and the associated << operator are implemented @@ -3250,11 +3240,11 @@ class DecisionVisitor : public BaseObject { public: DecisionVisitor() {} ~DecisionVisitor() override {} - virtual void VisitSetVariableValue(IntVar* const var, int64 value); - virtual void VisitSplitVariableDomain(IntVar* const var, int64 value, + virtual void VisitSetVariableValue(IntVar* const var, int64_t value); + virtual void VisitSplitVariableDomain(IntVar* const var, int64_t value, bool start_with_lower_half); - virtual void VisitScheduleOrPostpone(IntervalVar* const var, int64 est); - virtual void VisitScheduleOrExpedite(IntervalVar* const var, int64 est); + virtual void VisitScheduleOrPostpone(IntervalVar* const var, int64_t est); + virtual void VisitScheduleOrExpedite(IntervalVar* const var, int64_t est); virtual void VisitRankFirstInterval(SequenceVar* const sequence, int index); virtual void VisitRankLastInterval(SequenceVar* const sequence, int index); virtual void VisitUnknownDecision(); @@ -3324,9 +3314,9 @@ class Demon : public BaseObject { private: friend class Queue; - void set_stamp(int64 stamp) { stamp_ = stamp; } - uint64 stamp() const { return stamp_; } - uint64 stamp_; + void set_stamp(int64_t stamp) { stamp_ = stamp; } + uint64_t stamp() const { return stamp_; } + uint64_t stamp_; DISALLOW_COPY_AND_ASSIGN(Demon); }; @@ -3525,17 +3515,17 @@ class ModelVisitor : public BaseObject { virtual void VisitIntegerVariable(const IntVar* const variable, IntExpr* const delegate); virtual void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate); virtual void VisitIntervalVariable(const IntervalVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntervalVar* const delegate); virtual void VisitSequenceVariable(const SequenceVar* const variable); /// Visit integer arguments. - virtual void VisitIntegerArgument(const std::string& arg_name, int64 value); + virtual void VisitIntegerArgument(const std::string& arg_name, int64_t value); virtual void VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values); + const std::vector& values); virtual void VisitIntegerMatrixArgument(const std::string& arg_name, const IntTupleSet& tuples); @@ -3565,13 +3555,13 @@ class ModelVisitor : public BaseObject { /// Using SWIG on callbacks is troublesome, so we hide these methods during /// the wrapping. - void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64 index_min, - int64 index_max); + void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, + int64_t index_max); void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1& eval, - int64 index_min, int64 index_max); + int64_t index_min, int64_t index_max); /// Expands function as array when index min is 0. void VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1& eval, - const std::string& arg_name, int64 index_max); + const std::string& arg_name, int64_t index_max); #endif // #if !defined(SWIG) }; @@ -3749,7 +3739,7 @@ class Rev { } private: - uint64 stamp_; + uint64_t stamp_; T value_; }; @@ -3777,7 +3767,7 @@ template class RevArray { public: RevArray(int size, const T& val) - : stamps_(new uint64[size]), values_(new T[size]), size_(size) { + : stamps_(new uint64_t[size]), values_(new T[size]), size_(size) { for (int i = 0; i < size; ++i) { stamps_[i] = 0; values_[i] = val; @@ -3786,7 +3776,7 @@ class RevArray { ~RevArray() {} - int64 size() const { return size_; } + int64_t size() const { return size_; } const T& Value(int index) const { return values_[index]; } @@ -3806,7 +3796,7 @@ class RevArray { } private: - std::unique_ptr stamps_; + std::unique_ptr stamps_; std::unique_ptr values_; const int size_; }; @@ -3838,25 +3828,25 @@ class IntExpr : public PropagationBaseObject { explicit IntExpr(Solver* const s) : PropagationBaseObject(s) {} ~IntExpr() override {} - virtual int64 Min() const = 0; - virtual void SetMin(int64 m) = 0; - virtual int64 Max() const = 0; - virtual void SetMax(int64 m) = 0; + virtual int64_t Min() const = 0; + virtual void SetMin(int64_t m) = 0; + virtual int64_t Max() const = 0; + virtual void SetMax(int64_t m) = 0; /// By default calls Min() and Max(), but can be redefined when Min and Max /// code can be factorized. - virtual void Range(int64* l, int64* u) { + virtual void Range(int64_t* l, int64_t* u) { *l = Min(); *u = Max(); } /// This method sets both the min and the max of the expression. - virtual void SetRange(int64 l, int64 u) { + virtual void SetRange(int64_t l, int64_t u) { SetMin(l); SetMax(u); } /// This method sets the value of the expression. - virtual void SetValue(int64 v) { SetRange(v, v); } + virtual void SetValue(int64_t v) { SetRange(v, v); } /// Returns true if the min and the max of the expression are equal. virtual bool Bound() const { return (Min() == Max()); } @@ -3907,7 +3897,7 @@ class IntExpr : public PropagationBaseObject { /// IntVar* current_var; /// std::unique_ptr it(current_var->MakeHoleIterator(false)); -/// for (const int64 hole : InitAndGetValues(it)) { +/// for (const int64_t hole : InitAndGetValues(it)) { /// /// use the hole /// } @@ -3922,7 +3912,7 @@ class IntVarIterator : public BaseObject { virtual bool Ok() const = 0; /// This method returns the current value of the iterator. - virtual int64 Value() const = 0; + virtual int64_t Value() const = 0; /// This method moves the iterator to the next value. virtual void Next() = 0; @@ -3945,6 +3935,7 @@ class InitAndGetValues { it_->Init(); } struct Iterator; + Iterator begin() { if (DEBUG_MODE) { DCHECK(!begin_was_called_); @@ -3963,7 +3954,7 @@ class InitAndGetValues { return Iterator(it, /*is_end=*/true); } - int64 operator*() const { + int64_t operator*() const { DCHECK(it_->Ok()); return it_->Value(); } @@ -4005,20 +3996,20 @@ class IntVar : public IntExpr { /// This method returns the value of the variable. This method checks /// before that the variable is bound. - virtual int64 Value() const = 0; + virtual int64_t Value() const = 0; /// This method removes the value 'v' from the domain of the variable. - virtual void RemoveValue(int64 v) = 0; + virtual void RemoveValue(int64_t v) = 0; /// This method removes the interval 'l' .. 'u' from the domain of /// the variable. It assumes that 'l' <= 'u'. - virtual void RemoveInterval(int64 l, int64 u) = 0; + virtual void RemoveInterval(int64_t l, int64_t u) = 0; /// This method remove the values from the domain of the variable. - virtual void RemoveValues(const std::vector& values); + virtual void RemoveValues(const std::vector& values); /// This method intersects the current domain with the values in the array. - virtual void SetValues(const std::vector& values); + virtual void SetValues(const std::vector& values); /// This method attaches a demon that will be awakened when the /// variable is bound. @@ -4054,11 +4045,11 @@ class IntVar : public IntExpr { #endif // SWIG /// This method returns the number of values in the domain of the variable. - virtual uint64 Size() const = 0; + virtual uint64_t Size() const = 0; /// This method returns whether the value 'v' is in the domain of the /// variable. - virtual bool Contains(int64 v) const = 0; + virtual bool Contains(int64_t v) const = 0; /// Creates a hole iterator. When 'reversible' is false, the returned /// object is created on the normal C++ heap and the solver does NOT @@ -4071,10 +4062,10 @@ class IntVar : public IntExpr { virtual IntVarIterator* MakeDomainIterator(bool reversible) const = 0; /// Returns the previous min. - virtual int64 OldMin() const = 0; + virtual int64_t OldMin() const = 0; /// Returns the previous max. - virtual int64 OldMax() const = 0; + virtual int64_t OldMax() const = 0; virtual int VarType() const; @@ -4082,10 +4073,10 @@ class IntVar : public IntExpr { void Accept(ModelVisitor* const visitor) const override; /// IsEqual - virtual IntVar* IsEqual(int64 constant) = 0; - virtual IntVar* IsDifferent(int64 constant) = 0; - virtual IntVar* IsGreaterOrEqual(int64 constant) = 0; - virtual IntVar* IsLessOrEqual(int64 constant) = 0; + virtual IntVar* IsEqual(int64_t constant) = 0; + virtual IntVar* IsDifferent(int64_t constant) = 0; + virtual IntVar* IsGreaterOrEqual(int64_t constant) = 0; + virtual IntVar* IsLessOrEqual(int64_t constant) = 0; /// Returns the index of the variable. int index() const { return index_; } @@ -4124,32 +4115,32 @@ class SolutionCollector : public SearchMonitor { Assignment* solution(int n) const; /// Returns the wall time in ms for the nth solution. - int64 wall_time(int n) const; + int64_t wall_time(int n) const; /// Returns the number of branches when the nth solution was found. - int64 branches(int n) const; + int64_t branches(int n) const; /// Returns the number of failures encountered at the time of the nth /// solution. - int64 failures(int n) const; + int64_t failures(int n) const; /// Returns the objective value of the nth solution. - int64 objective_value(int n) const; + int64_t objective_value(int n) const; /// This is a shortcut to get the Value of 'var' in the nth solution. - int64 Value(int n, IntVar* const var) const; + int64_t Value(int n, IntVar* const var) const; /// This is a shortcut to get the StartValue of 'var' in the nth solution. - int64 StartValue(int n, IntervalVar* const var) const; + int64_t StartValue(int n, IntervalVar* const var) const; /// This is a shortcut to get the EndValue of 'var' in the nth solution. - int64 EndValue(int n, IntervalVar* const var) const; + int64_t EndValue(int n, IntervalVar* const var) const; /// This is a shortcut to get the DurationValue of 'var' in the nth solution. - int64 DurationValue(int n, IntervalVar* const var) const; + int64_t DurationValue(int n, IntervalVar* const var) const; /// This is a shortcut to get the PerformedValue of 'var' in the nth solution. - int64 PerformedValue(int n, IntervalVar* const var) const; + int64_t PerformedValue(int n, IntervalVar* const var) const; /// This is a shortcut to get the ForwardSequence of 'var' in the /// nth solution. The forward sequence is the list of ranked interval @@ -4166,10 +4157,10 @@ class SolutionCollector : public SearchMonitor { protected: struct SolutionData { Assignment* solution; - int64 time; - int64 branches; - int64 failures; - int64 objective_value; + int64_t time; + int64_t branches; + int64_t failures; + int64_t objective_value; bool operator<(const SolutionData& other) const { return std::tie(solution, time, branches, failures, objective_value) < std::tie(other.solution, other.time, other.branches, @@ -4203,11 +4194,11 @@ class SolutionCollector : public SearchMonitor { /// improvement step. class OptimizeVar : public SearchMonitor { public: - OptimizeVar(Solver* const s, bool maximize, IntVar* const a, int64 step); + OptimizeVar(Solver* const s, bool maximize, IntVar* const a, int64_t step); ~OptimizeVar() override; /// Returns the best value found during search. - int64 best() const { return best_; } + int64_t best() const { return best_; } /// Returns the variable that is optimized. IntVar* Var() const { return var_; } @@ -4226,8 +4217,8 @@ class OptimizeVar : public SearchMonitor { protected: IntVar* const var_; - int64 step_; - int64 best_; + int64_t step_; + int64_t best_; bool maximize_; bool found_initial_solution_; @@ -4280,8 +4271,8 @@ class SearchLimit : public SearchMonitor { /// number of failures in the search tree class RegularLimit : public SearchLimit { public: - RegularLimit(Solver* const s, absl::Duration time, int64 branches, - int64 failures, int64 solutions, bool smart_time_check, + RegularLimit(Solver* const s, absl::Duration time, int64_t branches, + int64_t failures, int64_t solutions, bool smart_time_check, bool cumulative); ~RegularLimit() override; void Copy(const SearchLimit* const limit) override; @@ -4290,17 +4281,17 @@ class RegularLimit : public SearchLimit { bool Check() override; void Init() override; void ExitSearch() override; - void UpdateLimits(absl::Duration time, int64 branches, int64 failures, - int64 solutions); + void UpdateLimits(absl::Duration time, int64_t branches, int64_t failures, + int64_t solutions); absl::Duration duration_limit() const { return duration_limit_; } - int64 wall_time() const { + int64_t wall_time() const { return duration_limit_ == absl::InfiniteDuration() ? kint64max : absl::ToInt64Milliseconds(duration_limit()); } - int64 branches() const { return branches_; } - int64 failures() const { return failures_; } - int64 solutions() const { return solutions_; } + int64_t branches() const { return branches_; } + int64_t failures() const { return failures_; } + int64_t solutions() const { return solutions_; } bool IsUncheckedSolutionLimitReached() override; int ProgressPercent() override; std::string DebugString() const override; @@ -4314,7 +4305,7 @@ class RegularLimit : public SearchLimit { private: bool CheckTime(); absl::Duration TimeElapsed(); - static int64 GetPercent(int64 value, int64 offset, int64 total) { + static int64_t GetPercent(int64_t value, int64_t offset, int64_t total) { return (total > 0 && total < kint64max) ? 100 * (value - offset) / total : -1; } @@ -4322,15 +4313,15 @@ class RegularLimit : public SearchLimit { absl::Duration duration_limit_; absl::Time solver_time_at_limit_start_; absl::Duration last_time_elapsed_; - int64 check_count_; - int64 next_check_; + int64_t check_count_; + int64_t next_check_; bool smart_time_check_; - int64 branches_; - int64 branches_offset_; - int64 failures_; - int64 failures_offset_; - int64 solutions_; - int64 solutions_offset_; + int64_t branches_; + int64_t branches_offset_; + int64_t failures_; + int64_t failures_offset_; + int64_t solutions_; + int64_t solutions_offset_; /// If cumulative if false, then the limit applies to each search /// independently. If it's true, the limit applies globally to all search for /// which this monitor is used. @@ -4374,7 +4365,7 @@ class ImprovementSearchLimit : public SearchLimit { double best_objective_; // clang-format off - std::deque > improvements_; + std::deque > improvements_; // clang-format on double threshold_; bool objective_updated_; @@ -4394,9 +4385,9 @@ class ImprovementSearchLimit : public SearchLimit { class IntervalVar : public PropagationBaseObject { public: /// The smallest acceptable value to be returned by StartMin() - static const int64 kMinValidValue; + static const int64_t kMinValidValue; /// The largest acceptable value to be returned by EndMax() - static const int64 kMaxValidValue; + static const int64_t kMaxValidValue; IntervalVar(Solver* const solver, const std::string& name) : PropagationBaseObject(solver) { set_name(name); @@ -4405,13 +4396,13 @@ class IntervalVar : public PropagationBaseObject { /// These methods query, set, and watch the start position of the /// interval var. - virtual int64 StartMin() const = 0; - virtual int64 StartMax() const = 0; - virtual void SetStartMin(int64 m) = 0; - virtual void SetStartMax(int64 m) = 0; - virtual void SetStartRange(int64 mi, int64 ma) = 0; - virtual int64 OldStartMin() const = 0; - virtual int64 OldStartMax() const = 0; + virtual int64_t StartMin() const = 0; + virtual int64_t StartMax() const = 0; + virtual void SetStartMin(int64_t m) = 0; + virtual void SetStartMax(int64_t m) = 0; + virtual void SetStartRange(int64_t mi, int64_t ma) = 0; + virtual int64_t OldStartMin() const = 0; + virtual int64_t OldStartMax() const = 0; virtual void WhenStartRange(Demon* const d) = 0; void WhenStartRange(Solver::Closure closure) { WhenStartRange(solver()->MakeClosureDemon(std::move(closure))); @@ -4432,13 +4423,13 @@ class IntervalVar : public PropagationBaseObject { #endif // SWIG /// These methods query, set, and watch the duration of the interval var. - virtual int64 DurationMin() const = 0; - virtual int64 DurationMax() const = 0; - virtual void SetDurationMin(int64 m) = 0; - virtual void SetDurationMax(int64 m) = 0; - virtual void SetDurationRange(int64 mi, int64 ma) = 0; - virtual int64 OldDurationMin() const = 0; - virtual int64 OldDurationMax() const = 0; + virtual int64_t DurationMin() const = 0; + virtual int64_t DurationMax() const = 0; + virtual void SetDurationMin(int64_t m) = 0; + virtual void SetDurationMax(int64_t m) = 0; + virtual void SetDurationRange(int64_t mi, int64_t ma) = 0; + virtual int64_t OldDurationMin() const = 0; + virtual int64_t OldDurationMax() const = 0; virtual void WhenDurationRange(Demon* const d) = 0; void WhenDurationRange(Solver::Closure closure) { WhenDurationRange(solver()->MakeClosureDemon(std::move(closure))); @@ -4459,13 +4450,13 @@ class IntervalVar : public PropagationBaseObject { #endif // SWIG /// These methods query, set, and watch the end position of the interval var. - virtual int64 EndMin() const = 0; - virtual int64 EndMax() const = 0; - virtual void SetEndMin(int64 m) = 0; - virtual void SetEndMax(int64 m) = 0; - virtual void SetEndRange(int64 mi, int64 ma) = 0; - virtual int64 OldEndMin() const = 0; - virtual int64 OldEndMax() const = 0; + virtual int64_t EndMin() const = 0; + virtual int64_t EndMax() const = 0; + virtual void SetEndMin(int64_t m) = 0; + virtual void SetEndMax(int64_t m) = 0; + virtual void SetEndRange(int64_t mi, int64_t ma) = 0; + virtual int64_t OldEndMin() const = 0; + virtual int64_t OldEndMax() const = 0; virtual void WhenEndRange(Demon* const d) = 0; void WhenEndRange(Solver::Closure closure) { WhenEndRange(solver()->MakeClosureDemon(std::move(closure))); @@ -4528,9 +4519,9 @@ class IntervalVar : public PropagationBaseObject { /// These methods create expressions encapsulating the start, end /// and duration of the interval var. If the interval var is /// unperformed, they will return the unperformed_value. - virtual IntExpr* SafeStartExpr(int64 unperformed_value) = 0; - virtual IntExpr* SafeDurationExpr(int64 unperformed_value) = 0; - virtual IntExpr* SafeEndExpr(int64 unperformed_value) = 0; + virtual IntExpr* SafeStartExpr(int64_t unperformed_value) = 0; + virtual IntExpr* SafeDurationExpr(int64_t unperformed_value) = 0; + virtual IntExpr* SafeEndExpr(int64_t unperformed_value) = 0; /// Accepts the given visitor. virtual void Accept(ModelVisitor* const visitor) const = 0; @@ -4557,15 +4548,15 @@ class SequenceVar : public PropagationBaseObject { #if !defined(SWIG) /// Returns the minimum and maximum duration of combined interval /// vars in the sequence. - void DurationRange(int64* const dmin, int64* const dmax) const; + void DurationRange(int64_t* const dmin, int64_t* const dmax) const; /// Returns the minimum start min and the maximum end max of all /// interval vars in the sequence. - void HorizonRange(int64* const hmin, int64* const hmax) const; + void HorizonRange(int64_t* const hmin, int64_t* const hmax) const; /// Returns the minimum start min and the maximum end max of all /// unranked interval vars in the sequence. - void ActiveHorizonRange(int64* const hmin, int64* const hmax) const; + void ActiveHorizonRange(int64_t* const hmin, int64_t* const hmax) const; /// Compute statistics on the sequence. void ComputeStatistics(int* const ranked, int* const not_ranked, @@ -4621,7 +4612,7 @@ class SequenceVar : public PropagationBaseObject { IntVar* Next(int index) const; /// Returns the number of interval vars in the sequence. - int64 size() const { return intervals_.size(); } + int64_t size() const { return intervals_.size(); } /// Accepts the given visitor. virtual void Accept(ModelVisitor* const visitor) const; @@ -4668,21 +4659,21 @@ class IntVarElement : public AssignmentElement { void LoadFromProto(const IntVarAssignment& int_var_assignment_proto); void WriteToProto(IntVarAssignment* int_var_assignment_proto) const; - int64 Min() const { return min_; } - void SetMin(int64 m) { min_ = m; } - int64 Max() const { return max_; } - void SetMax(int64 m) { max_ = m; } - int64 Value() const { + int64_t Min() const { return min_; } + void SetMin(int64_t m) { min_ = m; } + int64_t Max() const { return max_; } + void SetMax(int64_t m) { max_ = m; } + int64_t Value() const { DCHECK_EQ(min_, max_); // Get the value from an unbound int var assignment element. return min_; } bool Bound() const { return (max_ == min_); } - void SetRange(int64 l, int64 u) { + void SetRange(int64_t l, int64_t u) { min_ = l; max_ = u; } - void SetValue(int64 v) { + void SetValue(int64_t v) { min_ = v; max_ = v; } @@ -4695,8 +4686,8 @@ class IntVarElement : public AssignmentElement { private: IntVar* var_; - int64 min_; - int64 max_; + int64_t min_; + int64_t max_; }; class IntervalVarElement : public AssignmentElement { @@ -4713,67 +4704,67 @@ class IntervalVarElement : public AssignmentElement { const IntervalVarAssignment& interval_var_assignment_proto); void WriteToProto(IntervalVarAssignment* interval_var_assignment_proto) const; - int64 StartMin() const { return start_min_; } - int64 StartMax() const { return start_max_; } - int64 StartValue() const { + int64_t StartMin() const { return start_min_; } + int64_t StartMax() const { return start_max_; } + int64_t StartValue() const { CHECK_EQ(start_max_, start_min_); return start_max_; } - int64 DurationMin() const { return duration_min_; } - int64 DurationMax() const { return duration_max_; } - int64 DurationValue() const { + int64_t DurationMin() const { return duration_min_; } + int64_t DurationMax() const { return duration_max_; } + int64_t DurationValue() const { CHECK_EQ(duration_max_, duration_min_); return duration_max_; } - int64 EndMin() const { return end_min_; } - int64 EndMax() const { return end_max_; } - int64 EndValue() const { + int64_t EndMin() const { return end_min_; } + int64_t EndMax() const { return end_max_; } + int64_t EndValue() const { CHECK_EQ(end_max_, end_min_); return end_max_; } - int64 PerformedMin() const { return performed_min_; } - int64 PerformedMax() const { return performed_max_; } - int64 PerformedValue() const { + int64_t PerformedMin() const { return performed_min_; } + int64_t PerformedMax() const { return performed_max_; } + int64_t PerformedValue() const { CHECK_EQ(performed_max_, performed_min_); return performed_max_; } - void SetStartMin(int64 m) { start_min_ = m; } - void SetStartMax(int64 m) { start_max_ = m; } - void SetStartRange(int64 mi, int64 ma) { + void SetStartMin(int64_t m) { start_min_ = m; } + void SetStartMax(int64_t m) { start_max_ = m; } + void SetStartRange(int64_t mi, int64_t ma) { start_min_ = mi; start_max_ = ma; } - void SetStartValue(int64 v) { + void SetStartValue(int64_t v) { start_min_ = v; start_max_ = v; } - void SetDurationMin(int64 m) { duration_min_ = m; } - void SetDurationMax(int64 m) { duration_max_ = m; } - void SetDurationRange(int64 mi, int64 ma) { + void SetDurationMin(int64_t m) { duration_min_ = m; } + void SetDurationMax(int64_t m) { duration_max_ = m; } + void SetDurationRange(int64_t mi, int64_t ma) { duration_min_ = mi; duration_max_ = ma; } - void SetDurationValue(int64 v) { + void SetDurationValue(int64_t v) { duration_min_ = v; duration_max_ = v; } - void SetEndMin(int64 m) { end_min_ = m; } - void SetEndMax(int64 m) { end_max_ = m; } - void SetEndRange(int64 mi, int64 ma) { + void SetEndMin(int64_t m) { end_min_ = m; } + void SetEndMax(int64_t m) { end_max_ = m; } + void SetEndRange(int64_t mi, int64_t ma) { end_min_ = mi; end_max_ = ma; } - void SetEndValue(int64 v) { + void SetEndValue(int64_t v) { end_min_ = v; end_max_ = v; } - void SetPerformedMin(int64 m) { performed_min_ = m; } - void SetPerformedMax(int64 m) { performed_max_ = m; } - void SetPerformedRange(int64 mi, int64 ma) { + void SetPerformedMin(int64_t m) { performed_min_ = m; } + void SetPerformedMax(int64_t m) { performed_max_ = m; } + void SetPerformedRange(int64_t mi, int64_t ma) { performed_min_ = mi; performed_max_ = ma; } - void SetPerformedValue(int64 v) { + void SetPerformedValue(int64_t v) { performed_min_ = v; performed_max_ = v; } @@ -4788,14 +4779,14 @@ class IntervalVarElement : public AssignmentElement { } private: - int64 start_min_; - int64 start_max_; - int64 duration_min_; - int64 duration_max_; - int64 end_min_; - int64 end_max_; - int64 performed_min_; - int64 performed_max_; + int64_t start_min_; + int64_t start_max_; + int64_t duration_min_; + int64_t duration_max_; + int64_t end_min_; + int64_t end_max_; + int64_t performed_min_; + int64_t performed_max_; IntervalVar* var_; }; @@ -5079,60 +5070,60 @@ class Assignment : public PropagationBaseObject { void ClearObjective() { objective_element_.Reset(nullptr); } IntVar* Objective() const; bool HasObjective() const { return (objective_element_.Var() != nullptr); } - int64 ObjectiveMin() const; - int64 ObjectiveMax() const; - int64 ObjectiveValue() const; + int64_t ObjectiveMin() const; + int64_t ObjectiveMax() const; + int64_t ObjectiveValue() const; bool ObjectiveBound() const; - void SetObjectiveMin(int64 m); - void SetObjectiveMax(int64 m); - void SetObjectiveValue(int64 value); - void SetObjectiveRange(int64 l, int64 u); + void SetObjectiveMin(int64_t m); + void SetObjectiveMax(int64_t m); + void SetObjectiveValue(int64_t value); + void SetObjectiveRange(int64_t l, int64_t u); IntVarElement* Add(IntVar* const var); void Add(const std::vector& vars); /// Adds without checking if variable has been previously added. IntVarElement* FastAdd(IntVar* const var); - int64 Min(const IntVar* const var) const; - int64 Max(const IntVar* const var) const; - int64 Value(const IntVar* const var) const; + int64_t Min(const IntVar* const var) const; + int64_t Max(const IntVar* const var) const; + int64_t Value(const IntVar* const var) const; bool Bound(const IntVar* const var) const; - void SetMin(const IntVar* const var, int64 m); - void SetMax(const IntVar* const var, int64 m); - void SetRange(const IntVar* const var, int64 l, int64 u); - void SetValue(const IntVar* const var, int64 value); + void SetMin(const IntVar* const var, int64_t m); + void SetMax(const IntVar* const var, int64_t m); + void SetRange(const IntVar* const var, int64_t l, int64_t u); + void SetValue(const IntVar* const var, int64_t value); IntervalVarElement* Add(IntervalVar* const var); void Add(const std::vector& vars); /// Adds without checking if variable has been previously added. IntervalVarElement* FastAdd(IntervalVar* const var); - int64 StartMin(const IntervalVar* const var) const; - int64 StartMax(const IntervalVar* const var) const; - int64 StartValue(const IntervalVar* const var) const; - int64 DurationMin(const IntervalVar* const var) const; - int64 DurationMax(const IntervalVar* const var) const; - int64 DurationValue(const IntervalVar* const var) const; - int64 EndMin(const IntervalVar* const var) const; - int64 EndMax(const IntervalVar* const var) const; - int64 EndValue(const IntervalVar* const var) const; - int64 PerformedMin(const IntervalVar* const var) const; - int64 PerformedMax(const IntervalVar* const var) const; - int64 PerformedValue(const IntervalVar* const var) const; - void SetStartMin(const IntervalVar* const var, int64 m); - void SetStartMax(const IntervalVar* const var, int64 m); - void SetStartRange(const IntervalVar* const var, int64 mi, int64 ma); - void SetStartValue(const IntervalVar* const var, int64 value); - void SetDurationMin(const IntervalVar* const var, int64 m); - void SetDurationMax(const IntervalVar* const var, int64 m); - void SetDurationRange(const IntervalVar* const var, int64 mi, int64 ma); - void SetDurationValue(const IntervalVar* const var, int64 value); - void SetEndMin(const IntervalVar* const var, int64 m); - void SetEndMax(const IntervalVar* const var, int64 m); - void SetEndRange(const IntervalVar* const var, int64 mi, int64 ma); - void SetEndValue(const IntervalVar* const var, int64 value); - void SetPerformedMin(const IntervalVar* const var, int64 m); - void SetPerformedMax(const IntervalVar* const var, int64 m); - void SetPerformedRange(const IntervalVar* const var, int64 mi, int64 ma); - void SetPerformedValue(const IntervalVar* const var, int64 value); + int64_t StartMin(const IntervalVar* const var) const; + int64_t StartMax(const IntervalVar* const var) const; + int64_t StartValue(const IntervalVar* const var) const; + int64_t DurationMin(const IntervalVar* const var) const; + int64_t DurationMax(const IntervalVar* const var) const; + int64_t DurationValue(const IntervalVar* const var) const; + int64_t EndMin(const IntervalVar* const var) const; + int64_t EndMax(const IntervalVar* const var) const; + int64_t EndValue(const IntervalVar* const var) const; + int64_t PerformedMin(const IntervalVar* const var) const; + int64_t PerformedMax(const IntervalVar* const var) const; + int64_t PerformedValue(const IntervalVar* const var) const; + void SetStartMin(const IntervalVar* const var, int64_t m); + void SetStartMax(const IntervalVar* const var, int64_t m); + void SetStartRange(const IntervalVar* const var, int64_t mi, int64_t ma); + void SetStartValue(const IntervalVar* const var, int64_t value); + void SetDurationMin(const IntervalVar* const var, int64_t m); + void SetDurationMax(const IntervalVar* const var, int64_t m); + void SetDurationRange(const IntervalVar* const var, int64_t mi, int64_t ma); + void SetDurationValue(const IntervalVar* const var, int64_t value); + void SetEndMin(const IntervalVar* const var, int64_t m); + void SetEndMax(const IntervalVar* const var, int64_t m); + void SetEndRange(const IntervalVar* const var, int64_t mi, int64_t ma); + void SetEndValue(const IntervalVar* const var, int64_t value); + void SetPerformedMin(const IntervalVar* const var, int64_t m); + void SetPerformedMax(const IntervalVar* const var, int64_t m); + void SetPerformedRange(const IntervalVar* const var, int64_t mi, int64_t ma); + void SetPerformedValue(const IntervalVar* const var, int64_t value); SequenceVarElement* Add(SequenceVar* const var); void Add(const std::vector& vars); @@ -5246,25 +5237,25 @@ class Pack : public Constraint { /// (weights[i]) of all objects i assigned to 'b' is less or equal /// 'bounds[b]'. void AddWeightedSumLessOrEqualConstantDimension( - const std::vector& weights, const std::vector& bounds); + const std::vector& weights, const std::vector& bounds); /// This dimension imposes that for all bins b, the weighted sum /// (weights->Run(i)) of all objects i assigned to 'b' is less or /// equal to 'bounds[b]'. Ownership of the callback is transferred to /// the pack constraint. void AddWeightedSumLessOrEqualConstantDimension( - Solver::IndexEvaluator1 weights, const std::vector& bounds); + Solver::IndexEvaluator1 weights, const std::vector& bounds); /// This dimension imposes that for all bins b, the weighted sum /// (weights->Run(i, b) of all objects i assigned to 'b' is less or /// equal to 'bounds[b]'. Ownership of the callback is transferred to /// the pack constraint. void AddWeightedSumLessOrEqualConstantDimension( - Solver::IndexEvaluator2 weights, const std::vector& bounds); + Solver::IndexEvaluator2 weights, const std::vector& bounds); /// This dimension imposes that for all bins b, the weighted sum /// (weights[i]) of all objects i assigned to 'b' is equal to loads[b]. - void AddWeightedSumEqualVarDimension(const std::vector& weights, + void AddWeightedSumEqualVarDimension(const std::vector& weights, const std::vector& loads); /// This dimension imposes that for all bins b, the weighted sum @@ -5283,11 +5274,11 @@ class Pack : public Constraint { /// the same item on parallel dimensions with an allowed assignment /// constraint. void AddSumVariableWeightsLessOrEqualConstantDimension( - const std::vector& usage, const std::vector& capacity); + const std::vector& usage, const std::vector& capacity); /// This dimension enforces that cost_var == sum of weights[i] for /// all objects 'i' assigned to a bin. - void AddWeightedSumOfAssignedDimension(const std::vector& weights, + void AddWeightedSumOfAssignedDimension(const std::vector& weights, IntVar* const cost_var); /// This dimension links 'count_var' to the actual number of bins used in the @@ -5329,7 +5320,7 @@ class Pack : public Constraint { std::vector> forced_; std::vector> removed_; std::vector holes_; - uint64 stamp_; + uint64_t stamp_; Demon* demon_; std::vector> to_set_; std::vector> to_unset_; @@ -5352,7 +5343,7 @@ class DisjunctiveConstraint : public Constraint { /// a positive or null value. void SetTransitionTime(Solver::IndexEvaluator2 transition_time); - int64 TransitionTime(int before_index, int after_index) { + int64_t TransitionTime(int before_index, int after_index) { DCHECK(transition_time_); return transition_time_(before_index, after_index); } diff --git a/ortools/constraint_solver/constraint_solveri.h b/ortools/constraint_solver/constraint_solveri.h index 2625334d70..9ed92f247f 100644 --- a/ortools/constraint_solver/constraint_solveri.h +++ b/ortools/constraint_solver/constraint_solveri.h @@ -49,37 +49,26 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_ +#include +#include + #include -#include -#include #include #include #include +#include #include #include "absl/container/flat_hash_map.h" #include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/str_join.h" -#include "ortools/base/commandlineflags.h" -#include "ortools/base/hash.h" #include "ortools/base/integral_types.h" #include "ortools/base/logging.h" -#include "ortools/base/map_util.h" -#include "ortools/base/sysinfo.h" #include "ortools/base/timer.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/util/bitset.h" #include "ortools/util/tuple_set.h" -#include "ortools/util/vector_map.h" - -class WallTimer; namespace operations_research { -class CPArgumentProto; -class CPConstraintProto; -class CPIntegerExpressionProto; -class CPIntervalVariableProto; /// This is the base class for all expressions that are not variables. /// It provides a basic 'CastToVar()' implementation. @@ -106,6 +95,8 @@ class CPIntervalVariableProto; /// expression built by the solver, and store the object as an IntVar*. /// This is a consequence of the stateless nature of the expressions that /// makes the code error-prone. +class LocalSearchMonitor; + class BaseIntExpr : public IntExpr { public: explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {} @@ -219,7 +210,7 @@ class SimpleRevFIFO { /// Hash functions // TODO(user): use murmurhash. -inline uint64 Hash1(uint64 value) { +inline uint64_t Hash1(uint64_t value) { value = (~value) + (value << 21); /// value = (value << 21) - value - 1; value ^= value >> 24; value += (value << 3) + (value << 8); /// value * 265 @@ -230,8 +221,8 @@ inline uint64 Hash1(uint64 value) { return value; } -inline uint64 Hash1(uint32 value) { - uint64 a = value; +inline uint64_t Hash1(uint32_t value) { + uint64_t a = value; a = (a + 0x7ed55d16) + (a << 12); a = (a ^ 0xc761c23c) ^ (a >> 19); a = (a + 0x165667b1) + (a << 5); @@ -241,34 +232,34 @@ inline uint64 Hash1(uint32 value) { return a; } -inline uint64 Hash1(int64 value) { return Hash1(static_cast(value)); } +inline uint64_t Hash1(int64_t value) { return Hash1(static_cast(value)); } -inline uint64 Hash1(int value) { return Hash1(static_cast(value)); } +inline uint64_t Hash1(int value) { return Hash1(static_cast(value)); } -inline uint64 Hash1(void* const ptr) { +inline uint64_t Hash1(void* const ptr) { #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \ defined(__aarch64__) - return Hash1(reinterpret_cast(ptr)); + return Hash1(reinterpret_cast(ptr)); #else - return Hash1(reinterpret_cast(ptr)); + return Hash1(reinterpret_cast(ptr)); #endif } template -uint64 Hash1(const std::vector& ptrs) { +uint64_t Hash1(const std::vector& ptrs) { if (ptrs.empty()) return 0; if (ptrs.size() == 1) return Hash1(ptrs[0]); - uint64 hash = Hash1(ptrs[0]); + uint64_t hash = Hash1(ptrs[0]); for (int i = 1; i < ptrs.size(); ++i) { hash = hash * i + Hash1(ptrs[i]); } return hash; } -inline uint64 Hash1(const std::vector& ptrs) { +inline uint64_t Hash1(const std::vector& ptrs) { if (ptrs.empty()) return 0; if (ptrs.size() == 1) return Hash1(ptrs[0]); - uint64 hash = Hash1(ptrs[0]); + uint64_t hash = Hash1(ptrs[0]); for (int i = 1; i < ptrs.size(); ++i) { hash = hash * i + Hash1(ptrs[i]); } @@ -294,7 +285,7 @@ class RevImmutableMultiMap { /// Returns true if the multi-map contains at least one instance of 'key'. bool ContainsKey(const K& key) const { - uint64 code = Hash1(key) % size_.Value(); + uint64_t code = Hash1(key) % size_.Value(); Cell* tmp = array_[code]; while (tmp) { if (tmp->key() == key) { @@ -309,7 +300,7 @@ class RevImmutableMultiMap { /// is not in the multi-map. The actual value returned if more than one /// values is attached to the same key is not specified. const V& FindWithDefault(const K& key, const V& default_value) const { - uint64 code = Hash1(key) % size_.Value(); + uint64_t code = Hash1(key) % size_.Value(); Cell* tmp = array_[code]; while (tmp) { if (tmp->key() == key) { @@ -370,7 +361,7 @@ class RevImmutableMultiMap { while (tmp != nullptr) { Cell* const to_reinsert = tmp; tmp = tmp->next(); - const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value(); + const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value(); to_reinsert->SetRevNext(solver_, array_[new_position]); solver_->SaveAndSetValue( reinterpret_cast(&array_[new_position]), @@ -402,13 +393,13 @@ class RevSwitch { /// This class is useful to maintain supports. class SmallRevBitSet { public: - explicit SmallRevBitSet(int64 size); + explicit SmallRevBitSet(int64_t size); /// Sets the 'pos' bit. - void SetToOne(Solver* const solver, int64 pos); + void SetToOne(Solver* const solver, int64_t pos); /// Erases the 'pos' bit. - void SetToZero(Solver* const solver, int64 pos); + void SetToZero(Solver* const solver, int64_t pos); /// Returns the number of bits set to one. - int64 Cardinality() const; + int64_t Cardinality() const; /// Is bitset null? bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; } /// Does it contains only one bit set? @@ -417,34 +408,34 @@ class SmallRevBitSet { } /// Gets the index of the first bit set starting from 0. /// It returns -1 if the bitset is empty. - int64 GetFirstOne() const; + int64_t GetFirstOne() const; private: - Rev bits_; + Rev bits_; }; /// This class represents a reversible bitset. /// This class is useful to maintain supports. class RevBitSet { public: - explicit RevBitSet(int64 size); + explicit RevBitSet(int64_t size); ~RevBitSet(); /// Sets the 'index' bit. - void SetToOne(Solver* const solver, int64 index); + void SetToOne(Solver* const solver, int64_t index); /// Erases the 'index' bit. - void SetToZero(Solver* const solver, int64 index); + void SetToZero(Solver* const solver, int64_t index); /// Returns whether the 'index' bit is set. - bool IsSet(int64 index) const; + bool IsSet(int64_t index) const; /// Returns the number of bits set to one. - int64 Cardinality() const; + int64_t Cardinality() const; /// Is bitset null? bool IsCardinalityZero() const; /// Does it contains only one bit set? bool IsCardinalityOne() const; /// Gets the index of the first bit set starting from start. /// It returns -1 if the bitset is empty after start. - int64 GetFirstBit(int start) const; + int64_t GetFirstBit(int start) const; /// Cleans all bits. void ClearAll(Solver* const solver); @@ -453,24 +444,24 @@ class RevBitSet { private: /// Save the offset's part of the bitset. void Save(Solver* const solver, int offset); - const int64 size_; - const int64 length_; - uint64* bits_; - uint64* stamps_; + const int64_t size_; + const int64_t length_; + uint64_t* bits_; + uint64_t* stamps_; }; /// Matrix version of the RevBitSet class. class RevBitMatrix : private RevBitSet { public: - RevBitMatrix(int64 rows, int64 columns); + RevBitMatrix(int64_t rows, int64_t columns); ~RevBitMatrix(); /// Sets the 'column' bit in the 'row' row. - void SetToOne(Solver* const solver, int64 row, int64 column); + void SetToOne(Solver* const solver, int64_t row, int64_t column); /// Erases the 'column' bit in the 'row' row. - void SetToZero(Solver* const solver, int64 row, int64 column); + void SetToZero(Solver* const solver, int64_t row, int64_t column); /// Returns whether the 'column' bit in the 'row' row is set. - bool IsSet(int64 row, int64 column) const { + bool IsSet(int64_t row, int64_t column) const { DCHECK_GE(row, 0); DCHECK_LT(row, rows_); DCHECK_GE(column, 0); @@ -478,20 +469,20 @@ class RevBitMatrix : private RevBitSet { return RevBitSet::IsSet(row * columns_ + column); } /// Returns the number of bits set to one in the 'row' row. - int64 Cardinality(int row) const; + int64_t Cardinality(int row) const; /// Is bitset of row 'row' null? bool IsCardinalityZero(int row) const; /// Does the 'row' bitset contains only one bit set? bool IsCardinalityOne(int row) const; /// Returns the first bit in the row 'row' which position is >= 'start'. /// It returns -1 if there are none. - int64 GetFirstBit(int row, int start) const; + int64_t GetFirstBit(int row, int start) const; /// Cleans all bits. void ClearAll(Solver* const solver); private: - const int64 rows_; - const int64 columns_; + const int64_t rows_; + const int64_t columns_; }; /// @{ @@ -840,30 +831,30 @@ class VarLocalSearchOperator : public LocalSearchOperator { int Size() const { return vars_.size(); } /// Returns the value in the current assignment of the variable of given /// index. - const Val& Value(int64 index) const { + const Val& Value(int64_t index) const { DCHECK_LT(index, vars_.size()); return values_[index]; } /// Returns the variable of given index. - V* Var(int64 index) const { return vars_[index]; } + V* Var(int64_t index) const { return vars_[index]; } virtual bool SkipUnchanged(int index) const { return false; } - const Val& OldValue(int64 index) const { return old_values_[index]; } - void SetValue(int64 index, const Val& value) { + const Val& OldValue(int64_t index) const { return old_values_[index]; } + void SetValue(int64_t index, const Val& value) { values_[index] = value; MarkChange(index); } - bool Activated(int64 index) const { return activated_[index]; } - void Activate(int64 index) { + bool Activated(int64_t index) const { return activated_[index]; } + void Activate(int64_t index) { activated_.Set(index); MarkChange(index); } - void Deactivate(int64 index) { + void Deactivate(int64_t index) { activated_.Clear(index); MarkChange(index); } bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const { if (IsIncremental() && !cleared_) { - for (const int64 index : delta_changes_.PositionsSetAtLeastOnce()) { + for (const int64_t index : delta_changes_.PositionsSetAtLeastOnce()) { V* var = Var(index); const Val& value = Value(index); const bool activated = activated_[index]; @@ -874,7 +865,7 @@ class VarLocalSearchOperator : public LocalSearchOperator { } } else { delta->Clear(); - for (const int64 index : changes_.PositionsSetAtLeastOnce()) { + for (const int64_t index : changes_.PositionsSetAtLeastOnce()) { const Val& value = Value(index); const bool activated = activated_[index]; if (!activated || value != OldValue(index) || !SkipUnchanged(index)) { @@ -890,7 +881,7 @@ class VarLocalSearchOperator : public LocalSearchOperator { delta_changes_.SparseClearAll(); if (incremental && IsIncremental()) return; cleared_ = true; - for (const int64 index : changes_.PositionsSetAtLeastOnce()) { + for (const int64_t index : changes_.PositionsSetAtLeastOnce()) { values_[index] = old_values_[index]; var_handler_.OnRevertChanges(index, values_[index]); activated_.CopyBucket(was_activated_, index); @@ -901,7 +892,7 @@ class VarLocalSearchOperator : public LocalSearchOperator { void AddVars(const std::vector& vars) { if (!vars.empty()) { vars_.insert(vars_.end(), vars.begin(), vars.end()); - const int64 size = Size(); + const int64_t size = Size(); values_.resize(size); old_values_.resize(size); prev_values_.resize(size); @@ -922,7 +913,7 @@ class VarLocalSearchOperator : public LocalSearchOperator { /// OnStart() should really be protected, but then SWIG doesn't see it. So we /// make it public, but only subclasses should access to it (to override it). protected: - void MarkChange(int64 index) { + void MarkChange(int64_t index) { delta_changes_.Set(index); changes_.Set(index); } @@ -949,8 +940,8 @@ class IntVarLocalSearchHandler { IntVarLocalSearchHandler(const IntVarLocalSearchHandler& other) : op_(other.op_) {} explicit IntVarLocalSearchHandler(IntVarLocalSearchOperator* op) : op_(op) {} - void AddToAssignment(IntVar* var, int64 value, bool active, - std::vector* assignment_indices, int64 index, + void AddToAssignment(IntVar* var, int64_t value, bool active, + std::vector* assignment_indices, int64_t index, Assignment* assignment) const { Assignment::IntContainer* const container = assignment->MutableIntVarContainer(); @@ -973,8 +964,8 @@ class IntVarLocalSearchHandler { } } bool ValueFromAssignment(const Assignment& assignment, IntVar* var, - int64 index, int64* value); - void OnRevertChanges(int64 index, int64 value); + int64_t index, int64_t* value); + void OnRevertChanges(int64_t index, int64_t value); void OnAddVars() {} private: @@ -997,35 +988,35 @@ class IntVarLocalSearchHandler { /// be extended here. #if defined(SWIGPYTHON) // clang-format off -%unignore VarLocalSearchOperator::Size; -%unignore VarLocalSearchOperator::Value; -%unignore VarLocalSearchOperator::OldValue; -%unignore VarLocalSearchOperator::SetValue; -%feature("director") VarLocalSearchOperator::IsIncremental; -%feature("director") VarLocalSearchOperator::OnStart; -%unignore VarLocalSearchOperator::IsIncremental; -%unignore VarLocalSearchOperator::OnStart; // clang-format on #endif // SWIGPYTHON // clang-format off %rename(IntVarLocalSearchOperatorTemplate) - VarLocalSearchOperator; + VarLocalSearchOperator; %template(IntVarLocalSearchOperatorTemplate) - VarLocalSearchOperator; + VarLocalSearchOperator; // clang-format on #endif // SWIG class IntVarLocalSearchOperator - : public VarLocalSearchOperator { + : public VarLocalSearchOperator { public: IntVarLocalSearchOperator() : max_inverse_value_(-1) {} // If keep_inverse_values is true, assumes that vars models an injective @@ -1033,12 +1024,12 @@ class IntVarLocalSearchOperator // maintain the inverse function. explicit IntVarLocalSearchOperator(const std::vector& vars, bool keep_inverse_values = false) - : VarLocalSearchOperator( + : VarLocalSearchOperator( IntVarLocalSearchHandler(this)), max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) { AddVars(vars); if (keep_inverse_values) { - int64 max_value = -1; + int64_t max_value = -1; for (const IntVar* const var : vars) { max_value = std::max(max_value, var->Max()); } @@ -1064,33 +1055,33 @@ class IntVarLocalSearchOperator /// MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator. virtual bool MakeOneNeighbor(); - bool IsInverseValue(int64 index) const { + bool IsInverseValue(int64_t index) const { DCHECK_GE(index, 0); return index <= max_inverse_value_; } - int64 InverseValue(int64 index) const { return inverse_values_[index]; } + int64_t InverseValue(int64_t index) const { return inverse_values_[index]; } - int64 OldInverseValue(int64 index) const { + int64_t OldInverseValue(int64_t index) const { return old_inverse_values_[index]; } - void SetInverseValue(int64 index, int64 value) { + void SetInverseValue(int64_t index, int64_t value) { inverse_values_[index] = value; } - void SetOldInverseValue(int64 index, int64 value) { + void SetOldInverseValue(int64_t index, int64_t value) { old_inverse_values_[index] = value; } private: - const int64 max_inverse_value_; - std::vector old_inverse_values_; - std::vector inverse_values_; + const int64_t max_inverse_value_; + std::vector old_inverse_values_; + std::vector inverse_values_; }; inline bool IntVarLocalSearchHandler::ValueFromAssignment( - const Assignment& assignment, IntVar* var, int64 index, int64* value) { + const Assignment& assignment, IntVar* var, int64_t index, int64_t* value) { const Assignment::IntContainer& container = assignment.IntVarContainer(); const IntVarElement* element = &(container.Element(index)); if (element->Var() != var) { @@ -1106,8 +1097,8 @@ inline bool IntVarLocalSearchHandler::ValueFromAssignment( return element->Activated(); } -inline void IntVarLocalSearchHandler::OnRevertChanges(int64 index, - int64 value) { +inline void IntVarLocalSearchHandler::OnRevertChanges(int64_t index, + int64_t value) { if (op_->IsInverseValue(index)) { op_->SetInverseValue(value, index); } @@ -1125,10 +1116,10 @@ class SequenceVarLocalSearchHandler { : op_(op) {} void AddToAssignment(SequenceVar* var, const std::vector& value, bool active, std::vector* assignment_indices, - int64 index, Assignment* assignment) const; + int64_t index, Assignment* assignment) const; bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var, - int64 index, std::vector* value); - void OnRevertChanges(int64 index, const std::vector& value); + int64_t index, std::vector* value); + void OnRevertChanges(int64_t index, const std::vector& value); void OnAddVars(); private: @@ -1165,14 +1156,14 @@ class SequenceVarLocalSearchOperator ~SequenceVarLocalSearchOperator() override {} /// Returns the value in the current assignment of the variable of given /// index. - const std::vector& Sequence(int64 index) const { return Value(index); } - const std::vector& OldSequence(int64 index) const { + const std::vector& Sequence(int64_t index) const { return Value(index); } + const std::vector& OldSequence(int64_t index) const { return OldValue(index); } - void SetForwardSequence(int64 index, const std::vector& value) { + void SetForwardSequence(int64_t index, const std::vector& value) { SetValue(index, value); } - void SetBackwardSequence(int64 index, const std::vector& value) { + void SetBackwardSequence(int64_t index, const std::vector& value) { backward_values_[index] = value; MarkChange(index); } @@ -1185,7 +1176,7 @@ class SequenceVarLocalSearchOperator inline void SequenceVarLocalSearchHandler::AddToAssignment( SequenceVar* var, const std::vector& value, bool active, - std::vector* assignment_indices, int64 index, + std::vector* assignment_indices, int64_t index, Assignment* assignment) const { Assignment::SequenceContainer* const container = assignment->MutableSequenceVarContainer(); @@ -1210,7 +1201,7 @@ inline void SequenceVarLocalSearchHandler::AddToAssignment( } inline bool SequenceVarLocalSearchHandler::ValueFromAssignment( - const Assignment& assignment, SequenceVar* var, int64 index, + const Assignment& assignment, SequenceVar* var, int64_t index, std::vector* value) { const Assignment::SequenceContainer& container = assignment.SequenceVarContainer(); @@ -1228,7 +1219,7 @@ inline bool SequenceVarLocalSearchHandler::ValueFromAssignment( } inline void SequenceVarLocalSearchHandler::OnRevertChanges( - int64 index, const std::vector& value) { + int64_t index, const std::vector& value) { op_->backward_values_[index].clear(); } @@ -1291,7 +1282,7 @@ class ChangeValue : public IntVarLocalSearchOperator { public: explicit ChangeValue(const std::vector& vars); ~ChangeValue() override; - virtual int64 ModifyValue(int64 index, int64 value) = 0; + virtual int64_t ModifyValue(int64_t index, int64_t value) = 0; protected: /// This method should not be overridden. Override ModifyValue() instead. @@ -1334,7 +1325,7 @@ class PathOperator : public IntVarLocalSearchOperator { PathOperator(const std::vector& next_vars, const std::vector& path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, bool accept_path_end_base, - std::function start_empty_path_class); + std::function start_empty_path_class); ~PathOperator() override {} virtual bool MakeNeighbor() = 0; void Reset() override; @@ -1343,13 +1334,13 @@ class PathOperator : public IntVarLocalSearchOperator { bool SkipUnchanged(int index) const override; /// Returns the node after node in the current delta. - int64 Next(int64 node) const { + int64_t Next(int64_t node) const { DCHECK(!IsPathEnd(node)); return Value(node); } /// Returns the node before node in the current delta. - int64 Prev(int64 node) const { + int64_t Prev(int64_t node) const { DCHECK(!IsPathStart(node)); DCHECK_EQ(Next(InverseValue(node)), node); return InverseValue(node); @@ -1357,7 +1348,7 @@ class PathOperator : public IntVarLocalSearchOperator { /// Returns the index of the path to which node belongs in the current delta. /// Only returns a valid value if path variables are taken into account. - int64 Path(int64 node) const { + int64_t Path(int64_t node) const { return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_); } @@ -1373,11 +1364,11 @@ class PathOperator : public IntVarLocalSearchOperator { virtual void OnNodeInitialization() {} /// Returns the ith base node of the operator. - int64 BaseNode(int i) const { return base_nodes_[i]; } + int64_t BaseNode(int i) const { return base_nodes_[i]; } /// Returns the alternative for the ith base node. int BaseAlternative(int i) const { return base_alternatives_[i]; } /// Returns the alternative node for the ith base node. - int64 BaseAlternativeNode(int i) const { + int64_t BaseAlternativeNode(int i) const { if (!ConsiderAlternatives(i)) return BaseNode(i); const int alternative_index = alternative_index_[BaseNode(i)]; return alternative_index >= 0 @@ -1389,7 +1380,7 @@ class PathOperator : public IntVarLocalSearchOperator { return base_sibling_alternatives_[i]; } /// Returns the alternative node for the sibling of the ith base node. - int64 BaseSiblingAlternativeNode(int i) const { + int64_t BaseSiblingAlternativeNode(int i) const { if (!ConsiderAlternatives(i)) return BaseNode(i); const int sibling_alternative_index = GetSiblingAlternativeIndex(BaseNode(i)); @@ -1399,9 +1390,9 @@ class PathOperator : public IntVarLocalSearchOperator { : BaseNode(i); } /// Returns the start node of the ith base node. - int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; } + int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; } /// Returns the vector of path start nodes. - const std::vector& path_starts() const { return path_starts_; } + const std::vector& path_starts() const { return path_starts_; } /// Returns the class of the path of the ith base node. int PathClass(int i) const { return start_empty_path_class_ != nullptr @@ -1420,58 +1411,58 @@ class PathOperator : public IntVarLocalSearchOperator { /// Returns true if a base node has to be on the same path as the "previous" /// base node (base node of index base_index - 1). /// Useful to limit neighborhood exploration to nodes on the same path. - // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2); + // TODO(user): ideally this should be OnSamePath(int64_t node1, int64_t node2); /// it's currently way more complicated to implement. - virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; } + virtual bool OnSamePathAsPreviousBase(int64_t base_index) { return false; } /// Returns the index of the node to which the base node of index base_index /// must be set to when it reaches the end of a path. /// By default, it is set to the start of the current path. /// When this method is called, one can only assume that base nodes with /// indices < base_index have their final position. - virtual int64 GetBaseNodeRestartPosition(int base_index) { + virtual int64_t GetBaseNodeRestartPosition(int base_index) { return StartNode(base_index); } /// Set the next base to increment on next iteration. All base > base_index /// will be reset to their start value. - virtual void SetNextBaseToIncrement(int64 base_index) { + virtual void SetNextBaseToIncrement(int64_t base_index) { next_base_to_increment_ = base_index; } /// Indicates if alternatives should be considered when iterating over base /// nodes. - virtual bool ConsiderAlternatives(int64 base_index) const { return false; } + virtual bool ConsiderAlternatives(int64_t base_index) const { return false; } - int64 OldNext(int64 node) const { + int64_t OldNext(int64_t node) const { DCHECK(!IsPathEnd(node)); return OldValue(node); } - int64 OldPrev(int64 node) const { + int64_t OldPrev(int64_t node) const { DCHECK(!IsPathStart(node)); return OldInverseValue(node); } - int64 OldPath(int64 node) const { + int64_t OldPath(int64_t node) const { return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_); } /// Moves the chain starting after the node before_chain and ending at the /// node chain_end after the node destination - bool MoveChain(int64 before_chain, int64 chain_end, int64 destination); + bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination); /// Reverses the chain starting after before_chain and ending before /// after_chain - bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last); + bool ReverseChain(int64_t before_chain, int64_t after_chain, int64_t* chain_last); /// Insert the inactive node after destination. - bool MakeActive(int64 node, int64 destination); + bool MakeActive(int64_t node, int64_t destination); /// Makes the nodes on the chain starting after before_chain and ending at /// chain_end inactive. - bool MakeChainInactive(int64 before_chain, int64 chain_end); + bool MakeChainInactive(int64_t before_chain, int64_t chain_end); /// Replaces active by inactive in the current path, making active inactive. - bool SwapActiveAndInactive(int64 active, int64 inactive); + bool SwapActiveAndInactive(int64_t active, int64_t inactive); /// Sets 'to' to be the node after 'from' on the given path. - void SetNext(int64 from, int64 to, int64 path) { + void SetNext(int64_t from, int64_t to, int64_t path) { DCHECK_LT(from, number_of_nexts_); SetValue(from, to); SetInverseValue(to, from); @@ -1483,13 +1474,13 @@ class PathOperator : public IntVarLocalSearchOperator { /// Returns true if node is the last node on the path; defined by the fact /// that node is outside the range of the variable array. - bool IsPathEnd(int64 node) const { return node >= number_of_nexts_; } + bool IsPathEnd(int64_t node) const { return node >= number_of_nexts_; } /// Returns true if node is the first node on the path. - bool IsPathStart(int64 node) const { return OldInverseValue(node) == -1; } + bool IsPathStart(int64_t node) const { return OldInverseValue(node) == -1; } /// Returns true if node is inactive. - bool IsInactive(int64 node) const { + bool IsInactive(int64_t node) const { return !IsPathEnd(node) && inactives_[node]; } @@ -1504,9 +1495,9 @@ class PathOperator : public IntVarLocalSearchOperator { /// Handling node alternatives. /// Adds a set of node alternatives to the neighborhood. No node can be in /// two altrnatives. - int AddAlternativeSet(const std::vector& alternative_set) { + int AddAlternativeSet(const std::vector& alternative_set) { const int alternative = alternative_sets_.size(); - for (int64 node : alternative_set) { + for (int64_t node : alternative_set) { DCHECK_EQ(-1, alternative_index_[node]); alternative_index_[node] = alternative; } @@ -1518,7 +1509,7 @@ class PathOperator : public IntVarLocalSearchOperator { /// Adds all sets of node alternatives of a vector of alternative pairs. No /// node can be in two altrnatives. void AddPairAlternativeSets( - const std::vector, std::vector>>& + const std::vector, std::vector>>& pair_alternative_sets) { for (const auto& pair_alternative_set : pair_alternative_sets) { const int alternative = AddAlternativeSet(pair_alternative_set.first); @@ -1528,13 +1519,13 @@ class PathOperator : public IntVarLocalSearchOperator { } #endif // SWIG /// Returns the active node in the given alternative set. - int64 GetActiveInAlternativeSet(int alternative_index) const { + int64_t GetActiveInAlternativeSet(int alternative_index) const { return alternative_index >= 0 ? active_in_alternative_set_[alternative_index] : -1; } /// Returns the active node in the alternative set of the given node. - int64 GetActiveAlternativeNode(int node) const { + int64_t GetActiveAlternativeNode(int node) const { return GetActiveInAlternativeSet(alternative_index_[node]); } /// Returns the index of the alternative set of the sibling of node. @@ -1545,7 +1536,7 @@ class PathOperator : public IntVarLocalSearchOperator { } /// Returns the active node in the alternative set of the sibling of the given /// node. - int64 GetActiveAlternativeSibling(int node) const { + int64_t GetActiveAlternativeSibling(int node) const { if (node >= alternative_index_.size()) return -1; const int alternative = alternative_index_[node]; const int sibling_alternative = @@ -1554,19 +1545,19 @@ class PathOperator : public IntVarLocalSearchOperator { } /// Returns true if the chain is a valid path without cycles from before_chain /// to chain_end and does not contain exclude. - bool CheckChainValidity(int64 before_chain, int64 chain_end, - int64 exclude) const; + bool CheckChainValidity(int64_t before_chain, int64_t chain_end, + int64_t exclude) const; const int number_of_nexts_; const bool ignore_path_vars_; int next_base_to_increment_; int num_paths_ = 0; - std::vector start_to_path_; + std::vector start_to_path_; private: void OnStart() override; /// Returns true if two nodes are on the same path in the current assignment. - bool OnSamePath(int64 node1, int64 node2) const; + bool OnSamePath(int64_t node1, int64_t node2) const; bool CheckEnds() const { const int base_node_size = base_nodes_.size(); @@ -1589,22 +1580,22 @@ class PathOperator : public IntVarLocalSearchOperator { std::vector base_sibling_alternatives_; std::vector end_nodes_; std::vector base_paths_; - std::vector path_starts_; + std::vector path_starts_; std::vector inactives_; bool just_started_; bool first_start_; const bool accept_path_end_base_; - std::function start_empty_path_class_; + std::function start_empty_path_class_; bool skip_locally_optimal_paths_; bool optimal_paths_enabled_; std::vector path_basis_; std::vector optimal_paths_; /// Node alternative data. #ifndef SWIG - std::vector> alternative_sets_; + std::vector> alternative_sets_; #endif // SWIG std::vector alternative_index_; - std::vector active_in_alternative_set_; + std::vector active_in_alternative_set_; std::vector sibling_alternative_; }; @@ -1613,22 +1604,22 @@ template LocalSearchOperator* MakeLocalSearchOperator( Solver* solver, const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class); + std::function start_empty_path_class); /// Classes to which this template function can be applied to as of 04/2014. /// Usage: LocalSearchOperator* op = MakeLocalSearchOperator(...); -class TwoOpt; -class Relocate; -class Exchange; -class Cross; -class MakeActiveOperator; -class MakeInactiveOperator; -class MakeChainInactiveOperator; -class SwapActiveOperator; -class ExtendedSwapActiveOperator; -class MakeActiveAndRelocate; -class RelocateAndMakeActiveOperator; -class RelocateAndMakeInactiveOperator; +/// class TwoOpt; +/// class Relocate; +/// class Exchange; +/// class Cross; +/// class MakeActiveOperator; +/// class MakeInactiveOperator; +/// class MakeChainInactiveOperator; +/// class SwapActiveOperator; +/// class ExtendedSwapActiveOperator; +/// class MakeActiveAndRelocate; +/// class RelocateAndMakeActiveOperator; +/// class RelocateAndMakeInactiveOperator; #if !defined(SWIG) // A LocalSearchState is a container for variables with bounds that can be @@ -1643,9 +1634,10 @@ class RelocateAndMakeInactiveOperator; // be marked as invalid. No other operations than Revert() can be called on an // invalid state: in particular, an invalid state cannot be saved. class LocalSearchVariable; + class LocalSearchState { public: - LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max); + LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max); void Commit(); void Revert(); bool StateIsValid() const { return state_is_valid_; } @@ -1654,15 +1646,15 @@ class LocalSearchState { friend class LocalSearchVariable; struct Bounds { - int64 min; - int64 max; + int64_t min; + int64_t max; }; void RelaxVariableBounds(int variable_index); - bool TightenVariableMin(int variable_index, int64 value); - bool TightenVariableMax(int variable_index, int64 value); - int64 VariableMin(int variable_index) const; - int64 VariableMax(int variable_index) const; + bool TightenVariableMin(int variable_index, int64_t value); + bool TightenVariableMax(int variable_index, int64_t value); + int64_t VariableMin(int variable_index) const; + int64_t VariableMax(int variable_index) const; std::vector initial_variable_bounds_; std::vector variable_bounds_; @@ -1678,12 +1670,12 @@ class LocalSearchState { // to ensure that variable users will not misuse the state. class LocalSearchVariable { public: - int64 Min() const { return state_->VariableMin(variable_index_); } - int64 Max() const { return state_->VariableMax(variable_index_); } - bool SetMin(int64 new_min) { + int64_t Min() const { return state_->VariableMin(variable_index_); } + int64_t Max() const { return state_->VariableMax(variable_index_); } + bool SetMin(int64_t new_min) { return state_->TightenVariableMin(variable_index_, new_min); } - bool SetMax(int64 new_max) { + bool SetMax(int64_t new_max) { return state_->TightenVariableMax(variable_index_, new_max); } void Relax() { state_->RelaxVariableBounds(variable_index_); } @@ -1734,7 +1726,7 @@ class LocalSearchFilter : public BaseObject { /// but the delta (a,0) will be accepted. /// TODO(user): Remove arguments when there are no more need for those. virtual bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) = 0; + int64_t objective_min, int64_t objective_max) = 0; virtual bool IsIncremental() const { return false; } /// Synchronizes the filter with the current solution, delta being the @@ -1751,10 +1743,10 @@ class LocalSearchFilter : public BaseObject { virtual void Reset() {} /// Objective value from last time Synchronize() was called. - virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; } + virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; } /// Objective value from the last time Accept() was called and returned true. // If the last Accept() call returned false, returns an undefined value. - virtual int64 GetAcceptedObjectiveValue() const { return 0LL; } + virtual int64_t GetAcceptedObjectiveValue() const { return 0LL; } }; /// Filter manager: when a move is made, filters are executed to decide whether @@ -1787,12 +1779,12 @@ class LocalSearchFilterManager : public BaseObject { /// objectives is between objective_min and objective_max. /// The monitor has its Begin/EndFiltering events triggered. bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta, - const Assignment* deltadelta, int64 objective_min, - int64 objective_max); + const Assignment* deltadelta, int64_t objective_min, + int64_t objective_max); /// Synchronizes all filters to assignment. void Synchronize(const Assignment* assignment, const Assignment* delta); - int64 GetSynchronizedObjectiveValue() const { return synchronized_value_; } - int64 GetAcceptedObjectiveValue() const { return accepted_value_; } + int64_t GetSynchronizedObjectiveValue() const { return synchronized_value_; } + int64_t GetAcceptedObjectiveValue() const { return accepted_value_; } private: void InitializeForcedEvents(); @@ -1804,8 +1796,8 @@ class LocalSearchFilterManager : public BaseObject { // To ensure that those filters have consistent inputs, all intermediate // Relax events are also triggered. All those events are called 'forced'. std::vector next_forced_events_; - int64 synchronized_value_; - int64 accepted_value_; + int64_t synchronized_value_; + int64_t accepted_value_; }; class IntVarLocalSearchFilter : public LocalSearchFilter { @@ -1817,7 +1809,7 @@ class IntVarLocalSearchFilter : public LocalSearchFilter { void Synchronize(const Assignment* assignment, const Assignment* delta) override; - bool FindIndex(IntVar* const var, int64* index) const { + bool FindIndex(IntVar* const var, int64_t* index) const { DCHECK(index != nullptr); const int var_index = var->index(); *index = (var_index < var_index_to_index_.size()) @@ -1830,7 +1822,7 @@ class IntVarLocalSearchFilter : public LocalSearchFilter { void AddVars(const std::vector& vars); int Size() const { return vars_.size(); } IntVar* Var(int index) const { return vars_[index]; } - int64 Value(int index) const { + int64_t Value(int index) const { DCHECK(IsVarSynced(index)); return values_[index]; } @@ -1842,7 +1834,7 @@ class IntVarLocalSearchFilter : public LocalSearchFilter { private: std::vector vars_; - std::vector values_; + std::vector values_; std::vector var_synced_; std::vector var_index_to_index_; static const int kUnassigned; @@ -1871,33 +1863,33 @@ class PropagationMonitor : public SearchMonitor { virtual void PushContext(const std::string& context) = 0; virtual void PopContext() = 0; /// IntExpr modifiers. - virtual void SetMin(IntExpr* const expr, int64 new_min) = 0; - virtual void SetMax(IntExpr* const expr, int64 new_max) = 0; - virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0; + virtual void SetMin(IntExpr* const expr, int64_t new_min) = 0; + virtual void SetMax(IntExpr* const expr, int64_t new_max) = 0; + virtual void SetRange(IntExpr* const expr, int64_t new_min, int64_t new_max) = 0; /// IntVar modifiers. - virtual void SetMin(IntVar* const var, int64 new_min) = 0; - virtual void SetMax(IntVar* const var, int64 new_max) = 0; - virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0; - virtual void RemoveValue(IntVar* const var, int64 value) = 0; - virtual void SetValue(IntVar* const var, int64 value) = 0; - virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0; + virtual void SetMin(IntVar* const var, int64_t new_min) = 0; + virtual void SetMax(IntVar* const var, int64_t new_max) = 0; + virtual void SetRange(IntVar* const var, int64_t new_min, int64_t new_max) = 0; + virtual void RemoveValue(IntVar* const var, int64_t value) = 0; + virtual void SetValue(IntVar* const var, int64_t value) = 0; + virtual void RemoveInterval(IntVar* const var, int64_t imin, int64_t imax) = 0; virtual void SetValues(IntVar* const var, - const std::vector& values) = 0; + const std::vector& values) = 0; virtual void RemoveValues(IntVar* const var, - const std::vector& values) = 0; + const std::vector& values) = 0; /// IntervalVar modifiers. - virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0; - virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0; - virtual void SetStartRange(IntervalVar* const var, int64 new_min, - int64 new_max) = 0; - virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0; - virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0; - virtual void SetEndRange(IntervalVar* const var, int64 new_min, - int64 new_max) = 0; - virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0; - virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0; - virtual void SetDurationRange(IntervalVar* const var, int64 new_min, - int64 new_max) = 0; + virtual void SetStartMin(IntervalVar* const var, int64_t new_min) = 0; + virtual void SetStartMax(IntervalVar* const var, int64_t new_max) = 0; + virtual void SetStartRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) = 0; + virtual void SetEndMin(IntervalVar* const var, int64_t new_min) = 0; + virtual void SetEndMax(IntervalVar* const var, int64_t new_max) = 0; + virtual void SetEndRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) = 0; + virtual void SetDurationMin(IntervalVar* const var, int64_t new_min) = 0; + virtual void SetDurationMax(IntervalVar* const var, int64_t new_max) = 0; + virtual void SetDurationRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) = 0; virtual void SetPerformed(IntervalVar* const var, bool value) = 0; /// SequenceVar modifiers virtual void RankFirst(SequenceVar* const var, int index) = 0; @@ -1948,32 +1940,32 @@ class BooleanVar : public IntVar { ~BooleanVar() override {} - int64 Min() const override { return (value_ == 1); } - void SetMin(int64 m) override; - int64 Max() const override { return (value_ != 0); } - void SetMax(int64 m) override; - void SetRange(int64 mi, int64 ma) override; + int64_t Min() const override { return (value_ == 1); } + void SetMin(int64_t m) override; + int64_t Max() const override { return (value_ != 0); } + void SetMax(int64_t m) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override { return (value_ != kUnboundBooleanVarValue); } - int64 Value() const override { + int64_t Value() const override { CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound"; return value_; } - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; void WhenBound(Demon* d) override; void WhenRange(Demon* d) override { WhenBound(d); } void WhenDomain(Demon* d) override { WhenBound(d); } - uint64 Size() const override; - bool Contains(int64 v) const override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; IntVarIterator* MakeHoleIterator(bool reversible) const override; IntVarIterator* MakeDomainIterator(bool reversible) const override; std::string DebugString() const override; int VarType() const override { return BOOLEAN_VAR; } - IntVar* IsEqual(int64 constant) override; - IntVar* IsDifferent(int64 constant) override; - IntVar* IsGreaterOrEqual(int64 constant) override; - IntVar* IsLessOrEqual(int64 constant) override; + IntVar* IsEqual(int64_t constant) override; + IntVar* IsDifferent(int64_t constant) override; + IntVar* IsGreaterOrEqual(int64_t constant) override; + IntVar* IsLessOrEqual(int64_t constant) override; virtual void RestoreValue() = 0; std::string BaseName() const override { return "BooleanVar"; } @@ -1997,10 +1989,10 @@ class SymmetryBreaker : public DecisionVisitor { : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {} ~SymmetryBreaker() override {} - void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value); + void AddIntegerVariableEqualValueClause(IntVar* const var, int64_t value); void AddIntegerVariableGreaterOrEqualValueClause(IntVar* const var, - int64 value); - void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value); + int64_t value); + void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64_t value); private: friend class SymmetryManager; @@ -2057,9 +2049,9 @@ class SearchLog : public SearchMonitor { std::function display_callback_; const bool display_on_new_solutions_only_; int nsol_; - int64 tick_; - int64 objective_min_; - int64 objective_max_; + int64_t tick_; + int64_t objective_min_; + int64_t objective_max_; int min_right_depth_; int max_depth_; int sliding_min_depth_; @@ -2181,20 +2173,20 @@ class ModelCache { /// Var Constant Constraints. virtual Constraint* FindVarConstantConstraint( - IntVar* const var, int64 value, VarConstantConstraintType type) const = 0; + IntVar* const var, int64_t value, VarConstantConstraintType type) const = 0; virtual void InsertVarConstantConstraint(Constraint* const ct, - IntVar* const var, int64 value, + IntVar* const var, int64_t value, VarConstantConstraintType type) = 0; /// Var Constant Constant Constraints. virtual Constraint* FindVarConstantConstantConstraint( - IntVar* const var, int64 value1, int64 value2, + IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) const = 0; virtual void InsertVarConstantConstantConstraint( - Constraint* const ct, IntVar* const var, int64 value1, int64 value2, + Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) = 0; /// Expr Expr Constraints. @@ -2220,11 +2212,11 @@ class ModelCache { /// Expr Constant Expressions. virtual IntExpr* FindExprConstantExpression( - IntExpr* const expr, int64 value, + IntExpr* const expr, int64_t value, ExprConstantExpressionType type) const = 0; virtual void InsertExprConstantExpression( - IntExpr* const expression, IntExpr* const var, int64 value, + IntExpr* const expression, IntExpr* const var, int64_t value, ExprConstantExpressionType type) = 0; /// Expr Expr Expressions. @@ -2241,32 +2233,32 @@ class ModelCache { /// Expr Expr Constant Expressions. virtual IntExpr* FindExprExprConstantExpression( - IntExpr* const var1, IntExpr* const var2, int64 constant, + IntExpr* const var1, IntExpr* const var2, int64_t constant, ExprExprConstantExpressionType type) const = 0; virtual void InsertExprExprConstantExpression( IntExpr* const expression, IntExpr* const var1, IntExpr* const var2, - int64 constant, ExprExprConstantExpressionType type) = 0; + int64_t constant, ExprExprConstantExpressionType type) = 0; /// Var Constant Constant Expressions. virtual IntExpr* FindVarConstantConstantExpression( - IntVar* const var, int64 value1, int64 value2, + IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) const = 0; virtual void InsertVarConstantConstantExpression( - IntExpr* const expression, IntVar* const var, int64 value1, int64 value2, + IntExpr* const expression, IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) = 0; /// Var Constant Array Expressions. virtual IntExpr* FindVarConstantArrayExpression( - IntVar* const var, const std::vector& values, + IntVar* const var, const std::vector& values, VarConstantArrayExpressionType type) const = 0; virtual void InsertVarConstantArrayExpression( IntExpr* const expression, IntVar* const var, - const std::vector& values, + const std::vector& values, VarConstantArrayExpressionType type) = 0; /// Var Array Expressions. @@ -2281,22 +2273,22 @@ class ModelCache { /// Var Array Constant Array Expressions. virtual IntExpr* FindVarArrayConstantArrayExpression( - const std::vector& vars, const std::vector& values, + const std::vector& vars, const std::vector& values, VarArrayConstantArrayExpressionType type) const = 0; virtual void InsertVarArrayConstantArrayExpression( IntExpr* const expression, const std::vector& var, - const std::vector& values, + const std::vector& values, VarArrayConstantArrayExpressionType type) = 0; /// Var Array Constant Expressions. virtual IntExpr* FindVarArrayConstantExpression( - const std::vector& vars, int64 value, + const std::vector& vars, int64_t value, VarArrayConstantExpressionType type) const = 0; virtual void InsertVarArrayConstantExpression( - IntExpr* const expression, const std::vector& var, int64 value, + IntExpr* const expression, const std::vector& var, int64_t value, VarArrayConstantExpressionType type) = 0; Solver* solver() const; @@ -2314,9 +2306,9 @@ class ArgumentHolder { void SetTypeName(const std::string& type_name); /// Setters. - void SetIntegerArgument(const std::string& arg_name, int64 value); + void SetIntegerArgument(const std::string& arg_name, int64_t value); void SetIntegerArrayArgument(const std::string& arg_name, - const std::vector& values); + const std::vector& values); void SetIntegerMatrixArgument(const std::string& arg_name, const IntTupleSet& values); void SetIntegerExpressionArgument(const std::string& arg_name, @@ -2335,10 +2327,10 @@ class ArgumentHolder { bool HasIntegerVariableArrayArgument(const std::string& arg_name) const; /// Getters. - int64 FindIntegerArgumentWithDefault(const std::string& arg_name, - int64 def) const; - int64 FindIntegerArgumentOrDie(const std::string& arg_name) const; - const std::vector& FindIntegerArrayArgumentOrDie( + int64_t FindIntegerArgumentWithDefault(const std::string& arg_name, + int64_t def) const; + int64_t FindIntegerArgumentOrDie(const std::string& arg_name) const; + const std::vector& FindIntegerArrayArgumentOrDie( const std::string& arg_name) const; const IntTupleSet& FindIntegerMatrixArgumentOrDie( const std::string& arg_name) const; @@ -2350,8 +2342,8 @@ class ArgumentHolder { private: std::string type_name_; - absl::flat_hash_map integer_argument_; - absl::flat_hash_map> integer_array_argument_; + absl::flat_hash_map integer_argument_; + absl::flat_hash_map> integer_array_argument_; absl::flat_hash_map matrix_argument_; absl::flat_hash_map integer_expression_argument_; absl::flat_hash_map interval_argument_; @@ -2385,16 +2377,16 @@ class ModelParser : public ModelVisitor { void VisitIntegerVariable(const IntVar* const variable, IntExpr* const delegate) override; void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override; void VisitIntervalVariable(const IntervalVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntervalVar* const delegate) override; void VisitSequenceVariable(const SequenceVar* const variable) override; /// Integer arguments - void VisitIntegerArgument(const std::string& arg_name, int64 value) override; + void VisitIntegerArgument(const std::string& arg_name, int64_t value) override; void VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) override; + const std::vector& values) override; void VisitIntegerMatrixArgument(const std::string& arg_name, const IntTupleSet& values) override; /// Variables. @@ -2428,7 +2420,7 @@ class ModelParser : public ModelVisitor { template class ArrayWithOffset : public BaseObject { public: - ArrayWithOffset(int64 index_min, int64 index_max) + ArrayWithOffset(int64_t index_min, int64_t index_max) : index_min_(index_min), index_max_(index_max), values_(new T[index_max - index_min + 1]) { @@ -2437,13 +2429,13 @@ class ArrayWithOffset : public BaseObject { ~ArrayWithOffset() override {} - virtual T Evaluate(int64 index) const { + virtual T Evaluate(int64_t index) const { DCHECK_GE(index, index_min_); DCHECK_LE(index, index_max_); return values_[index - index_min_]; } - void SetValue(int64 index, T value) { + void SetValue(int64_t index, T value) { DCHECK_GE(index, index_min_); DCHECK_LE(index, index_max_); values_[index - index_min_] = value; @@ -2452,8 +2444,8 @@ class ArrayWithOffset : public BaseObject { std::string DebugString() const override { return "ArrayWithOffset"; } private: - const int64 index_min_; - const int64 index_max_; + const int64_t index_min_; + const int64_t index_max_; std::unique_ptr values_; }; #endif // SWIG @@ -2465,7 +2457,7 @@ class ArrayWithOffset : public BaseObject { template class RevGrowingArray { public: - explicit RevGrowingArray(int64 block_size) + explicit RevGrowingArray(int64_t block_size) : block_size_(block_size), block_offset_(0) { CHECK_GT(block_size, 0); } @@ -2476,9 +2468,9 @@ class RevGrowingArray { } } - T At(int64 index) const { - const int64 block_index = ComputeBlockIndex(index); - const int64 relative_index = block_index - block_offset_; + T At(int64_t index) const { + const int64_t block_index = ComputeBlockIndex(index); + const int64_t relative_index = block_index - block_offset_; if (relative_index < 0 || relative_index >= elements_.size()) { return T(); } @@ -2486,10 +2478,10 @@ class RevGrowingArray { return block != nullptr ? block[index - block_index * block_size_] : T(); } - void RevInsert(Solver* const solver, int64 index, T value) { - const int64 block_index = ComputeBlockIndex(index); + void RevInsert(Solver* const solver, int64_t index, T value) { + const int64_t block_index = ComputeBlockIndex(index); T* const block = GetOrCreateBlock(block_index); - const int64 residual = index - block_index * block_size_; + const int64_t residual = index - block_index * block_size_; solver->SaveAndSetValue(reinterpret_cast(&block[residual]), reinterpret_cast(value)); } @@ -2520,23 +2512,23 @@ class RevGrowingArray { return block; } - int64 ComputeBlockIndex(int64 value) const { + int64_t ComputeBlockIndex(int64_t value) const { return value >= 0 ? value / block_size_ : (value - block_size_ + 1) / block_size_; } - void GrowUp(int64 block_index) { + void GrowUp(int64_t block_index) { elements_.resize(block_index - block_offset_ + 1); } - void GrowDown(int64 block_index) { - const int64 delta = block_offset_ - block_index; + void GrowDown(int64_t block_index) { + const int64_t delta = block_offset_ - block_index; block_offset_ = block_index; DCHECK_GT(delta, 0); elements_.insert(elements_.begin(), delta, nullptr); } - const int64 block_size_; + const int64_t block_size_; std::vector elements_; int block_offset_; }; @@ -2781,15 +2773,15 @@ class UnsortedNullableRevBitset { /// This methods overwrites the active bitset with the mask. This method /// should be called only once. - void Init(Solver* const solver, const std::vector& mask); + void Init(Solver* const solver, const std::vector& mask); /// This method subtracts the mask from the active bitset. It returns true if /// the active bitset was changed in the process. - bool RevSubtract(Solver* const solver, const std::vector& mask); + bool RevSubtract(Solver* const solver, const std::vector& mask); /// This method ANDs the mask with the active bitset. It returns true if /// the active bitset was changed in the process. - bool RevAnd(Solver* const solver, const std::vector& mask); + bool RevAnd(Solver* const solver, const std::vector& mask); /// This method returns the number of non null 64 bit words in the bitset /// representation. @@ -2805,21 +2797,21 @@ class UnsortedNullableRevBitset { /// - If the intersection is not null, the support_index will be filled with /// the index of the word that does intersect with the mask. This can be /// reused later to speed-up the check. - bool Intersects(const std::vector& mask, int* support_index); + bool Intersects(const std::vector& mask, int* support_index); /// Returns the number of bits given in the constructor of the bitset. - int64 bit_size() const { return bit_size_; } + int64_t bit_size() const { return bit_size_; } /// Returns the number of 64 bit words used to store the bitset. - int64 word_size() const { return word_size_; } + int64_t word_size() const { return word_size_; } /// Returns the set of active word indices. const RevIntSet& active_words() const { return active_words_; } private: void CleanUpActives(Solver* const solver); - const int64 bit_size_; - const int64 word_size_; - RevArray bits_; + const int64_t bit_size_; + const int64_t word_size_; + RevArray bits_; RevIntSet active_words_; std::vector to_remove_; }; @@ -2952,7 +2944,7 @@ bool AreAllBoundOrNull(const std::vector& vars, } /// Returns true if all variables are assigned to 'value'. -inline bool AreAllBoundTo(const std::vector& vars, int64 value) { +inline bool AreAllBoundTo(const std::vector& vars, int64_t value) { for (int i = 0; i < vars.size(); ++i) { if (!vars[i]->Bound() || vars[i]->Min() != value) { return false; @@ -2961,28 +2953,28 @@ inline bool AreAllBoundTo(const std::vector& vars, int64 value) { return true; } -inline int64 MaxVarArray(const std::vector& vars) { +inline int64_t MaxVarArray(const std::vector& vars) { DCHECK(!vars.empty()); - int64 result = kint64min; + int64_t result = kint64min; for (int i = 0; i < vars.size(); ++i) { - /// The std::max is needed for compilation on MSVC. - result = std::max(result, vars[i]->Max()); + /// The std::max is needed for compilation on MSVC. + result = std::max(result, vars[i]->Max()); } return result; } -inline int64 MinVarArray(const std::vector& vars) { +inline int64_t MinVarArray(const std::vector& vars) { DCHECK(!vars.empty()); - int64 result = kint64max; + int64_t result = kint64max; for (int i = 0; i < vars.size(); ++i) { - /// The std::min is needed for compilation on MSVC. - result = std::min(result, vars[i]->Min()); + /// The std::min is needed for compilation on MSVC. + result = std::min(result, vars[i]->Min()); } return result; } inline void FillValues(const std::vector& vars, - std::vector* const values) { + std::vector* const values) { values->clear(); values->resize(vars.size()); for (int i = 0; i < vars.size(); ++i) { @@ -2990,17 +2982,17 @@ inline void FillValues(const std::vector& vars, } } -inline int64 PosIntDivUp(int64 e, int64 v) { +inline int64_t PosIntDivUp(int64_t e, int64_t v) { DCHECK_GT(v, 0); return (e < 0 || e % v == 0) ? e / v : e / v + 1; } -inline int64 PosIntDivDown(int64 e, int64 v) { +inline int64_t PosIntDivDown(int64_t e, int64_t v) { DCHECK_GT(v, 0); return (e >= 0 || e % v == 0) ? e / v : e / v - 1; } -std::vector ToInt64Vector(const std::vector& input); +std::vector ToInt64Vector(const std::vector& input); #if !defined(SWIG) // A PathState represents a set of paths and changed made on it. @@ -3048,14 +3040,14 @@ std::vector ToInt64Vector(const std::vector& input); // to browse paths: each path has exactly one chain. class PathState { public: - // A ChainRange allows to iterate on all chains of a path. - // ChainRange is a range, its iterator Chain*, its value type Chain. - class ChainRange; // A Chain allows to iterate on all nodes of a chain, and access some data: // first node, last node, number of nodes in the chain. // Chain is a range, its iterator ChainNodeIterator, its value type int. // Chains are returned by PathChainIterator's operator*(). class Chain; + // A ChainRange allows to iterate on all chains of a path. + // ChainRange is a range, its iterator Chain*, its value type Chain. + class ChainRange; // A NodeRange allows to iterate on all nodes of a path. // NodeRange is a range, its iterator PathNodeIterator, its value type int. class NodeRange; @@ -3379,8 +3371,8 @@ class PathState::NodeRange { class UnaryDimensionChecker { public: struct Interval { - int64 min; - int64 max; + int64_t min; + int64_t max; }; UnaryDimensionChecker(const PathState* path_state, diff --git a/ortools/constraint_solver/constraints.cc b/ortools/constraint_solver/constraints.cc index 92660bf501..a1b7682581 100644 --- a/ortools/constraint_solver/constraints.cc +++ b/ortools/constraint_solver/constraints.cc @@ -14,6 +14,8 @@ #include #include +#include +#include #include #include #include @@ -136,7 +138,7 @@ class MapDomain : public Constraint { var_->WhenBound(vb); std::unique_ptr domain_it( var_->MakeDomainIterator(/*reversible=*/false)); - for (const int64 index : InitAndGetValues(domain_it.get())) { + for (const int64_t index : InitAndGetValues(domain_it.get())) { if (index >= 0 && index < actives_.size() && !actives_[index]->Bound()) { Demon* d = MakeConstraintDemon1( solver(), this, &MapDomain::UpdateActive, "UpdateActive", index); @@ -147,7 +149,7 @@ class MapDomain : public Constraint { void InitialPropagate() override { for (int i = 0; i < actives_.size(); ++i) { - actives_[i]->SetRange(int64{0}, int64{1}); + actives_[i]->SetRange(int64_t{0}, int64_t{1}); if (!var_->Contains(i)) { actives_[i]->SetValue(0); } else if (actives_[i]->Max() == 0LL) { @@ -162,7 +164,7 @@ class MapDomain : public Constraint { } } - void UpdateActive(int64 index) { + void UpdateActive(int64_t index) { IntVar* const act = actives_[index]; if (act->Max() == 0) { var_->RemoveValue(index); @@ -172,27 +174,28 @@ class MapDomain : public Constraint { } void VarDomain() { - const int64 oldmin = var_->OldMin(); - const int64 oldmax = var_->OldMax(); - const int64 vmin = var_->Min(); - const int64 vmax = var_->Max(); - const int64 size = actives_.size(); - for (int64 j = std::max(oldmin, int64{0}); j < std::min(vmin, size); ++j) { + const int64_t oldmin = var_->OldMin(); + const int64_t oldmax = var_->OldMax(); + const int64_t vmin = var_->Min(); + const int64_t vmax = var_->Max(); + const int64_t size = actives_.size(); + for (int64_t j = std::max(oldmin, int64_t{0}); j < std::min(vmin, size); + ++j) { actives_[j]->SetValue(0); } - for (const int64 j : InitAndGetValues(holes_)) { + for (const int64_t j : InitAndGetValues(holes_)) { if (j >= 0 && j < size) { actives_[j]->SetValue(0); } } - for (int64 j = std::max(vmax + int64{1}, int64{0}); - j <= std::min(oldmax, size - int64{1}); ++j) { - actives_[j]->SetValue(int64{0}); + for (int64_t j = std::max(vmax + int64_t{1}, int64_t{0}); + j <= std::min(oldmax, size - int64_t{1}); ++j) { + actives_[j]->SetValue(int64_t{0}); } } void VarBound() { - const int64 val = var_->Min(); + const int64_t val = var_->Min(); if (val >= 0 && val < actives_.size()) { actives_[val]->SetValue(1); } @@ -388,20 +391,20 @@ class InversePermutationConstraint : public Constraint { // See PropagateHolesOfLeftVarToRight() and PropagateHolesOfRightVarToLeft(). void PropagateHoles(int index, IntVar* const var, IntVarIterator* const holes, const std::vector& inverse) { - const int64 oldmin = std::max(var->OldMin(), int64{0}); - const int64 oldmax = - std::min(var->OldMax(), static_cast(left_.size() - 1)); - const int64 vmin = var->Min(); - const int64 vmax = var->Max(); - for (int64 value = oldmin; value < vmin; ++value) { + const int64_t oldmin = std::max(var->OldMin(), int64_t{0}); + const int64_t oldmax = + std::min(var->OldMax(), static_cast(left_.size() - 1)); + const int64_t vmin = var->Min(); + const int64_t vmax = var->Max(); + for (int64_t value = oldmin; value < vmin; ++value) { inverse[value]->RemoveValue(index); } - for (const int64 hole : InitAndGetValues(holes)) { + for (const int64_t hole : InitAndGetValues(holes)) { if (hole >= 0 && hole < left_.size()) { inverse[hole]->RemoveValue(index); } } - for (int64 value = vmax + 1; value <= oldmax; ++value) { + for (int64_t value = vmax + 1; value <= oldmax; ++value) { inverse[value]->RemoveValue(index); } } @@ -411,7 +414,7 @@ class InversePermutationConstraint : public Constraint { const std::vector& inverse) { // Iterators are not safe w.r.t. removal. Postponing deletions. tmp_removed_values_.clear(); - for (const int64 value : InitAndGetValues(domain)) { + for (const int64_t value : InitAndGetValues(domain)) { if (!inverse[value]->Contains(index)) { tmp_removed_values_.push_back(value); } @@ -431,7 +434,7 @@ class InversePermutationConstraint : public Constraint { std::vector right_domain_iterators_; // used only in PropagateDomain(). - std::vector tmp_removed_values_; + std::vector tmp_removed_values_; }; // Index of first Max Value @@ -454,11 +457,11 @@ class IndexOfFirstMaxValue : public Constraint { } void InitialPropagate() override { - const int64 vsize = vars_.size(); - const int64 imin = std::max(int64{0}, index_->Min()); - const int64 imax = std::min(vsize - 1, index_->Max()); - int64 max_max = kint64min; - int64 max_min = kint64min; + const int64_t vsize = vars_.size(); + const int64_t imin = std::max(int64_t{0}, index_->Min()); + const int64_t imax = std::min(vsize - 1, index_->Max()); + int64_t max_max = std::numeric_limits::min(); + int64_t max_min = std::numeric_limits::min(); // Compute min and max value in the current interval covered by index_. for (int i = imin; i <= imax; ++i) { @@ -476,11 +479,11 @@ class IndexOfFirstMaxValue : public Constraint { } // Shave bounds for index_. - int64 min_index = imin; + int64_t min_index = imin; while (vars_[min_index]->Max() < max_min) { min_index++; } - int64 max_index = imax; + int64_t max_index = imax; while (vars_[max_index]->Max() < max_min) { max_index--; } diff --git a/ortools/constraint_solver/count_cst.cc b/ortools/constraint_solver/count_cst.cc index 156ed6aaef..3433dd14d3 100644 --- a/ortools/constraint_solver/count_cst.cc +++ b/ortools/constraint_solver/count_cst.cc @@ -15,6 +15,8 @@ // Count constraints #include +#include +#include #include #include @@ -27,8 +29,8 @@ #include "ortools/util/string_array.h" namespace operations_research { -Constraint* Solver::MakeCount(const std::vector& vars, int64 value, - int64 max_count) { +Constraint* Solver::MakeCount(const std::vector& vars, int64_t value, + int64_t max_count) { std::vector tmp_sum; for (int i = 0; i < vars.size(); ++i) { if (vars[i]->Contains(value)) { @@ -42,13 +44,13 @@ Constraint* Solver::MakeCount(const std::vector& vars, int64 value, return MakeSumEquality(tmp_sum, max_count); } -Constraint* Solver::MakeCount(const std::vector& vars, int64 value, +Constraint* Solver::MakeCount(const std::vector& vars, int64_t value, IntVar* max_count) { if (max_count->Bound()) { return MakeCount(vars, value, max_count->Min()); } else { std::vector tmp_sum; - int64 num_vars_bound_to_v = 0; + int64_t num_vars_bound_to_v = 0; for (int i = 0; i < vars.size(); ++i) { if (vars[i]->Contains(value)) { if (vars[i]->Bound()) { @@ -68,8 +70,8 @@ Constraint* Solver::MakeCount(const std::vector& vars, int64 value, namespace { class AtMost : public Constraint { public: - AtMost(Solver* const s, std::vector vars, int64 value, - int64 max_count) + AtMost(Solver* const s, std::vector vars, int64_t value, + int64_t max_count) : Constraint(s), vars_(std::move(vars)), value_(value), @@ -141,15 +143,15 @@ class AtMost : public Constraint { private: const std::vector vars_; - const int64 value_; - const int64 max_count_; + const int64_t value_; + const int64_t max_count_; NumericalRev current_count_; }; class Distribute : public Constraint { public: Distribute(Solver* const s, const std::vector& vars, - const std::vector& values, + const std::vector& values, const std::vector& cards) : Constraint(s), vars_(vars), @@ -186,11 +188,11 @@ class Distribute : public Constraint { } private: - int64 var_size() const { return vars_.size(); } - int64 card_size() const { return cards_.size(); } + int64_t var_size() const { return vars_.size(); } + int64_t card_size() const { return cards_.size(); } const std::vector vars_; - const std::vector values_; + const std::vector values_; const std::vector cards_; RevBitMatrix undecided_; NumericalRevArray min_; @@ -333,7 +335,7 @@ class FastDistribute : public Constraint { void CardMin(int card_index); void CardMax(int card_index); std::string DebugString() const override; - void SetRevCannotContribute(int64 var_index, int64 card_index) { + void SetRevCannotContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); max_.Decr(s, card_index); @@ -342,7 +344,7 @@ class FastDistribute : public Constraint { CardMax(card_index); } } - void SetRevDoContribute(int64 var_index, int64 card_index) { + void SetRevDoContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); min_.Incr(s, card_index); @@ -362,8 +364,8 @@ class FastDistribute : public Constraint { } private: - int64 var_size() const { return vars_.size(); } - int64 card_size() const { return cards_.size(); } + int64_t var_size() const { return vars_.size(); } + int64_t card_size() const { return cards_.size(); } const std::vector vars_; const std::vector cards_; @@ -451,23 +453,23 @@ void FastDistribute::OneBound(int index) { void FastDistribute::OneDomain(int index) { IntVar* const var = vars_[index]; - const int64 oldmin = var->OldMin(); - const int64 oldmax = var->OldMax(); - const int64 vmin = var->Min(); - const int64 vmax = var->Max(); - for (int64 card_index = std::max(oldmin, int64{0}); + const int64_t oldmin = var->OldMin(); + const int64_t oldmax = var->OldMax(); + const int64_t vmin = var->Min(); + const int64_t vmax = var->Max(); + for (int64_t card_index = std::max(oldmin, int64_t{0}); card_index < std::min(vmin, card_size()); ++card_index) { if (undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); } } - for (const int64 card_index : InitAndGetValues(holes_[index])) { + for (const int64_t card_index : InitAndGetValues(holes_[index])) { if (card_index >= 0 && card_index < card_size() && undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); } } - for (int64 card_index = std::max(vmax + 1, int64{0}); + for (int64_t card_index = std::max(vmax + 1, int64_t{0}); card_index <= std::min(oldmax, card_size() - 1); ++card_index) { if (undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); @@ -476,8 +478,8 @@ void FastDistribute::OneDomain(int index) { } void FastDistribute::CountVar(int card_index) { - const int64 stored_min = min_[card_index]; - const int64 stored_max = max_[card_index]; + const int64_t stored_min = min_[card_index]; + const int64_t stored_max = max_[card_index]; cards_[card_index]->SetRange(min_[card_index], max_[card_index]); if (cards_[card_index]->Min() == stored_max) { CardMax(card_index); @@ -508,9 +510,9 @@ void FastDistribute::CardMax(int card_index) { class BoundedDistribute : public Constraint { public: BoundedDistribute(Solver* const s, const std::vector& vars, - const std::vector& values, - const std::vector& card_min, - const std::vector& card_max); + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); ~BoundedDistribute() override {} void Post() override; @@ -521,7 +523,7 @@ class BoundedDistribute : public Constraint { void CardMin(int card_index); void CardMax(int card_index); std::string DebugString() const override; - void SetRevCannotContribute(int64 var_index, int64 card_index) { + void SetRevCannotContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); max_.Decr(s, card_index); @@ -532,7 +534,7 @@ class BoundedDistribute : public Constraint { CardMax(card_index); } } - void SetRevDoContribute(int64 var_index, int64 card_index) { + void SetRevDoContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); min_.Incr(s, card_index); @@ -555,13 +557,13 @@ class BoundedDistribute : public Constraint { } private: - int64 var_size() const { return vars_.size(); } - int64 card_size() const { return values_.size(); } + int64_t var_size() const { return vars_.size(); } + int64_t card_size() const { return values_.size(); } const std::vector vars_; - const std::vector values_; - const std::vector card_min_; - const std::vector card_max_; + const std::vector values_; + const std::vector card_min_; + const std::vector card_max_; RevBitMatrix undecided_; NumericalRevArray min_; NumericalRevArray max_; @@ -570,9 +572,9 @@ class BoundedDistribute : public Constraint { BoundedDistribute::BoundedDistribute(Solver* const s, const std::vector& vars, - const std::vector& values, - const std::vector& card_min, - const std::vector& card_max) + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) : Constraint(s), vars_(vars), values_(values), @@ -612,7 +614,7 @@ void BoundedDistribute::Post() { void BoundedDistribute::InitialPropagate() { Solver* const s = solver(); - int64 sum_card_min = 0; + int64_t sum_card_min = 0; for (int i = 0; i < card_size(); ++i) { if (card_max_[i] < card_min_[i]) { solver()->Fail(); @@ -629,7 +631,7 @@ void BoundedDistribute::InitialPropagate() { } for (int card_index = 0; card_index < card_size(); ++card_index) { - const int64 value = values_[card_index]; + const int64_t value = values_[card_index]; int min = 0; int max = 0; for (int i = 0; i < var_size(); ++i) { @@ -652,7 +654,7 @@ void BoundedDistribute::InitialPropagate() { void BoundedDistribute::OneBound(int index) { IntVar* const var = vars_[index]; - const int64 var_min = var->Min(); + const int64_t var_min = var->Min(); for (int card_index = 0; card_index < card_size(); ++card_index) { if (undecided_.IsSet(index, card_index)) { if (var_min == values_[card_index]) { @@ -676,8 +678,8 @@ void BoundedDistribute::OneDomain(int index) { } void BoundedDistribute::CountVar(int card_index) { - const int64 stored_min = min_[card_index]; - const int64 stored_max = max_[card_index]; + const int64_t stored_min = min_[card_index]; + const int64_t stored_max = max_[card_index]; if (card_min_[card_index] > stored_max || card_max_[card_index] < stored_min) { solver()->Fail(); @@ -711,8 +713,8 @@ void BoundedDistribute::CardMax(int card_index) { class BoundedFastDistribute : public Constraint { public: BoundedFastDistribute(Solver* const s, const std::vector& vars, - const std::vector& card_min, - const std::vector& card_max); + const std::vector& card_min, + const std::vector& card_max); ~BoundedFastDistribute() override {} void Post() override; @@ -723,7 +725,7 @@ class BoundedFastDistribute : public Constraint { void CardMin(int card_index); void CardMax(int card_index); std::string DebugString() const override; - void SetRevCannotContribute(int64 var_index, int64 card_index) { + void SetRevCannotContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); max_.Decr(s, card_index); @@ -734,7 +736,7 @@ class BoundedFastDistribute : public Constraint { CardMax(card_index); } } - void SetRevDoContribute(int64 var_index, int64 card_index) { + void SetRevDoContribute(int64_t var_index, int64_t card_index) { Solver* const s = solver(); undecided_.SetToZero(s, var_index, card_index); min_.Incr(s, card_index); @@ -756,22 +758,21 @@ class BoundedFastDistribute : public Constraint { } private: - int64 var_size() const { return vars_.size(); } - int64 card_size() const { return card_min_.size(); } + int64_t var_size() const { return vars_.size(); } + int64_t card_size() const { return card_min_.size(); } const std::vector vars_; - const std::vector card_min_; - const std::vector card_max_; + const std::vector card_min_; + const std::vector card_max_; RevBitMatrix undecided_; NumericalRevArray min_; NumericalRevArray max_; std::vector holes_; }; -BoundedFastDistribute::BoundedFastDistribute(Solver* const s, - const std::vector& vars, - const std::vector& card_min, - const std::vector& card_max) +BoundedFastDistribute::BoundedFastDistribute( + Solver* const s, const std::vector& vars, + const std::vector& card_min, const std::vector& card_max) : Constraint(s), vars_(vars), card_min_(card_min), @@ -811,7 +812,7 @@ void BoundedFastDistribute::Post() { void BoundedFastDistribute::InitialPropagate() { Solver* const s = solver(); - int64 sum_card_min = 0; + int64_t sum_card_min = 0; for (int i = 0; i < card_size(); ++i) { if (card_max_[i] < card_min_[i]) { solver()->Fail(); @@ -850,7 +851,7 @@ void BoundedFastDistribute::InitialPropagate() { void BoundedFastDistribute::OneBound(int index) { IntVar* const var = vars_[index]; - const int64 var_min = var->Min(); + const int64_t var_min = var->Min(); for (int card_index = 0; card_index < card_size(); ++card_index) { if (undecided_.IsSet(index, card_index)) { if (var_min == card_index) { @@ -864,23 +865,23 @@ void BoundedFastDistribute::OneBound(int index) { void BoundedFastDistribute::OneDomain(int index) { IntVar* const var = vars_[index]; - const int64 oldmin = var->OldMin(); - const int64 oldmax = var->OldMax(); - const int64 vmin = var->Min(); - const int64 vmax = var->Max(); - for (int64 card_index = std::max(oldmin, int64{0}); + const int64_t oldmin = var->OldMin(); + const int64_t oldmax = var->OldMax(); + const int64_t vmin = var->Min(); + const int64_t vmax = var->Max(); + for (int64_t card_index = std::max(oldmin, int64_t{0}); card_index < std::min(vmin, card_size()); ++card_index) { if (undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); } } - for (const int64 card_index : InitAndGetValues(holes_[index])) { + for (const int64_t card_index : InitAndGetValues(holes_[index])) { if (card_index >= 0 && card_index < card_size() && undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); } } - for (int64 card_index = std::max(vmax + 1, int64{0}); + for (int64_t card_index = std::max(vmax + 1, int64_t{0}); card_index <= std::min(oldmax, card_size() - 1); ++card_index) { if (undecided_.IsSet(index, card_index)) { SetRevCannotContribute(index, card_index); @@ -889,8 +890,8 @@ void BoundedFastDistribute::OneDomain(int index) { } void BoundedFastDistribute::CountVar(int card_index) { - const int64 stored_min = min_[card_index]; - const int64 stored_max = max_[card_index]; + const int64_t stored_min = min_[card_index]; + const int64_t stored_max = max_[card_index]; if (card_min_[card_index] > stored_max || card_max_[card_index] < stored_min) { solver()->Fail(); @@ -952,8 +953,8 @@ class SetAllToZero : public Constraint { // ----- Factory ----- -Constraint* Solver::MakeAtMost(std::vector vars, int64 value, - int64 max_count) { +Constraint* Solver::MakeAtMost(std::vector vars, int64_t value, + int64_t max_count) { CHECK_GE(max_count, 0); if (max_count >= vars.size()) { return MakeTrueConstraint(); @@ -962,7 +963,7 @@ Constraint* Solver::MakeAtMost(std::vector vars, int64 value, } Constraint* Solver::MakeDistribute(const std::vector& vars, - const std::vector& values, + const std::vector& values, const std::vector& cards) { if (vars.empty()) { return RevAlloc(new SetAllToZero(this, cards)); @@ -1011,8 +1012,8 @@ Constraint* Solver::MakeDistribute(const std::vector& vars, } Constraint* Solver::MakeDistribute(const std::vector& vars, - int64 card_min, int64 card_max, - int64 card_size) { + int64_t card_min, int64_t card_max, + int64_t card_size) { const int vsize = vars.size(); CHECK_NE(vsize, 0); for (IntVar* const var : vars) { @@ -1023,19 +1024,19 @@ Constraint* Solver::MakeDistribute(const std::vector& vars, } else if (card_min > vsize || card_max < 0 || card_max < card_min) { return MakeFalseConstraint(); } else { - std::vector mins(card_size, card_min); - std::vector maxes(card_size, card_max); + std::vector mins(card_size, card_min); + std::vector maxes(card_size, card_max); return RevAlloc(new BoundedFastDistribute(this, vars, mins, maxes)); } } Constraint* Solver::MakeDistribute(const std::vector& vars, - const std::vector& card_min, - const std::vector& card_max) { + const std::vector& card_min, + const std::vector& card_max) { const int vsize = vars.size(); CHECK_NE(vsize, 0); - int64 cmax = kint64max; - int64 cmin = kint64min; + int64_t cmax = std::numeric_limits::max(); + int64_t cmin = std::numeric_limits::min(); for (int i = 0; i < card_max.size(); ++i) { cmax = std::min(cmax, card_max[i]); cmin = std::max(cmin, card_min[i]); @@ -1056,9 +1057,9 @@ Constraint* Solver::MakeDistribute(const std::vector& vars, } Constraint* Solver::MakeDistribute(const std::vector& vars, - const std::vector& values, - const std::vector& card_min, - const std::vector& card_max) { + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) { CHECK_NE(vars.size(), 0); CHECK_EQ(card_min.size(), values.size()); CHECK_EQ(card_min.size(), card_max.size()); diff --git a/ortools/constraint_solver/csharp/constraint_solver.i b/ortools/constraint_solver/csharp/constraint_solver.i index c3972606a9..b96fd722af 100644 --- a/ortools/constraint_solver/csharp/constraint_solver.i +++ b/ortools/constraint_solver/csharp/constraint_solver.i @@ -98,24 +98,24 @@ struct FailureProtect { %enddef // PROTECT_FROM_FAILURE namespace operations_research { -PROTECT_FROM_FAILURE(IntExpr::SetValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMin(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMax(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetRange(int64 l, int64 u), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), +PROTECT_FROM_FAILURE(IntExpr::SetValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMin(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMax(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetRange(int64_t l, int64_t u), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64_t mi, int64_t ma), arg1->solver()); PROTECT_FROM_FAILURE(IntervalVar::SetPerformed(bool val), arg1->solver()); PROTECT_FROM_FAILURE(Solver::AddConstraint(Constraint* const c), arg1); @@ -125,8 +125,8 @@ PROTECT_FROM_FAILURE(Solver::Fail(), arg1); // ############ END DUPLICATED CODE BLOCK ############ -%apply int64 * INOUT { int64 *const marker }; -%apply int64 * OUTPUT { int64 *l, int64 *u, int64 *value }; +%apply int64_t * INOUT { int64_t *const marker }; +%apply int64_t * OUTPUT { int64_t *l, int64_t *u, int64_t *value }; // Since knapsack_solver.i and constraint_solver.i both need to // instantiate the vector template, but their csharp_wrap.cc @@ -194,34 +194,34 @@ DEFINE_ARGS_TO_R_CALLBACK( void, *(void(*)()), (), ()) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongToInt, - int, *(int(*)(int64)), (int64 t), (t)) + std::function, LongToInt, + int, *(int(*)(int64_t)), (int64_t t), (t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongToLong, - int64, *(int64(*)(int64)), (int64 t), (t)) + std::function, LongToLong, + int64_t, *(int64_t(*)(int64_t)), (int64_t t), (t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongLongToLong, - int64, *(int64(*)(int64, int64)), (int64 t, int64 u), (t, u)) + std::function, LongLongToLong, + int64_t, *(int64_t(*)(int64_t, int64_t)), (int64_t t, int64_t u), (t, u)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongLongLongToLong, - int64, *(int64(*)(int64, int64, int64)), (int64 t, int64 u, int64 v), (t, u, v)) + std::function, LongLongLongToLong, + int64_t, *(int64_t(*)(int64_t, int64_t, int64_t)), (int64_t t, int64_t u, int64_t v), (t, u, v)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, IntIntToLong, - int64, *(int64(*)(int, int)), (int t, int u), (t, u)) + std::function, IntIntToLong, + int64_t, *(int64_t(*)(int, int)), (int t, int u), (t, u)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongToBoolean, - bool, *(bool(*)(int64)), (int64 t), (t)) + std::function, LongToBoolean, + bool, *(bool(*)(int64_t)), (int64_t t), (t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongLongLongToBoolean, - bool, *(bool(*)(int64, int64, int64)), (int64 t, int64 u, int64 v), (t, u, v)) + std::function, LongLongLongToBoolean, + bool, *(bool(*)(int64_t, int64_t, int64_t)), (int64_t t, int64_t u, int64_t v), (t, u, v)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, LongToVoid, - void, *(void(*)(int64)), (int64 t), (t)) + std::function, LongToVoid, + void, *(void(*)(int64_t)), (int64_t t), (t)) #undef DEFINE_ARGS_TO_R_CALLBACK #undef DEFINE_VOID_TO_STRING_CALLBACK @@ -426,37 +426,37 @@ namespace operations_research { Constraint* MapTo(const std::vector& vars) { return $self->solver()->MakeMapDomain($self->Var(), vars); } - IntExpr* IndexOf(const std::vector& vars) { + IntExpr* IndexOf(const std::vector& vars) { return $self->solver()->MakeElement(vars, $self->Var()); } IntExpr* IndexOf(const std::vector& vars) { return $self->solver()->MakeElement(vars, $self->Var()); } - IntVar* IsEqual(int64 value) { + IntVar* IsEqual(int64_t value) { return $self->solver()->MakeIsEqualCstVar($self->Var(), value); } - IntVar* IsDifferent(int64 value) { + IntVar* IsDifferent(int64_t value) { return $self->solver()->MakeIsDifferentCstVar($self->Var(), value); } - IntVar* IsGreater(int64 value) { + IntVar* IsGreater(int64_t value) { return $self->solver()->MakeIsGreaterCstVar($self->Var(), value); } - IntVar* IsGreaterOrEqual(int64 value) { + IntVar* IsGreaterOrEqual(int64_t value) { return $self->solver()->MakeIsGreaterOrEqualCstVar($self->Var(), value); } - IntVar* IsLess(int64 value) { + IntVar* IsLess(int64_t value) { return $self->solver()->MakeIsLessCstVar($self->Var(), value); } - IntVar* IsLessOrEqual(int64 value) { + IntVar* IsLessOrEqual(int64_t value) { return $self->solver()->MakeIsLessOrEqualCstVar($self->Var(), value); } - IntVar* IsMember(const std::vector& values) { + IntVar* IsMember(const std::vector& values) { return $self->solver()->MakeIsMemberVar($self->Var(), values); } IntVar* IsMember(const std::vector& values) { return $self->solver()->MakeIsMemberVar($self->Var(), values); } - Constraint* Member(const std::vector& values) { + Constraint* Member(const std::vector& values) { return $self->solver()->MakeMemberCt($self->Var(), values); } Constraint* Member(const std::vector& values) { @@ -480,10 +480,10 @@ namespace operations_research { IntVar* IsLessOrEqual(IntExpr* const other) { return $self->solver()->MakeIsLessOrEqualVar($self->Var(), other->Var()); } - OptimizeVar* Minimize(int64 step) { + OptimizeVar* Minimize(int64_t step) { return $self->solver()->MakeMinimize($self->Var(), step); } - OptimizeVar* Maximize(int64 step) { + OptimizeVar* Maximize(int64_t step) { return $self->solver()->MakeMaximize($self->Var(), step); } } @@ -553,52 +553,52 @@ namespace operations_research { Constraint* StartsAtStart(IntervalVar* other) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::STARTS_AT_START, other); } - Constraint* EndsAfterEndWithDelay(IntervalVar* other, int64 delay) { + Constraint* EndsAfterEndWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::ENDS_AFTER_END, other, delay); } - Constraint* EndsAfterStartWithDelay(IntervalVar* other, int64 delay) { + Constraint* EndsAfterStartWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::ENDS_AFTER_START, other, delay); } - Constraint* EndsAtEndWithDelay(IntervalVar* other, int64 delay) { + Constraint* EndsAtEndWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::ENDS_AT_END, other, delay); } - Constraint* EndsAtStartWithDelay(IntervalVar* other, int64 delay) { + Constraint* EndsAtStartWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::ENDS_AT_START, other, delay); } - Constraint* StartsAfterEndWithDelay(IntervalVar* other, int64 delay) { + Constraint* StartsAfterEndWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::STARTS_AFTER_END, other, delay); } - Constraint* StartsAfterStartWithDelay(IntervalVar* other, int64 delay) { + Constraint* StartsAfterStartWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::STARTS_AFTER_START, other, delay); } - Constraint* StartsAtEndWithDelay(IntervalVar* other, int64 delay) { + Constraint* StartsAtEndWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::STARTS_AT_END, other, delay); } - Constraint* StartsAtStartWithDelay(IntervalVar* other, int64 delay) { + Constraint* StartsAtStartWithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay($self, operations_research::Solver::STARTS_AT_START, other, delay); } - Constraint* EndsAfter(int64 date) { + Constraint* EndsAfter(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::ENDS_AFTER, date); } - Constraint* EndsAt(int64 date) { + Constraint* EndsAt(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::ENDS_AT, date); } - Constraint* EndsBefore(int64 date) { + Constraint* EndsBefore(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::ENDS_BEFORE, date); } - Constraint* StartsAfter(int64 date) { + Constraint* StartsAfter(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::STARTS_AFTER, date); } - Constraint* StartsAt(int64 date) { + Constraint* StartsAt(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::STARTS_AT, date); } - Constraint* StartsBefore(int64 date) { + Constraint* StartsBefore(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::STARTS_BEFORE, date); } - Constraint* CrossesDate(int64 date) { + Constraint* CrossesDate(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::CROSS_DATE, date); } - Constraint* AvoidsDate(int64 date) { + Constraint* AvoidsDate(int64_t date) { return $self->solver()->MakeIntervalVarRelation($self, operations_research::Solver::AVOID_DATE, date); } IntervalVar* RelaxedMax() { @@ -861,7 +861,7 @@ namespace operations_research { // Extend IntVarLocalSearchFilter with an intuitive API. %extend IntVarLocalSearchFilter { int Index(IntVar* const var) { - int64 index = -1; + int64_t index = -1; $self->FindIndex(var, &index); return index; } @@ -913,29 +913,29 @@ public delegate string VoidToString(); // Used to wrap std::function public delegate bool VoidToBoolean(); -// Used to wrap std::function +// Used to wrap std::function public delegate int LongToInt(long t); -// Used to wrap IndexEvaluator1 (std::function) +// Used to wrap IndexEvaluator1 (std::function) public delegate long LongToLong(long t); -// Used to wrap IndexEvaluator2 (std::function) +// Used to wrap IndexEvaluator2 (std::function) public delegate long LongLongToLong(long t, long u); -// Used to wrap IndexEvaluator3 (std::function) +// Used to wrap IndexEvaluator3 (std::function) public delegate long LongLongLongToLong(long t, long u, long v); -// Used to wrap std::function +// Used to wrap std::function public delegate long IntIntToLong(int t, int u); -// Used to wrap IndexFilter1 (std::function) +// Used to wrap IndexFilter1 (std::function) public delegate bool LongToBoolean(long t); -// Used to wrap std::function +// Used to wrap std::function public delegate bool LongLongLongToBoolean(long t, long u, long v); // Used to wrap std::function public delegate void SolverToVoid(Solver s); -// Used to wrap ObjectiveWatcher (std::function) +// Used to wrap ObjectiveWatcher (std::function) public delegate void LongToVoid(long t); // Used to wrap Closure (std::function) @@ -975,7 +975,7 @@ namespace operations_research { %include "ortools/constraint_solver/constraint_solveri.h" namespace operations_research { -%template(RevInteger) Rev; +%template(RevInteger) Rev; %template(RevBool) Rev; typedef Assignment::AssignmentContainer AssignmentContainer; %template(AssignmentIntContainer) AssignmentContainer; diff --git a/ortools/constraint_solver/csharp/routing_index_manager.i b/ortools/constraint_solver/csharp/routing_index_manager.i index 4fda136363..0b36f4f0d4 100644 --- a/ortools/constraint_solver/csharp/routing_index_manager.i +++ b/ortools/constraint_solver/csharp/routing_index_manager.i @@ -30,13 +30,18 @@ DEFINE_INDEX_TYPE_TYPEDEF(operations_research::RoutingNodeIndex, namespace operations_research { %unignore RoutingIndexManager; -%unignore RoutingIndexManager::GetStartIndex(int); -%unignore RoutingIndexManager::GetEndIndex(int); +%unignore RoutingIndexManager::GetStartIndex; +%unignore RoutingIndexManager::GetEndIndex; %unignore RoutingIndexManager::IndexToNode; %unignore RoutingIndexManager::NodeToIndex; %unignore RoutingIndexManager::NodesToIndices; -%unignore RoutingIndexManager::RoutingIndexManager(int, int, NodeIndex); -%unignore RoutingIndexManager::RoutingIndexManager(int, int, const std::vector&, const std::vector&); +%unignore RoutingIndexManager::RoutingIndexManager( + int, int, + NodeIndex); +%unignore RoutingIndexManager::RoutingIndexManager( + int, int, + const std::vector&, + const std::vector&); %rename (GetNumberOfNodes) RoutingIndexManager::num_nodes; %rename (GetNumberOfVehicles) RoutingIndexManager::num_vehicles; %rename (GetNumberOfIndices) RoutingIndexManager::num_indices; diff --git a/ortools/constraint_solver/default_search.cc b/ortools/constraint_solver/default_search.cc index e917d7548f..1120b566af 100644 --- a/ortools/constraint_solver/default_search.cc +++ b/ortools/constraint_solver/default_search.cc @@ -12,6 +12,7 @@ // limitations under the License. #include +#include #include #include #include @@ -76,7 +77,7 @@ class DomainWatcher { return result; } - double Log2(int64 size) const { return cached_log_.Log2(size); } + double Log2(int64_t size) const { return cached_log_.Log2(size); } private: std::vector vars_; @@ -94,20 +95,20 @@ class FindVar : public DecisionVisitor { ~FindVar() override {} - void VisitSetVariableValue(IntVar* const var, int64 value) override { + void VisitSetVariableValue(IntVar* const var, int64_t value) override { var_ = var; value_ = value; operation_ = ASSIGN; } - void VisitSplitVariableDomain(IntVar* const var, int64 value, + void VisitSplitVariableDomain(IntVar* const var, int64_t value, bool start_with_lower_half) override { var_ = var; value_ = value; operation_ = start_with_lower_half ? SPLIT_LOW : SPLIT_HIGH; } - void VisitScheduleOrPostpone(IntervalVar* const var, int64 est) override { + void VisitScheduleOrPostpone(IntervalVar* const var, int64_t est) override { operation_ = NONE; } @@ -128,7 +129,7 @@ class FindVar : public DecisionVisitor { } // Returns the value of the current variable. - int64 value() const { + int64_t value() const { CHECK_NE(operation_, NONE); return value_; } @@ -141,7 +142,7 @@ class FindVar : public DecisionVisitor { private: IntVar* var_; - int64 value_; + int64_t value_; Operation operation_; }; @@ -183,7 +184,7 @@ class InitVarImpacts : public DecisionBuilder { CHECK(iterator_ != nullptr); if (new_start_) { active_values_.clear(); - for (const int64 value : InitAndGetValues(iterator_)) { + for (const int64_t value : InitAndGetValues(iterator_)) { active_values_.push_back(value); } new_start_ = false; @@ -197,7 +198,7 @@ class InitVarImpacts : public DecisionBuilder { return &updater_; } - void set_update_impact_callback(std::function callback) { + void set_update_impact_callback(std::function callback) { update_impact_callback_ = std::move(callback); } @@ -222,7 +223,7 @@ class InitVarImpacts : public DecisionBuilder { void Refute(Solver* const solver) override {} // Public data for easy access. IntVar* var_; - int64 value_; + int64_t value_; private: const std::function& update_impact_closure_; @@ -230,11 +231,11 @@ class InitVarImpacts : public DecisionBuilder { }; IntVar* var_; - std::function update_impact_callback_; + std::function update_impact_callback_; bool new_start_; IntVarIterator* iterator_; int var_index_; - std::vector active_values_; + std::vector active_values_; int value_index_; std::function update_impact_closure_; AssignCallFail updater_; @@ -268,8 +269,8 @@ class InitVarImpactsWithSplits : public DecisionBuilder { // Public for easy access. IntVar* var_; - int64 value_min_; - int64 value_max_; + int64_t value_min_; + int64_t value_max_; private: const std::function& update_impact_closure_; @@ -295,7 +296,7 @@ class InitVarImpactsWithSplits : public DecisionBuilder { ~InitVarImpactsWithSplits() override {} void UpdateImpacts() { - for (const int64 value : InitAndGetValues(iterator_)) { + for (const int64_t value : InitAndGetValues(iterator_)) { update_impact_callback_(var_index_, value); } } @@ -308,8 +309,8 @@ class InitVarImpactsWithSplits : public DecisionBuilder { split_index_ = 0; } - int64 IntervalStart(int index) const { - const int64 length = max_value_ - min_value_ + 1; + int64_t IntervalStart(int index) const { + const int64_t length = max_value_ - min_value_ + 1; return (min_value_ + length * index / split_size_); } @@ -333,18 +334,18 @@ class InitVarImpactsWithSplits : public DecisionBuilder { return &updater_; } - void set_update_impact_callback(std::function callback) { + void set_update_impact_callback(std::function callback) { update_impact_callback_ = std::move(callback); } private: IntVar* var_; - std::function update_impact_callback_; + std::function update_impact_callback_; bool new_start_; IntVarIterator* iterator_; int var_index_; - int64 min_value_; - int64 max_value_; + int64_t min_value_; + int64_t max_value_; const int split_size_; int split_index_; std::function update_impact_closure_; @@ -441,8 +442,8 @@ class ImpactRecorder : public SearchMonitor { } } - void UpdateImpact(int var_index, int64 value, double impact) { - const int64 value_index = value - original_min_[var_index]; + void UpdateImpact(int var_index, int64_t value, double impact) { + const int64_t value_index = value - original_min_[var_index]; const double current_impact = impacts_[var_index][value_index]; const double new_impact = (current_impact * (absl::GetFlag(FLAGS_cp_impact_divider) - 1) + @@ -451,25 +452,25 @@ class ImpactRecorder : public SearchMonitor { impacts_[var_index][value_index] = new_impact; } - void InitImpact(int var_index, int64 value) { + void InitImpact(int var_index, int64_t value) { const double log_space = domain_watcher_->LogSearchSpaceSize(); const double impact = kPerfectImpact - log_space / current_log_space_; - const int64 value_index = value - original_min_[var_index]; + const int64_t value_index = value - original_min_[var_index]; DCHECK_LT(var_index, size_); DCHECK_LT(value_index, impacts_[var_index].size()); impacts_[var_index][value_index] = impact; init_count_++; } - void FirstRun(int64 splits) { + void FirstRun(int64_t splits) { Solver* const s = solver(); current_log_space_ = domain_watcher_->LogSearchSpaceSize(); if (display_level_ != DefaultPhaseParameters::NONE) { LOG(INFO) << " - initial log2(SearchSpace) = " << current_log_space_; } - const int64 init_time = s->wall_time(); + const int64_t init_time = s->wall_time(); ResetAllImpacts(); - int64 removed_counter = 0; + int64_t removed_counter = 0; FirstRunVariableContainers* container = s->RevAlloc(new FirstRunVariableContainers(this, splits)); // Loop on the variables, scan domains and initialize impacts. @@ -505,8 +506,8 @@ class ImpactRecorder : public SearchMonitor { // removed values in an intermediate vector. if (init_count_ != var->Size() && no_split) { container->ClearRemovedValues(); - for (const int64 value : InitAndGetValues(iterator)) { - const int64 value_index = value - original_min_[var_index]; + for (const int64_t value : InitAndGetValues(iterator)) { + const int64_t value_index = value - original_min_[var_index]; if (impacts_[var_index][value_index] == kInitFailureImpact) { container->PushBackRemovedValue(value); } @@ -535,7 +536,7 @@ class ImpactRecorder : public SearchMonitor { // This method scans the domain of one variable and returns the sum // of the impacts of all values in its domain, along with the value // with minimal impact. - void ScanVarImpacts(int var_index, int64* const best_impact_value, + void ScanVarImpacts(int var_index, int64_t* const best_impact_value, double* const var_impacts, DefaultPhaseParameters::VariableSelection var_select, DefaultPhaseParameters::ValueSelection value_select) { @@ -544,10 +545,10 @@ class ImpactRecorder : public SearchMonitor { double max_impact = -std::numeric_limits::max(); double min_impact = std::numeric_limits::max(); double sum_var_impact = 0.0; - int64 min_impact_value = -1; - int64 max_impact_value = -1; - for (const int64 value : InitAndGetValues(domain_iterators_[var_index])) { - const int64 value_index = value - original_min_[var_index]; + int64_t min_impact_value = -1; + int64_t max_impact_value = -1; + for (const int64_t value : InitAndGetValues(domain_iterators_[var_index])) { + const int64_t value_index = value - original_min_[var_index]; DCHECK_LT(var_index, size_); DCHECK_LT(value_index, impacts_[var_index].size()); const double current_impact = impacts_[var_index][value_index]; @@ -596,22 +597,26 @@ class ImpactRecorder : public SearchMonitor { // allocable. class FirstRunVariableContainers : public BaseObject { public: - FirstRunVariableContainers(ImpactRecorder* impact_recorder, int64 splits) + FirstRunVariableContainers(ImpactRecorder* impact_recorder, int64_t splits) : update_impact_callback_( - [impact_recorder](int var_index, int64 value) { + [impact_recorder](int var_index, int64_t value) { impact_recorder->InitImpact(var_index, value); }), removed_values_(), without_splits_(), with_splits_(splits) {} - std::function update_impact_callback() const { + std::function update_impact_callback() const { return update_impact_callback_; } - void PushBackRemovedValue(int64 value) { removed_values_.push_back(value); } + void PushBackRemovedValue(int64_t value) { + removed_values_.push_back(value); + } bool HasRemovedValues() const { return !removed_values_.empty(); } void ClearRemovedValues() { removed_values_.clear(); } size_t NumRemovedValues() const { return removed_values_.size(); } - const std::vector& removed_values() const { return removed_values_; } + const std::vector& removed_values() const { + return removed_values_; + } InitVarImpacts* without_split() { return &without_splits_; } InitVarImpactsWithSplits* with_splits() { return &with_splits_; } @@ -620,8 +625,8 @@ class ImpactRecorder : public SearchMonitor { } private: - const std::function update_impact_callback_; - std::vector removed_values_; + const std::function update_impact_callback_; + std::vector removed_values_; InitVarImpacts without_splits_; InitVarImpactsWithSplits with_splits_; }; @@ -633,12 +638,12 @@ class ImpactRecorder : public SearchMonitor { // impacts_[i][j] stores the average search space reduction when assigning // original_min_[i] + j to variable i. std::vector > impacts_; - std::vector original_min_; + std::vector original_min_; std::unique_ptr domain_iterators_; - int64 init_count_; + int64_t init_count_; const DefaultPhaseParameters::DisplayLevel display_level_; int current_var_; - int64 current_value_; + int64_t current_value_; FindVar find_var_; absl::flat_hash_map var_map_; bool init_done_; @@ -657,7 +662,7 @@ class ChoiceInfo { public: ChoiceInfo() : value_(0), var_(nullptr), left_(false) {} - ChoiceInfo(IntVar* const var, int64 value, bool left) + ChoiceInfo(IntVar* const var, int64_t value, bool left) : value_(value), var_(var), left_(left) {} std::string DebugString() const { @@ -669,12 +674,12 @@ class ChoiceInfo { bool left() const { return left_; } - int64 value() const { return value_; } + int64_t value() const { return value_; } void set_left(bool left) { left_ = left; } private: - int64 value_; + int64_t value_; IntVar* var_; bool left_; }; @@ -1059,11 +1064,11 @@ class DefaultIntegerSearch : public DecisionBuilder { // minimal impact. Decision* ImpactNext(Solver* const solver) { IntVar* var = nullptr; - int64 value = 0; + int64_t value = 0; double best_var_impact = -std::numeric_limits::max(); for (int i = 0; i < vars_.size(); ++i) { if (!vars_[i]->Bound()) { - int64 current_value = 0; + int64_t current_value = 0; double current_var_impact = 0.0; impact_recorder_.ScanVarImpacts(i, ¤t_value, ¤t_var_impact, parameters_.var_selection_schema, @@ -1091,7 +1096,7 @@ class DefaultIntegerSearch : public DecisionBuilder { RunHeuristicsAsDives heuristics_; FindVar find_var_; IntVar* last_int_var_; - int64 last_int_value_; + int64_t last_int_value_; FindVar::Operation last_operation_; int last_conflict_count_; bool init_done_; diff --git a/ortools/constraint_solver/demon_profiler.cc b/ortools/constraint_solver/demon_profiler.cc index 770fcd1ec9..d43265ffae 100644 --- a/ortools/constraint_solver/demon_profiler.cc +++ b/ortools/constraint_solver/demon_profiler.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -36,11 +37,11 @@ namespace operations_research { namespace { struct Container { - Container(const Constraint* ct_, int64 value_) : ct(ct_), value(value_) {} + Container(const Constraint* ct_, int64_t value_) : ct(ct_), value(value_) {} bool operator<(const Container& c) const { return value > c.value; } const Constraint* ct; - int64 value; + int64_t value; }; } // namespace @@ -62,7 +63,7 @@ class DemonProfiler : public PropagationMonitor { // In microseconds. // TODO(user): rename and return nanoseconds. - int64 CurrentTime() const { + int64_t CurrentTime() const { return (absl::GetCurrentTimeNanos() - start_time_ns_) / 1000; } @@ -204,33 +205,34 @@ class DemonProfiler : public PropagationMonitor { } // IntExpr modifiers. - void SetMin(IntExpr* const expr, int64 new_min) override {} - void SetMax(IntExpr* const expr, int64 new_max) override {} - void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) override {} + void SetMin(IntExpr* const expr, int64_t new_min) override {} + void SetMax(IntExpr* const expr, int64_t new_max) override {} + void SetRange(IntExpr* const expr, int64_t new_min, + int64_t new_max) override {} // IntVar modifiers. - void SetMin(IntVar* const var, int64 new_min) override {} - void SetMax(IntVar* const var, int64 new_max) override {} - void SetRange(IntVar* const var, int64 new_min, int64 new_max) override {} - void RemoveValue(IntVar* const var, int64 value) override {} - void SetValue(IntVar* const var, int64 value) override {} - void RemoveInterval(IntVar* const var, int64 imin, int64 imax) override {} - void SetValues(IntVar* const var, const std::vector& values) override { - } + void SetMin(IntVar* const var, int64_t new_min) override {} + void SetMax(IntVar* const var, int64_t new_max) override {} + void SetRange(IntVar* const var, int64_t new_min, int64_t new_max) override {} + void RemoveValue(IntVar* const var, int64_t value) override {} + void SetValue(IntVar* const var, int64_t value) override {} + void RemoveInterval(IntVar* const var, int64_t imin, int64_t imax) override {} + void SetValues(IntVar* const var, + const std::vector& values) override {} void RemoveValues(IntVar* const var, - const std::vector& values) override {} + const std::vector& values) override {} // IntervalVar modifiers. - void SetStartMin(IntervalVar* const var, int64 new_min) override {} - void SetStartMax(IntervalVar* const var, int64 new_max) override {} - void SetStartRange(IntervalVar* const var, int64 new_min, - int64 new_max) override {} - void SetEndMin(IntervalVar* const var, int64 new_min) override {} - void SetEndMax(IntervalVar* const var, int64 new_max) override {} - void SetEndRange(IntervalVar* const var, int64 new_min, - int64 new_max) override {} - void SetDurationMin(IntervalVar* const var, int64 new_min) override {} - void SetDurationMax(IntervalVar* const var, int64 new_max) override {} - void SetDurationRange(IntervalVar* const var, int64 new_min, - int64 new_max) override {} + void SetStartMin(IntervalVar* const var, int64_t new_min) override {} + void SetStartMax(IntervalVar* const var, int64_t new_max) override {} + void SetStartRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override {} + void SetEndMin(IntervalVar* const var, int64_t new_min) override {} + void SetEndMax(IntervalVar* const var, int64_t new_max) override {} + void SetEndRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override {} + void SetDurationMin(IntervalVar* const var, int64_t new_min) override {} + void SetDurationMax(IntervalVar* const var, int64_t new_max) override {} + void SetDurationRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override {} void SetPerformed(IntervalVar* const var, bool value) override {} void RankFirst(SequenceVar* const var, int index) override {} void RankNotFirst(SequenceVar* const var, int index) override {} @@ -241,7 +243,7 @@ class DemonProfiler : public PropagationMonitor { const std::vector& unperformed) override {} // Useful for unit tests. - void AddFakeRun(Demon* const demon, int64 start_time, int64 end_time, + void AddFakeRun(Demon* const demon, int64_t start_time, int64_t end_time, bool is_fail) { CHECK(demon != nullptr); DemonRuns* const demon_run = demon_map_[demon]; @@ -273,10 +275,10 @@ class DemonProfiler : public PropagationMonitor { constraint_map_.begin(); it != constraint_map_.end(); ++it) { const Constraint* const ct = it->first; - int64 fails = 0; - int64 demon_invocations = 0; - int64 initial_propagation_runtime = 0; - int64 total_demon_runtime = 0; + int64_t fails = 0; + int64_t demon_invocations = 0; + int64_t initial_propagation_runtime = 0; + int64_t total_demon_runtime = 0; int demon_count = 0; ExportInformation(ct, &fails, &initial_propagation_runtime, &demon_invocations, &total_demon_runtime, @@ -288,10 +290,10 @@ class DemonProfiler : public PropagationMonitor { for (int i = 0; i < to_sort.size(); ++i) { const Constraint* const ct = to_sort[i].ct; - int64 fails = 0; - int64 demon_invocations = 0; - int64 initial_propagation_runtime = 0; - int64 total_demon_runtime = 0; + int64_t fails = 0; + int64_t demon_invocations = 0; + int64_t initial_propagation_runtime = 0; + int64_t total_demon_runtime = 0; int demon_count = 0; ExportInformation(ct, &fails, &initial_propagation_runtime, &demon_invocations, &total_demon_runtime, @@ -306,9 +308,9 @@ class DemonProfiler : public PropagationMonitor { const int demon_size = demons.size(); for (int demon_index = 0; demon_index < demon_size; ++demon_index) { DemonRuns* const demon_runs = demons[demon_index]; - int64 invocations = 0; - int64 fails = 0; - int64 runtime = 0; + int64_t invocations = 0; + int64_t fails = 0; + int64_t runtime = 0; double mean_runtime = 0; double median_runtime = 0; double standard_deviation = 0.0; @@ -326,10 +328,11 @@ class DemonProfiler : public PropagationMonitor { } // Export Information - void ExportInformation(const Constraint* const constraint, int64* const fails, - int64* const initial_propagation_runtime, - int64* const demon_invocations, - int64* const total_demon_runtime, int* demons) { + void ExportInformation(const Constraint* const constraint, + int64_t* const fails, + int64_t* const initial_propagation_runtime, + int64_t* const demon_invocations, + int64_t* const total_demon_runtime, int* demons) { CHECK(constraint != nullptr); ConstraintRuns* const ct_run = constraint_map_[constraint]; CHECK(ct_run != nullptr); @@ -352,7 +355,7 @@ class DemonProfiler : public PropagationMonitor { const int runs = demon_runs.start_time_size(); *demon_invocations += runs; for (int run_index = 0; run_index < runs; ++run_index) { - const int64 demon_time = + const int64_t demon_time = demon_runs.end_time(run_index) - demon_runs.start_time(run_index); *total_demon_runtime += demon_time; } @@ -360,8 +363,8 @@ class DemonProfiler : public PropagationMonitor { } void ExportInformation(const DemonRuns* const demon_runs, - int64* const demon_invocations, int64* const fails, - int64* const total_demon_runtime, + int64_t* const demon_invocations, int64_t* const fails, + int64_t* const total_demon_runtime, double* const mean_demon_runtime, double* const median_demon_runtime, double* const stddev_demon_runtime) { @@ -377,7 +380,7 @@ class DemonProfiler : public PropagationMonitor { *stddev_demon_runtime = 0.0; std::vector runtimes; for (int run_index = 0; run_index < runs; ++run_index) { - const int64 demon_time = + const int64_t demon_time = demon_runs->end_time(run_index) - demon_runs->start_time(run_index); *total_demon_runtime += demon_time; runtimes.push_back(demon_time); @@ -420,7 +423,7 @@ class DemonProfiler : public PropagationMonitor { private: Constraint* active_constraint_; Demon* active_demon_; - const int64 start_time_ns_; + const int64_t start_time_ns_; absl::flat_hash_map constraint_map_; absl::flat_hash_map demon_map_; absl::flat_hash_map > @@ -463,16 +466,17 @@ void RegisterDemon(Solver* const solver, Demon* const demon, } void DemonProfilerAddFakeRun(DemonProfiler* const monitor, Demon* const demon, - int64 start_time, int64 end_time, bool is_fail) { + int64_t start_time, int64_t end_time, + bool is_fail) { monitor->AddFakeRun(demon, start_time, end_time, is_fail); } void DemonProfilerExportInformation(DemonProfiler* const monitor, const Constraint* const constraint, - int64* const fails, - int64* const initial_propagation_runtime, - int64* const demon_invocations, - int64* const total_demon_runtime, + int64_t* const fails, + int64_t* const initial_propagation_runtime, + int64_t* const demon_invocations, + int64_t* const total_demon_runtime, int* const demon_count) { monitor->ExportInformation(constraint, fails, initial_propagation_runtime, demon_invocations, total_demon_runtime, diff --git a/ortools/constraint_solver/deviation.cc b/ortools/constraint_solver/deviation.cc index aea93bc264..a634e15fa7 100644 --- a/ortools/constraint_solver/deviation.cc +++ b/ortools/constraint_solver/deviation.cc @@ -12,6 +12,7 @@ // limitations under the License. #include +#include #include #include #include @@ -32,19 +33,19 @@ namespace { class Deviation : public Constraint { public: Deviation(Solver* const solver, const std::vector& vars, - IntVar* const deviation_var, int64 total_sum) + IntVar* const deviation_var, int64_t total_sum) : Constraint(solver), vars_(vars), size_(vars.size()), deviation_var_(deviation_var), total_sum_(total_sum), - scaled_vars_assigned_value_(new int64[size_]), - scaled_vars_min_(new int64[size_]), - scaled_vars_max_(new int64[size_]), + scaled_vars_assigned_value_(new int64_t[size_]), + scaled_vars_min_(new int64_t[size_]), + scaled_vars_max_(new int64_t[size_]), scaled_sum_max_(0), scaled_sum_min_(0), - maximum_(new int64[size_]), - overlaps_sup_(new int64[size_]), + maximum_(new int64_t[size_]), + overlaps_sup_(new int64_t[size_]), active_sum_(0), active_sum_rounded_down_(0), active_sum_rounded_up_(0), @@ -65,7 +66,7 @@ class Deviation : public Constraint { } void InitialPropagate() override { - const int64 delta_min = BuildMinimalDeviationAssignment(); + const int64_t delta_min = BuildMinimalDeviationAssignment(); deviation_var_->SetMin(delta_min); PropagateBounds(delta_min); } @@ -90,9 +91,9 @@ class Deviation : public Constraint { // Builds an assignment with minimal deviation and assign it to // scaled_vars_assigned_value_. It returns the minimal deviation: // sum_i |scaled_vars_assigned_value_[i] - total_sum_|. - int64 BuildMinimalDeviationAssignment() { + int64_t BuildMinimalDeviationAssignment() { RepairGreedySum(BuildGreedySum(true)); - int64 minimal_deviation = 0; + int64_t minimal_deviation = 0; for (int i = 0; i < size_; ++i) { minimal_deviation += std::abs(scaled_vars_assigned_value_[i] - total_sum_); @@ -105,7 +106,7 @@ class Deviation : public Constraint { // - the sum constraint is consistent // - min deviation smaller than max allowed deviation // min_delta is the minimum possible deviation - void PropagateBounds(int64 min_delta) { + void PropagateBounds(int64_t min_delta) { PropagateBounds(min_delta, true); // Filter upper bounds. PropagateBounds(min_delta, false); // Filter lower bounds. } @@ -115,9 +116,9 @@ class Deviation : public Constraint { // same algo to prune both sides of the domains. upperBounds = true // to prune the upper bounds of vars, false to prune the lower // bounds. - void PropagateBounds(int64 min_delta, bool upper_bound) { + void PropagateBounds(int64_t min_delta, bool upper_bound) { // Builds greedy assignment. - const int64 greedy_sum = BuildGreedySum(upper_bound); + const int64_t greedy_sum = BuildGreedySum(upper_bound); // Repairs assignment and store information to be used when pruning. RepairSumAndComputeInfo(greedy_sum); // Does the actual pruning. @@ -139,7 +140,7 @@ class Deviation : public Constraint { active_sum_ = (!upper_bound ? -total_sum_ : total_sum_); // down is <= sum. active_sum_rounded_down_ = - size_ * MathUtil::FloorOfRatio(active_sum_, size_); + size_ * MathUtil::FloorOfRatio(active_sum_, size_); // up is > sum, always. active_sum_rounded_up_ = active_sum_rounded_down_ + size_; active_sum_nearest_ = (active_sum_rounded_up_ - active_sum_ <= @@ -149,7 +150,7 @@ class Deviation : public Constraint { } // Builds an approximate sum in a greedy way. - int64 BuildGreedySum(bool upper_bound) { + int64_t BuildGreedySum(bool upper_bound) { // Update data structure. ComputeData(upper_bound); @@ -157,7 +158,7 @@ class Deviation : public Constraint { DCHECK_GE(size_ * active_sum_, scaled_sum_min_); DCHECK_LE(size_ * active_sum_, scaled_sum_max_); - int64 sum = 0; + int64_t sum = 0; // Greedily assign variable to nearest value to average. overlaps_.clear(); for (int i = 0; i < size_; ++i) { @@ -188,11 +189,11 @@ class Deviation : public Constraint { } // Repairs the greedy sum obtained above to get the correct sum. - void RepairGreedySum(int64 greedy_sum) { + void RepairGreedySum(int64_t greedy_sum) { // Useful constant: scaled version of the sum. - const int64 scaled_total_sum = size_ * active_sum_; + const int64_t scaled_total_sum = size_ * active_sum_; // Step used to make the repair. - const int64 delta = greedy_sum > scaled_total_sum ? -size_ : size_; + const int64_t delta = greedy_sum > scaled_total_sum ? -size_ : size_; // Change overlapping variables as long as the sum is not // satisfied and there are overlapping vars, we use that ones to @@ -204,7 +205,7 @@ class Deviation : public Constraint { } // Change other variables if the sum is still not satisfied. for (int i = 0; i < size_ && greedy_sum != scaled_total_sum; ++i) { - const int64 old_scaled_vars_i = scaled_vars_assigned_value_[i]; + const int64_t old_scaled_vars_i = scaled_vars_assigned_value_[i]; if (greedy_sum < scaled_total_sum) { // Increase scaled_vars_assigned_value_[i] as much as // possible to fix the too low sum. @@ -261,7 +262,8 @@ class Deviation : public Constraint { // Returns whether we can push the greedy sum across the scaled // total sum in the same direction as going from the nearest rounded // sum to the farthest one. - bool CanPushSumAcrossMean(int64 greedy_sum, int64 scaled_total_sum) const { + bool CanPushSumAcrossMean(int64_t greedy_sum, + int64_t scaled_total_sum) const { return (greedy_sum > scaled_total_sum && active_sum_nearest_ == active_sum_rounded_up_) || (greedy_sum < scaled_total_sum && @@ -270,8 +272,8 @@ class Deviation : public Constraint { // Repairs the sum and store intermediate information to be used // during pruning. - void RepairSumAndComputeInfo(int64 greedy_sum) { - const int64 scaled_total_sum = size_ * active_sum_; + void RepairSumAndComputeInfo(int64_t greedy_sum) { + const int64_t scaled_total_sum = size_ * active_sum_; // Computation of key values for the pruning: // - overlaps_sup_ // - maximum_[i] @@ -280,7 +282,7 @@ class Deviation : public Constraint { } else { // Repair and compute maximums. // Try to repair the sum greedily. if (CanPushSumAcrossMean(greedy_sum, scaled_total_sum)) { - const int64 delta = greedy_sum > scaled_total_sum ? -size_ : size_; + const int64_t delta = greedy_sum > scaled_total_sum ? -size_ : size_; for (int j = 0; j < overlaps_.size() && greedy_sum != scaled_total_sum; ++j) { scaled_vars_assigned_value_[overlaps_[j]] += delta; @@ -330,15 +332,15 @@ class Deviation : public Constraint { } // Propagates onto variables with all computed data. - void PruneVars(int64 min_delta, bool upper_bound) { + void PruneVars(int64_t min_delta, bool upper_bound) { // Pruning of upper bound of vars_[i] for var_index in [1..n]. - const int64 increase_down_up = (active_sum_rounded_up_ - active_sum_) - - (active_sum_ - active_sum_rounded_down_); + const int64_t increase_down_up = (active_sum_rounded_up_ - active_sum_) - + (active_sum_ - active_sum_rounded_down_); for (int var_index = 0; var_index < size_; ++var_index) { // Not bound, and a compatible new max. if (scaled_vars_max_[var_index] != scaled_vars_min_[var_index] && maximum_[var_index] < scaled_vars_max_[var_index]) { - const int64 new_max = + const int64_t new_max = ComputeNewMax(var_index, min_delta, increase_down_up); PruneBound(var_index, new_max, upper_bound); } @@ -346,17 +348,18 @@ class Deviation : public Constraint { } // Computes new max for a variable. - int64 ComputeNewMax(int var_index, int64 min_delta, int64 increase_down_up) { - int64 maximum_value = maximum_[var_index]; - int64 current_min_delta = min_delta; + int64_t ComputeNewMax(int var_index, int64_t min_delta, + int64_t increase_down_up) { + int64_t maximum_value = maximum_[var_index]; + int64_t current_min_delta = min_delta; if (overlaps_sup_[var_index] > 0 && (current_min_delta + overlaps_sup_[var_index] * (size_ - increase_down_up) >= deviation_var_->Max())) { - const int64 delta = deviation_var_->Max() - current_min_delta; + const int64_t delta = deviation_var_->Max() - current_min_delta; maximum_value += (size_ * delta) / (size_ - increase_down_up); - return MathUtil::FloorOfRatio(maximum_value, size_); + return MathUtil::FloorOfRatio(maximum_value, size_); } else { if (maximum_value == active_sum_rounded_down_ && active_sum_rounded_down_ < active_sum_) { @@ -372,14 +375,14 @@ class Deviation : public Constraint { overlaps_sup_[var_index] * (size_ - increase_down_up); maximum_value += size_ * overlaps_sup_[var_index]; // Slope of 2 x n. - const int64 delta = deviation_var_->Max() - current_min_delta; + const int64_t delta = deviation_var_->Max() - current_min_delta; maximum_value += delta / 2; // n * delta / (2 * n); - return MathUtil::FloorOfRatio(maximum_value, size_); + return MathUtil::FloorOfRatio(maximum_value, size_); } } // Sets maximum on var or on its opposite. - void PruneBound(int var_index, int64 bound, bool upper_bound) { + void PruneBound(int var_index, int64_t bound, bool upper_bound) { if (upper_bound) { vars_[var_index]->SetMax(bound); } else { @@ -390,27 +393,27 @@ class Deviation : public Constraint { std::vector vars_; const int size_; IntVar* const deviation_var_; - const int64 total_sum_; - std::unique_ptr scaled_vars_assigned_value_; - std::unique_ptr scaled_vars_min_; - std::unique_ptr scaled_vars_max_; - int64 scaled_sum_max_; - int64 scaled_sum_min_; + const int64_t total_sum_; + std::unique_ptr scaled_vars_assigned_value_; + std::unique_ptr scaled_vars_min_; + std::unique_ptr scaled_vars_max_; + int64_t scaled_sum_max_; + int64_t scaled_sum_min_; // Stores the variables overlapping the mean value. std::vector overlaps_; - std::unique_ptr maximum_; - std::unique_ptr overlaps_sup_; + std::unique_ptr maximum_; + std::unique_ptr overlaps_sup_; // These values are updated by ComputeData(). - int64 active_sum_; - int64 active_sum_rounded_down_; - int64 active_sum_rounded_up_; - int64 active_sum_nearest_; + int64_t active_sum_; + int64_t active_sum_rounded_down_; + int64_t active_sum_rounded_up_; + int64_t active_sum_nearest_; }; } // namespace Constraint* Solver::MakeDeviation(const std::vector& vars, IntVar* const deviation_var, - int64 total_sum) { + int64_t total_sum) { return RevAlloc(new Deviation(this, vars, deviation_var, total_sum)); } } // namespace operations_research diff --git a/ortools/constraint_solver/diffn.cc b/ortools/constraint_solver/diffn.cc index 3c20575d92..6ab5f10d2b 100644 --- a/ortools/constraint_solver/diffn.cc +++ b/ortools/constraint_solver/diffn.cc @@ -12,6 +12,8 @@ // limitations under the License. #include +#include +#include #include #include @@ -61,8 +63,8 @@ class Diffn : public Constraint { delayed_demon_ = MakeDelayedConstraintDemon0(s, this, &Diffn::PropagateAll, "PropagateAll"); if (solver()->parameters().diffn_use_cumulative() && - IsArrayInRange(x_, 0, kint64max) && - IsArrayInRange(y_, 0, kint64max)) { + IsArrayInRange(x_, 0, std::numeric_limits::max()) && + IsArrayInRange(y_, 0, std::numeric_limits::max())) { Constraint* ct1 = nullptr; Constraint* ct2 = nullptr; { @@ -71,20 +73,20 @@ class Diffn : public Constraint { // constraints leads to a failure. A cumulative constraint is // a scheduling constraint that will perform finer energy // based reasoning to do more propagation. (see Solver::MakeCumulative). - const int64 min_x = MinVarArray(x_); - const int64 max_x = MaxVarArray(x_); - const int64 max_size_x = MaxVarArray(dx_); - const int64 min_y = MinVarArray(y_); - const int64 max_y = MaxVarArray(y_); - const int64 max_size_y = MaxVarArray(dy_); + const int64_t min_x = MinVarArray(x_); + const int64_t max_x = MaxVarArray(x_); + const int64_t max_size_x = MaxVarArray(dx_); + const int64_t min_y = MinVarArray(y_); + const int64_t max_y = MaxVarArray(y_); + const int64_t max_size_y = MaxVarArray(dy_); if (AreAllBound(dx_)) { - std::vector size_x; + std::vector size_x; FillValues(dx_, &size_x); ct1 = MakeCumulativeConstraint(x_, size_x, dy_, max_size_y + max_y - min_y); } if (AreAllBound(dy_)) { - std::vector size_y; + std::vector size_y; FillValues(dy_, &size_y); ct2 = MakeCumulativeConstraint(y_, size_y, dx_, max_size_x + max_x - min_x); @@ -192,11 +194,11 @@ class Diffn : public Constraint { // (that must already be computed in neighbors_) is greater than the area of a // bounding box that necessarily contains all these boxes. void FailWhenEnergyIsTooLarge(int box) { - int64 area_min_x = x_[box]->Min(); - int64 area_max_x = x_[box]->Max() + dx_[box]->Max(); - int64 area_min_y = y_[box]->Min(); - int64 area_max_y = y_[box]->Max() + dy_[box]->Max(); - int64 sum_of_areas = dx_[box]->Min() * dy_[box]->Min(); + int64_t area_min_x = x_[box]->Min(); + int64_t area_max_x = x_[box]->Max() + dx_[box]->Max(); + int64_t area_min_y = y_[box]->Min(); + int64_t area_max_y = y_[box]->Max() + dy_[box]->Max(); + int64_t sum_of_areas = dx_[box]->Min() * dy_[box]->Min(); // TODO(user): Is there a better order, maybe sort by distance // with the current box. for (int i = 0; i < neighbors_.size(); ++i) { @@ -208,7 +210,7 @@ class Diffn : public Constraint { area_max_y = std::max(area_max_y, y_[other]->Max() + dy_[other]->Max()); // Update sum of areas. sum_of_areas += dx_[other]->Min() * dy_[other]->Min(); - const int64 bounding_area = + const int64_t bounding_area = (area_max_x - area_min_x) * (area_max_y - area_min_y); if (sum_of_areas > bounding_area) { solver()->Fail(); @@ -272,9 +274,9 @@ class Diffn : public Constraint { } Constraint* MakeCumulativeConstraint(const std::vector& positions, - const std::vector& sizes, + const std::vector& sizes, const std::vector& demands, - int64 capacity) { + int64_t capacity) { std::vector intervals; solver()->MakeFixedDurationIntervalVarArray(positions, sizes, "interval", &intervals); @@ -286,11 +288,11 @@ class Diffn : public Constraint { std::vector dx_; std::vector dy_; const bool strict_; - const int64 size_; + const int64_t size_; Demon* delayed_demon_; absl::flat_hash_set to_propagate_; std::vector neighbors_; - uint64 fail_stamp_; + uint64_t fail_stamp_; }; } // namespace @@ -302,7 +304,7 @@ Constraint* Solver::MakeNonOverlappingBoxesConstraint( Constraint* Solver::MakeNonOverlappingBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, - const std::vector& x_size, const std::vector& y_size) { + const std::vector& x_size, const std::vector& y_size) { std::vector dx(x_size.size()); std::vector dy(y_size.size()); for (int i = 0; i < x_size.size(); ++i) { @@ -332,7 +334,7 @@ Constraint* Solver::MakeNonOverlappingNonStrictBoxesConstraint( Constraint* Solver::MakeNonOverlappingNonStrictBoxesConstraint( const std::vector& x_vars, const std::vector& y_vars, - const std::vector& x_size, const std::vector& y_size) { + const std::vector& x_size, const std::vector& y_size) { std::vector dx(x_size.size()); std::vector dy(y_size.size()); for (int i = 0; i < x_size.size(); ++i) { diff --git a/ortools/constraint_solver/doc/CP.md b/ortools/constraint_solver/doc/CP.md index ee8bf02f1b..be6cc5531c 100644 --- a/ortools/constraint_solver/doc/CP.md +++ b/ortools/constraint_solver/doc/CP.md @@ -20,7 +20,7 @@ void SimpleCpProgram() { Solver solver("CpSimple"); // Create the variables. - const int64 num_vals = 3; + const int64_t num_vals = 3; IntVar* const x = solver.MakeIntVar(0, num_vals - 1, "x"); IntVar* const y = solver.MakeIntVar(0, num_vals - 1, "y"); IntVar* const z = solver.MakeIntVar(0, num_vals - 1, "z"); diff --git a/ortools/constraint_solver/doc/ROUTING.md b/ortools/constraint_solver/doc/ROUTING.md index cd0ca229a2..70dd3d7ef8 100644 --- a/ortools/constraint_solver/doc/ROUTING.md +++ b/ortools/constraint_solver/doc/ROUTING.md @@ -19,6 +19,7 @@ and .Net. Each language have different requirements for the code samples. ```cpp #include +#include #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_enums.pb.h" @@ -41,7 +42,7 @@ void SimpleRoutingProgram() { // Define cost of each arc. int distance_call_index = routing.RegisterTransitCallback( - [&manager](int64 from_index, int64 to_index) -> int64 { + [&manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to user NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); @@ -60,16 +61,16 @@ void SimpleRoutingProgram() { // Print solution on console. LOG(INFO) << "Objective: " << solution->ObjectiveValue(); // Inspect solution. - int64 index = routing.Start(0); + int64_t index = routing.Start(0); LOG(INFO) << "Route for Vehicle 0:"; - int64 route_distance{0}; + int64_t route_distance{0}; std::ostringstream route; while (routing.IsEnd(index) == false) { route << manager.IndexToNode(index).value() << " -> "; - int64 previous_index = index; + int64_t previous_index = index; index = solution->Value(routing.NextVar(index)); route_distance += - routing.GetArcCostForVehicle(previous_index, index, int64{0}); + routing.GetArcCostForVehicle(previous_index, index, int64_t{0}); } LOG(INFO) << route.str() << manager.IndexToNode(index).value(); LOG(INFO) << "Distance of the route: " << route_distance << "m"; diff --git a/ortools/constraint_solver/element.cc b/ortools/constraint_solver/element.cc index d612886f4a..c35f7c83ee 100644 --- a/ortools/constraint_solver/element.cc +++ b/ortools/constraint_solver/element.cc @@ -12,6 +12,8 @@ // limitations under the License. #include +#include +#include #include #include #include @@ -67,29 +69,29 @@ class BaseIntExprElement : public BaseIntExpr { public: BaseIntExprElement(Solver* const s, IntVar* const e); ~BaseIntExprElement() override {} - int64 Min() const override; - int64 Max() const override; - void Range(int64* mi, int64* ma) override; - void SetMin(int64 m) override; - void SetMax(int64 m) override; - void SetRange(int64 mi, int64 ma) override; + int64_t Min() const override; + int64_t Max() const override; + void Range(int64_t* mi, int64_t* ma) override; + void SetMin(int64_t m) override; + void SetMax(int64_t m) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override { return (expr_->Bound()); } // TODO(user) : improve me, the previous test is not always true void WhenRange(Demon* d) override { expr_->WhenRange(d); } protected: - virtual int64 ElementValue(int index) const = 0; - virtual int64 ExprMin() const = 0; - virtual int64 ExprMax() const = 0; + virtual int64_t ElementValue(int index) const = 0; + virtual int64_t ExprMin() const = 0; + virtual int64_t ExprMax() const = 0; IntVar* const expr_; private: void UpdateSupports() const; - mutable int64 min_; + mutable int64_t min_; mutable int min_support_; - mutable int64 max_; + mutable int64_t max_; mutable int max_support_; mutable bool initial_update_; IntVarIterator* const expr_iterator_; @@ -108,27 +110,27 @@ BaseIntExprElement::BaseIntExprElement(Solver* const s, IntVar* const e) CHECK(e != nullptr); } -int64 BaseIntExprElement::Min() const { +int64_t BaseIntExprElement::Min() const { UpdateSupports(); return min_; } -int64 BaseIntExprElement::Max() const { +int64_t BaseIntExprElement::Max() const { UpdateSupports(); return max_; } -void BaseIntExprElement::Range(int64* mi, int64* ma) { +void BaseIntExprElement::Range(int64_t* mi, int64_t* ma) { UpdateSupports(); *mi = min_; *ma = max_; } #define UPDATE_BASE_ELEMENT_INDEX_BOUNDS(test) \ - const int64 emin = ExprMin(); \ - const int64 emax = ExprMax(); \ - int64 nmin = emin; \ - int64 value = ElementValue(nmin); \ + const int64_t emin = ExprMin(); \ + const int64_t emax = ExprMax(); \ + int64_t nmin = emin; \ + int64_t value = ElementValue(nmin); \ while (nmin < emax && test) { \ nmin++; \ value = ElementValue(nmin); \ @@ -136,7 +138,7 @@ void BaseIntExprElement::Range(int64* mi, int64* ma) { if (nmin == emax && test) { \ solver()->Fail(); \ } \ - int64 nmax = emax; \ + int64_t nmax = emax; \ value = ElementValue(nmax); \ while (nmax >= nmin && test) { \ nmax--; \ @@ -144,15 +146,15 @@ void BaseIntExprElement::Range(int64* mi, int64* ma) { } \ expr_->SetRange(nmin, nmax); -void BaseIntExprElement::SetMin(int64 m) { +void BaseIntExprElement::SetMin(int64_t m) { UPDATE_BASE_ELEMENT_INDEX_BOUNDS(value < m); } -void BaseIntExprElement::SetMax(int64 m) { +void BaseIntExprElement::SetMax(int64_t m) { UPDATE_BASE_ELEMENT_INDEX_BOUNDS(value > m); } -void BaseIntExprElement::SetRange(int64 mi, int64 ma) { +void BaseIntExprElement::SetRange(int64_t mi, int64_t ma) { if (mi > ma) { solver()->Fail(); } @@ -164,18 +166,18 @@ void BaseIntExprElement::SetRange(int64 mi, int64 ma) { void BaseIntExprElement::UpdateSupports() const { if (initial_update_ || !expr_->Contains(min_support_) || !expr_->Contains(max_support_)) { - const int64 emin = ExprMin(); - const int64 emax = ExprMax(); - int64 min_value = ElementValue(emax); - int64 max_value = min_value; + const int64_t emin = ExprMin(); + const int64_t emax = ExprMax(); + int64_t min_value = ElementValue(emax); + int64_t max_value = min_value; int min_support = emax; int max_support = emax; - const uint64 expr_size = expr_->Size(); + const uint64_t expr_size = expr_->Size(); if (expr_size > 1) { if (expr_size == emax - emin + 1) { // Value(emax) already stored in min_value, max_value. - for (int64 index = emin; index < emax; ++index) { - const int64 value = ElementValue(index); + for (int64_t index = emin; index < emax; ++index) { + const int64_t value = ElementValue(index); if (value > max_value) { max_value = value; max_support = index; @@ -185,9 +187,9 @@ void BaseIntExprElement::UpdateSupports() const { } } } else { - for (const int64 index : InitAndGetValues(expr_iterator_)) { + for (const int64_t index : InitAndGetValues(expr_iterator_)) { if (index >= emin && index <= emax) { - const int64 value = ElementValue(index); + const int64_t value = ElementValue(index); if (value > max_value) { max_value = value; max_support = index; @@ -215,7 +217,7 @@ void BaseIntExprElement::UpdateSupports() const { // It scans the domain of 'index' to compute the new bounds of 'elem'. class IntElementConstraint : public CastConstraint { public: - IntElementConstraint(Solver* const s, const std::vector& values, + IntElementConstraint(Solver* const s, const std::vector& values, IntVar* const index, IntVar* const elem) : CastConstraint(s, elem), values_(values), @@ -233,13 +235,13 @@ class IntElementConstraint : public CastConstraint { void InitialPropagate() override { index_->SetRange(0, values_.size() - 1); - const int64 target_var_min = target_var_->Min(); - const int64 target_var_max = target_var_->Max(); - int64 new_min = target_var_max; - int64 new_max = target_var_min; + const int64_t target_var_min = target_var_->Min(); + const int64_t target_var_max = target_var_->Max(); + int64_t new_min = target_var_max; + int64_t new_max = target_var_min; to_remove_.clear(); - for (const int64 index : InitAndGetValues(index_iterator_)) { - const int64 value = values_[index]; + for (const int64_t index : InitAndGetValues(index_iterator_)) { + const int64_t value = values_[index]; if (value < target_var_min || value > target_var_max) { to_remove_.push_back(index); } else { @@ -274,19 +276,19 @@ class IntElementConstraint : public CastConstraint { } private: - const std::vector values_; + const std::vector values_; IntVar* const index_; IntVarIterator* const index_iterator_; - std::vector to_remove_; + std::vector to_remove_; }; // ----- IntExprElement -IntVar* BuildDomainIntVar(Solver* const solver, std::vector* values); +IntVar* BuildDomainIntVar(Solver* const solver, std::vector* values); class IntExprElement : public BaseIntExprElement { public: - IntExprElement(Solver* const s, const std::vector& vals, + IntExprElement(Solver* const s, const std::vector& vals, IntVar* const expr) : BaseIntExprElement(s, expr), values_(vals) {} @@ -332,33 +334,37 @@ class IntExprElement : public BaseIntExprElement { } protected: - int64 ElementValue(int index) const override { + int64_t ElementValue(int index) const override { DCHECK_LT(index, values_.size()); return values_[index]; } - int64 ExprMin() const override { return std::max(0, expr_->Min()); } - int64 ExprMax() const override { - return values_.empty() ? 0 - : std::min(values_.size() - 1, expr_->Max()); + int64_t ExprMin() const override { + return std::max(0, expr_->Min()); + } + int64_t ExprMax() const override { + return values_.empty() + ? 0 + : std::min(values_.size() - 1, expr_->Max()); } private: - const std::vector values_; + const std::vector values_; }; // ----- Range Minimum Query-based Element ----- class RangeMinimumQueryExprElement : public BaseIntExpr { public: - RangeMinimumQueryExprElement(Solver* solver, const std::vector& values, + RangeMinimumQueryExprElement(Solver* solver, + const std::vector& values, IntVar* index); ~RangeMinimumQueryExprElement() override {} - int64 Min() const override; - int64 Max() const override; - void Range(int64* mi, int64* ma) override; - void SetMin(int64 m) override; - void SetMax(int64 m) override; - void SetRange(int64 mi, int64 ma) override; + int64_t Min() const override; + int64_t Max() const override; + void Range(int64_t* mi, int64_t* ma) override; + void SetMin(int64_t m) override; + void SetMax(int64_t m) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override { return (index_->Bound()); } // TODO(user) : improve me, the previous test is not always true void WhenRange(Demon* d) override { index_->WhenRange(d); } @@ -382,66 +388,66 @@ class RangeMinimumQueryExprElement : public BaseIntExpr { } private: - int64 IndexMin() const { return std::max(0, index_->Min()); } - int64 IndexMax() const { - return std::min(min_rmq_.array().size() - 1, index_->Max()); + int64_t IndexMin() const { return std::max(0, index_->Min()); } + int64_t IndexMax() const { + return std::min(min_rmq_.array().size() - 1, index_->Max()); } IntVar* const index_; - const RangeMinimumQuery> min_rmq_; - const RangeMinimumQuery> max_rmq_; + const RangeMinimumQuery> min_rmq_; + const RangeMinimumQuery> max_rmq_; }; RangeMinimumQueryExprElement::RangeMinimumQueryExprElement( - Solver* solver, const std::vector& values, IntVar* index) + Solver* solver, const std::vector& values, IntVar* index) : BaseIntExpr(solver), index_(index), min_rmq_(values), max_rmq_(values) { CHECK(solver != nullptr); CHECK(index != nullptr); } -int64 RangeMinimumQueryExprElement::Min() const { +int64_t RangeMinimumQueryExprElement::Min() const { return min_rmq_.GetMinimumFromRange(IndexMin(), IndexMax() + 1); } -int64 RangeMinimumQueryExprElement::Max() const { +int64_t RangeMinimumQueryExprElement::Max() const { return max_rmq_.GetMinimumFromRange(IndexMin(), IndexMax() + 1); } -void RangeMinimumQueryExprElement::Range(int64* mi, int64* ma) { - const int64 range_min = IndexMin(); - const int64 range_max = IndexMax() + 1; +void RangeMinimumQueryExprElement::Range(int64_t* mi, int64_t* ma) { + const int64_t range_min = IndexMin(); + const int64_t range_max = IndexMax() + 1; *mi = min_rmq_.GetMinimumFromRange(range_min, range_max); *ma = max_rmq_.GetMinimumFromRange(range_min, range_max); } -#define UPDATE_RMQ_BASE_ELEMENT_INDEX_BOUNDS(test) \ - const std::vector& values = min_rmq_.array(); \ - int64 index_min = IndexMin(); \ - int64 index_max = IndexMax(); \ - int64 value = values[index_min]; \ - while (index_min < index_max && (test)) { \ - index_min++; \ - value = values[index_min]; \ - } \ - if (index_min == index_max && (test)) { \ - solver()->Fail(); \ - } \ - value = values[index_max]; \ - while (index_max >= index_min && (test)) { \ - index_max--; \ - value = values[index_max]; \ - } \ +#define UPDATE_RMQ_BASE_ELEMENT_INDEX_BOUNDS(test) \ + const std::vector& values = min_rmq_.array(); \ + int64_t index_min = IndexMin(); \ + int64_t index_max = IndexMax(); \ + int64_t value = values[index_min]; \ + while (index_min < index_max && (test)) { \ + index_min++; \ + value = values[index_min]; \ + } \ + if (index_min == index_max && (test)) { \ + solver()->Fail(); \ + } \ + value = values[index_max]; \ + while (index_max >= index_min && (test)) { \ + index_max--; \ + value = values[index_max]; \ + } \ index_->SetRange(index_min, index_max); -void RangeMinimumQueryExprElement::SetMin(int64 m) { +void RangeMinimumQueryExprElement::SetMin(int64_t m) { UPDATE_RMQ_BASE_ELEMENT_INDEX_BOUNDS(value < m); } -void RangeMinimumQueryExprElement::SetMax(int64 m) { +void RangeMinimumQueryExprElement::SetMax(int64_t m) { UPDATE_RMQ_BASE_ELEMENT_INDEX_BOUNDS(value > m); } -void RangeMinimumQueryExprElement::SetRange(int64 mi, int64 ma) { +void RangeMinimumQueryExprElement::SetRange(int64_t mi, int64_t ma) { if (mi > ma) { solver()->Fail(); } @@ -454,15 +460,15 @@ void RangeMinimumQueryExprElement::SetRange(int64 mi, int64 ma) { class IncreasingIntExprElement : public BaseIntExpr { public: - IncreasingIntExprElement(Solver* const s, const std::vector& values, + IncreasingIntExprElement(Solver* const s, const std::vector& values, IntVar* const index); ~IncreasingIntExprElement() override {} - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 mi, int64 ma) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override { return (index_->Bound()); } // TODO(user) : improve me, the previous test is not always true std::string name() const override { @@ -492,80 +498,84 @@ class IncreasingIntExprElement : public BaseIntExpr { } private: - const std::vector values_; + const std::vector values_; IntVar* const index_; }; IncreasingIntExprElement::IncreasingIntExprElement( - Solver* const s, const std::vector& values, IntVar* const index) + Solver* const s, const std::vector& values, IntVar* const index) : BaseIntExpr(s), values_(values), index_(index) { DCHECK(index); DCHECK(s); } -int64 IncreasingIntExprElement::Min() const { - const int64 expression_min = std::max(0, index_->Min()); - return (expression_min < values_.size() ? values_[expression_min] - : kint64max); +int64_t IncreasingIntExprElement::Min() const { + const int64_t expression_min = std::max(0, index_->Min()); + return (expression_min < values_.size() + ? values_[expression_min] + : std::numeric_limits::max()); } -void IncreasingIntExprElement::SetMin(int64 m) { - const int64 index_min = std::max(0, index_->Min()); - const int64 index_max = std::min(values_.size() - 1, index_->Max()); +void IncreasingIntExprElement::SetMin(int64_t m) { + const int64_t index_min = std::max(0, index_->Min()); + const int64_t index_max = + std::min(values_.size() - 1, index_->Max()); if (index_min > index_max || m > values_[index_max]) { solver()->Fail(); } - const std::vector::const_iterator first = + const std::vector::const_iterator first = std::lower_bound(values_.begin(), values_.end(), m); - const int64 new_index_min = first - values_.begin(); + const int64_t new_index_min = first - values_.begin(); index_->SetMin(new_index_min); } -int64 IncreasingIntExprElement::Max() const { - const int64 expression_max = - std::min(values_.size() - 1, index_->Max()); - return (expression_max >= 0 ? values_[expression_max] : kint64max); +int64_t IncreasingIntExprElement::Max() const { + const int64_t expression_max = + std::min(values_.size() - 1, index_->Max()); + return (expression_max >= 0 ? values_[expression_max] + : std::numeric_limits::max()); } -void IncreasingIntExprElement::SetMax(int64 m) { - int64 index_min = std::max(0, index_->Min()); +void IncreasingIntExprElement::SetMax(int64_t m) { + int64_t index_min = std::max(0, index_->Min()); if (m < values_[index_min]) { solver()->Fail(); } - const std::vector::const_iterator last_after = + const std::vector::const_iterator last_after = std::upper_bound(values_.begin(), values_.end(), m); - const int64 new_index_max = (last_after - values_.begin()) - 1; + const int64_t new_index_max = (last_after - values_.begin()) - 1; index_->SetRange(0, new_index_max); } -void IncreasingIntExprElement::SetRange(int64 mi, int64 ma) { +void IncreasingIntExprElement::SetRange(int64_t mi, int64_t ma) { if (mi > ma) { solver()->Fail(); } - const int64 index_min = std::max(0, index_->Min()); - const int64 index_max = std::min(values_.size() - 1, index_->Max()); + const int64_t index_min = std::max(0, index_->Min()); + const int64_t index_max = + std::min(values_.size() - 1, index_->Max()); if (mi > ma || ma < values_[index_min] || mi > values_[index_max]) { solver()->Fail(); } - const std::vector::const_iterator first = + const std::vector::const_iterator first = std::lower_bound(values_.begin(), values_.end(), mi); - const int64 new_index_min = first - values_.begin(); + const int64_t new_index_min = first - values_.begin(); - const std::vector::const_iterator last_after = + const std::vector::const_iterator last_after = std::upper_bound(first, values_.end(), ma); - const int64 new_index_max = (last_after - values_.begin()) - 1; + const int64_t new_index_max = (last_after - values_.begin()) - 1; // Assign. index_->SetRange(new_index_min, new_index_max); } // ----- Solver::MakeElement(int array, int var) ----- -IntExpr* BuildElement(Solver* const solver, const std::vector& values, +IntExpr* BuildElement(Solver* const solver, const std::vector& values, IntVar* const index) { // Various checks. // Is array constant? @@ -576,7 +586,7 @@ IntExpr* BuildElement(Solver* const solver, const std::vector& values, // Is array built with booleans only? // TODO(user): We could maintain the index of the first one. if (IsArrayBoolean(values)) { - std::vector ones; + std::vector ones; int first_zero = -1; for (int i = 0; i < values.size(); ++i) { if (values[i] == 1) { @@ -586,7 +596,7 @@ IntExpr* BuildElement(Solver* const solver, const std::vector& values, } } if (ones.size() == 1) { - DCHECK_EQ(int64{1}, values[ones.back()]); + DCHECK_EQ(int64_t{1}, values[ones.back()]); solver->AddConstraint(solver->MakeBetweenCt(index, 0, values.size() - 1)); return solver->MakeIsEqualCstVar(index, ones.back()); } else if (ones.size() == values.size() - 1) { @@ -644,7 +654,7 @@ IntExpr* BuildElement(Solver* const solver, const std::vector& values, } } // namespace -IntExpr* Solver::MakeElement(const std::vector& values, +IntExpr* Solver::MakeElement(const std::vector& values, IntVar* const index) { DCHECK(index); DCHECK_EQ(this, index->solver()); @@ -691,9 +701,9 @@ class IntExprFunctionElement : public BaseIntExprElement { } protected: - int64 ElementValue(int index) const override { return values_(index); } - int64 ExprMin() const override { return expr_->Min(); } - int64 ExprMax() const override { return expr_->Max(); } + int64_t ElementValue(int index) const override { return values_(index); } + int64_t ExprMin() const override { return expr_->Min(); } + int64_t ExprMax() const override { return expr_->Max(); } private: Solver::IndexEvaluator1 values_; @@ -723,35 +733,35 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { ~IncreasingIntExprFunctionElement() override {} - int64 Min() const override { return values_(index_->Min()); } + int64_t Min() const override { return values_(index_->Min()); } - void SetMin(int64 m) override { - const int64 index_min = index_->Min(); - const int64 index_max = index_->Max(); + void SetMin(int64_t m) override { + const int64_t index_min = index_->Min(); + const int64_t index_max = index_->Max(); if (m > values_(index_max)) { solver()->Fail(); } - const int64 new_index_min = FindNewIndexMin(index_min, index_max, m); + const int64_t new_index_min = FindNewIndexMin(index_min, index_max, m); index_->SetMin(new_index_min); } - int64 Max() const override { return values_(index_->Max()); } + int64_t Max() const override { return values_(index_->Max()); } - void SetMax(int64 m) override { - int64 index_min = index_->Min(); - int64 index_max = index_->Max(); + void SetMax(int64_t m) override { + int64_t index_min = index_->Min(); + int64_t index_max = index_->Max(); if (m < values_(index_min)) { solver()->Fail(); } - const int64 new_index_max = FindNewIndexMax(index_min, index_max, m); + const int64_t new_index_max = FindNewIndexMax(index_min, index_max, m); index_->SetMax(new_index_max); } - void SetRange(int64 mi, int64 ma) override { - const int64 index_min = index_->Min(); - const int64 index_max = index_->Max(); - const int64 value_min = values_(index_min); - const int64 value_max = values_(index_max); + void SetRange(int64_t mi, int64_t ma) override { + const int64_t index_min = index_->Min(); + const int64_t index_max = index_->Max(); + const int64_t value_min = values_(index_min); + const int64_t value_max = values_(index_max); if (mi > ma || ma < value_min || mi > value_max) { solver()->Fail(); } @@ -760,8 +770,8 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { return; } - const int64 new_index_min = FindNewIndexMin(index_min, index_max, mi); - const int64 new_index_max = FindNewIndexMax(new_index_min, index_max, ma); + const int64_t new_index_min = FindNewIndexMin(index_min, index_max, mi); + const int64_t new_index_max = FindNewIndexMax(new_index_min, index_max, ma); // Assign. index_->SetRange(new_index_min, new_index_max); } @@ -794,7 +804,7 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { } private: - int64 FindNewIndexMin(int64 index_min, int64 index_max, int64 m) { + int64_t FindNewIndexMin(int64_t index_min, int64_t index_max, int64_t m) { if (m <= values_(index_min)) { return index_min; } @@ -802,13 +812,13 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { DCHECK_LT(values_(index_min), m); DCHECK_GE(values_(index_max), m); - int64 index_lower_bound = index_min; - int64 index_upper_bound = index_max; + int64_t index_lower_bound = index_min; + int64_t index_upper_bound = index_max; while (index_upper_bound - index_lower_bound > 1) { DCHECK_LT(values_(index_lower_bound), m); DCHECK_GE(values_(index_upper_bound), m); - const int64 pivot = (index_lower_bound + index_upper_bound) / 2; - const int64 pivot_value = values_(pivot); + const int64_t pivot = (index_lower_bound + index_upper_bound) / 2; + const int64_t pivot_value = values_(pivot); if (pivot_value < m) { index_lower_bound = pivot; } else { @@ -819,7 +829,7 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { return index_upper_bound; } - int64 FindNewIndexMax(int64 index_min, int64 index_max, int64 m) { + int64_t FindNewIndexMax(int64_t index_min, int64_t index_max, int64_t m) { if (m >= values_(index_max)) { return index_max; } @@ -827,13 +837,13 @@ class IncreasingIntExprFunctionElement : public BaseIntExpr { DCHECK_LE(values_(index_min), m); DCHECK_GT(values_(index_max), m); - int64 index_lower_bound = index_min; - int64 index_upper_bound = index_max; + int64_t index_lower_bound = index_min; + int64_t index_upper_bound = index_max; while (index_upper_bound - index_lower_bound > 1) { DCHECK_LE(values_(index_lower_bound), m); DCHECK_GT(values_(index_upper_bound), m); - const int64 pivot = (index_lower_bound + index_upper_bound) / 2; - const int64 pivot_value = values_(pivot); + const int64_t pivot = (index_lower_bound + index_upper_bound) / 2; + const int64_t pivot_value = values_(pivot); if (pivot_value > m) { index_upper_bound = pivot; } else { @@ -865,7 +875,7 @@ IntExpr* Solver::MakeMonotonicElement(Solver::IndexEvaluator1 values, } else { // You need to pass by copy such that opposite_value does not include a // dandling reference when leaving this scope. - Solver::IndexEvaluator1 opposite_values = [values](int64 i) { + Solver::IndexEvaluator1 opposite_values = [values](int64_t i) { return -values(i); }; return RegisterIntExpr(MakeOpposite(RevAlloc( @@ -885,12 +895,12 @@ class IntIntExprFunctionElement : public BaseIntExpr { return absl::StrFormat("IntIntFunctionElement(%s,%s)", expr1_->DebugString(), expr2_->DebugString()); } - int64 Min() const override; - int64 Max() const override; - void Range(int64* lower_bound, int64* upper_bound) override; - void SetMin(int64 lower_bound) override; - void SetMax(int64 upper_bound) override; - void SetRange(int64 lower_bound, int64 upper_bound) override; + int64_t Min() const override; + int64_t Max() const override; + void Range(int64_t* lower_bound, int64_t* upper_bound) override; + void SetMin(int64_t lower_bound) override; + void SetMax(int64_t upper_bound) override; + void SetRange(int64_t lower_bound, int64_t upper_bound) override; bool Bound() const override { return expr1_->Bound() && expr2_->Bound(); } // TODO(user) : improve me, the previous test is not always true void WhenRange(Demon* d) override { @@ -905,30 +915,30 @@ class IntIntExprFunctionElement : public BaseIntExpr { visitor->VisitIntegerExpressionArgument(ModelVisitor::kIndex2Argument, expr2_); // Warning: This will expand all values into a vector. - const int64 expr1_min = expr1_->Min(); - const int64 expr1_max = expr1_->Max(); + const int64_t expr1_min = expr1_->Min(); + const int64_t expr1_max = expr1_->Max(); visitor->VisitIntegerArgument(ModelVisitor::kMinArgument, expr1_min); visitor->VisitIntegerArgument(ModelVisitor::kMaxArgument, expr1_max); for (int i = expr1_min; i <= expr1_max; ++i) { visitor->VisitInt64ToInt64Extension( - [this, i](int64 j) { return values_(i, j); }, expr2_->Min(), + [this, i](int64_t j) { return values_(i, j); }, expr2_->Min(), expr2_->Max()); } visitor->EndVisitIntegerExpression(ModelVisitor::kElement, this); } private: - int64 ElementValue(int index1, int index2) const { + int64_t ElementValue(int index1, int index2) const { return values_(index1, index2); } void UpdateSupports() const; IntVar* const expr1_; IntVar* const expr2_; - mutable int64 min_; + mutable int64_t min_; mutable int min_support1_; mutable int min_support2_; - mutable int64 max_; + mutable int64_t max_; mutable int max_support1_; mutable int max_support2_; mutable bool initial_update_; @@ -958,101 +968,103 @@ IntIntExprFunctionElement::IntIntExprFunctionElement( IntIntExprFunctionElement::~IntIntExprFunctionElement() {} -int64 IntIntExprFunctionElement::Min() const { +int64_t IntIntExprFunctionElement::Min() const { UpdateSupports(); return min_; } -int64 IntIntExprFunctionElement::Max() const { +int64_t IntIntExprFunctionElement::Max() const { UpdateSupports(); return max_; } -void IntIntExprFunctionElement::Range(int64* lower_bound, int64* upper_bound) { +void IntIntExprFunctionElement::Range(int64_t* lower_bound, + int64_t* upper_bound) { UpdateSupports(); *lower_bound = min_; *upper_bound = max_; } -#define UPDATE_ELEMENT_INDEX_BOUNDS(test) \ - const int64 emin1 = expr1_->Min(); \ - const int64 emax1 = expr1_->Max(); \ - const int64 emin2 = expr2_->Min(); \ - const int64 emax2 = expr2_->Max(); \ - int64 nmin1 = emin1; \ - bool found = false; \ - while (nmin1 <= emax1 && !found) { \ - for (int i = emin2; i <= emax2; ++i) { \ - int64 value = ElementValue(nmin1, i); \ - if (test) { \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - nmin1++; \ - } \ - } \ - if (nmin1 > emax1) { \ - solver()->Fail(); \ - } \ - int64 nmin2 = emin2; \ - found = false; \ - while (nmin2 <= emax2 && !found) { \ - for (int i = emin1; i <= emax1; ++i) { \ - int64 value = ElementValue(i, nmin2); \ - if (test) { \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - nmin2++; \ - } \ - } \ - if (nmin2 > emax2) { \ - solver()->Fail(); \ - } \ - int64 nmax1 = emax1; \ - found = false; \ - while (nmax1 >= nmin1 && !found) { \ - for (int i = emin2; i <= emax2; ++i) { \ - int64 value = ElementValue(nmax1, i); \ - if (test) { \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - nmax1--; \ - } \ - } \ - int64 nmax2 = emax2; \ - found = false; \ - while (nmax2 >= nmin2 && !found) { \ - for (int i = emin1; i <= emax1; ++i) { \ - int64 value = ElementValue(i, nmax2); \ - if (test) { \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - nmax2--; \ - } \ - } \ - expr1_->SetRange(nmin1, nmax1); \ +#define UPDATE_ELEMENT_INDEX_BOUNDS(test) \ + const int64_t emin1 = expr1_->Min(); \ + const int64_t emax1 = expr1_->Max(); \ + const int64_t emin2 = expr2_->Min(); \ + const int64_t emax2 = expr2_->Max(); \ + int64_t nmin1 = emin1; \ + bool found = false; \ + while (nmin1 <= emax1 && !found) { \ + for (int i = emin2; i <= emax2; ++i) { \ + int64_t value = ElementValue(nmin1, i); \ + if (test) { \ + found = true; \ + break; \ + } \ + } \ + if (!found) { \ + nmin1++; \ + } \ + } \ + if (nmin1 > emax1) { \ + solver()->Fail(); \ + } \ + int64_t nmin2 = emin2; \ + found = false; \ + while (nmin2 <= emax2 && !found) { \ + for (int i = emin1; i <= emax1; ++i) { \ + int64_t value = ElementValue(i, nmin2); \ + if (test) { \ + found = true; \ + break; \ + } \ + } \ + if (!found) { \ + nmin2++; \ + } \ + } \ + if (nmin2 > emax2) { \ + solver()->Fail(); \ + } \ + int64_t nmax1 = emax1; \ + found = false; \ + while (nmax1 >= nmin1 && !found) { \ + for (int i = emin2; i <= emax2; ++i) { \ + int64_t value = ElementValue(nmax1, i); \ + if (test) { \ + found = true; \ + break; \ + } \ + } \ + if (!found) { \ + nmax1--; \ + } \ + } \ + int64_t nmax2 = emax2; \ + found = false; \ + while (nmax2 >= nmin2 && !found) { \ + for (int i = emin1; i <= emax1; ++i) { \ + int64_t value = ElementValue(i, nmax2); \ + if (test) { \ + found = true; \ + break; \ + } \ + } \ + if (!found) { \ + nmax2--; \ + } \ + } \ + expr1_->SetRange(nmin1, nmax1); \ expr2_->SetRange(nmin2, nmax2); -void IntIntExprFunctionElement::SetMin(int64 lower_bound) { +void IntIntExprFunctionElement::SetMin(int64_t lower_bound) { UPDATE_ELEMENT_INDEX_BOUNDS(value >= lower_bound); } -void IntIntExprFunctionElement::SetMax(int64 upper_bound) { +void IntIntExprFunctionElement::SetMax(int64_t upper_bound) { UPDATE_ELEMENT_INDEX_BOUNDS(value <= upper_bound); } -void IntIntExprFunctionElement::SetRange(int64 lower_bound, int64 upper_bound) { +void IntIntExprFunctionElement::SetRange(int64_t lower_bound, + int64_t upper_bound) { if (lower_bound > upper_bound) { solver()->Fail(); } @@ -1065,17 +1077,17 @@ void IntIntExprFunctionElement::UpdateSupports() const { if (initial_update_ || !expr1_->Contains(min_support1_) || !expr1_->Contains(max_support1_) || !expr2_->Contains(min_support2_) || !expr2_->Contains(max_support2_)) { - const int64 emax1 = expr1_->Max(); - const int64 emax2 = expr2_->Max(); - int64 min_value = ElementValue(emax1, emax2); - int64 max_value = min_value; + const int64_t emax1 = expr1_->Max(); + const int64_t emax2 = expr2_->Max(); + int64_t min_value = ElementValue(emax1, emax2); + int64_t max_value = min_value; int min_support1 = emax1; int max_support1 = emax1; int min_support2 = emax2; int max_support2 = emax2; - for (const int64 index1 : InitAndGetValues(expr1_iterator_)) { - for (const int64 index2 : InitAndGetValues(expr2_iterator_)) { - const int64 value = ElementValue(index1, index2); + for (const int64_t index1 : InitAndGetValues(expr1_iterator_)) { + for (const int64_t index2 : InitAndGetValues(expr2_iterator_)) { + const int64_t value = ElementValue(index1, index2); if (value > max_value) { max_value = value; max_support1 = index1; @@ -1132,10 +1144,10 @@ class IfThenElseCt : public CastConstraint { void InitialPropagate() override { condition_->SetRange(0, 1); - const int64 target_var_min = target_var_->Min(); - const int64 target_var_max = target_var_->Max(); - int64 new_min = kint64min; - int64 new_max = kint64max; + const int64_t target_var_min = target_var_->Min(); + const int64_t target_var_max = target_var_->Max(); + int64_t new_min = std::numeric_limits::min(); + int64_t new_max = std::numeric_limits::max(); if (condition_->Max() == 0) { zero_->SetRange(target_var_min, target_var_max); zero_->Range(&new_min, &new_max); @@ -1152,10 +1164,10 @@ class IfThenElseCt : public CastConstraint { zero_->SetRange(target_var_min, target_var_max); zero_->Range(&new_min, &new_max); } else { - int64 zl = 0; - int64 zu = 0; - int64 ol = 0; - int64 ou = 0; + int64_t zl = 0; + int64_t zu = 0; + int64_t ol = 0; + int64_t ou = 0; zero_->Range(&zl, &zu); one_->Range(&ol, &ou); new_min = std::min(zl, ol); @@ -1189,7 +1201,7 @@ namespace { class IntExprEvaluatorElementCt : public CastConstraint { public: IntExprEvaluatorElementCt(Solver* const s, Solver::Int64ToIntVar evaluator, - int64 range_start, int64 range_end, + int64_t range_start, int64_t range_end, IntVar* const index, IntVar* const target_var); ~IntExprEvaluatorElementCt() override {} @@ -1208,15 +1220,15 @@ class IntExprEvaluatorElementCt : public CastConstraint { private: const Solver::Int64ToIntVar evaluator_; - const int64 range_start_; - const int64 range_end_; + const int64_t range_start_; + const int64_t range_end_; int min_support_; int max_support_; }; IntExprEvaluatorElementCt::IntExprEvaluatorElementCt( - Solver* const s, Solver::Int64ToIntVar evaluator, int64 range_start, - int64 range_end, IntVar* const index, IntVar* const target_var) + Solver* const s, Solver::Int64ToIntVar evaluator, int64_t range_start, + int64_t range_end, IntVar* const index, IntVar* const target_var) : CastConstraint(s, target_var), index_(index), evaluator_(std::move(evaluator)), @@ -1248,15 +1260,15 @@ void IntExprEvaluatorElementCt::Post() { void IntExprEvaluatorElementCt::InitialPropagate() { Propagate(); } void IntExprEvaluatorElementCt::Propagate() { - const int64 emin = std::max(range_start_, index_->Min()); - const int64 emax = std::min(range_end_ - 1, index_->Max()); - const int64 vmin = target_var_->Min(); - const int64 vmax = target_var_->Max(); + const int64_t emin = std::max(range_start_, index_->Min()); + const int64_t emax = std::min(range_end_ - 1, index_->Max()); + const int64_t vmin = target_var_->Min(); + const int64_t vmax = target_var_->Max(); if (emin == emax) { index_->SetValue(emin); // in case it was reduced by the above min/max. evaluator_(emin)->SetRange(vmin, vmax); } else { - int64 nmin = emin; + int64_t nmin = emin; for (; nmin <= emax; nmin++) { // break if the intersection of // [evaluator_(nmin)->Min(), evaluator_(nmin)->Max()] and [vmin, vmax] @@ -1264,7 +1276,7 @@ void IntExprEvaluatorElementCt::Propagate() { IntVar* const nmin_var = evaluator_(nmin); if (nmin_var->Min() <= vmax && nmin_var->Max() >= vmin) break; } - int64 nmax = emax; + int64_t nmax = emax; for (; nmin <= nmax; nmax--) { // break if the intersection of // [evaluator_(nmin)->Min(), evaluator_(nmin)->Max()] and [vmin, vmax] @@ -1280,15 +1292,15 @@ void IntExprEvaluatorElementCt::Propagate() { if (min_support_ == -1 || max_support_ == -1) { int min_support = -1; int max_support = -1; - int64 gmin = kint64max; - int64 gmax = kint64min; + int64_t gmin = std::numeric_limits::max(); + int64_t gmax = std::numeric_limits::min(); for (int i = index_->Min(); i <= index_->Max(); ++i) { IntExpr* const var_i = evaluator_(i); - const int64 vmin = var_i->Min(); + const int64_t vmin = var_i->Min(); if (vmin < gmin) { gmin = vmin; } - const int64 vmax = var_i->Max(); + const int64_t vmax = var_i->Max(); if (vmax > gmax) { gmax = vmax; } @@ -1315,9 +1327,9 @@ void IntExprEvaluatorElementCt::UpdateExpr() { namespace { std::string StringifyEvaluatorBare(const Solver::Int64ToIntVar& evaluator, - int64 range_start, int64 range_end) { + int64_t range_start, int64_t range_end) { std::string out; - for (int64 i = range_start; i < range_end; ++i) { + for (int64_t i = range_start; i < range_end; ++i) { if (i != range_start) { out += ", "; } @@ -1327,7 +1339,7 @@ std::string StringifyEvaluatorBare(const Solver::Int64ToIntVar& evaluator, } std::string StringifyInt64ToIntVar(const Solver::Int64ToIntVar& evaluator, - int64 range_begin, int64 range_end) { + int64_t range_begin, int64_t range_end) { std::string out; if (range_end - range_begin > 10) { out = absl::StrFormat( @@ -1379,12 +1391,12 @@ IntExprArrayElementCt::IntExprArrayElementCt(Solver* const s, IntVar* const index, IntVar* const target_var) : IntExprEvaluatorElementCt( - s, [this](int64 idx) { return vars_[idx]; }, 0, vars.size(), index, + s, [this](int64_t idx) { return vars_[idx]; }, 0, vars.size(), index, target_var), vars_(std::move(vars)) {} std::string IntExprArrayElementCt::DebugString() const { - int64 size = vars_.size(); + int64_t size = vars_.size(); if (size > 10) { return absl::StrFormat( "IntExprArrayElement(var array of size %d, %s) == %s", size, @@ -1413,7 +1425,7 @@ void IntExprArrayElementCt::Accept(ModelVisitor* const visitor) const { class IntExprArrayElementCstCt : public Constraint { public: IntExprArrayElementCstCt(Solver* const s, const std::vector& vars, - IntVar* const index, int64 target) + IntVar* const index, int64_t target) : Constraint(s), vars_(vars), index_(index), @@ -1473,7 +1485,7 @@ class IntExprArrayElementCstCt : public Constraint { private: const std::vector vars_; IntVar* const index_; - const int64 target_; + const int64_t target_; std::vector demons_; }; @@ -1482,7 +1494,7 @@ class IntExprArrayElementCstCt : public Constraint { class IntExprIndexOfCt : public Constraint { public: IntExprIndexOfCt(Solver* const s, const std::vector& vars, - IntVar* const index, int64 target) + IntVar* const index, int64_t target) : Constraint(s), vars_(vars), index_(index), @@ -1527,18 +1539,18 @@ class IntExprIndexOfCt : public Constraint { } void PropagateIndex() { - const int64 oldmax = index_->OldMax(); - const int64 vmin = index_->Min(); - const int64 vmax = index_->Max(); - for (int64 value = index_->OldMin(); value < vmin; ++value) { + const int64_t oldmax = index_->OldMax(); + const int64_t vmin = index_->Min(); + const int64_t vmax = index_->Max(); + for (int64_t value = index_->OldMin(); value < vmin; ++value) { vars_[value]->RemoveValue(target_); demons_[value]->inhibit(solver()); } - for (const int64 value : InitAndGetValues(index_iterator_)) { + for (const int64_t value : InitAndGetValues(index_iterator_)) { vars_[value]->RemoveValue(target_); demons_[value]->inhibit(solver()); } - for (int64 value = vmax + 1; value <= oldmax; ++value) { + for (int64_t value = vmax + 1; value <= oldmax; ++value) { vars_[value]->RemoveValue(target_); demons_[value]->inhibit(solver()); } @@ -1566,7 +1578,7 @@ class IntExprIndexOfCt : public Constraint { private: const std::vector vars_; IntVar* const index_; - const int64 target_; + const int64_t target_; std::vector demons_; IntVarIterator* const index_iterator_; }; @@ -1574,10 +1586,10 @@ class IntExprIndexOfCt : public Constraint { // Factory helper. Constraint* MakeElementEqualityFunc(Solver* const solver, - const std::vector& vals, + const std::vector& vals, IntVar* const index, IntVar* const target) { if (index->Bound()) { - const int64 val = index->Min(); + const int64_t val = index->Min(); if (val < 0 || val >= vals.size()) { return solver->MakeFalseConstraint(); } else { @@ -1609,7 +1621,7 @@ IntExpr* Solver::MakeElement(const std::vector& vars, } const int size = vars.size(); if (AreAllBound(vars)) { - std::vector values(size); + std::vector values(size); for (int i = 0; i < size; ++i) { values[i] = vars[i]->Value(); } @@ -1629,10 +1641,10 @@ IntExpr* Solver::MakeElement(const std::vector& vars, RevAlloc(new IfThenElseCt(this, scaled_index, one, zero, target))); return target; } - int64 emin = kint64max; - int64 emax = kint64min; + int64_t emin = std::numeric_limits::max(); + int64_t emax = std::numeric_limits::min(); std::unique_ptr iterator(index->MakeDomainIterator(false)); - for (const int64 index_value : InitAndGetValues(iterator.get())) { + for (const int64_t index_value : InitAndGetValues(iterator.get())) { if (index_value >= 0 && index_value < size) { emin = std::min(emin, vars[index_value]->Min()); emax = std::max(emax, vars[index_value]->Max()); @@ -1649,14 +1661,16 @@ IntExpr* Solver::MakeElement(const std::vector& vars, return element_var; } -IntExpr* Solver::MakeElement(Int64ToIntVar vars, int64 range_start, - int64 range_end, IntVar* argument) { +IntExpr* Solver::MakeElement(Int64ToIntVar vars, int64_t range_start, + int64_t range_end, IntVar* argument) { const std::string index_name = !argument->name().empty() ? argument->name() : argument->DebugString(); const std::string vname = absl::StrFormat( "ElementVar(%s, %s)", StringifyInt64ToIntVar(vars, range_start, range_end), index_name); - IntVar* const element_var = MakeIntVar(kint64min, kint64max, vname); + IntVar* const element_var = + MakeIntVar(std::numeric_limits::min(), + std::numeric_limits::max(), vname); IntExprEvaluatorElementCt* evaluation_ct = new IntExprEvaluatorElementCt( this, std::move(vars), range_start, range_end, argument, element_var); AddConstraint(RevAlloc(evaluation_ct)); @@ -1664,7 +1678,7 @@ IntExpr* Solver::MakeElement(Int64ToIntVar vars, int64 range_start, return element_var; } -Constraint* Solver::MakeElementEquality(const std::vector& vals, +Constraint* Solver::MakeElementEquality(const std::vector& vals, IntVar* const index, IntVar* const target) { return MakeElementEqualityFunc(this, vals, index, target); @@ -1680,14 +1694,14 @@ Constraint* Solver::MakeElementEquality(const std::vector& vars, IntVar* const index, IntVar* const target) { if (AreAllBound(vars)) { - std::vector values(vars.size()); + std::vector values(vars.size()); for (int i = 0; i < vars.size(); ++i) { values[i] = vars[i]->Value(); } return MakeElementEquality(values, index, target); } if (index->Bound()) { - const int64 val = index->Min(); + const int64_t val = index->Min(); if (val < 0 || val >= vars.size()) { return MakeFalseConstraint(); } else { @@ -1704,7 +1718,7 @@ Constraint* Solver::MakeElementEquality(const std::vector& vars, } Constraint* Solver::MakeElementEquality(const std::vector& vars, - IntVar* const index, int64 target) { + IntVar* const index, int64_t target) { if (AreAllBound(vars)) { std::vector valid_indices; for (int i = 0; i < vars.size(); ++i) { @@ -1715,7 +1729,7 @@ Constraint* Solver::MakeElementEquality(const std::vector& vars, return MakeMemberCt(index, valid_indices); } if (index->Bound()) { - const int64 pos = index->Min(); + const int64_t pos = index->Min(); if (pos >= 0 && pos < vars.size()) { IntVar* const var = vars[pos]; return MakeEquality(var, target); @@ -1728,9 +1742,9 @@ Constraint* Solver::MakeElementEquality(const std::vector& vars, } Constraint* Solver::MakeIndexOfConstraint(const std::vector& vars, - IntVar* const index, int64 target) { + IntVar* const index, int64_t target) { if (index->Bound()) { - const int64 pos = index->Min(); + const int64_t pos = index->Min(); if (pos >= 0 && pos < vars.size()) { IntVar* const var = vars[pos]; return MakeEquality(var, target); @@ -1743,7 +1757,7 @@ Constraint* Solver::MakeIndexOfConstraint(const std::vector& vars, } IntExpr* Solver::MakeIndexExpression(const std::vector& vars, - int64 value) { + int64_t value) { IntExpr* const cache = model_cache_->FindVarArrayConstantExpression( vars, value, ModelCache::VAR_ARRAY_CONSTANT_INDEX); if (cache != nullptr) { diff --git a/ortools/constraint_solver/expr_array.cc b/ortools/constraint_solver/expr_array.cc index 3f15cba6b7..a7756c7528 100644 --- a/ortools/constraint_solver/expr_array.cc +++ b/ortools/constraint_solver/expr_array.cc @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include @@ -72,7 +74,8 @@ class TreeArrayConstraint : public CastConstraint { } // Increases min by delta_min, reduces max by delta_max. - void ReduceRange(int depth, int position, int64 delta_min, int64 delta_max) { + void ReduceRange(int depth, int position, int64_t delta_min, + int64_t delta_max) { NodeInfo* const info = &tree_[depth][position]; if (delta_min > 0) { info->node_min.SetValue(solver(), @@ -85,7 +88,7 @@ class TreeArrayConstraint : public CastConstraint { } // Sets the range on the given node. - void SetRange(int depth, int position, int64 new_min, int64 new_max) { + void SetRange(int depth, int position, int64_t new_min, int64_t new_max) { NodeInfo* const info = &tree_[depth][position]; if (new_min > info->node_min.Value()) { info->node_min.SetValue(solver(), new_min); @@ -95,26 +98,26 @@ class TreeArrayConstraint : public CastConstraint { } } - void InitLeaf(int position, int64 var_min, int64 var_max) { + void InitLeaf(int position, int64_t var_min, int64_t var_max) { InitNode(MaxDepth(), position, var_min, var_max); } - void InitNode(int depth, int position, int64 node_min, int64 node_max) { + void InitNode(int depth, int position, int64_t node_min, int64_t node_max) { tree_[depth][position].node_min.SetValue(solver(), node_min); tree_[depth][position].node_max.SetValue(solver(), node_max); } - int64 Min(int depth, int position) const { + int64_t Min(int depth, int position) const { return tree_[depth][position].node_min.Value(); } - int64 Max(int depth, int position) const { + int64_t Max(int depth, int position) const { return tree_[depth][position].node_max.Value(); } - int64 RootMin() const { return root_node_->node_min.Value(); } + int64_t RootMin() const { return root_node_->node_min.Value(); } - int64 RootMax() const { return root_node_->node_max.Value(); } + int64_t RootMax() const { return root_node_->node_max.Value(); } int Parent(int position) const { return position / block_size_; } @@ -137,8 +140,8 @@ class TreeArrayConstraint : public CastConstraint { private: struct NodeInfo { NodeInfo() : node_min(0), node_max(0) {} - Rev node_min; - Rev node_max; + Rev node_min; + Rev node_max; }; std::vector > tree_; @@ -185,8 +188,8 @@ class SumConstraint : public TreeArrayConstraint { // Compute up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; const int block_start = ChildStart(j); const int block_end = ChildEnd(i, j); for (int k = block_start; k <= block_end; ++k) { @@ -204,13 +207,14 @@ class SumConstraint : public TreeArrayConstraint { } void SumChanged() { - if (target_var_->Max() == RootMin() && target_var_->Max() != kint64max) { + if (target_var_->Max() == RootMin() && + target_var_->Max() != std::numeric_limits::max()) { // We can fix all terms to min. for (int i = 0; i < vars_.size(); ++i) { vars_[i]->SetValue(vars_[i]->Min()); } } else if (target_var_->Min() == RootMax() && - target_var_->Min() != kint64min) { + target_var_->Min() != std::numeric_limits::min()) { // We can fix all terms to max. for (int i = 0; i < vars_.size(); ++i) { vars_[i]->SetValue(vars_[i]->Max()); @@ -220,7 +224,7 @@ class SumConstraint : public TreeArrayConstraint { } } - void PushDown(int depth, int position, int64 new_min, int64 new_max) { + void PushDown(int depth, int position, int64_t new_min, int64_t new_max) { // Nothing to do? if (new_min <= Min(depth, position) && new_max >= Max(depth, position)) { return; @@ -236,8 +240,8 @@ class SumConstraint : public TreeArrayConstraint { // individuals terms. // These are maintained automatically in the tree structure. - const int64 sum_min = Min(depth, position); - const int64 sum_max = Max(depth, position); + const int64_t sum_min = Min(depth, position); + const int64_t sum_max = Max(depth, position); // Intersect the new bounds with the computed bounds. new_max = std::min(sum_max, new_max); @@ -252,10 +256,10 @@ class SumConstraint : public TreeArrayConstraint { const int block_start = ChildStart(position); const int block_end = ChildEnd(depth, position); for (int i = block_start; i <= block_end; ++i) { - const int64 target_var_min = Min(depth + 1, i); - const int64 target_var_max = Max(depth + 1, i); - const int64 residual_min = CapSub(sum_min, target_var_min); - const int64 residual_max = CapSub(sum_max, target_var_max); + const int64_t target_var_min = Min(depth + 1, i); + const int64_t target_var_max = Max(depth + 1, i); + const int64_t residual_min = CapSub(sum_min, target_var_min); + const int64_t residual_max = CapSub(sum_max, target_var_max); PushDown(depth + 1, i, CapSub(new_min, residual_max), CapSub(new_max, residual_min)); } @@ -270,7 +274,7 @@ class SumConstraint : public TreeArrayConstraint { EnqueueDelayedDemon(sum_demon_); // TODO(user): Is this needed? } - void PushUp(int position, int64 delta_min, int64 delta_max) { + void PushUp(int position, int64_t delta_min, int64_t delta_max) { DCHECK_GE(delta_max, 0); DCHECK_GE(delta_min, 0); DCHECK_GT(CapAdd(delta_min, delta_max), 0); @@ -324,8 +328,8 @@ class SmallSumConstraint : public Constraint { void InitialPropagate() override { // Compute up. - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; for (IntVar* const var : vars_) { sum_min = CapAdd(sum_min, var->Min()); sum_max = CapAdd(sum_max, var->Max()); @@ -341,16 +345,17 @@ class SmallSumConstraint : public Constraint { } void SumChanged() { - int64 new_min = target_var_->Min(); - int64 new_max = target_var_->Max(); - const int64 sum_min = computed_min_.Value(); - const int64 sum_max = computed_max_.Value(); - if (new_max == sum_min && new_max != kint64max) { + int64_t new_min = target_var_->Min(); + int64_t new_max = target_var_->Max(); + const int64_t sum_min = computed_min_.Value(); + const int64_t sum_max = computed_max_.Value(); + if (new_max == sum_min && new_max != std::numeric_limits::max()) { // We can fix all terms to min. for (int i = 0; i < vars_.size(); ++i) { vars_[i]->SetValue(vars_[i]->Min()); } - } else if (new_min == sum_max && new_min != kint64min) { + } else if (new_min == sum_max && + new_min != std::numeric_limits::min()) { // We can fix all terms to max. for (int i = 0; i < vars_.size(); ++i) { vars_[i]->SetValue(vars_[i]->Max()); @@ -368,10 +373,10 @@ class SmallSumConstraint : public Constraint { // Push to variables. for (IntVar* const var : vars_) { - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); - const int64 residual_min = CapSub(sum_min, var_min); - const int64 residual_max = CapSub(sum_max, var_max); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); + const int64_t residual_min = CapSub(sum_min, var_min); + const int64_t residual_max = CapSub(sum_max, var_max); var->SetRange(CapSub(new_min, residual_max), CapSub(new_max, residual_min)); } @@ -380,8 +385,8 @@ class SmallSumConstraint : public Constraint { } void VarChanged(IntVar* var) { - const int64 delta_min = CapSub(var->Min(), var->OldMin()); - const int64 delta_max = CapSub(var->OldMax(), var->Max()); + const int64_t delta_min = CapSub(var->Min(), var->OldMin()); + const int64_t delta_max = CapSub(var->OldMax(), var->Max()); computed_min_.Add(solver(), delta_min); computed_max_.Add(solver(), -delta_max); if (computed_max_.Value() < target_var_->Max() || @@ -410,19 +415,20 @@ class SmallSumConstraint : public Constraint { private: const std::vector vars_; IntVar* target_var_; - NumericalRev computed_min_; - NumericalRev computed_max_; + NumericalRev computed_min_; + NumericalRev computed_max_; Demon* sum_demon_; }; // ----- SafeSumConstraint ----- bool DetectSumOverflow(const std::vector& vars) { - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; for (int i = 0; i < vars.size(); ++i) { sum_min = CapAdd(sum_min, vars[i]->Min()); sum_max = CapAdd(sum_max, vars[i]->Max()); - if (sum_min == kint64min || sum_max == kint64max) { + if (sum_min == std::numeric_limits::min() || + sum_max == std::numeric_limits::max()) { return true; } } @@ -449,19 +455,20 @@ class SafeSumConstraint : public TreeArrayConstraint { target_var_->WhenRange(sum_demon_); } - void SafeComputeNode(int depth, int position, int64* const sum_min, - int64* const sum_max) { + void SafeComputeNode(int depth, int position, int64_t* const sum_min, + int64_t* const sum_max) { DCHECK_LT(depth, MaxDepth()); const int block_start = ChildStart(position); const int block_end = ChildEnd(depth, position); for (int k = block_start; k <= block_end; ++k) { - if (*sum_min != kint64min) { + if (*sum_min != std::numeric_limits::min()) { *sum_min = CapAdd(*sum_min, Min(depth + 1, k)); } - if (*sum_max != kint64max) { + if (*sum_max != std::numeric_limits::max()) { *sum_max = CapAdd(*sum_max, Max(depth + 1, k)); } - if (*sum_min == kint64min && *sum_max == kint64max) { + if (*sum_min == std::numeric_limits::min() && + *sum_max == std::numeric_limits::max()) { break; } } @@ -475,8 +482,8 @@ class SafeSumConstraint : public TreeArrayConstraint { // Compute up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; SafeComputeNode(i, j, &sum_min, &sum_max); InitNode(i, j, sum_min, sum_max); } @@ -505,7 +512,7 @@ class SafeSumConstraint : public TreeArrayConstraint { } } - void PushDown(int depth, int position, int64 new_min, int64 new_max) { + void PushDown(int depth, int position, int64_t new_min, int64_t new_max) { // Nothing to do? if (new_min <= Min(depth, position) && new_max >= Max(depth, position)) { return; @@ -521,8 +528,8 @@ class SafeSumConstraint : public TreeArrayConstraint { // individuals terms. // These are maintained automatically in the tree structure. - const int64 sum_min = Min(depth, position); - const int64 sum_max = Max(depth, position); + const int64_t sum_min = Min(depth, position); + const int64_t sum_max = Max(depth, position); // Intersect the new bounds with the computed bounds. new_max = std::min(sum_max, new_max); @@ -537,17 +544,23 @@ class SafeSumConstraint : public TreeArrayConstraint { const int block_start = ChildStart(position); const int block_end = ChildEnd(depth, position); for (int pos = block_start; pos <= block_end; ++pos) { - const int64 target_var_min = Min(depth + 1, pos); - const int64 residual_min = - sum_min != kint64min ? CapSub(sum_min, target_var_min) : kint64min; - const int64 target_var_max = Max(depth + 1, pos); - const int64 residual_max = - sum_max != kint64max ? CapSub(sum_max, target_var_max) : kint64max; + const int64_t target_var_min = Min(depth + 1, pos); + const int64_t residual_min = + sum_min != std::numeric_limits::min() + ? CapSub(sum_min, target_var_min) + : std::numeric_limits::min(); + const int64_t target_var_max = Max(depth + 1, pos); + const int64_t residual_max = + sum_max != std::numeric_limits::max() + ? CapSub(sum_max, target_var_max) + : std::numeric_limits::max(); PushDown(depth + 1, pos, - (residual_max == kint64min ? kint64min - : CapSub(new_min, residual_max)), - (residual_min == kint64max ? kint64min - : CapSub(new_max, residual_min))); + (residual_max == std::numeric_limits::min() + ? std::numeric_limits::min() + : CapSub(new_min, residual_max)), + (residual_min == std::numeric_limits::max() + ? std::numeric_limits::min() + : CapSub(new_max, residual_min))); } // TODO(user) : Is the diameter optimization (see reference // above, rule 5) useful? @@ -560,7 +573,7 @@ class SafeSumConstraint : public TreeArrayConstraint { EnqueueDelayedDemon(sum_demon_); // TODO(user): Is this needed? } - void PushUp(int position, int64 delta_min, int64 delta_max) { + void PushUp(int position, int64_t delta_min, int64_t delta_max) { DCHECK_GE(delta_max, 0); DCHECK_GE(delta_min, 0); if (CapAdd(delta_min, delta_max) == 0) { @@ -570,19 +583,22 @@ class SafeSumConstraint : public TreeArrayConstraint { } bool delta_corrupted = false; for (int depth = MaxDepth(); depth >= 0; --depth) { - if (Min(depth, position) != kint64min && - Max(depth, position) != kint64max && delta_min != kint64max && - delta_max != kint64max && !delta_corrupted) { // No overflow. + if (Min(depth, position) != std::numeric_limits::min() && + Max(depth, position) != std::numeric_limits::max() && + delta_min != std::numeric_limits::max() && + delta_max != std::numeric_limits::max() && + !delta_corrupted) { // No overflow. ReduceRange(depth, position, delta_min, delta_max); } else if (depth == MaxDepth()) { // Leaf. SetRange(depth, position, vars_[position]->Min(), vars_[position]->Max()); delta_corrupted = true; } else { // Recompute. - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; SafeComputeNode(depth, position, &sum_min, &sum_max); - if (sum_min == kint64min && sum_max == kint64max) { + if (sum_min == std::numeric_limits::min() && + sum_max == std::numeric_limits::max()) { return; // Nothing to do upward. } SetRange(depth, position, sum_min, sum_max); @@ -610,8 +626,8 @@ class SafeSumConstraint : public TreeArrayConstraint { // Check up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 sum_min = 0; - int64 sum_max = 0; + int64_t sum_min = 0; + int64_t sum_max = 0; SafeComputeNode(i, j, &sum_min, &sum_max); CheckNode(i, j, sum_min, sum_max); } @@ -619,11 +635,11 @@ class SafeSumConstraint : public TreeArrayConstraint { return true; } - void CheckLeaf(int position, int64 var_min, int64 var_max) { + void CheckLeaf(int position, int64_t var_min, int64_t var_max) { CheckNode(MaxDepth(), position, var_min, var_max); } - void CheckNode(int depth, int position, int64 node_min, int64 node_max) { + void CheckNode(int depth, int position, int64_t node_min, int64_t node_max) { DCHECK_EQ(Min(depth, position), node_min); DCHECK_EQ(Max(depth, position), node_max); } @@ -662,8 +678,8 @@ class MinConstraint : public TreeArrayConstraint { // Compute up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 min_min = kint64max; - int64 min_max = kint64max; + int64_t min_min = std::numeric_limits::max(); + int64_t min_max = std::numeric_limits::max(); const int block_start = ChildStart(j); const int block_end = ChildEnd(i, j); for (int k = block_start; k <= block_end; ++k) { @@ -684,7 +700,7 @@ class MinConstraint : public TreeArrayConstraint { PushDown(0, 0, target_var_->Min(), target_var_->Max()); } - void PushDown(int depth, int position, int64 new_min, int64 new_max) { + void PushDown(int depth, int position, int64_t new_min, int64_t new_max) { // Nothing to do? if (new_min <= Min(depth, position) && new_max >= Max(depth, position)) { return; @@ -696,8 +712,8 @@ class MinConstraint : public TreeArrayConstraint { return; } - const int64 node_min = Min(depth, position); - const int64 node_max = Max(depth, position); + const int64_t node_min = Min(depth, position); + const int64_t node_max = Max(depth, position); int candidate = -1; int active = 0; @@ -738,9 +754,9 @@ class MinConstraint : public TreeArrayConstraint { SetRange(MaxDepth(), term_index, var->Min(), var->Max()); const int parent_depth = MaxDepth() - 1; const int parent = Parent(term_index); - const int64 old_min = var->OldMin(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t old_min = var->OldMin(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); if ((old_min == Min(parent_depth, parent) && old_min != var_min) || var_max < Max(parent_depth, parent)) { // Can influence the parent bounds. @@ -753,8 +769,8 @@ class MinConstraint : public TreeArrayConstraint { while (depth > 0) { const int parent = Parent(position); const int parent_depth = depth - 1; - int64 min_min = kint64max; - int64 min_max = kint64max; + int64_t min_min = std::numeric_limits::max(); + int64_t min_max = std::numeric_limits::max(); const int block_start = ChildStart(parent); const int block_end = ChildEnd(parent_depth, parent); for (int k = block_start; k <= block_end; ++k) { @@ -815,8 +831,8 @@ class SmallMinConstraint : public Constraint { } void InitialPropagate() override { - int64 min_min = kint64max; - int64 min_max = kint64max; + int64_t min_min = std::numeric_limits::max(); + int64_t min_max = std::numeric_limits::max(); for (IntVar* const var : vars_) { min_min = std::min(min_min, var->Min()); min_max = std::min(min_max, var->Max()); @@ -847,14 +863,14 @@ class SmallMinConstraint : public Constraint { private: void VarChanged(IntVar* var) { - const int64 old_min = var->OldMin(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t old_min = var->OldMin(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); if ((old_min == computed_min_.Value() && old_min != var_min) || var_max < computed_max_.Value()) { // Can influence the min var bounds. - int64 min_min = kint64max; - int64 min_max = kint64max; + int64_t min_min = std::numeric_limits::max(); + int64_t min_max = std::numeric_limits::max(); for (IntVar* const var : vars_) { min_min = std::min(min_min, var->Min()); min_max = std::min(min_max, var->Max()); @@ -869,8 +885,8 @@ class SmallMinConstraint : public Constraint { } void MinVarChanged() { - const int64 new_min = target_var_->Min(); - const int64 new_max = target_var_->Max(); + const int64_t new_min = target_var_->Min(); + const int64_t new_max = target_var_->Max(); // Nothing to do? if (new_min <= computed_min_.Value() && new_max >= computed_max_.Value()) { return; @@ -908,8 +924,8 @@ class SmallMinConstraint : public Constraint { std::vector vars_; IntVar* const target_var_; - Rev computed_min_; - Rev computed_max_; + Rev computed_min_; + Rev computed_max_; }; // ---------- Max Array ---------- @@ -943,8 +959,8 @@ class MaxConstraint : public TreeArrayConstraint { // Compute up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 max_min = kint64min; - int64 max_max = kint64min; + int64_t max_min = std::numeric_limits::min(); + int64_t max_max = std::numeric_limits::min(); const int block_start = ChildStart(j); const int block_end = ChildEnd(i, j); for (int k = block_start; k <= block_end; ++k) { @@ -965,7 +981,7 @@ class MaxConstraint : public TreeArrayConstraint { PushDown(0, 0, target_var_->Min(), target_var_->Max()); } - void PushDown(int depth, int position, int64 new_min, int64 new_max) { + void PushDown(int depth, int position, int64_t new_min, int64_t new_max) { // Nothing to do? if (new_min <= Min(depth, position) && new_max >= Max(depth, position)) { return; @@ -977,8 +993,8 @@ class MaxConstraint : public TreeArrayConstraint { return; } - const int64 node_min = Min(depth, position); - const int64 node_max = Max(depth, position); + const int64_t node_min = Min(depth, position); + const int64_t node_max = Max(depth, position); int candidate = -1; int active = 0; @@ -1018,9 +1034,9 @@ class MaxConstraint : public TreeArrayConstraint { SetRange(MaxDepth(), term_index, var->Min(), var->Max()); const int parent_depth = MaxDepth() - 1; const int parent = Parent(term_index); - const int64 old_max = var->OldMax(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t old_max = var->OldMax(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); if ((old_max == Max(parent_depth, parent) && old_max != var_max) || var_min > Min(parent_depth, parent)) { // Can influence the parent bounds. @@ -1033,8 +1049,8 @@ class MaxConstraint : public TreeArrayConstraint { while (depth > 0) { const int parent = Parent(position); const int parent_depth = depth - 1; - int64 max_min = kint64min; - int64 max_max = kint64min; + int64_t max_min = std::numeric_limits::min(); + int64_t max_max = std::numeric_limits::min(); const int block_start = ChildStart(parent); const int block_end = ChildEnd(parent_depth, parent); for (int k = block_start; k <= block_end; ++k) { @@ -1095,8 +1111,8 @@ class SmallMaxConstraint : public Constraint { } void InitialPropagate() override { - int64 max_min = kint64min; - int64 max_max = kint64min; + int64_t max_min = std::numeric_limits::min(); + int64_t max_max = std::numeric_limits::min(); for (IntVar* const var : vars_) { max_min = std::max(max_min, var->Min()); max_max = std::max(max_max, var->Max()); @@ -1127,14 +1143,14 @@ class SmallMaxConstraint : public Constraint { private: void VarChanged(IntVar* var) { - const int64 old_max = var->OldMax(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t old_max = var->OldMax(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); if ((old_max == computed_max_.Value() && old_max != var_max) || var_min > computed_min_.Value()) { // REWRITE // Can influence the min var bounds. - int64 max_min = kint64min; - int64 max_max = kint64min; + int64_t max_min = std::numeric_limits::min(); + int64_t max_max = std::numeric_limits::min(); for (IntVar* const var : vars_) { max_min = std::max(max_min, var->Min()); max_max = std::max(max_max, var->Max()); @@ -1149,8 +1165,8 @@ class SmallMaxConstraint : public Constraint { } void MaxVarChanged() { - const int64 new_min = target_var_->Min(); - const int64 new_max = target_var_->Max(); + const int64_t new_min = target_var_->Min(); + const int64_t new_max = target_var_->Max(); // Nothing to do? if (new_min <= computed_min_.Value() && new_max >= computed_max_.Value()) { return; @@ -1188,8 +1204,8 @@ class SmallMaxConstraint : public Constraint { std::vector vars_; IntVar* const target_var_; - Rev computed_min_; - Rev computed_max_; + Rev computed_min_; + Rev computed_max_; }; // Boolean And and Ors @@ -1588,7 +1604,7 @@ void SumBooleanGreaterOrEqualToOne::InitialPropagate() { if (bits_.IsCardinalityZero()) { solver()->Fail(); } else if (bits_.IsCardinalityOne()) { - vars_[bits_.GetFirstBit(0)]->SetValue(int64{1}); + vars_[bits_.GetFirstBit(0)]->SetValue(int64_t{1}); inactive_.Switch(solver()); } } @@ -1602,7 +1618,7 @@ void SumBooleanGreaterOrEqualToOne::Update(int index) { if (bits_.IsCardinalityZero()) { solver()->Fail(); } else if (bits_.IsCardinalityOne()) { - vars_[bits_.GetFirstBit(0)]->SetValue(int64{1}); + vars_[bits_.GetFirstBit(0)]->SetValue(int64_t{1}); inactive_.Switch(solver()); } } @@ -1663,7 +1679,7 @@ class SumBooleanEqualToOne : public BaseSumBooleanConstraint { void Update(int index) { if (!inactive_.Switched()) { DCHECK(vars_[index]->Bound()); - const int64 value = vars_[index]->Min(); // Faster than Value(). + const int64_t value = vars_[index]->Min(); // Faster than Value(). if (value == 0) { active_vars_.Decr(solver()); DCHECK_GE(active_vars_.Value(), 0); @@ -1754,8 +1770,8 @@ class SumBooleanEqualToVar : public BaseSumBooleanConstraint { } } sum_var_->SetRange(num_always_true_vars, possible_true); - const int64 var_min = sum_var_->Min(); - const int64 var_max = sum_var_->Max(); + const int64_t var_min = sum_var_->Min(); + const int64_t var_max = sum_var_->Max(); if (num_always_true_vars == var_max && possible_true > var_max) { PushAllUnboundToZero(); } else if (possible_true == var_min && num_always_true_vars < var_min) { @@ -1781,7 +1797,7 @@ class SumBooleanEqualToVar : public BaseSumBooleanConstraint { void Update(int index) { if (!inactive_.Switched()) { DCHECK(vars_[index]->Bound()); - const int64 value = vars_[index]->Min(); // Faster than Value(). + const int64_t value = vars_[index]->Min(); // Faster than Value(). if (value == 0) { num_possible_true_vars_.Decr(solver()); sum_var_->SetRange(num_always_true_vars_.Value(), @@ -1802,7 +1818,7 @@ class SumBooleanEqualToVar : public BaseSumBooleanConstraint { } void PushAllUnboundToZero() { - int64 counter = 0; + int64_t counter = 0; inactive_.Switch(solver()); for (int i = 0; i < vars_.size(); ++i) { if (vars_[i]->Min() == 0) { @@ -1817,7 +1833,7 @@ class SumBooleanEqualToVar : public BaseSumBooleanConstraint { } void PushAllUnboundToOne() { - int64 counter = 0; + int64_t counter = 0; inactive_.Switch(solver()); for (int i = 0; i < vars_.size(); ++i) { if (vars_[i]->Max() == 1) { @@ -1856,8 +1872,8 @@ class SumBooleanEqualToVar : public BaseSumBooleanConstraint { struct Container { IntVar* var; - int64 coef; - Container(IntVar* v, int64 c) : var(v), coef(c) {} + int64_t coef; + Container(IntVar* v, int64_t c) : var(v), coef(c) {} bool operator<(const Container& c) const { return (coef < c.coef); } }; @@ -1868,15 +1884,15 @@ struct Container { // this method. // If keep_inside is true, the constant will be added back into the // scalprod as IntConst(1) * constant. -int64 SortBothChangeConstant(std::vector* const vars, - std::vector* const coefs, - bool keep_inside) { +int64_t SortBothChangeConstant(std::vector* const vars, + std::vector* const coefs, + bool keep_inside) { CHECK(vars != nullptr); CHECK(coefs != nullptr); if (vars->empty()) { return 0; } - int64 cst = 0; + int64_t cst = 0; std::vector to_sort; for (int index = 0; index < vars->size(); ++index) { if ((*vars)[index]->Bound()) { @@ -1906,8 +1922,8 @@ int64 SortBothChangeConstant(std::vector* const vars, class BooleanScalProdLessConstant : public Constraint { public: BooleanScalProdLessConstant(Solver* const s, const std::vector& vars, - const std::vector& coefs, - int64 upper_bound) + const std::vector& coefs, + int64_t upper_bound) : Constraint(s), vars_(vars), coefs_(coefs), @@ -1939,12 +1955,12 @@ class BooleanScalProdLessConstant : public Constraint { } void PushFromTop() { - const int64 slack = CapSub(upper_bound_, sum_of_bound_variables_.Value()); + const int64_t slack = CapSub(upper_bound_, sum_of_bound_variables_.Value()); if (slack < 0) { solver()->Fail(); } if (slack < max_coefficient_.Value()) { - int64 last_unbound = first_unbound_backward_.Value(); + int64_t last_unbound = first_unbound_backward_.Value(); for (; last_unbound >= 0; --last_unbound) { if (!vars_[last_unbound]->Bound()) { if (coefs_[last_unbound] <= slack) { @@ -1962,10 +1978,10 @@ class BooleanScalProdLessConstant : public Constraint { void InitialPropagate() override { Solver* const s = solver(); int last_unbound = -1; - int64 sum = 0LL; + int64_t sum = 0LL; for (int index = 0; index < vars_.size(); ++index) { if (vars_[index]->Bound()) { - const int64 value = vars_[index]->Min(); + const int64_t value = vars_[index]->Min(); sum = CapAdd(sum, CapProd(value, coefs_[index])); } else { last_unbound = index; @@ -2002,11 +2018,11 @@ class BooleanScalProdLessConstant : public Constraint { private: std::vector vars_; - std::vector coefs_; - int64 upper_bound_; + std::vector coefs_; + int64_t upper_bound_; Rev first_unbound_backward_; - Rev sum_of_bound_variables_; - Rev max_coefficient_; + Rev sum_of_bound_variables_; + Rev max_coefficient_; }; // ----- PositiveBooleanScalProdEqVar ----- @@ -2015,7 +2031,7 @@ class PositiveBooleanScalProdEqVar : public CastConstraint { public: PositiveBooleanScalProdEqVar(Solver* const s, const std::vector& vars, - const std::vector& coefs, + const std::vector& coefs, IntVar* const var) : CastConstraint(s, var), vars_(vars), @@ -2051,13 +2067,13 @@ class PositiveBooleanScalProdEqVar : public CastConstraint { void Propagate() { target_var_->SetRange(sum_of_bound_variables_.Value(), sum_of_all_variables_.Value()); - const int64 slack_up = + const int64_t slack_up = CapSub(target_var_->Max(), sum_of_bound_variables_.Value()); - const int64 slack_down = + const int64_t slack_down = CapSub(sum_of_all_variables_.Value(), target_var_->Min()); - const int64 max_coeff = max_coefficient_.Value(); + const int64_t max_coeff = max_coefficient_.Value(); if (slack_down < max_coeff || slack_up < max_coeff) { - int64 last_unbound = first_unbound_backward_.Value(); + int64_t last_unbound = first_unbound_backward_.Value(); for (; last_unbound >= 0; --last_unbound) { if (!vars_[last_unbound]->Bound()) { if (coefs_[last_unbound] > slack_up) { @@ -2077,10 +2093,10 @@ class PositiveBooleanScalProdEqVar : public CastConstraint { void InitialPropagate() override { Solver* const s = solver(); int last_unbound = -1; - int64 sum_bound = 0; - int64 sum_all = 0; + int64_t sum_bound = 0; + int64_t sum_all = 0; for (int index = 0; index < vars_.size(); ++index) { - const int64 value = CapProd(vars_[index]->Max(), coefs_[index]); + const int64_t value = CapProd(vars_[index]->Max(), coefs_[index]); sum_all = CapAdd(sum_all, value); if (vars_[index]->Bound()) { sum_bound = CapAdd(sum_bound, value); @@ -2125,11 +2141,11 @@ class PositiveBooleanScalProdEqVar : public CastConstraint { private: std::vector vars_; - std::vector coefs_; + std::vector coefs_; Rev first_unbound_backward_; - Rev sum_of_bound_variables_; - Rev sum_of_all_variables_; - Rev max_coefficient_; + Rev sum_of_bound_variables_; + Rev sum_of_all_variables_; + Rev max_coefficient_; }; // ----- PositiveBooleanScalProd ----- @@ -2139,7 +2155,7 @@ class PositiveBooleanScalProd : public BaseIntExpr { // this constructor will copy the array. The caller can safely delete the // exprs array himself PositiveBooleanScalProd(Solver* const s, const std::vector& vars, - const std::vector& coefs) + const std::vector& coefs) : BaseIntExpr(s), vars_(vars), coefs_(coefs) { CHECK(!vars.empty()); SortBothChangeConstant(&vars_, &coefs_, true); @@ -2150,8 +2166,8 @@ class PositiveBooleanScalProd : public BaseIntExpr { ~PositiveBooleanScalProd() override {} - int64 Min() const override { - int64 min = 0; + int64_t Min() const override { + int64_t min = 0; for (int i = 0; i < vars_.size(); ++i) { if (vars_[i]->Min()) { min = CapAdd(min, coefs_[i]); @@ -2160,10 +2176,12 @@ class PositiveBooleanScalProd : public BaseIntExpr { return min; } - void SetMin(int64 m) override { SetRange(m, kint64max); } + void SetMin(int64_t m) override { + SetRange(m, std::numeric_limits::max()); + } - int64 Max() const override { - int64 max = 0; + int64_t Max() const override { + int64_t max = 0; for (int i = 0; i < vars_.size(); ++i) { if (vars_[i]->Max()) { max = CapAdd(max, coefs_[i]); @@ -2172,16 +2190,18 @@ class PositiveBooleanScalProd : public BaseIntExpr { return max; } - void SetMax(int64 m) override { SetRange(kint64min, m); } + void SetMax(int64_t m) override { + SetRange(std::numeric_limits::min(), m); + } - void SetRange(int64 l, int64 u) override { - int64 current_min = 0; - int64 current_max = 0; - int64 diameter = -1; + void SetRange(int64_t l, int64_t u) override { + int64_t current_min = 0; + int64_t current_max = 0; + int64_t diameter = -1; for (int i = 0; i < vars_.size(); ++i) { - const int64 coefficient = coefs_[i]; - const int64 var_min = CapProd(vars_[i]->Min(), coefficient); - const int64 var_max = CapProd(vars_[i]->Max(), coefficient); + const int64_t coefficient = coefs_[i]; + const int64_t var_min = CapProd(vars_[i]->Min(), coefficient); + const int64_t var_max = CapProd(vars_[i]->Max(), coefficient); current_min = CapAdd(current_min, var_min); current_max = CapAdd(current_max, var_max); if (var_min != var_max) { // Coefficients are increasing. @@ -2203,19 +2223,19 @@ class PositiveBooleanScalProd : public BaseIntExpr { } for (int i = 0; i < vars_.size(); ++i) { - const int64 coefficient = coefs_[i]; + const int64_t coefficient = coefs_[i]; IntVar* const var = vars_[i]; - const int64 new_min = + const int64_t new_min = CapAdd(CapSub(l, current_max), CapProd(var->Max(), coefficient)); - const int64 new_max = + const int64_t new_max = CapAdd(CapSub(u, current_min), CapProd(var->Min(), coefficient)); if (new_max < 0 || new_min > coefficient || new_min > new_max) { solver()->Fail(); } if (new_min > 0LL) { - var->SetMin(int64{1}); + var->SetMin(int64_t{1}); } else if (new_max < coefficient) { - var->SetMax(int64{0}); + var->SetMax(int64_t{0}); } } } @@ -2233,8 +2253,8 @@ class PositiveBooleanScalProd : public BaseIntExpr { } IntVar* CastToVar() override { Solver* const s = solver(); - int64 vmin = 0LL; - int64 vmax = 0LL; + int64_t vmin = 0LL; + int64_t vmax = 0LL; Range(&vmin, &vmax); IntVar* const var = solver()->MakeIntVar(vmin, vmax); if (!vars_.empty()) { @@ -2256,7 +2276,7 @@ class PositiveBooleanScalProd : public BaseIntExpr { private: std::vector vars_; - std::vector coefs_; + std::vector coefs_; }; // ----- PositiveBooleanScalProdEqCst ----- (all constants >= 0) @@ -2265,7 +2285,8 @@ class PositiveBooleanScalProdEqCst : public Constraint { public: PositiveBooleanScalProdEqCst(Solver* const s, const std::vector& vars, - const std::vector& coefs, int64 constant) + const std::vector& coefs, + int64_t constant) : Constraint(s), vars_(vars), coefs_(coefs), @@ -2298,11 +2319,11 @@ class PositiveBooleanScalProdEqCst : public Constraint { sum_of_all_variables_.Value() < constant_) { solver()->Fail(); } - const int64 slack_up = CapSub(constant_, sum_of_bound_variables_.Value()); - const int64 slack_down = CapSub(sum_of_all_variables_.Value(), constant_); - const int64 max_coeff = max_coefficient_.Value(); + const int64_t slack_up = CapSub(constant_, sum_of_bound_variables_.Value()); + const int64_t slack_down = CapSub(sum_of_all_variables_.Value(), constant_); + const int64_t max_coeff = max_coefficient_.Value(); if (slack_down < max_coeff || slack_up < max_coeff) { - int64 last_unbound = first_unbound_backward_.Value(); + int64_t last_unbound = first_unbound_backward_.Value(); for (; last_unbound >= 0; --last_unbound) { if (!vars_[last_unbound]->Bound()) { if (coefs_[last_unbound] > slack_up) { @@ -2322,10 +2343,10 @@ class PositiveBooleanScalProdEqCst : public Constraint { void InitialPropagate() override { Solver* const s = solver(); int last_unbound = -1; - int64 sum_bound = 0LL; - int64 sum_all = 0LL; + int64_t sum_bound = 0LL; + int64_t sum_all = 0LL; for (int index = 0; index < vars_.size(); ++index) { - const int64 value = CapProd(vars_[index]->Max(), coefs_[index]); + const int64_t value = CapProd(vars_[index]->Max(), coefs_[index]); sum_all = CapAdd(sum_all, value); if (vars_[index]->Bound()) { sum_bound = CapAdd(sum_bound, value); @@ -2368,12 +2389,12 @@ class PositiveBooleanScalProdEqCst : public Constraint { private: std::vector vars_; - std::vector coefs_; + std::vector coefs_; Rev first_unbound_backward_; - Rev sum_of_bound_variables_; - Rev sum_of_all_variables_; - int64 constant_; - Rev max_coefficient_; + Rev sum_of_bound_variables_; + Rev sum_of_all_variables_; + int64_t constant_; + Rev max_coefficient_; }; // ----- Linearizer ----- @@ -2383,7 +2404,7 @@ class PositiveBooleanScalProdEqCst : public Constraint { class ExprLinearizer : public ModelParser { public: explicit ExprLinearizer( - absl::flat_hash_map* const variables_to_coefficients) + absl::flat_hash_map* const variables_to_coefficients) : variables_to_coefficients_(variables_to_coefficients), constant_(0) {} ~ExprLinearizer() override {} @@ -2436,7 +2457,7 @@ class ExprLinearizer : public ModelParser { } void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override { if (operation == ModelVisitor::kSumOperation) { AddConstant(value); @@ -2469,12 +2490,13 @@ class ExprLinearizer : public ModelParser { } // Visit integer arguments. - void VisitIntegerArgument(const std::string& arg_name, int64 value) override { + void VisitIntegerArgument(const std::string& arg_name, + int64_t value) override { Top()->SetIntegerArgument(arg_name, value); } void VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) override { + const std::vector& values) override { Top()->SetIntegerArrayArgument(arg_name, values); } @@ -2503,7 +2525,7 @@ class ExprLinearizer : public ModelParser { const std::string& arg_name, const std::vector& argument) override {} - void Visit(const IntExpr* const expr, int64 multiplier) { + void Visit(const IntExpr* const expr, int64_t multiplier) { if (expr->Min() == expr->Max()) { constant_ = CapAdd(constant_, CapProd(expr->Min(), multiplier)); } else { @@ -2513,7 +2535,7 @@ class ExprLinearizer : public ModelParser { } } - int64 Constant() const { return constant_; } + int64_t Constant() const { return constant_; } std::string DebugString() const override { return "ExprLinearizer"; } @@ -2545,7 +2567,7 @@ class ExprLinearizer : public ModelParser { } else { const IntExpr* const expr = Top()->FindIntegerExpressionArgumentOrDie( ModelVisitor::kExpressionArgument); - const int64 value = + const int64_t value = Top()->FindIntegerArgumentOrDie(ModelVisitor::kValueArgument); VisitSubExpression(expr); AddConstant(value); @@ -2556,12 +2578,12 @@ class ExprLinearizer : public ModelParser { const std::vector& cp_vars = Top()->FindIntegerVariableArrayArgumentOrDie( ModelVisitor::kVarsArgument); - const std::vector& cp_coefficients = + const std::vector& cp_coefficients = Top()->FindIntegerArrayArgumentOrDie( ModelVisitor::kCoefficientsArgument); CHECK_EQ(cp_vars.size(), cp_coefficients.size()); for (int i = 0; i < cp_vars.size(); ++i) { - const int64 coefficient = cp_coefficients[i]; + const int64_t coefficient = cp_coefficients[i]; PushMultiplier(coefficient); VisitSubExpression(cp_vars[i]); PopMultiplier(); @@ -2581,7 +2603,7 @@ class ExprLinearizer : public ModelParser { } else { const IntExpr* const expr = Top()->FindIntegerExpressionArgumentOrDie( ModelVisitor::kExpressionArgument); - const int64 value = + const int64_t value = Top()->FindIntegerArgumentOrDie(ModelVisitor::kValueArgument); AddConstant(value); PushMultiplier(-1); @@ -2603,7 +2625,7 @@ class ExprLinearizer : public ModelParser { ModelVisitor::kExpressionArgument)) { const IntExpr* const expr = Top()->FindIntegerExpressionArgumentOrDie( ModelVisitor::kExpressionArgument); - const int64 value = + const int64_t value = Top()->FindIntegerArgumentOrDie(ModelVisitor::kValueArgument); PushMultiplier(value); VisitSubExpression(expr); @@ -2623,17 +2645,17 @@ class ExprLinearizer : public ModelParser { RegisterExpression(cp_expr, 1); } - void RegisterExpression(const IntExpr* const expr, int64 coef) { - int64& value = + void RegisterExpression(const IntExpr* const expr, int64_t coef) { + int64_t& value = (*variables_to_coefficients_)[const_cast(expr)->Var()]; value = CapAdd(value, CapProd(coef, multipliers_.back())); } - void AddConstant(int64 constant) { + void AddConstant(int64_t constant) { constant_ = CapAdd(constant_, CapProd(constant, multipliers_.back())); } - void PushMultiplier(int64 multiplier) { + void PushMultiplier(int64_t multiplier) { if (multipliers_.empty()) { multipliers_.push_back(multiplier); } else { @@ -2645,18 +2667,18 @@ class ExprLinearizer : public ModelParser { // We do need a IntVar* as key, and not const IntVar*, because clients of this // class typically iterate over the map keys and use them as mutable IntVar*. - absl::flat_hash_map* const variables_to_coefficients_; - std::vector multipliers_; - int64 constant_; + absl::flat_hash_map* const variables_to_coefficients_; + std::vector multipliers_; + int64_t constant_; }; #undef IS_TYPE // ----- Factory functions ----- void DeepLinearize(Solver* const solver, const std::vector& pre_vars, - const std::vector& pre_coefs, - std::vector* vars, std::vector* coefs, - int64* constant) { + const std::vector& pre_coefs, + std::vector* vars, std::vector* coefs, + int64_t* constant) { CHECK(solver != nullptr); CHECK(vars != nullptr); CHECK(coefs != nullptr); @@ -2668,7 +2690,7 @@ void DeepLinearize(Solver* const solver, const std::vector& pre_vars, bool need_linearization = false; for (int i = 0; i < pre_vars.size(); ++i) { IntVar* const variable = pre_vars[i]; - const int64 coefficient = pre_coefs[i]; + const int64_t coefficient = pre_coefs[i]; if (variable->Bound()) { *constant = CapAdd(*constant, CapProd(coefficient, variable->Min())); } else if (solver->CastExpression(variable) == nullptr) { @@ -2683,7 +2705,7 @@ void DeepLinearize(Solver* const solver, const std::vector& pre_vars, } if (need_linearization) { // Instrospect the variables to simplify the sum. - absl::flat_hash_map variables_to_coefficients; + absl::flat_hash_map variables_to_coefficients; ExprLinearizer linearizer(&variables_to_coefficients); for (int i = 0; i < pre_vars.size(); ++i) { linearizer.Visit(pre_vars[i], pre_coefs[i]); @@ -2700,11 +2722,11 @@ void DeepLinearize(Solver* const solver, const std::vector& pre_vars, Constraint* MakeScalProdEqualityFct(Solver* const solver, const std::vector& pre_vars, - const std::vector& pre_coefs, - int64 cst) { - int64 constant = 0; + const std::vector& pre_coefs, + int64_t cst) { + int64_t constant = 0; std::vector vars; - std::vector coefs; + std::vector coefs; DeepLinearize(solver, pre_vars, pre_coefs, &vars, &coefs, &constant); cst = CapSub(cst, constant); @@ -2714,7 +2736,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, : solver->MakeFalseConstraint(); } if (AreAllBoundOrNull(vars, coefs)) { - int64 sum = 0; + int64_t sum = 0; for (int i = 0; i < size; ++i) { sum = CapAdd(sum, CapProd(coefs[i], vars[i]->Min())); } @@ -2730,7 +2752,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, new PositiveBooleanScalProdEqCst(solver, vars, coefs, cst)); } if (AreAllNegative(coefs)) { - std::vector opp_coefs(coefs.size()); + std::vector opp_coefs(coefs.size()); for (int i = 0; i < coefs.size(); ++i) { opp_coefs[i] = -coefs[i]; } @@ -2755,7 +2777,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, if (positives > 0 && negatives > 0) { std::vector pos_terms; std::vector neg_terms; - int64 rhs = cst; + int64_t rhs = cst; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2784,7 +2806,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, } } else if (positives == 1) { IntExpr* pos_term = nullptr; - int64 rhs = cst; + int64_t rhs = cst; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2797,7 +2819,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, return solver->MakeEquality(pos_term, rhs); } else if (negatives == 1) { IntExpr* neg_term = nullptr; - int64 rhs = cst; + int64_t rhs = cst; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2810,7 +2832,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, return solver->MakeEquality(neg_term, -rhs); } else if (positives > 1) { std::vector pos_terms; - int64 rhs = cst; + int64_t rhs = cst; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2823,7 +2845,7 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, return solver->MakeSumEquality(pos_terms, rhs); } else if (negatives > 1) { std::vector neg_terms; - int64 rhs = cst; + int64_t rhs = cst; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2844,22 +2866,22 @@ Constraint* MakeScalProdEqualityFct(Solver* const solver, Constraint* MakeScalProdEqualityVarFct(Solver* const solver, const std::vector& pre_vars, - const std::vector& pre_coefs, + const std::vector& pre_coefs, IntVar* const target) { - int64 constant = 0; + int64_t constant = 0; std::vector vars; - std::vector coefs; + std::vector coefs; DeepLinearize(solver, pre_vars, pre_coefs, &vars, &coefs, &constant); const int size = vars.size(); - if (size == 0 || AreAllNull(coefs)) { + if (size == 0 || AreAllNull(coefs)) { return solver->MakeEquality(target, constant); } if (AreAllOnes(coefs)) { return solver->MakeSumEquality(vars, solver->MakeSum(target, -constant)->Var()); } - if (AreAllBooleans(vars) && AreAllPositive(coefs)) { + if (AreAllBooleans(vars) && AreAllPositive(coefs)) { // TODO(user) : bench BooleanScalProdEqVar with IntConst. return solver->RevAlloc(new PositiveBooleanScalProdEqVar( solver, vars, coefs, solver->MakeSum(target, -constant)->Var())); @@ -2874,16 +2896,16 @@ Constraint* MakeScalProdEqualityVarFct(Solver* const solver, Constraint* MakeScalProdGreaterOrEqualFct(Solver* solver, const std::vector& pre_vars, - const std::vector& pre_coefs, - int64 cst) { - int64 constant = 0; + const std::vector& pre_coefs, + int64_t cst) { + int64_t constant = 0; std::vector vars; - std::vector coefs; + std::vector coefs; DeepLinearize(solver, pre_vars, pre_coefs, &vars, &coefs, &constant); cst = CapSub(cst, constant); const int size = vars.size(); - if (size == 0 || AreAllNull(coefs)) { + if (size == 0 || AreAllNull(coefs)) { return cst <= 0 ? solver->MakeTrueConstraint() : solver->MakeFalseConstraint(); } @@ -2909,22 +2931,22 @@ Constraint* MakeScalProdGreaterOrEqualFct(Solver* solver, Constraint* MakeScalProdLessOrEqualFct(Solver* solver, const std::vector& pre_vars, - const std::vector& pre_coefs, - int64 upper_bound) { - int64 constant = 0; + const std::vector& pre_coefs, + int64_t upper_bound) { + int64_t constant = 0; std::vector vars; - std::vector coefs; + std::vector coefs; DeepLinearize(solver, pre_vars, pre_coefs, &vars, &coefs, &constant); upper_bound = CapSub(upper_bound, constant); const int size = vars.size(); - if (size == 0 || AreAllNull(coefs)) { + if (size == 0 || AreAllNull(coefs)) { return upper_bound >= 0 ? solver->MakeTrueConstraint() : solver->MakeFalseConstraint(); } // TODO(user) : compute constant on the fly. if (AreAllBoundOrNull(vars, coefs)) { - int64 cst = 0; + int64_t cst = 0; for (int i = 0; i < size; ++i) { cst = CapAdd(cst, CapProd(vars[i]->Min(), coefs[i])); } @@ -2934,7 +2956,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, if (AreAllOnes(coefs)) { return solver->MakeSumLessOrEqual(vars, upper_bound); } - if (AreAllBooleans(vars) && AreAllPositive(coefs)) { + if (AreAllBooleans(vars) && AreAllPositive(coefs)) { return solver->RevAlloc( new BooleanScalProdLessConstant(solver, vars, coefs, upper_bound)); } @@ -2954,7 +2976,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, if (positives > 0 && negatives > 0) { std::vector pos_terms; std::vector neg_terms; - int64 rhs = upper_bound; + int64_t rhs = upper_bound; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2979,7 +3001,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, } } else if (positives == 1) { IntExpr* pos_term = nullptr; - int64 rhs = upper_bound; + int64_t rhs = upper_bound; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -2992,7 +3014,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, return solver->MakeLessOrEqual(pos_term, rhs); } else if (negatives == 1) { IntExpr* neg_term = nullptr; - int64 rhs = upper_bound; + int64_t rhs = upper_bound; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -3005,7 +3027,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, return solver->MakeGreaterOrEqual(neg_term, -rhs); } else if (positives > 1) { std::vector pos_terms; - int64 rhs = upper_bound; + int64_t rhs = upper_bound; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -3018,7 +3040,7 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, return solver->MakeSumLessOrEqual(pos_terms, rhs); } else if (negatives > 1) { std::vector neg_terms; - int64 rhs = upper_bound; + int64_t rhs = upper_bound; for (int i = 0; i < size; ++i) { if (coefs[i] == 0 || vars[i]->Bound()) { rhs = CapSub(rhs, CapProd(coefs[i], vars[i]->Min())); @@ -3038,16 +3060,16 @@ Constraint* MakeScalProdLessOrEqualFct(Solver* solver, } IntExpr* MakeSumArrayAux(Solver* const solver, const std::vector& vars, - int64 constant) { + int64_t constant) { const int size = vars.size(); DCHECK_GT(size, 2); - int64 new_min = 0; - int64 new_max = 0; + int64_t new_min = 0; + int64_t new_max = 0; for (int i = 0; i < size; ++i) { - if (new_min != kint64min) { + if (new_min != std::numeric_limits::min()) { new_min = CapAdd(vars[i]->Min(), new_min); } - if (new_max != kint64max) { + if (new_max != std::numeric_limits::max()) { new_max = CapAdd(vars[i]->Max(), new_max); } } @@ -3076,7 +3098,7 @@ IntExpr* MakeSumArrayAux(Solver* const solver, const std::vector& vars, } IntExpr* MakeSumAux(Solver* const solver, const std::vector& vars, - int64 constant) { + int64_t constant) { const int size = vars.size(); if (size == 0) { return solver->MakeIntConst(constant); @@ -3090,7 +3112,7 @@ IntExpr* MakeSumAux(Solver* const solver, const std::vector& vars, } IntExpr* MakeScalProdAux(Solver* solver, const std::vector& vars, - const std::vector& coefs, int64 constant) { + const std::vector& coefs, int64_t constant) { if (AreAllOnes(coefs)) { return MakeSumAux(solver, vars, constant); } @@ -3141,8 +3163,8 @@ IntExpr* MakeScalProdAux(Solver* solver, const std::vector& vars, // other on Opposite(N) (s2). // The final expression is then s1 - s2. // If P is empty, the expression is Opposite(s2). - std::vector positive_coefs; - std::vector negative_coefs; + std::vector positive_coefs; + std::vector negative_coefs; std::vector positive_coef_vars; std::vector negative_coef_vars; for (int i = 0; i < size; ++i) { @@ -3176,17 +3198,17 @@ IntExpr* MakeScalProdAux(Solver* solver, const std::vector& vars, } IntExpr* MakeScalProdFct(Solver* solver, const std::vector& pre_vars, - const std::vector& pre_coefs) { - int64 constant = 0; + const std::vector& pre_coefs) { + int64_t constant = 0; std::vector vars; - std::vector coefs; + std::vector coefs; DeepLinearize(solver, pre_vars, pre_coefs, &vars, &coefs, &constant); if (vars.empty()) { return solver->MakeIntConst(constant); } // Can we simplify using some gcd computation. - int64 gcd = std::abs(coefs[0]); + int64_t gcd = std::abs(coefs[0]); for (int i = 1; i < coefs.size(); ++i) { gcd = MathUtil::GCD64(gcd, std::abs(coefs[i])); if (gcd == 1) { @@ -3207,14 +3229,14 @@ IntExpr* MakeScalProdFct(Solver* solver, const std::vector& pre_vars, } IntExpr* MakeSumFct(Solver* solver, const std::vector& pre_vars) { - absl::flat_hash_map variables_to_coefficients; + absl::flat_hash_map variables_to_coefficients; ExprLinearizer linearizer(&variables_to_coefficients); for (int i = 0; i < pre_vars.size(); ++i) { linearizer.Visit(pre_vars[i], 1); } - const int64 constant = linearizer.Constant(); + const int64_t constant = linearizer.Constant(); std::vector vars; - std::vector coefs; + std::vector coefs; for (const auto& variable_to_coefficient : variables_to_coefficients) { if (variable_to_coefficient.second != 0) { vars.push_back(variable_to_coefficient.first); @@ -3230,7 +3252,7 @@ IntExpr* MakeSumFct(Solver* solver, const std::vector& pre_vars) { IntExpr* Solver::MakeSum(const std::vector& vars) { const int size = vars.size(); if (size == 0) { - return MakeIntConst(int64{0}); + return MakeIntConst(int64_t{0}); } else if (size == 1) { return vars[0]; } else if (size == 2) { @@ -3241,13 +3263,13 @@ IntExpr* Solver::MakeSum(const std::vector& vars) { if (cache != nullptr) { return cache; } else { - int64 new_min = 0; - int64 new_max = 0; + int64_t new_min = 0; + int64_t new_max = 0; for (int i = 0; i < size; ++i) { - if (new_min != kint64min) { + if (new_min != std::numeric_limits::min()) { new_min = CapAdd(vars[i]->Min(), new_min); } - if (new_max != kint64max) { + if (new_max != std::numeric_limits::max()) { new_max = CapAdd(vars[i]->Max(), new_max); } } @@ -3259,7 +3281,8 @@ IntExpr* Solver::MakeSum(const std::vector& vars) { sum_expr = MakeIntVar(new_min, new_max, name); AddConstraint( RevAlloc(new SumBooleanEqualToVar(this, vars, sum_expr->Var()))); - } else if (new_min != kint64min && new_max != kint64max) { + } else if (new_min != std::numeric_limits::min() && + new_max != std::numeric_limits::max()) { sum_expr = MakeSumFct(this, vars); } else { const std::string name = @@ -3280,7 +3303,7 @@ IntExpr* Solver::MakeMin(const std::vector& vars) { if (size == 0) { LOG(WARNING) << "operations_research::Solver::MakeMin() was called with an " "empty list of variables. Was this intentional?"; - return MakeIntConst(kint64max); + return MakeIntConst(std::numeric_limits::max()); } else if (size == 1) { return vars[0]; } else if (size == 2) { @@ -3298,8 +3321,8 @@ IntExpr* Solver::MakeMin(const std::vector& vars) { ModelCache::VAR_ARRAY_MIN); return new_var; } else { - int64 new_min = kint64max; - int64 new_max = kint64max; + int64_t new_min = std::numeric_limits::max(); + int64_t new_max = std::numeric_limits::max(); for (int i = 0; i < size; ++i) { new_min = std::min(new_min, vars[i]->Min()); new_max = std::min(new_max, vars[i]->Max()); @@ -3323,7 +3346,7 @@ IntExpr* Solver::MakeMax(const std::vector& vars) { if (size == 0) { LOG(WARNING) << "operations_research::Solver::MakeMax() was called with an " "empty list of variables. Was this intentional?"; - return MakeIntConst(kint64min); + return MakeIntConst(std::numeric_limits::min()); } else if (size == 1) { return vars[0]; } else if (size == 2) { @@ -3341,8 +3364,8 @@ IntExpr* Solver::MakeMax(const std::vector& vars) { ModelCache::VAR_ARRAY_MIN); return new_var; } else { - int64 new_min = kint64min; - int64 new_max = kint64min; + int64_t new_min = std::numeric_limits::min(); + int64_t new_max = std::numeric_limits::min(); for (int i = 0; i < size; ++i) { new_min = std::max(new_min, vars[i]->Min()); new_max = std::max(new_max, vars[i]->Max()); @@ -3379,7 +3402,7 @@ Constraint* Solver::MakeMinEquality(const std::vector& vars, } else { LOG(WARNING) << "operations_research::Solver::MakeMinEquality() was called " "with an empty list of variables. Was this intentional?"; - return MakeEquality(min_var, kint64max); + return MakeEquality(min_var, std::numeric_limits::max()); } } @@ -3401,12 +3424,12 @@ Constraint* Solver::MakeMaxEquality(const std::vector& vars, } else { LOG(WARNING) << "operations_research::Solver::MakeMaxEquality() was called " "with an empty list of variables. Was this intentional?"; - return MakeEquality(max_var, kint64min); + return MakeEquality(max_var, std::numeric_limits::min()); } } Constraint* Solver::MakeSumLessOrEqual(const std::vector& vars, - int64 cst) { + int64_t cst) { const int size = vars.size(); if (cst == 1LL && AreAllBooleans(vars) && size > 2) { return RevAlloc(new SumBooleanLessOrEqualToOne(this, vars)); @@ -3416,7 +3439,7 @@ Constraint* Solver::MakeSumLessOrEqual(const std::vector& vars, } Constraint* Solver::MakeSumGreaterOrEqual(const std::vector& vars, - int64 cst) { + int64_t cst) { const int size = vars.size(); if (cst == 1LL && AreAllBooleans(vars) && size > 2) { return RevAlloc(new SumBooleanGreaterOrEqualToOne(this, vars)); @@ -3426,7 +3449,7 @@ Constraint* Solver::MakeSumGreaterOrEqual(const std::vector& vars, } Constraint* Solver::MakeSumEquality(const std::vector& vars, - int64 cst) { + int64_t cst) { const int size = vars.size(); if (size == 0) { return cst == 0 ? MakeTrueConstraint() : MakeFalseConstraint(); @@ -3480,23 +3503,23 @@ Constraint* Solver::MakeSumEquality(const std::vector& vars, } } -Constraint* Solver::MakeScalProdEquality(const std::vector& vars, - const std::vector& coefficients, - int64 cst) { +Constraint* Solver::MakeScalProdEquality( + const std::vector& vars, const std::vector& coefficients, + int64_t cst) { DCHECK_EQ(vars.size(), coefficients.size()); return MakeScalProdEqualityFct(this, vars, coefficients, cst); } Constraint* Solver::MakeScalProdEquality(const std::vector& vars, const std::vector& coefficients, - int64 cst) { + int64_t cst) { DCHECK_EQ(vars.size(), coefficients.size()); return MakeScalProdEqualityFct(this, vars, ToInt64Vector(coefficients), cst); } -Constraint* Solver::MakeScalProdEquality(const std::vector& vars, - const std::vector& coefficients, - IntVar* const target) { +Constraint* Solver::MakeScalProdEquality( + const std::vector& vars, const std::vector& coefficients, + IntVar* const target) { DCHECK_EQ(vars.size(), coefficients.size()); return MakeScalProdEqualityVarFct(this, vars, coefficients, target); } @@ -3509,37 +3532,37 @@ Constraint* Solver::MakeScalProdEquality(const std::vector& vars, target); } -Constraint* Solver::MakeScalProdGreaterOrEqual(const std::vector& vars, - const std::vector& coeffs, - int64 cst) { +Constraint* Solver::MakeScalProdGreaterOrEqual( + const std::vector& vars, const std::vector& coeffs, + int64_t cst) { DCHECK_EQ(vars.size(), coeffs.size()); return MakeScalProdGreaterOrEqualFct(this, vars, coeffs, cst); } Constraint* Solver::MakeScalProdGreaterOrEqual(const std::vector& vars, const std::vector& coeffs, - int64 cst) { + int64_t cst) { DCHECK_EQ(vars.size(), coeffs.size()); return MakeScalProdGreaterOrEqualFct(this, vars, ToInt64Vector(coeffs), cst); } Constraint* Solver::MakeScalProdLessOrEqual( - const std::vector& vars, const std::vector& coefficients, - int64 cst) { + const std::vector& vars, const std::vector& coefficients, + int64_t cst) { DCHECK_EQ(vars.size(), coefficients.size()); return MakeScalProdLessOrEqualFct(this, vars, coefficients, cst); } Constraint* Solver::MakeScalProdLessOrEqual( const std::vector& vars, const std::vector& coefficients, - int64 cst) { + int64_t cst) { DCHECK_EQ(vars.size(), coefficients.size()); return MakeScalProdLessOrEqualFct(this, vars, ToInt64Vector(coefficients), cst); } IntExpr* Solver::MakeScalProd(const std::vector& vars, - const std::vector& coefs) { + const std::vector& coefs) { DCHECK_EQ(vars.size(), coefs.size()); return MakeScalProdFct(this, vars, coefs); } diff --git a/ortools/constraint_solver/expr_cst.cc b/ortools/constraint_solver/expr_cst.cc index 590c93de44..a945868726 100644 --- a/ortools/constraint_solver/expr_cst.cc +++ b/ortools/constraint_solver/expr_cst.cc @@ -15,6 +15,8 @@ // Expression constraints #include +#include +#include #include #include #include @@ -42,7 +44,7 @@ namespace operations_research { namespace { class EqualityExprCst : public Constraint { public: - EqualityExprCst(Solver* const s, IntExpr* const e, int64 v); + EqualityExprCst(Solver* const s, IntExpr* const e, int64_t v); ~EqualityExprCst() override {} void Post() override; void InitialPropagate() override; @@ -61,10 +63,10 @@ class EqualityExprCst : public Constraint { private: IntExpr* const expr_; - int64 value_; + int64_t value_; }; -EqualityExprCst::EqualityExprCst(Solver* const s, IntExpr* const e, int64 v) +EqualityExprCst::EqualityExprCst(Solver* const s, IntExpr* const e, int64_t v) : Constraint(s), expr_(e), value_(v) {} void EqualityExprCst::Post() { @@ -81,7 +83,7 @@ std::string EqualityExprCst::DebugString() const { } } // namespace -Constraint* Solver::MakeEquality(IntExpr* const e, int64 v) { +Constraint* Solver::MakeEquality(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); IntExpr* left = nullptr; IntExpr* right = nullptr; @@ -117,7 +119,7 @@ Constraint* Solver::MakeEquality(IntExpr* const e, int v) { namespace { class GreaterEqExprCst : public Constraint { public: - GreaterEqExprCst(Solver* const s, IntExpr* const e, int64 v); + GreaterEqExprCst(Solver* const s, IntExpr* const e, int64_t v); ~GreaterEqExprCst() override {} void Post() override; void InitialPropagate() override; @@ -136,11 +138,11 @@ class GreaterEqExprCst : public Constraint { private: IntExpr* const expr_; - int64 value_; + int64_t value_; Demon* demon_; }; -GreaterEqExprCst::GreaterEqExprCst(Solver* const s, IntExpr* const e, int64 v) +GreaterEqExprCst::GreaterEqExprCst(Solver* const s, IntExpr* const e, int64_t v) : Constraint(s), expr_(e), value_(v), demon_(nullptr) {} void GreaterEqExprCst::Post() { @@ -165,7 +167,7 @@ std::string GreaterEqExprCst::DebugString() const { } } // namespace -Constraint* Solver::MakeGreaterOrEqual(IntExpr* const e, int64 v) { +Constraint* Solver::MakeGreaterOrEqual(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); if (e->Min() >= v) { return MakeTrueConstraint(); @@ -187,7 +189,7 @@ Constraint* Solver::MakeGreaterOrEqual(IntExpr* const e, int v) { } } -Constraint* Solver::MakeGreater(IntExpr* const e, int64 v) { +Constraint* Solver::MakeGreater(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); if (e->Min() > v) { return MakeTrueConstraint(); @@ -215,7 +217,7 @@ Constraint* Solver::MakeGreater(IntExpr* const e, int v) { namespace { class LessEqExprCst : public Constraint { public: - LessEqExprCst(Solver* const s, IntExpr* const e, int64 v); + LessEqExprCst(Solver* const s, IntExpr* const e, int64_t v); ~LessEqExprCst() override {} void Post() override; void InitialPropagate() override; @@ -233,11 +235,11 @@ class LessEqExprCst : public Constraint { private: IntExpr* const expr_; - int64 value_; + int64_t value_; Demon* demon_; }; -LessEqExprCst::LessEqExprCst(Solver* const s, IntExpr* const e, int64 v) +LessEqExprCst::LessEqExprCst(Solver* const s, IntExpr* const e, int64_t v) : Constraint(s), expr_(e), value_(v), demon_(nullptr) {} void LessEqExprCst::Post() { @@ -262,7 +264,7 @@ std::string LessEqExprCst::DebugString() const { } } // namespace -Constraint* Solver::MakeLessOrEqual(IntExpr* const e, int64 v) { +Constraint* Solver::MakeLessOrEqual(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); if (e->Max() <= v) { return MakeTrueConstraint(); @@ -284,7 +286,7 @@ Constraint* Solver::MakeLessOrEqual(IntExpr* const e, int v) { } } -Constraint* Solver::MakeLess(IntExpr* const e, int64 v) { +Constraint* Solver::MakeLess(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); if (e->Max() < v) { return MakeTrueConstraint(); @@ -312,7 +314,7 @@ Constraint* Solver::MakeLess(IntExpr* const e, int v) { namespace { class DiffCst : public Constraint { public: - DiffCst(Solver* const s, IntVar* const var, int64 value); + DiffCst(Solver* const s, IntVar* const var, int64_t value); ~DiffCst() override {} void Post() override {} void InitialPropagate() override; @@ -333,11 +335,11 @@ class DiffCst : public Constraint { bool HasLargeDomain(IntVar* var); IntVar* const var_; - int64 value_; + int64_t value_; Demon* demon_; }; -DiffCst::DiffCst(Solver* const s, IntVar* const var, int64 value) +DiffCst::DiffCst(Solver* const s, IntVar* const var, int64_t value) : Constraint(s), var_(var), value_(value), demon_(nullptr) {} void DiffCst::InitialPropagate() { @@ -351,8 +353,8 @@ void DiffCst::InitialPropagate() { } void DiffCst::BoundPropagate() { - const int64 var_min = var_->Min(); - const int64 var_max = var_->Max(); + const int64_t var_min = var_->Min(); + const int64_t var_max = var_->Max(); if (var_min > value_ || var_max < value_) { demon_->inhibit(solver()); } else if (var_min == value_) { @@ -374,7 +376,7 @@ bool DiffCst::HasLargeDomain(IntVar* var) { } } // namespace -Constraint* Solver::MakeNonEquality(IntExpr* const e, int64 v) { +Constraint* Solver::MakeNonEquality(IntExpr* const e, int64_t v) { CHECK_EQ(this, e->solver()); IntExpr* left = nullptr; IntExpr* right = nullptr; @@ -408,7 +410,7 @@ Constraint* Solver::MakeNonEquality(IntExpr* const e, int v) { namespace { class IsEqualCstCt : public CastConstraint { public: - IsEqualCstCt(Solver* const s, IntVar* const v, int64 c, IntVar* const b) + IsEqualCstCt(Solver* const s, IntVar* const v, int64_t c, IntVar* const b) : CastConstraint(s, b), var_(v), cst_(c), demon_(nullptr) {} void Post() override { demon_ = solver()->MakeConstraintInitialPropagateCallback(this); @@ -417,8 +419,8 @@ class IsEqualCstCt : public CastConstraint { } void InitialPropagate() override { bool inhibit = var_->Bound(); - int64 u = var_->Contains(cst_); - int64 l = inhibit ? u : 0; + int64_t u = var_->Contains(cst_); + int64_t l = inhibit ? u : 0; target_var_->SetRange(l, u); if (target_var_->Bound()) { if (target_var_->Min() == 0) { @@ -452,12 +454,12 @@ class IsEqualCstCt : public CastConstraint { private: IntVar* const var_; - int64 cst_; + int64_t cst_; Demon* demon_; }; } // namespace -IntVar* Solver::MakeIsEqualCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsEqualCstVar(IntExpr* const var, int64_t value) { IntExpr* left = nullptr; IntExpr* right = nullptr; if (IsADifference(var, &left, &right)) { @@ -482,7 +484,7 @@ IntVar* Solver::MakeIsEqualCstVar(IntExpr* const var, int64 value) { } } -Constraint* Solver::MakeIsEqualCstCt(IntExpr* const var, int64 value, +Constraint* Solver::MakeIsEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar) { CHECK_EQ(this, var->solver()); CHECK_EQ(this, boolvar->solver()); @@ -523,7 +525,7 @@ Constraint* Solver::MakeIsEqualCstCt(IntExpr* const var, int64 value, namespace { class IsDiffCstCt : public CastConstraint { public: - IsDiffCstCt(Solver* const s, IntVar* const v, int64 c, IntVar* const b) + IsDiffCstCt(Solver* const s, IntVar* const v, int64_t c, IntVar* const b) : CastConstraint(s, b), var_(v), cst_(c), demon_(nullptr) {} void Post() override { @@ -534,8 +536,8 @@ class IsDiffCstCt : public CastConstraint { void InitialPropagate() override { bool inhibit = var_->Bound(); - int64 l = 1 - var_->Contains(cst_); - int64 u = inhibit ? l : 1; + int64_t l = 1 - var_->Contains(cst_); + int64_t u = inhibit ? l : 1; target_var_->SetRange(l, u); if (target_var_->Bound()) { if (target_var_->Min() == 1) { @@ -570,12 +572,12 @@ class IsDiffCstCt : public CastConstraint { private: IntVar* const var_; - int64 cst_; + int64_t cst_; Demon* demon_; }; } // namespace -IntVar* Solver::MakeIsDifferentCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsDifferentCstVar(IntExpr* const var, int64_t value) { IntExpr* left = nullptr; IntExpr* right = nullptr; if (IsADifference(var, &left, &right)) { @@ -584,7 +586,7 @@ IntVar* Solver::MakeIsDifferentCstVar(IntExpr* const var, int64 value) { return var->Var()->IsDifferent(value); } -Constraint* Solver::MakeIsDifferentCstCt(IntExpr* const var, int64 value, +Constraint* Solver::MakeIsDifferentCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar) { CHECK_EQ(this, var->solver()); CHECK_EQ(this, boolvar->solver()); @@ -595,7 +597,7 @@ Constraint* Solver::MakeIsDifferentCstCt(IntExpr* const var, int64 value, return MakeIsLessOrEqualCstCt(var, value - 1, boolvar); } if (var->IsVar() && !var->Var()->Contains(value)) { - return MakeEquality(boolvar, int64{1}); + return MakeEquality(boolvar, int64_t{1}); } if (var->Bound() && var->Min() == value) { return MakeEquality(boolvar, Zero()); @@ -623,7 +625,7 @@ Constraint* Solver::MakeIsDifferentCstCt(IntExpr* const var, int64 value, namespace { class IsGreaterEqualCstCt : public CastConstraint { public: - IsGreaterEqualCstCt(Solver* const s, IntExpr* const v, int64 c, + IsGreaterEqualCstCt(Solver* const s, IntExpr* const v, int64_t c, IntVar* const b) : CastConstraint(s, b), expr_(v), cst_(c), demon_(nullptr) {} void Post() override { @@ -633,8 +635,8 @@ class IsGreaterEqualCstCt : public CastConstraint { } void InitialPropagate() override { bool inhibit = false; - int64 u = expr_->Max() >= cst_; - int64 l = expr_->Min() >= cst_; + int64_t u = expr_->Max() >= cst_; + int64_t l = expr_->Min() >= cst_; target_var_->SetRange(l, u); if (target_var_->Bound()) { inhibit = true; @@ -669,17 +671,17 @@ class IsGreaterEqualCstCt : public CastConstraint { private: IntExpr* const expr_; - int64 cst_; + int64_t cst_; Demon* demon_; }; } // namespace -IntVar* Solver::MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64_t value) { if (var->Min() >= value) { - return MakeIntConst(int64{1}); + return MakeIntConst(int64_t{1}); } if (var->Max() < value) { - return MakeIntConst(int64{0}); + return MakeIntConst(int64_t{0}); } if (var->IsVar()) { return var->Var()->IsGreaterOrEqual(value); @@ -691,11 +693,11 @@ IntVar* Solver::MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64 value) { } } -IntVar* Solver::MakeIsGreaterCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsGreaterCstVar(IntExpr* const var, int64_t value) { return MakeIsGreaterOrEqualCstVar(var, value + 1); } -Constraint* Solver::MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64 value, +Constraint* Solver::MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar) { if (boolvar->Bound()) { if (boolvar->Min() == 0) { @@ -711,7 +713,7 @@ Constraint* Solver::MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64 value, return RevAlloc(new IsGreaterEqualCstCt(this, var, value, boolvar)); } -Constraint* Solver::MakeIsGreaterCstCt(IntExpr* const v, int64 c, +Constraint* Solver::MakeIsGreaterCstCt(IntExpr* const v, int64_t c, IntVar* const b) { return MakeIsGreaterOrEqualCstCt(v, c + 1, b); } @@ -721,7 +723,8 @@ Constraint* Solver::MakeIsGreaterCstCt(IntExpr* const v, int64 c, namespace { class IsLessEqualCstCt : public CastConstraint { public: - IsLessEqualCstCt(Solver* const s, IntExpr* const v, int64 c, IntVar* const b) + IsLessEqualCstCt(Solver* const s, IntExpr* const v, int64_t c, + IntVar* const b) : CastConstraint(s, b), expr_(v), cst_(c), demon_(nullptr) {} void Post() override { @@ -732,8 +735,8 @@ class IsLessEqualCstCt : public CastConstraint { void InitialPropagate() override { bool inhibit = false; - int64 u = expr_->Min() <= cst_; - int64 l = expr_->Max() <= cst_; + int64_t u = expr_->Min() <= cst_; + int64_t l = expr_->Max() <= cst_; target_var_->SetRange(l, u); if (target_var_->Bound()) { inhibit = true; @@ -768,17 +771,17 @@ class IsLessEqualCstCt : public CastConstraint { private: IntExpr* const expr_; - int64 cst_; + int64_t cst_; Demon* demon_; }; } // namespace -IntVar* Solver::MakeIsLessOrEqualCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsLessOrEqualCstVar(IntExpr* const var, int64_t value) { if (var->Max() <= value) { - return MakeIntConst(int64{1}); + return MakeIntConst(int64_t{1}); } if (var->Min() > value) { - return MakeIntConst(int64{0}); + return MakeIntConst(int64_t{0}); } if (var->IsVar()) { return var->Var()->IsLessOrEqual(value); @@ -790,11 +793,11 @@ IntVar* Solver::MakeIsLessOrEqualCstVar(IntExpr* const var, int64 value) { } } -IntVar* Solver::MakeIsLessCstVar(IntExpr* const var, int64 value) { +IntVar* Solver::MakeIsLessCstVar(IntExpr* const var, int64_t value) { return MakeIsLessOrEqualCstVar(var, value - 1); } -Constraint* Solver::MakeIsLessOrEqualCstCt(IntExpr* const var, int64 value, +Constraint* Solver::MakeIsLessOrEqualCstCt(IntExpr* const var, int64_t value, IntVar* const boolvar) { if (boolvar->Bound()) { if (boolvar->Min() == 0) { @@ -810,7 +813,7 @@ Constraint* Solver::MakeIsLessOrEqualCstCt(IntExpr* const var, int64 value, return RevAlloc(new IsLessEqualCstCt(this, var, value, boolvar)); } -Constraint* Solver::MakeIsLessCstCt(IntExpr* const v, int64 c, +Constraint* Solver::MakeIsLessCstCt(IntExpr* const v, int64_t c, IntVar* const b) { return MakeIsLessOrEqualCstCt(v, c - 1, b); } @@ -820,7 +823,7 @@ Constraint* Solver::MakeIsLessCstCt(IntExpr* const v, int64 c, namespace { class BetweenCt : public Constraint { public: - BetweenCt(Solver* const s, IntExpr* const v, int64 l, int64 u) + BetweenCt(Solver* const s, IntExpr* const v, int64_t l, int64_t u) : Constraint(s), expr_(v), min_(l), max_(u), demon_(nullptr) {} void Post() override { @@ -832,8 +835,8 @@ class BetweenCt : public Constraint { void InitialPropagate() override { expr_->SetRange(min_, max_); - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (demon_ != nullptr && emin >= min_ && emax <= max_) { demon_->inhibit(solver()); @@ -856,8 +859,8 @@ class BetweenCt : public Constraint { private: IntExpr* const expr_; - int64 min_; - int64 max_; + int64_t min_; + int64_t max_; Demon* demon_; }; @@ -865,7 +868,7 @@ class BetweenCt : public Constraint { class NotBetweenCt : public Constraint { public: - NotBetweenCt(Solver* const s, IntExpr* const v, int64 l, int64 u) + NotBetweenCt(Solver* const s, IntExpr* const v, int64_t l, int64_t u) : Constraint(s), expr_(v), min_(l), max_(u), demon_(nullptr) {} void Post() override { @@ -874,8 +877,8 @@ class NotBetweenCt : public Constraint { } void InitialPropagate() override { - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin >= min_) { expr_->SetMin(max_ + 1); @@ -904,28 +907,28 @@ class NotBetweenCt : public Constraint { private: IntExpr* const expr_; - int64 min_; - int64 max_; + int64_t min_; + int64_t max_; Demon* demon_; }; -int64 ExtractExprProductCoeff(IntExpr** expr) { - int64 prod = 1; - int64 coeff = 1; +int64_t ExtractExprProductCoeff(IntExpr** expr) { + int64_t prod = 1; + int64_t coeff = 1; while ((*expr)->solver()->IsProduct(*expr, expr, &coeff)) prod *= coeff; return prod; } } // namespace -Constraint* Solver::MakeBetweenCt(IntExpr* expr, int64 l, int64 u) { +Constraint* Solver::MakeBetweenCt(IntExpr* expr, int64_t l, int64_t u) { DCHECK_EQ(this, expr->solver()); // Catch empty and singleton intervals. if (l >= u) { if (l > u) return MakeFalseConstraint(); return MakeEquality(expr, l); } - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr->Range(&emin, &emax); // Catch the trivial cases first. if (emax < l || emin > u) return MakeFalseConstraint(); @@ -934,7 +937,7 @@ Constraint* Solver::MakeBetweenCt(IntExpr* expr, int64 l, int64 u) { if (emax <= u) return MakeGreaterOrEqual(expr, l); if (emin >= l) return MakeLessOrEqual(expr, u); // Simplify the common factor, if any. - int64 coeff = ExtractExprProductCoeff(&expr); + int64_t coeff = ExtractExprProductCoeff(&expr); if (coeff != 1) { CHECK_NE(coeff, 0); // Would have been caught by the trivial cases already. if (coeff < 0) { @@ -950,15 +953,15 @@ Constraint* Solver::MakeBetweenCt(IntExpr* expr, int64 l, int64 u) { } } -Constraint* Solver::MakeNotBetweenCt(IntExpr* expr, int64 l, int64 u) { +Constraint* Solver::MakeNotBetweenCt(IntExpr* expr, int64_t l, int64_t u) { DCHECK_EQ(this, expr->solver()); // Catch empty interval. if (l > u) { return MakeTrueConstraint(); } - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr->Range(&emin, &emax); // Catch the trivial cases first. if (emax < l || emin > u) return MakeTrueConstraint(); @@ -976,7 +979,7 @@ Constraint* Solver::MakeNotBetweenCt(IntExpr* expr, int64 l, int64 u) { namespace { class IsBetweenCt : public Constraint { public: - IsBetweenCt(Solver* const s, IntExpr* const e, int64 l, int64 u, + IsBetweenCt(Solver* const s, IntExpr* const e, int64_t l, int64_t u, IntVar* const b) : Constraint(s), expr_(e), @@ -993,11 +996,11 @@ class IsBetweenCt : public Constraint { void InitialPropagate() override { bool inhibit = false; - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); - int64 u = 1 - (emin > max_ || emax < min_); - int64 l = emax <= max_ && emin >= min_; + int64_t u = 1 - (emin > max_ || emax < min_); + int64_t l = emax <= max_ && emin >= min_; boolvar_->SetRange(l, u); if (boolvar_->Bound()) { inhibit = true; @@ -1038,14 +1041,14 @@ class IsBetweenCt : public Constraint { private: IntExpr* const expr_; - int64 min_; - int64 max_; + int64_t min_; + int64_t max_; IntVar* const boolvar_; Demon* demon_; }; } // namespace -Constraint* Solver::MakeIsBetweenCt(IntExpr* expr, int64 l, int64 u, +Constraint* Solver::MakeIsBetweenCt(IntExpr* expr, int64_t l, int64_t u, IntVar* const b) { CHECK_EQ(this, expr->solver()); CHECK_EQ(this, b->solver()); @@ -1054,8 +1057,8 @@ Constraint* Solver::MakeIsBetweenCt(IntExpr* expr, int64 l, int64 u, if (l > u) return MakeEquality(b, Zero()); return MakeIsEqualCstCt(expr, l, b); } - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr->Range(&emin, &emax); // Catch the trivial cases first. if (emax < l || emin > u) return MakeEquality(b, Zero()); @@ -1064,7 +1067,7 @@ Constraint* Solver::MakeIsBetweenCt(IntExpr* expr, int64 l, int64 u, if (emax <= u) return MakeIsGreaterOrEqualCstCt(expr, l, b); if (emin >= l) return MakeIsLessOrEqualCstCt(expr, u, b); // Simplify the common factor, if any. - int64 coeff = ExtractExprProductCoeff(&expr); + int64_t coeff = ExtractExprProductCoeff(&expr); if (coeff != 1) { CHECK_NE(coeff, 0); // Would have been caught by the trivial cases already. if (coeff < 0) { @@ -1081,7 +1084,7 @@ Constraint* Solver::MakeIsBetweenCt(IntExpr* expr, int64 l, int64 u, } } -IntVar* Solver::MakeIsBetweenVar(IntExpr* const v, int64 l, int64 u) { +IntVar* Solver::MakeIsBetweenVar(IntExpr* const v, int64_t l, int64_t u) { CHECK_EQ(this, v->solver()); IntVar* const b = MakeBoolVar(); AddConstraint(MakeIsBetweenCt(v, l, u, b)); @@ -1097,7 +1100,7 @@ namespace { class MemberCt : public Constraint { public: MemberCt(Solver* const s, IntVar* const v, - const std::vector& sorted_values) + const std::vector& sorted_values) : Constraint(s), var_(v), values_(sorted_values) { DCHECK(v != nullptr); DCHECK(s != nullptr); @@ -1122,13 +1125,13 @@ class MemberCt : public Constraint { private: IntVar* const var_; - const std::vector values_; + const std::vector values_; }; class NotMemberCt : public Constraint { public: NotMemberCt(Solver* const s, IntVar* const v, - const std::vector& sorted_values) + const std::vector& sorted_values) : Constraint(s), var_(v), values_(sorted_values) { DCHECK(v != nullptr); DCHECK(s != nullptr); @@ -1153,34 +1156,34 @@ class NotMemberCt : public Constraint { private: IntVar* const var_; - const std::vector values_; + const std::vector values_; }; } // namespace Constraint* Solver::MakeMemberCt(IntExpr* expr, - const std::vector& values) { - const int64 coeff = ExtractExprProductCoeff(&expr); + const std::vector& values) { + const int64_t coeff = ExtractExprProductCoeff(&expr); if (coeff == 0) { return std::find(values.begin(), values.end(), 0) == values.end() ? MakeFalseConstraint() : MakeTrueConstraint(); } - std::vector copied_values = values; + std::vector copied_values = values; // If the expression is a non-trivial product, we filter out the values that // aren't multiples of "coeff", and divide them. if (coeff != 1) { int num_kept = 0; - for (const int64 v : copied_values) { + for (const int64_t v : copied_values) { if (v % coeff == 0) copied_values[num_kept++] = v / coeff; } copied_values.resize(num_kept); } // Filter out the values that are outside the [Min, Max] interval. int num_kept = 0; - int64 emin; - int64 emax; + int64_t emin; + int64_t emax; expr->Range(&emin, &emax); - for (const int64 v : copied_values) { + for (const int64_t v : copied_values) { if (v >= emin && v <= emax) copied_values[num_kept++] = v; } copied_values.resize(num_kept); @@ -1202,11 +1205,12 @@ Constraint* Solver::MakeMemberCt(IntExpr* expr, if (emax - emin < 2 * copied_values.size()) { // Convert "copied_values" to list the values *not* allowed. std::vector is_among_input_values(emax - emin + 1, false); - for (const int64 v : copied_values) is_among_input_values[v - emin] = true; + for (const int64_t v : copied_values) + is_among_input_values[v - emin] = true; // We use the zero valued indices of is_among_input_values to build the // complement of copied_values. copied_values.clear(); - for (int64 v_off = 0; v_off < is_among_input_values.size(); ++v_off) { + for (int64_t v_off = 0; v_off < is_among_input_values.size(); ++v_off) { if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin); } // The empty' case (all values in range [expr.Min(), expr.Max()] are in the @@ -1227,29 +1231,29 @@ Constraint* Solver::MakeMemberCt(IntExpr* const expr, } Constraint* Solver::MakeNotMemberCt(IntExpr* expr, - const std::vector& values) { - const int64 coeff = ExtractExprProductCoeff(&expr); + const std::vector& values) { + const int64_t coeff = ExtractExprProductCoeff(&expr); if (coeff == 0) { return std::find(values.begin(), values.end(), 0) == values.end() ? MakeTrueConstraint() : MakeFalseConstraint(); } - std::vector copied_values = values; + std::vector copied_values = values; // If the expression is a non-trivial product, we filter out the values that // aren't multiples of "coeff", and divide them. if (coeff != 1) { int num_kept = 0; - for (const int64 v : copied_values) { + for (const int64_t v : copied_values) { if (v % coeff == 0) copied_values[num_kept++] = v / coeff; } copied_values.resize(num_kept); } // Filter out the values that are outside the [Min, Max] interval. int num_kept = 0; - int64 emin; - int64 emax; + int64_t emin; + int64_t emax; expr->Range(&emin, &emax); - for (const int64 v : copied_values) { + for (const int64_t v : copied_values) { if (v >= emin && v <= emax) copied_values[num_kept++] = v; } copied_values.resize(num_kept); @@ -1270,11 +1274,12 @@ Constraint* Solver::MakeNotMemberCt(IntExpr* expr, if (emax - emin < 2 * copied_values.size()) { // Convert "copied_values" to a dense boolean vector. std::vector is_among_input_values(emax - emin + 1, false); - for (const int64 v : copied_values) is_among_input_values[v - emin] = true; + for (const int64_t v : copied_values) + is_among_input_values[v - emin] = true; // Use zero valued indices for is_among_input_values to build the // complement of copied_values. copied_values.clear(); - for (int64 v_off = 0; v_off < is_among_input_values.size(); ++v_off) { + for (int64_t v_off = 0; v_off < is_among_input_values.size(); ++v_off) { if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin); } // The empty' case (all values in range [expr.Min(), expr.Max()] are in the @@ -1300,7 +1305,7 @@ namespace { class IsMemberCt : public Constraint { public: IsMemberCt(Solver* const s, IntVar* const v, - const std::vector& sorted_values, IntVar* const b) + const std::vector& sorted_values, IntVar* const b) : Constraint(s), var_(v), values_as_set_(sorted_values.begin(), sorted_values.end()), @@ -1309,7 +1314,7 @@ class IsMemberCt : public Constraint { support_(0), demon_(nullptr), domain_(var_->MakeDomainIterator(true)), - neg_support_(kint64min) { + neg_support_(std::numeric_limits::min()) { DCHECK(v != nullptr); DCHECK(s != nullptr); DCHECK(b != nullptr); @@ -1376,7 +1381,7 @@ class IsMemberCt : public Constraint { return; } else { // Look for a new negative support. - for (const int64 value : InitAndGetValues(domain_)) { + for (const int64_t value : InitAndGetValues(domain_)) { if (!gtl::ContainsKey(values_as_set_, value)) { neg_support_ = value; return; @@ -1407,13 +1412,13 @@ class IsMemberCt : public Constraint { } IntVar* const var_; - absl::flat_hash_set values_as_set_; - std::vector values_; + absl::flat_hash_set values_as_set_; + std::vector values_; IntVar* const boolvar_; int support_; Demon* demon_; IntVarIterator* const domain_; - int64 neg_support_; + int64_t neg_support_; }; template @@ -1423,11 +1428,11 @@ Constraint* BuildIsMemberCt(Solver* const solver, IntExpr* const expr, // TODO(user): optimize this by copying the code from MakeMemberCt. // Simplify and filter if expr is a product. IntExpr* sub = nullptr; - int64 coef = 1; + int64_t coef = 1; if (solver->IsProduct(expr, &sub, &coef) && coef != 0 && coef != 1) { - std::vector new_values; + std::vector new_values; new_values.reserve(values.size()); - for (const int64 value : values) { + for (const int64_t value : values) { if (value % coef == 0) { new_values.push_back(value / coef); } @@ -1436,7 +1441,7 @@ Constraint* BuildIsMemberCt(Solver* const solver, IntExpr* const expr, } std::set set_of_values(values.begin(), values.end()); - std::vector filtered_values; + std::vector filtered_values; bool all_values = false; if (expr->IsVar()) { IntVar* const var = expr->Var(); @@ -1447,8 +1452,8 @@ Constraint* BuildIsMemberCt(Solver* const solver, IntExpr* const expr, } all_values = (filtered_values.size() == var->Size()); } else { - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr->Range(&emin, &emax); for (const T value : set_of_values) { if (value >= emin && value <= emax) { @@ -1476,7 +1481,7 @@ Constraint* BuildIsMemberCt(Solver* const solver, IntExpr* const expr, } // namespace Constraint* Solver::MakeIsMemberCt(IntExpr* const expr, - const std::vector& values, + const std::vector& values, IntVar* const boolvar) { return BuildIsMemberCt(this, expr, values, boolvar); } @@ -1488,7 +1493,7 @@ Constraint* Solver::MakeIsMemberCt(IntExpr* const expr, } IntVar* Solver::MakeIsMemberVar(IntExpr* const expr, - const std::vector& values) { + const std::vector& values) { IntVar* const b = MakeBoolVar(); AddConstraint(MakeIsMemberCt(expr, values, b)); return b; @@ -1517,8 +1522,8 @@ class SortedDisjointForbiddenIntervalsConstraint : public Constraint { } void InitialPropagate() override { - const int64 vmin = var_->Min(); - const int64 vmax = var_->Max(); + const int64_t vmin = var_->Min(); + const int64_t vmax = var_->Max(); const auto first_interval_it = intervals_.FirstIntervalGreaterOrEqual(vmin); if (first_interval_it == intervals_.end()) { // No interval intersects the variable's range. Nothing to do. @@ -1551,8 +1556,8 @@ class SortedDisjointForbiddenIntervalsConstraint : public Constraint { visitor->BeginVisitConstraint(ModelVisitor::kNotMember, this); visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument, var_); - std::vector starts; - std::vector ends; + std::vector starts; + std::vector ends; for (auto& interval : intervals_) { starts.push_back(interval.start); ends.push_back(interval.end); @@ -1569,8 +1574,8 @@ class SortedDisjointForbiddenIntervalsConstraint : public Constraint { } // namespace Constraint* Solver::MakeNotMemberCt(IntExpr* const expr, - std::vector starts, - std::vector ends) { + std::vector starts, + std::vector ends) { return RevAlloc(new SortedDisjointForbiddenIntervalsConstraint( this, expr->Var(), {starts, ends})); } diff --git a/ortools/constraint_solver/expressions.cc b/ortools/constraint_solver/expressions.cc index 07e9de37da..73f87592d1 100644 --- a/ortools/constraint_solver/expressions.cc +++ b/ortools/constraint_solver/expressions.cc @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -65,19 +67,19 @@ IntVar::IntVar(Solver* const s, const std::string& name) const int BooleanVar::kUnboundBooleanVarValue = 2; -void BooleanVar::SetMin(int64 m) { +void BooleanVar::SetMin(int64_t m) { if (m <= 0) return; if (m > 1) solver()->Fail(); SetValue(1); } -void BooleanVar::SetMax(int64 m) { +void BooleanVar::SetMax(int64_t m) { if (m >= 1) return; if (m < 0) solver()->Fail(); SetValue(0); } -void BooleanVar::SetRange(int64 mi, int64 ma) { +void BooleanVar::SetRange(int64_t mi, int64_t ma) { if (mi > 1 || ma < 0 || mi > ma) { solver()->Fail(); } @@ -88,7 +90,7 @@ void BooleanVar::SetRange(int64 mi, int64 ma) { } } -void BooleanVar::RemoveValue(int64 v) { +void BooleanVar::RemoveValue(int64_t v) { if (value_ == kUnboundBooleanVarValue) { if (v == 0) { SetValue(1); @@ -100,7 +102,7 @@ void BooleanVar::RemoveValue(int64 v) { } } -void BooleanVar::RemoveInterval(int64 l, int64 u) { +void BooleanVar::RemoveInterval(int64_t l, int64_t u) { if (u < l) return; if (l <= 0 && u >= 1) { solver()->Fail(); @@ -121,15 +123,15 @@ void BooleanVar::WhenBound(Demon* d) { } } -uint64 BooleanVar::Size() const { +uint64_t BooleanVar::Size() const { return (1 + (value_ == kUnboundBooleanVarValue)); } -bool BooleanVar::Contains(int64 v) const { +bool BooleanVar::Contains(int64_t v) const { return ((v == 0 && value_ != 1) || (v == 1 && value_ != 0)); } -IntVar* BooleanVar::IsEqual(int64 constant) { +IntVar* BooleanVar::IsEqual(int64_t constant) { if (constant > 1 || constant < 0) { return solver()->MakeIntConst(0); } @@ -140,7 +142,7 @@ IntVar* BooleanVar::IsEqual(int64 constant) { } } -IntVar* BooleanVar::IsDifferent(int64 constant) { +IntVar* BooleanVar::IsDifferent(int64_t constant) { if (constant > 1 || constant < 0) { return solver()->MakeIntConst(1); } @@ -151,7 +153,7 @@ IntVar* BooleanVar::IsDifferent(int64 constant) { } } -IntVar* BooleanVar::IsGreaterOrEqual(int64 constant) { +IntVar* BooleanVar::IsGreaterOrEqual(int64_t constant) { if (constant > 1) { return solver()->MakeIntConst(0); } else if (constant <= 0) { @@ -161,7 +163,7 @@ IntVar* BooleanVar::IsGreaterOrEqual(int64 constant) { } } -IntVar* BooleanVar::IsLessOrEqual(int64 constant) { +IntVar* BooleanVar::IsLessOrEqual(int64_t constant) { if (constant < 0) { return solver()->MakeIntConst(0); } else if (constant >= 1) { @@ -204,19 +206,22 @@ class DomainIntVar : public IntVar { // Utility classes class BitSetIterator : public BaseObject { public: - BitSetIterator(uint64* const bitset, int64 omin) - : bitset_(bitset), omin_(omin), max_(kint64min), current_(kint64max) {} + BitSetIterator(uint64_t* const bitset, int64_t omin) + : bitset_(bitset), + omin_(omin), + max_(std::numeric_limits::min()), + current_(std::numeric_limits::max()) {} ~BitSetIterator() override {} - void Init(int64 min, int64 max) { + void Init(int64_t min, int64_t max) { max_ = max; current_ = min; } bool Ok() const { return current_ <= max_; } - int64 Value() const { return current_; } + int64_t Value() const { return current_; } void Next() { if (++current_ <= max_) { @@ -229,10 +234,10 @@ class DomainIntVar : public IntVar { std::string DebugString() const override { return "BitSetIterator"; } private: - uint64* const bitset_; - const int64 omin_; - int64 max_; - int64 current_; + uint64_t* const bitset_; + const int64_t omin_; + int64_t max_; + int64_t current_; }; class BitSet : public BaseObject { @@ -240,20 +245,20 @@ class DomainIntVar : public IntVar { explicit BitSet(Solver* const s) : solver_(s), holes_stamp_(0) {} ~BitSet() override {} - virtual int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) = 0; - virtual int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) = 0; - virtual bool Contains(int64 val) const = 0; - virtual bool SetValue(int64 val) = 0; - virtual bool RemoveValue(int64 val) = 0; - virtual uint64 Size() const = 0; - virtual void DelayRemoveValue(int64 val) = 0; + virtual int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax) = 0; + virtual int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax) = 0; + virtual bool Contains(int64_t val) const = 0; + virtual bool SetValue(int64_t val) = 0; + virtual bool RemoveValue(int64_t val) = 0; + virtual uint64_t Size() const = 0; + virtual void DelayRemoveValue(int64_t val) = 0; virtual void ApplyRemovedValues(DomainIntVar* var) = 0; virtual void ClearRemovedValues() = 0; - virtual std::string pretty_DebugString(int64 min, int64 max) const = 0; + virtual std::string pretty_DebugString(int64_t min, int64_t max) const = 0; virtual BitSetIterator* MakeIterator() = 0; void InitHoles() { - const uint64 current_stamp = solver_->stamp(); + const uint64_t current_stamp = solver_->stamp(); if (holes_stamp_ < current_stamp) { holes_.clear(); holes_stamp_ = current_stamp; @@ -262,9 +267,9 @@ class DomainIntVar : public IntVar { virtual void ClearHoles() { holes_.clear(); } - const std::vector& Holes() { return holes_; } + const std::vector& Holes() { return holes_; } - void AddHole(int64 value) { holes_.push_back(value); } + void AddHole(int64_t value) { holes_.push_back(value); } int NumHoles() const { return holes_stamp_ < solver_->stamp() ? 0 : holes_.size(); @@ -274,8 +279,8 @@ class DomainIntVar : public IntVar { Solver* const solver_; private: - std::vector holes_; - uint64 holes_stamp_; + std::vector holes_; + uint64_t holes_stamp_; }; class QueueHandler : public Demon { @@ -306,7 +311,7 @@ class DomainIntVar : public IntVar { template class RevIntPtrMap { public: - RevIntPtrMap(Solver* const solver, int64 rmin, int64 rmax) + RevIntPtrMap(Solver* const solver, int64_t rmin, int64_t rmax) : solver_(solver), range_min_(rmin), start_(0) {} ~RevIntPtrMap() {} @@ -318,7 +323,7 @@ class DomainIntVar : public IntVar { // Access with value API. // Add the pointer to the map attached to the given value. - void UnsafeRevInsert(int64 value, T* elem) { + void UnsafeRevInsert(int64_t value, T* elem) { elements_.push_back(std::make_pair(value, elem)); if (solver_->state() != Solver::OUTSIDE_SEARCH) { solver_->AddBacktrackAction( @@ -326,7 +331,7 @@ class DomainIntVar : public IntVar { } } - T* FindPtrOrNull(int64 value, int* position) { + T* FindPtrOrNull(int64_t value, int* position) { for (int pos = start_.Value(); pos < elements_.size(); ++pos) { if (elements_[pos].first == value) { if (position != nullptr) *position = pos; @@ -344,14 +349,14 @@ class DomainIntVar : public IntVar { if (position > start) { // Swap the current element with the one at the start position, and // increase start. - const std::pair copy = elements_[start]; + const std::pair copy = elements_[start]; elements_[start] = elements_[position]; elements_[position] = copy; } start_.Incr(solver_); } - const std::pair& At(int position) const { + const std::pair& At(int position) const { DCHECK_GE(position, start_.Value()); DCHECK_LT(position, elements_.size()); return elements_[position]; @@ -365,7 +370,7 @@ class DomainIntVar : public IntVar { int Size() const { return elements_.size() - start_.Value(); } // Removes the object permanently from the map. - void Uninsert(int64 value) { + void Uninsert(int64_t value) { for (int pos = 0; pos < elements_.size(); ++pos) { if (elements_[pos].first == value) { DCHECK_GE(pos, start_.Value()); @@ -382,9 +387,9 @@ class DomainIntVar : public IntVar { private: Solver* const solver_; - const int64 range_min_; + const int64_t range_min_; NumericalRev start_; - std::vector> elements_; + std::vector> elements_; }; // Base class for value watchers @@ -394,9 +399,9 @@ class DomainIntVar : public IntVar { ~BaseValueWatcher() override {} - virtual IntVar* GetOrMakeValueWatcher(int64 value) = 0; + virtual IntVar* GetOrMakeValueWatcher(int64_t value) = 0; - virtual void SetValueWatcher(IntVar* const boolvar, int64 value) = 0; + virtual void SetValueWatcher(IntVar* const boolvar, int64_t value) = 0; }; // This class monitors the domain of the variable and updates the @@ -405,7 +410,7 @@ class DomainIntVar : public IntVar { public: class WatchDemon : public Demon { public: - WatchDemon(ValueWatcher* const watcher, int64 value, IntVar* var) + WatchDemon(ValueWatcher* const watcher, int64_t value, IntVar* var) : value_watcher_(watcher), value_(value), var_(var) {} ~WatchDemon() override {} @@ -415,7 +420,7 @@ class DomainIntVar : public IntVar { private: ValueWatcher* const value_watcher_; - const int64 value_; + const int64_t value_; IntVar* const var_; }; @@ -441,7 +446,7 @@ class DomainIntVar : public IntVar { ~ValueWatcher() override {} - IntVar* GetOrMakeValueWatcher(int64 value) override { + IntVar* GetOrMakeValueWatcher(int64_t value) override { IntVar* const watcher = watchers_.FindPtrOrNull(value, nullptr); if (watcher != nullptr) return watcher; if (variable_->Contains(value)) { @@ -467,7 +472,7 @@ class DomainIntVar : public IntVar { } } - void SetValueWatcher(IntVar* const boolvar, int64 value) override { + void SetValueWatcher(IntVar* const boolvar, int64_t value) override { CHECK(watchers_.FindPtrOrNull(value, nullptr) == nullptr); if (!boolvar->Bound()) { watchers_.UnsafeRevInsert(value, boolvar); @@ -483,8 +488,8 @@ class DomainIntVar : public IntVar { var_demon_ = solver()->RevAlloc(new VarDemon(this)); variable_->WhenDomain(var_demon_); for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); - const int64 value = w.first; + const std::pair& w = watchers_.At(pos); + const int64_t value = w.first; IntVar* const boolvar = w.second; if (!boolvar->Bound() && variable_->Contains(value)) { boolvar->WhenBound( @@ -499,8 +504,8 @@ class DomainIntVar : public IntVar { VariableBound(); } else { for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); - const int64 value = w.first; + const std::pair& w = watchers_.At(pos); + const int64_t value = w.first; IntVar* const boolvar = w.second; if (!variable_->Contains(value)) { boolvar->SetValue(0); @@ -516,7 +521,7 @@ class DomainIntVar : public IntVar { } } - void ProcessValueWatcher(int64 value, IntVar* boolvar) { + void ProcessValueWatcher(int64_t value, IntVar* boolvar) { if (boolvar->Min() == 0) { if (variable_->Size() < 0xFFFFFF) { variable_->RemoveValue(value); @@ -548,7 +553,7 @@ class DomainIntVar : public IntVar { BitSet* const bitset = variable_->bitset(); if (bitset != nullptr && !watchers_.Empty()) { if (bitset->NumHoles() * 2 < watchers_.Size()) { - for (const int64 hole : InitAndGetValues(hole_iterator_)) { + for (const int64_t hole : InitAndGetValues(hole_iterator_)) { int pos = 0; IntVar* const boolvar = watchers_.FindPtrOrNull(hole, &pos); if (boolvar != nullptr) { @@ -567,9 +572,9 @@ class DomainIntVar : public IntVar { // Optimized case if the variable is bound. void VariableBound() { DCHECK(variable_->Bound()); - const int64 value = variable_->Min(); + const int64_t value = variable_->Min(); for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); + const std::pair& w = watchers_.At(pos); w.second->SetValue(w.first == value); } watchers_.RemoveAll(); @@ -579,7 +584,7 @@ class DomainIntVar : public IntVar { // Scans all the watchers to check and assign them. void ScanWatchers() { for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); + const std::pair& w = watchers_.At(pos); if (!variable_->Contains(w.first)) { IntVar* const boolvar = w.second; boolvar->SetValue(0); @@ -600,11 +605,11 @@ class DomainIntVar : public IntVar { visitor->BeginVisitConstraint(ModelVisitor::kVarValueWatcher, this); visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument, variable_); - std::vector all_coefficients; + std::vector all_coefficients; std::vector all_bool_vars; for (int position = watchers_.start(); position < watchers_.end(); ++position) { - const std::pair& w = watchers_.At(position); + const std::pair& w = watchers_.At(position); all_coefficients.push_back(w.first); all_bool_vars.push_back(w.second); } @@ -632,7 +637,7 @@ class DomainIntVar : public IntVar { public: class WatchDemon : public Demon { public: - WatchDemon(DenseValueWatcher* const watcher, int64 value, IntVar* var) + WatchDemon(DenseValueWatcher* const watcher, int64_t value, IntVar* var) : value_watcher_(watcher), value_(value), var_(var) {} ~WatchDemon() override {} @@ -642,7 +647,7 @@ class DomainIntVar : public IntVar { private: DenseValueWatcher* const value_watcher_; - const int64 value_; + const int64_t value_; IntVar* const var_; }; @@ -670,8 +675,8 @@ class DomainIntVar : public IntVar { ~DenseValueWatcher() override {} - IntVar* GetOrMakeValueWatcher(int64 value) override { - const int64 var_max = offset_ + watchers_.size() - 1; // Bad cast. + IntVar* GetOrMakeValueWatcher(int64_t value) override { + const int64_t var_max = offset_ + watchers_.size() - 1; // Bad cast. if (value < offset_ || value > var_max) { return solver()->MakeIntConst(0); } @@ -701,7 +706,7 @@ class DomainIntVar : public IntVar { } } - void SetValueWatcher(IntVar* const boolvar, int64 value) override { + void SetValueWatcher(IntVar* const boolvar, int64_t value) override { const int index = value - offset_; CHECK(watchers_[index] == nullptr); if (!boolvar->Bound()) { @@ -718,7 +723,7 @@ class DomainIntVar : public IntVar { var_demon_ = solver()->RevAlloc(new VarDemon(this)); variable_->WhenDomain(var_demon_); for (int pos = 0; pos < watchers_.size(); ++pos) { - const int64 value = pos + offset_; + const int64_t value = pos + offset_; IntVar* const boolvar = watchers_[pos]; if (boolvar != nullptr && !boolvar->Bound() && variable_->Contains(value)) { @@ -736,7 +741,7 @@ class DomainIntVar : public IntVar { for (int pos = 0; pos < watchers_.size(); ++pos) { IntVar* const boolvar = watchers_[pos]; if (boolvar == nullptr) continue; - const int64 value = pos + offset_; + const int64_t value = pos + offset_; if (!variable_->Contains(value)) { boolvar->SetValue(0); RevRemove(pos); @@ -751,7 +756,7 @@ class DomainIntVar : public IntVar { } } - void ProcessValueWatcher(int64 value, IntVar* boolvar) { + void ProcessValueWatcher(int64_t value, IntVar* boolvar) { if (boolvar->Min() == 0) { variable_->RemoveValue(value); } else { @@ -774,7 +779,7 @@ class DomainIntVar : public IntVar { // Optimized case if the variable is bound. void VariableBound() { DCHECK(variable_->Bound()); - const int64 value = variable_->Min(); + const int64_t value = variable_->Min(); for (int pos = 0; pos < watchers_.size(); ++pos) { IntVar* const boolvar = watchers_[pos]; if (boolvar != nullptr) { @@ -787,10 +792,10 @@ class DomainIntVar : public IntVar { // Scans all the watchers to check and assign them. void ScanWatchers() { - const int64 old_min_index = variable_->OldMin() - offset_; - const int64 old_max_index = variable_->OldMax() - offset_; - const int64 min_index = variable_->Min() - offset_; - const int64 max_index = variable_->Max() - offset_; + const int64_t old_min_index = variable_->OldMin() - offset_; + const int64_t old_max_index = variable_->OldMax() - offset_; + const int64_t min_index = variable_->Min() - offset_; + const int64_t max_index = variable_->Max() - offset_; for (int pos = old_min_index; pos < min_index; ++pos) { IntVar* const boolvar = watchers_[pos]; if (boolvar != nullptr) { @@ -808,7 +813,7 @@ class DomainIntVar : public IntVar { BitSet* const bitset = variable_->bitset(); if (bitset != nullptr) { if (bitset->NumHoles() * 2 < active_watchers_.Value()) { - for (const int64 hole : InitAndGetValues(hole_iterator_)) { + for (const int64_t hole : InitAndGetValues(hole_iterator_)) { IntVar* const boolvar = watchers_[hole - offset_]; if (boolvar != nullptr) { boolvar->SetValue(0); @@ -843,7 +848,7 @@ class DomainIntVar : public IntVar { visitor->BeginVisitConstraint(ModelVisitor::kVarValueWatcher, this); visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument, variable_); - std::vector all_coefficients; + std::vector all_coefficients; std::vector all_bool_vars; for (int position = 0; position < watchers_.size(); ++position) { if (watchers_[position] != nullptr) { @@ -867,7 +872,7 @@ class DomainIntVar : public IntVar { IntVarIterator* const hole_iterator_; RevSwitch posted_; Demon* var_demon_; - const int64 offset_; + const int64_t offset_; std::vector watchers_; NumericalRev active_watchers_; }; @@ -878,9 +883,9 @@ class DomainIntVar : public IntVar { ~BaseUpperBoundWatcher() override {} - virtual IntVar* GetOrMakeUpperBoundWatcher(int64 value) = 0; + virtual IntVar* GetOrMakeUpperBoundWatcher(int64_t value) = 0; - virtual void SetUpperBoundWatcher(IntVar* const boolvar, int64 value) = 0; + virtual void SetUpperBoundWatcher(IntVar* const boolvar, int64_t value) = 0; }; // This class watches the bounds of the variable and updates the @@ -890,7 +895,7 @@ class DomainIntVar : public IntVar { public: class WatchDemon : public Demon { public: - WatchDemon(UpperBoundWatcher* const watcher, int64 index, + WatchDemon(UpperBoundWatcher* const watcher, int64_t index, IntVar* const var) : value_watcher_(watcher), index_(index), var_(var) {} ~WatchDemon() override {} @@ -901,7 +906,7 @@ class DomainIntVar : public IntVar { private: UpperBoundWatcher* const value_watcher_; - const int64 index_; + const int64_t index_; IntVar* const var_; }; @@ -928,7 +933,7 @@ class DomainIntVar : public IntVar { ~UpperBoundWatcher() override {} - IntVar* GetOrMakeUpperBoundWatcher(int64 value) override { + IntVar* GetOrMakeUpperBoundWatcher(int64_t value) override { IntVar* const watcher = watchers_.FindPtrOrNull(value, nullptr); if (watcher != nullptr) { return watcher; @@ -957,7 +962,7 @@ class DomainIntVar : public IntVar { } } - void SetUpperBoundWatcher(IntVar* const boolvar, int64 value) override { + void SetUpperBoundWatcher(IntVar* const boolvar, int64_t value) override { CHECK(watchers_.FindPtrOrNull(value, nullptr) == nullptr); watchers_.UnsafeRevInsert(value, boolvar); if (posted_.Switched() && !boolvar->Bound()) { @@ -981,9 +986,9 @@ class DomainIntVar : public IntVar { } for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); + const std::pair& w = watchers_.At(pos); IntVar* const boolvar = w.second; - const int64 value = w.first; + const int64_t value = w.first; if (!boolvar->Bound() && value > variable_->Min() && value <= variable_->Max()) { boolvar->WhenBound( @@ -994,11 +999,11 @@ class DomainIntVar : public IntVar { } void InitialPropagate() override { - const int64 var_min = variable_->Min(); - const int64 var_max = variable_->Max(); + const int64_t var_min = variable_->Min(); + const int64_t var_max = variable_->Max(); if (sorted_) { while (start_.Value() <= end_.Value()) { - const std::pair& w = watchers_.At(start_.Value()); + const std::pair& w = watchers_.At(start_.Value()); if (w.first <= var_min) { w.second->SetValue(1); start_.Incr(solver()); @@ -1007,7 +1012,7 @@ class DomainIntVar : public IntVar { } } while (end_.Value() >= start_.Value()) { - const std::pair& w = watchers_.At(end_.Value()); + const std::pair& w = watchers_.At(end_.Value()); if (w.first > var_max) { w.second->SetValue(0); end_.Decr(solver()); @@ -1016,7 +1021,7 @@ class DomainIntVar : public IntVar { } } for (int i = start_.Value(); i <= end_.Value(); ++i) { - const std::pair& w = watchers_.At(i); + const std::pair& w = watchers_.At(i); if (w.second->Bound()) { ProcessUpperBoundWatcher(w.first, w.second); } @@ -1026,8 +1031,8 @@ class DomainIntVar : public IntVar { } } else { for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); - const int64 value = w.first; + const std::pair& w = watchers_.At(pos); + const int64_t value = w.first; IntVar* const boolvar = w.second; if (value <= var_min) { @@ -1048,10 +1053,10 @@ class DomainIntVar : public IntVar { visitor->BeginVisitConstraint(ModelVisitor::kVarBoundWatcher, this); visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument, variable_); - std::vector all_coefficients; + std::vector all_coefficients; std::vector all_bool_vars; for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); + const std::pair& w = watchers_.At(pos); all_coefficients.push_back(w.first); all_bool_vars.push_back(w.second); } @@ -1067,7 +1072,7 @@ class DomainIntVar : public IntVar { } private: - void ProcessUpperBoundWatcher(int64 value, IntVar* const boolvar) { + void ProcessUpperBoundWatcher(int64_t value, IntVar* const boolvar) { if (boolvar->Min() == 0) { variable_->SetMax(value - 1); } else { @@ -1076,11 +1081,11 @@ class DomainIntVar : public IntVar { } void ProcessVar() { - const int64 var_min = variable_->Min(); - const int64 var_max = variable_->Max(); + const int64_t var_min = variable_->Min(); + const int64_t var_max = variable_->Max(); if (sorted_) { while (start_.Value() <= end_.Value()) { - const std::pair& w = watchers_.At(start_.Value()); + const std::pair& w = watchers_.At(start_.Value()); if (w.first <= var_min) { w.second->SetValue(1); start_.Incr(solver()); @@ -1089,7 +1094,7 @@ class DomainIntVar : public IntVar { } } while (end_.Value() >= start_.Value()) { - const std::pair& w = watchers_.At(end_.Value()); + const std::pair& w = watchers_.At(end_.Value()); if (w.first > var_max) { w.second->SetValue(0); end_.Decr(solver()); @@ -1102,8 +1107,8 @@ class DomainIntVar : public IntVar { } } else { for (int pos = watchers_.start(); pos < watchers_.end(); ++pos) { - const std::pair& w = watchers_.At(pos); - const int64 value = w.first; + const std::pair& w = watchers_.At(pos); + const int64_t value = w.first; IntVar* const boolvar = w.second; if (value <= var_min) { @@ -1134,7 +1139,7 @@ class DomainIntVar : public IntVar { public: class WatchDemon : public Demon { public: - WatchDemon(DenseUpperBoundWatcher* const watcher, int64 value, + WatchDemon(DenseUpperBoundWatcher* const watcher, int64_t value, IntVar* var) : value_watcher_(watcher), value_(value), var_(var) {} ~WatchDemon() override {} @@ -1145,7 +1150,7 @@ class DomainIntVar : public IntVar { private: DenseUpperBoundWatcher* const value_watcher_; - const int64 value_; + const int64_t value_; IntVar* const var_; }; @@ -1172,7 +1177,7 @@ class DomainIntVar : public IntVar { ~DenseUpperBoundWatcher() override {} - IntVar* GetOrMakeUpperBoundWatcher(int64 value) override { + IntVar* GetOrMakeUpperBoundWatcher(int64_t value) override { if (variable_->Max() >= value) { if (variable_->Min() >= value) { return solver()->MakeIntConst(1); @@ -1196,7 +1201,7 @@ class DomainIntVar : public IntVar { } } - void SetUpperBoundWatcher(IntVar* const boolvar, int64 value) override { + void SetUpperBoundWatcher(IntVar* const boolvar, int64_t value) override { const int index = value - offset_; CHECK(watchers_[index] == nullptr); if (!boolvar->Bound()) { @@ -1213,7 +1218,7 @@ class DomainIntVar : public IntVar { var_demon_ = solver()->RevAlloc(new VarDemon(this)); variable_->WhenRange(var_demon_); for (int pos = 0; pos < watchers_.size(); ++pos) { - const int64 value = pos + offset_; + const int64_t value = pos + offset_; IntVar* const boolvar = watchers_[pos]; if (boolvar != nullptr && !boolvar->Bound() && value > variable_->Min() && value <= variable_->Max()) { @@ -1228,7 +1233,7 @@ class DomainIntVar : public IntVar { for (int pos = 0; pos < watchers_.size(); ++pos) { IntVar* const boolvar = watchers_[pos]; if (boolvar == nullptr) continue; - const int64 value = pos + offset_; + const int64_t value = pos + offset_; if (value <= variable_->Min()) { boolvar->SetValue(1); RevRemove(pos); @@ -1245,7 +1250,7 @@ class DomainIntVar : public IntVar { } } - void ProcessUpperBoundWatcher(int64 value, IntVar* boolvar) { + void ProcessUpperBoundWatcher(int64_t value, IntVar* boolvar) { if (boolvar->Min() == 0) { variable_->SetMax(value - 1); } else { @@ -1254,10 +1259,10 @@ class DomainIntVar : public IntVar { } void ProcessVar() { - const int64 old_min_index = variable_->OldMin() - offset_; - const int64 old_max_index = variable_->OldMax() - offset_; - const int64 min_index = variable_->Min() - offset_; - const int64 max_index = variable_->Max() - offset_; + const int64_t old_min_index = variable_->OldMin() - offset_; + const int64_t old_max_index = variable_->OldMax() - offset_; + const int64_t min_index = variable_->Min() - offset_; + const int64_t max_index = variable_->Max() - offset_; for (int pos = old_min_index; pos <= min_index; ++pos) { IntVar* const boolvar = watchers_[pos]; if (boolvar != nullptr) { @@ -1294,7 +1299,7 @@ class DomainIntVar : public IntVar { visitor->BeginVisitConstraint(ModelVisitor::kVarBoundWatcher, this); visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument, variable_); - std::vector all_coefficients; + std::vector all_coefficients; std::vector all_bool_vars; for (int position = 0; position < watchers_.size(); ++position) { if (watchers_[position] != nullptr) { @@ -1318,32 +1323,32 @@ class DomainIntVar : public IntVar { DomainIntVar* const variable_; RevSwitch posted_; Demon* var_demon_; - const int64 offset_; + const int64_t offset_; std::vector watchers_; NumericalRev active_watchers_; }; // ----- Main Class ----- - DomainIntVar(Solver* const s, int64 vmin, int64 vmax, + DomainIntVar(Solver* const s, int64_t vmin, int64_t vmax, const std::string& name); - DomainIntVar(Solver* const s, const std::vector& sorted_values, + DomainIntVar(Solver* const s, const std::vector& sorted_values, const std::string& name); ~DomainIntVar() override; - int64 Min() const override { return min_.Value(); } - void SetMin(int64 m) override; - int64 Max() const override { return max_.Value(); } - void SetMax(int64 m) override; - void SetRange(int64 mi, int64 ma) override; - void SetValue(int64 v) override; + int64_t Min() const override { return min_.Value(); } + void SetMin(int64_t m) override; + int64_t Max() const override { return max_.Value(); } + void SetMax(int64_t m) override; + void SetRange(int64_t mi, int64_t ma) override; + void SetValue(int64_t v) override; bool Bound() const override { return (min_.Value() == max_.Value()); } - int64 Value() const override { + int64_t Value() const override { CHECK_EQ(min_.Value(), max_.Value()) << " variable " << DebugString() << " is not bound."; return min_.Value(); } - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; void CreateBits(); void WhenBound(Demon* d) override { if (min_.Value() != max_.Value()) { @@ -1376,7 +1381,7 @@ class DomainIntVar : public IntVar { } } - IntVar* IsEqual(int64 constant) override { + IntVar* IsEqual(int64_t constant) override { Solver* const s = solver(); if (constant == min_.Value() && value_watcher_ == nullptr) { return s->MakeIsLessOrEqualCstVar(this, constant); @@ -1385,10 +1390,10 @@ class DomainIntVar : public IntVar { return s->MakeIsGreaterOrEqualCstVar(this, constant); } if (!Contains(constant)) { - return s->MakeIntConst(int64{0}); + return s->MakeIntConst(int64_t{0}); } if (Bound() && min_.Value() == constant) { - return s->MakeIntConst(int64{1}); + return s->MakeIntConst(int64_t{1}); } IntExpr* const cache = s->Cache()->FindExprConstantExpression( this, constant, ModelCache::EXPR_CONSTANT_IS_EQUAL); @@ -1416,7 +1421,7 @@ class DomainIntVar : public IntVar { } } - Constraint* SetIsEqual(const std::vector& values, + Constraint* SetIsEqual(const std::vector& values, const std::vector& vars) { if (value_watcher_ == nullptr) { solver()->SaveAndSetValue(reinterpret_cast(&value_watcher_), @@ -1429,7 +1434,7 @@ class DomainIntVar : public IntVar { return value_watcher_; } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { Solver* const s = solver(); if (constant == min_.Value() && value_watcher_ == nullptr) { return s->MakeIsGreaterOrEqualCstVar(this, constant + 1); @@ -1438,10 +1443,10 @@ class DomainIntVar : public IntVar { return s->MakeIsLessOrEqualCstVar(this, constant - 1); } if (!Contains(constant)) { - return s->MakeIntConst(int64{1}); + return s->MakeIntConst(int64_t{1}); } if (Bound() && min_.Value() == constant) { - return s->MakeIntConst(int64{0}); + return s->MakeIntConst(int64_t{0}); } IntExpr* const cache = s->Cache()->FindExprConstantExpression( this, constant, ModelCache::EXPR_CONSTANT_IS_NOT_EQUAL); @@ -1455,13 +1460,13 @@ class DomainIntVar : public IntVar { } } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { Solver* const s = solver(); if (max_.Value() < constant) { - return s->MakeIntConst(int64{0}); + return s->MakeIntConst(int64_t{0}); } if (min_.Value() >= constant) { - return s->MakeIntConst(int64{1}); + return s->MakeIntConst(int64_t{1}); } IntExpr* const cache = s->Cache()->FindExprConstantExpression( this, constant, ModelCache::EXPR_CONSTANT_IS_GREATER_OR_EQUAL); @@ -1492,7 +1497,7 @@ class DomainIntVar : public IntVar { } } - Constraint* SetIsGreaterOrEqual(const std::vector& values, + Constraint* SetIsGreaterOrEqual(const std::vector& values, const std::vector& vars) { if (bound_watcher_ == nullptr) { if (CapSub(Max(), Min()) <= 256) { @@ -1514,7 +1519,7 @@ class DomainIntVar : public IntVar { return bound_watcher_; } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { Solver* const s = solver(); IntExpr* const cache = s->Cache()->FindExprConstantExpression( this, constant, ModelCache::EXPR_CONSTANT_IS_LESS_OR_EQUAL); @@ -1532,19 +1537,19 @@ class DomainIntVar : public IntVar { void Process(); void Push(); void CleanInProcess(); - uint64 Size() const override { + uint64_t Size() const override { if (bits_ != nullptr) return bits_->Size(); - return (static_cast(max_.Value()) - - static_cast(min_.Value()) + 1); + return (static_cast(max_.Value()) - + static_cast(min_.Value()) + 1); } - bool Contains(int64 v) const override { + bool Contains(int64_t v) const override { if (v < min_.Value() || v > max_.Value()) return false; return (bits_ == nullptr ? true : bits_->Contains(v)); } IntVarIterator* MakeHoleIterator(bool reversible) const override; IntVarIterator* MakeDomainIterator(bool reversible) const override; - int64 OldMin() const override { return std::min(old_min_, min_.Value()); } - int64 OldMax() const override { return std::max(old_max_, max_.Value()); } + int64_t OldMin() const override { return std::min(old_min_, min_.Value()); } + int64_t OldMax() const override { return std::max(old_max_, max_.Value()); } std::string DebugString() const override; BitSet* bitset() const { return bits_; } @@ -1565,12 +1570,12 @@ class DomainIntVar : public IntVar { old_max_ = max_.Value(); } } - Rev min_; - Rev max_; - int64 old_min_; - int64 old_max_; - int64 new_min_; - int64 new_max_; + Rev min_; + Rev max_; + int64_t old_min_; + int64_t old_max_; + int64_t new_min_; + int64_t new_max_; SimpleRevFIFO bound_demons_; SimpleRevFIFO range_demons_; SimpleRevFIFO domain_demons_; @@ -1590,7 +1595,7 @@ class DomainIntVar : public IntVar { // K values, i.e. b - a < K, in a way that's robust to overflows. // For performance reasons, in opt mode it doesn't check that [a, b] is a // valid interval, nor that K is nonnegative. -inline bool ClosedIntervalNoLargerThan(int64 a, int64 b, int64 K) { +inline bool ClosedIntervalNoLargerThan(int64_t a, int64_t b, int64_t K) { DCHECK_LE(a, b); DCHECK_GE(K, 0); if (a > 0) { @@ -1602,7 +1607,7 @@ inline bool ClosedIntervalNoLargerThan(int64 a, int64 b, int64 K) { class SimpleBitSet : public DomainIntVar::BitSet { public: - SimpleBitSet(Solver* const s, int64 vmin, int64 vmax) + SimpleBitSet(Solver* const s, int64_t vmin, int64_t vmax) : BitSet(s), bits_(nullptr), stamps_(nullptr), @@ -1612,8 +1617,8 @@ class SimpleBitSet : public DomainIntVar::BitSet { bsize_(BitLength64(size_.Value())) { CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF)) << "Bitset too large: [" << vmin << ", " << vmax << "]"; - bits_ = new uint64[bsize_]; - stamps_ = new uint64[bsize_]; + bits_ = new uint64_t[bsize_]; + stamps_ = new uint64_t[bsize_]; for (int i = 0; i < bsize_; ++i) { const int bs = (i == size_.Value() - 1) ? 63 - BitPos64(size_.Value()) : 0; @@ -1622,8 +1627,8 @@ class SimpleBitSet : public DomainIntVar::BitSet { } } - SimpleBitSet(Solver* const s, const std::vector& sorted_values, - int64 vmin, int64 vmax) + SimpleBitSet(Solver* const s, const std::vector& sorted_values, + int64_t vmin, int64_t vmax) : BitSet(s), bits_(nullptr), stamps_(nullptr), @@ -1633,14 +1638,14 @@ class SimpleBitSet : public DomainIntVar::BitSet { bsize_(BitLength64(vmax - vmin + 1)) { CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF)) << "Bitset too large: [" << vmin << ", " << vmax << "]"; - bits_ = new uint64[bsize_]; - stamps_ = new uint64[bsize_]; + bits_ = new uint64_t[bsize_]; + stamps_ = new uint64_t[bsize_]; for (int i = 0; i < bsize_; ++i) { bits_[i] = uint64_t{0}; stamps_[i] = s->stamp() - 1; } for (int i = 0; i < sorted_values.size(); ++i) { - const int64 val = sorted_values[i]; + const int64_t val = sorted_values[i]; DCHECK(!bit(val)); const int offset = BitOffset64(val - omin_); const int pos = BitPos64(val - omin_); @@ -1653,39 +1658,39 @@ class SimpleBitSet : public DomainIntVar::BitSet { delete[] stamps_; } - bool bit(int64 val) const { return IsBitSet64(bits_, val - omin_); } + bool bit(int64_t val) const { return IsBitSet64(bits_, val - omin_); } - int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) override { + int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax) override { DCHECK_GE(nmin, cmin); DCHECK_LE(nmin, cmax); DCHECK_LE(cmin, cmax); DCHECK_GE(cmin, omin_); DCHECK_LE(cmax, omax_); - const int64 new_min = + const int64_t new_min = UnsafeLeastSignificantBitPosition64(bits_, nmin - omin_, cmax - omin_) + omin_; - const uint64 removed_bits = + const uint64_t removed_bits = BitCountRange64(bits_, cmin - omin_, new_min - omin_ - 1); size_.Add(solver_, -removed_bits); return new_min; } - int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) override { + int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax) override { DCHECK_GE(nmax, cmin); DCHECK_LE(nmax, cmax); DCHECK_LE(cmin, cmax); DCHECK_GE(cmin, omin_); DCHECK_LE(cmax, omax_); - const int64 new_max = + const int64_t new_max = UnsafeMostSignificantBitPosition64(bits_, cmin - omin_, nmax - omin_) + omin_; - const uint64 removed_bits = + const uint64_t removed_bits = BitCountRange64(bits_, new_max - omin_ + 1, cmax - omin_); size_.Add(solver_, -removed_bits); return new_max; } - bool SetValue(int64 val) override { + bool SetValue(int64_t val) override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); if (bit(val)) { @@ -1695,20 +1700,20 @@ class SimpleBitSet : public DomainIntVar::BitSet { return false; } - bool Contains(int64 val) const override { + bool Contains(int64_t val) const override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); return bit(val); } - bool RemoveValue(int64 val) override { + bool RemoveValue(int64_t val) override { if (val < omin_ || val > omax_ || !bit(val)) { return false; } // Bitset. - const int64 val_offset = val - omin_; + const int64_t val_offset = val - omin_; const int offset = BitOffset64(val_offset); - const uint64 current_stamp = solver_->stamp(); + const uint64_t current_stamp = solver_->stamp(); if (stamps_[offset] < current_stamp) { stamps_[offset] = current_stamp; solver_->SaveValue(&bits_[offset]); @@ -1722,7 +1727,7 @@ class SimpleBitSet : public DomainIntVar::BitSet { AddHole(val); return true; } - uint64 Size() const override { return size_.Value(); } + uint64_t Size() const override { return size_.Value(); } std::string DebugString() const override { std::string out; @@ -1734,11 +1739,11 @@ class SimpleBitSet : public DomainIntVar::BitSet { return out; } - void DelayRemoveValue(int64 val) override { removed_.push_back(val); } + void DelayRemoveValue(int64_t val) override { removed_.push_back(val); } void ApplyRemovedValues(DomainIntVar* var) override { std::sort(removed_.begin(), removed_.end()); - for (std::vector::iterator it = removed_.begin(); + for (std::vector::iterator it = removed_.begin(); it != removed_.end(); ++it) { var->RemoveValue(*it); } @@ -1746,14 +1751,14 @@ class SimpleBitSet : public DomainIntVar::BitSet { void ClearRemovedValues() override { removed_.clear(); } - std::string pretty_DebugString(int64 min, int64 max) const override { + std::string pretty_DebugString(int64_t min, int64_t max) const override { std::string out; DCHECK(bit(min)); DCHECK(bit(max)); if (max != min) { int cumul = true; - int64 start_cumul = min; - for (int64 v = min + 1; v < max; ++v) { + int64_t start_cumul = min; + for (int64_t v = min + 1; v < max; ++v) { if (bit(v)) { if (!cumul) { cumul = true; @@ -1792,13 +1797,13 @@ class SimpleBitSet : public DomainIntVar::BitSet { } private: - uint64* bits_; - uint64* stamps_; - const int64 omin_; - const int64 omax_; - NumericalRev size_; + uint64_t* bits_; + uint64_t* stamps_; + const int64_t omin_; + const int64_t omax_; + NumericalRev size_; const int bsize_; - std::vector removed_; + std::vector removed_; }; // This is a special case where the bitset fits into one 64 bit integer. @@ -1806,7 +1811,7 @@ class SimpleBitSet : public DomainIntVar::BitSet { // Overflows are caught by the robust ClosedIntervalNoLargerThan() method. class SmallBitSet : public DomainIntVar::BitSet { public: - SmallBitSet(Solver* const s, int64 vmin, int64 vmax) + SmallBitSet(Solver* const s, int64_t vmin, int64_t vmax) : BitSet(s), bits_(uint64_t{0}), stamp_(s->stamp() - 1), @@ -1817,8 +1822,8 @@ class SmallBitSet : public DomainIntVar::BitSet { bits_ = OneRange64(0, size_.Value() - 1); } - SmallBitSet(Solver* const s, const std::vector& sorted_values, - int64 vmin, int64 vmax) + SmallBitSet(Solver* const s, const std::vector& sorted_values, + int64_t vmin, int64_t vmax) : BitSet(s), bits_(uint64_t{0}), stamp_(s->stamp() - 1), @@ -1828,7 +1833,7 @@ class SmallBitSet : public DomainIntVar::BitSet { CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin << ", " << vmax; // We know the array is sorted and does not contains duplicate values. for (int i = 0; i < sorted_values.size(); ++i) { - const int64 val = sorted_values[i]; + const int64_t val = sorted_values[i]; DCHECK_GE(val, vmin); DCHECK_LE(val, vmax); DCHECK(!IsBitSet64(&bits_, val - omin_)); @@ -1838,13 +1843,13 @@ class SmallBitSet : public DomainIntVar::BitSet { ~SmallBitSet() override {} - bool bit(int64 val) const { + bool bit(int64_t val) const { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); return (bits_ & OneBit64(val - omin_)) != 0; } - int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) override { + int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax) override { DCHECK_GE(nmin, cmin); DCHECK_LE(nmin, cmax); DCHECK_LE(cmin, cmax); @@ -1854,7 +1859,7 @@ class SmallBitSet : public DomainIntVar::BitSet { // But we use mask to look only at 'active' bits. // Create the mask and compute new bits - const uint64 new_bits = bits_ & OneRange64(nmin - omin_, cmax - omin_); + const uint64_t new_bits = bits_ & OneRange64(nmin - omin_, cmax - omin_); if (new_bits != uint64_t{0}) { // Compute new size and new min size_.SetValue(solver_, BitCount64(new_bits)); @@ -1864,11 +1869,11 @@ class SmallBitSet : public DomainIntVar::BitSet { return LeastSignificantBitPosition64(new_bits) + omin_; } else { // == 0 -> Fail() solver_->Fail(); - return kint64max; + return std::numeric_limits::max(); } } - int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) override { + int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax) override { DCHECK_GE(nmax, cmin); DCHECK_LE(nmax, cmax); DCHECK_LE(cmin, cmax); @@ -1878,7 +1883,7 @@ class SmallBitSet : public DomainIntVar::BitSet { // But we use mask to look only at 'active' bits. // Create the mask and compute new_bits - const uint64 new_bits = bits_ & OneRange64(cmin - omin_, nmax - omin_); + const uint64_t new_bits = bits_ & OneRange64(cmin - omin_, nmax - omin_); if (new_bits != uint64_t{0}) { // Compute new size and new min size_.SetValue(solver_, BitCount64(new_bits)); @@ -1888,11 +1893,11 @@ class SmallBitSet : public DomainIntVar::BitSet { return MostSignificantBitPosition64(new_bits) + omin_; } else { // == 0 -> Fail() solver_->Fail(); - return kint64min; + return std::numeric_limits::min(); } } - bool SetValue(int64 val) override { + bool SetValue(int64_t val) override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); // We do not clean the bits. We will use masks to ignore the bits @@ -1904,18 +1909,18 @@ class SmallBitSet : public DomainIntVar::BitSet { return false; } - bool Contains(int64 val) const override { + bool Contains(int64_t val) const override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); return bit(val); } - bool RemoveValue(int64 val) override { + bool RemoveValue(int64_t val) override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); if (bit(val)) { // Bitset. - const uint64 current_stamp = solver_->stamp(); + const uint64_t current_stamp = solver_->stamp(); if (stamp_ < current_stamp) { stamp_ = current_stamp; solver_->SaveValue(&bits_); @@ -1933,13 +1938,13 @@ class SmallBitSet : public DomainIntVar::BitSet { } } - uint64 Size() const override { return size_.Value(); } + uint64_t Size() const override { return size_.Value(); } std::string DebugString() const override { return absl::StrFormat("SmallBitSet(%d..%d : %llx)", omin_, omax_, bits_); } - void DelayRemoveValue(int64 val) override { + void DelayRemoveValue(int64_t val) override { DCHECK_GE(val, omin_); DCHECK_LE(val, omax_); removed_.push_back(val); @@ -1947,7 +1952,7 @@ class SmallBitSet : public DomainIntVar::BitSet { void ApplyRemovedValues(DomainIntVar* var) override { std::sort(removed_.begin(), removed_.end()); - for (std::vector::iterator it = removed_.begin(); + for (std::vector::iterator it = removed_.begin(); it != removed_.end(); ++it) { var->RemoveValue(*it); } @@ -1955,14 +1960,14 @@ class SmallBitSet : public DomainIntVar::BitSet { void ClearRemovedValues() override { removed_.clear(); } - std::string pretty_DebugString(int64 min, int64 max) const override { + std::string pretty_DebugString(int64_t min, int64_t max) const override { std::string out; DCHECK(bit(min)); DCHECK(bit(max)); if (max != min) { int cumul = true; - int64 start_cumul = min; - for (int64 v = min + 1; v < max; ++v) { + int64_t start_cumul = min; + for (int64_t v = min + 1; v < max; ++v) { if (bit(v)) { if (!cumul) { cumul = true; @@ -2001,12 +2006,12 @@ class SmallBitSet : public DomainIntVar::BitSet { } private: - uint64 bits_; - uint64 stamp_; - const int64 omin_; - const int64 omax_; - NumericalRev size_; - std::vector removed_; + uint64_t bits_; + uint64_t stamp_; + const int64_t omin_; + const int64_t omax_; + NumericalRev size_; + std::vector removed_; }; class EmptyIterator : public IntVarIterator { @@ -2014,7 +2019,7 @@ class EmptyIterator : public IntVarIterator { ~EmptyIterator() override {} void Init() override {} bool Ok() const override { return false; } - int64 Value() const override { + int64_t Value() const override { LOG(FATAL) << "Should not be called"; return 0LL; } @@ -2024,7 +2029,10 @@ class EmptyIterator : public IntVarIterator { class RangeIterator : public IntVarIterator { public: explicit RangeIterator(const IntVar* const var) - : var_(var), min_(kint64max), max_(kint64min), current_(-1) {} + : var_(var), + min_(std::numeric_limits::max()), + max_(std::numeric_limits::min()), + current_(-1) {} ~RangeIterator() override {} @@ -2036,15 +2044,15 @@ class RangeIterator : public IntVarIterator { bool Ok() const override { return current_ <= max_; } - int64 Value() const override { return current_; } + int64_t Value() const override { return current_; } void Next() override { current_++; } private: const IntVar* const var_; - int64 min_; - int64 max_; - int64 current_; + int64_t min_; + int64_t max_; + int64_t current_; }; class DomainIntVarHoleIterator : public IntVarIterator { @@ -2069,7 +2077,7 @@ class DomainIntVarHoleIterator : public IntVarIterator { bool Ok() const override { return index_ < size_; } - int64 Value() const override { + int64_t Value() const override { DCHECK(bits_ != nullptr); DCHECK(index_ < size_); return values_[index_]; @@ -2080,7 +2088,7 @@ class DomainIntVarHoleIterator : public IntVarIterator { private: const DomainIntVar* const var_; DomainIntVar::BitSet* bits_; - const int64* values_; + const int64_t* values_; int size_; int index_; }; @@ -2091,8 +2099,8 @@ class DomainIntVarDomainIterator : public IntVarIterator { bool reversible) : var_(v), bitset_iterator_(nullptr), - min_(kint64max), - max_(kint64min), + min_(std::numeric_limits::max()), + max_(std::numeric_limits::min()), current_(-1), reversible_(reversible) {} @@ -2137,7 +2145,7 @@ class DomainIntVarDomainIterator : public IntVarIterator { return bitset_iterator_ ? bitset_iterator_->Ok() : (current_ <= max_); } - int64 Value() const override { + int64_t Value() const override { return bitset_iterator_ ? bitset_iterator_->Value() : current_; } @@ -2152,9 +2160,9 @@ class DomainIntVarDomainIterator : public IntVarIterator { private: const DomainIntVar* const var_; DomainIntVar::BitSetIterator* bitset_iterator_; - int64 min_; - int64 max_; - int64 current_; + int64_t min_; + int64_t max_; + int64_t current_; const bool reversible_; }; @@ -2182,7 +2190,7 @@ class UnaryIterator : public IntVarIterator { const bool reversible_; }; -DomainIntVar::DomainIntVar(Solver* const s, int64 vmin, int64 vmax, +DomainIntVar::DomainIntVar(Solver* const s, int64_t vmin, int64_t vmax, const std::string& name) : IntVar(s, name), min_(vmin), @@ -2198,15 +2206,15 @@ DomainIntVar::DomainIntVar(Solver* const s, int64 vmin, int64 vmax, bound_watcher_(nullptr) {} DomainIntVar::DomainIntVar(Solver* const s, - const std::vector& sorted_values, + const std::vector& sorted_values, const std::string& name) : IntVar(s, name), - min_(kint64max), - max_(kint64min), - old_min_(kint64max), - old_max_(kint64min), - new_min_(kint64max), - new_max_(kint64min), + min_(std::numeric_limits::max()), + max_(std::numeric_limits::min()), + old_min_(std::numeric_limits::max()), + old_max_(std::numeric_limits::min()), + new_min_(std::numeric_limits::max()), + new_max_(std::numeric_limits::min()), handler_(this), in_process_(false), bits_(nullptr), @@ -2214,8 +2222,8 @@ DomainIntVar::DomainIntVar(Solver* const s, bound_watcher_(nullptr) { CHECK_GE(sorted_values.size(), 1); // We know that the vector is sorted and does not have duplicate values. - const int64 vmin = sorted_values.front(); - const int64 vmax = sorted_values.back(); + const int64_t vmin = sorted_values.front(); + const int64_t vmax = sorted_values.back(); const bool contiguous = vmax - vmin + 1 == sorted_values.size(); min_.SetValue(solver(), vmin); @@ -2238,7 +2246,7 @@ DomainIntVar::DomainIntVar(Solver* const s, DomainIntVar::~DomainIntVar() {} -void DomainIntVar::SetMin(int64 m) { +void DomainIntVar::SetMin(int64_t m) { if (m <= min_.Value()) return; if (m > max_.Value()) solver()->Fail(); if (in_process_) { @@ -2250,7 +2258,7 @@ void DomainIntVar::SetMin(int64 m) { } } else { CheckOldMin(); - const int64 new_min = + const int64_t new_min = (bits_ == nullptr ? m : bits_->ComputeNewMin(m, min_.Value(), max_.Value())); @@ -2262,7 +2270,7 @@ void DomainIntVar::SetMin(int64 m) { } } -void DomainIntVar::SetMax(int64 m) { +void DomainIntVar::SetMax(int64_t m) { if (m >= max_.Value()) return; if (m < min_.Value()) solver()->Fail(); if (in_process_) { @@ -2274,7 +2282,7 @@ void DomainIntVar::SetMax(int64 m) { } } else { CheckOldMax(); - const int64 new_max = + const int64_t new_max = (bits_ == nullptr ? m : bits_->ComputeNewMax(m, min_.Value(), max_.Value())); @@ -2286,7 +2294,7 @@ void DomainIntVar::SetMax(int64 m) { } } -void DomainIntVar::SetRange(int64 mi, int64 ma) { +void DomainIntVar::SetRange(int64_t mi, int64_t ma) { if (mi == ma) { SetValue(mi); } else { @@ -2305,7 +2313,7 @@ void DomainIntVar::SetRange(int64 mi, int64 ma) { } else { if (mi > min_.Value()) { CheckOldMin(); - const int64 new_min = + const int64_t new_min = (bits_ == nullptr ? mi : bits_->ComputeNewMin(mi, min_.Value(), max_.Value())); @@ -2316,7 +2324,7 @@ void DomainIntVar::SetRange(int64 mi, int64 ma) { } if (ma < max_.Value()) { CheckOldMax(); - const int64 new_max = + const int64_t new_max = (bits_ == nullptr ? ma : bits_->ComputeNewMax(ma, min_.Value(), max_.Value())); @@ -2330,7 +2338,7 @@ void DomainIntVar::SetRange(int64 mi, int64 ma) { } } -void DomainIntVar::SetValue(int64 v) { +void DomainIntVar::SetValue(int64_t v) { if (v != min_.Value() || v != max_.Value()) { if (v < min_.Value() || v > max_.Value()) { solver()->Fail(); @@ -2354,7 +2362,7 @@ void DomainIntVar::SetValue(int64 v) { } } -void DomainIntVar::RemoveValue(int64 v) { +void DomainIntVar::RemoveValue(int64_t v) { if (v < min_.Value() || v > max_.Value()) return; if (v == min_.Value()) { SetMin(v + 1); @@ -2376,13 +2384,13 @@ void DomainIntVar::RemoveValue(int64 v) { } } -void DomainIntVar::RemoveInterval(int64 l, int64 u) { +void DomainIntVar::RemoveInterval(int64_t l, int64_t u) { if (l <= min_.Value()) { SetMin(u + 1); } else if (u >= max_.Value()) { SetMax(l - 1); } else { - for (int64 v = l; v <= u; ++v) { + for (int64_t v = l; v <= u; ++v) { RemoveValue(v); } } @@ -2518,7 +2526,7 @@ class ConcreteBooleanVar : public BooleanVar { ~ConcreteBooleanVar() override {} - void SetValue(int64 v) override { + void SetValue(int64_t v) override { if (value_ == kUnboundBooleanVarValue) { if ((v & 0xfffffffffffffffe) == 0) { InternalSaveBooleanVarValue(solver(), this); @@ -2541,8 +2549,8 @@ class ConcreteBooleanVar : public BooleanVar { } } - int64 OldMin() const override { return 0LL; } - int64 OldMax() const override { return 1LL; } + int64_t OldMin() const override { return 0LL; } + int64_t OldMax() const override { return 1LL; } void RestoreValue() override { value_ = kUnboundBooleanVarValue; } private: @@ -2553,40 +2561,40 @@ class ConcreteBooleanVar : public BooleanVar { class IntConst : public IntVar { public: - IntConst(Solver* const s, int64 value, const std::string& name = "") + IntConst(Solver* const s, int64_t value, const std::string& name = "") : IntVar(s, name), value_(value) {} ~IntConst() override {} - int64 Min() const override { return value_; } - void SetMin(int64 m) override { + int64_t Min() const override { return value_; } + void SetMin(int64_t m) override { if (m > value_) { solver()->Fail(); } } - int64 Max() const override { return value_; } - void SetMax(int64 m) override { + int64_t Max() const override { return value_; } + void SetMax(int64_t m) override { if (m < value_) { solver()->Fail(); } } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { if (l > value_ || u < value_) { solver()->Fail(); } } - void SetValue(int64 v) override { + void SetValue(int64_t v) override { if (v != value_) { solver()->Fail(); } } bool Bound() const override { return true; } - int64 Value() const override { return value_; } - void RemoveValue(int64 v) override { + int64_t Value() const override { return value_; } + void RemoveValue(int64_t v) override { if (v == value_) { solver()->Fail(); } } - void RemoveInterval(int64 l, int64 u) override { + void RemoveInterval(int64_t l, int64_t u) override { if (l <= value_ && value_ <= u) { solver()->Fail(); } @@ -2594,16 +2602,16 @@ class IntConst : public IntVar { void WhenBound(Demon* d) override {} void WhenRange(Demon* d) override {} void WhenDomain(Demon* d) override {} - uint64 Size() const override { return 1; } - bool Contains(int64 v) const override { return (v == value_); } + uint64_t Size() const override { return 1; } + bool Contains(int64_t v) const override { return (v == value_); } IntVarIterator* MakeHoleIterator(bool reversible) const override { return COND_REV_ALLOC(reversible, new EmptyIterator()); } IntVarIterator* MakeDomainIterator(bool reversible) const override { return COND_REV_ALLOC(reversible, new RangeIterator(this)); } - int64 OldMin() const override { return value_; } - int64 OldMax() const override { return value_; } + int64_t OldMin() const override { return value_; } + int64_t OldMax() const override { return value_; } std::string DebugString() const override { std::string out; if (solver()->HasName(this)) { @@ -2617,7 +2625,7 @@ class IntConst : public IntVar { int VarType() const override { return CONST_VAR; } - IntVar* IsEqual(int64 constant) override { + IntVar* IsEqual(int64_t constant) override { if (constant == value_) { return solver()->MakeIntConst(1); } else { @@ -2625,7 +2633,7 @@ class IntConst : public IntVar { } } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { if (constant == value_) { return solver()->MakeIntConst(0); } else { @@ -2633,11 +2641,11 @@ class IntConst : public IntVar { } } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { return solver()->MakeIntConst(value_ >= constant); } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { return solver()->MakeIntConst(value_ <= constant); } @@ -2650,14 +2658,14 @@ class IntConst : public IntVar { } private: - int64 value_; + int64_t value_; }; // ----- x + c variable, optimized case ----- class PlusCstVar : public IntVar { public: - PlusCstVar(Solver* const s, IntVar* v, int64 c) + PlusCstVar(Solver* const s, IntVar* v, int64_t c) : IntVar(s), var_(v), cst_(c) {} ~PlusCstVar() override {} @@ -2668,9 +2676,9 @@ class PlusCstVar : public IntVar { void WhenDomain(Demon* d) override { var_->WhenDomain(d); } - int64 OldMin() const override { return CapAdd(var_->OldMin(), cst_); } + int64_t OldMin() const override { return CapAdd(var_->OldMin(), cst_); } - int64 OldMax() const override { return CapAdd(var_->OldMax(), cst_); } + int64_t OldMax() const override { return CapAdd(var_->OldMax(), cst_); } std::string DebugString() const override { if (HasName()) { @@ -2687,77 +2695,77 @@ class PlusCstVar : public IntVar { var_); } - IntVar* IsEqual(int64 constant) override { + IntVar* IsEqual(int64_t constant) override { return var_->IsEqual(constant - cst_); } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { return var_->IsDifferent(constant - cst_); } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { return var_->IsGreaterOrEqual(constant - cst_); } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { return var_->IsLessOrEqual(constant - cst_); } IntVar* SubVar() const { return var_; } - int64 Constant() const { return cst_; } + int64_t Constant() const { return cst_; } protected: IntVar* const var_; - const int64 cst_; + const int64_t cst_; }; class PlusCstIntVar : public PlusCstVar { public: class PlusCstIntVarIterator : public UnaryIterator { public: - PlusCstIntVarIterator(const IntVar* const v, int64 c, bool hole, bool rev) + PlusCstIntVarIterator(const IntVar* const v, int64_t c, bool hole, bool rev) : UnaryIterator(v, hole, rev), cst_(c) {} ~PlusCstIntVarIterator() override {} - int64 Value() const override { return iterator_->Value() + cst_; } + int64_t Value() const override { return iterator_->Value() + cst_; } private: - const int64 cst_; + const int64_t cst_; }; - PlusCstIntVar(Solver* const s, IntVar* v, int64 c) : PlusCstVar(s, v, c) {} + PlusCstIntVar(Solver* const s, IntVar* v, int64_t c) : PlusCstVar(s, v, c) {} ~PlusCstIntVar() override {} - int64 Min() const override { return var_->Min() + cst_; } + int64_t Min() const override { return var_->Min() + cst_; } - void SetMin(int64 m) override { var_->SetMin(CapSub(m, cst_)); } + void SetMin(int64_t m) override { var_->SetMin(CapSub(m, cst_)); } - int64 Max() const override { return var_->Max() + cst_; } + int64_t Max() const override { return var_->Max() + cst_; } - void SetMax(int64 m) override { var_->SetMax(CapSub(m, cst_)); } + void SetMax(int64_t m) override { var_->SetMax(CapSub(m, cst_)); } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { var_->SetRange(CapSub(l, cst_), CapSub(u, cst_)); } - void SetValue(int64 v) override { var_->SetValue(v - cst_); } + void SetValue(int64_t v) override { var_->SetValue(v - cst_); } - int64 Value() const override { return var_->Value() + cst_; } + int64_t Value() const override { return var_->Value() + cst_; } bool Bound() const override { return var_->Bound(); } - void RemoveValue(int64 v) override { var_->RemoveValue(v - cst_); } + void RemoveValue(int64_t v) override { var_->RemoveValue(v - cst_); } - void RemoveInterval(int64 l, int64 u) override { + void RemoveInterval(int64_t l, int64_t u) override { var_->RemoveInterval(l - cst_, u - cst_); } - uint64 Size() const override { return var_->Size(); } + uint64_t Size() const override { return var_->Size(); } - bool Contains(int64 v) const override { return var_->Contains(v - cst_); } + bool Contains(int64_t v) const override { return var_->Contains(v - cst_); } IntVarIterator* MakeHoleIterator(bool reversible) const override { return COND_REV_ALLOC( @@ -2773,35 +2781,35 @@ class PlusCstDomainIntVar : public PlusCstVar { public: class PlusCstDomainIntVarIterator : public UnaryIterator { public: - PlusCstDomainIntVarIterator(const IntVar* const v, int64 c, bool hole, + PlusCstDomainIntVarIterator(const IntVar* const v, int64_t c, bool hole, bool reversible) : UnaryIterator(v, hole, reversible), cst_(c) {} ~PlusCstDomainIntVarIterator() override {} - int64 Value() const override { return iterator_->Value() + cst_; } + int64_t Value() const override { return iterator_->Value() + cst_; } private: - const int64 cst_; + const int64_t cst_; }; - PlusCstDomainIntVar(Solver* const s, DomainIntVar* v, int64 c) + PlusCstDomainIntVar(Solver* const s, DomainIntVar* v, int64_t c) : PlusCstVar(s, v, c) {} ~PlusCstDomainIntVar() override {} - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; DomainIntVar* domain_int_var() const { return reinterpret_cast(var_); @@ -2817,27 +2825,27 @@ class PlusCstDomainIntVar : public PlusCstVar { } }; -int64 PlusCstDomainIntVar::Min() const { +int64_t PlusCstDomainIntVar::Min() const { return domain_int_var()->min_.Value() + cst_; } -void PlusCstDomainIntVar::SetMin(int64 m) { +void PlusCstDomainIntVar::SetMin(int64_t m) { domain_int_var()->DomainIntVar::SetMin(m - cst_); } -int64 PlusCstDomainIntVar::Max() const { +int64_t PlusCstDomainIntVar::Max() const { return domain_int_var()->max_.Value() + cst_; } -void PlusCstDomainIntVar::SetMax(int64 m) { +void PlusCstDomainIntVar::SetMax(int64_t m) { domain_int_var()->DomainIntVar::SetMax(m - cst_); } -void PlusCstDomainIntVar::SetRange(int64 l, int64 u) { +void PlusCstDomainIntVar::SetRange(int64_t l, int64_t u) { domain_int_var()->DomainIntVar::SetRange(l - cst_, u - cst_); } -void PlusCstDomainIntVar::SetValue(int64 v) { +void PlusCstDomainIntVar::SetValue(int64_t v) { domain_int_var()->DomainIntVar::SetValue(v - cst_); } @@ -2845,25 +2853,25 @@ bool PlusCstDomainIntVar::Bound() const { return domain_int_var()->min_.Value() == domain_int_var()->max_.Value(); } -int64 PlusCstDomainIntVar::Value() const { +int64_t PlusCstDomainIntVar::Value() const { CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value()) << " variable is not bound"; return domain_int_var()->min_.Value() + cst_; } -void PlusCstDomainIntVar::RemoveValue(int64 v) { +void PlusCstDomainIntVar::RemoveValue(int64_t v) { domain_int_var()->DomainIntVar::RemoveValue(v - cst_); } -void PlusCstDomainIntVar::RemoveInterval(int64 l, int64 u) { +void PlusCstDomainIntVar::RemoveInterval(int64_t l, int64_t u) { domain_int_var()->DomainIntVar::RemoveInterval(l - cst_, u - cst_); } -uint64 PlusCstDomainIntVar::Size() const { +uint64_t PlusCstDomainIntVar::Size() const { return domain_int_var()->DomainIntVar::Size(); } -bool PlusCstDomainIntVar::Contains(int64 v) const { +bool PlusCstDomainIntVar::Contains(int64_t v) const { return domain_int_var()->DomainIntVar::Contains(v - cst_); } @@ -2873,31 +2881,31 @@ class SubCstIntVar : public IntVar { public: class SubCstIntVarIterator : public UnaryIterator { public: - SubCstIntVarIterator(const IntVar* const v, int64 c, bool hole, bool rev) + SubCstIntVarIterator(const IntVar* const v, int64_t c, bool hole, bool rev) : UnaryIterator(v, hole, rev), cst_(c) {} ~SubCstIntVarIterator() override {} - int64 Value() const override { return cst_ - iterator_->Value(); } + int64_t Value() const override { return cst_ - iterator_->Value(); } private: - const int64 cst_; + const int64_t cst_; }; - SubCstIntVar(Solver* const s, IntVar* v, int64 c); + SubCstIntVar(Solver* const s, IntVar* v, int64_t c); ~SubCstIntVar() override; - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; void WhenRange(Demon* d) override; void WhenBound(Demon* d) override; void WhenDomain(Demon* d) override; @@ -2909,8 +2917,8 @@ class SubCstIntVar : public IntVar { return COND_REV_ALLOC( reversible, new SubCstIntVarIterator(var_, cst_, false, reversible)); } - int64 OldMin() const override { return CapSub(cst_, var_->OldMax()); } - int64 OldMax() const override { return CapSub(cst_, var_->OldMin()); } + int64_t OldMin() const override { return CapSub(cst_, var_->OldMax()); } + int64_t OldMax() const override { return CapSub(cst_, var_->OldMin()); } std::string DebugString() const override; std::string name() const override; int VarType() const override { return CST_SUB_VAR; } @@ -2920,58 +2928,58 @@ class SubCstIntVar : public IntVar { cst_, var_); } - IntVar* IsEqual(int64 constant) override { + IntVar* IsEqual(int64_t constant) override { return var_->IsEqual(cst_ - constant); } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { return var_->IsDifferent(cst_ - constant); } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { return var_->IsLessOrEqual(cst_ - constant); } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { return var_->IsGreaterOrEqual(cst_ - constant); } IntVar* SubVar() const { return var_; } - int64 Constant() const { return cst_; } + int64_t Constant() const { return cst_; } private: IntVar* const var_; - const int64 cst_; + const int64_t cst_; }; -SubCstIntVar::SubCstIntVar(Solver* const s, IntVar* v, int64 c) +SubCstIntVar::SubCstIntVar(Solver* const s, IntVar* v, int64_t c) : IntVar(s), var_(v), cst_(c) {} SubCstIntVar::~SubCstIntVar() {} -int64 SubCstIntVar::Min() const { return cst_ - var_->Max(); } +int64_t SubCstIntVar::Min() const { return cst_ - var_->Max(); } -void SubCstIntVar::SetMin(int64 m) { var_->SetMax(CapSub(cst_, m)); } +void SubCstIntVar::SetMin(int64_t m) { var_->SetMax(CapSub(cst_, m)); } -int64 SubCstIntVar::Max() const { return cst_ - var_->Min(); } +int64_t SubCstIntVar::Max() const { return cst_ - var_->Min(); } -void SubCstIntVar::SetMax(int64 m) { var_->SetMin(CapSub(cst_, m)); } +void SubCstIntVar::SetMax(int64_t m) { var_->SetMin(CapSub(cst_, m)); } -void SubCstIntVar::SetRange(int64 l, int64 u) { +void SubCstIntVar::SetRange(int64_t l, int64_t u) { var_->SetRange(CapSub(cst_, u), CapSub(cst_, l)); } -void SubCstIntVar::SetValue(int64 v) { var_->SetValue(cst_ - v); } +void SubCstIntVar::SetValue(int64_t v) { var_->SetValue(cst_ - v); } bool SubCstIntVar::Bound() const { return var_->Bound(); } void SubCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); } -int64 SubCstIntVar::Value() const { return cst_ - var_->Value(); } +int64_t SubCstIntVar::Value() const { return cst_ - var_->Value(); } -void SubCstIntVar::RemoveValue(int64 v) { var_->RemoveValue(cst_ - v); } +void SubCstIntVar::RemoveValue(int64_t v) { var_->RemoveValue(cst_ - v); } -void SubCstIntVar::RemoveInterval(int64 l, int64 u) { +void SubCstIntVar::RemoveInterval(int64_t l, int64_t u) { var_->RemoveInterval(cst_ - u, cst_ - l); } @@ -2979,9 +2987,11 @@ void SubCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); } void SubCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); } -uint64 SubCstIntVar::Size() const { return var_->Size(); } +uint64_t SubCstIntVar::Size() const { return var_->Size(); } -bool SubCstIntVar::Contains(int64 v) const { return var_->Contains(cst_ - v); } +bool SubCstIntVar::Contains(int64_t v) const { + return var_->Contains(cst_ - v); +} std::string SubCstIntVar::DebugString() const { if (cst_ == 1 && var_->VarType() == BOOLEAN_VAR) { @@ -3011,24 +3021,24 @@ class OppIntVar : public IntVar { : UnaryIterator(v, hole, reversible) {} ~OppIntVarIterator() override {} - int64 Value() const override { return -iterator_->Value(); } + int64_t Value() const override { return -iterator_->Value(); } }; OppIntVar(Solver* const s, IntVar* v); ~OppIntVar() override; - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; void WhenRange(Demon* d) override; void WhenBound(Demon* d) override; void WhenDomain(Demon* d) override; @@ -3040,8 +3050,8 @@ class OppIntVar : public IntVar { return COND_REV_ALLOC(reversible, new OppIntVarIterator(var_, false, reversible)); } - int64 OldMin() const override { return CapOpp(var_->OldMax()); } - int64 OldMax() const override { return CapOpp(var_->OldMin()); } + int64_t OldMin() const override { return CapOpp(var_->OldMax()); } + int64_t OldMax() const override { return CapOpp(var_->OldMin()); } std::string DebugString() const override; int VarType() const override { return OPP_VAR; } @@ -3050,17 +3060,19 @@ class OppIntVar : public IntVar { var_); } - IntVar* IsEqual(int64 constant) override { return var_->IsEqual(-constant); } + IntVar* IsEqual(int64_t constant) override { + return var_->IsEqual(-constant); + } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { return var_->IsDifferent(-constant); } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { return var_->IsLessOrEqual(-constant); } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { return var_->IsGreaterOrEqual(-constant); } @@ -3074,29 +3086,29 @@ OppIntVar::OppIntVar(Solver* const s, IntVar* v) : IntVar(s), var_(v) {} OppIntVar::~OppIntVar() {} -int64 OppIntVar::Min() const { return -var_->Max(); } +int64_t OppIntVar::Min() const { return -var_->Max(); } -void OppIntVar::SetMin(int64 m) { var_->SetMax(CapOpp(m)); } +void OppIntVar::SetMin(int64_t m) { var_->SetMax(CapOpp(m)); } -int64 OppIntVar::Max() const { return -var_->Min(); } +int64_t OppIntVar::Max() const { return -var_->Min(); } -void OppIntVar::SetMax(int64 m) { var_->SetMin(CapOpp(m)); } +void OppIntVar::SetMax(int64_t m) { var_->SetMin(CapOpp(m)); } -void OppIntVar::SetRange(int64 l, int64 u) { +void OppIntVar::SetRange(int64_t l, int64_t u) { var_->SetRange(CapOpp(u), CapOpp(l)); } -void OppIntVar::SetValue(int64 v) { var_->SetValue(CapOpp(v)); } +void OppIntVar::SetValue(int64_t v) { var_->SetValue(CapOpp(v)); } bool OppIntVar::Bound() const { return var_->Bound(); } void OppIntVar::WhenRange(Demon* d) { var_->WhenRange(d); } -int64 OppIntVar::Value() const { return -var_->Value(); } +int64_t OppIntVar::Value() const { return -var_->Value(); } -void OppIntVar::RemoveValue(int64 v) { var_->RemoveValue(-v); } +void OppIntVar::RemoveValue(int64_t v) { var_->RemoveValue(-v); } -void OppIntVar::RemoveInterval(int64 l, int64 u) { +void OppIntVar::RemoveInterval(int64_t l, int64_t u) { var_->RemoveInterval(-u, -l); } @@ -3104,9 +3116,9 @@ void OppIntVar::WhenBound(Demon* d) { var_->WhenBound(d); } void OppIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); } -uint64 OppIntVar::Size() const { return var_->Size(); } +uint64_t OppIntVar::Size() const { return var_->Size(); } -bool OppIntVar::Contains(int64 v) const { return var_->Contains(-v); } +bool OppIntVar::Contains(int64_t v) const { return var_->Contains(-v); } std::string OppIntVar::DebugString() const { return absl::StrFormat("-(%s)", var_->DebugString()); @@ -3118,19 +3130,19 @@ std::string OppIntVar::DebugString() const { class TimesCstIntVar : public IntVar { public: - TimesCstIntVar(Solver* const s, IntVar* v, int64 c) + TimesCstIntVar(Solver* const s, IntVar* v, int64_t c) : IntVar(s), var_(v), cst_(c) {} ~TimesCstIntVar() override {} IntVar* SubVar() const { return var_; } - int64 Constant() const { return cst_; } + int64_t Constant() const { return cst_; } void Accept(ModelVisitor* const visitor) const override { visitor->VisitIntegerVariable(this, ModelVisitor::kProductOperation, cst_, var_); } - IntVar* IsEqual(int64 constant) override { + IntVar* IsEqual(int64_t constant) override { if (constant % cst_ == 0) { return var_->IsEqual(constant / cst_); } else { @@ -3138,7 +3150,7 @@ class TimesCstIntVar : public IntVar { } } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { if (constant % cst_ == 0) { return var_->IsDifferent(constant / cst_); } else { @@ -3146,7 +3158,7 @@ class TimesCstIntVar : public IntVar { } } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { if (cst_ > 0) { return var_->IsGreaterOrEqual(PosIntDivUp(constant, cst_)); } else { @@ -3154,7 +3166,7 @@ class TimesCstIntVar : public IntVar { } } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { if (cst_ > 0) { return var_->IsLessOrEqual(PosIntDivDown(constant, cst_)); } else { @@ -3170,39 +3182,39 @@ class TimesCstIntVar : public IntVar { protected: IntVar* const var_; - const int64 cst_; + const int64_t cst_; }; class TimesPosCstIntVar : public TimesCstIntVar { public: class TimesPosCstIntVarIterator : public UnaryIterator { public: - TimesPosCstIntVarIterator(const IntVar* const v, int64 c, bool hole, + TimesPosCstIntVarIterator(const IntVar* const v, int64_t c, bool hole, bool reversible) : UnaryIterator(v, hole, reversible), cst_(c) {} ~TimesPosCstIntVarIterator() override {} - int64 Value() const override { return iterator_->Value() * cst_; } + int64_t Value() const override { return iterator_->Value() * cst_; } private: - const int64 cst_; + const int64_t cst_; }; - TimesPosCstIntVar(Solver* const s, IntVar* v, int64 c); + TimesPosCstIntVar(Solver* const s, IntVar* v, int64_t c); ~TimesPosCstIntVar() override; - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; void WhenRange(Demon* d) override; void WhenBound(Demon* d) override; void WhenDomain(Demon* d) override; @@ -3214,38 +3226,38 @@ class TimesPosCstIntVar : public TimesCstIntVar { return COND_REV_ALLOC(reversible, new TimesPosCstIntVarIterator( var_, cst_, false, reversible)); } - int64 OldMin() const override { return CapProd(var_->OldMin(), cst_); } - int64 OldMax() const override { return CapProd(var_->OldMax(), cst_); } + int64_t OldMin() const override { return CapProd(var_->OldMin(), cst_); } + int64_t OldMax() const override { return CapProd(var_->OldMax(), cst_); } }; // ----- TimesPosCstIntVar ----- -TimesPosCstIntVar::TimesPosCstIntVar(Solver* const s, IntVar* v, int64 c) +TimesPosCstIntVar::TimesPosCstIntVar(Solver* const s, IntVar* v, int64_t c) : TimesCstIntVar(s, v, c) {} TimesPosCstIntVar::~TimesPosCstIntVar() {} -int64 TimesPosCstIntVar::Min() const { return CapProd(var_->Min(), cst_); } +int64_t TimesPosCstIntVar::Min() const { return CapProd(var_->Min(), cst_); } -void TimesPosCstIntVar::SetMin(int64 m) { - if (m != kint64min) { +void TimesPosCstIntVar::SetMin(int64_t m) { + if (m != std::numeric_limits::min()) { var_->SetMin(PosIntDivUp(m, cst_)); } } -int64 TimesPosCstIntVar::Max() const { return CapProd(var_->Max(), cst_); } +int64_t TimesPosCstIntVar::Max() const { return CapProd(var_->Max(), cst_); } -void TimesPosCstIntVar::SetMax(int64 m) { - if (m != kint64max) { +void TimesPosCstIntVar::SetMax(int64_t m) { + if (m != std::numeric_limits::max()) { var_->SetMax(PosIntDivDown(m, cst_)); } } -void TimesPosCstIntVar::SetRange(int64 l, int64 u) { +void TimesPosCstIntVar::SetRange(int64_t l, int64_t u) { var_->SetRange(PosIntDivUp(l, cst_), PosIntDivDown(u, cst_)); } -void TimesPosCstIntVar::SetValue(int64 v) { +void TimesPosCstIntVar::SetValue(int64_t v) { if (v % cst_ != 0) { solver()->Fail(); } @@ -3256,16 +3268,18 @@ bool TimesPosCstIntVar::Bound() const { return var_->Bound(); } void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); } -int64 TimesPosCstIntVar::Value() const { return CapProd(var_->Value(), cst_); } +int64_t TimesPosCstIntVar::Value() const { + return CapProd(var_->Value(), cst_); +} -void TimesPosCstIntVar::RemoveValue(int64 v) { +void TimesPosCstIntVar::RemoveValue(int64_t v) { if (v % cst_ == 0) { var_->RemoveValue(v / cst_); } } -void TimesPosCstIntVar::RemoveInterval(int64 l, int64 u) { - for (int64 v = l; v <= u; ++v) { +void TimesPosCstIntVar::RemoveInterval(int64_t l, int64_t u) { + for (int64_t v = l; v <= u; ++v) { RemoveValue(v); } // TODO(user) : Improve me @@ -3275,9 +3289,9 @@ void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); } void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); } -uint64 TimesPosCstIntVar::Size() const { return var_->Size(); } +uint64_t TimesPosCstIntVar::Size() const { return var_->Size(); } -bool TimesPosCstIntVar::Contains(int64 v) const { +bool TimesPosCstIntVar::Contains(int64_t v) const { return (v % cst_ == 0 && var_->Contains(v / cst_)); } @@ -3288,32 +3302,32 @@ class TimesPosCstBoolVar : public TimesCstIntVar { class TimesPosCstBoolVarIterator : public UnaryIterator { public: // TODO(user) : optimize this. - TimesPosCstBoolVarIterator(const IntVar* const v, int64 c, bool hole, + TimesPosCstBoolVarIterator(const IntVar* const v, int64_t c, bool hole, bool reversible) : UnaryIterator(v, hole, reversible), cst_(c) {} ~TimesPosCstBoolVarIterator() override {} - int64 Value() const override { return iterator_->Value() * cst_; } + int64_t Value() const override { return iterator_->Value() * cst_; } private: - const int64 cst_; + const int64_t cst_; }; - TimesPosCstBoolVar(Solver* const s, BooleanVar* v, int64 c); + TimesPosCstBoolVar(Solver* const s, BooleanVar* v, int64_t c); ~TimesPosCstBoolVar() override; - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; void WhenRange(Demon* d) override; void WhenBound(Demon* d) override; void WhenDomain(Demon* d) override; @@ -3325,8 +3339,8 @@ class TimesPosCstBoolVar : public TimesCstIntVar { reversible, new TimesPosCstBoolVarIterator(boolean_var(), cst_, false, reversible)); } - int64 OldMin() const override { return 0; } - int64 OldMax() const override { return cst_; } + int64_t OldMin() const override { return 0; } + int64_t OldMax() const override { return cst_; } BooleanVar* boolean_var() const { return reinterpret_cast(var_); @@ -3335,16 +3349,17 @@ class TimesPosCstBoolVar : public TimesCstIntVar { // ----- TimesPosCstBoolVar ----- -TimesPosCstBoolVar::TimesPosCstBoolVar(Solver* const s, BooleanVar* v, int64 c) +TimesPosCstBoolVar::TimesPosCstBoolVar(Solver* const s, BooleanVar* v, + int64_t c) : TimesCstIntVar(s, v, c) {} TimesPosCstBoolVar::~TimesPosCstBoolVar() {} -int64 TimesPosCstBoolVar::Min() const { +int64_t TimesPosCstBoolVar::Min() const { return (boolean_var()->RawValue() == 1) * cst_; } -void TimesPosCstBoolVar::SetMin(int64 m) { +void TimesPosCstBoolVar::SetMin(int64_t m) { if (m > cst_) { solver()->Fail(); } else if (m > 0) { @@ -3352,11 +3367,11 @@ void TimesPosCstBoolVar::SetMin(int64 m) { } } -int64 TimesPosCstBoolVar::Max() const { +int64_t TimesPosCstBoolVar::Max() const { return (boolean_var()->RawValue() != 0) * cst_; } -void TimesPosCstBoolVar::SetMax(int64 m) { +void TimesPosCstBoolVar::SetMax(int64_t m) { if (m < 0) { solver()->Fail(); } else if (m < cst_) { @@ -3364,7 +3379,7 @@ void TimesPosCstBoolVar::SetMax(int64 m) { } } -void TimesPosCstBoolVar::SetRange(int64 l, int64 u) { +void TimesPosCstBoolVar::SetRange(int64_t l, int64_t u) { if (u < 0 || l > cst_ || l > u) { solver()->Fail(); } @@ -3375,7 +3390,7 @@ void TimesPosCstBoolVar::SetRange(int64 l, int64 u) { } } -void TimesPosCstBoolVar::SetValue(int64 v) { +void TimesPosCstBoolVar::SetValue(int64_t v) { if (v == 0) { boolean_var()->SetValue(0); } else if (v == cst_) { @@ -3391,13 +3406,13 @@ bool TimesPosCstBoolVar::Bound() const { void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); } -int64 TimesPosCstBoolVar::Value() const { +int64_t TimesPosCstBoolVar::Value() const { CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue) << " variable is not bound"; return boolean_var()->RawValue() * cst_; } -void TimesPosCstBoolVar::RemoveValue(int64 v) { +void TimesPosCstBoolVar::RemoveValue(int64_t v) { if (v == 0) { boolean_var()->RemoveValue(0); } else if (v == cst_) { @@ -3405,7 +3420,7 @@ void TimesPosCstBoolVar::RemoveValue(int64 v) { } } -void TimesPosCstBoolVar::RemoveInterval(int64 l, int64 u) { +void TimesPosCstBoolVar::RemoveInterval(int64_t l, int64_t u) { if (l <= 0 && u >= 0) { boolean_var()->RemoveValue(0); } @@ -3418,12 +3433,12 @@ void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); } void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); } -uint64 TimesPosCstBoolVar::Size() const { +uint64_t TimesPosCstBoolVar::Size() const { return (1 + (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue)); } -bool TimesPosCstBoolVar::Contains(int64 v) const { +bool TimesPosCstBoolVar::Contains(int64_t v) const { if (v == 0) { return boolean_var()->RawValue() != 1; } else if (v == cst_) { @@ -3438,32 +3453,32 @@ class TimesNegCstIntVar : public TimesCstIntVar { public: class TimesNegCstIntVarIterator : public UnaryIterator { public: - TimesNegCstIntVarIterator(const IntVar* const v, int64 c, bool hole, + TimesNegCstIntVarIterator(const IntVar* const v, int64_t c, bool hole, bool reversible) : UnaryIterator(v, hole, reversible), cst_(c) {} ~TimesNegCstIntVarIterator() override {} - int64 Value() const override { return iterator_->Value() * cst_; } + int64_t Value() const override { return iterator_->Value() * cst_; } private: - const int64 cst_; + const int64_t cst_; }; - TimesNegCstIntVar(Solver* const s, IntVar* v, int64 c); + TimesNegCstIntVar(Solver* const s, IntVar* v, int64_t c); ~TimesNegCstIntVar() override; - int64 Min() const override; - void SetMin(int64 m) override; - int64 Max() const override; - void SetMax(int64 m) override; - void SetRange(int64 l, int64 u) override; - void SetValue(int64 v) override; + int64_t Min() const override; + void SetMin(int64_t m) override; + int64_t Max() const override; + void SetMax(int64_t m) override; + void SetRange(int64_t l, int64_t u) override; + void SetValue(int64_t v) override; bool Bound() const override; - int64 Value() const override; - void RemoveValue(int64 v) override; - void RemoveInterval(int64 l, int64 u) override; - uint64 Size() const override; - bool Contains(int64 v) const override; + int64_t Value() const override; + void RemoveValue(int64_t v) override; + void RemoveInterval(int64_t l, int64_t u) override; + uint64_t Size() const override; + bool Contains(int64_t v) const override; void WhenRange(Demon* d) override; void WhenBound(Demon* d) override; void WhenDomain(Demon* d) override; @@ -3475,38 +3490,38 @@ class TimesNegCstIntVar : public TimesCstIntVar { return COND_REV_ALLOC(reversible, new TimesNegCstIntVarIterator( var_, cst_, false, reversible)); } - int64 OldMin() const override { return CapProd(var_->OldMax(), cst_); } - int64 OldMax() const override { return CapProd(var_->OldMin(), cst_); } + int64_t OldMin() const override { return CapProd(var_->OldMax(), cst_); } + int64_t OldMax() const override { return CapProd(var_->OldMin(), cst_); } }; // ----- TimesNegCstIntVar ----- -TimesNegCstIntVar::TimesNegCstIntVar(Solver* const s, IntVar* v, int64 c) +TimesNegCstIntVar::TimesNegCstIntVar(Solver* const s, IntVar* v, int64_t c) : TimesCstIntVar(s, v, c) {} TimesNegCstIntVar::~TimesNegCstIntVar() {} -int64 TimesNegCstIntVar::Min() const { return CapProd(var_->Max(), cst_); } +int64_t TimesNegCstIntVar::Min() const { return CapProd(var_->Max(), cst_); } -void TimesNegCstIntVar::SetMin(int64 m) { - if (m != kint64min) { +void TimesNegCstIntVar::SetMin(int64_t m) { + if (m != std::numeric_limits::min()) { var_->SetMax(PosIntDivDown(-m, -cst_)); } } -int64 TimesNegCstIntVar::Max() const { return CapProd(var_->Min(), cst_); } +int64_t TimesNegCstIntVar::Max() const { return CapProd(var_->Min(), cst_); } -void TimesNegCstIntVar::SetMax(int64 m) { - if (m != kint64max) { +void TimesNegCstIntVar::SetMax(int64_t m) { + if (m != std::numeric_limits::max()) { var_->SetMin(PosIntDivUp(-m, -cst_)); } } -void TimesNegCstIntVar::SetRange(int64 l, int64 u) { +void TimesNegCstIntVar::SetRange(int64_t l, int64_t u) { var_->SetRange(PosIntDivUp(-u, -cst_), PosIntDivDown(-l, -cst_)); } -void TimesNegCstIntVar::SetValue(int64 v) { +void TimesNegCstIntVar::SetValue(int64_t v) { if (v % cst_ != 0) { solver()->Fail(); } @@ -3517,16 +3532,18 @@ bool TimesNegCstIntVar::Bound() const { return var_->Bound(); } void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); } -int64 TimesNegCstIntVar::Value() const { return CapProd(var_->Value(), cst_); } +int64_t TimesNegCstIntVar::Value() const { + return CapProd(var_->Value(), cst_); +} -void TimesNegCstIntVar::RemoveValue(int64 v) { +void TimesNegCstIntVar::RemoveValue(int64_t v) { if (v % cst_ == 0) { var_->RemoveValue(v / cst_); } } -void TimesNegCstIntVar::RemoveInterval(int64 l, int64 u) { - for (int64 v = l; v <= u; ++v) { +void TimesNegCstIntVar::RemoveInterval(int64_t l, int64_t u) { + for (int64_t v = l; v <= u; ++v) { RemoveValue(v); } // TODO(user) : Improve me @@ -3536,9 +3553,9 @@ void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); } void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); } -uint64 TimesNegCstIntVar::Size() const { return var_->Size(); } +uint64_t TimesNegCstIntVar::Size() const { return var_->Size(); } -bool TimesNegCstIntVar::Contains(int64 v) const { +bool TimesNegCstIntVar::Contains(int64_t v) const { return (v % cst_ == 0 && var_->Contains(v / cst_)); } @@ -3553,20 +3570,20 @@ class PlusIntExpr : public BaseIntExpr { ~PlusIntExpr() override {} - int64 Min() const override { return left_->Min() + right_->Min(); } + int64_t Min() const override { return left_->Min() + right_->Min(); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > left_->Min() + right_->Min()) { left_->SetMin(m - right_->Max()); right_->SetMin(m - left_->Max()); } } - void SetRange(int64 l, int64 u) override { - const int64 left_min = left_->Min(); - const int64 right_min = right_->Min(); - const int64 left_max = left_->Max(); - const int64 right_max = right_->Max(); + void SetRange(int64_t l, int64_t u) override { + const int64_t left_min = left_->Min(); + const int64_t right_min = right_->Min(); + const int64_t left_max = left_->Max(); + const int64_t right_max = right_->Max(); if (l > left_min + right_min) { left_->SetMin(l - right_max); right_->SetMin(l - left_max); @@ -3577,9 +3594,9 @@ class PlusIntExpr : public BaseIntExpr { } } - int64 Max() const override { return left_->Max() + right_->Max(); } + int64_t Max() const override { return left_->Max() + right_->Max(); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < left_->Max() + right_->Max()) { left_->SetMax(m - right_->Min()); right_->SetMax(m - left_->Min()); @@ -3588,7 +3605,7 @@ class PlusIntExpr : public BaseIntExpr { bool Bound() const override { return (left_->Bound() && right_->Bound()); } - void Range(int64* const mi, int64* const ma) override { + void Range(int64_t* const mi, int64_t* const ma) override { *mi = left_->Min() + right_->Min(); *ma = left_->Max() + right_->Max(); } @@ -3654,18 +3671,18 @@ class SafePlusIntExpr : public BaseIntExpr { ~SafePlusIntExpr() override {} - int64 Min() const override { return CapAdd(left_->Min(), right_->Min()); } + int64_t Min() const override { return CapAdd(left_->Min(), right_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { left_->SetMin(CapSub(m, right_->Max())); right_->SetMin(CapSub(m, left_->Max())); } - void SetRange(int64 l, int64 u) override { - const int64 left_min = left_->Min(); - const int64 right_min = right_->Min(); - const int64 left_max = left_->Max(); - const int64 right_max = right_->Max(); + void SetRange(int64_t l, int64_t u) override { + const int64_t left_min = left_->Min(); + const int64_t right_min = right_->Min(); + const int64_t left_max = left_->Max(); + const int64_t right_max = right_->Max(); if (l > CapAdd(left_min, right_min)) { left_->SetMin(CapSub(l, right_max)); right_->SetMin(CapSub(l, left_max)); @@ -3676,9 +3693,9 @@ class SafePlusIntExpr : public BaseIntExpr { } } - int64 Max() const override { return CapAdd(left_->Max(), right_->Max()); } + int64_t Max() const override { return CapAdd(left_->Max(), right_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { left_->SetMax(CapSub(m, right_->Min())); right_->SetMax(CapSub(m, left_->Min())); } @@ -3716,13 +3733,13 @@ class SafePlusIntExpr : public BaseIntExpr { class PlusIntCstExpr : public BaseIntExpr { public: - PlusIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + PlusIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) {} ~PlusIntCstExpr() override {} - int64 Min() const override { return CapAdd(expr_->Min(), value_); } - void SetMin(int64 m) override { expr_->SetMin(CapSub(m, value_)); } - int64 Max() const override { return CapAdd(expr_->Max(), value_); } - void SetMax(int64 m) override { expr_->SetMax(CapSub(m, value_)); } + int64_t Min() const override { return CapAdd(expr_->Min(), value_); } + void SetMin(int64_t m) override { expr_->SetMin(CapSub(m, value_)); } + int64_t Max() const override { return CapAdd(expr_->Max(), value_); } + void SetMax(int64_t m) override { expr_->SetMax(CapSub(m, value_)); } bool Bound() const override { return (expr_->Bound()); } std::string name() const override { return absl::StrFormat("(%s + %d)", expr_->name(), value_); @@ -3742,7 +3759,7 @@ class PlusIntCstExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; IntVar* PlusIntCstExpr::CastToVar() { @@ -3775,30 +3792,30 @@ class SubIntExpr : public BaseIntExpr { ~SubIntExpr() override {} - int64 Min() const override { return left_->Min() - right_->Max(); } + int64_t Min() const override { return left_->Min() - right_->Max(); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { left_->SetMin(CapAdd(m, right_->Min())); right_->SetMax(CapSub(left_->Max(), m)); } - int64 Max() const override { return left_->Max() - right_->Min(); } + int64_t Max() const override { return left_->Max() - right_->Min(); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { left_->SetMax(CapAdd(m, right_->Max())); right_->SetMin(CapSub(left_->Min(), m)); } - void Range(int64* mi, int64* ma) override { + void Range(int64_t* mi, int64_t* ma) override { *mi = left_->Min() - right_->Max(); *ma = left_->Max() - right_->Min(); } - void SetRange(int64 l, int64 u) override { - const int64 left_min = left_->Min(); - const int64 right_min = right_->Min(); - const int64 left_max = left_->Max(); - const int64 right_max = right_->Max(); + void SetRange(int64_t l, int64_t u) override { + const int64_t left_min = left_->Min(); + const int64_t right_min = right_->Min(); + const int64_t left_max = left_->Max(); + const int64_t right_max = right_->Max(); if (l > left_min - right_max) { left_->SetMin(CapAdd(l, right_min)); right_->SetMax(CapSub(left_max, l)); @@ -3848,18 +3865,18 @@ class SafeSubIntExpr : public SubIntExpr { ~SafeSubIntExpr() override {} - int64 Min() const override { return CapSub(left_->Min(), right_->Max()); } + int64_t Min() const override { return CapSub(left_->Min(), right_->Max()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { left_->SetMin(CapAdd(m, right_->Min())); right_->SetMax(CapSub(left_->Max(), m)); } - void SetRange(int64 l, int64 u) override { - const int64 left_min = left_->Min(); - const int64 right_min = right_->Min(); - const int64 left_max = left_->Max(); - const int64 right_max = right_->Max(); + void SetRange(int64_t l, int64_t u) override { + const int64_t left_min = left_->Min(); + const int64_t right_min = right_->Min(); + const int64_t left_max = left_->Max(); + const int64_t right_max = right_->Max(); if (l > CapSub(left_min, right_max)) { left_->SetMin(CapAdd(l, right_min)); right_->SetMax(CapSub(left_max, l)); @@ -3870,14 +3887,14 @@ class SafeSubIntExpr : public SubIntExpr { } } - void Range(int64* mi, int64* ma) override { + void Range(int64_t* mi, int64_t* ma) override { *mi = CapSub(left_->Min(), right_->Max()); *ma = CapSub(left_->Max(), right_->Min()); } - int64 Max() const override { return CapSub(left_->Max(), right_->Min()); } + int64_t Max() const override { return CapSub(left_->Max(), right_->Min()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { left_->SetMax(CapAdd(m, right_->Max())); right_->SetMin(CapSub(left_->Min(), m)); } @@ -3889,13 +3906,13 @@ class SafeSubIntExpr : public SubIntExpr { class SubIntCstExpr : public BaseIntExpr { public: - SubIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + SubIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) {} ~SubIntCstExpr() override {} - int64 Min() const override { return CapSub(value_, expr_->Max()); } - void SetMin(int64 m) override { expr_->SetMax(CapSub(value_, m)); } - int64 Max() const override { return CapSub(value_, expr_->Min()); } - void SetMax(int64 m) override { expr_->SetMin(CapSub(value_, m)); } + int64_t Min() const override { return CapSub(value_, expr_->Max()); } + void SetMin(int64_t m) override { expr_->SetMax(CapSub(value_, m)); } + int64_t Max() const override { return CapSub(value_, expr_->Min()); } + void SetMax(int64_t m) override { expr_->SetMin(CapSub(value_, m)); } bool Bound() const override { return (expr_->Bound()); } std::string name() const override { return absl::StrFormat("(%d - %s)", value_, expr_->name()); @@ -3916,7 +3933,7 @@ class SubIntCstExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; IntVar* SubIntCstExpr::CastToVar() { @@ -3936,10 +3953,10 @@ class OppIntExpr : public BaseIntExpr { public: OppIntExpr(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {} ~OppIntExpr() override {} - int64 Min() const override { return (-expr_->Max()); } - void SetMin(int64 m) override { expr_->SetMax(-m); } - int64 Max() const override { return (-expr_->Min()); } - void SetMax(int64 m) override { expr_->SetMin(-m); } + int64_t Min() const override { return (-expr_->Max()); } + void SetMin(int64_t m) override { expr_->SetMax(-m); } + int64_t Max() const override { return (-expr_->Min()); } + void SetMax(int64_t m) override { expr_->SetMin(-m); } bool Bound() const override { return (expr_->Bound()); } std::string name() const override { return absl::StrFormat("(-%s)", expr_->name()); @@ -3972,7 +3989,7 @@ IntVar* OppIntExpr::CastToVar() { class TimesIntCstExpr : public BaseIntExpr { public: - TimesIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + TimesIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) {} ~TimesIntCstExpr() override {} @@ -3991,7 +4008,7 @@ class TimesIntCstExpr : public BaseIntExpr { IntExpr* Expr() const { return expr_; } - int64 Constant() const { return value_; } + int64_t Constant() const { return value_; } void Accept(ModelVisitor* const visitor) const override { visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this); @@ -4003,27 +4020,27 @@ class TimesIntCstExpr : public BaseIntExpr { protected: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; // ----- TimesPosIntCstExpr ----- class TimesPosIntCstExpr : public TimesIntCstExpr { public: - TimesPosIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + TimesPosIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : TimesIntCstExpr(s, e, v) { CHECK_GT(v, 0); } ~TimesPosIntCstExpr() override {} - int64 Min() const override { return expr_->Min() * value_; } + int64_t Min() const override { return expr_->Min() * value_; } - void SetMin(int64 m) override { expr_->SetMin(PosIntDivUp(m, value_)); } + void SetMin(int64_t m) override { expr_->SetMin(PosIntDivUp(m, value_)); } - int64 Max() const override { return expr_->Max() * value_; } + int64_t Max() const override { return expr_->Max() * value_; } - void SetMax(int64 m) override { expr_->SetMax(PosIntDivDown(m, value_)); } + void SetMax(int64_t m) override { expr_->SetMax(PosIntDivDown(m, value_)); } IntVar* CastToVar() override { Solver* const s = solver(); @@ -4044,25 +4061,25 @@ class TimesPosIntCstExpr : public TimesIntCstExpr { // to the previous one. class SafeTimesPosIntCstExpr : public TimesIntCstExpr { public: - SafeTimesPosIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + SafeTimesPosIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : TimesIntCstExpr(s, e, v) { CHECK_GT(v, 0); } ~SafeTimesPosIntCstExpr() override {} - int64 Min() const override { return CapProd(expr_->Min(), value_); } + int64_t Min() const override { return CapProd(expr_->Min(), value_); } - void SetMin(int64 m) override { - if (m != kint64min) { + void SetMin(int64_t m) override { + if (m != std::numeric_limits::min()) { expr_->SetMin(PosIntDivUp(m, value_)); } } - int64 Max() const override { return CapProd(expr_->Max(), value_); } + int64_t Max() const override { return CapProd(expr_->Max(), value_); } - void SetMax(int64 m) override { - if (m != kint64max) { + void SetMax(int64_t m) override { + if (m != std::numeric_limits::max()) { expr_->SetMax(PosIntDivDown(m, value_)); } } @@ -4087,25 +4104,25 @@ class SafeTimesPosIntCstExpr : public TimesIntCstExpr { class TimesIntNegCstExpr : public TimesIntCstExpr { public: - TimesIntNegCstExpr(Solver* const s, IntExpr* const e, int64 v) + TimesIntNegCstExpr(Solver* const s, IntExpr* const e, int64_t v) : TimesIntCstExpr(s, e, v) { CHECK_LT(v, 0); } ~TimesIntNegCstExpr() override {} - int64 Min() const override { return CapProd(expr_->Max(), value_); } + int64_t Min() const override { return CapProd(expr_->Max(), value_); } - void SetMin(int64 m) override { - if (m != kint64min) { + void SetMin(int64_t m) override { + if (m != std::numeric_limits::min()) { expr_->SetMax(PosIntDivDown(-m, -value_)); } } - int64 Max() const override { return CapProd(expr_->Min(), value_); } + int64_t Max() const override { return CapProd(expr_->Min(), value_); } - void SetMax(int64 m) override { - if (m != kint64max) { + void SetMax(int64_t m) override { + if (m != std::numeric_limits::max()) { expr_->SetMin(PosIntDivUp(-m, -value_)); } } @@ -4122,11 +4139,11 @@ class TimesIntNegCstExpr : public TimesIntCstExpr { // ----- Utilities for product expression ----- // Propagates set_min on left * right, left and right >= 0. -void SetPosPosMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { +void SetPosPosMinExpr(IntExpr* const left, IntExpr* const right, int64_t m) { DCHECK_GE(left->Min(), 0); DCHECK_GE(right->Min(), 0); - const int64 lmax = left->Max(); - const int64 rmax = right->Max(); + const int64_t lmax = left->Max(); + const int64_t rmax = right->Max(); if (m > CapProd(lmax, rmax)) { left->solver()->Fail(); } @@ -4142,11 +4159,11 @@ void SetPosPosMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { } // Propagates set_max on left * right, left and right >= 0. -void SetPosPosMaxExpr(IntExpr* const left, IntExpr* const right, int64 m) { +void SetPosPosMaxExpr(IntExpr* const left, IntExpr* const right, int64_t m) { DCHECK_GE(left->Min(), 0); DCHECK_GE(right->Min(), 0); - const int64 lmin = left->Min(); - const int64 rmin = right->Min(); + const int64_t lmin = left->Min(); + const int64_t rmin = right->Min(); if (m < CapProd(lmin, rmin)) { left->solver()->Fail(); } @@ -4162,12 +4179,12 @@ void SetPosPosMaxExpr(IntExpr* const left, IntExpr* const right, int64 m) { } // Propagates set_min on left * right, left >= 0, right across 0. -void SetPosGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { +void SetPosGenMinExpr(IntExpr* const left, IntExpr* const right, int64_t m) { DCHECK_GE(left->Min(), 0); DCHECK_GT(right->Max(), 0); DCHECK_LT(right->Min(), 0); - const int64 lmax = left->Max(); - const int64 rmax = right->Max(); + const int64_t lmax = left->Max(); + const int64_t rmax = right->Max(); if (m > CapProd(lmax, rmax)) { left->solver()->Fail(); } @@ -4179,12 +4196,12 @@ void SetPosGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { left->SetMin(PosIntDivUp(m, rmax)); right->SetMin(PosIntDivUp(m, lmax)); } else if (m == 0) { - const int64 lmin = left->Min(); + const int64_t lmin = left->Min(); if (lmin > 0) { right->SetMin(0); } } else { // m < 0 - const int64 lmin = left->Min(); + const int64_t lmin = left->Min(); if (0 != lmin) { // We cannot deduce anything if 0 is in the domain. right->SetMin(-PosIntDivDown(-m, lmin)); } @@ -4193,15 +4210,15 @@ void SetPosGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { } // Propagates set_min on left * right, left and right across 0. -void SetGenGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { +void SetGenGenMinExpr(IntExpr* const left, IntExpr* const right, int64_t m) { DCHECK_LT(left->Min(), 0); DCHECK_GT(left->Max(), 0); DCHECK_GT(right->Max(), 0); DCHECK_LT(right->Min(), 0); - const int64 lmin = left->Min(); - const int64 lmax = left->Max(); - const int64 rmin = right->Min(); - const int64 rmax = right->Max(); + const int64_t lmin = left->Min(); + const int64_t lmax = left->Max(); + const int64_t rmin = right->Min(); + const int64_t rmax = right->Max(); if (m > std::max(CapProd(lmin, rmin), CapProd(lmax, rmax))) { left->solver()->Fail(); } @@ -4216,7 +4233,7 @@ void SetGenGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) { void TimesSetMin(IntExpr* const left, IntExpr* const right, IntExpr* const minus_left, IntExpr* const minus_right, - int64 m) { + int64_t m) { if (left->Min() >= 0) { if (right->Min() >= 0) { SetPosPosMinExpr(left, right, m); @@ -4252,24 +4269,24 @@ class TimesIntExpr : public BaseIntExpr { minus_left_(s->MakeOpposite(left_)), minus_right_(s->MakeOpposite(right_)) {} ~TimesIntExpr() override {} - int64 Min() const override { - const int64 lmin = left_->Min(); - const int64 lmax = left_->Max(); - const int64 rmin = right_->Min(); - const int64 rmax = right_->Max(); + int64_t Min() const override { + const int64_t lmin = left_->Min(); + const int64_t lmax = left_->Max(); + const int64_t rmin = right_->Min(); + const int64_t rmax = right_->Max(); return std::min(std::min(CapProd(lmin, rmin), CapProd(lmax, rmax)), std::min(CapProd(lmax, rmin), CapProd(lmin, rmax))); } - void SetMin(int64 m) override; - int64 Max() const override { - const int64 lmin = left_->Min(); - const int64 lmax = left_->Max(); - const int64 rmin = right_->Min(); - const int64 rmax = right_->Max(); + void SetMin(int64_t m) override; + int64_t Max() const override { + const int64_t lmin = left_->Min(); + const int64_t lmax = left_->Max(); + const int64_t rmin = right_->Min(); + const int64_t rmax = right_->Max(); return std::max(std::max(CapProd(lmin, rmin), CapProd(lmax, rmax)), std::max(CapProd(lmax, rmin), CapProd(lmin, rmax))); } - void SetMax(int64 m) override; + void SetMax(int64_t m) override; bool Bound() const override; std::string name() const override { return absl::StrFormat("(%s * %s)", left_->name(), right_->name()); @@ -4298,14 +4315,14 @@ class TimesIntExpr : public BaseIntExpr { IntExpr* const minus_right_; }; -void TimesIntExpr::SetMin(int64 m) { - if (m != kint64min) { +void TimesIntExpr::SetMin(int64_t m) { + if (m != std::numeric_limits::min()) { TimesSetMin(left_, right_, minus_left_, minus_right_, m); } } -void TimesIntExpr::SetMax(int64 m) { - if (m != kint64max) { +void TimesIntExpr::SetMax(int64_t m) { + if (m != std::numeric_limits::max()) { TimesSetMin(left_, minus_right_, minus_left_, right_, -m); } } @@ -4324,10 +4341,10 @@ class TimesPosIntExpr : public BaseIntExpr { TimesPosIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r) : BaseIntExpr(s), left_(l), right_(r) {} ~TimesPosIntExpr() override {} - int64 Min() const override { return (left_->Min() * right_->Min()); } - void SetMin(int64 m) override; - int64 Max() const override { return (left_->Max() * right_->Max()); } - void SetMax(int64 m) override; + int64_t Min() const override { return (left_->Min() * right_->Min()); } + void SetMin(int64_t m) override; + int64_t Max() const override { return (left_->Max() * right_->Max()); } + void SetMax(int64_t m) override; bool Bound() const override; std::string name() const override { return absl::StrFormat("(%s * %s)", left_->name(), right_->name()); @@ -4354,9 +4371,9 @@ class TimesPosIntExpr : public BaseIntExpr { IntExpr* const right_; }; -void TimesPosIntExpr::SetMin(int64 m) { SetPosPosMinExpr(left_, right_, m); } +void TimesPosIntExpr::SetMin(int64_t m) { SetPosPosMinExpr(left_, right_, m); } -void TimesPosIntExpr::SetMax(int64 m) { SetPosPosMaxExpr(left_, right_, m); } +void TimesPosIntExpr::SetMax(int64_t m) { SetPosPosMaxExpr(left_, right_, m); } bool TimesPosIntExpr::Bound() const { return (left_->Max() == 0 || right_->Max() == 0 || @@ -4370,15 +4387,15 @@ class SafeTimesPosIntExpr : public BaseIntExpr { SafeTimesPosIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r) : BaseIntExpr(s), left_(l), right_(r) {} ~SafeTimesPosIntExpr() override {} - int64 Min() const override { return CapProd(left_->Min(), right_->Min()); } - void SetMin(int64 m) override { - if (m != kint64min) { + int64_t Min() const override { return CapProd(left_->Min(), right_->Min()); } + void SetMin(int64_t m) override { + if (m != std::numeric_limits::min()) { SetPosPosMinExpr(left_, right_, m); } } - int64 Max() const override { return CapProd(left_->Max(), right_->Max()); } - void SetMax(int64 m) override { - if (m != kint64max) { + int64_t Max() const override { return CapProd(left_->Max(), right_->Max()); } + void SetMax(int64_t m) override { + if (m != std::numeric_limits::max()) { SetPosPosMaxExpr(left_, right_, m); } } @@ -4418,16 +4435,16 @@ class TimesBooleanPosIntExpr : public BaseIntExpr { TimesBooleanPosIntExpr(Solver* const s, BooleanVar* const b, IntExpr* const e) : BaseIntExpr(s), boolvar_(b), expr_(e) {} ~TimesBooleanPosIntExpr() override {} - int64 Min() const override { + int64_t Min() const override { return (boolvar_->RawValue() == 1 ? expr_->Min() : 0); } - void SetMin(int64 m) override; - int64 Max() const override { + void SetMin(int64_t m) override; + int64_t Max() const override { return (boolvar_->RawValue() == 0 ? 0 : expr_->Max()); } - void SetMax(int64 m) override; - void Range(int64* mi, int64* ma) override; - void SetRange(int64 mi, int64 ma) override; + void SetMax(int64_t m) override; + void Range(int64_t* mi, int64_t* ma) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override; std::string name() const override { return absl::StrFormat("(%s * %s)", boolvar_->name(), expr_->name()); @@ -4455,14 +4472,14 @@ class TimesBooleanPosIntExpr : public BaseIntExpr { IntExpr* const expr_; }; -void TimesBooleanPosIntExpr::SetMin(int64 m) { +void TimesBooleanPosIntExpr::SetMin(int64_t m) { if (m > 0) { boolvar_->SetValue(1); expr_->SetMin(m); } } -void TimesBooleanPosIntExpr::SetMax(int64 m) { +void TimesBooleanPosIntExpr::SetMax(int64_t m) { if (m < 0) { solver()->Fail(); } @@ -4474,7 +4491,7 @@ void TimesBooleanPosIntExpr::SetMax(int64 m) { } } -void TimesBooleanPosIntExpr::Range(int64* mi, int64* ma) { +void TimesBooleanPosIntExpr::Range(int64_t* mi, int64_t* ma) { const int value = boolvar_->RawValue(); if (value == 0) { *mi = 0; @@ -4487,7 +4504,7 @@ void TimesBooleanPosIntExpr::Range(int64* mi, int64* ma) { } } -void TimesBooleanPosIntExpr::SetRange(int64 mi, int64 ma) { +void TimesBooleanPosIntExpr::SetRange(int64_t mi, int64_t ma) { if (ma < 0 || mi > ma) { solver()->Fail(); } @@ -4516,7 +4533,7 @@ class TimesBooleanIntExpr : public BaseIntExpr { TimesBooleanIntExpr(Solver* const s, BooleanVar* const b, IntExpr* const e) : BaseIntExpr(s), boolvar_(b), expr_(e) {} ~TimesBooleanIntExpr() override {} - int64 Min() const override { + int64_t Min() const override { switch (boolvar_->RawValue()) { case 0: { return 0LL; @@ -4526,12 +4543,12 @@ class TimesBooleanIntExpr : public BaseIntExpr { } default: { DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue()); - return std::min(int64{0}, expr_->Min()); + return std::min(int64_t{0}, expr_->Min()); } } } - void SetMin(int64 m) override; - int64 Max() const override { + void SetMin(int64_t m) override; + int64_t Max() const override { switch (boolvar_->RawValue()) { case 0: { return 0LL; @@ -4541,13 +4558,13 @@ class TimesBooleanIntExpr : public BaseIntExpr { } default: { DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue()); - return std::max(int64{0}, expr_->Max()); + return std::max(int64_t{0}, expr_->Max()); } } } - void SetMax(int64 m) override; - void Range(int64* mi, int64* ma) override; - void SetRange(int64 mi, int64 ma) override; + void SetMax(int64_t m) override; + void Range(int64_t* mi, int64_t* ma) override; + void SetRange(int64_t mi, int64_t ma) override; bool Bound() const override; std::string name() const override { return absl::StrFormat("(%s * %s)", boolvar_->name(), expr_->name()); @@ -4575,7 +4592,7 @@ class TimesBooleanIntExpr : public BaseIntExpr { IntExpr* const expr_; }; -void TimesBooleanIntExpr::SetMin(int64 m) { +void TimesBooleanIntExpr::SetMin(int64_t m) { switch (boolvar_->RawValue()) { case 0: { if (m > 0) { @@ -4599,7 +4616,7 @@ void TimesBooleanIntExpr::SetMin(int64 m) { } } -void TimesBooleanIntExpr::SetMax(int64 m) { +void TimesBooleanIntExpr::SetMax(int64_t m) { switch (boolvar_->RawValue()) { case 0: { if (m < 0) { @@ -4623,7 +4640,7 @@ void TimesBooleanIntExpr::SetMax(int64 m) { } } -void TimesBooleanIntExpr::Range(int64* mi, int64* ma) { +void TimesBooleanIntExpr::Range(int64_t* mi, int64_t* ma) { switch (boolvar_->RawValue()) { case 0: { *mi = 0; @@ -4637,14 +4654,14 @@ void TimesBooleanIntExpr::Range(int64* mi, int64* ma) { } default: { DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue()); - *mi = std::min(int64{0}, expr_->Min()); - *ma = std::max(int64{0}, expr_->Max()); + *mi = std::min(int64_t{0}, expr_->Min()); + *ma = std::max(int64_t{0}, expr_->Max()); break; } } } -void TimesBooleanIntExpr::SetRange(int64 mi, int64 ma) { +void TimesBooleanIntExpr::SetRange(int64_t mi, int64_t ma) { if (mi > ma) { solver()->Fail(); } @@ -4689,24 +4706,24 @@ bool TimesBooleanIntExpr::Bound() const { class DivPosIntCstExpr : public BaseIntExpr { public: - DivPosIntCstExpr(Solver* const s, IntExpr* const e, int64 v) + DivPosIntCstExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) { CHECK_GE(v, 0); } ~DivPosIntCstExpr() override {} - int64 Min() const override { return expr_->Min() / value_; } + int64_t Min() const override { return expr_->Min() / value_; } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > 0) { expr_->SetMin(m * value_); } else { expr_->SetMin((m - 1) * value_ + 1); } } - int64 Max() const override { return expr_->Max() / value_; } + int64_t Max() const override { return expr_->Max() / value_; } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m >= 0) { expr_->SetMax((m + 1) * value_ - 1); } else { @@ -4734,7 +4751,7 @@ class DivPosIntCstExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; // DivPosIntExpr @@ -4749,30 +4766,30 @@ class DivPosIntExpr : public BaseIntExpr { ~DivPosIntExpr() override {} - int64 Min() const override { + int64_t Min() const override { return num_->Min() >= 0 ? num_->Min() / denom_->Max() : (denom_->Min() == 0 ? num_->Min() : num_->Min() / denom_->Min()); } - int64 Max() const override { + int64_t Max() const override { return num_->Max() >= 0 ? (denom_->Min() == 0 ? num_->Max() : num_->Max() / denom_->Min()) : num_->Max() / denom_->Max(); } - static void SetPosMin(IntExpr* const num, IntExpr* const denom, int64 m) { + static void SetPosMin(IntExpr* const num, IntExpr* const denom, int64_t m) { num->SetMin(m * denom->Min()); denom->SetMax(num->Max() / m); } - static void SetPosMax(IntExpr* const num, IntExpr* const denom, int64 m) { + static void SetPosMax(IntExpr* const num, IntExpr* const denom, int64_t m) { num->SetMax((m + 1) * denom->Max() - 1); denom->SetMin(num->Min() / (m + 1) + 1); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > 0) { SetPosMin(num_, denom_, m); } else { @@ -4780,7 +4797,7 @@ class DivPosIntExpr : public BaseIntExpr { } } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m >= 0) { SetPosMax(num_, denom_, m); } else { @@ -4821,14 +4838,14 @@ class DivPosPosIntExpr : public BaseIntExpr { ~DivPosPosIntExpr() override {} - int64 Min() const override { + int64_t Min() const override { if (denom_->Max() == 0) { solver()->Fail(); } return num_->Min() / denom_->Max(); } - int64 Max() const override { + int64_t Max() const override { if (denom_->Min() == 0) { return num_->Max(); } else { @@ -4836,14 +4853,14 @@ class DivPosPosIntExpr : public BaseIntExpr { } } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > 0) { num_->SetMin(m * denom_->Min()); denom_->SetMax(num_->Max() / m); } } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m >= 0) { num_->SetMax((m + 1) * denom_->Max() - 1); denom_->SetMin(num_->Min() / (m + 1) + 1); @@ -4891,46 +4908,48 @@ class DivIntExpr : public BaseIntExpr { ~DivIntExpr() override {} - int64 Min() const override { - const int64 num_min = num_->Min(); - const int64 num_max = num_->Max(); - const int64 denom_min = denom_->Min(); - const int64 denom_max = denom_->Max(); + int64_t Min() const override { + const int64_t num_min = num_->Min(); + const int64_t num_max = num_->Max(); + const int64_t denom_min = denom_->Min(); + const int64_t denom_max = denom_->Max(); if (denom_min == 0 && denom_max == 0) { - return kint64max; // TODO(user): Check this convention. + return std::numeric_limits::max(); // TODO(user): Check this + // convention. } if (denom_min >= 0) { // Denominator strictly positive. DCHECK_GT(denom_max, 0); - const int64 adjusted_denom_min = denom_min == 0 ? 1 : denom_min; + const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min; return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min; } else if (denom_max <= 0) { // Denominator strictly negative. DCHECK_LT(denom_min, 0); - const int64 adjusted_denom_max = denom_max == 0 ? -1 : denom_max; + const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max; return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min; } else { // Denominator across 0. return std::min(num_min, -num_max); } } - int64 Max() const override { - const int64 num_min = num_->Min(); - const int64 num_max = num_->Max(); - const int64 denom_min = denom_->Min(); - const int64 denom_max = denom_->Max(); + int64_t Max() const override { + const int64_t num_min = num_->Min(); + const int64_t num_max = num_->Max(); + const int64_t denom_min = denom_->Min(); + const int64_t denom_max = denom_->Max(); if (denom_min == 0 && denom_max == 0) { - return kint64min; // TODO(user): Check this convention. + return std::numeric_limits::min(); // TODO(user): Check this + // convention. } if (denom_min >= 0) { // Denominator strictly positive. DCHECK_GT(denom_max, 0); - const int64 adjusted_denom_min = denom_min == 0 ? 1 : denom_min; + const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min; return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max; } else if (denom_max <= 0) { // Denominator strictly negative. DCHECK_LT(denom_min, 0); - const int64 adjusted_denom_max = denom_max == 0 ? -1 : denom_max; + const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max; return num_min >= 0 ? num_min / denom_min : -num_min / -adjusted_denom_max; } else { // Denominator across 0. @@ -4947,12 +4966,12 @@ class DivIntExpr : public BaseIntExpr { } // m > 0. - static void SetPosMin(IntExpr* const num, IntExpr* const denom, int64 m) { + static void SetPosMin(IntExpr* const num, IntExpr* const denom, int64_t m) { DCHECK_GT(m, 0); - const int64 num_min = num->Min(); - const int64 num_max = num->Max(); - const int64 denom_min = denom->Min(); - const int64 denom_max = denom->Max(); + const int64_t num_min = num->Min(); + const int64_t num_max = num->Max(); + const int64_t denom_min = denom->Min(); + const int64_t denom_max = denom->Max(); DCHECK_NE(denom_min, 0); DCHECK_NE(denom_max, 0); if (denom_min > 0) { // Denominator strictly positive. @@ -4983,12 +5002,12 @@ class DivIntExpr : public BaseIntExpr { } // m >= 0. - static void SetPosMax(IntExpr* const num, IntExpr* const denom, int64 m) { + static void SetPosMax(IntExpr* const num, IntExpr* const denom, int64_t m) { DCHECK_GE(m, 0); - const int64 num_min = num->Min(); - const int64 num_max = num->Max(); - const int64 denom_min = denom->Min(); - const int64 denom_max = denom->Max(); + const int64_t num_min = num->Min(); + const int64_t num_max = num->Max(); + const int64_t denom_min = denom->Min(); + const int64_t denom_max = denom->Max(); DCHECK_NE(denom_min, 0); DCHECK_NE(denom_max, 0); if (denom_min > 0) { // Denominator strictly positive. @@ -5004,7 +5023,7 @@ class DivIntExpr : public BaseIntExpr { } } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { AdjustDenominator(); if (m > 0) { SetPosMin(num_, denom_, m); @@ -5013,7 +5032,7 @@ class DivIntExpr : public BaseIntExpr { } } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { AdjustDenominator(); if (m >= 0) { SetPosMax(num_, denom_, m); @@ -5072,8 +5091,8 @@ class IntAbsConstraint : public CastConstraint { } void PropagateSub() { - const int64 smin = sub_->Min(); - const int64 smax = sub_->Max(); + const int64_t smin = sub_->Min(); + const int64_t smax = sub_->Max(); if (smax <= 0) { target_var_->SetRange(-smax, -smin); } else if (smin >= 0) { @@ -5084,9 +5103,9 @@ class IntAbsConstraint : public CastConstraint { } void PropagateTarget() { - const int64 target_max = target_var_->Max(); + const int64_t target_max = target_var_->Max(); sub_->SetRange(-target_max, target_max); - const int64 target_min = target_var_->Min(); + const int64_t target_min = target_var_->Min(); if (target_min > 0) { if (sub_->Min() > -target_min) { sub_->SetMin(target_min); @@ -5120,9 +5139,9 @@ class IntAbs : public BaseIntExpr { ~IntAbs() override {} - int64 Min() const override { - int64 emin = 0; - int64 emax = 0; + int64_t Min() const override { + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin >= 0) { return emin; @@ -5133,10 +5152,10 @@ class IntAbs : public BaseIntExpr { return 0; } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > 0) { - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin > -m) { expr_->SetMin(m); @@ -5146,20 +5165,20 @@ class IntAbs : public BaseIntExpr { } } - int64 Max() const override { - int64 emin = 0; - int64 emax = 0; + int64_t Max() const override { + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); return std::max(-emin, emax); } - void SetMax(int64 m) override { expr_->SetRange(-m, m); } + void SetMax(int64_t m) override { expr_->SetRange(-m, m); } - void SetRange(int64 mi, int64 ma) override { + void SetRange(int64_t mi, int64_t ma) override { expr_->SetRange(-ma, ma); if (mi > 0) { - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin > -mi) { expr_->SetMin(mi); @@ -5169,9 +5188,9 @@ class IntAbs : public BaseIntExpr { } } - void Range(int64* mi, int64* ma) override { - int64 emin = 0; - int64 emax = 0; + void Range(int64_t* mi, int64_t* ma) override { + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin >= 0) { *mi = emin; @@ -5205,8 +5224,8 @@ class IntAbs : public BaseIntExpr { } IntVar* CastToVar() override { - int64 min_value = 0; - int64 max_value = 0; + int64_t min_value = 0; + int64_t max_value = 0; Range(&min_value, &max_value); Solver* const s = solver(); const std::string name = absl::StrFormat("AbsVar(%s)", expr_->name()); @@ -5229,25 +5248,30 @@ class IntSquare : public BaseIntExpr { IntSquare(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {} ~IntSquare() override {} - int64 Min() const override { - const int64 emin = expr_->Min(); + int64_t Min() const override { + const int64_t emin = expr_->Min(); if (emin >= 0) { - return emin >= kint32max ? kint64max : emin * emin; + return emin >= std::numeric_limits::max() + ? std::numeric_limits::max() + : emin * emin; } - const int64 emax = expr_->Max(); + const int64_t emax = expr_->Max(); if (emax < 0) { - return emax <= -kint32max ? kint64max : emax * emax; + return emax <= -std::numeric_limits::max() + ? std::numeric_limits::max() + : emax * emax; } return 0LL; } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m <= 0) { return; } // TODO(user): What happens if m is kint64max? - const int64 emin = expr_->Min(); - const int64 emax = expr_->Max(); - const int64 root = static_cast(ceil(sqrt(static_cast(m)))); + const int64_t emin = expr_->Min(); + const int64_t emax = expr_->Max(); + const int64_t root = + static_cast(ceil(sqrt(static_cast(m)))); if (emin >= 0) { expr_->SetMin(root); } else if (emax <= 0) { @@ -5256,22 +5280,24 @@ class IntSquare : public BaseIntExpr { reinterpret_cast(expr_)->RemoveInterval(-root + 1, root - 1); } } - int64 Max() const override { - const int64 emax = expr_->Max(); - const int64 emin = expr_->Min(); - if (emax >= kint32max || emin <= -kint32max) { - return kint64max; + int64_t Max() const override { + const int64_t emax = expr_->Max(); + const int64_t emin = expr_->Min(); + if (emax >= std::numeric_limits::max() || + emin <= -std::numeric_limits::max()) { + return std::numeric_limits::max(); } return std::max(emin * emin, emax * emax); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } - if (m == kint64max) { + if (m == std::numeric_limits::max()) { return; } - const int64 root = static_cast(floor(sqrt(static_cast(m)))); + const int64_t root = + static_cast(floor(sqrt(static_cast(m)))); expr_->SetRange(-root, root); } bool Bound() const override { return expr_->Bound(); } @@ -5301,37 +5327,43 @@ class PosIntSquare : public IntSquare { PosIntSquare(Solver* const s, IntExpr* const e) : IntSquare(s, e) {} ~PosIntSquare() override {} - int64 Min() const override { - const int64 emin = expr_->Min(); - return emin >= kint32max ? kint64max : emin * emin; + int64_t Min() const override { + const int64_t emin = expr_->Min(); + return emin >= std::numeric_limits::max() + ? std::numeric_limits::max() + : emin * emin; } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m <= 0) { return; } - const int64 root = static_cast(ceil(sqrt(static_cast(m)))); + const int64_t root = + static_cast(ceil(sqrt(static_cast(m)))); expr_->SetMin(root); } - int64 Max() const override { - const int64 emax = expr_->Max(); - return emax >= kint32max ? kint64max : emax * emax; + int64_t Max() const override { + const int64_t emax = expr_->Max(); + return emax >= std::numeric_limits::max() + ? std::numeric_limits::max() + : emax * emax; } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } - if (m == kint64max) { + if (m == std::numeric_limits::max()) { return; } - const int64 root = static_cast(floor(sqrt(static_cast(m)))); + const int64_t root = + static_cast(floor(sqrt(static_cast(m)))); expr_->SetMax(root); } }; // ----- EvenPower ----- -int64 IntPower(int64 value, int64 power) { - int64 result = value; +int64_t IntPower(int64_t value, int64_t power) { + int64_t result = value; // TODO(user): Speed that up. for (int i = 1; i < power; ++i) { result *= value; @@ -5339,14 +5371,14 @@ int64 IntPower(int64 value, int64 power) { return result; } -int64 OverflowLimit(int64 power) { - return static_cast( - floor(exp(log(static_cast(kint64max)) / power))); +int64_t OverflowLimit(int64_t power) { + return static_cast(floor(exp( + log(static_cast(std::numeric_limits::max())) / power))); } class BasePower : public BaseIntExpr { public: - BasePower(Solver* const s, IntExpr* const e, int64 n) + BasePower(Solver* const s, IntExpr* const e, int64_t n) : BaseIntExpr(s), expr_(e), pow_(n), limit_(OverflowLimit(n)) { CHECK_GT(n, 0); } @@ -5357,7 +5389,7 @@ class BasePower : public BaseIntExpr { IntExpr* expr() const { return expr_; } - int64 exponant() const { return pow_; } + int64_t exponant() const { return pow_; } void WhenRange(Demon* d) override { expr_->WhenRange(d); } @@ -5378,38 +5410,38 @@ class BasePower : public BaseIntExpr { } protected: - int64 Pown(int64 value) const { + int64_t Pown(int64_t value) const { if (value >= limit_) { - return kint64max; + return std::numeric_limits::max(); } if (value <= -limit_) { if (pow_ % 2 == 0) { - return kint64max; + return std::numeric_limits::max(); } else { - return kint64min; + return std::numeric_limits::min(); } } return IntPower(value, pow_); } - int64 SqrnDown(int64 value) const { - if (value == kint64min) { - return kint64min; + int64_t SqrnDown(int64_t value) const { + if (value == std::numeric_limits::min()) { + return std::numeric_limits::min(); } - if (value == kint64max) { - return kint64max; + if (value == std::numeric_limits::max()) { + return std::numeric_limits::max(); } - int64 res = 0; + int64_t res = 0; const double d_value = static_cast(value); if (value >= 0) { const double sq = exp(log(d_value) / pow_); - res = static_cast(floor(sq)); + res = static_cast(floor(sq)); } else { CHECK_EQ(1, pow_ % 2); const double sq = exp(log(-d_value) / pow_); - res = -static_cast(ceil(sq)); + res = -static_cast(ceil(sq)); } - const int64 pow_res = Pown(res + 1); + const int64_t pow_res = Pown(res + 1); if (pow_res <= value) { return res + 1; } else { @@ -5417,24 +5449,24 @@ class BasePower : public BaseIntExpr { } } - int64 SqrnUp(int64 value) const { - if (value == kint64min) { - return kint64min; + int64_t SqrnUp(int64_t value) const { + if (value == std::numeric_limits::min()) { + return std::numeric_limits::min(); } - if (value == kint64max) { - return kint64max; + if (value == std::numeric_limits::max()) { + return std::numeric_limits::max(); } - int64 res = 0; + int64_t res = 0; const double d_value = static_cast(value); if (value >= 0) { const double sq = exp(log(d_value) / pow_); - res = static_cast(ceil(sq)); + res = static_cast(ceil(sq)); } else { CHECK_EQ(1, pow_ % 2); const double sq = exp(log(-d_value) / pow_); - res = -static_cast(floor(sq)); + res = -static_cast(floor(sq)); } - const int64 pow_res = Pown(res - 1); + const int64_t pow_res = Pown(res - 1); if (pow_res >= value) { return res - 1; } else { @@ -5443,22 +5475,22 @@ class BasePower : public BaseIntExpr { } IntExpr* const expr_; - const int64 pow_; - const int64 limit_; + const int64_t pow_; + const int64_t limit_; }; class IntEvenPower : public BasePower { public: - IntEvenPower(Solver* const s, IntExpr* const e, int64 n) + IntEvenPower(Solver* const s, IntExpr* const e, int64_t n) : BasePower(s, e, n) { CHECK_EQ(0, n % 2); } ~IntEvenPower() override {} - int64 Min() const override { - int64 emin = 0; - int64 emax = 0; + int64_t Min() const override { + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); if (emin >= 0) { return Pown(emin); @@ -5468,14 +5500,14 @@ class IntEvenPower : public BasePower { } return 0LL; } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m <= 0) { return; } - int64 emin = 0; - int64 emax = 0; + int64_t emin = 0; + int64_t emax = 0; expr_->Range(&emin, &emax); - const int64 root = SqrnUp(m); + const int64_t root = SqrnUp(m); if (emin > -root) { expr_->SetMin(root); } else if (emax < root) { @@ -5485,46 +5517,46 @@ class IntEvenPower : public BasePower { } } - int64 Max() const override { + int64_t Max() const override { return std::max(Pown(expr_->Min()), Pown(expr_->Max())); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } - if (m == kint64max) { + if (m == std::numeric_limits::max()) { return; } - const int64 root = SqrnDown(m); + const int64_t root = SqrnDown(m); expr_->SetRange(-root, root); } }; class PosIntEvenPower : public BasePower { public: - PosIntEvenPower(Solver* const s, IntExpr* const e, int64 pow) + PosIntEvenPower(Solver* const s, IntExpr* const e, int64_t pow) : BasePower(s, e, pow) { CHECK_EQ(0, pow % 2); } ~PosIntEvenPower() override {} - int64 Min() const override { return Pown(expr_->Min()); } + int64_t Min() const override { return Pown(expr_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m <= 0) { return; } expr_->SetMin(SqrnUp(m)); } - int64 Max() const override { return Pown(expr_->Max()); } + int64_t Max() const override { return Pown(expr_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } - if (m == kint64max) { + if (m == std::numeric_limits::max()) { return; } expr_->SetMax(SqrnDown(m)); @@ -5533,19 +5565,20 @@ class PosIntEvenPower : public BasePower { class IntOddPower : public BasePower { public: - IntOddPower(Solver* const s, IntExpr* const e, int64 n) : BasePower(s, e, n) { + IntOddPower(Solver* const s, IntExpr* const e, int64_t n) + : BasePower(s, e, n) { CHECK_EQ(1, n % 2); } ~IntOddPower() override {} - int64 Min() const override { return Pown(expr_->Min()); } + int64_t Min() const override { return Pown(expr_->Min()); } - void SetMin(int64 m) override { expr_->SetMin(SqrnUp(m)); } + void SetMin(int64_t m) override { expr_->SetMin(SqrnUp(m)); } - int64 Max() const override { return Pown(expr_->Max()); } + int64_t Max() const override { return Pown(expr_->Max()); } - void SetMax(int64 m) override { expr_->SetMax(SqrnDown(m)); } + void SetMax(int64_t m) override { expr_->SetMax(SqrnDown(m)); } }; // ----- Min(expr, expr) ----- @@ -5555,21 +5588,21 @@ class MinIntExpr : public BaseIntExpr { MinIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r) : BaseIntExpr(s), left_(l), right_(r) {} ~MinIntExpr() override {} - int64 Min() const override { - const int64 lmin = left_->Min(); - const int64 rmin = right_->Min(); + int64_t Min() const override { + const int64_t lmin = left_->Min(); + const int64_t rmin = right_->Min(); return std::min(lmin, rmin); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { left_->SetMin(m); right_->SetMin(m); } - int64 Max() const override { - const int64 lmax = left_->Max(); - const int64 rmax = right_->Max(); + int64_t Max() const override { + const int64_t lmax = left_->Max(); + const int64_t rmax = right_->Max(); return std::min(lmax, rmax); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (left_->Min() > m) { right_->SetMax(m); } @@ -5606,23 +5639,23 @@ class MinIntExpr : public BaseIntExpr { class MinCstIntExpr : public BaseIntExpr { public: - MinCstIntExpr(Solver* const s, IntExpr* const e, int64 v) + MinCstIntExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) {} ~MinCstIntExpr() override {} - int64 Min() const override { return std::min(expr_->Min(), value_); } + int64_t Min() const override { return std::min(expr_->Min(), value_); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > value_) { solver()->Fail(); } expr_->SetMin(m); } - int64 Max() const override { return std::min(expr_->Max(), value_); } + int64_t Max() const override { return std::min(expr_->Max(), value_); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (value_ > m) { expr_->SetMax(m); } @@ -5653,7 +5686,7 @@ class MinCstIntExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; // ----- Max(expr, expr) ----- @@ -5665,9 +5698,9 @@ class MaxIntExpr : public BaseIntExpr { ~MaxIntExpr() override {} - int64 Min() const override { return std::max(left_->Min(), right_->Min()); } + int64_t Min() const override { return std::max(left_->Min(), right_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (left_->Max() < m) { right_->SetMin(m); } else { @@ -5677,9 +5710,9 @@ class MaxIntExpr : public BaseIntExpr { } } - int64 Max() const override { return std::max(left_->Max(), right_->Max()); } + int64_t Max() const override { return std::max(left_->Max(), right_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { left_->SetMax(m); right_->SetMax(m); } @@ -5715,22 +5748,22 @@ class MaxIntExpr : public BaseIntExpr { class MaxCstIntExpr : public BaseIntExpr { public: - MaxCstIntExpr(Solver* const s, IntExpr* const e, int64 v) + MaxCstIntExpr(Solver* const s, IntExpr* const e, int64_t v) : BaseIntExpr(s), expr_(e), value_(v) {} ~MaxCstIntExpr() override {} - int64 Min() const override { return std::max(expr_->Min(), value_); } + int64_t Min() const override { return std::max(expr_->Min(), value_); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (value_ < m) { expr_->SetMin(m); } } - int64 Max() const override { return std::max(expr_->Max(), value_); } + int64_t Max() const override { return std::max(expr_->Max(), value_); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < value_) { solver()->Fail(); } @@ -5762,7 +5795,7 @@ class MaxCstIntExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 value_; + const int64_t value_; }; // ----- Convex Piecewise ----- @@ -5775,16 +5808,16 @@ class MaxCstIntExpr : public BaseIntExpr { class SimpleConvexPiecewiseExpr : public BaseIntExpr { public: - SimpleConvexPiecewiseExpr(Solver* const s, IntExpr* const e, int64 ec, - int64 ed, int64 ld, int64 lc) + SimpleConvexPiecewiseExpr(Solver* const s, IntExpr* const e, int64_t ec, + int64_t ed, int64_t ld, int64_t lc) : BaseIntExpr(s), expr_(e), early_cost_(ec), - early_date_(ec == 0 ? kint64min : ed), - late_date_(lc == 0 ? kint64max : ld), + early_date_(ec == 0 ? std::numeric_limits::min() : ed), + late_date_(lc == 0 ? std::numeric_limits::max() : ld), late_cost_(lc) { - DCHECK_GE(ec, int64{0}); - DCHECK_GE(lc, int64{0}); + DCHECK_GE(ec, int64_t{0}); + DCHECK_GE(lc, int64_t{0}); DCHECK_GE(ld, ed); // If the penalty is 0, we can push the "confort zone or zone @@ -5793,9 +5826,9 @@ class SimpleConvexPiecewiseExpr : public BaseIntExpr { ~SimpleConvexPiecewiseExpr() override {} - int64 Min() const override { - const int64 vmin = expr_->Min(); - const int64 vmax = expr_->Max(); + int64_t Min() const override { + const int64_t vmin = expr_->Min(); + const int64_t vmax = expr_->Max(); if (vmin >= late_date_) { return (vmin - late_date_) * late_cost_; } else if (vmax <= early_date_) { @@ -5805,17 +5838,17 @@ class SimpleConvexPiecewiseExpr : public BaseIntExpr { } } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m <= 0) { return; } - int64 vmin = 0; - int64 vmax = 0; + int64_t vmin = 0; + int64_t vmax = 0; expr_->Range(&vmin, &vmax); - const int64 rb = + const int64_t rb = (late_cost_ == 0 ? vmax : late_date_ + PosIntDivUp(m, late_cost_) - 1); - const int64 lb = + const int64_t lb = (early_cost_ == 0 ? vmin : early_date_ - PosIntDivUp(m, early_cost_) + 1); @@ -5824,30 +5857,30 @@ class SimpleConvexPiecewiseExpr : public BaseIntExpr { } } - int64 Max() const override { - const int64 vmin = expr_->Min(); - const int64 vmax = expr_->Max(); - const int64 mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0; - const int64 ml = + int64_t Max() const override { + const int64_t vmin = expr_->Min(); + const int64_t vmax = expr_->Max(); + const int64_t mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0; + const int64_t ml = vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0; return std::max(mr, ml); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } if (late_cost_ != 0LL) { - const int64 rb = late_date_ + PosIntDivDown(m, late_cost_); + const int64_t rb = late_date_ + PosIntDivDown(m, late_cost_); if (early_cost_ != 0LL) { - const int64 lb = early_date_ - PosIntDivDown(m, early_cost_); + const int64_t lb = early_date_ - PosIntDivDown(m, early_cost_); expr_->SetRange(lb, rb); } else { expr_->SetMax(rb); } } else { if (early_cost_ != 0LL) { - const int64 lb = early_date_ - PosIntDivDown(m, early_cost_); + const int64_t lb = early_date_ - PosIntDivDown(m, early_cost_); expr_->SetMin(lb); } } @@ -5882,26 +5915,26 @@ class SimpleConvexPiecewiseExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 early_cost_; - const int64 early_date_; - const int64 late_date_; - const int64 late_cost_; + const int64_t early_cost_; + const int64_t early_date_; + const int64_t late_date_; + const int64_t late_cost_; }; // ----- Semi Continuous ----- class SemiContinuousExpr : public BaseIntExpr { public: - SemiContinuousExpr(Solver* const s, IntExpr* const e, int64 fixed_charge, - int64 step) + SemiContinuousExpr(Solver* const s, IntExpr* const e, int64_t fixed_charge, + int64_t step) : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge), step_(step) { - DCHECK_GE(fixed_charge, int64{0}); - DCHECK_GT(step, int64{0}); + DCHECK_GE(fixed_charge, int64_t{0}); + DCHECK_GT(step, int64_t{0}); } ~SemiContinuousExpr() override {} - int64 Value(int64 x) const { + int64_t Value(int64_t x) const { if (x <= 0) { return 0; } else { @@ -5909,30 +5942,30 @@ class SemiContinuousExpr : public BaseIntExpr { } } - int64 Min() const override { return Value(expr_->Min()); } + int64_t Min() const override { return Value(expr_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m >= CapAdd(fixed_charge_, step_)) { - const int64 y = PosIntDivUp(CapSub(m, fixed_charge_), step_); + const int64_t y = PosIntDivUp(CapSub(m, fixed_charge_), step_); expr_->SetMin(y); } else if (m > 0) { expr_->SetMin(1); } } - int64 Max() const override { return Value(expr_->Max()); } + int64_t Max() const override { return Value(expr_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } - if (m == kint64max) { + if (m == std::numeric_limits::max()) { return; } if (m < CapAdd(fixed_charge_, step_)) { expr_->SetMax(0); } else { - const int64 y = PosIntDivDown(CapSub(m, fixed_charge_), step_); + const int64_t y = PosIntDivDown(CapSub(m, fixed_charge_), step_); expr_->SetMax(y); } } @@ -5961,21 +5994,21 @@ class SemiContinuousExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 fixed_charge_; - const int64 step_; + const int64_t fixed_charge_; + const int64_t step_; }; class SemiContinuousStepOneExpr : public BaseIntExpr { public: SemiContinuousStepOneExpr(Solver* const s, IntExpr* const e, - int64 fixed_charge) + int64_t fixed_charge) : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) { - DCHECK_GE(fixed_charge, int64{0}); + DCHECK_GE(fixed_charge, int64_t{0}); } ~SemiContinuousStepOneExpr() override {} - int64 Value(int64 x) const { + int64_t Value(int64_t x) const { if (x <= 0) { return 0; } else { @@ -5983,9 +6016,9 @@ class SemiContinuousStepOneExpr : public BaseIntExpr { } } - int64 Min() const override { return Value(expr_->Min()); } + int64_t Min() const override { return Value(expr_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m >= fixed_charge_ + 1) { expr_->SetMin(m - fixed_charge_); } else if (m > 0) { @@ -5993,9 +6026,9 @@ class SemiContinuousStepOneExpr : public BaseIntExpr { } } - int64 Max() const override { return Value(expr_->Max()); } + int64_t Max() const override { return Value(expr_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } @@ -6030,20 +6063,20 @@ class SemiContinuousStepOneExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 fixed_charge_; + const int64_t fixed_charge_; }; class SemiContinuousStepZeroExpr : public BaseIntExpr { public: SemiContinuousStepZeroExpr(Solver* const s, IntExpr* const e, - int64 fixed_charge) + int64_t fixed_charge) : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) { - DCHECK_GT(fixed_charge, int64{0}); + DCHECK_GT(fixed_charge, int64_t{0}); } ~SemiContinuousStepZeroExpr() override {} - int64 Value(int64 x) const { + int64_t Value(int64_t x) const { if (x <= 0) { return 0; } else { @@ -6051,9 +6084,9 @@ class SemiContinuousStepZeroExpr : public BaseIntExpr { } } - int64 Min() const override { return Value(expr_->Min()); } + int64_t Min() const override { return Value(expr_->Min()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m >= fixed_charge_) { solver()->Fail(); } else if (m > 0) { @@ -6061,9 +6094,9 @@ class SemiContinuousStepZeroExpr : public BaseIntExpr { } } - int64 Max() const override { return Value(expr_->Max()); } + int64_t Max() const override { return Value(expr_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < 0) { solver()->Fail(); } @@ -6096,7 +6129,7 @@ class SemiContinuousStepZeroExpr : public BaseIntExpr { private: IntExpr* const expr_; - const int64 fixed_charge_; + const int64_t fixed_charge_; }; // This constraints links an expression and the variable it is casted into @@ -6116,7 +6149,7 @@ class LinkExprAndVar : public CastConstraint { void InitialPropagate() override { expr_->SetRange(target_var_->Min(), target_var_->Max()); - int64 l, u; + int64_t l, u; expr_->Range(&l, &u); target_var_->SetRange(l, u); } @@ -6144,7 +6177,7 @@ class LinkExprAndVar : public CastConstraint { class ExprWithEscapeValue : public BaseIntExpr { public: ExprWithEscapeValue(Solver* const s, IntVar* const c, IntExpr* const e, - int64 unperformed_value) + int64_t unperformed_value) : BaseIntExpr(s), condition_(c), expression_(e), @@ -6152,7 +6185,7 @@ class ExprWithEscapeValue : public BaseIntExpr { ~ExprWithEscapeValue() override {} - int64 Min() const override { + int64_t Min() const override { if (condition_->Min() == 1) { return expression_->Min(); } else if (condition_->Max() == 1) { @@ -6162,7 +6195,7 @@ class ExprWithEscapeValue : public BaseIntExpr { } } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > unperformed_value_) { condition_->SetValue(1); expression_->SetMin(m); @@ -6173,7 +6206,7 @@ class ExprWithEscapeValue : public BaseIntExpr { } } - int64 Max() const override { + int64_t Max() const override { if (condition_->Min() == 1) { return expression_->Max(); } else if (condition_->Max() == 1) { @@ -6183,7 +6216,7 @@ class ExprWithEscapeValue : public BaseIntExpr { } } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < unperformed_value_) { condition_->SetValue(1); expression_->SetMax(m); @@ -6194,7 +6227,7 @@ class ExprWithEscapeValue : public BaseIntExpr { } } - void SetRange(int64 mi, int64 ma) override { + void SetRange(int64_t mi, int64_t ma) override { if (ma < unperformed_value_ || mi > unperformed_value_) { condition_->SetValue(1); expression_->SetRange(mi, ma); @@ -6205,7 +6238,7 @@ class ExprWithEscapeValue : public BaseIntExpr { } } - void SetValue(int64 v) override { + void SetValue(int64_t v) override { if (v != unperformed_value_) { condition_->SetValue(1); expression_->SetValue(v); @@ -6245,7 +6278,7 @@ class ExprWithEscapeValue : public BaseIntExpr { private: IntVar* const condition_; IntExpr* const expression_; - const int64 unperformed_value_; + const int64_t unperformed_value_; DISALLOW_COPY_AND_ASSIGN(ExprWithEscapeValue); }; @@ -6256,8 +6289,8 @@ class LinkExprAndDomainIntVar : public CastConstraint { DomainIntVar* const var) : CastConstraint(s, var), expr_(expr), - cached_min_(kint64min), - cached_max_(kint64max), + cached_min_(std::numeric_limits::min()), + cached_max_(std::numeric_limits::max()), fail_stamp_(uint64_t{0}) {} ~LinkExprAndDomainIntVar() override {} @@ -6306,9 +6339,9 @@ class LinkExprAndDomainIntVar : public CastConstraint { private: IntExpr* const expr_; - int64 cached_min_; - int64 cached_max_; - uint64 fail_stamp_; + int64_t cached_min_; + int64_t cached_max_; + uint64_t fail_stamp_; }; } // namespace @@ -6329,7 +6362,7 @@ void CleanVariableOnFail(IntVar* const var) { dvar->CleanInProcess(); } -Constraint* SetIsEqual(IntVar* const var, const std::vector& values, +Constraint* SetIsEqual(IntVar* const var, const std::vector& values, const std::vector& vars) { DomainIntVar* const dvar = reinterpret_cast(var); CHECK(dvar != nullptr); @@ -6337,7 +6370,7 @@ Constraint* SetIsEqual(IntVar* const var, const std::vector& values, } Constraint* SetIsGreaterOrEqual(IntVar* const var, - const std::vector& values, + const std::vector& values, const std::vector& vars) { DomainIntVar* const dvar = reinterpret_cast(var); CHECK(dvar != nullptr); @@ -6352,7 +6385,7 @@ void RestoreBoolValue(IntVar* const var) { // ----- API ----- -IntVar* Solver::MakeIntVar(int64 min, int64 max, const std::string& name) { +IntVar* Solver::MakeIntVar(int64_t min, int64_t max, const std::string& name) { if (min == max) { return MakeIntConst(min, name); } @@ -6368,7 +6401,7 @@ IntVar* Solver::MakeIntVar(int64 min, int64 max, const std::string& name) { } } -IntVar* Solver::MakeIntVar(int64 min, int64 max) { +IntVar* Solver::MakeIntVar(int64_t min, int64_t max) { return MakeIntVar(min, max, ""); } @@ -6380,13 +6413,13 @@ IntVar* Solver::MakeBoolVar() { return RegisterIntVar(RevAlloc(new ConcreteBooleanVar(this, ""))); } -IntVar* Solver::MakeIntVar(const std::vector& values, +IntVar* Solver::MakeIntVar(const std::vector& values, const std::string& name) { DCHECK(!values.empty()); // Fast-track the case where we have a single value. if (values.size() == 1) return MakeIntConst(values[0], name); // Sort and remove duplicates. - std::vector unique_sorted_values = values; + std::vector unique_sorted_values = values; gtl::STLSortAndRemoveDuplicates(&unique_sorted_values); // Case when we have a single value, after clean-up. if (unique_sorted_values.size() == 1) return MakeIntConst(values[0], name); @@ -6398,8 +6431,8 @@ IntVar* Solver::MakeIntVar(const std::vector& values, } // Compute the GCD: if it's not 1, we can express the variable's domain as // the product of the GCD and of a domain with smaller values. - int64 gcd = 0; - for (const int64 v : unique_sorted_values) { + int64_t gcd = 0; + for (const int64_t v : unique_sorted_values) { if (gcd == 0) { gcd = std::abs(v); } else { @@ -6413,7 +6446,7 @@ IntVar* Solver::MakeIntVar(const std::vector& values, } } DCHECK_GT(gcd, 1); - for (int64& v : unique_sorted_values) { + for (int64_t& v : unique_sorted_values) { DCHECK_EQ(0, v % gcd); v /= gcd; } @@ -6431,7 +6464,7 @@ IntVar* Solver::MakeIntVar(const std::vector& values, return MakeProd(inner_intvar, gcd)->Var(); } -IntVar* Solver::MakeIntVar(const std::vector& values) { +IntVar* Solver::MakeIntVar(const std::vector& values) { return MakeIntVar(values, ""); } @@ -6444,7 +6477,7 @@ IntVar* Solver::MakeIntVar(const std::vector& values) { return MakeIntVar(values, ""); } -IntVar* Solver::MakeIntConst(int64 val, const std::string& name) { +IntVar* Solver::MakeIntConst(int64_t val, const std::string& name) { // If IntConst is going to be named after its creation, // cp_share_int_consts should be set to false otherwise names can potentially // be overwritten. @@ -6455,7 +6488,7 @@ IntVar* Solver::MakeIntConst(int64 val, const std::string& name) { return RevAlloc(new IntConst(this, val, name)); } -IntVar* Solver::MakeIntConst(int64 val) { return MakeIntConst(val, ""); } +IntVar* Solver::MakeIntConst(int64_t val) { return MakeIntConst(val, ""); } // ----- Int Var and associated methods ----- @@ -6476,7 +6509,7 @@ std::string IndexedName(const std::string& prefix, int index, int max_index) { } } // namespace -void Solver::MakeIntVarArray(int var_count, int64 vmin, int64 vmax, +void Solver::MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string& name, std::vector* vars) { for (int i = 0; i < var_count; ++i) { @@ -6484,14 +6517,14 @@ void Solver::MakeIntVarArray(int var_count, int64 vmin, int64 vmax, } } -void Solver::MakeIntVarArray(int var_count, int64 vmin, int64 vmax, +void Solver::MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, std::vector* vars) { for (int i = 0; i < var_count; ++i) { vars->push_back(MakeIntVar(vmin, vmax)); } } -IntVar** Solver::MakeIntVarArray(int var_count, int64 vmin, int64 vmax, +IntVar** Solver::MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string& name) { IntVar** vars = new IntVar*[var_count]; for (int i = 0; i < var_count; ++i) { @@ -6560,7 +6593,7 @@ IntExpr* Solver::MakeSum(IntExpr* const left, IntExpr* const right) { } } -IntExpr* Solver::MakeSum(IntExpr* const expr, int64 value) { +IntExpr* Solver::MakeSum(IntExpr* const expr, int64_t value) { CHECK_EQ(this, expr->solver()); if (expr->Bound()) { return MakeIntConst(expr->Min() + value); @@ -6587,7 +6620,7 @@ IntExpr* Solver::MakeSum(IntExpr* const expr, int64 value) { case VAR_ADD_CST: { PlusCstVar* const add_var = reinterpret_cast(var); IntVar* const sub_var = add_var->SubVar(); - const int64 new_constant = value + add_var->Constant(); + const int64_t new_constant = value + add_var->Constant(); if (new_constant == 0) { result = sub_var; } else { @@ -6606,7 +6639,7 @@ IntExpr* Solver::MakeSum(IntExpr* const expr, int64 value) { case CST_SUB_VAR: { SubCstIntVar* const add_var = reinterpret_cast(var); IntVar* const sub_var = add_var->SubVar(); - const int64 new_constant = value + add_var->Constant(); + const int64_t new_constant = value + add_var->Constant(); result = RegisterIntExpr( RevAlloc(new SubCstIntVar(this, sub_var, new_constant))); break; @@ -6642,11 +6675,11 @@ IntExpr* Solver::MakeDifference(IntExpr* const left, IntExpr* const right) { } IntExpr* sub_left = nullptr; IntExpr* sub_right = nullptr; - int64 left_coef = 1; - int64 right_coef = 1; + int64_t left_coef = 1; + int64_t right_coef = 1; if (IsProduct(left, &sub_left, &left_coef) && IsProduct(right, &sub_right, &right_coef)) { - const int64 abs_gcd = + const int64_t abs_gcd = MathUtil::GCD64(std::abs(left_coef), std::abs(right_coef)); if (abs_gcd != 0 && abs_gcd != 1) { return MakeProd(MakeDifference(MakeProd(sub_left, left_coef / abs_gcd), @@ -6671,7 +6704,7 @@ IntExpr* Solver::MakeDifference(IntExpr* const left, IntExpr* const right) { } // warning: this is 'value - expr'. -IntExpr* Solver::MakeDifference(int64 value, IntExpr* const expr) { +IntExpr* Solver::MakeDifference(int64_t value, IntExpr* const expr) { CHECK_EQ(this, expr->solver()); if (expr->Bound()) { return MakeIntConst(value - expr->Min()); @@ -6682,7 +6715,7 @@ IntExpr* Solver::MakeDifference(int64 value, IntExpr* const expr) { IntExpr* result = Cache()->FindExprConstantExpression( expr, value, ModelCache::EXPR_CONSTANT_DIFFERENCE); if (result == nullptr) { - if (expr->IsVar() && expr->Min() != kint64min && + if (expr->IsVar() && expr->Min() != std::numeric_limits::min() && !SubOverflows(value, expr->Min()) && !SubOverflows(value, expr->Max())) { IntVar* const var = expr->Var(); @@ -6690,7 +6723,7 @@ IntExpr* Solver::MakeDifference(int64 value, IntExpr* const expr) { case VAR_ADD_CST: { PlusCstVar* const add_var = reinterpret_cast(var); IntVar* const sub_var = add_var->SubVar(); - const int64 new_constant = value - add_var->Constant(); + const int64_t new_constant = value - add_var->Constant(); if (new_constant == 0) { result = sub_var; } else { @@ -6702,7 +6735,7 @@ IntExpr* Solver::MakeDifference(int64 value, IntExpr* const expr) { case CST_SUB_VAR: { SubCstIntVar* const add_var = reinterpret_cast(var); IntVar* const sub_var = add_var->SubVar(); - const int64 new_constant = value - add_var->Constant(); + const int64_t new_constant = value - add_var->Constant(); result = MakeSum(sub_var, new_constant); break; } @@ -6743,7 +6776,7 @@ IntExpr* Solver::MakeOpposite(IntExpr* const expr) { return result; } -IntExpr* Solver::MakeProd(IntExpr* const expr, int64 value) { +IntExpr* Solver::MakeProd(IntExpr* const expr, int64_t value) { CHECK_EQ(this, expr->solver()); IntExpr* result = Cache()->FindExprConstantExpression( expr, value, ModelCache::EXPR_CONSTANT_PROD); @@ -6751,7 +6784,7 @@ IntExpr* Solver::MakeProd(IntExpr* const expr, int64 value) { return result; } else { IntExpr* m_expr = nullptr; - int64 coefficient = 1; + int64_t coefficient = 1; if (IsProduct(expr, &m_expr, &coefficient)) { coefficient *= value; } else { @@ -6765,8 +6798,8 @@ IntExpr* Solver::MakeProd(IntExpr* const expr, int64 value) { } else if (coefficient == -1) { return MakeOpposite(m_expr); } else if (coefficient > 0) { - if (m_expr->Max() > kint64max / coefficient || - m_expr->Min() < kint64min / coefficient) { + if (m_expr->Max() > std::numeric_limits::max() / coefficient || + m_expr->Min() < std::numeric_limits::min() / coefficient) { result = RegisterIntExpr( RevAlloc(new SafeTimesPosIntCstExpr(this, m_expr, coefficient))); } else { @@ -6790,7 +6823,7 @@ IntExpr* Solver::MakeProd(IntExpr* const expr, int64 value) { } namespace { -void ExtractPower(IntExpr** const expr, int64* const exponant) { +void ExtractPower(IntExpr** const expr, int64_t* const exponant) { if (dynamic_cast(*expr) != nullptr) { BasePower* const power = dynamic_cast(*expr); *expr = power->expr(); @@ -6817,7 +6850,7 @@ void ExtractPower(IntExpr** const expr, int64* const exponant) { } } -void ExtractProduct(IntExpr** const expr, int64* const coefficient, +void ExtractProduct(IntExpr** const expr, int64_t* const coefficient, bool* modified) { if (dynamic_cast(*expr) != nullptr) { TimesCstIntVar* const left_prod = dynamic_cast(*expr); @@ -6846,8 +6879,8 @@ IntExpr* Solver::MakeProd(IntExpr* const left, IntExpr* const right) { IntExpr* m_left = left; IntExpr* m_right = right; - int64 left_exponant = 1; - int64 right_exponant = 1; + int64_t left_exponant = 1; + int64_t right_exponant = 1; ExtractPower(&m_left, &left_exponant); ExtractPower(&m_right, &right_exponant); @@ -6859,7 +6892,7 @@ IntExpr* Solver::MakeProd(IntExpr* const left, IntExpr* const right) { m_left = left; m_right = right; - int64 coefficient = 1; + int64_t coefficient = 1; bool modified = false; ExtractProduct(&m_left, &coefficient, &modified); @@ -6900,7 +6933,7 @@ IntExpr* Solver::MakeProd(IntExpr* const left, IntExpr* const right) { } } else if (left->Min() >= 0 && right->Min() >= 0) { if (CapProd(left->Max(), right->Max()) == - kint64max) { // Potential overflow. + std::numeric_limits::max()) { // Potential overflow. result = RegisterIntExpr(RevAlloc(new SafeTimesPosIntExpr(this, left, right))); } else { @@ -6953,7 +6986,7 @@ IntExpr* Solver::MakeDiv(IntExpr* const numerator, IntExpr* const denominator) { return result; } -IntExpr* Solver::MakeDiv(IntExpr* const expr, int64 value) { +IntExpr* Solver::MakeDiv(IntExpr* const expr, int64_t value) { CHECK(expr != nullptr); CHECK_EQ(this, expr->solver()); if (expr->Bound()) { @@ -6990,7 +7023,7 @@ IntExpr* Solver::MakeAbs(IntExpr* const e) { } IntExpr* result = Cache()->FindExprExpression(e, ModelCache::EXPR_ABS); if (result == nullptr) { - int64 coefficient = 1; + int64_t coefficient = 1; IntExpr* expr = nullptr; if (IsProduct(e, &expr, &coefficient)) { result = MakeProd(MakeAbs(expr), std::abs(coefficient)); @@ -7005,7 +7038,7 @@ IntExpr* Solver::MakeAbs(IntExpr* const e) { IntExpr* Solver::MakeSquare(IntExpr* const expr) { CHECK_EQ(this, expr->solver()); if (expr->Bound()) { - const int64 v = expr->Min(); + const int64_t v = expr->Min(); return MakeIntConst(v * v); } IntExpr* result = Cache()->FindExprExpression(expr, ModelCache::EXPR_SQUARE); @@ -7020,13 +7053,13 @@ IntExpr* Solver::MakeSquare(IntExpr* const expr) { return result; } -IntExpr* Solver::MakePower(IntExpr* const expr, int64 n) { +IntExpr* Solver::MakePower(IntExpr* const expr, int64_t n) { CHECK_EQ(this, expr->solver()); CHECK_GE(n, 0); if (expr->Bound()) { - const int64 v = expr->Min(); + const int64_t v = expr->Min(); if (v >= OverflowLimit(n)) { // Overflow. - return MakeIntConst(kint64max); + return MakeIntConst(std::numeric_limits::max()); } return MakeIntConst(IntPower(v, n)); } @@ -7072,7 +7105,7 @@ IntExpr* Solver::MakeMin(IntExpr* const left, IntExpr* const right) { return RegisterIntExpr(RevAlloc(new MinIntExpr(this, left, right))); } -IntExpr* Solver::MakeMin(IntExpr* const expr, int64 value) { +IntExpr* Solver::MakeMin(IntExpr* const expr, int64_t value) { CHECK_EQ(this, expr->solver()); if (value <= expr->Min()) { return MakeIntConst(value); @@ -7087,7 +7120,7 @@ IntExpr* Solver::MakeMin(IntExpr* const expr, int64 value) { } IntExpr* Solver::MakeMin(IntExpr* const expr, int value) { - return MakeMin(expr, static_cast(value)); + return MakeMin(expr, static_cast(value)); } IntExpr* Solver::MakeMax(IntExpr* const left, IntExpr* const right) { @@ -7108,7 +7141,7 @@ IntExpr* Solver::MakeMax(IntExpr* const left, IntExpr* const right) { return RegisterIntExpr(RevAlloc(new MaxIntExpr(this, left, right))); } -IntExpr* Solver::MakeMax(IntExpr* const expr, int64 value) { +IntExpr* Solver::MakeMax(IntExpr* const expr, int64_t value) { CHECK_EQ(this, expr->solver()); if (expr->Bound()) { return MakeIntConst(std::max(expr->Min(), value)); @@ -7123,21 +7156,21 @@ IntExpr* Solver::MakeMax(IntExpr* const expr, int64 value) { } IntExpr* Solver::MakeMax(IntExpr* const expr, int value) { - return MakeMax(expr, static_cast(value)); + return MakeMax(expr, static_cast(value)); } -IntExpr* Solver::MakeConvexPiecewiseExpr(IntExpr* expr, int64 early_cost, - int64 early_date, int64 late_date, - int64 late_cost) { +IntExpr* Solver::MakeConvexPiecewiseExpr(IntExpr* expr, int64_t early_cost, + int64_t early_date, int64_t late_date, + int64_t late_cost) { return RegisterIntExpr(RevAlloc(new SimpleConvexPiecewiseExpr( this, expr, early_cost, early_date, late_date, late_cost))); } -IntExpr* Solver::MakeSemiContinuousExpr(IntExpr* const expr, int64 fixed_charge, - int64 step) { +IntExpr* Solver::MakeSemiContinuousExpr(IntExpr* const expr, + int64_t fixed_charge, int64_t step) { if (step == 0) { if (fixed_charge == 0) { - return MakeIntConst(int64{0}); + return MakeIntConst(int64_t{0}); } else { return RegisterIntExpr( RevAlloc(new SemiContinuousStepZeroExpr(this, expr, fixed_charge))); @@ -7161,26 +7194,26 @@ class PiecewiseLinearExpr : public BaseIntExpr { const PiecewiseLinearFunction& f) : BaseIntExpr(solver), expr_(expr), f_(f) {} ~PiecewiseLinearExpr() override {} - int64 Min() const override { + int64_t Min() const override { return f_.GetMinimum(expr_->Min(), expr_->Max()); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { const auto& range = f_.GetSmallestRangeGreaterThanValue(expr_->Min(), expr_->Max(), m); expr_->SetRange(range.first, range.second); } - int64 Max() const override { + int64_t Max() const override { return f_.GetMaximum(expr_->Min(), expr_->Max()); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { const auto& range = f_.GetSmallestRangeLessThanValue(expr_->Min(), expr_->Max(), m); expr_->SetRange(range.first, range.second); } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { const auto& range = f_.GetSmallestRangeInValueRange(expr_->Min(), expr_->Max(), l, u); expr_->SetRange(range.first, range.second); @@ -7215,7 +7248,7 @@ IntExpr* Solver::MakePiecewiseLinearExpr(IntExpr* expr, IntExpr* Solver::MakeConditionalExpression(IntVar* const condition, IntExpr* const expr, - int64 unperformed_value) { + int64_t unperformed_value) { if (condition->Min() == 1) { return expr; } else if (condition->Max() == 0) { @@ -7237,7 +7270,7 @@ IntExpr* Solver::MakeConditionalExpression(IntVar* const condition, // ----- Modulo ----- -IntExpr* Solver::MakeModulo(IntExpr* const x, int64 mod) { +IntExpr* Solver::MakeModulo(IntExpr* const x, int64_t mod) { IntVar* const result = MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->Var(); if (mod >= 0) { @@ -7263,7 +7296,7 @@ IntExpr* Solver::MakeModulo(IntExpr* const x, IntExpr* const mod) { int IntVar::VarType() const { return UNSPECIFIED; } -void IntVar::RemoveValues(const std::vector& values) { +void IntVar::RemoveValues(const std::vector& values) { // TODO(user): Check and maybe inline this code. const int size = values.size(); DCHECK_GE(size, 0); @@ -7290,7 +7323,7 @@ void IntVar::RemoveValues(const std::vector& values) { // 4 values, let's start doing some more clever things. // TODO(user) : Sort values! int start_index = 0; - int64 new_min = Min(); + int64_t new_min = Min(); if (values[start_index] <= new_min) { while (start_index < size - 1 && values[start_index + 1] == values[start_index] + 1) { @@ -7299,7 +7332,7 @@ void IntVar::RemoveValues(const std::vector& values) { } } int end_index = size - 1; - int64 new_max = Max(); + int64_t new_max = Max(); if (values[end_index] >= new_max) { while (end_index > start_index + 1 && values[end_index - 1] == values[end_index] - 1) { @@ -7320,7 +7353,7 @@ void IntVar::Accept(ModelVisitor* const visitor) const { visitor->VisitIntegerVariable(this, casted); } -void IntVar::SetValues(const std::vector& values) { +void IntVar::SetValues(const std::vector& values) { switch (values.size()) { case 0: { solver()->Fail(); @@ -7333,8 +7366,8 @@ void IntVar::SetValues(const std::vector& values) { case 2: { if (Contains(values[0])) { if (Contains(values[1])) { - const int64 l = std::min(values[0], values[1]); - const int64 u = std::max(values[0], values[1]); + const int64_t l = std::min(values[0], values[1]); + const int64_t u = std::max(values[0], values[1]); SetRange(l, u); if (u > l + 1) { RemoveInterval(l + 1, u - 1); @@ -7354,14 +7387,14 @@ void IntVar::SetValues(const std::vector& values) { // STLSortAndRemoveDuplicates from ortools/base/stl_util.h to the // existing open_source/base/stl_util.h and using it here. // TODO(user): We could filter out values not in the var. - std::vector& tmp = solver()->tmp_vector_; + std::vector& tmp = solver()->tmp_vector_; tmp.clear(); tmp.insert(tmp.end(), values.begin(), values.end()); std::sort(tmp.begin(), tmp.end()); tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end()); const int size = tmp.size(); - const int64 vmin = Min(); - const int64 vmax = Max(); + const int64_t vmin = Min(); + const int64_t vmax = Max(); int first = 0; int last = size - 1; if (tmp.front() > vmax || tmp.back() < vmin) { @@ -7381,8 +7414,8 @@ void IntVar::SetValues(const std::vector& values) { DCHECK_GE(last, first); SetRange(tmp[first], tmp[last]); while (first < last) { - const int64 start = tmp[first] + 1; - const int64 end = tmp[first + 1] - 1; + const int64_t start = tmp[first] + 1; + const int64_t end = tmp[first + 1] - 1; if (start <= end) { RemoveInterval(start, end); } @@ -7415,7 +7448,7 @@ IntVar* BaseIntExpr::Var() { } IntVar* BaseIntExpr::CastToVar() { - int64 vmin, vmax; + int64_t vmin, vmax; Range(&vmin, &vmax); IntVar* const var = solver()->MakeIntVar(vmin, vmax); LinkVarExpr(solver(), this, var); @@ -7459,7 +7492,7 @@ bool Solver::IsBooleanVar(IntExpr* const expr, IntVar** inner_var, } bool Solver::IsProduct(IntExpr* const expr, IntExpr** inner_expr, - int64* coefficient) { + int64_t* coefficient) { if (dynamic_cast(expr) != nullptr) { TimesCstIntVar* const var = dynamic_cast(expr); *coefficient = var->Constant(); diff --git a/ortools/constraint_solver/graph_constraints.cc b/ortools/constraint_solver/graph_constraints.cc index 249cf0d779..69415a8b34 100644 --- a/ortools/constraint_solver/graph_constraints.cc +++ b/ortools/constraint_solver/graph_constraints.cc @@ -12,6 +12,7 @@ // limitations under the License. #include +#include #include #include #include @@ -72,20 +73,20 @@ class NoCycle : public Constraint { } private: - int64 size() const { return nexts_.size(); } + int64_t size() const { return nexts_.size(); } const std::vector nexts_; const std::vector active_; std::vector iterators_; - RevArray starts_; - RevArray ends_; + RevArray starts_; + RevArray ends_; RevArray marked_; bool all_nexts_bound_; - std::vector outbound_supports_; - std::vector support_leaves_; - std::vector unsupported_; + std::vector outbound_supports_; + std::vector support_leaves_; + std::vector unsupported_; Solver::IndexFilter1 sink_handler_; - std::vector sinks_; + std::vector sinks_; bool assume_paths_; }; @@ -151,8 +152,8 @@ void NoCycle::Post() { active_[i]->WhenBound(active_demon); } // Setting up sinks - int64 min_min = nexts_[0]->Min(); - int64 max_max = nexts_[0]->Max(); + int64_t min_min = nexts_[0]->Min(); + int64_t max_max = nexts_[0]->Max(); for (int i = 1; i < size(); ++i) { const IntVar* next = nexts_[i]; min_min = std::min(min_min, next->Min()); @@ -202,9 +203,9 @@ void NoCycle::NextBound(int index) { // Subtle: marking indices to avoid overwriting chain starts and ends if // propagation for active_[index] or nexts_[index] has already been done. marked_.SetValue(s, index, true); - const int64 next = nexts_[index]->Value(); - const int64 chain_start = starts_[index]; - const int64 chain_end = !sink_handler_(next) ? ends_[next] : next; + const int64_t next = nexts_[index]->Value(); + const int64_t chain_start = starts_[index]; + const int64_t chain_end = !sink_handler_(next) ? ends_[next] : next; if (!sink_handler_(chain_start)) { ends_.SetValue(s, chain_start, chain_end); if (!sink_handler_(chain_end)) { @@ -212,7 +213,7 @@ void NoCycle::NextBound(int index) { nexts_[chain_end]->RemoveValue(chain_start); if (!assume_paths_) { for (int i = 0; i < size(); ++i) { - int64 current = i; + int64_t current = i; bool found = (current == chain_end); // Counter to detect implicit cycles. int count = 0; @@ -252,7 +253,7 @@ void NoCycle::ComputeSupports() { const IntVar* next = nexts_[i]; // If node is not active, no need to try to connect it to a sink. if (active_[i]->Max() != 0) { - const int64 current_support = outbound_supports_[i]; + const int64_t current_support = outbound_supports_[i]; // Optimization: if this node was already supported by a sink, check if // it's still a valid support. if (current_support >= 0 && sink_handler_(current_support) && @@ -271,7 +272,7 @@ void NoCycle::ComputeSupports() { } } } else { - for (const int64 value : InitAndGetValues(iterators_[i])) { + for (const int64_t value : InitAndGetValues(iterators_[i])) { if (sink_handler_(value)) { outbound_supports_[i] = value; support_leaves_.push_back(i); @@ -292,9 +293,9 @@ void NoCycle::ComputeSupports() { size_t leaves_end = support_leaves_.size(); while (!unsupported_.empty()) { // Try to connected unsupported nodes to nodes connected to sinks. - for (int64 unsupported_index = 0; unsupported_index < unsupported_.size(); + for (int64_t unsupported_index = 0; unsupported_index < unsupported_.size(); ++unsupported_index) { - const int64 unsupported = unsupported_[unsupported_index]; + const int64_t unsupported = unsupported_[unsupported_index]; const IntVar* const next = nexts_[unsupported]; for (int i = leaves_begin; i < leaves_end; ++i) { if (next->Contains(support_leaves_[i])) { @@ -318,7 +319,7 @@ void NoCycle::ComputeSupports() { leaves_end = support_leaves_.size(); } // Mark as inactive any unsupported node. - for (int64 unsupported_index = 0; unsupported_index < unsupported_.size(); + for (int64_t unsupported_index = 0; unsupported_index < unsupported_.size(); ++unsupported_index) { active_[unsupported_[unsupported_index]]->SetMax(0); } @@ -328,13 +329,13 @@ void NoCycle::ComputeSupport(int index) { // Try to reconnect the node to the support tree by finding a next node // which is both supported and was not a descendant of the node in the tree. if (active_[index]->Max() != 0) { - for (const int64 next : InitAndGetValues(iterators_[index])) { + for (const int64_t next : InitAndGetValues(iterators_[index])) { if (sink_handler_(next)) { outbound_supports_[index] = next; return; } if (next != index && next < outbound_supports_.size()) { - int64 next_support = outbound_supports_[next]; + int64_t next_support = outbound_supports_[next]; if (next_support >= 0) { // Check if next is not already a descendant of index. bool ancestor_found = false; @@ -500,7 +501,7 @@ class Circuit : public Constraint { } } - void TryInsertReached(int candidate, int64 after) { + void TryInsertReached(int candidate, int64_t after) { if (!reached_[after]) { reached_[after] = true; insertion_queue_.push_back(after); @@ -540,7 +541,7 @@ class Circuit : public Constraint { } default: { IntVarIterator* const domain = domains_[candidate]; - for (const int64 value : InitAndGetValues(domain)) { + for (const int64_t value : InitAndGetValues(domain)) { TryInsertReached(candidate, value); } } @@ -622,8 +623,8 @@ Constraint* Solver::MakeNoCycle(const std::vector& nexts, bool assume_paths) { CHECK_EQ(nexts.size(), active.size()); if (sink_handler == nullptr) { - const int64 size = nexts.size(); - sink_handler = [size](int64 index) { return index >= size; }; + const int64_t size = nexts.size(); + sink_handler = [size](int64_t index) { return index >= size; }; } return RevAlloc(new NoCycle(this, nexts, active, sink_handler, assume_paths)); } @@ -662,7 +663,7 @@ class BasePathCumul : public Constraint { std::string DebugString() const override; protected: - int64 size() const { return nexts_.size(); } + int64_t size() const { return nexts_.size(); } int cumul_size() const { return cumuls_.size(); } const std::vector nexts_; @@ -809,7 +810,7 @@ void PathCumul::Post() { void PathCumul::NextBound(int index) { if (active_[index]->Min() == 0) return; - const int64 next = nexts_[index]->Value(); + const int64_t next = nexts_[index]->Value(); IntVar* cumul = cumuls_[index]; IntVar* cumul_next = cumuls_[next]; IntVar* transit = transits_[index]; @@ -875,7 +876,7 @@ class StampedVector { } std::vector values_; - uint64 stamp_; + uint64_t stamp_; }; } // namespace @@ -900,7 +901,7 @@ class DelayedPathCumul : public Constraint { supports_(nexts.size()), was_bound_(nexts.size(), false), has_cumul_demon_(cumuls.size(), false) { - for (int64 i = 0; i < cumuls_.size(); ++i) { + for (int64_t i = 0; i < cumuls_.size(); ++i) { cumul_transit_demons_[i] = MakeDelayedConstraintDemon1( solver, this, &DelayedPathCumul::CumulRange, "CumulRange", i); chain_starts_[i] = i; @@ -975,7 +976,7 @@ class DelayedPathCumul : public Constraint { IntVar* const next_var = nexts_[touched]; if (!was_bound_[touched] && next_var->Bound() && active_[touched]->Min() > 0) { - const int64 next = next_var->Min(); + const int64_t next = next_var->Min(); was_bound_.SetValue(solver(), touched, true); chain_starts_[chain_ends_[next]] = chain_starts_[touched]; chain_ends_[chain_starts_[touched]] = chain_ends_[next]; @@ -988,8 +989,8 @@ class DelayedPathCumul : public Constraint { // Is touched the start of a chain ? if (is_chain_start_[touched]) { // Propagate min cumuls from chain_starts[touch] to chain_ends_[touch]. - int64 current = touched; - int64 next = nexts_[current]->Min(); + int64_t current = touched; + int64_t next = nexts_[current]->Min(); while (current != chain_ends_[touched]) { prevs_.SetValue(solver(), next, current); PropagateLink(current, next); @@ -999,7 +1000,7 @@ class DelayedPathCumul : public Constraint { } } // Propagate max cumuls from chain_ends_[i] to chain_starts_[i]. - int64 prev = prevs_[current]; + int64_t prev = prevs_[current]; while (current != touched) { PropagateLink(prev, current); current = prev; @@ -1057,7 +1058,7 @@ class DelayedPathCumul : public Constraint { } private: - void CumulRange(int64 index) { + void CumulRange(int64_t index) { if (index < nexts_.size()) { if (nexts_[index]->Bound()) { if (active_[index]->Min() > 0) { @@ -1090,16 +1091,16 @@ class DelayedPathCumul : public Constraint { active_[index]->SetMax(0); } } - void PropagateLink(int64 index, int64 next) { + void PropagateLink(int64_t index, int64_t next) { IntVar* const cumul_var = cumuls_[index]; IntVar* const next_cumul_var = cumuls_[next]; IntVar* const transit = transits_[index]; - const int64 transit_min = transit->Min(); - const int64 transit_max = transit->Max(); + const int64_t transit_min = transit->Min(); + const int64_t transit_max = transit->Max(); next_cumul_var->SetMin(CapAdd(cumul_var->Min(), transit_min)); next_cumul_var->SetMax(CapAdd(cumul_var->Max(), transit_max)); - const int64 next_cumul_min = next_cumul_var->Min(); - const int64 next_cumul_max = next_cumul_var->Max(); + const int64_t next_cumul_min = next_cumul_var->Min(); + const int64_t next_cumul_max = next_cumul_var->Max(); cumul_var->SetMin(CapSub(next_cumul_min, transit_max)); cumul_var->SetMax(CapSub(next_cumul_max, transit_min)); transit->SetMin(CapSub(next_cumul_min, cumul_var->Max())); @@ -1120,8 +1121,8 @@ class DelayedPathCumul : public Constraint { std::vector cumul_transit_demons_; Demon* path_demon_; StampedVector touched_; - std::vector chain_starts_; - std::vector chain_ends_; + std::vector chain_starts_; + std::vector chain_ends_; std::vector is_chain_start_; RevArray prevs_; std::vector supports_; @@ -1169,10 +1170,10 @@ IndexEvaluator2PathCumul::IndexEvaluator2PathCumul( void IndexEvaluator2PathCumul::NextBound(int index) { if (active_[index]->Min() == 0) return; - const int64 next = nexts_[index]->Value(); + const int64_t next = nexts_[index]->Value(); IntVar* cumul = cumuls_[index]; IntVar* cumul_next = cumuls_[next]; - const int64 transit = transits_evaluator_(index, next); + const int64_t transit = transits_evaluator_(index, next); cumul_next->SetMin(cumul->Min() + transit); cumul_next->SetMax(CapAdd(cumul->Max(), transit)); cumul->SetMin(CapSub(cumul_next->Min(), transit)); @@ -1185,7 +1186,7 @@ void IndexEvaluator2PathCumul::NextBound(int index) { bool IndexEvaluator2PathCumul::AcceptLink(int i, int j) const { const IntVar* const cumul_i = cumuls_[i]; const IntVar* const cumul_j = cumuls_[j]; - const int64 transit = transits_evaluator_(i, j); + const int64_t transit = transits_evaluator_(i, j); return transit <= CapSub(cumul_j->Max(), cumul_i->Min()) && CapSub(cumul_j->Min(), cumul_i->Max()) <= transit; } @@ -1264,13 +1265,15 @@ void IndexEvaluator2SlackPathCumul::SlackRange(int index) { void IndexEvaluator2SlackPathCumul::NextBound(int index) { if (active_[index]->Min() == 0) return; - const int64 next = nexts_[index]->Value(); + const int64_t next = nexts_[index]->Value(); IntVar* const cumul = cumuls_[index]; IntVar* const cumul_next = cumuls_[next]; IntVar* const slack = slacks_[index]; - const int64 transit = transits_evaluator_(index, next); - const int64 cumul_next_minus_transit_min = CapSub(cumul_next->Min(), transit); - const int64 cumul_next_minus_transit_max = CapSub(cumul_next->Max(), transit); + const int64_t transit = transits_evaluator_(index, next); + const int64_t cumul_next_minus_transit_min = + CapSub(cumul_next->Min(), transit); + const int64_t cumul_next_minus_transit_max = + CapSub(cumul_next->Max(), transit); cumul_next->SetMin(CapAdd(CapAdd(cumul->Min(), transit), slack->Min())); cumul_next->SetMax(CapAdd(CapAdd(cumul->Max(), transit), slack->Max())); cumul->SetMin(CapSub(cumul_next_minus_transit_min, slack->Max())); @@ -1286,7 +1289,7 @@ bool IndexEvaluator2SlackPathCumul::AcceptLink(int i, int j) const { const IntVar* const cumul_i = cumuls_[i]; const IntVar* const cumul_j = cumuls_[j]; const IntVar* const slack = slacks_[i]; - const int64 transit = transits_evaluator_(i, j); + const int64_t transit = transits_evaluator_(i, j); return CapAdd(transit, slack->Min()) <= CapSub(cumul_j->Max(), cumul_i->Min()) && CapSub(cumul_j->Min(), cumul_i->Max()) <= @@ -1337,8 +1340,9 @@ namespace { class PathConnectedConstraint : public Constraint { public: PathConnectedConstraint(Solver* solver, std::vector nexts, - const std::vector& sources, - std::vector sinks, std::vector status) + const std::vector& sources, + std::vector sinks, + std::vector status) : Constraint(solver), sources_(sources.size(), -1), index_to_path_(nexts.size(), -1), @@ -1349,7 +1353,7 @@ class PathConnectedConstraint : public Constraint { CHECK_EQ(status_.size(), sources_.size()); CHECK_EQ(status_.size(), sinks_.size()); for (int i = 0; i < status_.size(); ++i) { - const int64 source = sources[i]; + const int64_t source = sources[i]; sources_.SetValue(solver, i, source); if (source < index_to_path_.size()) { index_to_path_.SetValue(solver, source, i); @@ -1383,7 +1387,7 @@ class PathConnectedConstraint : public Constraint { for (int i = 0; i < sources_.size(); ++i) { elements.push_back(absl::StrCat(sources_[i])); } - for (int64 sink : sinks_) { + for (int64_t sink : sinks_) { elements.push_back(absl::StrCat(sink)); } for (IntVar* const status : status_) { @@ -1402,8 +1406,8 @@ class PathConnectedConstraint : public Constraint { } void EvaluatePath(int path) { touched_.SparseClearAll(); - int64 source = sources_[path]; - const int64 end = sinks_[path]; + int64_t source = sources_[path]; + const int64_t end = sinks_[path]; while (source != end) { if (source >= nexts_.size() || touched_[source]) { status_[path]->SetValue(0); @@ -1422,18 +1426,18 @@ class PathConnectedConstraint : public Constraint { status_[path]->SetValue(1); } - RevArray sources_; + RevArray sources_; RevArray index_to_path_; - const std::vector sinks_; + const std::vector sinks_; const std::vector nexts_; const std::vector status_; - SparseBitset touched_; + SparseBitset touched_; }; } // namespace Constraint* Solver::MakePathConnected(std::vector nexts, - std::vector sources, - std::vector sinks, + std::vector sources, + std::vector sinks, std::vector status) { return RevAlloc(new PathConnectedConstraint( this, std::move(nexts), sources, std::move(sinks), std::move(status))); @@ -1528,7 +1532,7 @@ class PathTransitPrecedenceConstraint : public Constraint { forbidden_.clear(); marked_.clear(); pushed_.clear(); - int64 transit_cumul = 0; + int64_t transit_cumul = 0; const bool has_transits = !transits_.empty(); while (current < nexts_.size() && current != end) { transit_cumuls_[current] = transit_cumul; @@ -1598,7 +1602,7 @@ class PathTransitPrecedenceConstraint : public Constraint { absl::flat_hash_set forbidden_; absl::flat_hash_set marked_; std::deque pushed_; - std::vector transit_cumuls_; + std::vector transit_cumuls_; }; Constraint* MakePathTransitTypedPrecedenceConstraint( diff --git a/ortools/constraint_solver/interval.cc b/ortools/constraint_solver/interval.cc index f2467aa081..60a3b9c6a2 100644 --- a/ortools/constraint_solver/interval.cc +++ b/ortools/constraint_solver/interval.cc @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include #include @@ -37,15 +39,16 @@ namespace operations_research { IntExpr* BuildStartExpr(IntervalVar* var); IntExpr* BuildDurationExpr(IntervalVar* var); IntExpr* BuildEndExpr(IntervalVar* var); -IntExpr* BuildSafeStartExpr(IntervalVar* var, int64 unperformed_value); -IntExpr* BuildSafeDurationExpr(IntervalVar* var, int64 unperformed_value); -IntExpr* BuildSafeEndExpr(IntervalVar* var, int64 unperformed_value); +IntExpr* BuildSafeStartExpr(IntervalVar* var, int64_t unperformed_value); +IntExpr* BuildSafeDurationExpr(IntervalVar* var, int64_t unperformed_value); +IntExpr* BuildSafeEndExpr(IntervalVar* var, int64_t unperformed_value); void LinkVarExpr(Solver* const s, IntExpr* const expr, IntVar* const var); // It's good to have the two extreme values being symmetrical around zero: it // makes mirroring easier. -const int64 IntervalVar::kMaxValidValue = kint64max >> 2; -const int64 IntervalVar::kMinValidValue = -kMaxValidValue; +const int64_t IntervalVar::kMaxValidValue = + std::numeric_limits::max() >> 2; +const int64_t IntervalVar::kMinValidValue = -kMaxValidValue; namespace { enum IntervalField { START, DURATION, END }; @@ -61,37 +64,41 @@ class MirrorIntervalVar : public IntervalVar { // These methods query, set and watch the start position of the // interval var. - int64 StartMin() const override { return -t_->EndMax(); } - int64 StartMax() const override { return -t_->EndMin(); } - void SetStartMin(int64 m) override { t_->SetEndMax(-m); } - void SetStartMax(int64 m) override { t_->SetEndMin(-m); } - void SetStartRange(int64 mi, int64 ma) override { t_->SetEndRange(-ma, -mi); } - int64 OldStartMin() const override { return -t_->OldEndMax(); } - int64 OldStartMax() const override { return -t_->OldEndMin(); } + int64_t StartMin() const override { return -t_->EndMax(); } + int64_t StartMax() const override { return -t_->EndMin(); } + void SetStartMin(int64_t m) override { t_->SetEndMax(-m); } + void SetStartMax(int64_t m) override { t_->SetEndMin(-m); } + void SetStartRange(int64_t mi, int64_t ma) override { + t_->SetEndRange(-ma, -mi); + } + int64_t OldStartMin() const override { return -t_->OldEndMax(); } + int64_t OldStartMax() const override { return -t_->OldEndMin(); } void WhenStartRange(Demon* const d) override { t_->WhenEndRange(d); } void WhenStartBound(Demon* const d) override { t_->WhenEndBound(d); } // These methods query, set and watch the duration of the interval var. - int64 DurationMin() const override { return t_->DurationMin(); } - int64 DurationMax() const override { return t_->DurationMax(); } - void SetDurationMin(int64 m) override { t_->SetDurationMin(m); } - void SetDurationMax(int64 m) override { t_->SetDurationMax(m); } - void SetDurationRange(int64 mi, int64 ma) override { + int64_t DurationMin() const override { return t_->DurationMin(); } + int64_t DurationMax() const override { return t_->DurationMax(); } + void SetDurationMin(int64_t m) override { t_->SetDurationMin(m); } + void SetDurationMax(int64_t m) override { t_->SetDurationMax(m); } + void SetDurationRange(int64_t mi, int64_t ma) override { t_->SetDurationRange(mi, ma); } - int64 OldDurationMin() const override { return t_->OldDurationMin(); } - int64 OldDurationMax() const override { return t_->OldDurationMax(); } + int64_t OldDurationMin() const override { return t_->OldDurationMin(); } + int64_t OldDurationMax() const override { return t_->OldDurationMax(); } void WhenDurationRange(Demon* const d) override { t_->WhenDurationRange(d); } void WhenDurationBound(Demon* const d) override { t_->WhenDurationBound(d); } // These methods query, set and watch the end position of the interval var. - int64 EndMin() const override { return -t_->StartMax(); } - int64 EndMax() const override { return -t_->StartMin(); } - void SetEndMin(int64 m) override { t_->SetStartMax(-m); } - void SetEndMax(int64 m) override { t_->SetStartMin(-m); } - void SetEndRange(int64 mi, int64 ma) override { t_->SetStartRange(-ma, -mi); } - int64 OldEndMin() const override { return -t_->OldStartMax(); } - int64 OldEndMax() const override { return -t_->OldStartMin(); } + int64_t EndMin() const override { return -t_->StartMax(); } + int64_t EndMax() const override { return -t_->StartMin(); } + void SetEndMin(int64_t m) override { t_->SetStartMax(-m); } + void SetEndMax(int64_t m) override { t_->SetStartMin(-m); } + void SetEndRange(int64_t mi, int64_t ma) override { + t_->SetStartRange(-ma, -mi); + } + int64_t OldEndMin() const override { return -t_->OldStartMax(); } + int64_t OldEndMax() const override { return -t_->OldStartMin(); } void WhenEndRange(Demon* const d) override { t_->WhenStartRange(d); } void WhenEndBound(Demon* const d) override { t_->WhenStartBound(d); } @@ -124,13 +131,13 @@ class MirrorIntervalVar : public IntervalVar { // These methods create expressions encapsulating the start, end // and duration of the interval var. If the interval var is // unperformed, they will return the unperformed_value. - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return solver()->MakeOpposite(t_->SafeEndExpr(-unperformed_value)); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return t_->SafeDurationExpr(unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return solver()->MakeOpposite(t_->SafeStartExpr(-unperformed_value)); } @@ -166,55 +173,57 @@ class AlwaysPerformedIntervalVarWrapper : public IntervalVar { end_expr_(nullptr) {} ~AlwaysPerformedIntervalVarWrapper() override {} - int64 StartMin() const override { + int64_t StartMin() const override { return MayUnderlyingBePerformed() ? t_->StartMin() : kMinValidValue; } - int64 StartMax() const override { + int64_t StartMax() const override { return MayUnderlyingBePerformed() ? t_->StartMax() : kMaxValidValue; } - void SetStartMin(int64 m) override { t_->SetStartMin(m); } - void SetStartMax(int64 m) override { t_->SetStartMax(m); } - void SetStartRange(int64 mi, int64 ma) override { t_->SetStartRange(mi, ma); } - int64 OldStartMin() const override { + void SetStartMin(int64_t m) override { t_->SetStartMin(m); } + void SetStartMax(int64_t m) override { t_->SetStartMax(m); } + void SetStartRange(int64_t mi, int64_t ma) override { + t_->SetStartRange(mi, ma); + } + int64_t OldStartMin() const override { return MayUnderlyingBePerformed() ? t_->OldStartMin() : kMinValidValue; } - int64 OldStartMax() const override { + int64_t OldStartMax() const override { return MayUnderlyingBePerformed() ? t_->OldStartMax() : kMaxValidValue; } void WhenStartRange(Demon* const d) override { t_->WhenStartRange(d); } void WhenStartBound(Demon* const d) override { t_->WhenStartBound(d); } - int64 DurationMin() const override { + int64_t DurationMin() const override { return MayUnderlyingBePerformed() ? t_->DurationMin() : 0LL; } - int64 DurationMax() const override { + int64_t DurationMax() const override { return MayUnderlyingBePerformed() ? t_->DurationMax() : 0LL; } - void SetDurationMin(int64 m) override { t_->SetDurationMin(m); } - void SetDurationMax(int64 m) override { t_->SetDurationMax(m); } - void SetDurationRange(int64 mi, int64 ma) override { + void SetDurationMin(int64_t m) override { t_->SetDurationMin(m); } + void SetDurationMax(int64_t m) override { t_->SetDurationMax(m); } + void SetDurationRange(int64_t mi, int64_t ma) override { t_->SetDurationRange(mi, ma); } - int64 OldDurationMin() const override { + int64_t OldDurationMin() const override { return MayUnderlyingBePerformed() ? t_->OldDurationMin() : 0LL; } - int64 OldDurationMax() const override { + int64_t OldDurationMax() const override { return MayUnderlyingBePerformed() ? t_->OldDurationMax() : 0LL; } void WhenDurationRange(Demon* const d) override { t_->WhenDurationRange(d); } void WhenDurationBound(Demon* const d) override { t_->WhenDurationBound(d); } - int64 EndMin() const override { + int64_t EndMin() const override { return MayUnderlyingBePerformed() ? t_->EndMin() : kMinValidValue; } - int64 EndMax() const override { + int64_t EndMax() const override { return MayUnderlyingBePerformed() ? t_->EndMax() : kMaxValidValue; } - void SetEndMin(int64 m) override { t_->SetEndMin(m); } - void SetEndMax(int64 m) override { t_->SetEndMax(m); } - void SetEndRange(int64 mi, int64 ma) override { t_->SetEndRange(mi, ma); } - int64 OldEndMin() const override { + void SetEndMin(int64_t m) override { t_->SetEndMin(m); } + void SetEndMax(int64_t m) override { t_->SetEndMax(m); } + void SetEndRange(int64_t mi, int64_t ma) override { t_->SetEndRange(mi, ma); } + int64_t OldEndMin() const override { return MayUnderlyingBePerformed() ? t_->OldEndMin() : kMinValidValue; } - int64 OldEndMax() const override { + int64_t OldEndMax() const override { return MayUnderlyingBePerformed() ? t_->OldEndMax() : kMaxValidValue; } void WhenEndRange(Demon* const d) override { t_->WhenEndRange(d); } @@ -256,13 +265,13 @@ class AlwaysPerformedIntervalVarWrapper : public IntervalVar { return end_expr_; } IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return StartExpr(); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return DurationExpr(); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { return EndExpr(); } + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); } protected: IntervalVar* const underlying() const { return t_; } @@ -296,21 +305,21 @@ class IntervalVarRelaxedMax : public AlwaysPerformedIntervalVarWrapper { explicit IntervalVarRelaxedMax(IntervalVar* const t) : AlwaysPerformedIntervalVarWrapper(t) {} ~IntervalVarRelaxedMax() override {} - int64 StartMax() const override { + int64_t StartMax() const override { // It matters to use DurationMin() and not underlying()->DurationMin() here. return underlying()->MustBePerformed() ? underlying()->StartMax() : (kMaxValidValue - DurationMin()); } - void SetStartMax(int64 m) override { + void SetStartMax(int64_t m) override { LOG(FATAL) << "Calling SetStartMax on a IntervalVarRelaxedMax is not supported, " << "as it seems there is no legitimate use case."; } - int64 EndMax() const override { + int64_t EndMax() const override { return underlying()->MustBePerformed() ? underlying()->EndMax() : kMaxValidValue; } - void SetEndMax(int64 m) override { + void SetEndMax(int64_t m) override { LOG(FATAL) << "Calling SetEndMax on a IntervalVarRelaxedMax is not supported, " << "as it seems there is no legitimate use case."; @@ -346,21 +355,21 @@ class IntervalVarRelaxedMin : public AlwaysPerformedIntervalVarWrapper { explicit IntervalVarRelaxedMin(IntervalVar* const t) : AlwaysPerformedIntervalVarWrapper(t) {} ~IntervalVarRelaxedMin() override {} - int64 StartMin() const override { + int64_t StartMin() const override { return underlying()->MustBePerformed() ? underlying()->StartMin() : kMinValidValue; } - void SetStartMin(int64 m) override { + void SetStartMin(int64_t m) override { LOG(FATAL) << "Calling SetStartMin on a IntervalVarRelaxedMin is not supported, " << "as it seems there is no legitimate use case."; } - int64 EndMin() const override { + int64_t EndMin() const override { // It matters to use DurationMin() and not underlying()->DurationMin() here. return underlying()->MustBePerformed() ? underlying()->EndMin() : (kMinValidValue + DurationMin()); } - void SetEndMin(int64 m) override { + void SetEndMin(int64_t m) override { LOG(FATAL) << "Calling SetEndMin on a IntervalVarRelaxedMin is not supported, " << "as it seems there is no legitimate use case."; @@ -423,7 +432,7 @@ class BaseIntervalVar : public IntervalVar { class RangeVar : public IntExpr { public: - RangeVar(Solver* const s, BaseIntervalVar* var, int64 mi, int64 ma) + RangeVar(Solver* const s, BaseIntervalVar* var, int64_t mi, int64_t ma) : IntExpr(s), min_(mi), max_(ma), @@ -438,11 +447,11 @@ class RangeVar : public IntExpr { bool Bound() const override { return min_.Value() == max_.Value(); } - int64 Min() const override { return min_.Value(); } + int64_t Min() const override { return min_.Value(); } - int64 Max() const override { return max_.Value(); } + int64_t Max() const override { return max_.Value(); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { // No Op. if (m <= min_.Value()) { return; @@ -468,12 +477,12 @@ class RangeVar : public IntExpr { } } - int64 OldMin() const { + int64_t OldMin() const { DCHECK(var_->InProcess()); return previous_min_; } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m >= max_.Value()) { return; } @@ -497,9 +506,9 @@ class RangeVar : public IntExpr { } } - int64 OldMax() const { return previous_min_; } + int64_t OldMax() const { return previous_min_; } - void SetRange(int64 mi, int64 ma) override { + void SetRange(int64_t mi, int64_t ma) override { if (mi <= min_.Value() && ma >= max_.Value()) { // No Op. return; @@ -627,17 +636,17 @@ class RangeVar : public IntExpr { } // The current reversible bounds of the interval. - NumericalRev min_; - NumericalRev max_; + NumericalRev min_; + NumericalRev max_; BaseIntervalVar* const var_; // When in process, the modifications are postponed and stored in // these 2 fields. - int64 postponed_min_; - int64 postponed_max_; + int64_t postponed_min_; + int64_t postponed_max_; // The previous bounds stores the bounds since the last time // ProcessDemons() was run. These are maintained lazily. - int64 previous_min_; - int64 previous_max_; + int64_t previous_min_; + int64_t previous_max_; // Demons attached to the 'bound' event (min == max). SimpleRevFIFO bound_demons_; SimpleRevFIFO delayed_bound_demons_; @@ -669,7 +678,7 @@ class PerformedVar : public BooleanVar { ~PerformedVar() override {} - void SetValue(int64 v) override { + void SetValue(int64_t v) override { if ((v & 0xfffffffffffffffe) != 0 || // Not 0 or 1. (value_ != kUnboundBooleanVarValue && v != value_)) { solver()->Fail(); @@ -689,9 +698,9 @@ class PerformedVar : public BooleanVar { } } - int64 OldMin() const override { return previous_value_ == 1; } + int64_t OldMin() const override { return previous_value_ == 1; } - int64 OldMax() const override { return previous_value_ != 0; } + int64_t OldMax() const override { return previous_value_ != 0; } void RestoreValue() override { previous_value_ = kUnboundBooleanVarValue; @@ -737,20 +746,20 @@ class PerformedVar : public BooleanVar { class FixedDurationIntervalVar : public BaseIntervalVar { public: - FixedDurationIntervalVar(Solver* const s, int64 start_min, int64 start_max, - int64 duration, bool optional, + FixedDurationIntervalVar(Solver* const s, int64_t start_min, + int64_t start_max, int64_t duration, bool optional, const std::string& name); // Unperformed interval. FixedDurationIntervalVar(Solver* const s, const std::string& name); ~FixedDurationIntervalVar() override {} - int64 StartMin() const override; - int64 StartMax() const override; - void SetStartMin(int64 m) override; - void SetStartMax(int64 m) override; - void SetStartRange(int64 mi, int64 ma) override; - int64 OldStartMin() const override { return start_.OldMin(); } - int64 OldStartMax() const override { return start_.OldMax(); } + int64_t StartMin() const override; + int64_t StartMax() const override; + void SetStartMin(int64_t m) override; + void SetStartMax(int64_t m) override; + void SetStartRange(int64_t mi, int64_t ma) override; + int64_t OldStartMin() const override { return start_.OldMin(); } + int64_t OldStartMax() const override { return start_.OldMax(); } void WhenStartRange(Demon* const d) override { if (performed_.Max() == 1) { start_.WhenRange(d); @@ -762,23 +771,27 @@ class FixedDurationIntervalVar : public BaseIntervalVar { } } - int64 DurationMin() const override; - int64 DurationMax() const override; - void SetDurationMin(int64 m) override; - void SetDurationMax(int64 m) override; - void SetDurationRange(int64 mi, int64 ma) override; - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t DurationMin() const override; + int64_t DurationMax() const override; + void SetDurationMin(int64_t m) override; + void SetDurationMax(int64_t m) override; + void SetDurationRange(int64_t mi, int64_t ma) override; + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override; - int64 EndMax() const override; - void SetEndMin(int64 m) override; - void SetEndMax(int64 m) override; - void SetEndRange(int64 mi, int64 ma) override; - int64 OldEndMin() const override { return CapAdd(OldStartMin(), duration_); } - int64 OldEndMax() const override { return CapAdd(OldStartMax(), duration_); } + int64_t EndMin() const override; + int64_t EndMax() const override; + void SetEndMin(int64_t m) override; + void SetEndMax(int64_t m) override; + void SetEndRange(int64_t mi, int64_t ma) override; + int64_t OldEndMin() const override { + return CapAdd(OldStartMin(), duration_); + } + int64_t OldEndMax() const override { + return CapAdd(OldStartMax(), duration_); + } void WhenEndRange(Demon* const d) override { WhenStartRange(d); } void WhenEndBound(Demon* const d) override { WhenStartBound(d); } @@ -802,13 +815,13 @@ class FixedDurationIntervalVar : public BaseIntervalVar { return solver()->MakeSum(StartExpr(), duration_); } IntExpr* PerformedExpr() override { return &performed_; } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return BuildSafeStartExpr(this, unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return BuildSafeDurationExpr(this, unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return BuildSafeEndExpr(this, unperformed_value); } @@ -816,12 +829,12 @@ class FixedDurationIntervalVar : public BaseIntervalVar { private: RangeVar start_; - int64 duration_; + int64_t duration_; PerformedVar performed_; }; FixedDurationIntervalVar::FixedDurationIntervalVar( - Solver* const s, int64 start_min, int64 start_max, int64 duration, + Solver* const s, int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string& name) : BaseIntervalVar(s, name), start_(s, this, start_min, start_max), @@ -852,81 +865,81 @@ void FixedDurationIntervalVar::Process() { performed_.UpdatePreviousValueAndApplyPostponedValue(); } -int64 FixedDurationIntervalVar::StartMin() const { +int64_t FixedDurationIntervalVar::StartMin() const { CHECK_EQ(performed_.Max(), 1); return start_.Min(); } -int64 FixedDurationIntervalVar::StartMax() const { +int64_t FixedDurationIntervalVar::StartMax() const { CHECK_EQ(performed_.Max(), 1); return start_.Max(); } -void FixedDurationIntervalVar::SetStartMin(int64 m) { +void FixedDurationIntervalVar::SetStartMin(int64_t m) { if (performed_.Max() == 1) { start_.SetMin(m); } } -void FixedDurationIntervalVar::SetStartMax(int64 m) { +void FixedDurationIntervalVar::SetStartMax(int64_t m) { if (performed_.Max() == 1) { start_.SetMax(m); } } -void FixedDurationIntervalVar::SetStartRange(int64 mi, int64 ma) { +void FixedDurationIntervalVar::SetStartRange(int64_t mi, int64_t ma) { if (performed_.Max() == 1) { start_.SetRange(mi, ma); } } -int64 FixedDurationIntervalVar::DurationMin() const { +int64_t FixedDurationIntervalVar::DurationMin() const { CHECK_EQ(performed_.Max(), 1); return duration_; } -int64 FixedDurationIntervalVar::DurationMax() const { +int64_t FixedDurationIntervalVar::DurationMax() const { CHECK_EQ(performed_.Max(), 1); return duration_; } -void FixedDurationIntervalVar::SetDurationMin(int64 m) { +void FixedDurationIntervalVar::SetDurationMin(int64_t m) { if (m > duration_) { SetPerformed(false); } } -void FixedDurationIntervalVar::SetDurationMax(int64 m) { +void FixedDurationIntervalVar::SetDurationMax(int64_t m) { if (m < duration_) { SetPerformed(false); } } -void FixedDurationIntervalVar::SetDurationRange(int64 mi, int64 ma) { +void FixedDurationIntervalVar::SetDurationRange(int64_t mi, int64_t ma) { if (mi > duration_ || ma < duration_ || mi > ma) { SetPerformed(false); } } -int64 FixedDurationIntervalVar::EndMin() const { +int64_t FixedDurationIntervalVar::EndMin() const { CHECK_EQ(performed_.Max(), 1); return start_.Min() + duration_; } -int64 FixedDurationIntervalVar::EndMax() const { +int64_t FixedDurationIntervalVar::EndMax() const { CHECK_EQ(performed_.Max(), 1); return CapAdd(start_.Max(), duration_); } -void FixedDurationIntervalVar::SetEndMin(int64 m) { +void FixedDurationIntervalVar::SetEndMin(int64_t m) { SetStartMin(CapSub(m, duration_)); } -void FixedDurationIntervalVar::SetEndMax(int64 m) { +void FixedDurationIntervalVar::SetEndMax(int64_t m) { SetStartMax(CapSub(m, duration_)); } -void FixedDurationIntervalVar::SetEndRange(int64 mi, int64 ma) { +void FixedDurationIntervalVar::SetEndRange(int64_t mi, int64_t ma) { SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } @@ -974,40 +987,44 @@ std::string FixedDurationIntervalVar::DebugString() const { class FixedDurationPerformedIntervalVar : public BaseIntervalVar { public: - FixedDurationPerformedIntervalVar(Solver* const s, int64 start_min, - int64 start_max, int64 duration, + FixedDurationPerformedIntervalVar(Solver* const s, int64_t start_min, + int64_t start_max, int64_t duration, const std::string& name); // Unperformed interval. FixedDurationPerformedIntervalVar(Solver* const s, const std::string& name); ~FixedDurationPerformedIntervalVar() override {} - int64 StartMin() const override; - int64 StartMax() const override; - void SetStartMin(int64 m) override; - void SetStartMax(int64 m) override; - void SetStartRange(int64 mi, int64 ma) override; - int64 OldStartMin() const override { return start_.OldMin(); } - int64 OldStartMax() const override { return start_.OldMax(); } + int64_t StartMin() const override; + int64_t StartMax() const override; + void SetStartMin(int64_t m) override; + void SetStartMax(int64_t m) override; + void SetStartRange(int64_t mi, int64_t ma) override; + int64_t OldStartMin() const override { return start_.OldMin(); } + int64_t OldStartMax() const override { return start_.OldMax(); } void WhenStartRange(Demon* const d) override { start_.WhenRange(d); } void WhenStartBound(Demon* const d) override { start_.WhenBound(d); } - int64 DurationMin() const override; - int64 DurationMax() const override; - void SetDurationMin(int64 m) override; - void SetDurationMax(int64 m) override; - void SetDurationRange(int64 mi, int64 ma) override; - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t DurationMin() const override; + int64_t DurationMax() const override; + void SetDurationMin(int64_t m) override; + void SetDurationMax(int64_t m) override; + void SetDurationRange(int64_t mi, int64_t ma) override; + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override; - int64 EndMax() const override; - void SetEndMin(int64 m) override; - void SetEndMax(int64 m) override; - void SetEndRange(int64 mi, int64 ma) override; - int64 OldEndMin() const override { return CapAdd(OldStartMin(), duration_); } - int64 OldEndMax() const override { return CapAdd(OldStartMax(), duration_); } + int64_t EndMin() const override; + int64_t EndMax() const override; + void SetEndMin(int64_t m) override; + void SetEndMax(int64_t m) override; + void SetEndRange(int64_t mi, int64_t ma) override; + int64_t OldEndMin() const override { + return CapAdd(OldStartMin(), duration_); + } + int64_t OldEndMax() const override { + return CapAdd(OldStartMax(), duration_); + } void WhenEndRange(Demon* const d) override { WhenStartRange(d); } void WhenEndBound(Demon* const d) override { WhenEndRange(d); } @@ -1029,24 +1046,24 @@ class FixedDurationPerformedIntervalVar : public BaseIntervalVar { return solver()->MakeSum(StartExpr(), duration_); } IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return StartExpr(); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return DurationExpr(); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { return EndExpr(); } + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); } private: void CheckOldPerformed() {} void Push() override; RangeVar start_; - int64 duration_; + int64_t duration_; }; FixedDurationPerformedIntervalVar::FixedDurationPerformedIntervalVar( - Solver* const s, int64 start_min, int64 start_max, int64 duration, + Solver* const s, int64_t start_min, int64_t start_max, int64_t duration, const std::string& name) : BaseIntervalVar(s, name), start_(s, this, start_min, start_max), @@ -1068,66 +1085,67 @@ void FixedDurationPerformedIntervalVar::Process() { start_.ApplyPostponedBounds(START); } -int64 FixedDurationPerformedIntervalVar::StartMin() const { +int64_t FixedDurationPerformedIntervalVar::StartMin() const { return start_.Min(); } -int64 FixedDurationPerformedIntervalVar::StartMax() const { +int64_t FixedDurationPerformedIntervalVar::StartMax() const { return start_.Max(); } -void FixedDurationPerformedIntervalVar::SetStartMin(int64 m) { +void FixedDurationPerformedIntervalVar::SetStartMin(int64_t m) { start_.SetMin(m); } -void FixedDurationPerformedIntervalVar::SetStartMax(int64 m) { +void FixedDurationPerformedIntervalVar::SetStartMax(int64_t m) { start_.SetMax(m); } -void FixedDurationPerformedIntervalVar::SetStartRange(int64 mi, int64 ma) { +void FixedDurationPerformedIntervalVar::SetStartRange(int64_t mi, int64_t ma) { start_.SetRange(mi, ma); } -int64 FixedDurationPerformedIntervalVar::DurationMin() const { +int64_t FixedDurationPerformedIntervalVar::DurationMin() const { return duration_; } -int64 FixedDurationPerformedIntervalVar::DurationMax() const { +int64_t FixedDurationPerformedIntervalVar::DurationMax() const { return duration_; } -void FixedDurationPerformedIntervalVar::SetDurationMin(int64 m) { +void FixedDurationPerformedIntervalVar::SetDurationMin(int64_t m) { if (m > duration_) { SetPerformed(false); } } -void FixedDurationPerformedIntervalVar::SetDurationMax(int64 m) { +void FixedDurationPerformedIntervalVar::SetDurationMax(int64_t m) { if (m < duration_) { SetPerformed(false); } } -int64 FixedDurationPerformedIntervalVar::EndMin() const { +int64_t FixedDurationPerformedIntervalVar::EndMin() const { return CapAdd(start_.Min(), duration_); } -int64 FixedDurationPerformedIntervalVar::EndMax() const { +int64_t FixedDurationPerformedIntervalVar::EndMax() const { return CapAdd(start_.Max(), duration_); } -void FixedDurationPerformedIntervalVar::SetEndMin(int64 m) { +void FixedDurationPerformedIntervalVar::SetEndMin(int64_t m) { SetStartMin(CapSub(m, duration_)); } -void FixedDurationPerformedIntervalVar::SetEndMax(int64 m) { +void FixedDurationPerformedIntervalVar::SetEndMax(int64_t m) { SetStartMax(CapSub(m, duration_)); } -void FixedDurationPerformedIntervalVar::SetEndRange(int64 mi, int64 ma) { +void FixedDurationPerformedIntervalVar::SetEndRange(int64_t mi, int64_t ma) { SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } -void FixedDurationPerformedIntervalVar::SetDurationRange(int64 mi, int64 ma) { +void FixedDurationPerformedIntervalVar::SetDurationRange(int64_t mi, + int64_t ma) { if (mi > duration_ || ma < duration_ || mi > ma) { SetPerformed(false); } @@ -1167,36 +1185,40 @@ std::string FixedDurationPerformedIntervalVar::DebugString() const { class StartVarPerformedIntervalVar : public IntervalVar { public: StartVarPerformedIntervalVar(Solver* const s, IntVar* const var, - int64 duration, const std::string& name); + int64_t duration, const std::string& name); ~StartVarPerformedIntervalVar() override {} - int64 StartMin() const override; - int64 StartMax() const override; - void SetStartMin(int64 m) override; - void SetStartMax(int64 m) override; - void SetStartRange(int64 mi, int64 ma) override; - int64 OldStartMin() const override { return start_var_->OldMin(); } - int64 OldStartMax() const override { return start_var_->OldMax(); } + int64_t StartMin() const override; + int64_t StartMax() const override; + void SetStartMin(int64_t m) override; + void SetStartMax(int64_t m) override; + void SetStartRange(int64_t mi, int64_t ma) override; + int64_t OldStartMin() const override { return start_var_->OldMin(); } + int64_t OldStartMax() const override { return start_var_->OldMax(); } void WhenStartRange(Demon* const d) override { start_var_->WhenRange(d); } void WhenStartBound(Demon* const d) override { start_var_->WhenBound(d); } - int64 DurationMin() const override; - int64 DurationMax() const override; - void SetDurationMin(int64 m) override; - void SetDurationMax(int64 m) override; - void SetDurationRange(int64 mi, int64 ma) override; - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t DurationMin() const override; + int64_t DurationMax() const override; + void SetDurationMin(int64_t m) override; + void SetDurationMax(int64_t m) override; + void SetDurationRange(int64_t mi, int64_t ma) override; + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override; - int64 EndMax() const override; - void SetEndMin(int64 m) override; - void SetEndMax(int64 m) override; - void SetEndRange(int64 mi, int64 ma) override; - int64 OldEndMin() const override { return CapAdd(OldStartMin(), duration_); } - int64 OldEndMax() const override { return CapAdd(OldStartMax(), duration_); } + int64_t EndMin() const override; + int64_t EndMax() const override; + void SetEndMin(int64_t m) override; + void SetEndMax(int64_t m) override; + void SetEndRange(int64_t mi, int64_t ma) override; + int64_t OldEndMin() const override { + return CapAdd(OldStartMin(), duration_); + } + int64_t OldEndMax() const override { + return CapAdd(OldStartMax(), duration_); + } void WhenEndRange(Demon* const d) override { start_var_->WhenRange(d); } void WhenEndBound(Demon* const d) override { start_var_->WhenBound(d); } @@ -1213,13 +1235,13 @@ class StartVarPerformedIntervalVar : public IntervalVar { return solver()->MakeSum(start_var_, duration_); } IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return StartExpr(); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return DurationExpr(); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { return EndExpr(); } + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); } void Accept(ModelVisitor* const visitor) const override { visitor->VisitIntervalVariable(this, "", 0, NullInterval()); @@ -1227,70 +1249,71 @@ class StartVarPerformedIntervalVar : public IntervalVar { private: IntVar* const start_var_; - int64 duration_; + int64_t duration_; }; // TODO(user): Take care of overflows. StartVarPerformedIntervalVar::StartVarPerformedIntervalVar( - Solver* const s, IntVar* const var, int64 duration, const std::string& name) + Solver* const s, IntVar* const var, int64_t duration, + const std::string& name) : IntervalVar(s, name), start_var_(var), duration_(duration) {} -int64 StartVarPerformedIntervalVar::StartMin() const { +int64_t StartVarPerformedIntervalVar::StartMin() const { return start_var_->Min(); } -int64 StartVarPerformedIntervalVar::StartMax() const { +int64_t StartVarPerformedIntervalVar::StartMax() const { return start_var_->Max(); } -void StartVarPerformedIntervalVar::SetStartMin(int64 m) { +void StartVarPerformedIntervalVar::SetStartMin(int64_t m) { start_var_->SetMin(m); } -void StartVarPerformedIntervalVar::SetStartMax(int64 m) { +void StartVarPerformedIntervalVar::SetStartMax(int64_t m) { start_var_->SetMax(m); } -void StartVarPerformedIntervalVar::SetStartRange(int64 mi, int64 ma) { +void StartVarPerformedIntervalVar::SetStartRange(int64_t mi, int64_t ma) { start_var_->SetRange(mi, ma); } -int64 StartVarPerformedIntervalVar::DurationMin() const { return duration_; } +int64_t StartVarPerformedIntervalVar::DurationMin() const { return duration_; } -int64 StartVarPerformedIntervalVar::DurationMax() const { return duration_; } +int64_t StartVarPerformedIntervalVar::DurationMax() const { return duration_; } -void StartVarPerformedIntervalVar::SetDurationMin(int64 m) { +void StartVarPerformedIntervalVar::SetDurationMin(int64_t m) { if (m > duration_) { solver()->Fail(); } } -void StartVarPerformedIntervalVar::SetDurationMax(int64 m) { +void StartVarPerformedIntervalVar::SetDurationMax(int64_t m) { if (m < duration_) { solver()->Fail(); } } -int64 StartVarPerformedIntervalVar::EndMin() const { +int64_t StartVarPerformedIntervalVar::EndMin() const { return start_var_->Min() + duration_; } -int64 StartVarPerformedIntervalVar::EndMax() const { +int64_t StartVarPerformedIntervalVar::EndMax() const { return start_var_->Max() + duration_; } -void StartVarPerformedIntervalVar::SetEndMin(int64 m) { +void StartVarPerformedIntervalVar::SetEndMin(int64_t m) { SetStartMin(CapSub(m, duration_)); } -void StartVarPerformedIntervalVar::SetEndMax(int64 m) { +void StartVarPerformedIntervalVar::SetEndMax(int64_t m) { SetStartMax(CapSub(m, duration_)); } -void StartVarPerformedIntervalVar::SetEndRange(int64 mi, int64 ma) { +void StartVarPerformedIntervalVar::SetEndRange(int64_t mi, int64_t ma) { SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } -void StartVarPerformedIntervalVar::SetDurationRange(int64 mi, int64 ma) { +void StartVarPerformedIntervalVar::SetDurationRange(int64_t mi, int64_t ma) { if (mi > duration_ || ma < duration_ || mi > ma) { solver()->Fail(); } @@ -1327,17 +1350,17 @@ std::string StartVarPerformedIntervalVar::DebugString() const { class StartVarIntervalVar : public BaseIntervalVar { public: - StartVarIntervalVar(Solver* const s, IntVar* const start, int64 duration, + StartVarIntervalVar(Solver* const s, IntVar* const start, int64_t duration, IntVar* const performed, const std::string& name); ~StartVarIntervalVar() override {} - int64 StartMin() const override; - int64 StartMax() const override; - void SetStartMin(int64 m) override; - void SetStartMax(int64 m) override; - void SetStartRange(int64 mi, int64 ma) override; - int64 OldStartMin() const override { return start_->OldMin(); } - int64 OldStartMax() const override { return start_->OldMax(); } + int64_t StartMin() const override; + int64_t StartMax() const override; + void SetStartMin(int64_t m) override; + void SetStartMax(int64_t m) override; + void SetStartRange(int64_t mi, int64_t ma) override; + int64_t OldStartMin() const override { return start_->OldMin(); } + int64_t OldStartMax() const override { return start_->OldMax(); } void WhenStartRange(Demon* const d) override { if (performed_->Max() == 1) { start_->WhenRange(d); @@ -1349,23 +1372,27 @@ class StartVarIntervalVar : public BaseIntervalVar { } } - int64 DurationMin() const override; - int64 DurationMax() const override; - void SetDurationMin(int64 m) override; - void SetDurationMax(int64 m) override; - void SetDurationRange(int64 mi, int64 ma) override; - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t DurationMin() const override; + int64_t DurationMax() const override; + void SetDurationMin(int64_t m) override; + void SetDurationMax(int64_t m) override; + void SetDurationRange(int64_t mi, int64_t ma) override; + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override; - int64 EndMax() const override; - void SetEndMin(int64 m) override; - void SetEndMax(int64 m) override; - void SetEndRange(int64 mi, int64 ma) override; - int64 OldEndMin() const override { return CapAdd(OldStartMin(), duration_); } - int64 OldEndMax() const override { return CapAdd(OldStartMax(), duration_); } + int64_t EndMin() const override; + int64_t EndMax() const override; + void SetEndMin(int64_t m) override; + void SetEndMax(int64_t m) override; + void SetEndRange(int64_t mi, int64_t ma) override; + int64_t OldEndMin() const override { + return CapAdd(OldStartMin(), duration_); + } + int64_t OldEndMax() const override { + return CapAdd(OldStartMax(), duration_); + } void WhenEndRange(Demon* const d) override { WhenStartRange(d); } void WhenEndBound(Demon* const d) override { WhenStartBound(d); } @@ -1388,13 +1415,13 @@ class StartVarIntervalVar : public BaseIntervalVar { return solver()->MakeSum(StartExpr(), duration_); } IntExpr* PerformedExpr() override { return performed_; } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return BuildSafeStartExpr(this, unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return BuildSafeDurationExpr(this, unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return BuildSafeEndExpr(this, unperformed_value); } @@ -1402,19 +1429,19 @@ class StartVarIntervalVar : public BaseIntervalVar { void Push() override { LOG(FATAL) << "Should not be here"; } - int64 StoredMin() const { return start_min_.Value(); } - int64 StoredMax() const { return start_max_.Value(); } + int64_t StoredMin() const { return start_min_.Value(); } + int64_t StoredMax() const { return start_max_.Value(); } private: IntVar* const start_; - int64 duration_; + int64_t duration_; IntVar* const performed_; - Rev start_min_; - Rev start_max_; + Rev start_min_; + Rev start_max_; }; StartVarIntervalVar::StartVarIntervalVar(Solver* const s, IntVar* const start, - int64 duration, + int64_t duration, IntVar* const performed, const std::string& name) : BaseIntervalVar(s, name), @@ -1424,17 +1451,17 @@ StartVarIntervalVar::StartVarIntervalVar(Solver* const s, IntVar* const start, start_min_(start->Min()), start_max_(start->Max()) {} -int64 StartVarIntervalVar::StartMin() const { +int64_t StartVarIntervalVar::StartMin() const { DCHECK_EQ(performed_->Max(), 1); return std::max(start_->Min(), start_min_.Value()); } -int64 StartVarIntervalVar::StartMax() const { +int64_t StartVarIntervalVar::StartMax() const { DCHECK_EQ(performed_->Max(), 1); return std::min(start_->Max(), start_max_.Value()); } -void StartVarIntervalVar::SetStartMin(int64 m) { +void StartVarIntervalVar::SetStartMin(int64_t m) { if (performed_->Min() == 1) { start_->SetMin(m); } else { @@ -1445,7 +1472,7 @@ void StartVarIntervalVar::SetStartMin(int64 m) { } } -void StartVarIntervalVar::SetStartMax(int64 m) { +void StartVarIntervalVar::SetStartMax(int64_t m) { if (performed_->Min() == 1) { start_->SetMax(m); } else { @@ -1456,7 +1483,7 @@ void StartVarIntervalVar::SetStartMax(int64 m) { } } -void StartVarIntervalVar::SetStartRange(int64 mi, int64 ma) { +void StartVarIntervalVar::SetStartRange(int64_t mi, int64_t ma) { if (performed_->Min() == 1) { start_->SetRange(mi, ma); } else { @@ -1469,53 +1496,53 @@ void StartVarIntervalVar::SetStartRange(int64 mi, int64 ma) { } } -int64 StartVarIntervalVar::DurationMin() const { +int64_t StartVarIntervalVar::DurationMin() const { DCHECK_EQ(performed_->Max(), 1); return duration_; } -int64 StartVarIntervalVar::DurationMax() const { +int64_t StartVarIntervalVar::DurationMax() const { DCHECK_EQ(performed_->Max(), 1); return duration_; } -void StartVarIntervalVar::SetDurationMin(int64 m) { +void StartVarIntervalVar::SetDurationMin(int64_t m) { if (m > duration_) { SetPerformed(false); } } -void StartVarIntervalVar::SetDurationMax(int64 m) { +void StartVarIntervalVar::SetDurationMax(int64_t m) { if (m < duration_) { SetPerformed(false); } } -void StartVarIntervalVar::SetDurationRange(int64 mi, int64 ma) { +void StartVarIntervalVar::SetDurationRange(int64_t mi, int64_t ma) { if (mi > duration_ || ma < duration_ || mi > ma) { SetPerformed(false); } } -int64 StartVarIntervalVar::EndMin() const { +int64_t StartVarIntervalVar::EndMin() const { DCHECK_EQ(performed_->Max(), 1); return CapAdd(StartMin(), duration_); } -int64 StartVarIntervalVar::EndMax() const { +int64_t StartVarIntervalVar::EndMax() const { DCHECK_EQ(performed_->Max(), 1); return CapAdd(StartMax(), duration_); } -void StartVarIntervalVar::SetEndMin(int64 m) { +void StartVarIntervalVar::SetEndMin(int64_t m) { SetStartMin(CapSub(m, duration_)); } -void StartVarIntervalVar::SetEndMax(int64 m) { +void StartVarIntervalVar::SetEndMax(int64_t m) { SetStartMax(CapSub(m, duration_)); } -void StartVarIntervalVar::SetEndRange(int64 mi, int64 ma) { +void StartVarIntervalVar::SetEndRange(int64_t mi, int64_t ma) { SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } @@ -1598,37 +1625,37 @@ class LinkStartVarIntervalVar : public Constraint { class FixedInterval : public IntervalVar { public: - FixedInterval(Solver* const s, int64 start, int64 duration, + FixedInterval(Solver* const s, int64_t start, int64_t duration, const std::string& name); ~FixedInterval() override {} - int64 StartMin() const override { return start_; } - int64 StartMax() const override { return start_; } - void SetStartMin(int64 m) override; - void SetStartMax(int64 m) override; - void SetStartRange(int64 mi, int64 ma) override; - int64 OldStartMin() const override { return start_; } - int64 OldStartMax() const override { return start_; } + int64_t StartMin() const override { return start_; } + int64_t StartMax() const override { return start_; } + void SetStartMin(int64_t m) override; + void SetStartMax(int64_t m) override; + void SetStartRange(int64_t mi, int64_t ma) override; + int64_t OldStartMin() const override { return start_; } + int64_t OldStartMax() const override { return start_; } void WhenStartRange(Demon* const d) override {} void WhenStartBound(Demon* const d) override {} - int64 DurationMin() const override { return duration_; } - int64 DurationMax() const override { return duration_; } - void SetDurationMin(int64 m) override; - void SetDurationMax(int64 m) override; - void SetDurationRange(int64 mi, int64 ma) override; - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t DurationMin() const override { return duration_; } + int64_t DurationMax() const override { return duration_; } + void SetDurationMin(int64_t m) override; + void SetDurationMax(int64_t m) override; + void SetDurationRange(int64_t mi, int64_t ma) override; + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override { return start_ + duration_; } - int64 EndMax() const override { return start_ + duration_; } - void SetEndMin(int64 m) override; - void SetEndMax(int64 m) override; - void SetEndRange(int64 mi, int64 ma) override; - int64 OldEndMin() const override { return start_ + duration_; } - int64 OldEndMax() const override { return start_ + duration_; } + int64_t EndMin() const override { return start_ + duration_; } + int64_t EndMax() const override { return start_ + duration_; } + void SetEndMin(int64_t m) override; + void SetEndMax(int64_t m) override; + void SetEndRange(int64_t mi, int64_t ma) override; + int64_t OldEndMin() const override { return start_ + duration_; } + int64_t OldEndMax() const override { return start_ + duration_; } void WhenEndRange(Demon* const d) override {} void WhenEndBound(Demon* const d) override {} @@ -1649,72 +1676,72 @@ class FixedInterval : public IntervalVar { return solver()->MakeIntConst(start_ + duration_); } IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return StartExpr(); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return DurationExpr(); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { return EndExpr(); } + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); } private: - const int64 start_; - const int64 duration_; + const int64_t start_; + const int64_t duration_; }; -FixedInterval::FixedInterval(Solver* const s, int64 start, int64 duration, +FixedInterval::FixedInterval(Solver* const s, int64_t start, int64_t duration, const std::string& name) : IntervalVar(s, name), start_(start), duration_(duration) {} -void FixedInterval::SetStartMin(int64 m) { +void FixedInterval::SetStartMin(int64_t m) { if (m > start_) { solver()->Fail(); } } -void FixedInterval::SetStartMax(int64 m) { +void FixedInterval::SetStartMax(int64_t m) { if (m < start_) { solver()->Fail(); } } -void FixedInterval::SetStartRange(int64 mi, int64 ma) { +void FixedInterval::SetStartRange(int64_t mi, int64_t ma) { if (mi > start_ || ma < start_) { solver()->Fail(); } } -void FixedInterval::SetDurationMin(int64 m) { +void FixedInterval::SetDurationMin(int64_t m) { if (m > duration_) { solver()->Fail(); } } -void FixedInterval::SetDurationMax(int64 m) { +void FixedInterval::SetDurationMax(int64_t m) { if (m < duration_) { solver()->Fail(); } } -void FixedInterval::SetEndMin(int64 m) { +void FixedInterval::SetEndMin(int64_t m) { if (m > start_ + duration_) { solver()->Fail(); } } -void FixedInterval::SetEndMax(int64 m) { +void FixedInterval::SetEndMax(int64_t m) { if (m < start_ + duration_) { solver()->Fail(); } } -void FixedInterval::SetEndRange(int64 mi, int64 ma) { +void FixedInterval::SetEndRange(int64_t mi, int64_t ma) { if (mi > start_ + duration_ || ma < start_ + duration_) { solver()->Fail(); } } -void FixedInterval::SetDurationRange(int64 mi, int64 ma) { +void FixedInterval::SetDurationRange(int64_t mi, int64_t ma) { if (mi > duration_ || ma < duration_) { solver()->Fail(); } @@ -1743,9 +1770,10 @@ std::string FixedInterval::DebugString() const { class VariableDurationIntervalVar : public BaseIntervalVar { public: - VariableDurationIntervalVar(Solver* const s, int64 start_min, int64 start_max, - int64 duration_min, int64 duration_max, - int64 end_min, int64 end_max, bool optional, + VariableDurationIntervalVar(Solver* const s, int64_t start_min, + int64_t start_max, int64_t duration_min, + int64_t duration_max, int64_t end_min, + int64_t end_max, bool optional, const std::string& name) : BaseIntervalVar(s, name), start_(s, this, std::max(start_min, CapSub(end_min, duration_max)), @@ -1758,41 +1786,41 @@ class VariableDurationIntervalVar : public BaseIntervalVar { ~VariableDurationIntervalVar() override {} - int64 StartMin() const override { + int64_t StartMin() const override { CHECK_EQ(performed_.Max(), 1); return start_.Min(); } - int64 StartMax() const override { + int64_t StartMax() const override { CHECK_EQ(performed_.Max(), 1); return start_.Max(); } - void SetStartMin(int64 m) override { + void SetStartMin(int64_t m) override { if (performed_.Max() == 1) { start_.SetMin(m); } } - void SetStartMax(int64 m) override { + void SetStartMax(int64_t m) override { if (performed_.Max() == 1) { start_.SetMax(m); } } - void SetStartRange(int64 mi, int64 ma) override { + void SetStartRange(int64_t mi, int64_t ma) override { if (performed_.Max() == 1) { start_.SetRange(mi, ma); } } - int64 OldStartMin() const override { + int64_t OldStartMin() const override { CHECK_EQ(performed_.Max(), 1); CHECK(in_process_); return start_.OldMin(); } - int64 OldStartMax() const override { + int64_t OldStartMax() const override { CHECK_EQ(performed_.Max(), 1); CHECK(in_process_); return start_.OldMax(); @@ -1810,41 +1838,41 @@ class VariableDurationIntervalVar : public BaseIntervalVar { } } - int64 DurationMin() const override { + int64_t DurationMin() const override { CHECK_EQ(performed_.Max(), 1); return duration_.Min(); } - int64 DurationMax() const override { + int64_t DurationMax() const override { CHECK_EQ(performed_.Max(), 1); return duration_.Max(); } - void SetDurationMin(int64 m) override { + void SetDurationMin(int64_t m) override { if (performed_.Max() == 1) { duration_.SetMin(m); } } - void SetDurationMax(int64 m) override { + void SetDurationMax(int64_t m) override { if (performed_.Max() == 1) { duration_.SetMax(m); } } - void SetDurationRange(int64 mi, int64 ma) override { + void SetDurationRange(int64_t mi, int64_t ma) override { if (performed_.Max() == 1) { duration_.SetRange(mi, ma); } } - int64 OldDurationMin() const override { + int64_t OldDurationMin() const override { CHECK_EQ(performed_.Max(), 1); CHECK(in_process_); return duration_.OldMin(); } - int64 OldDurationMax() const override { + int64_t OldDurationMax() const override { CHECK_EQ(performed_.Max(), 1); CHECK(in_process_); return duration_.OldMax(); @@ -1862,41 +1890,41 @@ class VariableDurationIntervalVar : public BaseIntervalVar { } } - int64 EndMin() const override { + int64_t EndMin() const override { CHECK_EQ(performed_.Max(), 1); return end_.Min(); } - int64 EndMax() const override { + int64_t EndMax() const override { CHECK_EQ(performed_.Max(), 1); return end_.Max(); } - void SetEndMin(int64 m) override { + void SetEndMin(int64_t m) override { if (performed_.Max() == 1) { end_.SetMin(m); } } - void SetEndMax(int64 m) override { + void SetEndMax(int64_t m) override { if (performed_.Max() == 1) { end_.SetMax(m); } } - void SetEndRange(int64 mi, int64 ma) override { + void SetEndRange(int64_t mi, int64_t ma) override { if (performed_.Max() == 1) { end_.SetRange(mi, ma); } } - int64 OldEndMin() const override { + int64_t OldEndMin() const override { CHECK_EQ(performed_.Max(), 1); DCHECK(in_process_); return end_.OldMin(); } - int64 OldEndMax() const override { + int64_t OldEndMax() const override { CHECK_EQ(performed_.Max(), 1); DCHECK(in_process_); return end_.OldMax(); @@ -1985,13 +2013,13 @@ class VariableDurationIntervalVar : public BaseIntervalVar { IntExpr* DurationExpr() override { return &duration_; } IntExpr* EndExpr() override { return &end_; } IntExpr* PerformedExpr() override { return &performed_; } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return BuildSafeStartExpr(this, unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return BuildSafeDurationExpr(this, unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return BuildSafeEndExpr(this, unperformed_value); } @@ -2023,43 +2051,47 @@ class VariableDurationIntervalVar : public BaseIntervalVar { class FixedDurationSyncedIntervalVar : public IntervalVar { public: - FixedDurationSyncedIntervalVar(IntervalVar* const t, int64 duration, - int64 offset, const std::string& name) + FixedDurationSyncedIntervalVar(IntervalVar* const t, int64_t duration, + int64_t offset, const std::string& name) : IntervalVar(t->solver(), name), t_(t), duration_(duration), offset_(offset) {} ~FixedDurationSyncedIntervalVar() override {} - int64 DurationMin() const override { return duration_; } - int64 DurationMax() const override { return duration_; } - void SetDurationMin(int64 m) override { + int64_t DurationMin() const override { return duration_; } + int64_t DurationMax() const override { return duration_; } + void SetDurationMin(int64_t m) override { if (m > duration_) { solver()->Fail(); } } - void SetDurationMax(int64 m) override { + void SetDurationMax(int64_t m) override { if (m < duration_) { solver()->Fail(); } } - void SetDurationRange(int64 mi, int64 ma) override { + void SetDurationRange(int64_t mi, int64_t ma) override { if (mi > duration_ || ma < duration_ || mi > ma) { solver()->Fail(); } } - int64 OldDurationMin() const override { return duration_; } - int64 OldDurationMax() const override { return duration_; } + int64_t OldDurationMin() const override { return duration_; } + int64_t OldDurationMax() const override { return duration_; } void WhenDurationRange(Demon* const d) override {} void WhenDurationBound(Demon* const d) override {} - int64 EndMin() const override { return CapAdd(StartMin(), duration_); } - int64 EndMax() const override { return CapAdd(StartMax(), duration_); } - void SetEndMin(int64 m) override { SetStartMin(CapSub(m, duration_)); } - void SetEndMax(int64 m) override { SetStartMax(CapSub(m, duration_)); } - void SetEndRange(int64 mi, int64 ma) override { + int64_t EndMin() const override { return CapAdd(StartMin(), duration_); } + int64_t EndMax() const override { return CapAdd(StartMax(), duration_); } + void SetEndMin(int64_t m) override { SetStartMin(CapSub(m, duration_)); } + void SetEndMax(int64_t m) override { SetStartMax(CapSub(m, duration_)); } + void SetEndRange(int64_t mi, int64_t ma) override { SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_)); } - int64 OldEndMin() const override { return CapAdd(OldStartMin(), duration_); } - int64 OldEndMax() const override { return CapAdd(OldStartMax(), duration_); } + int64_t OldEndMin() const override { + return CapAdd(OldStartMin(), duration_); + } + int64_t OldEndMax() const override { + return CapAdd(OldStartMax(), duration_); + } void WhenEndRange(Demon* const d) override { WhenStartRange(d); } void WhenEndBound(Demon* const d) override { WhenStartBound(d); } bool MustBePerformed() const override { return t_->MustBePerformed(); } @@ -2072,8 +2104,8 @@ class FixedDurationSyncedIntervalVar : public IntervalVar { protected: IntervalVar* const t_; - const int64 duration_; - const int64 offset_; + const int64_t duration_; + const int64_t offset_; private: DISALLOW_COPY_AND_ASSIGN(FixedDurationSyncedIntervalVar); @@ -2085,24 +2117,24 @@ class FixedDurationIntervalVarStartSyncedOnStart : public FixedDurationSyncedIntervalVar { public: FixedDurationIntervalVarStartSyncedOnStart(IntervalVar* const t, - int64 duration, int64 offset) + int64_t duration, int64_t offset) : FixedDurationSyncedIntervalVar( t, duration, offset, absl::StrFormat( "IntervalStartSyncedOnStart(%s, duration = %d, offset = %d)", t->name(), duration, offset)) {} ~FixedDurationIntervalVarStartSyncedOnStart() override {} - int64 StartMin() const override { return CapAdd(t_->StartMin(), offset_); } - int64 StartMax() const override { return CapAdd(t_->StartMax(), offset_); } - void SetStartMin(int64 m) override { t_->SetStartMin(CapSub(m, offset_)); } - void SetStartMax(int64 m) override { t_->SetStartMax(CapSub(m, offset_)); } - void SetStartRange(int64 mi, int64 ma) override { + int64_t StartMin() const override { return CapAdd(t_->StartMin(), offset_); } + int64_t StartMax() const override { return CapAdd(t_->StartMax(), offset_); } + void SetStartMin(int64_t m) override { t_->SetStartMin(CapSub(m, offset_)); } + void SetStartMax(int64_t m) override { t_->SetStartMax(CapSub(m, offset_)); } + void SetStartRange(int64_t mi, int64_t ma) override { t_->SetStartRange(CapSub(mi, offset_), CapSub(ma, offset_)); } - int64 OldStartMin() const override { + int64_t OldStartMin() const override { return CapAdd(t_->OldStartMin(), offset_); } - int64 OldStartMax() const override { + int64_t OldStartMax() const override { return CapAdd(t_->OldStartMax(), offset_); } void WhenStartRange(Demon* const d) override { t_->WhenStartRange(d); } @@ -2118,13 +2150,13 @@ class FixedDurationIntervalVarStartSyncedOnStart // These methods create expressions encapsulating the start, end // and duration of the interval var. If the interval var is // unperformed, they will return the unperformed_value. - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return BuildSafeStartExpr(t_, unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return BuildSafeDurationExpr(t_, unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return BuildSafeEndExpr(t_, unperformed_value); } void Accept(ModelVisitor* const visitor) const override { @@ -2143,25 +2175,25 @@ class FixedDurationIntervalVarStartSyncedOnStart class FixedDurationIntervalVarStartSyncedOnEnd : public FixedDurationSyncedIntervalVar { public: - FixedDurationIntervalVarStartSyncedOnEnd(IntervalVar* const t, int64 duration, - int64 offset) + FixedDurationIntervalVarStartSyncedOnEnd(IntervalVar* const t, + int64_t duration, int64_t offset) : FixedDurationSyncedIntervalVar( t, duration, offset, absl::StrFormat( "IntervalStartSyncedOnEnd(%s, duration = %d, offset = %d)", t->name(), duration, offset)) {} ~FixedDurationIntervalVarStartSyncedOnEnd() override {} - int64 StartMin() const override { return CapAdd(t_->EndMin(), offset_); } - int64 StartMax() const override { return CapAdd(t_->EndMax(), offset_); } - void SetStartMin(int64 m) override { t_->SetEndMin(CapSub(m, offset_)); } - void SetStartMax(int64 m) override { t_->SetEndMax(CapSub(m, offset_)); } - void SetStartRange(int64 mi, int64 ma) override { + int64_t StartMin() const override { return CapAdd(t_->EndMin(), offset_); } + int64_t StartMax() const override { return CapAdd(t_->EndMax(), offset_); } + void SetStartMin(int64_t m) override { t_->SetEndMin(CapSub(m, offset_)); } + void SetStartMax(int64_t m) override { t_->SetEndMax(CapSub(m, offset_)); } + void SetStartRange(int64_t mi, int64_t ma) override { t_->SetEndRange(CapSub(mi, offset_), CapSub(ma, offset_)); } - int64 OldStartMin() const override { + int64_t OldStartMin() const override { return CapAdd(t_->OldEndMin(), offset_); } - int64 OldStartMax() const override { + int64_t OldStartMax() const override { return CapAdd(t_->OldEndMax(), offset_); } void WhenStartRange(Demon* const d) override { t_->WhenEndRange(d); } @@ -2177,13 +2209,13 @@ class FixedDurationIntervalVarStartSyncedOnEnd // These methods create expressions encapsulating the start, end // and duration of the interval var. If the interval var is // unperformed, they will return the unperformed_value. - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return BuildSafeStartExpr(t_, unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return BuildSafeDurationExpr(t_, unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return BuildSafeEndExpr(t_, unperformed_value); } @@ -2231,14 +2263,15 @@ void IntervalVar::WhenAnything(Demon* const d) { WhenPerformedBound(d); } -IntervalVar* Solver::MakeFixedInterval(int64 start, int64 duration, +IntervalVar* Solver::MakeFixedInterval(int64_t start, int64_t duration, const std::string& name) { return RevAlloc(new FixedInterval(this, start, duration, name)); } -IntervalVar* Solver::MakeFixedDurationIntervalVar(int64 start_min, - int64 start_max, - int64 duration, bool optional, +IntervalVar* Solver::MakeFixedDurationIntervalVar(int64_t start_min, + int64_t start_max, + int64_t duration, + bool optional, const std::string& name) { if (start_min == start_max && !optional) { return MakeFixedInterval(start_min, duration, name); @@ -2251,8 +2284,8 @@ IntervalVar* Solver::MakeFixedDurationIntervalVar(int64 start_min, } void Solver::MakeFixedDurationIntervalVarArray( - int count, int64 start_min, int64 start_max, int64 duration, bool optional, - const std::string& name, std::vector* array) { + int count, int64_t start_min, int64_t start_max, int64_t duration, + bool optional, const std::string& name, std::vector* array) { CHECK_GT(count, 0); CHECK(array != nullptr); array->clear(); @@ -2264,7 +2297,7 @@ void Solver::MakeFixedDurationIntervalVarArray( } IntervalVar* Solver::MakeFixedDurationIntervalVar(IntVar* const start_variable, - int64 duration, + int64_t duration, const std::string& name) { CHECK(start_variable != nullptr); CHECK_GE(duration, 0); @@ -2275,7 +2308,7 @@ IntervalVar* Solver::MakeFixedDurationIntervalVar(IntVar* const start_variable, // Creates an interval var with a fixed duration, and performed var. // The duration must be greater than 0. IntervalVar* Solver::MakeFixedDurationIntervalVar( - IntVar* const start_variable, int64 duration, + IntVar* const start_variable, int64_t duration, IntVar* const performed_variable, const std::string& name) { CHECK(start_variable != nullptr); CHECK(performed_variable != nullptr); @@ -2296,7 +2329,7 @@ IntervalVar* Solver::MakeFixedDurationIntervalVar( } void Solver::MakeFixedDurationIntervalVarArray( - const std::vector& start_variables, int64 duration, + const std::vector& start_variables, int64_t duration, const std::string& name, std::vector* array) { CHECK(array != nullptr); array->clear(); @@ -2311,7 +2344,7 @@ void Solver::MakeFixedDurationIntervalVarArray( // the corresponding start variables. void Solver::MakeFixedDurationIntervalVarArray( const std::vector& start_variables, - const std::vector& durations, const std::string& name, + const std::vector& durations, const std::string& name, std::vector* array) { CHECK(array != nullptr); CHECK_EQ(start_variables.size(), durations.size()); @@ -2353,7 +2386,7 @@ void Solver::MakeFixedDurationIntervalVarArray( void Solver::MakeFixedDurationIntervalVarArray( const std::vector& start_variables, - const std::vector& durations, + const std::vector& durations, const std::vector& performed_variables, const std::string& name, std::vector* array) { CHECK(array != nullptr); @@ -2367,18 +2400,19 @@ void Solver::MakeFixedDurationIntervalVarArray( // Variable Duration Interval Var -IntervalVar* Solver::MakeIntervalVar(int64 start_min, int64 start_max, - int64 duration_min, int64 duration_max, - int64 end_min, int64 end_max, +IntervalVar* Solver::MakeIntervalVar(int64_t start_min, int64_t start_max, + int64_t duration_min, int64_t duration_max, + int64_t end_min, int64_t end_max, bool optional, const std::string& name) { return RegisterIntervalVar(RevAlloc(new VariableDurationIntervalVar( this, start_min, start_max, duration_min, duration_max, end_min, end_max, optional, name))); } -void Solver::MakeIntervalVarArray(int count, int64 start_min, int64 start_max, - int64 duration_min, int64 duration_max, - int64 end_min, int64 end_max, bool optional, +void Solver::MakeIntervalVarArray(int count, int64_t start_min, + int64_t start_max, int64_t duration_min, + int64_t duration_max, int64_t end_min, + int64_t end_max, bool optional, const std::string& name, std::vector* const array) { CHECK_GT(count, 0); @@ -2394,28 +2428,28 @@ void Solver::MakeIntervalVarArray(int count, int64 start_min, int64 start_max, // Synced Interval Vars IntervalVar* Solver::MakeFixedDurationStartSyncedOnStartIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset) { + IntervalVar* const interval_var, int64_t duration, int64_t offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart( interval_var, duration, offset))); } IntervalVar* Solver::MakeFixedDurationStartSyncedOnEndIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset) { + IntervalVar* const interval_var, int64_t duration, int64_t offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd(interval_var, duration, offset))); } IntervalVar* Solver::MakeFixedDurationEndSyncedOnStartIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset) { + IntervalVar* const interval_var, int64_t duration, int64_t offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart( interval_var, duration, CapSub(offset, duration)))); } IntervalVar* Solver::MakeFixedDurationEndSyncedOnEndIntervalVar( - IntervalVar* const interval_var, int64 duration, int64 offset) { + IntervalVar* const interval_var, int64_t duration, int64_t offset) { return RegisterIntervalVar( RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd( interval_var, duration, CapSub(offset, duration)))); diff --git a/ortools/constraint_solver/java/constraint_solver.i b/ortools/constraint_solver/java/constraint_solver.i index 44149566be..9d2ddb9d34 100644 --- a/ortools/constraint_solver/java/constraint_solver.i +++ b/ortools/constraint_solver/java/constraint_solver.i @@ -87,24 +87,24 @@ class GlobalRefGuard { %enddef namespace operations_research { -PROTECT_FROM_FAILURE(IntExpr::SetValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMin(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMax(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetRange(int64 l, int64 u), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), +PROTECT_FROM_FAILURE(IntExpr::SetValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMin(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMax(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetRange(int64_t l, int64_t u), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64_t mi, int64_t ma), arg1->solver()); PROTECT_FROM_FAILURE(IntervalVar::SetPerformed(bool val), arg1->solver()); PROTECT_FROM_FAILURE(Solver::AddConstraint(Constraint* const c), arg1); @@ -126,10 +126,10 @@ PROTECT_FROM_FAILURE(Solver::Fail(), arg1); %} // Use to correctly wrap Solver::MakeScheduleOrPostpone. -%apply int64 * INOUT { int64 *const marker }; +%apply int64_t * INOUT { int64_t *const marker }; // Use to correctly wrap arguments otherwise SWIG will wrap them as // SWIGTYPE_p_long_long opaque pointer. -%apply int64 * OUTPUT { int64 *l, int64 *u, int64 *value }; +%apply int64_t * OUTPUT { int64_t *l, int64_t *u, int64_t *value }; // Types in Proxy class (e.g. Solver.java) e.g.: // Solver::f(jstype $javainput, ...) {Solver_f_SWIG(javain, ...);} @@ -282,54 +282,54 @@ DEFINE_VOID_TO_R_CALLBACK( void, CallVoidMethod) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongToIntFunction, "applyAsInt", "(J)I", int, CallIntMethod, VAR_ARGS(long t), VAR_ARGS((jlong)t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongUnaryOperator, "applyAsLong", "(J)J", long, CallLongMethod, VAR_ARGS(long t), VAR_ARGS((jlong)t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongBinaryOperator, "applyAsLong", "(JJ)J", long, CallLongMethod, VAR_ARGS(long t, long u), VAR_ARGS((jlong)t, (jlong)u)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongTernaryOperator, "applyAsLong", "(JJJ)J", long, CallLongMethod, VAR_ARGS(long t, long u, long v), VAR_ARGS((jlong)t, (jlong)u, (jlong)v)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, IntIntToLongFunction, "applyAsLong", "(II)J", long, CallLongMethod, VAR_ARGS(int t, int u), VAR_ARGS((jint)t, (jint)u)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongPredicate, "test", "(J)Z", bool, CallBooleanMethod, VAR_ARGS(long t), VAR_ARGS((jlong)t)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongTernaryPredicate, "test", "(JJJ)Z", bool, CallBooleanMethod, VAR_ARGS(long t, long u, long v), VAR_ARGS((jlong)t, (jlong)u, (jlong)v)) DEFINE_ARGS_TO_R_CALLBACK( - std::function, + std::function, LongConsumer, "accept", "(J)V", void, CallVoidMethod, VAR_ARGS(long t), @@ -344,7 +344,7 @@ DEFINE_ARGS_TO_R_CALLBACK( // Renaming namespace operations_research { -// This method causes issues with our std::vector wrapping. It's not really +// This method causes issues with our std::vector wrapping. It's not really // part of the public API anyway. %ignore ToInt64Vector; @@ -657,24 +657,24 @@ import java.util.function.Supplier; // see https://docs.oracle.com/javase/8/docs/api/java/util/function/BooleanSupplier.html import java.util.function.BooleanSupplier; -// Used to wrap IndexEvaluator1 (std::function) +// Used to wrap IndexEvaluator1 (std::function) // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongUnaryOperator.html import java.util.function.LongUnaryOperator; -// Used to wrap IndexEvaluator2 (std::function) +// Used to wrap IndexEvaluator2 (std::function) // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongBinaryOperator.html import java.util.function.LongBinaryOperator; -// Used to wrap IndexEvaluator3 (std::function) +// Used to wrap IndexEvaluator3 (std::function) // note: Java does not provide TernaryOperator so we provide it. import com.google.ortools.constraintsolver.LongTernaryOperator; -// Used to wrap std::function +// Used to wrap std::function // note: Java does not provide it, so we provide it. import com.google.ortools.constraintsolver.IntIntToLongFunction; -// Used to wrap IndexFilter1 (std::function) +// Used to wrap IndexFilter1 (std::function) // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongPredicate.html import java.util.function.LongPredicate; -// Used to wrap std::function +// Used to wrap std::function // note: Java does not provide TernaryPredicate so we provide it import com.google.ortools.constraintsolver.LongTernaryPredicate; @@ -682,7 +682,7 @@ import com.google.ortools.constraintsolver.LongTernaryPredicate; // see https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html import java.util.function.Consumer; -// Used to wrap ObjectiveWatcher (std::function) +// Used to wrap ObjectiveWatcher (std::function) // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongConsumer.html import java.util.function.LongConsumer; @@ -1451,7 +1451,7 @@ import java.util.function.LongConsumer; %rename (var) IntVarLocalSearchFilter::Var; // Inherited. %extend IntVarLocalSearchFilter { int index(IntVar* const var) { - int64 index = -1; + int64_t index = -1; $self->FindIndex(var, &index); return index; } @@ -1502,31 +1502,31 @@ import java.util.function.Supplier; // see https://docs.oracle.com/javase/8/docs/api/java/util/function/BooleanSupplier.html import java.util.function.BooleanSupplier; -// Used to wrap std::function +// Used to wrap std::function // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongToIntFunction.html import java.util.function.LongToIntFunction; -// Used to wrap std::function +// Used to wrap std::function // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongUnaryOperator.html import java.util.function.LongUnaryOperator; -// Used to wrap std::function +// Used to wrap std::function // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongBinaryOperator.html import java.util.function.LongBinaryOperator; -// Used to wrap std::function +// Used to wrap std::function // note: Java does not provide TernaryOperator so we provide it import com.google.ortools.constraintsolver.LongTernaryOperator; -// Used to wrap std::function +// Used to wrap std::function // note: Java does not provide it, so we provide it. import com.google.ortools.constraintsolver.IntIntToLongFunction; -// Used to wrap std::function +// Used to wrap std::function // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongPredicate.html import java.util.function.LongPredicate; -// Used to wrap std::function +// Used to wrap std::function // note: Java does not provide TernaryPredicate so we provide it import com.google.ortools.constraintsolver.LongTernaryPredicate; @@ -1534,7 +1534,7 @@ import com.google.ortools.constraintsolver.LongTernaryPredicate; // see https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html import java.util.function.Consumer; -// Used to wrap std::function +// Used to wrap std::function // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongConsumer.html import java.util.function.LongConsumer; @@ -1583,7 +1583,7 @@ namespace operations_research { // Define templates instantiation after wrapping. namespace operations_research { %template(RevInteger) Rev; -%template(RevLong) Rev; +%template(RevLong) Rev; %template(RevBool) Rev; %template(AssignmentIntContainer) AssignmentContainer; %template(AssignmentIntervalContainer) AssignmentContainer; diff --git a/ortools/constraint_solver/java/routing.i b/ortools/constraint_solver/java/routing.i index 0e4517c66b..611e016935 100644 --- a/ortools/constraint_solver/java/routing.i +++ b/ortools/constraint_solver/java/routing.i @@ -233,7 +233,7 @@ import java.util.function.LongUnaryOperator; // Map transit callback to Java @FunctionalInterface types. // This replaces the RoutingTransitCallback[1-2] in the Java proxy class %typemap(javaimports) RoutingDimension %{ -// Used to wrap std::function group_delay +// Used to wrap std::function group_delay // see https://docs.oracle.com/javase/8/docs/api/java/util/function/LongBinaryOperator.html import java.util.function.LongBinaryOperator; %} diff --git a/ortools/constraint_solver/local_search.cc b/ortools/constraint_solver/local_search.cc index 96138b9358..4af07f1fed 100644 --- a/ortools/constraint_solver/local_search.cc +++ b/ortools/constraint_solver/local_search.cc @@ -12,7 +12,9 @@ // limitations under the License. #include +#include #include +#include #include #include #include @@ -164,7 +166,7 @@ bool SimpleLns::NextFragment() { class RandomLns : public BaseLns { public: RandomLns(const std::vector& vars, int number_of_variables, - int32 seed) + int32_t seed) : BaseLns(vars), rand_(seed), number_of_variables_(number_of_variables) { CHECK_GT(number_of_variables_, 0); CHECK_LE(number_of_variables_, Size()); @@ -194,7 +196,7 @@ LocalSearchOperator* Solver::MakeRandomLnsOperator( } LocalSearchOperator* Solver::MakeRandomLnsOperator( - const std::vector& vars, int number_of_variables, int32 seed) { + const std::vector& vars, int number_of_variables, int32_t seed) { return RevAlloc(new RandomLns(vars, number_of_variables, seed)); } @@ -207,7 +209,7 @@ namespace { class MoveTowardTargetLS : public IntVarLocalSearchOperator { public: MoveTowardTargetLS(const std::vector& variables, - const std::vector& target_values) + const std::vector& target_values) : IntVarLocalSearchOperator(variables), target_(target_values), // Initialize variable_index_ at the number of the of variables minus @@ -227,8 +229,8 @@ class MoveTowardTargetLS : public IntVarLocalSearchOperator { while (num_var_since_last_start_ < Size()) { ++num_var_since_last_start_; variable_index_ = (variable_index_ + 1) % Size(); - const int64 target_value = target_.at(variable_index_); - const int64 current_value = OldValue(variable_index_); + const int64_t target_value = target_.at(variable_index_); + const int64_t current_value = OldValue(variable_index_); if (current_value != target_value) { SetValue(variable_index_, target_value); return true; @@ -256,13 +258,13 @@ class MoveTowardTargetLS : public IntVarLocalSearchOperator { } // Target values - const std::vector target_; + const std::vector target_; // Index of the next variable to try to restore - int64 variable_index_; + int64_t variable_index_; // Number of variables checked since the last call to OnStart(). - int64 num_var_since_last_start_; + int64_t num_var_since_last_start_; }; } // namespace @@ -272,7 +274,7 @@ LocalSearchOperator* Solver::MakeMoveTowardTargetOperator( const Elements& elements = target.IntVarContainer().elements(); // Copy target values and construct the vector of variables std::vector vars; - std::vector values; + std::vector values; vars.reserve(target.NumIntVars()); values.reserve(target.NumIntVars()); for (const auto& it : elements) { @@ -284,7 +286,7 @@ LocalSearchOperator* Solver::MakeMoveTowardTargetOperator( LocalSearchOperator* Solver::MakeMoveTowardTargetOperator( const std::vector& variables, - const std::vector& target_values) { + const std::vector& target_values) { return RevAlloc(new MoveTowardTargetLS(variables, target_values)); } @@ -298,7 +300,7 @@ ChangeValue::~ChangeValue() {} bool ChangeValue::MakeOneNeighbor() { const int size = Size(); while (index_ < size) { - const int64 value = ModifyValue(index_, Value(index_)); + const int64_t value = ModifyValue(index_, Value(index_)); SetValue(index_, value); ++index_; return true; @@ -316,7 +318,9 @@ class IncrementValue : public ChangeValue { explicit IncrementValue(const std::vector& vars) : ChangeValue(vars) {} ~IncrementValue() override {} - int64 ModifyValue(int64 index, int64 value) override { return value + 1; } + int64_t ModifyValue(int64_t index, int64_t value) override { + return value + 1; + } std::string DebugString() const override { return "IncrementValue"; } }; @@ -328,7 +332,9 @@ class DecrementValue : public ChangeValue { explicit DecrementValue(const std::vector& vars) : ChangeValue(vars) {} ~DecrementValue() override {} - int64 ModifyValue(int64 index, int64 value) override { return value - 1; } + int64_t ModifyValue(int64_t index, int64_t value) override { + return value - 1; + } std::string DebugString() const override { return "DecrementValue"; } }; @@ -341,7 +347,7 @@ PathOperator::PathOperator(const std::vector& next_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, bool accept_path_end_base, - std::function start_empty_path_class) + std::function start_empty_path_class) : IntVarLocalSearchOperator(next_vars, true), number_of_nexts_(next_vars.size()), ignore_path_vars_(path_vars.empty()), @@ -408,13 +414,13 @@ bool PathOperator::SkipUnchanged(int index) const { return Value(next_index) == OldValue(next_index); } -bool PathOperator::MoveChain(int64 before_chain, int64 chain_end, - int64 destination) { +bool PathOperator::MoveChain(int64_t before_chain, int64_t chain_end, + int64_t destination) { if (destination == before_chain || destination == chain_end) return false; DCHECK(CheckChainValidity(before_chain, chain_end, destination) && !IsPathEnd(chain_end) && !IsPathEnd(destination)); - const int64 destination_path = Path(destination); - const int64 after_chain = Next(chain_end); + const int64_t destination_path = Path(destination); + const int64_t after_chain = Next(chain_end); SetNext(chain_end, Next(destination), destination_path); if (!ignore_path_vars_) { int current = destination; @@ -431,18 +437,18 @@ bool PathOperator::MoveChain(int64 before_chain, int64 chain_end, return true; } -bool PathOperator::ReverseChain(int64 before_chain, int64 after_chain, - int64* chain_last) { +bool PathOperator::ReverseChain(int64_t before_chain, int64_t after_chain, + int64_t* chain_last) { if (CheckChainValidity(before_chain, after_chain, -1)) { - int64 path = Path(before_chain); - int64 current = Next(before_chain); + int64_t path = Path(before_chain); + int64_t current = Next(before_chain); if (current == after_chain) { return false; } - int64 current_next = Next(current); + int64_t current_next = Next(current); SetNext(current, after_chain, path); while (current_next != after_chain) { - const int64 next = Next(current_next); + const int64_t next = Next(current_next); SetNext(current_next, current, path); current = current_next; current_next = next; @@ -454,9 +460,9 @@ bool PathOperator::ReverseChain(int64 before_chain, int64 after_chain, return false; } -bool PathOperator::MakeActive(int64 node, int64 destination) { +bool PathOperator::MakeActive(int64_t node, int64_t destination) { if (!IsPathEnd(destination)) { - int64 destination_path = Path(destination); + int64_t destination_path = Path(destination); SetNext(node, Next(destination), destination_path); SetNext(destination, node, destination_path); return true; @@ -464,14 +470,14 @@ bool PathOperator::MakeActive(int64 node, int64 destination) { return false; } -bool PathOperator::MakeChainInactive(int64 before_chain, int64 chain_end) { - const int64 kNoPath = -1; +bool PathOperator::MakeChainInactive(int64_t before_chain, int64_t chain_end) { + const int64_t kNoPath = -1; if (CheckChainValidity(before_chain, chain_end, -1) && !IsPathEnd(chain_end)) { - const int64 after_chain = Next(chain_end); - int64 current = Next(before_chain); + const int64_t after_chain = Next(chain_end); + int64_t current = Next(before_chain); while (current != after_chain) { - const int64 next = Next(current); + const int64_t next = Next(current); SetNext(current, current, kNoPath); current = next; } @@ -481,9 +487,9 @@ bool PathOperator::MakeChainInactive(int64 before_chain, int64 chain_end) { return false; } -bool PathOperator::SwapActiveAndInactive(int64 active, int64 inactive) { +bool PathOperator::SwapActiveAndInactive(int64_t active, int64_t inactive) { if (active == inactive) return false; - const int64 prev = Prev(active); + const int64_t prev = Prev(active); return MakeChainInactive(prev, active) && MakeActive(inactive, prev); } @@ -674,7 +680,7 @@ void PathOperator::InitializePathStarts() { // Create a list of path starts, dropping equivalent path starts of // currently empty paths. std::vector empty_found(number_of_nexts_, false); - std::vector new_path_starts; + std::vector new_path_starts; const bool use_empty_path_symmetry_breaker = absl::GetFlag(FLAGS_cp_use_empty_path_symmetry_breaker); for (int i = 0; i < number_of_nexts_; ++i) { @@ -769,7 +775,7 @@ void PathOperator::InitializeBaseNodes() { } for (int i = 0; i < base_nodes_.size(); ++i) { // If base node has been made inactive, restart from path start. - int64 base_node = base_nodes_[i]; + int64_t base_node = base_nodes_[i]; if (RestartAtPathStartOnSynchronize() || IsInactive(base_node)) { base_node = path_starts_[base_paths_[i]]; base_nodes_[i] = base_node; @@ -781,7 +787,7 @@ void PathOperator::InitializeBaseNodes() { for (int i = 1; i < base_nodes_.size(); ++i) { if (OnSamePathAsPreviousBase(i) && !OnSamePath(base_nodes_[i - 1], base_nodes_[i])) { - const int64 base_node = base_nodes_[i - 1]; + const int64_t base_node = base_nodes_[i - 1]; base_nodes_[i] = base_node; end_nodes_[i] = base_node; base_paths_[i] = base_paths_[i - 1]; @@ -797,9 +803,9 @@ void PathOperator::InitializeBaseNodes() { void PathOperator::InitializeAlternatives() { active_in_alternative_set_.resize(alternative_sets_.size(), -1); for (int i = 0; i < alternative_sets_.size(); ++i) { - const int64 current_active = active_in_alternative_set_[i]; + const int64_t current_active = active_in_alternative_set_[i]; if (current_active >= 0 && !IsInactive(current_active)) continue; - for (int64 index : alternative_sets_[i]) { + for (int64_t index : alternative_sets_[i]) { if (!IsInactive(index)) { active_in_alternative_set_[i] = index; break; @@ -808,7 +814,7 @@ void PathOperator::InitializeAlternatives() { } } -bool PathOperator::OnSamePath(int64 node1, int64 node2) const { +bool PathOperator::OnSamePath(int64_t node1, int64_t node2) const { if (IsInactive(node1) != IsInactive(node2)) { return false; } @@ -830,10 +836,10 @@ bool PathOperator::OnSamePath(int64 node1, int64 node2) const { // chain, if before_chain and chain_end are the same the chain is rejected too. // Also rejects cycles (cycle detection is detected through chain length // overflow). -bool PathOperator::CheckChainValidity(int64 before_chain, int64 chain_end, - int64 exclude) const { +bool PathOperator::CheckChainValidity(int64_t before_chain, int64_t chain_end, + int64_t exclude) const { if (before_chain == chain_end || before_chain == exclude) return false; - int64 current = before_chain; + int64_t current = before_chain; int chain_size = 0; while (current != chain_end) { if (chain_size > number_of_nexts_) { @@ -865,7 +871,7 @@ class TwoOpt : public PathOperator { public: TwoOpt(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 2, true, true, std::move(start_empty_path_class)), last_base_(-1), @@ -877,19 +883,19 @@ class TwoOpt : public PathOperator { std::string DebugString() const override { return "TwoOpt"; } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { // Both base nodes have to be on the same path. return true; } - int64 GetBaseNodeRestartPosition(int base_index) override { + int64_t GetBaseNodeRestartPosition(int base_index) override { return (base_index == 0) ? StartNode(0) : BaseNode(0); } private: void OnNodeInitialization() override { last_ = -1; } - int64 last_base_; - int64 last_; + int64_t last_base_; + int64_t last_; }; bool TwoOpt::MakeNeighbor() { @@ -902,7 +908,7 @@ bool TwoOpt::MakeNeighbor() { } last_base_ = BaseNode(0); last_ = Next(BaseNode(0)); - int64 chain_last; + int64_t chain_last; if (ReverseChain(BaseNode(0), BaseNode(1), &chain_last) // Check there are more than one node in the chain (reversing a // single node is a NOP). @@ -912,7 +918,7 @@ bool TwoOpt::MakeNeighbor() { last_ = -1; return false; } - const int64 to_move = Next(last_); + const int64_t to_move = Next(last_); DCHECK_EQ(Next(to_move), BaseNode(1)); return MoveChain(last_, to_move, BaseNode(0)); } @@ -936,8 +942,8 @@ class Relocate : public PathOperator { public: Relocate(const std::vector& vars, const std::vector& secondary_vars, const std::string& name, - std::function start_empty_path_class, - int64 chain_length = 1LL, bool single_path = false) + std::function start_empty_path_class, + int64_t chain_length = 1LL, bool single_path = false) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)), chain_length_(chain_length), @@ -947,8 +953,8 @@ class Relocate : public PathOperator { } Relocate(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, - int64 chain_length = 1LL, bool single_path = false) + std::function start_empty_path_class, + int64_t chain_length = 1LL, bool single_path = false) : Relocate(vars, secondary_vars, absl::StrCat("Relocate<", chain_length, ">"), std::move(start_empty_path_class), chain_length, single_path) { @@ -959,24 +965,24 @@ class Relocate : public PathOperator { std::string DebugString() const override { return name_; } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { // Both base nodes have to be on the same path when it's the single path // version. return single_path_; } private: - const int64 chain_length_; + const int64_t chain_length_; const bool single_path_; const std::string name_; }; bool Relocate::MakeNeighbor() { DCHECK(!single_path_ || StartNode(0) == StartNode(1)); - const int64 destination = BaseNode(1); + const int64_t destination = BaseNode(1); DCHECK(!IsPathEnd(destination)); - const int64 before_chain = BaseNode(0); - int64 chain_end = before_chain; + const int64_t before_chain = BaseNode(0); + int64_t chain_end = before_chain; for (int i = 0; i < chain_length_; ++i) { if (IsPathEnd(chain_end) || chain_end == destination) { return false; @@ -1001,7 +1007,7 @@ class Exchange : public PathOperator { public: Exchange(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)) {} ~Exchange() override {} @@ -1011,11 +1017,11 @@ class Exchange : public PathOperator { }; bool Exchange::MakeNeighbor() { - const int64 prev_node0 = BaseNode(0); - const int64 node0 = Next(prev_node0); + const int64_t prev_node0 = BaseNode(0); + const int64_t node0 = Next(prev_node0); if (IsPathEnd(node0)) return false; - const int64 prev_node1 = BaseNode(1); - const int64 node1 = Next(prev_node1); + const int64_t prev_node1 = BaseNode(1); + const int64_t node1 = Next(prev_node1); if (IsPathEnd(node1)) return false; const bool ok = MoveChain(prev_node0, node0, prev_node1); return MoveChain(Prev(node1), node1, prev_node0) || ok; @@ -1037,7 +1043,7 @@ class Cross : public PathOperator { public: Cross(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 2, true, true, std::move(start_empty_path_class)) {} ~Cross() override {} @@ -1047,12 +1053,12 @@ class Cross : public PathOperator { }; bool Cross::MakeNeighbor() { - const int64 start0 = StartNode(0); - const int64 start1 = StartNode(1); + const int64_t start0 = StartNode(0); + const int64_t start1 = StartNode(1); if (start1 == start0) return false; - const int64 node0 = BaseNode(0); + const int64_t node0 = BaseNode(0); if (node0 == start0) return false; - const int64 node1 = BaseNode(1); + const int64_t node1 = BaseNode(1); if (node1 == start1) return false; if (!IsPathEnd(node0) && !IsPathEnd(node1)) { // If two paths are equivalent don't exchange them. @@ -1075,7 +1081,7 @@ class BaseInactiveNodeToPathOperator : public PathOperator { BaseInactiveNodeToPathOperator( const std::vector& vars, const std::vector& secondary_vars, int number_of_base_nodes, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, number_of_base_nodes, false, false, std::move(start_empty_path_class)), inactive_node_(0) { @@ -1085,7 +1091,7 @@ class BaseInactiveNodeToPathOperator : public PathOperator { protected: bool MakeOneNeighbor() override; - int64 GetInactiveNode() const { return inactive_node_; } + int64_t GetInactiveNode() const { return inactive_node_; } private: void OnNodeInitialization() override; @@ -1128,7 +1134,7 @@ class MakeActiveOperator : public BaseInactiveNodeToPathOperator { public: MakeActiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : BaseInactiveNodeToPathOperator(vars, secondary_vars, 1, std::move(start_empty_path_class)) {} ~MakeActiveOperator() override {} @@ -1155,13 +1161,13 @@ class RelocateAndMakeActiveOperator : public BaseInactiveNodeToPathOperator { RelocateAndMakeActiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : BaseInactiveNodeToPathOperator(vars, secondary_vars, 2, std::move(start_empty_path_class)) {} ~RelocateAndMakeActiveOperator() override {} bool MakeNeighbor() override { - const int64 before_node_to_move = BaseNode(1); - const int64 node = Next(before_node_to_move); + const int64_t before_node_to_move = BaseNode(1); + const int64_t node = Next(before_node_to_move); return !IsPathEnd(node) && MoveChain(before_node_to_move, node, BaseNode(0)) && MakeActive(GetInactiveNode(), before_node_to_move); @@ -1182,7 +1188,7 @@ class MakeActiveAndRelocate : public BaseInactiveNodeToPathOperator { public: MakeActiveAndRelocate(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : BaseInactiveNodeToPathOperator(vars, secondary_vars, 2, std::move(start_empty_path_class)) {} ~MakeActiveAndRelocate() override {} @@ -1194,9 +1200,9 @@ class MakeActiveAndRelocate : public BaseInactiveNodeToPathOperator { }; bool MakeActiveAndRelocate::MakeNeighbor() { - const int64 before_chain = BaseNode(1); - const int64 chain_end = Next(before_chain); - const int64 destination = BaseNode(0); + const int64_t before_chain = BaseNode(1); + const int64_t chain_end = Next(before_chain); + const int64_t destination = BaseNode(0); return !IsPathEnd(chain_end) && MoveChain(before_chain, chain_end, destination) && MakeActive(GetInactiveNode(), destination); @@ -1214,12 +1220,12 @@ class MakeInactiveOperator : public PathOperator { public: MakeInactiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 1, true, false, std::move(start_empty_path_class)) {} ~MakeInactiveOperator() override {} bool MakeNeighbor() override { - const int64 base = BaseNode(0); + const int64_t base = BaseNode(0); return MakeChainInactive(base, Next(base)); } @@ -1239,19 +1245,19 @@ class RelocateAndMakeInactiveOperator : public PathOperator { RelocateAndMakeInactiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)) {} ~RelocateAndMakeInactiveOperator() override {} bool MakeNeighbor() override { - const int64 destination = BaseNode(1); - const int64 before_to_move = BaseNode(0); - const int64 node_to_inactivate = Next(destination); + const int64_t destination = BaseNode(1); + const int64_t before_to_move = BaseNode(0); + const int64_t node_to_inactivate = Next(destination); if (node_to_inactivate == before_to_move || IsPathEnd(node_to_inactivate) || !MakeChainInactive(destination, node_to_inactivate)) { return false; } - const int64 node = Next(before_to_move); + const int64_t node = Next(before_to_move); return !IsPathEnd(node) && MoveChain(before_to_move, node, destination); } @@ -1273,7 +1279,7 @@ class MakeChainInactiveOperator : public PathOperator { public: MakeChainInactiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)) {} ~MakeChainInactiveOperator() override {} @@ -1286,13 +1292,13 @@ class MakeChainInactiveOperator : public PathOperator { } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { // Start and end of chain (defined by both base nodes) must be on the same // path. return true; } - int64 GetBaseNodeRestartPosition(int base_index) override { + int64_t GetBaseNodeRestartPosition(int base_index) override { // Base node 1 must be after base node 0. return (base_index == 0) ? StartNode(base_index) : BaseNode(base_index - 1); } @@ -1310,7 +1316,7 @@ class SwapActiveOperator : public BaseInactiveNodeToPathOperator { public: SwapActiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : BaseInactiveNodeToPathOperator(vars, secondary_vars, 1, std::move(start_empty_path_class)) {} ~SwapActiveOperator() override {} @@ -1320,7 +1326,7 @@ class SwapActiveOperator : public BaseInactiveNodeToPathOperator { }; bool SwapActiveOperator::MakeNeighbor() { - const int64 base = BaseNode(0); + const int64_t base = BaseNode(0); return MakeChainInactive(base, Next(base)) && MakeActive(GetInactiveNode(), base); } @@ -1342,7 +1348,7 @@ class ExtendedSwapActiveOperator : public BaseInactiveNodeToPathOperator { public: ExtendedSwapActiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) + std::function start_empty_path_class) : BaseInactiveNodeToPathOperator(vars, secondary_vars, 2, std::move(start_empty_path_class)) {} ~ExtendedSwapActiveOperator() override {} @@ -1354,8 +1360,8 @@ class ExtendedSwapActiveOperator : public BaseInactiveNodeToPathOperator { }; bool ExtendedSwapActiveOperator::MakeNeighbor() { - const int64 base0 = BaseNode(0); - const int64 base1 = BaseNode(1); + const int64_t base0 = BaseNode(0); + const int64_t base1 = BaseNode(1); if (Next(base0) == base1) { return false; } @@ -1383,8 +1389,8 @@ class TSPOpt : public PathOperator { std::string DebugString() const override { return "TSPOpt"; } private: - std::vector> cost_; - HamiltonianPathSolver>> + std::vector> cost_; + HamiltonianPathSolver>> hamiltonian_path_solver_; Solver::IndexEvaluator3 evaluator_; const int chain_length_; @@ -1399,8 +1405,8 @@ TSPOpt::TSPOpt(const std::vector& vars, chain_length_(chain_length) {} bool TSPOpt::MakeNeighbor() { - std::vector nodes; - int64 chain_end = BaseNode(0); + std::vector nodes; + int64_t chain_end = BaseNode(0); for (int i = 0; i < chain_length_ + 1; ++i) { nodes.push_back(chain_end); if (IsPathEnd(chain_end)) { @@ -1411,7 +1417,7 @@ bool TSPOpt::MakeNeighbor() { if (nodes.size() <= 3) { return false; } - int64 chain_path = Path(BaseNode(0)); + int64_t chain_path = Path(BaseNode(0)); const int size = nodes.size() - 1; cost_.resize(size); for (int i = 0; i < size; ++i) { @@ -1459,8 +1465,8 @@ class TSPLns : public PathOperator { has_long_enough_paths_ = Size() != 0; } - std::vector> cost_; - HamiltonianPathSolver>> + std::vector> cost_; + HamiltonianPathSolver>> hamiltonian_path_solver_; Solver::IndexEvaluator3 evaluator_; const int tsp_size_; @@ -1496,9 +1502,9 @@ bool TSPLns::MakeOneNeighbor() { } bool TSPLns::MakeNeighbor() { - const int64 base_node = BaseNode(0); - std::vector nodes; - for (int64 node = StartNode(0); !IsPathEnd(node); node = Next(node)) { + const int64_t base_node = BaseNode(0); + std::vector nodes; + for (int64_t node = StartNode(0); !IsPathEnd(node); node = Next(node)) { nodes.push_back(node); } if (nodes.size() <= tsp_size_) { @@ -1507,7 +1513,7 @@ bool TSPLns::MakeNeighbor() { has_long_enough_paths_ = true; // Randomly select break nodes (final nodes of a meta-node, after which // an arc is relaxed. - absl::flat_hash_set breaks_set; + absl::flat_hash_set breaks_set; // Always add base node to break nodes (diversification) breaks_set.insert(base_node); CHECK(!nodes.empty()); // Should have been caught earlier. @@ -1520,12 +1526,12 @@ bool TSPLns::MakeNeighbor() { // this cost has to be added to the TSP matrix cost in order to respect the // triangle inequality. std::vector breaks; - std::vector meta_node_costs; - int64 cost = 0; - int64 node = StartNode(0); - int64 node_path = Path(node); + std::vector meta_node_costs; + int64_t cost = 0; + int64_t node = StartNode(0); + int64_t node_path = Path(node); while (!IsPathEnd(node)) { - int64 next = Next(node); + int64_t next = Next(node); if (gtl::ContainsKey(breaks_set, node)) { breaks.push_back(node); meta_node_costs.push_back(cost); @@ -1629,9 +1635,9 @@ void NearestNeighbors::ComputeNearest(int row) { // Find size_ nearest neighbors for row of index 'row'. const int path = path_operator_.Path(row); const IntVar* var = path_operator_.Var(row); - const int64 var_min = var->Min(); + const int64_t var_min = var->Min(); const int var_size = var->Max() - var_min + 1; - using ValuedIndex = std::pair; + using ValuedIndex = std::pair; std::vector neighbors(var_size); for (int i = 0; i < var_size; ++i) { const int index = i + var_min; @@ -1664,11 +1670,11 @@ class LinKernighan : public PathOperator { static const int kNeighbors; - bool InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain); + bool InFromOut(int64_t in_i, int64_t in_j, int64_t* out, int64_t* gain); Solver::IndexEvaluator3 const evaluator_; NearestNeighbors neighbors_; - absl::flat_hash_set marked_; + absl::flat_hash_set marked_; const bool topt_; }; @@ -1690,21 +1696,21 @@ void LinKernighan::OnNodeInitialization() { neighbors_.Initialize(); } bool LinKernighan::MakeNeighbor() { marked_.clear(); - int64 node = BaseNode(0); - int64 path = Path(node); - int64 base = node; - int64 next = Next(node); + int64_t node = BaseNode(0); + int64_t path = Path(node); + int64_t base = node; + int64_t next = Next(node); if (IsPathEnd(next)) return false; - int64 out = -1; - int64 gain = 0; + int64_t out = -1; + int64_t gain = 0; marked_.insert(node); if (topt_) { // Try a 3opt first if (!InFromOut(node, next, &out, &gain)) return false; marked_.insert(next); marked_.insert(out); - const int64 node1 = out; + const int64_t node1 = out; if (IsPathEnd(node1)) return false; - const int64 next1 = Next(node1); + const int64_t next1 = Next(node1); if (IsPathEnd(next1)) return false; if (!InFromOut(node1, next1, &out, &gain)) return false; marked_.insert(next1); @@ -1712,9 +1718,9 @@ bool LinKernighan::MakeNeighbor() { if (!CheckChainValidity(out, node1, node) || !MoveChain(out, node1, node)) { return false; } - const int64 next_out = Next(out); - const int64 in_cost = evaluator_(node, next_out, path); - const int64 out_cost = evaluator_(out, next_out, path); + const int64_t next_out = Next(out); + const int64_t in_cost = evaluator_(node, next_out, path); + const int64_t out_cost = evaluator_(out, next_out, path); if (CapAdd(CapSub(gain, in_cost), out_cost) > 0) return true; node = out; if (IsPathEnd(node)) return false; @@ -1725,12 +1731,12 @@ bool LinKernighan::MakeNeighbor() { while (InFromOut(node, next, &out, &gain)) { marked_.insert(next); marked_.insert(out); - int64 chain_last; + int64_t chain_last; if (!ReverseChain(node, out, &chain_last)) { return false; } - int64 in_cost = evaluator_(base, chain_last, path); - int64 out_cost = evaluator_(chain_last, out, path); + int64_t in_cost = evaluator_(base, chain_last, path); + int64_t out_cost = evaluator_(chain_last, out, path); if (CapAdd(CapSub(gain, in_cost), out_cost) > 0) { return true; } @@ -1748,17 +1754,18 @@ bool LinKernighan::MakeNeighbor() { const int LinKernighan::kNeighbors = 5 + 1; -bool LinKernighan::InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain) { +bool LinKernighan::InFromOut(int64_t in_i, int64_t in_j, int64_t* out, + int64_t* gain) { const std::vector& nexts = neighbors_.Neighbors(in_j); - int64 best_gain = kint64min; - int64 path = Path(in_i); - int64 out_cost = evaluator_(in_i, in_j, path); - const int64 current_gain = CapAdd(*gain, out_cost); + int64_t best_gain = std::numeric_limits::min(); + int64_t path = Path(in_i); + int64_t out_cost = evaluator_(in_i, in_j, path); + const int64_t current_gain = CapAdd(*gain, out_cost); for (int k = 0; k < nexts.size(); ++k) { - const int64 next = nexts[k]; + const int64_t next = nexts[k]; if (next != in_j) { - int64 in_cost = evaluator_(in_j, next, path); - int64 new_gain = CapSub(current_gain, in_cost); + int64_t in_cost = evaluator_(in_j, next, path); + int64_t new_gain = CapSub(current_gain, in_cost); if (new_gain > 0 && next != Next(in_j) && marked_.count(in_j) == 0 && marked_.count(next) == 0) { if (best_gain < new_gain) { @@ -1769,7 +1776,7 @@ bool LinKernighan::InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain) { } } *gain = best_gain; - return (best_gain > kint64min); + return (best_gain > std::numeric_limits::min()); } // ----- Path-based Large Neighborhood Search ----- @@ -1798,7 +1805,7 @@ class PathLns : public PathOperator { private: inline bool ChainsAreFullPaths() const { return chunk_size_ == 0; } - void DeactivateChain(int64 node); + void DeactivateChain(int64_t node); void DeactivateUnactives(); const int number_of_chunks_; @@ -1822,7 +1829,7 @@ bool PathLns::MakeNeighbor() { return true; } -void PathLns::DeactivateChain(int64 node) { +void PathLns::DeactivateChain(int64_t node) { for (int i = 0, current = node; (ChainsAreFullPaths() || i < chunk_size_) && !IsPathEnd(current); ++i, current = Next(current)) { @@ -1850,7 +1857,7 @@ void PathLns::DeactivateUnactives() { class NeighborhoodLimit : public LocalSearchOperator { public: - NeighborhoodLimit(LocalSearchOperator* const op, int64 limit) + NeighborhoodLimit(LocalSearchOperator* const op, int64_t limit) : operator_(op), limit_(limit), next_neighborhood_calls_(0) { CHECK(op != nullptr); CHECK_GT(limit, 0); @@ -1875,12 +1882,12 @@ class NeighborhoodLimit : public LocalSearchOperator { private: LocalSearchOperator* const operator_; - const int64 limit_; - int64 next_neighborhood_calls_; + const int64_t limit_; + int64_t next_neighborhood_calls_; }; LocalSearchOperator* Solver::MakeNeighborhoodLimit( - LocalSearchOperator* const op, int64 limit) { + LocalSearchOperator* const op, int64_t limit) { return RevAlloc(new NeighborhoodLimit(op, limit)); } @@ -1890,7 +1897,7 @@ namespace { class CompoundOperator : public LocalSearchOperator { public: CompoundOperator(std::vector operators, - std::function evaluator); + std::function evaluator); ~CompoundOperator() override {} void Reset() override; void Start(const Assignment* assignment) override; @@ -1911,35 +1918,35 @@ class CompoundOperator : public LocalSearchOperator { private: class OperatorComparator { public: - OperatorComparator(std::function evaluator, + OperatorComparator(std::function evaluator, int active_operator) : evaluator_(std::move(evaluator)), active_operator_(active_operator) {} bool operator()(int lhs, int rhs) const { - const int64 lhs_value = Evaluate(lhs); - const int64 rhs_value = Evaluate(rhs); + const int64_t lhs_value = Evaluate(lhs); + const int64_t rhs_value = Evaluate(rhs); return lhs_value < rhs_value || (lhs_value == rhs_value && lhs < rhs); } private: - int64 Evaluate(int operator_index) const { + int64_t Evaluate(int operator_index) const { return evaluator_(active_operator_, operator_index); } - std::function evaluator_; + std::function evaluator_; const int active_operator_; }; - int64 index_; + int64_t index_; std::vector operators_; std::vector operator_indices_; - std::function evaluator_; + std::function evaluator_; Bitset64<> started_; const Assignment* start_assignment_; bool has_fragments_; }; CompoundOperator::CompoundOperator(std::vector operators, - std::function evaluator) + std::function evaluator) : index_(0), operators_(std::move(operators)), evaluator_(std::move(evaluator)), @@ -1980,7 +1987,7 @@ bool CompoundOperator::MakeNextNeighbor(Assignment* delta, do { // TODO(user): keep copy of delta in case MakeNextNeighbor // pollutes delta on a fail. - const int64 operator_index = operator_indices_[index_]; + const int64_t operator_index = operator_indices_[index_]; if (!started_[operator_index]) { operators_[operator_index]->Start(start_assignment_); started_.Set(operator_index); @@ -2001,13 +2008,13 @@ bool CompoundOperator::MakeNextNeighbor(Assignment* delta, return false; } -int64 CompoundOperatorNoRestart(int size, int active_index, - int operator_index) { +int64_t CompoundOperatorNoRestart(int size, int active_index, + int operator_index) { return (operator_index < active_index) ? size + operator_index - active_index : operator_index - active_index; } -int64 CompoundOperatorRestart(int active_index, int operator_index) { +int64_t CompoundOperatorRestart(int active_index, int operator_index) { return 0; } } // namespace @@ -2020,7 +2027,7 @@ LocalSearchOperator* Solver::ConcatenateOperators( LocalSearchOperator* Solver::ConcatenateOperators( const std::vector& ops, bool restart) { if (restart) { - std::function eval = CompoundOperatorRestart; + std::function eval = CompoundOperatorRestart; return ConcatenateOperators(ops, eval); } const int size = ops.size(); @@ -2031,7 +2038,7 @@ LocalSearchOperator* Solver::ConcatenateOperators( LocalSearchOperator* Solver::ConcatenateOperators( const std::vector& ops, - std::function evaluator) { + std::function evaluator) { return RevAlloc(new CompoundOperator(ops, std::move(evaluator))); } @@ -2040,7 +2047,7 @@ class RandomCompoundOperator : public LocalSearchOperator { public: explicit RandomCompoundOperator(std::vector operators); RandomCompoundOperator(std::vector operators, - int32 seed); + int32_t seed); ~RandomCompoundOperator() override {} void Reset() override; void Start(const Assignment* assignment) override; @@ -2067,7 +2074,7 @@ RandomCompoundOperator::RandomCompoundOperator( : RandomCompoundOperator(std::move(operators), CpRandomSeed()) {} RandomCompoundOperator::RandomCompoundOperator( - std::vector operators, int32 seed) + std::vector operators, int32_t seed) : rand_(seed), operators_(std::move(operators)), has_fragments_(false) { for (LocalSearchOperator* const op : operators_) { if (op->HasFragments()) { @@ -2108,7 +2115,7 @@ LocalSearchOperator* Solver::RandomConcatenateOperators( } LocalSearchOperator* Solver::RandomConcatenateOperators( - const std::vector& ops, int32 seed) { + const std::vector& ops, int32_t seed) { return RevAlloc(new RandomCompoundOperator(ops, seed)); } @@ -2142,7 +2149,7 @@ class MultiArmedBanditCompoundOperator : public LocalSearchOperator { const Assignment* start_assignment_; bool has_fragments_; std::vector operator_indices_; - int64 last_objective_; + int64_t last_objective_; std::vector avg_improvement_; int num_neighbors_; std::vector num_neighbors_per_operator_; @@ -2167,7 +2174,7 @@ MultiArmedBanditCompoundOperator::MultiArmedBanditCompoundOperator( started_(operators_.size()), start_assignment_(nullptr), has_fragments_(false), - last_objective_(kint64max), + last_objective_(std::numeric_limits::max()), num_neighbors_(0), maximize_(maximize), memory_coefficient_(memory_coefficient), @@ -2211,7 +2218,7 @@ void MultiArmedBanditCompoundOperator::Start(const Assignment* assignment) { if (objective == last_objective_) return; // Skip a neighbor evaluation if last_objective_ hasn't been set yet. - if (last_objective_ == kint64max) { + if (last_objective_ == std::numeric_limits::max()) { last_objective_ = objective; return; } @@ -2277,7 +2284,7 @@ template LocalSearchOperator* MakeLocalSearchOperator( Solver* solver, const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class) { + std::function start_empty_path_class) { return solver->RevAlloc( new T(vars, secondary_vars, std::move(start_empty_path_class))); } @@ -2287,7 +2294,7 @@ LocalSearchOperator* MakeLocalSearchOperator( LocalSearchOperator* MakeLocalSearchOperator( \ Solver * solver, const std::vector& vars, \ const std::vector& secondary_vars, \ - std::function start_empty_path_class) { \ + std::function start_empty_path_class) { \ return solver->RevAlloc(new OperatorClass( \ vars, secondary_vars, std::move(start_empty_path_class))); \ } @@ -2467,58 +2474,58 @@ class SumOperation { public: SumOperation() : value_(0) {} void Init() { value_ = 0; } - void Update(int64 update) { value_ = CapAdd(value_, update); } - void Remove(int64 remove) { value_ = CapSub(value_, remove); } - int64 value() const { return value_; } - void set_value(int64 new_value) { value_ = new_value; } + void Update(int64_t update) { value_ = CapAdd(value_, update); } + void Remove(int64_t remove) { value_ = CapSub(value_, remove); } + int64_t value() const { return value_; } + void set_value(int64_t new_value) { value_ = new_value; } private: - int64 value_; + int64_t value_; }; class ProductOperation { public: ProductOperation() : value_(1) {} void Init() { value_ = 1; } - void Update(int64 update) { value_ *= update; } - void Remove(int64 remove) { + void Update(int64_t update) { value_ *= update; } + void Remove(int64_t remove) { if (remove != 0) { value_ /= remove; } } - int64 value() const { return value_; } - void set_value(int64 new_value) { value_ = new_value; } + int64_t value() const { return value_; } + void set_value(int64_t new_value) { value_ = new_value; } private: - int64 value_; + int64_t value_; }; class MinOperation { public: void Init() { values_set_.clear(); } - void Update(int64 update) { values_set_.insert(update); } - void Remove(int64 remove) { values_set_.erase(remove); } - int64 value() const { + void Update(int64_t update) { values_set_.insert(update); } + void Remove(int64_t remove) { values_set_.erase(remove); } + int64_t value() const { return (!values_set_.empty()) ? *values_set_.begin() : 0; } - void set_value(int64 new_value) {} + void set_value(int64_t new_value) {} private: - std::set values_set_; + std::set values_set_; }; class MaxOperation { public: void Init() { values_set_.clear(); } - void Update(int64 update) { values_set_.insert(update); } - void Remove(int64 remove) { values_set_.erase(remove); } - int64 value() const { + void Update(int64_t update) { values_set_.insert(update); } + void Remove(int64_t remove) { values_set_.erase(remove); } + int64_t value() const { return (!values_set_.empty()) ? *values_set_.rbegin() : 0; } - void set_value(int64 new_value) {} + void set_value(int64_t new_value) {} private: - std::set values_set_; + std::set values_set_; }; // Always accepts deltas, cost 0. @@ -2526,7 +2533,7 @@ class AcceptFilter : public LocalSearchFilter { public: std::string DebugString() const override { return "AcceptFilter"; } bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 obj_min, int64 obj_max) override { + int64_t obj_min, int64_t obj_max) override { return true; } void Synchronize(const Assignment* assignment, @@ -2544,7 +2551,7 @@ class RejectFilter : public LocalSearchFilter { public: std::string DebugString() const override { return "RejectFilter"; } bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 obj_min, int64 obj_max) override { + int64_t obj_min, int64_t obj_max) override { return false; } void Synchronize(const Assignment* assignment, @@ -2699,7 +2706,7 @@ void PathState::MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm() { const int first_fake_arc = num_arc_indices - changed_paths_.size(); for (int fake_arc = first_fake_arc; fake_arc < num_arc_indices; ++fake_arc) { const int new_path_begin = chains_.size(); - int32 arc = fake_arc; + int32_t arc = fake_arc; do { const int chain_begin = tail_head_indices_[arc].head_index; arc = next_arc_[arc]; @@ -2852,7 +2859,7 @@ class PathStateFilter : public LocalSearchFilter { const std::vector& nexts); void Relax(const Assignment* delta, const Assignment* deltadelta) override; bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override { + int64_t objective_min, int64_t objective_max) override { return true; } void Synchronize(const Assignment* delta, @@ -2984,7 +2991,8 @@ bool UnaryDimensionChecker::Check() const { if (path_state_->IsInvalid()) return true; for (const int path : path_state_->ChangedPaths()) { const Interval path_capacity = path_capacity_[path]; - if (path_capacity.min == kint64min && path_capacity.max == kint64max) { + if (path_capacity.min == std::numeric_limits::min() && + path_capacity.max == std::numeric_limits::max()) { continue; } const int path_class = path_class_[path]; @@ -3107,8 +3115,9 @@ void UnaryDimensionChecker::AppendPathDemandsToSums(int path) { partial_demand_sums_rmq_[0].push_back(demand_sum); const Interval node_capacity = node_capacity_[node]; - if (demand.min != demand.max || node_capacity.min != kint64min || - node_capacity.max != kint64max) { + if (demand.min != demand.max || + node_capacity.min != std::numeric_limits::min() || + node_capacity.max != std::numeric_limits::max()) { previous_nontrivial_index = index; } previous_nontrivial_index_.push_back(previous_nontrivial_index); @@ -3178,7 +3187,7 @@ class UnaryDimensionFilter : public LocalSearchFilter { : checker_(std::move(checker)) {} bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override { + int64_t objective_min, int64_t objective_max) override { return checker_->Check(); } @@ -3208,7 +3217,7 @@ class VariableDomainFilter : public LocalSearchFilter { VariableDomainFilter() {} ~VariableDomainFilter() override {} bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override; + int64_t objective_min, int64_t objective_max) override; void Synchronize(const Assignment* assignment, const Assignment* delta) override {} @@ -3217,7 +3226,8 @@ class VariableDomainFilter : public LocalSearchFilter { bool VariableDomainFilter::Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) { + int64_t objective_min, + int64_t objective_max) { const Assignment::IntContainer& container = delta->IntVarContainer(); const int size = container.Size(); for (int i = 0; i < size; ++i) { @@ -3283,8 +3293,8 @@ void IntVarLocalSearchFilter::SynchronizeOnAssignment( values_[i] = element.Value(); var_synced_[i] = true; } else { - const int64 kUnallocated = -1; - int64 index = kUnallocated; + const int64_t kUnallocated = -1; + int64_t index = kUnallocated; if (FindIndex(var, &index)) { values_[index] = element.Value(); var_synced_[index] = true; @@ -3310,11 +3320,11 @@ class SumObjectiveFilter : public IntVarLocalSearchFilter { Solver::LocalSearchFilterBound filter_enum) : IntVarLocalSearchFilter(vars), primary_vars_size_(vars.size()), - synchronized_costs_(new int64[vars.size()]), - delta_costs_(new int64[vars.size()]), + synchronized_costs_(new int64_t[vars.size()]), + delta_costs_(new int64_t[vars.size()]), filter_enum_(filter_enum), - synchronized_sum_(kint64min), - delta_sum_(kint64min), + synchronized_sum_(std::numeric_limits::min()), + delta_sum_(std::numeric_limits::min()), incremental_(false) { for (int i = 0; i < vars.size(); ++i) { synchronized_costs_[i] = 0; @@ -3326,7 +3336,7 @@ class SumObjectiveFilter : public IntVarLocalSearchFilter { delete[] delta_costs_; } bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override { + int64_t objective_min, int64_t objective_max) override { if (delta == nullptr) { return false; } @@ -3368,36 +3378,36 @@ class SumObjectiveFilter : public IntVarLocalSearchFilter { } // If the variable is synchronized, returns its associated cost, otherwise // returns 0. - virtual int64 CostOfSynchronizedVariable(int64 index) = 0; + virtual int64_t CostOfSynchronizedVariable(int64_t index) = 0; // If the variable is bound, fills new_cost with the cost associated to the // variable's valuation in container, and returns true. Otherwise, fills // new_cost with 0, and returns false. virtual bool FillCostOfBoundDeltaVariable( const Assignment::IntContainer& container, int index, - int* container_index, int64* new_cost) = 0; + int* container_index, int64_t* new_cost) = 0; bool IsIncremental() const override { return true; } std::string DebugString() const override { return "SumObjectiveFilter"; } - int64 GetSynchronizedObjectiveValue() const override { + int64_t GetSynchronizedObjectiveValue() const override { return synchronized_sum_; } - int64 GetAcceptedObjectiveValue() const override { return delta_sum_; } + int64_t GetAcceptedObjectiveValue() const override { return delta_sum_; } protected: const int primary_vars_size_; - int64* const synchronized_costs_; - int64* const delta_costs_; + int64_t* const synchronized_costs_; + int64_t* const delta_costs_; Solver::LocalSearchFilterBound filter_enum_; - int64 synchronized_sum_; - int64 delta_sum_; + int64_t synchronized_sum_; + int64_t delta_sum_; bool incremental_; private: void OnSynchronize(const Assignment* delta) override { synchronized_sum_ = 0; for (int i = 0; i < primary_vars_size_; ++i) { - const int64 cost = CostOfSynchronizedVariable(i); + const int64_t cost = CostOfSynchronizedVariable(i); synchronized_costs_[i] = cost; delta_costs_[i] = cost; synchronized_sum_ = CapAdd(synchronized_sum_, cost); @@ -3405,18 +3415,19 @@ class SumObjectiveFilter : public IntVarLocalSearchFilter { delta_sum_ = synchronized_sum_; incremental_ = false; } - int64 CostOfChanges(const Assignment* changes, const int64* const old_costs, - bool cache_delta_values) { - int64 total_cost = 0; + int64_t CostOfChanges(const Assignment* changes, + const int64_t* const old_costs, + bool cache_delta_values) { + int64_t total_cost = 0; const Assignment::IntContainer& container = changes->IntVarContainer(); const int size = container.Size(); for (int i = 0; i < size; ++i) { const IntVarElement& new_element = container.Element(i); IntVar* const var = new_element.Var(); - int64 index = -1; + int64_t index = -1; if (FindIndex(var, &index) && index < primary_vars_size_) { total_cost = CapSub(total_cost, old_costs[index]); - int64 new_cost = 0LL; + int64_t new_cost = 0LL; if (FillCostOfBoundDeltaVariable(container, index, &i, &new_cost)) { total_cost = CapAdd(total_cost, new_cost); } @@ -3437,14 +3448,14 @@ class BinaryObjectiveFilter : public SumObjectiveFilter { : SumObjectiveFilter(vars, filter_enum), value_evaluator_(std::move(value_evaluator)) {} ~BinaryObjectiveFilter() override {} - int64 CostOfSynchronizedVariable(int64 index) override { + int64_t CostOfSynchronizedVariable(int64_t index) override { return IntVarLocalSearchFilter::IsVarSynced(index) ? value_evaluator_(index, IntVarLocalSearchFilter::Value(index)) : 0; } bool FillCostOfBoundDeltaVariable(const Assignment::IntContainer& container, int index, int* container_index, - int64* new_cost) override { + int64_t* new_cost) override { const IntVarElement& element = container.Element(*container_index); if (element.Activated()) { *new_cost = value_evaluator_(index, element.Value()); @@ -3476,7 +3487,7 @@ class TernaryObjectiveFilter : public SumObjectiveFilter { CHECK_GE(IntVarLocalSearchFilter::Size(), 0); } ~TernaryObjectiveFilter() override {} - int64 CostOfSynchronizedVariable(int64 index) override { + int64_t CostOfSynchronizedVariable(int64_t index) override { DCHECK_LT(index, secondary_vars_offset_); return IntVarLocalSearchFilter::IsVarSynced(index) ? value_evaluator_(index, IntVarLocalSearchFilter::Value(index), @@ -3486,14 +3497,14 @@ class TernaryObjectiveFilter : public SumObjectiveFilter { } bool FillCostOfBoundDeltaVariable(const Assignment::IntContainer& container, int index, int* container_index, - int64* new_cost) override { + int64_t* new_cost) override { DCHECK_LT(index, secondary_vars_offset_); *new_cost = 0LL; const IntVarElement& element = container.Element(*container_index); const IntVar* secondary_var = IntVarLocalSearchFilter::Var(index + secondary_vars_offset_); if (element.Activated()) { - const int64 value = element.Value(); + const int64_t value = element.Value(); int hint_index = *container_index + 1; if (hint_index < container.Size() && secondary_var == container.Element(hint_index).Var()) { @@ -3536,8 +3547,8 @@ IntVarLocalSearchFilter* Solver::MakeSumObjectiveFilter( std::move(values), filter_enum)); } -LocalSearchVariable LocalSearchState::AddVariable(int64 initial_min, - int64 initial_max) { +LocalSearchVariable LocalSearchState::AddVariable(int64_t initial_min, + int64_t initial_max) { DCHECK(state_is_valid_); DCHECK_LE(initial_min, initial_max); initial_variable_bounds_.push_back({initial_min, initial_max}); @@ -3559,19 +3570,20 @@ void LocalSearchState::RelaxVariableBounds(int variable_index) { } } -int64 LocalSearchState::VariableMin(int variable_index) const { +int64_t LocalSearchState::VariableMin(int variable_index) const { DCHECK(state_is_valid_); DCHECK(0 <= variable_index && variable_index < variable_bounds_.size()); return variable_bounds_[variable_index].min; } -int64 LocalSearchState::VariableMax(int variable_index) const { +int64_t LocalSearchState::VariableMax(int variable_index) const { DCHECK(state_is_valid_); DCHECK(0 <= variable_index && variable_index < variable_bounds_.size()); return variable_bounds_[variable_index].max; } -bool LocalSearchState::TightenVariableMin(int variable_index, int64 min_value) { +bool LocalSearchState::TightenVariableMin(int variable_index, + int64_t min_value) { DCHECK(state_is_valid_); DCHECK(variable_is_relaxed_[variable_index]); DCHECK(0 <= variable_index && variable_index < variable_bounds_.size()); @@ -3583,7 +3595,8 @@ bool LocalSearchState::TightenVariableMin(int variable_index, int64 min_value) { return state_is_valid_; } -bool LocalSearchState::TightenVariableMax(int variable_index, int64 max_value) { +bool LocalSearchState::TightenVariableMax(int variable_index, + int64_t max_value) { DCHECK(state_is_valid_); DCHECK(variable_is_relaxed_[variable_index]); DCHECK(0 <= variable_index && variable_index < variable_bounds_.size()); @@ -3808,15 +3821,15 @@ class LocalSearchProfiler : public LocalSearchMonitor { } struct OperatorStats { - int64 neighbors = 0; - int64 filtered_neighbors = 0; - int64 accepted_neighbors = 0; + int64_t neighbors = 0; + int64_t filtered_neighbors = 0; + int64_t accepted_neighbors = 0; double seconds = 0; }; struct FilterStats { - int64 calls = 0; - int64 rejects = 0; + int64_t calls = 0; + int64_t rejects = 0; double seconds = 0; }; WallTimer timer_; @@ -3870,7 +3883,8 @@ void LocalSearchFilterManager::InitializeForcedEvents() { LocalSearchFilterManager::LocalSearchFilterManager( std::vector filters) - : synchronized_value_(kint64min), accepted_value_(kint64min) { + : synchronized_value_(std::numeric_limits::min()), + accepted_value_(std::numeric_limits::min()) { filter_events_.reserve(2 * filters.size()); for (LocalSearchFilter* filter : filters) { filter_events_.push_back({filter, FilterEventType::kRelax}); @@ -3884,8 +3898,8 @@ LocalSearchFilterManager::LocalSearchFilterManager( LocalSearchFilterManager::LocalSearchFilterManager( std::vector filter_events) : filter_events_(std::move(filter_events)), - synchronized_value_(kint64min), - accepted_value_(kint64min) { + synchronized_value_(std::numeric_limits::min()), + accepted_value_(std::numeric_limits::min()) { InitializeForcedEvents(); } @@ -3905,8 +3919,8 @@ void LocalSearchFilterManager::Revert() { bool LocalSearchFilterManager::Accept(LocalSearchMonitor* const monitor, const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, - int64 objective_max) { + int64_t objective_min, + int64_t objective_max) { Revert(); accepted_value_ = 0; bool ok = true; @@ -4009,7 +4023,7 @@ class FindOneNeighbor : public DecisionBuilder { private: bool FilterAccept(Solver* solver, Assignment* delta, Assignment* deltadelta, - int64 objective_min, int64 objective_max); + int64_t objective_min, int64_t objective_max); void SynchronizeAll(Solver* solver, bool synchronize_filters = true); Assignment* const assignment_; @@ -4022,8 +4036,8 @@ class FindOneNeighbor : public DecisionBuilder { const RegularLimit* const original_limit_; bool neighbor_found_; LocalSearchFilterManager* const filter_manager_; - int64 solutions_since_last_check_; - int64 check_period_; + int64_t solutions_since_last_check_; + int64_t check_period_; Assignment last_checked_assignment_; bool has_checked_assignment_ = false; }; @@ -4146,8 +4160,8 @@ Decision* FindOneNeighbor::Next(Solver* const solver) { solver->GetLocalSearchMonitor()->BeginFilterNeighbor(ls_operator_); const bool mh_filter = AcceptDelta(solver->ParentSearch(), delta, deltadelta); - int64 objective_min = kint64min; - int64 objective_max = kint64max; + int64_t objective_min = std::numeric_limits::min(); + int64_t objective_max = std::numeric_limits::max(); if (objective_) { objective_min = objective_->Min(); objective_max = objective_->Max(); @@ -4266,8 +4280,9 @@ Decision* FindOneNeighbor::Next(Solver* const solver) { } bool FindOneNeighbor::FilterAccept(Solver* solver, Assignment* delta, - Assignment* deltadelta, int64 objective_min, - int64 objective_max) { + Assignment* deltadelta, + int64_t objective_min, + int64_t objective_max) { if (filter_manager_ == nullptr) return true; LocalSearchMonitor* const monitor = solver->GetLocalSearchMonitor(); return filter_manager_->Accept(monitor, delta, deltadelta, objective_min, @@ -4671,7 +4686,7 @@ Decision* LocalSearch::Next(Solver* const solver) { case NestedSolveDecision::DECISION_PENDING: { // TODO(user): Find a way to make this balancing invisible to the // user (no increase in branch or fail counts for instance). - const int32 kLocalSearchBalancedTreeDepth = 32; + const int32_t kLocalSearchBalancedTreeDepth = 32; const int depth = solver->SearchDepth(); if (depth < kLocalSearchBalancedTreeDepth) { return solver->balancing_decision(); diff --git a/ortools/constraint_solver/model_cache.cc b/ortools/constraint_solver/model_cache.cc index 33265c93e8..dcd93571fb 100644 --- a/ortools/constraint_solver/model_cache.cc +++ b/ortools/constraint_solver/model_cache.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -55,28 +56,28 @@ bool IsEqual(const std::vector& a1, const std::vector& a2) { } template -uint64 Hash2(const A1& a1, const A2& a2) { - uint64 a = Hash1(a1); - uint64 b = uint64_t{0xe08c1d668b756f82}; // more of the golden ratio - uint64 c = Hash1(a2); +uint64_t Hash2(const A1& a1, const A2& a2) { + uint64_t a = Hash1(a1); + uint64_t b = uint64_t{0xe08c1d668b756f82}; // more of the golden ratio + uint64_t c = Hash1(a2); mix(a, b, c); return c; } template -uint64 Hash3(const A1& a1, const A2& a2, const A3& a3) { - uint64 a = Hash1(a1); - uint64 b = Hash1(a2); - uint64 c = Hash1(a3); +uint64_t Hash3(const A1& a1, const A2& a2, const A3& a3) { + uint64_t a = Hash1(a1); + uint64_t b = Hash1(a2); + uint64_t c = Hash1(a3); mix(a, b, c); return c; } template -uint64 Hash4(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - uint64 a = Hash1(a1); - uint64 b = Hash1(a2); - uint64 c = Hash2(a3, a4); +uint64_t Hash4(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { + uint64_t a = Hash1(a1); + uint64_t b = Hash1(a2); + uint64_t c = Hash2(a3, a4); mix(a, b, c); return c; } @@ -95,7 +96,7 @@ void Double(C*** array_ptr, int* size_ptr) { while (tmp != nullptr) { C* const to_reinsert = tmp; tmp = tmp->next(); - const uint64 position = to_reinsert->Hash() % (*size_ptr); + const uint64_t position = to_reinsert->Hash() % (*size_ptr); to_reinsert->set_next((*array_ptr)[position]); (*array_ptr)[position] = to_reinsert; } @@ -140,7 +141,7 @@ class Cache1 { } C* Find(const A1& a1) const { - uint64 code = Hash1(a1) % size_; + uint64_t code = Hash1(a1) % size_; Cell* tmp = array_[code]; while (tmp) { C* const result = tmp->ReturnsIfEqual(a1); @@ -174,7 +175,7 @@ class Cache1 { return nullptr; } - uint64 Hash() const { return Hash1(a1_); } + uint64_t Hash() const { return Hash1(a1_); } void set_next(Cell* const next) { next_ = next; } @@ -228,7 +229,7 @@ class Cache2 { } C* Find(const A1& a1, const A2& a2) const { - uint64 code = Hash2(a1, a2) % size_; + uint64_t code = Hash2(a1, a2) % size_; Cell* tmp = array_[code]; while (tmp) { C* const result = tmp->ReturnsIfEqual(a1, a2); @@ -262,7 +263,7 @@ class Cache2 { return nullptr; } - uint64 Hash() const { return Hash2(a1_, a2_); } + uint64_t Hash() const { return Hash2(a1_, a2_); } void set_next(Cell* const next) { next_ = next; } @@ -317,7 +318,7 @@ class Cache3 { } C* Find(const A1& a1, const A2& a2, const A3& a3) const { - uint64 code = Hash3(a1, a2, a3) % size_; + uint64_t code = Hash3(a1, a2, a3) % size_; Cell* tmp = array_[code]; while (tmp) { C* const result = tmp->ReturnsIfEqual(a1, a2, a3); @@ -352,7 +353,7 @@ class Cache3 { return nullptr; } - uint64 Hash() const { return Hash3(a1_, a2_, a3_); } + uint64_t Hash() const { return Hash3(a1_, a2_, a3_); } void set_next(Cell* const next) { next_ = next; } @@ -378,23 +379,23 @@ class NonReversibleCache : public ModelCache { typedef Cache1 ExprIntExprCache; typedef Cache1 > VarArrayIntExprCache; - typedef Cache2 VarConstantConstraintCache; + typedef Cache2 VarConstantConstraintCache; typedef Cache2 ExprExprConstraintCache; - typedef Cache2 VarConstantIntExprCache; - typedef Cache2 ExprConstantIntExprCache; + typedef Cache2 VarConstantIntExprCache; + typedef Cache2 ExprConstantIntExprCache; typedef Cache2 ExprExprIntExprCache; - typedef Cache2&> + typedef Cache2&> VarConstantArrayIntExprCache; - typedef Cache2, const std::vector&> + typedef Cache2, const std::vector&> VarArrayConstantArrayIntExprCache; - typedef Cache2, int64> + typedef Cache2, int64_t> VarArrayConstantIntExprCache; - typedef Cache3 + typedef Cache3 VarConstantConstantIntExprCache; - typedef Cache3 + typedef Cache3 VarConstantConstantConstraintCache; - typedef Cache3 + typedef Cache3 ExprExprConstantIntExprCache; explicit NonReversibleCache(Solver* const solver) @@ -519,7 +520,7 @@ class NonReversibleCache : public ModelCache { // VarConstantConstraint. Constraint* FindVarConstantConstraint( - IntVar* const var, int64 value, + IntVar* const var, int64_t value, VarConstantConstraintType type) const override { DCHECK(var != nullptr); DCHECK_GE(type, 0); @@ -528,7 +529,7 @@ class NonReversibleCache : public ModelCache { } void InsertVarConstantConstraint(Constraint* const ct, IntVar* const var, - int64 value, + int64_t value, VarConstantConstraintType type) override { DCHECK(ct != nullptr); DCHECK(var != nullptr); @@ -544,7 +545,7 @@ class NonReversibleCache : public ModelCache { // Var Constant Constant Constraint. Constraint* FindVarConstantConstantConstraint( - IntVar* const var, int64 value1, int64 value2, + IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) const override { DCHECK(var != nullptr); DCHECK_GE(type, 0); @@ -553,7 +554,7 @@ class NonReversibleCache : public ModelCache { } void InsertVarConstantConstantConstraint( - Constraint* const ct, IntVar* const var, int64 value1, int64 value2, + Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) override { DCHECK(ct != nullptr); DCHECK(var != nullptr); @@ -621,7 +622,7 @@ class NonReversibleCache : public ModelCache { // Expr Constant Expressions. IntExpr* FindExprConstantExpression( - IntExpr* const expr, int64 value, + IntExpr* const expr, int64_t value, ExprConstantExpressionType type) const override { DCHECK(expr != nullptr); DCHECK_GE(type, 0); @@ -630,7 +631,7 @@ class NonReversibleCache : public ModelCache { } void InsertExprConstantExpression(IntExpr* const expression, - IntExpr* const expr, int64 value, + IntExpr* const expr, int64_t value, ExprConstantExpressionType type) override { DCHECK(expression != nullptr); DCHECK(expr != nullptr); @@ -672,7 +673,7 @@ class NonReversibleCache : public ModelCache { // Expr Expr Constant Expression. IntExpr* FindExprExprConstantExpression( - IntExpr* const var1, IntExpr* const var2, int64 constant, + IntExpr* const var1, IntExpr* const var2, int64_t constant, ExprExprConstantExpressionType type) const override { DCHECK(var1 != nullptr); DCHECK(var2 != nullptr); @@ -683,7 +684,7 @@ class NonReversibleCache : public ModelCache { void InsertExprExprConstantExpression( IntExpr* const expression, IntExpr* const var1, IntExpr* const var2, - int64 constant, ExprExprConstantExpressionType type) override { + int64_t constant, ExprExprConstantExpressionType type) override { DCHECK(expression != nullptr); DCHECK(var1 != nullptr); DCHECK(var2 != nullptr); @@ -701,7 +702,7 @@ class NonReversibleCache : public ModelCache { // Var Constant Constant Expression. IntExpr* FindVarConstantConstantExpression( - IntVar* const var, int64 value1, int64 value2, + IntVar* const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) const override { DCHECK(var != nullptr); DCHECK_GE(type, 0); @@ -710,8 +711,8 @@ class NonReversibleCache : public ModelCache { } void InsertVarConstantConstantExpression( - IntExpr* const expression, IntVar* const var, int64 value1, int64 value2, - VarConstantConstantExpressionType type) override { + IntExpr* const expression, IntVar* const var, int64_t value1, + int64_t value2, VarConstantConstantExpressionType type) override { DCHECK(expression != nullptr); DCHECK(var != nullptr); DCHECK_GE(type, 0); @@ -728,7 +729,7 @@ class NonReversibleCache : public ModelCache { // Var Constant Array Expression. IntExpr* FindVarConstantArrayExpression( - IntVar* const var, const std::vector& values, + IntVar* const var, const std::vector& values, VarConstantArrayExpressionType type) const override { DCHECK(var != nullptr); DCHECK_GE(type, 0); @@ -738,7 +739,7 @@ class NonReversibleCache : public ModelCache { void InsertVarConstantArrayExpression( IntExpr* const expression, IntVar* const var, - const std::vector& values, + const std::vector& values, VarConstantArrayExpressionType type) override { DCHECK(expression != nullptr); DCHECK(var != nullptr); @@ -777,7 +778,7 @@ class NonReversibleCache : public ModelCache { // Var Array Constant Array Expressions. IntExpr* FindVarArrayConstantArrayExpression( - const std::vector& vars, const std::vector& values, + const std::vector& vars, const std::vector& values, VarArrayConstantArrayExpressionType type) const override { DCHECK_GE(type, 0); DCHECK_LT(type, VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX); @@ -786,7 +787,7 @@ class NonReversibleCache : public ModelCache { void InsertVarArrayConstantArrayExpression( IntExpr* const expression, const std::vector& vars, - const std::vector& values, + const std::vector& values, VarArrayConstantArrayExpressionType type) override { DCHECK(expression != nullptr); DCHECK_GE(type, 0); @@ -802,7 +803,7 @@ class NonReversibleCache : public ModelCache { // Var Array Constant Expressions. IntExpr* FindVarArrayConstantExpression( - const std::vector& vars, int64 value, + const std::vector& vars, int64_t value, VarArrayConstantExpressionType type) const override { DCHECK_GE(type, 0); DCHECK_LT(type, VAR_ARRAY_CONSTANT_EXPRESSION_MAX); @@ -810,8 +811,8 @@ class NonReversibleCache : public ModelCache { } void InsertVarArrayConstantExpression( - IntExpr* const expression, const std::vector& vars, int64 value, - VarArrayConstantExpressionType type) override { + IntExpr* const expression, const std::vector& vars, + int64_t value, VarArrayConstantExpressionType type) override { DCHECK(expression != nullptr); DCHECK_GE(type, 0); DCHECK_LT(type, VAR_ARRAY_CONSTANT_EXPRESSION_MAX); diff --git a/ortools/constraint_solver/pack.cc b/ortools/constraint_solver/pack.cc index b96cdcc935..e3d8b13d0c 100644 --- a/ortools/constraint_solver/pack.cc +++ b/ortools/constraint_solver/pack.cc @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -196,7 +197,7 @@ void Pack::InitialPropagate() { IntVar* const var = vars_[var_index]; var->SetRange(0, bins_); // bins_ -> item is not assigned to a bin. if (var->Bound()) { - const int64 value = var->Min(); + const int64_t value = var->Min(); if (value < bins_) { forced_[value].push_back(var_index); data->PushAssigned(var_index); @@ -212,7 +213,7 @@ void Pack::InitialPropagate() { data->PushAssigned(var_index); } std::unique_ptr it(var->MakeDomainIterator(false)); - for (const int64 value : InitAndGetValues(it.get())) { + for (const int64_t value : InitAndGetValues(it.get())) { if (value >= 0 && value <= bins_) { unprocessed_->SetToOne(s, value, var_index); if (value != bins_) { @@ -334,36 +335,36 @@ void Pack::OneDomain(int var_index) { // TODO(user): We know var ranges from 0 to bins_. There are lots // of simplifications possible. Solver* const s = solver(); - const uint64 current_stamp = s->fail_stamp(); + const uint64_t current_stamp = s->fail_stamp(); if (stamp_ < current_stamp) { stamp_ = current_stamp; ClearAll(); } IntVar* const var = vars_[var_index]; bool bound = var->Bound(); - const int64 oldmin = var->OldMin(); - const int64 oldmax = var->OldMax(); - const int64 vmin = var->Min(); - const int64 vmax = var->Max(); - for (int64 value = std::max(oldmin, int64{0}); - value < std::min(vmin, bins_ + int64{1}); ++value) { + const int64_t oldmin = var->OldMin(); + const int64_t oldmax = var->OldMax(); + const int64_t vmin = var->Min(); + const int64_t vmax = var->Max(); + for (int64_t value = std::max(oldmin, int64_t{0}); + value < std::min(vmin, bins_ + int64_t{1}); ++value) { if (unprocessed_->IsSet(value, var_index)) { unprocessed_->SetToZero(s, value, var_index); removed_[value].push_back(var_index); } } if (!bound) { - for (const int64 value : InitAndGetValues(holes_[var_index])) { - if (value >= std::max(int64{0}, vmin) && - value <= std::min(static_cast(bins_), vmax)) { + for (const int64_t value : InitAndGetValues(holes_[var_index])) { + if (value >= std::max(int64_t{0}, vmin) && + value <= std::min(static_cast(bins_), vmax)) { DCHECK(unprocessed_->IsSet(value, var_index)); unprocessed_->SetToZero(s, value, var_index); removed_[value].push_back(var_index); } } } - for (int64 value = std::max(vmax + 1, int64{0}); - value <= std::min(oldmax, static_cast(bins_)); ++value) { + for (int64_t value = std::max(vmax + 1, int64_t{0}); + value <= std::min(oldmax, static_cast(bins_)); ++value) { if (unprocessed_->IsSet(value, var_index)) { unprocessed_->SetToZero(s, value, var_index); removed_[value].push_back(var_index); @@ -506,8 +507,8 @@ void Pack::UnassignAllRemainingItems() { namespace { struct WeightContainer { int index; - int64 weight; - WeightContainer(int i, int64 w) : index(i), weight(w) {} + int64_t weight; + WeightContainer(int i, int64_t w) : index(i), weight(w) {} bool operator<(const WeightContainer& c) const { return (weight < c.weight); } }; @@ -521,7 +522,7 @@ void SortWeightVector(std::vector* const indices, } void SortIndexByWeight(std::vector* const indices, - const std::vector& weights) { + const std::vector& weights) { std::vector to_sort; for (int index = 0; index < indices->size(); ++index) { if (weights[index] != 0) { @@ -558,8 +559,8 @@ void SortIndexByWeight(std::vector* const indices, class DimensionLessThanConstant : public Dimension { public: DimensionLessThanConstant(Solver* const s, Pack* const p, - const std::vector& weights, - const std::vector& upper_bounds) + const std::vector& weights, + const std::vector& upper_bounds) : Dimension(s, p), vars_count_(weights.size()), weights_(weights), @@ -579,7 +580,7 @@ class DimensionLessThanConstant : public Dimension { void Post() override {} void PushFromTop(int bin_index) { - const int64 slack = + const int64_t slack = upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index]; if (slack < 0) { solver()->Fail(); @@ -601,7 +602,7 @@ class DimensionLessThanConstant : public Dimension { void InitialPropagate(int bin_index, const std::vector& forced, const std::vector& undecided) override { Solver* const s = solver(); - int64 sum = 0LL; + int64_t sum = 0LL; for (const int value : forced) { sum += weights_[value]; } @@ -616,7 +617,7 @@ class DimensionLessThanConstant : public Dimension { const std::vector& removed) override { if (!forced.empty()) { Solver* const s = solver(); - int64 sum = sum_of_bound_variables_vector_[bin_index]; + int64_t sum = sum_of_bound_variables_vector_[bin_index]; for (const int value : forced) { sum += weights_[value]; } @@ -643,11 +644,11 @@ class DimensionLessThanConstant : public Dimension { private: const int vars_count_; - const std::vector weights_; + const std::vector weights_; const int bins_count_; - const std::vector upper_bounds_; + const std::vector upper_bounds_; RevArray first_unbound_backward_vector_; - RevArray sum_of_bound_variables_vector_; + RevArray sum_of_bound_variables_vector_; std::vector ranked_; }; @@ -656,7 +657,7 @@ class DimensionSumCallbackLessThanConstant : public Dimension { DimensionSumCallbackLessThanConstant(Solver* const s, Pack* const p, const Solver::IndexEvaluator1& weights, int vars_count, - const std::vector& upper_bounds) + const std::vector& upper_bounds) : Dimension(s, p), vars_count_(vars_count), weights_(weights), @@ -678,7 +679,7 @@ class DimensionSumCallbackLessThanConstant : public Dimension { void Post() override {} void PushFromTop(int bin_index) { - const int64 slack = + const int64_t slack = upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index]; if (slack < 0) { solver()->Fail(); @@ -700,7 +701,7 @@ class DimensionSumCallbackLessThanConstant : public Dimension { void InitialPropagate(int bin_index, const std::vector& forced, const std::vector& undecided) override { Solver* const s = solver(); - int64 sum = 0LL; + int64_t sum = 0LL; for (const int value : forced) { sum += weights_(value); } @@ -715,7 +716,7 @@ class DimensionSumCallbackLessThanConstant : public Dimension { const std::vector& removed) override { if (!forced.empty()) { Solver* const s = solver(); - int64 sum = sum_of_bound_variables_vector_[bin_index]; + int64_t sum = sum_of_bound_variables_vector_[bin_index]; for (const int value : forced) { sum += weights_(value); } @@ -745,9 +746,9 @@ class DimensionSumCallbackLessThanConstant : public Dimension { const int vars_count_; Solver::IndexEvaluator1 weights_; const int bins_count_; - const std::vector upper_bounds_; + const std::vector upper_bounds_; RevArray first_unbound_backward_vector_; - RevArray sum_of_bound_variables_vector_; + RevArray sum_of_bound_variables_vector_; std::vector ranked_; }; @@ -756,7 +757,7 @@ class DimensionLessThanConstantCallback2 : public Dimension { DimensionLessThanConstantCallback2(Solver* const s, Pack* const p, const Solver::IndexEvaluator2& weights, int vars_count, - const std::vector& upper_bounds) + const std::vector& upper_bounds) : Dimension(s, p), vars_count_(vars_count), weights_(weights), @@ -781,7 +782,7 @@ class DimensionLessThanConstantCallback2 : public Dimension { void Post() override {} void PushFromTop(int bin_index) { - const int64 slack = + const int64_t slack = upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index]; if (slack < 0) { solver()->Fail(); @@ -803,7 +804,7 @@ class DimensionLessThanConstantCallback2 : public Dimension { void InitialPropagate(int bin_index, const std::vector& forced, const std::vector& undecided) override { Solver* const s = solver(); - int64 sum = 0LL; + int64_t sum = 0LL; for (const int value : forced) { sum += weights_(value, bin_index); } @@ -819,7 +820,7 @@ class DimensionLessThanConstantCallback2 : public Dimension { const std::vector& removed) override { if (!forced.empty()) { Solver* const s = solver(); - int64 sum = sum_of_bound_variables_vector_[bin_index]; + int64_t sum = sum_of_bound_variables_vector_[bin_index]; for (const int value : forced) { sum += weights_(value, bin_index); } @@ -849,9 +850,9 @@ class DimensionLessThanConstantCallback2 : public Dimension { const int vars_count_; Solver::IndexEvaluator2 weights_; const int bins_count_; - const std::vector upper_bounds_; + const std::vector upper_bounds_; RevArray first_unbound_backward_vector_; - RevArray sum_of_bound_variables_vector_; + RevArray sum_of_bound_variables_vector_; std::vector> ranked_; }; @@ -871,7 +872,7 @@ class DimensionWeightedSumEqVar : public Dimension { }; DimensionWeightedSumEqVar(Solver* const s, Pack* const p, - const std::vector& weights, + const std::vector& weights, const std::vector& loads) : Dimension(s, p), vars_count_(weights.size()), @@ -905,17 +906,17 @@ class DimensionWeightedSumEqVar : public Dimension { void PushFromTop(int bin_index) { IntVar* const load = loads_[bin_index]; - const int64 sum_min = sum_of_bound_variables_vector_[bin_index]; - const int64 sum_max = sum_of_all_variables_vector_[bin_index]; + const int64_t sum_min = sum_of_bound_variables_vector_[bin_index]; + const int64_t sum_max = sum_of_all_variables_vector_[bin_index]; load->SetRange(sum_min, sum_max); - const int64 slack_up = load->Max() - sum_min; - const int64 slack_down = sum_max - load->Min(); + const int64_t slack_up = load->Max() - sum_min; + const int64_t slack_down = sum_max - load->Min(); DCHECK_GE(slack_down, 0); DCHECK_GE(slack_up, 0); int last_unbound = first_unbound_backward_vector_[bin_index]; for (; last_unbound >= 0; --last_unbound) { const int var_index = ranked_[last_unbound]; - const int64 weight = weights_[var_index]; + const int64_t weight = weights_[var_index]; if (IsUndecided(var_index, bin_index)) { if (weight > slack_up) { SetImpossible(var_index, bin_index); @@ -932,7 +933,7 @@ class DimensionWeightedSumEqVar : public Dimension { void InitialPropagate(int bin_index, const std::vector& forced, const std::vector& undecided) override { Solver* const s = solver(); - int64 sum = 0LL; + int64_t sum = 0LL; for (const int value : forced) { sum += weights_[value]; } @@ -950,12 +951,12 @@ class DimensionWeightedSumEqVar : public Dimension { void Propagate(int bin_index, const std::vector& forced, const std::vector& removed) override { Solver* const s = solver(); - int64 down = sum_of_bound_variables_vector_[bin_index]; + int64_t down = sum_of_bound_variables_vector_[bin_index]; for (const int value : forced) { down += weights_[value]; } sum_of_bound_variables_vector_.SetValue(s, bin_index, down); - int64 up = sum_of_all_variables_vector_[bin_index]; + int64_t up = sum_of_all_variables_vector_[bin_index]; for (const int value : removed) { up -= weights_[value]; } @@ -981,12 +982,12 @@ class DimensionWeightedSumEqVar : public Dimension { private: const int vars_count_; - const std::vector weights_; + const std::vector weights_; const int bins_count_; const std::vector loads_; RevArray first_unbound_backward_vector_; - RevArray sum_of_bound_variables_vector_; - RevArray sum_of_all_variables_vector_; + RevArray sum_of_bound_variables_vector_; + RevArray sum_of_all_variables_vector_; std::vector ranked_; }; @@ -1045,17 +1046,17 @@ class DimensionWeightedCallback2SumEqVar : public Dimension { void PushFromTop(int bin_index) { IntVar* const load = loads_[bin_index]; - const int64 sum_min = sum_of_bound_variables_vector_[bin_index]; - const int64 sum_max = sum_of_all_variables_vector_[bin_index]; + const int64_t sum_min = sum_of_bound_variables_vector_[bin_index]; + const int64_t sum_max = sum_of_all_variables_vector_[bin_index]; load->SetRange(sum_min, sum_max); - const int64 slack_up = load->Max() - sum_min; - const int64 slack_down = sum_max - load->Min(); + const int64_t slack_up = load->Max() - sum_min; + const int64_t slack_down = sum_max - load->Min(); DCHECK_GE(slack_down, 0); DCHECK_GE(slack_up, 0); int last_unbound = first_unbound_backward_vector_[bin_index]; for (; last_unbound >= 0; --last_unbound) { const int var_index = ranked_[bin_index][last_unbound]; - const int64 weight = weights_(var_index, bin_index); + const int64_t weight = weights_(var_index, bin_index); if (IsUndecided(var_index, bin_index)) { if (weight > slack_up) { SetImpossible(var_index, bin_index); @@ -1072,7 +1073,7 @@ class DimensionWeightedCallback2SumEqVar : public Dimension { void InitialPropagate(int bin_index, const std::vector& forced, const std::vector& undecided) override { Solver* const s = solver(); - int64 sum = 0LL; + int64_t sum = 0LL; for (const int value : forced) { sum += weights_(value, bin_index); } @@ -1091,12 +1092,12 @@ class DimensionWeightedCallback2SumEqVar : public Dimension { void Propagate(int bin_index, const std::vector& forced, const std::vector& removed) override { Solver* const s = solver(); - int64 down = sum_of_bound_variables_vector_[bin_index]; + int64_t down = sum_of_bound_variables_vector_[bin_index]; for (const int value : forced) { down += weights_(value, bin_index); } sum_of_bound_variables_vector_.SetValue(s, bin_index, down); - int64 up = sum_of_all_variables_vector_[bin_index]; + int64_t up = sum_of_all_variables_vector_[bin_index]; for (const int value : removed) { up -= weights_(value, bin_index); } @@ -1127,8 +1128,8 @@ class DimensionWeightedCallback2SumEqVar : public Dimension { const int bins_count_; const std::vector loads_; RevArray first_unbound_backward_vector_; - RevArray sum_of_bound_variables_vector_; - RevArray sum_of_all_variables_vector_; + RevArray sum_of_bound_variables_vector_; + RevArray sum_of_all_variables_vector_; std::vector> ranked_; }; @@ -1146,7 +1147,7 @@ class AssignedWeightedSumDimension : public Dimension { }; AssignedWeightedSumDimension(Solver* const s, Pack* const p, - const std::vector& weights, + const std::vector& weights, int bins_count, IntVar* const cost_var) : Dimension(s, p), vars_count_(weights.size()), @@ -1178,13 +1179,13 @@ class AssignedWeightedSumDimension : public Dimension { void PropagateAll() { cost_var_->SetRange(sum_of_assigned_items_.Value(), sum_all_weights_ - sum_of_unassigned_items_.Value()); - const int64 slack_up = cost_var_->Max() - sum_of_assigned_items_.Value(); - const int64 slack_down = sum_all_weights_ - cost_var_->Min(); + const int64_t slack_up = cost_var_->Max() - sum_of_assigned_items_.Value(); + const int64_t slack_down = sum_all_weights_ - cost_var_->Min(); int last_unbound = first_unbound_backward_.Value(); for (; last_unbound >= 0; --last_unbound) { const int var_index = ranked_[last_unbound]; if (!IsAssignedStatusKnown(var_index)) { - const int64 coefficient = weights_[var_index]; + const int64_t coefficient = weights_[var_index]; if (coefficient > slack_up) { SetUnassigned(var_index); } else if (coefficient > slack_down) { @@ -1216,13 +1217,13 @@ class AssignedWeightedSumDimension : public Dimension { void PropagateUnassigned(const std::vector& assigned, const std::vector& unassigned) override { - int64 sum_assigned = sum_of_assigned_items_.Value(); + int64_t sum_assigned = sum_of_assigned_items_.Value(); for (int index = 0; index < assigned.size(); ++index) { const int var_index = assigned[index]; sum_assigned += weights_[var_index]; } - int64 sum_unassigned = sum_of_unassigned_items_.Value(); + int64_t sum_unassigned = sum_of_unassigned_items_.Value(); for (int index = 0; index < unassigned.size(); ++index) { const int var_index = unassigned[index]; sum_unassigned += weights_[var_index]; @@ -1249,14 +1250,14 @@ class AssignedWeightedSumDimension : public Dimension { private: const int vars_count_; - const std::vector weights_; + const std::vector weights_; const int bins_count_; IntVar* const cost_var_; Rev first_unbound_backward_; - Rev sum_of_assigned_items_; - Rev sum_of_unassigned_items_; + Rev sum_of_assigned_items_; + Rev sum_of_unassigned_items_; std::vector ranked_; - int64 sum_all_weights_; + int64_t sum_all_weights_; }; // ----- Count unassigned jobs dimension ----- @@ -1471,7 +1472,7 @@ class CountUsedBinDimension : public Dimension { class VariableUsageDimension : public Dimension { public: VariableUsageDimension(Solver* const solver, Pack* const pack, - const std::vector& capacities, + const std::vector& capacities, const std::vector& weights) : Dimension(solver, pack), capacities_(capacities), weights_(weights) {} @@ -1518,7 +1519,7 @@ class VariableUsageDimension : public Dimension { } private: - const std::vector capacities_; + const std::vector capacities_; const std::vector weights_; }; } // namespace @@ -1526,7 +1527,7 @@ class VariableUsageDimension : public Dimension { // ---------- API ---------- void Pack::AddWeightedSumLessOrEqualConstantDimension( - const std::vector& weights, const std::vector& bounds) { + const std::vector& weights, const std::vector& bounds) { CHECK_EQ(weights.size(), vars_.size()); CHECK_EQ(bounds.size(), bins_); Solver* const s = solver(); @@ -1536,7 +1537,7 @@ void Pack::AddWeightedSumLessOrEqualConstantDimension( } void Pack::AddWeightedSumLessOrEqualConstantDimension( - Solver::IndexEvaluator1 weights, const std::vector& bounds) { + Solver::IndexEvaluator1 weights, const std::vector& bounds) { CHECK(weights != nullptr); CHECK_EQ(bounds.size(), bins_); Solver* const s = solver(); @@ -1546,7 +1547,7 @@ void Pack::AddWeightedSumLessOrEqualConstantDimension( } void Pack::AddWeightedSumLessOrEqualConstantDimension( - Solver::IndexEvaluator2 weights, const std::vector& bounds) { + Solver::IndexEvaluator2 weights, const std::vector& bounds) { CHECK(weights != nullptr); CHECK_EQ(bounds.size(), bins_); Solver* const s = solver(); @@ -1555,7 +1556,7 @@ void Pack::AddWeightedSumLessOrEqualConstantDimension( dims_.push_back(dim); } -void Pack::AddWeightedSumEqualVarDimension(const std::vector& weights, +void Pack::AddWeightedSumEqualVarDimension(const std::vector& weights, const std::vector& loads) { CHECK_EQ(weights.size(), vars_.size()); CHECK_EQ(loads.size(), bins_); @@ -1575,8 +1576,8 @@ void Pack::AddWeightedSumEqualVarDimension(Solver::IndexEvaluator2 weights, dims_.push_back(dim); } -void Pack::AddWeightedSumOfAssignedDimension(const std::vector& weights, - IntVar* const cost_var) { +void Pack::AddWeightedSumOfAssignedDimension( + const std::vector& weights, IntVar* const cost_var) { CHECK_EQ(weights.size(), vars_.size()); Solver* const s = solver(); Dimension* const dim = s->RevAlloc( @@ -1585,7 +1586,7 @@ void Pack::AddWeightedSumOfAssignedDimension(const std::vector& weights, } void Pack::AddSumVariableWeightsLessOrEqualConstantDimension( - const std::vector& usage, const std::vector& capacity) { + const std::vector& usage, const std::vector& capacity) { CHECK_EQ(usage.size(), vars_.size()); CHECK_EQ(capacity.size(), bins_); Solver* const s = solver(); diff --git a/ortools/constraint_solver/python/constraint_solver.i b/ortools/constraint_solver/python/constraint_solver.i index 19df0155be..9e6b6c6635 100644 --- a/ortools/constraint_solver/python/constraint_solver.i +++ b/ortools/constraint_solver/python/constraint_solver.i @@ -31,15 +31,12 @@ // - examples/python/sudoku.py // - examples/python/zebra.py -%include "stdint.i" - %include "ortools/base/base.i" %include "ortools/util/python/proto.i" // PY_CONVERT_HELPER_* macros. %include "ortools/constraint_solver/python/constraint_solver_helpers.i" -// std::function utilities. %include "ortools/util/python/functions.i" %include "ortools/util/python/vector.i" @@ -55,6 +52,7 @@ namespace operations_research { class AssignmentProto; class ConstraintSolverParameters; +class IntTupleSet; class RegularLimitParameters; } // namespace operations_research @@ -192,13 +190,13 @@ Constraint* PythonMethodName(IntervalVar* other) { $self, operations_research::Solver::CppEnumName, other); } -Constraint* PythonMethodName##WithDelay(IntervalVar* other, int64 delay) { +Constraint* PythonMethodName##WithDelay(IntervalVar* other, int64_t delay) { return $self->solver()->MakeIntervalVarRelationWithDelay( $self, operations_research::Solver::CppEnumName, other, delay); } %enddef %define SCHEDULING_CONSTRAINT(PythonMethodName, CppEnumName) -Constraint* PythonMethodName(int64 date) { +Constraint* PythonMethodName(int64_t date) { return $self->solver()->MakeIntervalVarRelation( $self, operations_research::Solver::CppEnumName, date); } @@ -262,7 +260,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); return $self->MakeSearchLog(period, callback); } - IntExpr* ElementFunction(std::function values, + IntExpr* ElementFunction(std::function values, IntVar* const index) { return $self->MakeElement(values, index); } @@ -270,7 +268,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); DecisionBuilder* VarEvalValStrPhase( const std::vector& vars, - std::function var_evaluator, + std::function var_evaluator, operations_research::Solver::IntValueStrategy val_str) { return $self->MakePhase(vars, var_evaluator, val_str); } @@ -284,7 +282,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); DecisionBuilder* VarEvalValEvalPhase( const std::vector& vars, - std::function var_eval, + std::function var_eval, Solver::IndexEvaluator2 val_eval) { return $self->MakePhase(vars, var_eval, val_eval); } @@ -293,15 +291,15 @@ PY_STRINGIFY_DEBUGSTRING(Decision); const std::vector& vars, operations_research::Solver::IntVarStrategy var_str, Solver::IndexEvaluator2 val_eval, - std::function tie_breaker) { + std::function tie_breaker) { return $self->MakePhase(vars, var_str, val_eval, tie_breaker); } DecisionBuilder* VarEvalValEvalTieBreakPhase( const std::vector& vars, - std::function var_eval, + std::function var_eval, Solver::IndexEvaluator2 val_eval, - std::function tie_breaker) { + std::function tie_breaker) { return $self->MakePhase(vars, var_eval, val_eval, tie_breaker); } @@ -324,7 +322,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); bool maximize, IntVar* const objective, Solver::IndexEvaluator2 objective_function, - int64 step, + int64_t step, const std::vector& vars, double penalty_factor) { return $self->MakeGuidedLocalSearch(maximize, @@ -353,10 +351,10 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __add__(Constraint* other) { return $self->solver()->MakeSum($self, other->Var()); } - IntExpr* __add__(int64 v) { + IntExpr* __add__(int64_t v) { return $self->solver()->MakeSum($self, v); } - IntExpr* __radd__(int64 v) { + IntExpr* __radd__(int64_t v) { return $self->solver()->MakeSum($self, v); } IntExpr* __sub__(IntExpr* other) { @@ -365,10 +363,10 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __sub__(Constraint* other) { return $self->solver()->MakeDifference($self, other->Var()); } - IntExpr* __sub__(int64 v) { + IntExpr* __sub__(int64_t v) { return $self->solver()->MakeSum($self, -v); } - IntExpr* __rsub__(int64 v) { + IntExpr* __rsub__(int64_t v) { return $self->solver()->MakeDifference(v, $self); } IntExpr* __mul__(IntExpr* other) { @@ -377,19 +375,19 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __mul__(Constraint* other) { return $self->solver()->MakeProd($self, other->Var()); } - IntExpr* __mul__(int64 v) { + IntExpr* __mul__(int64_t v) { return $self->solver()->MakeProd($self, v); } - IntExpr* __rmul__(int64 v) { + IntExpr* __rmul__(int64_t v) { return $self->solver()->MakeProd($self, v); } - IntExpr* __floordiv__(int64 v) { + IntExpr* __floordiv__(int64_t v) { return $self->solver()->MakeDiv($self, v); } IntExpr* __floordiv__(IntExpr* e) { return $self->solver()->MakeDiv($self, e); } - IntExpr* __mod__(int64 v) { + IntExpr* __mod__(int64_t v) { return $self->solver()->MakeModulo($self, v); } IntExpr* __mod__(IntExpr* e) { @@ -405,22 +403,22 @@ PY_STRINGIFY_DEBUGSTRING(Decision); return $self->solver()->MakeSquare($self); } - Constraint* __eq__(int64 v) { + Constraint* __eq__(int64_t v) { return $self->solver()->MakeEquality($self, v); } - Constraint* __ne__(int64 v) { + Constraint* __ne__(int64_t v) { return $self->solver()->MakeNonEquality($self->Var(), v); } - Constraint* __ge__(int64 v) { + Constraint* __ge__(int64_t v) { return $self->solver()->MakeGreaterOrEqual($self, v); } - Constraint* __gt__(int64 v) { + Constraint* __gt__(int64_t v) { return $self->solver()->MakeGreater($self, v); } - Constraint* __le__(int64 v) { + Constraint* __le__(int64_t v) { return $self->solver()->MakeLessOrEqual($self, v); } - Constraint* __lt__(int64 v) { + Constraint* __lt__(int64_t v) { return $self->solver()->MakeLess($self, v); } Constraint* __eq__(IntExpr* other) { @@ -462,20 +460,20 @@ PY_STRINGIFY_DEBUGSTRING(Decision); Constraint* MapTo(const std::vector& vars) { return $self->solver()->MakeMapDomain($self->Var(), vars); } - IntExpr* IndexOf(const std::vector& vars) { + IntExpr* IndexOf(const std::vector& vars) { return $self->solver()->MakeElement(vars, $self->Var()); } IntExpr* IndexOf(const std::vector& vars) { return $self->solver()->MakeElement(vars, $self->Var()); } - IntVar* IsMember(const std::vector& values) { + IntVar* IsMember(const std::vector& values) { return $self->solver()->MakeIsMemberVar($self->Var(), values); } - Constraint* Member(const std::vector& values) { + Constraint* Member(const std::vector& values) { return $self->solver()->MakeMemberCt($self->Var(), values); } - Constraint* NotMember(const std::vector& starts, - const std::vector& ends) { + Constraint* NotMember(const std::vector& starts, + const std::vector& ends) { return $self->solver()->MakeNotMemberCt($self, starts, ends); } } @@ -488,10 +486,10 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __add__(Constraint* other) { return $self->solver()->MakeSum($self->Var(), other->Var()); } - IntExpr* __add__(int64 v) { + IntExpr* __add__(int64_t v) { return $self->solver()->MakeSum($self->Var(), v); } - IntExpr* __radd__(int64 v) { + IntExpr* __radd__(int64_t v) { return $self->solver()->MakeSum($self->Var(), v); } IntExpr* __sub__(IntExpr* other) { @@ -500,10 +498,10 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __sub__(Constraint* other) { return $self->solver()->MakeDifference($self->Var(), other->Var()); } - IntExpr* __sub__(int64 v) { + IntExpr* __sub__(int64_t v) { return $self->solver()->MakeSum($self->Var(), -v); } - IntExpr* __rsub__(int64 v) { + IntExpr* __rsub__(int64_t v) { return $self->solver()->MakeDifference(v, $self->Var()); } IntExpr* __mul__(IntExpr* other) { @@ -512,13 +510,13 @@ PY_STRINGIFY_DEBUGSTRING(Decision); IntExpr* __mul__(Constraint* other) { return $self->solver()->MakeProd($self->Var(), other->Var()); } - IntExpr* __mul__(int64 v) { + IntExpr* __mul__(int64_t v) { return $self->solver()->MakeProd($self->Var(), v); } - IntExpr* __rmul__(int64 v) { + IntExpr* __rmul__(int64_t v) { return $self->solver()->MakeProd($self->Var(), v); } - IntExpr* __floordiv__(int64 v) { + IntExpr* __floordiv__(int64_t v) { return $self->solver()->MakeDiv($self->Var(), v); } @@ -532,22 +530,22 @@ PY_STRINGIFY_DEBUGSTRING(Decision); return $self->solver()->MakeSquare($self->Var()); } - Constraint* __eq__(int64 v) { + Constraint* __eq__(int64_t v) { return $self->solver()->MakeEquality($self->Var(), v); } - Constraint* __ne__(int64 v) { + Constraint* __ne__(int64_t v) { return $self->solver()->MakeNonEquality($self->Var(), v); } - Constraint* __ge__(int64 v) { + Constraint* __ge__(int64_t v) { return $self->solver()->MakeGreaterOrEqual($self->Var(), v); } - Constraint* __gt__(int64 v) { + Constraint* __gt__(int64_t v) { return $self->solver()->MakeGreater($self->Var(), v); } - Constraint* __le__(int64 v) { + Constraint* __le__(int64_t v) { return $self->solver()->MakeLessOrEqual($self->Var(), v); } - Constraint* __lt__(int64 v) { + Constraint* __lt__(int64_t v) { return $self->solver()->MakeLess($self->Var(), v); } Constraint* __eq__(IntExpr* other) { @@ -589,7 +587,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); Constraint* MapTo(const std::vector& vars) { return $self->solver()->MakeMapDomain($self->Var(), vars); } - IntExpr* IndexOf(const std::vector& vars) { + IntExpr* IndexOf(const std::vector& vars) { return $self->solver()->MakeElement(vars, $self->Var()); } IntExpr* IndexOf(const std::vector& vars) { @@ -599,7 +597,7 @@ PY_STRINGIFY_DEBUGSTRING(Decision); // Add easy variable getters to BaseLns ([i] gets the value of variable #i). %extend operations_research::BaseLns { - int64 __getitem__(int index) { + int64_t __getitem__(int index) { return $self->Value(index); } @@ -640,8 +638,8 @@ PY_STRINGIFY_DEBUGSTRING(Decision); } %extend operations_research::IntVarLocalSearchFilter { - int64 IndexFromVar(IntVar* const var) const { - int64 index = -1; + int64_t IndexFromVar(IntVar* const var) const { + int64_t index = -1; $self->FindIndex(var, &index); return index; } @@ -676,24 +674,24 @@ PY_STRINGIFY_DEBUGSTRING(Decision); %enddef namespace operations_research { -PROTECT_FROM_FAILURE(IntExpr::SetValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMin(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetMax(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntExpr::SetRange(int64 l, int64 u), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64 v), arg1->solver()); -PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), +PROTECT_FROM_FAILURE(IntExpr::SetValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMin(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMax(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetRange(int64_t l, int64_t u), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64_t v), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64_t mi, int64_t ma), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64 m), arg1->solver()); -PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64 mi, int64 ma), +PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64_t m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64_t mi, int64_t ma), arg1->solver()); PROTECT_FROM_FAILURE(IntervalVar::SetPerformed(bool val), arg1->solver()); PROTECT_FROM_FAILURE(Solver::AddConstraint(Constraint* const c), arg1); @@ -1865,20 +1863,20 @@ PY_PROTO_TYPEMAP(ortools.constraint_solver.search_limit_pb2, // Define templates instantiation after wrapping. namespace operations_research { -%rename (RevInteger) Rev; -%rename (RevInteger) Rev::Rev; -%unignore Rev::Value; -%unignore Rev::SetValue; -%template(RevInteger) Rev; +%rename (RevInteger) Rev; +%rename (RevInteger) Rev::Rev; +%unignore Rev::Value; +%unignore Rev::SetValue; +%template(RevInteger) Rev; -%rename (NumericalRevInteger) NumericalRev; -%rename (NumericalRevInteger) NumericalRev::NumericalRev; -%unignore NumericalRev::Add; -%unignore NumericalRev::Decr; -%unignore NumericalRev::Incr; -%unignore NumericalRev::SetValue; -%unignore NumericalRev::Value; -%template(NumericalRevInteger) NumericalRev; +%rename (NumericalRevInteger) NumericalRev; +%rename (NumericalRevInteger) NumericalRev::NumericalRev; +%unignore NumericalRev::Add; +%unignore NumericalRev::Decr; +%unignore NumericalRev::Incr; +%unignore NumericalRev::SetValue; +%unignore NumericalRev::Value; +%template(NumericalRevInteger) NumericalRev; %rename (RevBool) Rev; %rename (RevBool) Rev::Rev; diff --git a/ortools/constraint_solver/python/constraint_solver_helpers.i b/ortools/constraint_solver/python/constraint_solver_helpers.i index ef08878981..20633cb267 100644 --- a/ortools/constraint_solver/python/constraint_solver_helpers.i +++ b/ortools/constraint_solver/python/constraint_solver_helpers.i @@ -25,7 +25,7 @@ // solver and the routing library. %{ template<> -PyObject* PyObjFrom(const int64& c) { return PyLong_FromLongLong(c); } +PyObject* PyObjFrom(const int64_t& c) { return PyLong_FromLongLong(c); } %} // Conversion of IntExpr* and IntVar* are a bit special because of the two diff --git a/ortools/constraint_solver/resource.cc b/ortools/constraint_solver/resource.cc index 0b61b8175f..4dc278d77e 100644 --- a/ortools/constraint_solver/resource.cc +++ b/ortools/constraint_solver/resource.cc @@ -21,6 +21,8 @@ // on a set of interval variables. #include +#include +#include #include #include #include @@ -105,12 +107,12 @@ struct DisjunctiveTask { // intervals contain any integer t cannot exceed c. // It is indexed, that is it is aware of its position in a reference array. struct CumulativeTask { - CumulativeTask(IntervalVar* const interval_, int64 demand_) + CumulativeTask(IntervalVar* const interval_, int64_t demand_) : interval(interval_), demand(demand_), index(-1) {} - int64 EnergyMin() const { return interval->DurationMin() * demand; } + int64_t EnergyMin() const { return interval->DurationMin() * demand; } - int64 DemandMin() const { return demand; } + int64_t DemandMin() const { return demand; } void WhenAnything(Demon* const demon) { interval->WhenAnything(demon); } @@ -120,7 +122,7 @@ struct CumulativeTask { } IntervalVar* interval; - int64 demand; + int64_t demand; int index; }; @@ -134,9 +136,9 @@ struct VariableCumulativeTask { VariableCumulativeTask(IntervalVar* const interval_, IntVar* demand_) : interval(interval_), demand(demand_), index(-1) {} - int64 EnergyMin() const { return interval->DurationMin() * demand->Min(); } + int64_t EnergyMin() const { return interval->DurationMin() * demand->Min(); } - int64 DemandMin() const { return demand->Min(); } + int64_t DemandMin() const { return demand->Min(); } void WhenAnything(Demon* const demon) { interval->WhenAnything(demon); @@ -161,7 +163,8 @@ struct VariableCumulativeTask { // Node of a Theta-tree struct ThetaNode { // Identity element - ThetaNode() : total_processing(0), total_ect(kint64min) {} + ThetaNode() + : total_processing(0), total_ect(std::numeric_limits::min()) {} // Single interval element explicit ThetaNode(const IntervalVar* const interval) @@ -184,7 +187,8 @@ struct ThetaNode { } bool IsIdentity() const { - return total_processing == 0LL && total_ect == kint64min; + return total_processing == 0LL && + total_ect == std::numeric_limits::min(); } std::string DebugString() const { @@ -192,8 +196,8 @@ struct ThetaNode { ", e = ", total_ect < 0LL ? -1LL : total_ect, " }"); } - int64 total_processing; - int64 total_ect; + int64_t total_processing; + int64_t total_ect; }; // A theta-tree is a container for a set of intervals supporting the following @@ -207,7 +211,7 @@ class ThetaTree : public MonoidOperationTree { public: explicit ThetaTree(int size) : MonoidOperationTree(size) {} - int64 Ect() const { return result().total_ect; } + int64_t Ect() const { return result().total_ect; } void Insert(const DisjunctiveTask* const task) { Set(task->index, ThetaNode(task->interval)); @@ -233,14 +237,14 @@ struct LambdaThetaNode { // Identity constructor LambdaThetaNode() : energy(0LL), - energetic_end_min(kint64min), + energetic_end_min(std::numeric_limits::min()), energy_opt(0LL), argmax_energy_opt(kNone), - energetic_end_min_opt(kint64min), + energetic_end_min_opt(std::numeric_limits::min()), argmax_energetic_end_min_opt(kNone) {} // Constructor for a single cumulative task in the Theta set - LambdaThetaNode(int64 capacity, const CumulativeTask& task) + LambdaThetaNode(int64_t capacity, const CumulativeTask& task) : energy(task.EnergyMin()), energetic_end_min(CapAdd(capacity * task.interval->StartMin(), energy)), energy_opt(energy), @@ -249,9 +253,9 @@ struct LambdaThetaNode { argmax_energetic_end_min_opt(kNone) {} // Constructor for a single cumulative task in the Lambda set - LambdaThetaNode(int64 capacity, const CumulativeTask& task, int index) + LambdaThetaNode(int64_t capacity, const CumulativeTask& task, int index) : energy(0LL), - energetic_end_min(kint64min), + energetic_end_min(std::numeric_limits::min()), energy_opt(task.EnergyMin()), argmax_energy_opt(index), energetic_end_min_opt(capacity * task.interval->StartMin() + @@ -261,7 +265,7 @@ struct LambdaThetaNode { } // Constructor for a single cumulative task in the Theta set - LambdaThetaNode(int64 capacity, const VariableCumulativeTask& task) + LambdaThetaNode(int64_t capacity, const VariableCumulativeTask& task) : energy(task.EnergyMin()), energetic_end_min(CapAdd(capacity * task.interval->StartMin(), energy)), energy_opt(energy), @@ -270,9 +274,10 @@ struct LambdaThetaNode { argmax_energetic_end_min_opt(kNone) {} // Constructor for a single cumulative task in the Lambda set - LambdaThetaNode(int64 capacity, const VariableCumulativeTask& task, int index) + LambdaThetaNode(int64_t capacity, const VariableCumulativeTask& task, + int index) : energy(0LL), - energetic_end_min(kint64min), + energetic_end_min(std::numeric_limits::min()), energy_opt(task.EnergyMin()), argmax_energy_opt(index), energetic_end_min_opt(capacity * task.interval->StartMin() + @@ -294,7 +299,7 @@ struct LambdaThetaNode { // 'index' is the index of the given interval in the est vector LambdaThetaNode(const IntervalVar* const interval, int index) : energy(0LL), - energetic_end_min(kint64min), + energetic_end_min(std::numeric_limits::min()), energy_opt(interval->DurationMin()), argmax_energy_opt(index), energetic_end_min_opt(interval->EndMin()), @@ -313,8 +318,8 @@ struct LambdaThetaNode { energy = CapAdd(left.energy, right.energy); energetic_end_min = std::max(right.energetic_end_min, CapAdd(left.energetic_end_min, right.energy)); - const int64 energy_left_opt = CapAdd(left.energy_opt, right.energy); - const int64 energy_right_opt = CapAdd(left.energy, right.energy_opt); + const int64_t energy_left_opt = CapAdd(left.energy_opt, right.energy); + const int64_t energy_right_opt = CapAdd(left.energy, right.energy_opt); if (energy_left_opt > energy_right_opt) { energy_opt = energy_left_opt; argmax_energy_opt = left.argmax_energy_opt; @@ -322,9 +327,9 @@ struct LambdaThetaNode { energy_opt = energy_right_opt; argmax_energy_opt = right.argmax_energy_opt; } - const int64 ect1 = right.energetic_end_min_opt; - const int64 ect2 = CapAdd(left.energetic_end_min, right.energy_opt); - const int64 ect3 = CapAdd(left.energetic_end_min_opt, right.energy); + const int64_t ect1 = right.energetic_end_min_opt; + const int64_t ect2 = CapAdd(left.energetic_end_min, right.energy_opt); + const int64_t ect3 = CapAdd(left.energetic_end_min_opt, right.energy); if (ect1 >= ect2 && ect1 >= ect3) { // ect1 max energetic_end_min_opt = ect1; argmax_energetic_end_min_opt = right.argmax_energetic_end_min_opt; @@ -346,13 +351,13 @@ struct LambdaThetaNode { // Amount of resource consumed by the Theta set, in units of demand X time. // This is energy(Theta). - int64 energy; + int64_t energy; // Max_{subset S of Theta} (capacity * start_min(S) + energy(S)) - int64 energetic_end_min; + int64_t energetic_end_min; // Max_{i in Lambda} (energy(Theta union {i})) - int64 energy_opt; + int64_t energy_opt; // The argmax in energy_opt_. It is the index of the chosen task in the Lambda // set, if any, or kNone if none. @@ -360,7 +365,7 @@ struct LambdaThetaNode { // Max_{subset S of Theta, i in Lambda} // (capacity * start_min(S union {i}) + energy(S union {i})) - int64 energetic_end_min_opt; + int64_t energetic_end_min_opt; // The argmax in energetic_end_min_opt_. It is the index of the chosen task in // the Lambda set, if any, or kNone if none. @@ -384,19 +389,19 @@ class DisjunctiveLambdaThetaTree : public MonoidOperationTree { Set(index, LambdaThetaNode(task.interval, index)); } - int64 Ect() const { return result().energetic_end_min; } - int64 EctOpt() const { return result().energetic_end_min_opt; } + int64_t Ect() const { return result().energetic_end_min; } + int64_t EctOpt() const { return result().energetic_end_min_opt; } int ResponsibleOpt() const { return result().argmax_energetic_end_min_opt; } }; // A cumulative lambda-theta tree class CumulativeLambdaThetaTree : public MonoidOperationTree { public: - CumulativeLambdaThetaTree(int size, int64 capacity_max) + CumulativeLambdaThetaTree(int size, int64_t capacity_max) : MonoidOperationTree(size), capacity_max_(capacity_max) {} - void Init(int64 capacity_max) { + void Init(int64_t capacity_max) { Clear(); capacity_max_ = capacity_max; } @@ -419,12 +424,14 @@ class CumulativeLambdaThetaTree : public MonoidOperationTree { Set(index, LambdaThetaNode(capacity_max_, task, index)); } - int64 energetic_end_min() const { return result().energetic_end_min; } - int64 energetic_end_min_opt() const { return result().energetic_end_min_opt; } - int64 Ect() const { + int64_t energetic_end_min() const { return result().energetic_end_min; } + int64_t energetic_end_min_opt() const { + return result().energetic_end_min_opt; + } + int64_t Ect() const { return MathUtil::CeilOfRatio(energetic_end_min(), capacity_max_); } - int64 EctOpt() const { + int64_t EctOpt() const { return MathUtil::CeilOfRatio(result().energetic_end_min_opt, capacity_max_); } int argmax_energetic_end_min_opt() const { @@ -432,7 +439,7 @@ class CumulativeLambdaThetaTree : public MonoidOperationTree { } private: - int64 capacity_max_; + int64_t capacity_max_; }; // -------------- Not Last ----------------------------------------- @@ -453,7 +460,7 @@ class NotLast { std::vector by_start_min_; std::vector by_end_max_; std::vector by_start_max_; - std::vector new_lct_; + std::vector new_lct_; const bool strict_; }; @@ -500,7 +507,7 @@ bool NotLast::Propagate() { while (j < by_start_max_.size() && twi->interval->EndMax() > by_start_max_[j]->interval->StartMax()) { if (j > 0 && theta_tree_.Ect() > by_start_max_[j]->interval->StartMax()) { - const int64 new_end_max = by_start_max_[j - 1]->interval->StartMax(); + const int64_t new_end_max = by_start_max_[j - 1]->interval->StartMax(); new_lct_[by_start_max_[j]->index] = new_end_max; } theta_tree_.Insert(by_start_max_[j]); @@ -510,12 +517,12 @@ bool NotLast::Propagate() { if (inserted) { theta_tree_.Remove(twi); } - const int64 ect_theta_less_i = theta_tree_.Ect(); + const int64_t ect_theta_less_i = theta_tree_.Ect(); if (inserted) { theta_tree_.Insert(twi); } if (ect_theta_less_i > twi->interval->EndMax() && j > 0) { - const int64 new_end_max = by_start_max_[j - 1]->interval->EndMax(); + const int64_t new_end_max = by_start_max_[j - 1]->interval->EndMax(); if (new_end_max > new_lct_[twi->index]) { new_lct_[twi->index] = new_end_max; } @@ -547,7 +554,7 @@ class EdgeFinderAndDetectablePrecedences { ~EdgeFinderAndDetectablePrecedences() { gtl::STLDeleteElements(&by_start_min_); } - int64 size() const { return by_start_min_.size(); } + int64_t size() const { return by_start_min_.size(); } IntervalVar* interval(int index) { return by_start_min_[index]->interval; } void UpdateEst(); void OverloadChecking(); @@ -572,9 +579,9 @@ class EdgeFinderAndDetectablePrecedences { std::vector by_end_max_; std::vector by_start_max_; // new_est_[i] is the new start min for interval est_[i]->interval. - std::vector new_est_; + std::vector new_est_; // new_lct_[i] is the new end max for interval est_[i]->interval. - std::vector new_lct_; + std::vector new_lct_; DisjunctiveLambdaThetaTree lt_tree_; const bool strict_; }; @@ -596,7 +603,7 @@ EdgeFinderAndDetectablePrecedences::EdgeFinderAndDetectablePrecedences( by_start_min_.push_back(task); by_end_max_.push_back(task); by_start_max_.push_back(task); - new_est_.push_back(kint64min); + new_est_.push_back(std::numeric_limits::min()); } } @@ -626,7 +633,7 @@ void EdgeFinderAndDetectablePrecedences::OverloadChecking() { bool EdgeFinderAndDetectablePrecedences::DetectablePrecedences() { // Initialization. UpdateEst(); - new_est_.assign(size(), kint64min); + new_est_.assign(size(), std::numeric_limits::min()); // Propagate in one direction std::sort(by_end_min_.begin(), by_end_min_.end(), @@ -645,19 +652,19 @@ bool EdgeFinderAndDetectablePrecedences::DetectablePrecedences() { task_j = by_start_max_[j]; } } - const int64 esti = task_i->interval->StartMin(); + const int64_t esti = task_i->interval->StartMin(); bool inserted = theta_tree_.IsInserted(task_i); if (inserted) { theta_tree_.Remove(task_i); } - const int64 oesti = theta_tree_.Ect(); + const int64_t oesti = theta_tree_.Ect(); if (inserted) { theta_tree_.Insert(task_i); } if (oesti > esti) { new_est_[task_i->index] = oesti; } else { - new_est_[task_i->index] = kint64min; + new_est_[task_i->index] = std::numeric_limits::min(); } } @@ -665,7 +672,8 @@ bool EdgeFinderAndDetectablePrecedences::DetectablePrecedences() { bool modified = false; for (int i = 0; i < size(); ++i) { IntervalVar* const var = by_start_min_[i]->interval; - if (new_est_[i] != kint64min && (strict_ || var->DurationMin() > 0)) { + if (new_est_[i] != std::numeric_limits::min() && + (strict_ || var->DurationMin() > 0)) { modified = true; by_start_min_[i]->interval->SetStartMin(new_est_[i]); } @@ -801,7 +809,7 @@ class RankedPropagator : public Constraint { IntervalVar* const interval = RankedInterval(i); IntervalVar* const next_interval = RankedInterval(i + 1); IntVar* const slack = RankedSlack(i); - const int64 transition_time = RankedTransitionTime(i, i + 1); + const int64_t transition_time = RankedTransitionTime(i, i + 1); next_interval->SetStartRange( CapAdd(interval->StartMin(), CapAdd(slack->Min(), transition_time)), CapAdd(interval->StartMax(), CapAdd(slack->Max(), transition_time))); @@ -811,7 +819,7 @@ class RankedPropagator : public Constraint { IntervalVar* const interval = RankedInterval(i - 1); IntervalVar* const next_interval = RankedInterval(i); IntVar* const slack = RankedSlack(i - 1); - const int64 transition_time = RankedTransitionTime(i - 1, i); + const int64_t transition_time = RankedTransitionTime(i - 1, i); interval->SetStartRange(CapSub(next_interval->StartMin(), CapAdd(slack->Max(), transition_time)), CapSub(next_interval->StartMax(), @@ -838,7 +846,7 @@ class RankedPropagator : public Constraint { if (interval->MayBePerformed()) { const bool performed = interval->MustBePerformed(); if (first_interval != nullptr) { - const int64 transition_time = + const int64_t transition_time = RankedTransitionTime(first_sentinel - 1, i); interval->SetStartRange( CapAdd(first_interval->StartMin(), @@ -854,7 +862,7 @@ class RankedPropagator : public Constraint { } } if (last_interval != nullptr) { - const int64 transition_time = + const int64_t transition_time = RankedTransitionTime(i, last_sentinel + 1); interval->SetStartRange( CapSub(last_interval->StartMin(), @@ -877,7 +885,7 @@ class RankedPropagator : public Constraint { IntervalVar* const interval = RankedInterval(i); IntervalVar* const next_interval = RankedInterval(i + 1); IntVar* const slack = RankedSlack(i); - const int64 transition_time = RankedTransitionTime(i, i + 1); + const int64_t transition_time = RankedTransitionTime(i, i + 1); interval->SetStartRange(CapSub(next_interval->StartMin(), CapAdd(slack->Max(), transition_time)), CapSub(next_interval->StartMax(), @@ -888,7 +896,7 @@ class RankedPropagator : public Constraint { IntervalVar* const interval = RankedInterval(i); IntervalVar* const next_interval = RankedInterval(i + 1); IntVar* const slack = RankedSlack(i); - const int64 transition_time = RankedTransitionTime(i, i + 1); + const int64_t transition_time = RankedTransitionTime(i, i + 1); next_interval->SetStartRange( CapAdd(interval->StartMin(), CapAdd(slack->Min(), transition_time)), CapAdd(interval->StartMax(), CapAdd(slack->Max(), transition_time))); @@ -906,7 +914,7 @@ class RankedPropagator : public Constraint { return slacks_[index]; } - int64 RankedTransitionTime(int before, int after) const { + int64_t RankedTransitionTime(int before, int after) const { const int before_index = partial_sequence_[before]; const int after_index = partial_sequence_[after]; @@ -956,7 +964,7 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { Demon* const d = MakeDelayedConstraintDemon0( solver(), this, &FullDisjunctiveConstraint::InitialPropagate, "InitialPropagate"); - for (int32 i = 0; i < straight_.size(); ++i) { + for (int32_t i = 0; i < straight_.size(); ++i) { straight_.interval(i)->WhenAnything(d); } } @@ -1030,7 +1038,7 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { const int num_performed = performed_.size(); std::sort(optional_.begin(), optional_.end(), IntervalStartMinLessThan); for (IntervalVar* const candidate : optional_) { - const int64 start = candidate->StartMin(); + const int64_t start = candidate->StartMin(); while (index < num_performed && start >= performed_[index]->EndMax()) { index++; } @@ -1082,7 +1090,7 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { } private: - int64 Distance(int64 activity_plus_one, int64 next_activity_plus_one) { + int64_t Distance(int64_t activity_plus_one, int64_t next_activity_plus_one) { return (activity_plus_one == 0 || next_activity_plus_one > intervals_.size()) ? 0 @@ -1098,7 +1106,7 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { const std::string& ct_name = name(); const int num_intervals = intervals_.size(); const int num_nodes = intervals_.size() + 1; - int64 horizon = 0; + int64_t horizon = 0; for (int i = 0; i < intervals_.size(); ++i) { if (intervals_[i]->MayBePerformed()) { horizon = std::max(horizon, intervals_[i]->EndMax()); @@ -1131,10 +1139,10 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { // TODO(user): check this. time_cumuls_[0] = s->MakeIntConst(0); - for (int64 i = 0; i < num_intervals; ++i) { + for (int64_t i = 0; i < num_intervals; ++i) { IntervalVar* const var = intervals_[i]; if (var->MayBePerformed()) { - const int64 duration_min = var->DurationMin(); + const int64_t duration_min = var->DurationMin(); time_slacks_[i + 1] = s->MakeIntVar( duration_min, horizon, absl::StrFormat("time_slacks(%d)", i + 1)); // TODO(user): Check SafeStartExpr(); @@ -1153,7 +1161,7 @@ class FullDisjunctiveConstraint : public DisjunctiveConstraint { time_cumuls_[num_nodes] = s->MakeIntVar(0, 2 * horizon, ct_name + "_ect"); s->AddConstraint( s->MakePathCumul(nexts_, actives_, time_cumuls_, time_slacks_, - [this](int64 x, int64 y) { return Distance(x, y); })); + [this](int64_t x, int64_t y) { return Distance(x, y); })); std::vector short_slacks(time_slacks_.begin() + 1, time_slacks_.end()); @@ -1189,11 +1197,11 @@ struct DualCapacityThetaNode { // Identity constructor DualCapacityThetaNode() : energy(0LL), - energetic_end_min(kint64min), - residual_energetic_end_min(kint64min) {} + energetic_end_min(std::numeric_limits::min()), + residual_energetic_end_min(std::numeric_limits::min()) {} // Constructor for a single cumulative task in the Theta set. - DualCapacityThetaNode(int64 capacity, int64 residual_capacity, + DualCapacityThetaNode(int64_t capacity, int64_t residual_capacity, const CumulativeTask& task) : energy(task.EnergyMin()), energetic_end_min(CapAdd(capacity * task.interval->StartMin(), energy)), @@ -1201,7 +1209,7 @@ struct DualCapacityThetaNode { CapAdd(residual_capacity * task.interval->StartMin(), energy)) {} // Constructor for a single variable cumulative task in the Theta set. - DualCapacityThetaNode(int64 capacity, int64 residual_capacity, + DualCapacityThetaNode(int64_t capacity, int64_t residual_capacity, const VariableCumulativeTask& task) : energy(task.EnergyMin()), energetic_end_min(CapAdd(capacity * task.interval->StartMin(), energy)), @@ -1226,13 +1234,13 @@ struct DualCapacityThetaNode { // Amount of resource consumed by the Theta set, in units of demand X time. // This is energy(Theta). - int64 energy; + int64_t energy; // Max_{subset S of Theta} (capacity * start_min(S) + energy(S)) - int64 energetic_end_min; + int64_t energetic_end_min; // Max_{subset S of Theta} (residual_capacity * start_min(S) + energy(S)) - int64 residual_energetic_end_min; + int64_t residual_energetic_end_min; }; const int DualCapacityThetaNode::kNone = -1; @@ -1241,7 +1249,7 @@ const int DualCapacityThetaNode::kNone = -1; class DualCapacityThetaTree : public MonoidOperationTree { public: - static const int64 kNotInitialized; + static const int64_t kNotInitialized; explicit DualCapacityThetaTree(int size) : MonoidOperationTree(size), @@ -1250,7 +1258,7 @@ class DualCapacityThetaTree virtual ~DualCapacityThetaTree() {} - void Init(int64 capacity_max, int64 residual_capacity) { + void Init(int64_t capacity_max, int64_t residual_capacity) { DCHECK_LE(0, residual_capacity); DCHECK_LE(residual_capacity, capacity_max); Clear(); @@ -1269,12 +1277,12 @@ class DualCapacityThetaTree } private: - int64 capacity_max_; - int64 residual_capacity_; + int64_t capacity_max_; + int64_t residual_capacity_; DISALLOW_COPY_AND_ASSIGN(DualCapacityThetaTree); }; -const int64 DualCapacityThetaTree::kNotInitialized = -1LL; +const int64_t DualCapacityThetaTree::kNotInitialized = -1LL; // An object that can dive down a branch of a DualCapacityThetaTree to compute // Env(j, c) in Petr Vilim's notations. @@ -1288,7 +1296,7 @@ const int64 DualCapacityThetaTree::kNotInitialized = -1LL; // conference proceedings, which has a few errors. class EnvJCComputeDiver { public: - static const int64 kNotAvailable; + static const int64_t kNotAvailable; explicit EnvJCComputeDiver(int energy_threshold) : energy_threshold_(energy_threshold), energy_alpha_(kNotAvailable), @@ -1328,9 +1336,9 @@ class EnvJCComputeDiver { CapAdd(left_child.energetic_end_min, energy_alpha_)); energy_alpha_ += left_child.energy; } - int64 GetEnvJC(const DualCapacityThetaNode& root) const { - const int64 energy = root.energy; - const int64 energy_beta = CapSub(energy, energy_alpha_); + int64_t GetEnvJC(const DualCapacityThetaNode& root) const { + const int64_t energy = root.energy; + const int64_t energy_beta = CapSub(energy, energy_alpha_); return CapAdd(energetic_end_min_alpha_, energy_beta); } @@ -1340,21 +1348,21 @@ class EnvJCComputeDiver { // currently considered end max. // // Used when diving down only. - int64 energy_threshold_; + int64_t energy_threshold_; // Energy of the alpha set, that is, the set of tasks whose start min does not // exceed the max start min of a set with excess residual energy. // // Used when swimming up only. - int64 energy_alpha_; + int64_t energy_alpha_; // Energetic end min of the alpha set. // // Used when swimming up only. - int64 energetic_end_min_alpha_; + int64_t energetic_end_min_alpha_; }; -const int64 EnvJCComputeDiver::kNotAvailable = -1LL; +const int64_t EnvJCComputeDiver::kNotAvailable = -1LL; // In all the following, the term 'update' means 'a potential new start min for // a task'. The edge-finding algorithm is in two phase: one compute potential @@ -1368,9 +1376,9 @@ class UpdatesForADemand { explicit UpdatesForADemand(int size) : updates_(size, 0), up_to_date_(false) {} - const int64 Update(int index) { return updates_[index]; } + const int64_t Update(int index) { return updates_[index]; } void Reset() { up_to_date_ = false; } - void SetUpdate(int index, int64 update) { + void SetUpdate(int index, int64_t update) { DCHECK(!up_to_date_); DCHECK_LT(index, updates_.size()); updates_[index] = update; @@ -1379,7 +1387,7 @@ class UpdatesForADemand { void set_up_to_date() { up_to_date_ = true; } private: - std::vector updates_; + std::vector updates_; bool up_to_date_; DISALLOW_COPY_AND_ASSIGN(UpdatesForADemand); }; @@ -1434,7 +1442,7 @@ class EdgeFinder : public Constraint { std::string DebugString() const override { return "EdgeFinder"; } private: - UpdatesForADemand* GetOrMakeUpdate(int64 demand_min) { + UpdatesForADemand* GetOrMakeUpdate(int64_t demand_min) { UpdatesForADemand* update = gtl::FindPtrOrNull(update_map_, demand_min); if (update == nullptr) { update = new UpdatesForADemand(tasks_.size()); @@ -1491,31 +1499,31 @@ class EdgeFinder : public Constraint { // Runs in O(n log n). // This corresponds to lines 2--13 in algorithm 1.3 in Petr Vilim's paper. void ComputeConditionalStartMins(UpdatesForADemand* updates, - int64 demand_min) { + int64_t demand_min) { DCHECK_GT(demand_min, 0); DCHECK(updates != nullptr); - const int64 capacity_max = capacity_->Max(); - const int64 residual_capacity = CapSub(capacity_max, demand_min); + const int64_t capacity_max = capacity_->Max(); + const int64_t residual_capacity = CapSub(capacity_max, demand_min); dual_capacity_tree_.Init(capacity_max, residual_capacity); // It's important to initialize the update at IntervalVar::kMinValidValue // rather than at kInt64min, because its opposite may be used if it's a // mirror variable, and // -kInt64min = -(-kInt64max - 1) = kInt64max + 1 = -kInt64min - int64 update = IntervalVar::kMinValidValue; + int64_t update = IntervalVar::kMinValidValue; for (int i = 0; i < by_end_max_.size(); ++i) { Task* const task = by_end_max_[i]; if (task->EnergyMin() == 0) continue; - const int64 current_end_max = task->interval->EndMax(); + const int64_t current_end_max = task->interval->EndMax(); dual_capacity_tree_.Insert(task); - const int64 energy_threshold = residual_capacity * current_end_max; + const int64_t energy_threshold = residual_capacity * current_end_max; const DualCapacityThetaNode& root = dual_capacity_tree_.result(); - const int64 res_energetic_end_min = root.residual_energetic_end_min; + const int64_t res_energetic_end_min = root.residual_energetic_end_min; if (res_energetic_end_min > energy_threshold) { EnvJCComputeDiver diver(energy_threshold); dual_capacity_tree_.DiveInTree(&diver); - const int64 enjv = diver.GetEnvJC(dual_capacity_tree_.result()); - const int64 numerator = CapSub(enjv, energy_threshold); - const int64 diff = MathUtil::CeilOfRatio(numerator, demand_min); + const int64_t enjv = diver.GetEnvJC(dual_capacity_tree_.result()); + const int64_t numerator = CapSub(enjv, energy_threshold); + const int64_t diff = MathUtil::CeilOfRatio(numerator, demand_min); update = std::max(update, diff); } updates->SetUpdate(i, update); @@ -1525,11 +1533,11 @@ class EdgeFinder : public Constraint { // Returns the new start min that can be inferred for task_to_push if it is // proved that it cannot end before by_end_max[end_max_index] does. - int64 ConditionalStartMin(const Task& task_to_push, int end_max_index) { + int64_t ConditionalStartMin(const Task& task_to_push, int end_max_index) { if (task_to_push.EnergyMin() == 0) { return task_to_push.interval->StartMin(); } - const int64 demand_min = task_to_push.DemandMin(); + const int64_t demand_min = task_to_push.DemandMin(); UpdatesForADemand* const updates = GetOrMakeUpdate(demand_min); if (!updates->up_to_date()) { ComputeConditionalStartMins(updates, demand_min); @@ -1545,9 +1553,9 @@ class EdgeFinder : public Constraint { // See paragraph 6.2 in http://vilim.eu/petr/cp2009.pdf. void PropagateBasedOnEndMinGreaterThanEndMax() { int end_max_index = 0; - int64 max_start_min = kint64min; + int64_t max_start_min = std::numeric_limits::min(); for (Task* const task : by_end_min_) { - const int64 end_min = task->interval->EndMin(); + const int64_t end_min = task->interval->EndMin(); while (end_max_index < by_start_min_.size() && by_end_max_[end_max_index]->interval->EndMax() <= end_min) { max_start_min = std::max( @@ -1569,7 +1577,7 @@ class EdgeFinder : public Constraint { // that must end before end_min, which may cause the result of // ConditionalStartMin(task, end_max_index - 1) not to be a valid // update. - const int64 update = ConditionalStartMin(*task, end_max_index - 1); + const int64_t update = ConditionalStartMin(*task, end_max_index - 1); start_min_update_.push_back(std::make_pair(task->interval, update)); } } @@ -1580,7 +1588,7 @@ class EdgeFinder : public Constraint { for (Task* const task : by_end_max_) { lt_tree_.Insert(*task); // Maximum energetic end min without overload. - const int64 max_feasible = + const int64_t max_feasible = CapProd(capacity_->Max(), task->interval->EndMax()); if (lt_tree_.energetic_end_min() > max_feasible) { solver()->Fail(); @@ -1595,7 +1603,7 @@ class EdgeFinder : public Constraint { lt_tree_.Grey(*by_end_max_[j + 1]); Task* const twj = by_end_max_[j]; // We should have checked for overload earlier. - const int64 max_feasible = + const int64_t max_feasible = CapProd(capacity_->Max(), twj->interval->EndMax()); DCHECK_LE(lt_tree_.energetic_end_min(), max_feasible); while (lt_tree_.energetic_end_min_opt() > max_feasible) { @@ -1611,13 +1619,13 @@ class EdgeFinder : public Constraint { // the given new end min. void PropagateTaskCannotEndBefore(int index, int end_max_index) { Task* const task_to_push = by_start_min_[index]; - const int64 update = ConditionalStartMin(*task_to_push, end_max_index); + const int64_t update = ConditionalStartMin(*task_to_push, end_max_index); start_min_update_.push_back(std::make_pair(task_to_push->interval, update)); } // Applies the previously computed updates. void ApplyNewBounds() { - for (const std::pair& update : start_min_update_) { + for (const std::pair& update : start_min_update_) { update.first->SetStartMin(update.second); } } @@ -1644,12 +1652,12 @@ class EdgeFinder : public Constraint { DualCapacityThetaTree dual_capacity_tree_; // Stack of updates to the new start min to do. - std::vector> start_min_update_; + std::vector> start_min_update_; // update_map_[d][i] is an integer such that if a task // whose demand is d cannot end before by_end_max_[i], then it cannot start // before update_map_[d][i]. - absl::flat_hash_map update_map_; + absl::flat_hash_map update_map_; // Has one task a demand min == 0 Rev has_zero_demand_tasks_; @@ -1679,9 +1687,9 @@ class EdgeFinder : public Constraint { // This is because intervals for tasks are always closed on the start side // and open on the end side. struct ProfileDelta { - ProfileDelta(int64 _time, int64 _delta) : time(_time), delta(_delta) {} - int64 time; - int64 delta; + ProfileDelta(int64_t _time, int64_t _delta) : time(_time), delta(_delta) {} + int64_t time; + int64_t delta; }; bool TimeLessThan(const ProfileDelta& delta1, const ProfileDelta& delta2) { @@ -1745,10 +1753,10 @@ class CumulativeTimeTable : public Constraint { profile_non_unique_time_.clear(); for (const Task* const task : by_start_min_) { const IntervalVar* const interval = task->interval; - const int64 start_max = interval->StartMax(); - const int64 end_min = interval->EndMin(); + const int64_t start_max = interval->StartMax(); + const int64_t end_min = interval->EndMin(); if (interval->MustBePerformed() && start_max < end_min) { - const int64 demand_min = task->DemandMin(); + const int64_t demand_min = task->DemandMin(); if (demand_min > 0) { profile_non_unique_time_.emplace_back(start_max, +demand_min); profile_non_unique_time_.emplace_back(end_min, -demand_min); @@ -1760,8 +1768,8 @@ class CumulativeTimeTable : public Constraint { TimeLessThan); // Build profile with unique times profile_unique_time_.clear(); - profile_unique_time_.emplace_back(kint64min, 0); - int64 usage = 0; + profile_unique_time_.emplace_back(std::numeric_limits::min(), 0); + int64_t usage = 0; for (const ProfileDelta& step : profile_non_unique_time_) { if (step.time == profile_unique_time_.back().time) { profile_unique_time_.back().delta += step.delta; @@ -1774,7 +1782,7 @@ class CumulativeTimeTable : public Constraint { // Check final usage to be 0. DCHECK_EQ(0, usage); // Scan to find max usage. - int64 max_usage = 0; + int64_t max_usage = 0; for (const ProfileDelta& step : profile_unique_time_) { usage += step.delta; if (usage > max_usage) { @@ -1784,14 +1792,14 @@ class CumulativeTimeTable : public Constraint { DCHECK_EQ(0, usage); capacity_->SetMin(max_usage); // Add a sentinel. - profile_unique_time_.emplace_back(kint64max, 0); + profile_unique_time_.emplace_back(std::numeric_limits::max(), 0); } // Update the start min for all tasks. Runs in O(n^2) and Omega(n). void PushTasks() { std::sort(by_start_min_.begin(), by_start_min_.end(), StartMinLessThan); - int64 usage = 0; + int64_t usage = 0; int profile_index = 0; for (const Task* const task : by_start_min_) { const IntervalVar* const interval = task->interval; @@ -1812,18 +1820,18 @@ class CumulativeTimeTable : public Constraint { // that the profile usage for all tasks, excluding the current one, does not // exceed capacity_ - task->demand on the interval // [new_start_min, new_start_min + task->interval->DurationMin() ). - void PushTask(const Task* const task, int profile_index, int64 usage) { + void PushTask(const Task* const task, int profile_index, int64_t usage) { // Init const IntervalVar* const interval = task->interval; - const int64 demand_min = task->DemandMin(); + const int64_t demand_min = task->DemandMin(); if (demand_min == 0) { // Demand can be null, nothing to propagate. return; } - const int64 residual_capacity = CapSub(capacity_->Max(), demand_min); - const int64 duration = task->interval->DurationMin(); + const int64_t residual_capacity = CapSub(capacity_->Max(), demand_min); + const int64_t duration = task->interval->DurationMin(); const ProfileDelta& first_prof_delta = profile_unique_time_[profile_index]; - int64 new_start_min = interval->StartMin(); + int64_t new_start_min = interval->StartMin(); DCHECK_GE(first_prof_delta.time, interval->StartMin()); // The check above is with a '>='. Let's first treat the '>' case @@ -1836,15 +1844,15 @@ class CumulativeTimeTable : public Constraint { (interval->StartMax() >= interval->EndMin())); // The 'usage' given in argument is valid at first_prof_delta.time. To // compute the usage at the start min, we need to remove the last delta. - const int64 usage_at_start_min = CapSub(usage, first_prof_delta.delta); + const int64_t usage_at_start_min = CapSub(usage, first_prof_delta.delta); if (usage_at_start_min > residual_capacity) { new_start_min = profile_unique_time_[profile_index].time; } } // Influence of current task - const int64 start_max = interval->StartMax(); - const int64 end_min = interval->EndMin(); + const int64_t start_max = interval->StartMax(); + const int64_t end_min = interval->EndMin(); ProfileDelta delta_start(start_max, 0); ProfileDelta delta_end(end_min, 0); if (interval->MustBePerformed() && start_max < end_min) { @@ -1903,8 +1911,8 @@ class TimeTableSync : public Constraint { num_tasks_ = tasks_.size(); gap_ = 0; prev_gap_ = 0; - pos_ = kint64min; - next_pos_ = kint64min; + pos_ = std::numeric_limits::min(); + next_pos_ = std::numeric_limits::min(); // Allocate vectors to contain no more than n_tasks. start_min_.reserve(num_tasks_); start_max_.reserve(num_tasks_); @@ -1954,21 +1962,22 @@ class TimeTableSync : public Constraint { // Task state. enum State { NONE, READY, CHECK, CONFLICT }; - inline int64 NextScpTime() { - return !events_scp_.empty() ? events_scp_.top().first : kint64max; + inline int64_t NextScpTime() { + return !events_scp_.empty() ? events_scp_.top().first + : std::numeric_limits::max(); } - inline int64 NextEventTime() { - int64 time = kint64max; + inline int64_t NextEventTime() { + int64_t time = std::numeric_limits::max(); if (!events_pr_.empty()) { time = events_pr_.top().first; } if (!events_scp_.empty()) { - int64 t = events_scp_.top().first; + int64_t t = events_scp_.top().first; time = t < time ? t : time; } if (!events_ecp_.empty()) { - int64 t = events_ecp_.top().first; + int64_t t = events_ecp_.top().first; time = t < time ? t : time; } return time; @@ -1976,12 +1985,12 @@ class TimeTableSync : public Constraint { void ProcessEventsScp() { while (!events_scp_.empty() && events_scp_.top().first == pos_) { - const int64 task_id = events_scp_.top().second; + const int64_t task_id = events_scp_.top().second; events_scp_.pop(); - const int64 old_end_min = end_min_[task_id]; + const int64_t old_end_min = end_min_[task_id]; if (states_[task_id] == State::CONFLICT) { // Update cached values. - const int64 new_end_min = pos_ + durations_[task_id]; + const int64_t new_end_min = pos_ + durations_[task_id]; start_min_[task_id] = pos_; end_min_[task_id] = new_end_min; // Filter the domain @@ -2001,7 +2010,7 @@ class TimeTableSync : public Constraint { void ProcessEventsEcp() { while (!events_ecp_.empty() && events_ecp_.top().first == pos_) { - const int64 task_id = events_ecp_.top().second; + const int64_t task_id = events_ecp_.top().second; events_ecp_.pop(); // Update the event if it is not up to date. if (pos_ < end_min_[task_id]) { @@ -2014,7 +2023,7 @@ class TimeTableSync : public Constraint { void ProcessEventsPr() { while (!events_pr_.empty() && events_pr_.top().first == pos_) { - const int64 task_id = events_pr_.top().second; + const int64_t task_id = events_pr_.top().second; events_pr_.pop(); // The task is in conflict with the current profile. if (demands_[task_id] > gap_) { @@ -2040,7 +2049,7 @@ class TimeTableSync : public Constraint { if (gap_ < prev_gap_) { // Reconsider the task in check state. while (!check_.empty() && demands_[check_.top().second] > gap_) { - const int64 task_id = check_.top().second; + const int64_t task_id = check_.top().second; check_.pop(); if (states_[task_id] == State::CHECK && pos_ < end_min_[task_id]) { states_[task_id] = State::CONFLICT; @@ -2055,12 +2064,12 @@ class TimeTableSync : public Constraint { if (gap_ > prev_gap_) { // Reconsider the tasks in conflict. while (!conflict_.empty() && demands_[conflict_.top().second] <= gap_) { - const int64 task_id = conflict_.top().second; + const int64_t task_id = conflict_.top().second; conflict_.pop(); if (states_[task_id] != State::CONFLICT) { continue; } - const int64 old_end_min = end_min_[task_id]; + const int64_t old_end_min = end_min_[task_id]; // Update the cache. start_min_[task_id] = pos_; end_min_[task_id] = pos_ + durations_[task_id]; @@ -2074,7 +2083,7 @@ class TimeTableSync : public Constraint { states_[task_id] = State::READY; } // Update possible compulsory part. - const int64 start_max = start_max_[task_id]; + const int64_t start_max = start_max_[task_id]; if (start_max >= old_end_min && start_max < end_min_[task_id]) { events_ecp_.push(kv(end_min_[task_id], task_id)); } @@ -2085,8 +2094,8 @@ class TimeTableSync : public Constraint { void BuildEvents() { // Reset the sweep line. - pos_ = kint64min; - next_pos_ = kint64min; + pos_ = std::numeric_limits::min(); + next_pos_ = std::numeric_limits::min(); gap_ = capacity_->Max(); prev_gap_ = capacity_->Max(); // Reset dynamic states. @@ -2105,9 +2114,9 @@ class TimeTableSync : public Constraint { states_.clear(); // Build events. for (int i = 0; i < num_tasks_; i++) { - const int64 s_min = tasks_[i]->interval->StartMin(); - const int64 s_max = tasks_[i]->interval->StartMax(); - const int64 e_min = tasks_[i]->interval->EndMin(); + const int64_t s_min = tasks_[i]->interval->StartMin(); + const int64_t s_max = tasks_[i]->interval->StartMax(); + const int64_t e_min = tasks_[i]->interval->EndMin(); // Cache the values. start_min_.push_back(s_min); start_max_.push_back(s_max); @@ -2129,19 +2138,19 @@ class TimeTableSync : public Constraint { } } - int64 num_tasks_; + int64_t num_tasks_; std::vector tasks_; IntVar* const capacity_; - std::vector start_min_; - std::vector start_max_; - std::vector end_min_; - std::vector end_max_; - std::vector durations_; - std::vector demands_; + std::vector start_min_; + std::vector start_max_; + std::vector end_min_; + std::vector end_max_; + std::vector durations_; + std::vector demands_; // Pair key value. - typedef std::pair kv; + typedef std::pair kv; typedef std::priority_queue, std::greater> min_heap; typedef std::priority_queue, std::less> max_heap; @@ -2156,17 +2165,17 @@ class TimeTableSync : public Constraint { max_heap check_; // Sweep line state. - int64 pos_; - int64 next_pos_; - int64 gap_; - int64 prev_gap_; + int64_t pos_; + int64_t next_pos_; + int64_t gap_; + int64_t prev_gap_; }; class CumulativeConstraint : public Constraint { public: CumulativeConstraint(Solver* const s, const std::vector& intervals, - const std::vector& demands, + const std::vector& demands, IntVar* const capacity, const std::string& name) : Constraint(s), capacity_(capacity), @@ -2254,7 +2263,7 @@ class CumulativeConstraint : public Constraint { std::vector high_demand_intervals; high_demand_intervals.reserve(intervals_.size()); for (int i = 0; i < demands_.size(); ++i) { - const int64 demand = tasks_[i].demand; + const int64_t demand = tasks_[i].demand; // Consider two tasks with demand d1 and d2 such that // d1 * 2 > capacity_ and d2 * 2 > capacity_. // Then d1 + d2 = 1/2 (d1 * 2 + d2 * 2) @@ -2350,7 +2359,7 @@ class CumulativeConstraint : public Constraint { // Array of intervals for the visitor. const std::vector intervals_; // Array of demands for the visitor. - const std::vector demands_; + const std::vector demands_; DISALLOW_COPY_AND_ASSIGN(CumulativeConstraint); }; @@ -2444,7 +2453,7 @@ class VariableDemandCumulativeConstraint : public Constraint { std::vector high_demand_intervals; high_demand_intervals.reserve(intervals_.size()); for (int i = 0; i < demands_.size(); ++i) { - const int64 demand = tasks_[i].demand->Min(); + const int64_t demand = tasks_[i].demand->Min(); // Consider two tasks with demand d1 and d2 such that // d1 * 2 > capacity_ and d2 * 2 > capacity_. // Then d1 + d2 = 1/2 (d1 * 2 + d2 * 2) @@ -2555,17 +2564,17 @@ DisjunctiveConstraint::DisjunctiveConstraint( if (!name.empty()) { set_name(name); } - transition_time_ = [](int64 x, int64 y) { return 0; }; + transition_time_ = [](int64_t x, int64_t y) { return 0; }; } DisjunctiveConstraint::~DisjunctiveConstraint() {} void DisjunctiveConstraint::SetTransitionTime( - std::function transition_time) { + std::function transition_time) { if (transition_time != nullptr) { transition_time_ = transition_time; } else { - transition_time_ = [](int64 x, int64 y) { return 0; }; + transition_time_ = [](int64_t x, int64_t y) { return 0; }; } } @@ -2584,8 +2593,8 @@ DisjunctiveConstraint* Solver::MakeStrictDisjunctiveConstraint( // Demands are constant Constraint* Solver::MakeCumulative(const std::vector& intervals, - const std::vector& demands, - int64 capacity, const std::string& name) { + const std::vector& demands, + int64_t capacity, const std::string& name) { CHECK_EQ(intervals.size(), demands.size()); for (int i = 0; i < intervals.size(); ++i) { CHECK_GE(demands[i], 0); @@ -2599,12 +2608,12 @@ Constraint* Solver::MakeCumulative(const std::vector& intervals, Constraint* Solver::MakeCumulative(const std::vector& intervals, const std::vector& demands, - int64 capacity, const std::string& name) { + int64_t capacity, const std::string& name) { return MakeCumulative(intervals, ToInt64Vector(demands), capacity, name); } Constraint* Solver::MakeCumulative(const std::vector& intervals, - const std::vector& demands, + const std::vector& demands, IntVar* const capacity, const std::string& name) { CHECK_EQ(intervals.size(), demands.size()); @@ -2626,13 +2635,13 @@ Constraint* Solver::MakeCumulative(const std::vector& intervals, Constraint* Solver::MakeCumulative(const std::vector& intervals, const std::vector& demands, - int64 capacity, const std::string& name) { + int64_t capacity, const std::string& name) { CHECK_EQ(intervals.size(), demands.size()); for (int i = 0; i < intervals.size(); ++i) { CHECK_GE(demands[i]->Min(), 0); } if (AreAllBound(demands)) { - std::vector fixed_demands(demands.size()); + std::vector fixed_demands(demands.size()); for (int i = 0; i < demands.size(); ++i) { fixed_demands[i] = demands[i]->Value(); } @@ -2651,7 +2660,7 @@ Constraint* Solver::MakeCumulative(const std::vector& intervals, CHECK_GE(demands[i]->Min(), 0); } if (AreAllBound(demands)) { - std::vector fixed_demands(demands.size()); + std::vector fixed_demands(demands.size()); for (int i = 0; i < demands.size(); ++i) { fixed_demands[i] = demands[i]->Value(); } diff --git a/ortools/constraint_solver/routing.cc b/ortools/constraint_solver/routing.cc index 2120b65c4a..bf1e89e3d0 100644 --- a/ortools/constraint_solver/routing.cc +++ b/ortools/constraint_solver/routing.cc @@ -13,29 +13,42 @@ #include "ortools/constraint_solver/routing.h" +#include + #include #include #include +#include #include +#include #include -#include +#include +#include #include #include -#include +#include +#include #include +#include #include +#include -#include "absl/base/casts.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" +#include "absl/flags/flag.h" +#include "absl/functional/bind_front.h" #include "absl/memory/memory.h" +#include "absl/meta/type_traits.h" +#include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" #include "absl/time/time.h" #include "google/protobuf/duration.pb.h" #include "google/protobuf/text_format.h" #include "ortools/base/commandlineflags.h" #include "ortools/base/hash.h" +#include "ortools/base/int_type.h" #include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/map_util.h" @@ -45,29 +58,44 @@ #include "ortools/base/strong_vector.h" #include "ortools/base/thorough_hash.h" #include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/routing_enums.pb.h" +#include "ortools/constraint_solver/routing_filters.h" +#include "ortools/constraint_solver/routing_index_manager.h" #include "ortools/constraint_solver/routing_lp_scheduling.h" #include "ortools/constraint_solver/routing_neighborhoods.h" #include "ortools/constraint_solver/routing_parameters.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/constraint_solver/routing_search.h" +#include "ortools/constraint_solver/routing_types.h" +#include "ortools/constraint_solver/solver_parameters.pb.h" #include "ortools/graph/connected_components.h" +#include "ortools/graph/ebert_graph.h" +#include "ortools/graph/graph.h" #include "ortools/graph/linear_assignment.h" -#include "ortools/graph/min_cost_flow.h" -#include "ortools/graph/topologicalsorter.h" -#include "ortools/lp_data/lp_data.h" -#include "ortools/lp_data/lp_types.h" #include "ortools/util/bitset.h" #include "ortools/util/optional_boolean.pb.h" +#include "ortools/util/piecewise_linear_function.h" +#include "ortools/util/range_query_function.h" #include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" #include "ortools/util/stats.h" namespace operations_research { +class Cross; +class Exchange; +class ExtendedSwapActiveOperator; class LocalSearchPhaseParameters; +class MakeActiveAndRelocate; +class MakeActiveOperator; +class MakeChainInactiveOperator; +class MakeInactiveOperator; +class Relocate; +class RelocateAndMakeActiveOperator; +class SwapActiveOperator; +class TwoOpt; } // namespace operations_research -ABSL_FLAG(int64, sweep_sectors, 1, - "The number of sectors the space is divided before it is sweeped " - "by the ray."); - // Trace settings // TODO(user): Move most of the following settings to a model parameter @@ -82,7 +110,7 @@ namespace { class SetValuesFromTargets : public DecisionBuilder { public: SetValuesFromTargets(std::vector variables, - std::vector targets) + std::vector targets) : variables_(std::move(variables)), targets_(std::move(targets)), index_(0), @@ -96,8 +124,8 @@ class SetValuesFromTargets : public DecisionBuilder { } index_.SetValue(solver, index); if (index >= variables_.size()) return nullptr; - const int64 variable_min = variables_[index]->Min(); - const int64 variable_max = variables_[index]->Max(); + const int64_t variable_min = variables_[index]->Min(); + const int64_t variable_max = variables_[index]->Max(); // Target can be before, inside, or after the variable range. // We do a trichotomy on this for clarity. if (targets_[index] <= variable_min) { @@ -105,8 +133,8 @@ class SetValuesFromTargets : public DecisionBuilder { } else if (targets_[index] >= variable_max) { return solver->MakeAssignVariableValue(variables_[index], variable_max); } else { - int64 step = steps_[index]; - int64 value = CapAdd(targets_[index], step); + int64_t step = steps_[index]; + int64_t value = CapAdd(targets_[index], step); // If value is out of variable's range, we can remove the interval of // values already explored (which can make the solver fail) and // recall Next() to get back into the trichotomy above. @@ -129,20 +157,20 @@ class SetValuesFromTargets : public DecisionBuilder { } private: - int64 GetNextStep(int64 step) const { + int64_t GetNextStep(int64_t step) const { return (step > 0) ? -step : CapSub(1, step); } const std::vector variables_; - const std::vector targets_; + const std::vector targets_; Rev index_; - RevArray steps_; + RevArray steps_; }; } // namespace DecisionBuilder* MakeSetValuesFromTargets(Solver* solver, std::vector variables, - std::vector targets) { + std::vector targets) { return solver->RevAlloc( new SetValuesFromTargets(std::move(variables), std::move(targets))); } @@ -199,11 +227,11 @@ class SetCumulsFromLocalDimensionCosts : public DecisionBuilder { const auto& local_optimizer = local_optimizers_[i]; const RoutingDimension* const dimension = local_optimizer->dimension(); RoutingModel* const model = dimension->model(); - const auto next = [model](int64 i) { return model->NextVar(i)->Value(); }; + const auto next = [model](int64_t i) { return model->NextVar(i)->Value(); }; const auto compute_cumul_values = [this, &next](LocalDimensionCumulOptimizer* optimizer, int vehicle, - std::vector* cumul_values, - std::vector* break_start_end_values) { + std::vector* cumul_values, + std::vector* break_start_end_values) { if (optimize_and_pack_) { return optimizer->ComputePackedRouteCumuls( vehicle, next, cumul_values, break_start_end_values); @@ -223,8 +251,8 @@ class SetCumulsFromLocalDimensionCosts : public DecisionBuilder { vehicle_has_break_constraint ? local_mp_optimizers_[i].get() : local_optimizer.get(); DCHECK(optimizer != nullptr); - std::vector cumul_values; - std::vector break_start_end_values; + std::vector cumul_values; + std::vector break_start_end_values; const DimensionSchedulingStatus status = compute_cumul_values( optimizer, vehicle, &cumul_values, &break_start_end_values); if (status == DimensionSchedulingStatus::INFEASIBLE) { @@ -248,7 +276,7 @@ class SetCumulsFromLocalDimensionCosts : public DecisionBuilder { // Concatenate cumul_values and break_start_end_values into cp_values, // generate corresponding cp_variables vector. std::vector cp_variables; - std::vector cp_values; + std::vector cp_values; std::swap(cp_values, cumul_values); { int current = model->Start(vehicle); @@ -279,7 +307,7 @@ class SetCumulsFromLocalDimensionCosts : public DecisionBuilder { } // Value kint64min signals an unoptimized variable, set to min instead. for (int i = 0; i < cp_values.size(); ++i) { - if (cp_values[i] == kint64min) { + if (cp_values[i] == std::numeric_limits::min()) { cp_values[i] = cp_variables[i]->Min(); } } @@ -325,12 +353,12 @@ class SetCumulsFromGlobalDimensionCosts : public DecisionBuilder { const RoutingDimension* dimension = global_optimizer->dimension(); RoutingModel* const model = dimension->model(); - const auto next = [model](int64 i) { return model->NextVar(i)->Value(); }; + const auto next = [model](int64_t i) { return model->NextVar(i)->Value(); }; DCHECK(DimensionFixedTransitsEqualTransitEvaluators(*dimension)); - std::vector cumul_values; - std::vector break_start_end_values; + std::vector cumul_values; + std::vector break_start_end_values; const bool cumuls_optimized = optimize_and_pack_ ? global_optimizer->ComputePackedCumuls(next, &cumul_values, @@ -344,7 +372,7 @@ class SetCumulsFromGlobalDimensionCosts : public DecisionBuilder { // Concatenate cumul_values and break_start_end_values into cp_values, // generate corresponding cp_variables vector. std::vector cp_variables = dimension->cumuls(); - std::vector cp_values; + std::vector cp_values; std::swap(cp_values, cumul_values); if (dimension->HasBreakConstraints()) { const int num_vehicles = model->vehicles(); @@ -360,7 +388,7 @@ class SetCumulsFromGlobalDimensionCosts : public DecisionBuilder { } // Value kint64min signals an unoptimized variable, set to min instead. for (int i = 0; i < cp_values.size(); ++i) { - if (cp_values[i] == kint64min) { + if (cp_values[i] == std::numeric_limits::min()) { cp_values[i] = cp_variables[i]->Min(); } } @@ -398,7 +426,9 @@ const Assignment* RoutingModel::PackCumulsOfOptimizerDimensionsFromAssignment( return original_assignment; } RegularLimit* const limit = GetOrCreateLimit(); - limit->UpdateLimits(duration_limit, kint64max, kint64max, kint64max); + limit->UpdateLimits(duration_limit, std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); // Initialize the packed_assignment with the Next values in the // original_assignment. @@ -441,11 +471,19 @@ const Assignment* RoutingModel::PackCumulsOfOptimizerDimensionsFromAssignment( return packed_assignment; } +void RoutingModel::SetSweepArranger(SweepArranger* sweep_arranger) { + sweep_arranger_.reset(sweep_arranger); +} + +SweepArranger* RoutingModel::sweep_arranger() const { + return sweep_arranger_.get(); +} + namespace { // Constraint which ensures that var != values. class DifferentFromValues : public Constraint { public: - DifferentFromValues(Solver* solver, IntVar* var, std::vector values) + DifferentFromValues(Solver* solver, IntVar* var, std::vector values) : Constraint(solver), var_(var), values_(std::move(values)) {} void Post() override {} void InitialPropagate() override { var_->RemoveValues(values_); } @@ -460,7 +498,7 @@ class DifferentFromValues : public Constraint { private: IntVar* const var_; - const std::vector values_; + const std::vector values_; }; // Set of "light" constraints, well-suited for use within Local Search. @@ -576,14 +614,14 @@ class LightFunctionElement2Constraint : public Constraint { visitor->VisitIntegerExpressionArgument(ModelVisitor::kIndex2Argument, index2_); // Warning: This will expand all values into a vector. - const int64 index1_min = index1_->Min(); - const int64 index1_max = index1_->Max(); + const int64_t index1_min = index1_->Min(); + const int64_t index1_max = index1_->Max(); visitor->VisitIntegerArgument(ModelVisitor::kMinArgument, index1_min); visitor->VisitIntegerArgument(ModelVisitor::kMaxArgument, index1_max); if (deep_serialize_()) { for (int i = index1_min; i <= index1_max; ++i) { visitor->VisitInt64ToInt64Extension( - [this, i](int64 j) { return values_(i, j); }, index2_->Min(), + [this, i](int64_t j) { return values_(i, j); }, index2_->Min(), index2_->Max()); } } @@ -615,7 +653,7 @@ Constraint* MakeLightElement2(Solver* const solver, IntVar* const var, // Evaluators template -static int64 ReturnZero(A a, B b) { +static int64_t ReturnZero(A a, B b) { return 0; } @@ -636,7 +674,7 @@ bool TransitCallbackPositive(const RoutingTransitCallback2& callback, int size1, // ----- Routing model ----- static const int kUnassigned = -1; -const int64 RoutingModel::kNoPenalty = -1; +const int64_t RoutingModel::kNoPenalty = -1; const RoutingModel::DisjunctionIndex RoutingModel::kNoDisjunction(-1); @@ -672,7 +710,7 @@ RoutingModel::RoutingModel(const RoutingIndexManager& index_manager, manager_(index_manager) { // Initialize vehicle costs to the zero evaluator. vehicle_to_transit_cost_.assign( - vehicles_, RegisterTransitCallback(ReturnZero)); + vehicles_, RegisterTransitCallback(ReturnZero)); // Active caching after initializing vehicle_to_transit_cost_ to avoid // uselessly caching ReturnZero. cache_callbacks_ = (nodes_ <= parameters.max_callback_cache_size()); @@ -686,7 +724,7 @@ RoutingModel::RoutingModel(const RoutingIndexManager& index_manager, start_end_count_ = index_manager.num_unique_depots(); Initialize(); - const int64 size = Size(); + const int64_t size = Size(); index_to_pickup_index_pairs_.resize(size); index_to_delivery_index_pairs_.resize(size); index_to_visit_type_.resize(index_manager.num_indices(), kUnassigned); @@ -769,14 +807,14 @@ int RegisterUnaryCallback(RoutingTransitCallback1 callback, bool is_positive, } } // namespace -int RoutingModel::RegisterUnaryTransitVector(std::vector values) { +int RoutingModel::RegisterUnaryTransitVector(std::vector values) { return RegisterUnaryCallback( - [this, values = std::move(values)](int64 i) { + [this, values = std::move(values)](int64_t i) { return values[manager_.IndexToNode(i).value()]; }, /*is_positive=*/ std::all_of(std::cbegin(values), std::cend(values), - [](int64 transit) { return transit >= 0; }), + [](int64_t transit) { return transit >= 0; }), this); } @@ -789,18 +827,18 @@ int RoutingModel::RegisterUnaryTransitCallback(TransitCallback1 callback) { } int RoutingModel::RegisterTransitMatrix( - std::vector /*needed_for_swig*/> values) { + std::vector /*needed_for_swig*/> values) { bool all_transits_positive = true; - for (const std::vector& transit_values : values) { + for (const std::vector& transit_values : values) { all_transits_positive = std::all_of(std::cbegin(transit_values), std::cend(transit_values), - [](int64 transit) { return transit >= 0; }); + [](int64_t transit) { return transit >= 0; }); if (!all_transits_positive) { break; } } return RegisterCallback( - [this, values = std::move(values)](int64 i, int64 j) { + [this, values = std::move(values)](int64_t i, int64_t j) { return values[manager_.IndexToNode(i).value()] [manager_.IndexToNode(j).value()]; }, @@ -818,14 +856,14 @@ int RoutingModel::RegisterPositiveUnaryTransitCallback( int RoutingModel::RegisterTransitCallback(TransitCallback2 callback) { if (cache_callbacks_) { const int size = Size() + vehicles(); - std::vector cache(size * size, 0); + std::vector cache(size * size, 0); for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { cache[i * size + j] = callback(i, j); } } transit_evaluators_.push_back( - [cache, size](int64 i, int64 j) { return cache[i * size + j]; }); + [cache, size](int64_t i, int64_t j) { return cache[i * size + j]; }); } else { transit_evaluators_.push_back(std::move(callback)); } @@ -855,7 +893,7 @@ int RoutingModel::RegisterStateDependentTransitCallback( StateDependentTransitCallbackCache* const cache = state_dependent_transit_evaluators_cache_.back().get(); state_dependent_transit_evaluators_.push_back( - [cache, callback](int64 i, int64 j) { + [cache, callback](int64_t i, int64_t j) { StateDependentTransit value; if (gtl::FindCopy(*cache, CacheKey(i, j), &value)) return value; value = callback(i, j); @@ -872,28 +910,29 @@ void RoutingModel::AddNoCycleConstraintInternal() { } } -bool RoutingModel::AddDimension(int evaluator_index, int64 slack_max, - int64 capacity, bool fix_start_cumul_to_zero, +bool RoutingModel::AddDimension(int evaluator_index, int64_t slack_max, + int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name) { const std::vector evaluator_indices(vehicles_, evaluator_index); - std::vector capacities(vehicles_, capacity); + std::vector capacities(vehicles_, capacity); return AddDimensionWithCapacityInternal(evaluator_indices, slack_max, std::move(capacities), fix_start_cumul_to_zero, name); } bool RoutingModel::AddDimensionWithVehicleTransits( - const std::vector& evaluator_indices, int64 slack_max, int64 capacity, - bool fix_start_cumul_to_zero, const std::string& name) { - std::vector capacities(vehicles_, capacity); + const std::vector& evaluator_indices, int64_t slack_max, + int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name) { + std::vector capacities(vehicles_, capacity); return AddDimensionWithCapacityInternal(evaluator_indices, slack_max, std::move(capacities), fix_start_cumul_to_zero, name); } bool RoutingModel::AddDimensionWithVehicleCapacity( - int evaluator_index, int64 slack_max, std::vector vehicle_capacities, - bool fix_start_cumul_to_zero, const std::string& name) { + int evaluator_index, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& name) { const std::vector evaluator_indices(vehicles_, evaluator_index); return AddDimensionWithCapacityInternal(evaluator_indices, slack_max, std::move(vehicle_capacities), @@ -901,8 +940,8 @@ bool RoutingModel::AddDimensionWithVehicleCapacity( } bool RoutingModel::AddDimensionWithVehicleTransitAndCapacity( - const std::vector& evaluator_indices, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::vector& evaluator_indices, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name) { return AddDimensionWithCapacityInternal(evaluator_indices, slack_max, std::move(vehicle_capacities), @@ -910,8 +949,8 @@ bool RoutingModel::AddDimensionWithVehicleTransitAndCapacity( } bool RoutingModel::AddDimensionWithCapacityInternal( - const std::vector& evaluator_indices, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::vector& evaluator_indices, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name) { CHECK_EQ(vehicles_, vehicle_capacities.size()); return InitializeDimensionInternal( @@ -921,8 +960,9 @@ bool RoutingModel::AddDimensionWithCapacityInternal( bool RoutingModel::InitializeDimensionInternal( const std::vector& evaluator_indices, - const std::vector& state_dependent_evaluator_indices, int64 slack_max, - bool fix_start_cumul_to_zero, RoutingDimension* dimension) { + const std::vector& state_dependent_evaluator_indices, + int64_t slack_max, bool fix_start_cumul_to_zero, + RoutingDimension* dimension) { CHECK(dimension != nullptr); CHECK_EQ(vehicles_, evaluator_indices.size()); CHECK((dimension->base_dimension_ == nullptr && @@ -950,10 +990,10 @@ bool RoutingModel::InitializeDimensionInternal( } std::pair RoutingModel::AddConstantDimensionWithSlack( - int64 value, int64 capacity, int64 slack_max, bool fix_start_cumul_to_zero, - const std::string& dimension_name) { + int64_t value, int64_t capacity, int64_t slack_max, + bool fix_start_cumul_to_zero, const std::string& dimension_name) { const int evaluator_index = - RegisterUnaryCallback([value](int64) { return value; }, + RegisterUnaryCallback([value](int64_t) { return value; }, /*is_positive=*/value >= 0, this); return std::make_pair(evaluator_index, AddDimension(evaluator_index, slack_max, capacity, @@ -961,7 +1001,7 @@ std::pair RoutingModel::AddConstantDimensionWithSlack( } std::pair RoutingModel::AddVectorDimension( - std::vector values, int64 capacity, bool fix_start_cumul_to_zero, + std::vector values, int64_t capacity, bool fix_start_cumul_to_zero, const std::string& dimension_name) { const int evaluator_index = RegisterUnaryTransitVector(std::move(values)); return std::make_pair(evaluator_index, @@ -970,7 +1010,7 @@ std::pair RoutingModel::AddVectorDimension( } std::pair RoutingModel::AddMatrixDimension( - std::vector> values, int64 capacity, + std::vector> values, int64_t capacity, bool fix_start_cumul_to_zero, const std::string& dimension_name) { const int evaluator_index = RegisterTransitMatrix(std::move(values)); return std::make_pair(evaluator_index, @@ -991,50 +1031,50 @@ class RangeMakeElementExpr : public BaseIntExpr { CHECK(index != nullptr); } - int64 Min() const override { + int64_t Min() const override { // Converting [index_->Min(), index_->Max()] to [idx_min, idx_max). const int idx_min = index_->Min(); const int idx_max = index_->Max() + 1; return (idx_min < idx_max) ? callback_->RangeMin(idx_min, idx_max) - : kint64max; + : std::numeric_limits::max(); } - void SetMin(int64 new_min) override { - const int64 old_min = Min(); - const int64 old_max = Max(); + void SetMin(int64_t new_min) override { + const int64_t old_min = Min(); + const int64_t old_max = Max(); if (old_min < new_min && new_min <= old_max) { - const int64 old_idx_min = index_->Min(); - const int64 old_idx_max = index_->Max() + 1; + const int64_t old_idx_min = index_->Min(); + const int64_t old_idx_max = index_->Max() + 1; if (old_idx_min < old_idx_max) { - const int64 new_idx_min = callback_->RangeFirstInsideInterval( + const int64_t new_idx_min = callback_->RangeFirstInsideInterval( old_idx_min, old_idx_max, new_min, old_max + 1); index_->SetMin(new_idx_min); if (new_idx_min < old_idx_max) { - const int64 new_idx_max = callback_->RangeLastInsideInterval( + const int64_t new_idx_max = callback_->RangeLastInsideInterval( new_idx_min, old_idx_max, new_min, old_max + 1); index_->SetMax(new_idx_max); } } } } - int64 Max() const override { + int64_t Max() const override { // Converting [index_->Min(), index_->Max()] to [idx_min, idx_max). const int idx_min = index_->Min(); const int idx_max = index_->Max() + 1; return (idx_min < idx_max) ? callback_->RangeMax(idx_min, idx_max) - : kint64min; + : std::numeric_limits::min(); } - void SetMax(int64 new_max) override { - const int64 old_min = Min(); - const int64 old_max = Max(); + void SetMax(int64_t new_max) override { + const int64_t old_min = Min(); + const int64_t old_max = Max(); if (old_min <= new_max && new_max < old_max) { - const int64 old_idx_min = index_->Min(); - const int64 old_idx_max = index_->Max() + 1; + const int64_t old_idx_min = index_->Min(); + const int64_t old_idx_max = index_->Max() + 1; if (old_idx_min < old_idx_max) { - const int64 new_idx_min = callback_->RangeFirstInsideInterval( + const int64_t new_idx_min = callback_->RangeFirstInsideInterval( old_idx_min, old_idx_max, old_min, new_max + 1); index_->SetMin(new_idx_min); if (new_idx_min < old_idx_max) { - const int64 new_idx_max = callback_->RangeLastInsideInterval( + const int64_t new_idx_max = callback_->RangeLastInsideInterval( new_idx_min, old_idx_max, old_min, new_max + 1); index_->SetMax(new_idx_max); } @@ -1057,8 +1097,8 @@ IntExpr* MakeRangeMakeElementExpr(const RangeIntToIntFunction* callback, bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacity( const std::vector& dependent_transits, - const RoutingDimension* base_dimension, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name) { const std::vector pure_transits(vehicles_, /*zero_evaluator*/ 0); return AddDimensionDependentDimensionWithVehicleCapacity( @@ -1067,8 +1107,8 @@ bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacity( } bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacity( - int transit, const RoutingDimension* dimension, int64 slack_max, - int64 vehicle_capacity, bool fix_start_cumul_to_zero, + int transit, const RoutingDimension* dimension, int64_t slack_max, + int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string& name) { return AddDimensionDependentDimensionWithVehicleCapacity( /*zero_evaluator*/ 0, transit, dimension, slack_max, vehicle_capacity, @@ -1078,8 +1118,8 @@ bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacity( bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacityInternal( const std::vector& pure_transits, const std::vector& dependent_transits, - const RoutingDimension* base_dimension, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name) { CHECK_EQ(vehicles_, vehicle_capacities.size()); RoutingDimension* new_dimension = nullptr; @@ -1097,21 +1137,21 @@ bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacityInternal( bool RoutingModel::AddDimensionDependentDimensionWithVehicleCapacity( int pure_transit, int dependent_transit, - const RoutingDimension* base_dimension, int64 slack_max, - int64 vehicle_capacity, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string& name) { std::vector pure_transits(vehicles_, pure_transit); std::vector dependent_transits(vehicles_, dependent_transit); - std::vector vehicle_capacities(vehicles_, vehicle_capacity); + std::vector vehicle_capacities(vehicles_, vehicle_capacity); return AddDimensionDependentDimensionWithVehicleCapacityInternal( pure_transits, dependent_transits, base_dimension, slack_max, std::move(vehicle_capacities), fix_start_cumul_to_zero, name); } RoutingModel::StateDependentTransit RoutingModel::MakeStateDependentTransit( - const std::function& f, int64 domain_start, - int64 domain_end) { - const std::function g = [&f](int64 x) { return f(x) + x; }; + const std::function& f, int64_t domain_start, + int64_t domain_end) { + const std::function g = [&f](int64_t x) { return f(x) + x; }; // The next line is safe, because MakeCachedIntToIntFunction does not count // on keeping the closure of its first argument alive. return {MakeCachedIntToIntFunction(f, domain_start, domain_end), @@ -1201,34 +1241,33 @@ void RoutingModel::SetArcCostEvaluatorOfVehicle(int evaluator_index, vehicle_to_transit_cost_[vehicle] = evaluator_index; } -void RoutingModel::SetFixedCostOfAllVehicles(int64 cost) { +void RoutingModel::SetFixedCostOfAllVehicles(int64_t cost) { for (int i = 0; i < vehicles_; ++i) { SetFixedCostOfVehicle(cost, i); } } -int64 RoutingModel::GetFixedCostOfVehicle(int vehicle) const { +int64_t RoutingModel::GetFixedCostOfVehicle(int vehicle) const { CHECK_LT(vehicle, vehicles_); return fixed_cost_of_vehicle_[vehicle]; } -void RoutingModel::SetFixedCostOfVehicle(int64 cost, int vehicle) { +void RoutingModel::SetFixedCostOfVehicle(int64_t cost, int vehicle) { CHECK_LT(vehicle, vehicles_); DCHECK_GE(cost, 0); fixed_cost_of_vehicle_[vehicle] = cost; } void RoutingModel::SetAmortizedCostFactorsOfAllVehicles( - int64 linear_cost_factor, int64 quadratic_cost_factor) { + int64_t linear_cost_factor, int64_t quadratic_cost_factor) { for (int v = 0; v < vehicles_; v++) { SetAmortizedCostFactorsOfVehicle(linear_cost_factor, quadratic_cost_factor, v); } } -void RoutingModel::SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, - int64 quadratic_cost_factor, - int vehicle) { +void RoutingModel::SetAmortizedCostFactorsOfVehicle( + int64_t linear_cost_factor, int64_t quadratic_cost_factor, int vehicle) { CHECK_LT(vehicle, vehicles_); DCHECK_GE(linear_cost_factor, 0); DCHECK_GE(quadratic_cost_factor, 0); @@ -1284,7 +1323,8 @@ void RoutingModel::ComputeCostClasses( // Insert the dimension data in a canonical way. for (const RoutingDimension* const dimension : dimensions_) { - const int64 coeff = dimension->vehicle_span_cost_coefficients()[vehicle]; + const int64_t coeff = + dimension->vehicle_span_cost_coefficients()[vehicle]; if (coeff == 0) continue; cost_class.dimension_transit_evaluator_class_and_cost_coefficient .push_back({dimension->vehicle_to_class(vehicle), coeff, dimension}); @@ -1405,13 +1445,13 @@ void RoutingModel::ComputeVehicleTypes() { vehicles_per_vehicle_class.clear(); vehicles_per_vehicle_class.resize(GetVehicleClassesCount()); - absl::flat_hash_map type_to_type_index; + absl::flat_hash_map type_to_type_index; for (int v = 0; v < vehicles_; v++) { const int start = manager_.IndexToNode(Start(v)).value(); const int end = manager_.IndexToNode(End(v)).value(); const int cost_class = GetCostClassIndexOfVehicle(v).value(); - const int64 type = cost_class * nodes_squared + start * nodes_ + end; + const int64_t type = cost_class * nodes_squared + start * nodes_ + end; const auto& vehicle_type_added = type_to_type_index.insert( std::make_pair(type, type_to_type_index.size())); @@ -1573,7 +1613,8 @@ void RoutingModel::TopologicallySortVisitTypes() { } RoutingModel::DisjunctionIndex RoutingModel::AddDisjunction( - const std::vector& indices, int64 penalty, int64 max_cardinality) { + const std::vector& indices, int64_t penalty, + int64_t max_cardinality) { CHECK_GE(max_cardinality, 1); for (int i = 0; i < indices.size(); ++i) { CHECK_NE(kUnassigned, indices[i]); @@ -1581,20 +1622,20 @@ RoutingModel::DisjunctionIndex RoutingModel::AddDisjunction( const DisjunctionIndex disjunction_index(disjunctions_.size()); disjunctions_.push_back({indices, {penalty, max_cardinality}}); - for (const int64 index : indices) { + for (const int64_t index : indices) { index_to_disjunctions_[index].push_back(disjunction_index); } return disjunction_index; } -std::vector> +std::vector> RoutingModel::GetPerfectBinaryDisjunctions() const { - std::vector> var_index_pairs; + std::vector> var_index_pairs; for (const Disjunction& disjunction : disjunctions_) { - const std::vector& var_indices = disjunction.indices; + const std::vector& var_indices = disjunction.indices; if (var_indices.size() != 2) continue; - const int64 v0 = var_indices[0]; - const int64 v1 = var_indices[1]; + const int64_t v0 = var_indices[0]; + const int64_t v1 = var_indices[1]; if (index_to_disjunctions_[v0].size() == 1 && index_to_disjunctions_[v1].size() == 1) { // We output sorted pairs. @@ -1609,7 +1650,7 @@ void RoutingModel::IgnoreDisjunctionsAlreadyForcedToZero() { CHECK(!closed_); for (Disjunction& disjunction : disjunctions_) { bool has_one_potentially_active_var = false; - for (const int64 var_index : disjunction.indices) { + for (const int64_t var_index : disjunction.indices) { if (ActiveVar(var_index)->Max() > 0) { has_one_potentially_active_var = true; break; @@ -1622,15 +1663,15 @@ void RoutingModel::IgnoreDisjunctionsAlreadyForcedToZero() { } IntVar* RoutingModel::CreateDisjunction(DisjunctionIndex disjunction) { - const std::vector& indices = disjunctions_[disjunction].indices; + const std::vector& indices = disjunctions_[disjunction].indices; const int indices_size = indices.size(); std::vector disjunction_vars(indices_size); for (int i = 0; i < indices_size; ++i) { - const int64 index = indices[i]; + const int64_t index = indices[i]; CHECK_LT(index, Size()); disjunction_vars[i] = ActiveVar(index); } - const int64 max_cardinality = + const int64_t max_cardinality = disjunctions_[disjunction].value.max_cardinality; IntVar* no_active_var = solver_->MakeBoolVar(); IntVar* number_active_vars = solver_->MakeIntVar(0, max_cardinality); @@ -1638,7 +1679,7 @@ IntVar* RoutingModel::CreateDisjunction(DisjunctionIndex disjunction) { solver_->MakeSumEquality(disjunction_vars, number_active_vars)); solver_->AddConstraint(solver_->MakeIsDifferentCstCt( number_active_vars, max_cardinality, no_active_var)); - const int64 penalty = disjunctions_[disjunction].value.penalty; + const int64_t penalty = disjunctions_[disjunction].value.penalty; if (penalty < 0) { no_active_var->SetMax(0); return nullptr; @@ -1648,10 +1689,10 @@ IntVar* RoutingModel::CreateDisjunction(DisjunctionIndex disjunction) { } void RoutingModel::AddSoftSameVehicleConstraint( - const std::vector& indices, int64 cost) { + const std::vector& indices, int64_t cost) { if (!indices.empty()) { - ValuedNodes same_vehicle_cost; - for (const int64 index : indices) { + ValuedNodes same_vehicle_cost; + for (const int64_t index : indices) { same_vehicle_cost.indices.push_back(index); } same_vehicle_cost.value = cost; @@ -1660,7 +1701,7 @@ void RoutingModel::AddSoftSameVehicleConstraint( } void RoutingModel::SetAllowedVehiclesForIndex(const std::vector& vehicles, - int64 index) { + int64_t index) { auto& allowed_vehicles = allowed_vehicles_[index]; allowed_vehicles.clear(); for (int vehicle : vehicles) { @@ -1668,7 +1709,7 @@ void RoutingModel::SetAllowedVehiclesForIndex(const std::vector& vehicles, } } -void RoutingModel::AddPickupAndDelivery(int64 pickup, int64 delivery) { +void RoutingModel::AddPickupAndDelivery(int64_t pickup, int64_t delivery) { AddPickupAndDeliverySetsInternal({pickup}, {delivery}); pickup_delivery_disjunctions_.push_back({kNoDisjunction, kNoDisjunction}); } @@ -1683,20 +1724,21 @@ void RoutingModel::AddPickupAndDeliverySets( } void RoutingModel::AddPickupAndDeliverySetsInternal( - const std::vector& pickups, const std::vector& deliveries) { + const std::vector& pickups, + const std::vector& deliveries) { if (pickups.empty() || deliveries.empty()) { return; } - const int64 size = Size(); + const int64_t size = Size(); const int pair_index = pickup_delivery_pairs_.size(); for (int pickup_index = 0; pickup_index < pickups.size(); pickup_index++) { - const int64 pickup = pickups[pickup_index]; + const int64_t pickup = pickups[pickup_index]; CHECK_LT(pickup, size); index_to_pickup_index_pairs_[pickup].emplace_back(pair_index, pickup_index); } for (int delivery_index = 0; delivery_index < deliveries.size(); delivery_index++) { - const int64 delivery = deliveries[delivery_index]; + const int64_t delivery = deliveries[delivery_index]; CHECK_LT(delivery, size); index_to_delivery_index_pairs_[delivery].emplace_back(pair_index, delivery_index); @@ -1705,13 +1747,13 @@ void RoutingModel::AddPickupAndDeliverySetsInternal( } const std::vector>& RoutingModel::GetPickupIndexPairs( - int64 node_index) const { + int64_t node_index) const { CHECK_LT(node_index, index_to_pickup_index_pairs_.size()); return index_to_pickup_index_pairs_[node_index]; } const std::vector>& RoutingModel::GetDeliveryIndexPairs( - int64 node_index) const { + int64_t node_index) const { CHECK_LT(node_index, index_to_delivery_index_pairs_.size()); return index_to_delivery_index_pairs_[node_index]; } @@ -1749,20 +1791,20 @@ int RoutingModel::GetNumOfSingletonNodes() const { } IntVar* RoutingModel::CreateSameVehicleCost(int vehicle_index) { - const std::vector& indices = + const std::vector& indices = same_vehicle_costs_[vehicle_index].indices; CHECK(!indices.empty()); std::vector vehicle_counts; solver_->MakeIntVarArray(vehicle_vars_.size() + 1, 0, indices.size() + 1, &vehicle_counts); - std::vector vehicle_values(vehicle_vars_.size() + 1); + std::vector vehicle_values(vehicle_vars_.size() + 1); for (int i = 0; i < vehicle_vars_.size(); ++i) { vehicle_values[i] = i; } vehicle_values[vehicle_vars_.size()] = -1; std::vector vehicle_vars; vehicle_vars.reserve(indices.size()); - for (const int64 index : indices) { + for (const int64_t index : indices) { vehicle_vars.push_back(vehicle_vars_[index]); } solver_->AddConstraint(solver_->MakeDistribute(vehicle_vars, vehicle_counts)); @@ -1782,7 +1824,9 @@ void RoutingModel::AddLocalSearchOperator(LocalSearchOperator* ls_operator) { extra_operators_.push_back(ls_operator); } -int64 RoutingModel::GetDepot() const { return vehicles() > 0 ? Start(0) : -1; } +int64_t RoutingModel::GetDepot() const { + return vehicles() > 0 ? Start(0) : -1; +} // TODO(user): Remove the need for the homogeneous version once the // vehicle var to cost class element constraint is fast enough. @@ -1790,14 +1834,15 @@ void RoutingModel::AppendHomogeneousArcCosts( const RoutingSearchParameters& parameters, int node_index, std::vector* cost_elements) { CHECK(cost_elements != nullptr); - const auto arc_cost_evaluator = [this, node_index](int64 next_index) { + const auto arc_cost_evaluator = [this, node_index](int64_t next_index) { return GetHomogeneousCost(node_index, next_index); }; if (UsesLightPropagation(parameters)) { // Only supporting positive costs. // TODO(user): Detect why changing lower bound to kint64min stalls // the search in GLS in some cases (Solomon instances for instance). - IntVar* const base_cost_var = solver_->MakeIntVar(0, kint64max); + IntVar* const base_cost_var = + solver_->MakeIntVar(0, std::numeric_limits::max()); solver_->AddConstraint(MakeLightElement( solver_.get(), base_cost_var, nexts_[node_index], arc_cost_evaluator, [this]() { return enable_deep_serialization_; })); @@ -1821,11 +1866,12 @@ void RoutingModel::AppendArcCosts(const RoutingSearchParameters& parameters, // Only supporting positive costs. // TODO(user): Detect why changing lower bound to kint64min stalls // the search in GLS in some cases (Solomon instances for instance). - IntVar* const base_cost_var = solver_->MakeIntVar(0, kint64max); + IntVar* const base_cost_var = + solver_->MakeIntVar(0, std::numeric_limits::max()); solver_->AddConstraint(MakeLightElement2( solver_.get(), base_cost_var, nexts_[node_index], vehicle_vars_[node_index], - [this, node_index](int64 to, int64 vehicle) { + [this, node_index](int64_t to, int64_t vehicle) { return GetArcCostForVehicle(node_index, to, vehicle); }, [this]() { return enable_deep_serialization_; })); @@ -1836,13 +1882,13 @@ void RoutingModel::AppendArcCosts(const RoutingSearchParameters& parameters, IntVar* const vehicle_class_var = solver_ ->MakeElement( - [this](int64 index) { + [this](int64_t index) { return SafeGetCostClassInt64OfVehicle(index); }, vehicle_vars_[node_index]) ->Var(); IntExpr* const expr = solver_->MakeElement( - [this, node_index](int64 next, int64 vehicle_class) { + [this, node_index](int64_t next, int64_t vehicle_class) { return GetArcCostForClass(node_index, next, vehicle_class); }, nexts_[node_index], vehicle_class_var); @@ -1851,7 +1897,7 @@ void RoutingModel::AppendArcCosts(const RoutingSearchParameters& parameters, } } -int RoutingModel::GetVehicleStartClass(int64 start_index) const { +int RoutingModel::GetVehicleStartClass(int64_t start_index) const { const int vehicle = index_to_vehicle_[start_index]; if (vehicle != kUnassigned) { return GetVehicleClassIndexOfVehicle(vehicle).value(); @@ -1925,14 +1971,14 @@ class RoutingModelInspector : public ModelVisitor { [](const IntExpr* expr) {})(expr); } void VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) override { + const std::vector& values) override { gtl::FindWithDefault(array_inspectors_, arg_name, - [](const std::vector& int_array) {})(values); + [](const std::vector& int_array) {})(values); } private: using ExprInspector = std::function; - using ArrayInspector = std::function&)>; + using ArrayInspector = std::function&)>; using ConstraintInspector = std::function; void RegisterInspectors() { @@ -1946,11 +1992,11 @@ class RoutingModelInspector : public ModelVisitor { right_ = expr; }; array_inspectors_[kStartsArgument] = - [this](const std::vector& int_array) { + [this](const std::vector& int_array) { starts_argument_ = int_array; }; array_inspectors_[kEndsArgument] = - [this](const std::vector& int_array) { + [this](const std::vector& int_array) { ends_argument_ = int_array; }; constraint_inspectors_[kNotMember] = [this]() { @@ -2009,8 +2055,8 @@ class RoutingModelInspector : public ModelVisitor { const IntExpr* expr_ = nullptr; const IntExpr* left_ = nullptr; const IntExpr* right_ = nullptr; - std::vector starts_argument_; - std::vector ends_argument_; + std::vector starts_argument_; + std::vector ends_argument_; }; void RoutingModel::DetectImplicitPickupAndDeliveries() { @@ -2022,7 +2068,7 @@ void RoutingModel::DetectImplicitPickupAndDeliveries() { } } // Needs to be sorted for stability. - std::set> implicit_pickup_deliveries; + std::set> implicit_pickup_deliveries; for (const RoutingDimension* const dimension : dimensions_) { if (dimension->class_evaluators_.size() != 1) { continue; @@ -2030,10 +2076,10 @@ void RoutingModel::DetectImplicitPickupAndDeliveries() { 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; + 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); + const int64_t demand = transit(node); if (demand > 0) { nodes_by_positive_demand[demand].push_back(node); } else if (demand < 0) { @@ -2041,11 +2087,11 @@ void RoutingModel::DetectImplicitPickupAndDeliveries() { } } for (const auto& [demand, positive_nodes] : nodes_by_positive_demand) { - const std::vector* const negative_nodes = + 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) { + for (int64_t positive_node : positive_nodes) { + for (int64_t negative_node : *negative_nodes) { implicit_pickup_deliveries.insert({positive_node, negative_node}); } } @@ -2055,7 +2101,7 @@ void RoutingModel::DetectImplicitPickupAndDeliveries() { 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})); + std::vector({pickup}), std::vector({delivery})); } } @@ -2080,7 +2126,7 @@ void RoutingModel::CloseModelWithParameters( ComputeVehicleClasses(); ComputeVehicleTypes(); FinalizeVisitTypes(); - vehicle_start_class_callback_ = [this](int64 start) { + vehicle_start_class_callback_ = [this](int64_t start) { return GetVehicleStartClass(start); }; @@ -2090,8 +2136,8 @@ void RoutingModel::CloseModelWithParameters( // Vehicle variable constraints for (int i = 0; i < vehicles_; ++i) { - const int64 start = starts_[i]; - const int64 end = ends_[i]; + const int64_t start = starts_[i]; + const int64_t end = ends_[i]; solver_->AddConstraint( solver_->MakeEquality(vehicle_vars_[start], solver_->MakeIntConst(i))); solver_->AddConstraint( @@ -2145,7 +2191,7 @@ void RoutingModel::CloseModelWithParameters( for (int i = 0; i < allowed_vehicles_.size(); ++i) { const auto& allowed_vehicles = allowed_vehicles_[i]; if (!allowed_vehicles.empty()) { - std::vector vehicles; + std::vector vehicles; vehicles.reserve(allowed_vehicles.size() + 1); vehicles.push_back(-1); for (int vehicle : allowed_vehicles) { @@ -2179,7 +2225,7 @@ void RoutingModel::CloseModelWithParameters( // Associate first and "logical" last nodes for (int i = 0; i < vehicles_; ++i) { - std::vector forbidden_ends; + std::vector forbidden_ends; forbidden_ends.reserve(vehicles_ - 1); for (int j = 0; j < vehicles_; ++j) { if (i != j) { @@ -2191,7 +2237,7 @@ void RoutingModel::CloseModelWithParameters( } // Constraining is_bound_to_end_ variables. - for (const int64 end : ends_) { + for (const int64_t end : ends_) { is_bound_to_end_[end]->SetValue(1); } @@ -2233,14 +2279,17 @@ void RoutingModel::CloseModelWithParameters( for (const RoutingDimension* dimension : dimensions_) { dimension->SetupGlobalSpanCost(&cost_elements); dimension->SetupSlackAndDependentTransitCosts(); - const std::vector& span_costs = + const std::vector& span_costs = dimension->vehicle_span_cost_coefficients(); - const std::vector& span_ubs = dimension->vehicle_span_upper_bounds(); + const std::vector& span_ubs = + dimension->vehicle_span_upper_bounds(); const bool has_span_constraint = std::any_of(span_costs.begin(), span_costs.end(), - [](int64 coeff) { return coeff != 0; }) || + [](int64_t coeff) { return coeff != 0; }) || std::any_of(span_ubs.begin(), span_ubs.end(), - [](int64 value) { return value < kint64max; }) || + [](int64_t value) { + return value < std::numeric_limits::max(); + }) || dimension->HasSoftSpanUpperBounds() || dimension->HasQuadraticCostSoftSpanUpperBounds(); if (has_span_constraint) { @@ -2248,7 +2297,7 @@ void RoutingModel::CloseModelWithParameters( std::vector total_slacks(vehicles(), nullptr); // Generate variables only where needed. for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { - if (span_ubs[vehicle] < kint64max) { + if (span_ubs[vehicle] < std::numeric_limits::max()) { spans[vehicle] = solver_->MakeIntVar(0, span_ubs[vehicle], ""); } if (span_costs[vehicle] != 0) { @@ -2280,12 +2329,13 @@ void RoutingModel::CloseModelWithParameters( for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { if (!spans[vehicle] && !total_slacks[vehicle]) continue; if (spans[vehicle]) { - AddVariableTargetToFinalizer(spans[vehicle], kint64min); + AddVariableTargetToFinalizer(spans[vehicle], + std::numeric_limits::min()); } AddVariableTargetToFinalizer(dimension->CumulVar(End(vehicle)), - kint64min); + std::numeric_limits::min()); AddVariableTargetToFinalizer(dimension->CumulVar(Start(vehicle)), - kint64max); + std::numeric_limits::max()); } // Add costs of variables. for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { @@ -2306,7 +2356,9 @@ void RoutingModel::CloseModelWithParameters( for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { const auto bound_cost = dimension->GetSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.cost == 0 || bound_cost.bound == kint64max) continue; + if (bound_cost.cost == 0 || + bound_cost.bound == std::numeric_limits::max()) + continue; DCHECK(spans[vehicle] != nullptr); // Additional cost is vehicle_cost_considered_[vehicle] * // max(0, spans[vehicle] - bound_cost.bound) * bound_cost.cost. @@ -2329,7 +2381,9 @@ void RoutingModel::CloseModelWithParameters( for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { const auto bound_cost = dimension->GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.cost == 0 || bound_cost.bound == kint64max) continue; + if (bound_cost.cost == 0 || + bound_cost.bound == std::numeric_limits::max()) + continue; DCHECK(spans[vehicle] != nullptr); // Additional cost is vehicle_cost_considered_[vehicle] * // max(0, spans[vehicle] - bound_cost.bound)^2 * bound_cost.cost. @@ -2423,8 +2477,8 @@ void RoutingModel::CloseModelWithParameters( // Dimension node precedences. for (const RoutingDimension::NodePrecedence& node_precedence : dimension->GetNodePrecedences()) { - const int64 first_node = node_precedence.first_node; - const int64 second_node = node_precedence.second_node; + const int64_t first_node = node_precedence.first_node; + const int64_t second_node = node_precedence.second_node; IntExpr* const nodes_are_selected = solver_->MakeMin(active_[first_node], active_[second_node]); IntExpr* const cumul_difference = solver_->MakeDifference( @@ -2458,652 +2512,6 @@ void RoutingModel::CloseModelWithParameters( SetupSearch(parameters); } -struct Link { - Link(std::pair link, double value, int vehicle_class, - int64 start_depot, int64 end_depot) - : link(link), - value(value), - vehicle_class(vehicle_class), - start_depot(start_depot), - end_depot(end_depot) {} - ~Link() {} - - std::pair link; - int64 value; - int vehicle_class; - int64 start_depot; - int64 end_depot; -}; - -struct LinkSort { - bool operator()(const Link& link1, const Link& link2) const { - return (link1.value > link2.value); - } -} LinkComparator; - -// The RouteConstructor creates the routes of a VRP instance subject to its -// constraints by iterating on a list of arcs appearing in descending order -// of priority. -// TODO(user): Use the dimension class in this class. -// TODO(user): Add support for vehicle-dependent dimension transits. -class RouteConstructor { - public: - RouteConstructor(Assignment* const assignment, RoutingModel* const model, - bool check_assignment, int64 num_indices, - const std::vector& links_list) - : assignment_(assignment), - model_(model), - check_assignment_(check_assignment), - solver_(model_->solver()), - num_indices_(num_indices), - links_list_(links_list), - nexts_(model_->Nexts()), - in_route_(num_indices_, -1), - final_routes_(), - index_to_chain_index_(num_indices, -1), - index_to_vehicle_class_index_(num_indices, -1) { - { - const std::vector dimension_names = - model_->GetAllDimensionNames(); - dimensions_.assign(dimension_names.size(), nullptr); - for (int i = 0; i < dimension_names.size(); ++i) { - dimensions_[i] = &model_->GetDimensionOrDie(dimension_names[i]); - } - } - cumuls_.resize(dimensions_.size()); - for (std::vector& cumuls : cumuls_) { - cumuls.resize(num_indices_); - } - new_possible_cumuls_.resize(dimensions_.size()); - } - - ~RouteConstructor() {} - - void Construct() { - model_->solver()->TopPeriodicCheck(); - // Initial State: Each order is served by its own vehicle. - for (int index = 0; index < num_indices_; ++index) { - if (!model_->IsStart(index) && !model_->IsEnd(index)) { - std::vector route(1, index); - routes_.push_back(route); - in_route_[index] = routes_.size() - 1; - } - } - - for (const Link& link : links_list_) { - model_->solver()->TopPeriodicCheck(); - const int index1 = link.link.first; - const int index2 = link.link.second; - const int vehicle_class = link.vehicle_class; - const int64 start_depot = link.start_depot; - const int64 end_depot = link.end_depot; - - // Initialisation of cumuls_ if the indices are encountered for first time - if (index_to_vehicle_class_index_[index1] < 0) { - for (int dimension_index = 0; dimension_index < dimensions_.size(); - ++dimension_index) { - cumuls_[dimension_index][index1] = - std::max(dimensions_[dimension_index]->GetTransitValue( - start_depot, index1, 0), - dimensions_[dimension_index]->CumulVar(index1)->Min()); - } - } - if (index_to_vehicle_class_index_[index2] < 0) { - for (int dimension_index = 0; dimension_index < dimensions_.size(); - ++dimension_index) { - cumuls_[dimension_index][index2] = - std::max(dimensions_[dimension_index]->GetTransitValue( - start_depot, index2, 0), - dimensions_[dimension_index]->CumulVar(index2)->Min()); - } - } - - const int route_index1 = in_route_[index1]; - const int route_index2 = in_route_[index2]; - const bool merge = - route_index1 >= 0 && route_index2 >= 0 && - FeasibleMerge(routes_[route_index1], routes_[route_index2], index1, - index2, route_index1, route_index2, vehicle_class, - start_depot, end_depot); - if (Merge(merge, route_index1, route_index2)) { - index_to_vehicle_class_index_[index1] = vehicle_class; - index_to_vehicle_class_index_[index2] = vehicle_class; - } - } - - model_->solver()->TopPeriodicCheck(); - // Beyond this point not checking limits anymore as the rest of the code is - // linear and that given we managed to build a solution would be stupid to - // drop it now. - for (int chain_index = 0; chain_index < chains_.size(); ++chain_index) { - if (!gtl::ContainsKey(deleted_chains_, chain_index)) { - final_chains_.push_back(chains_[chain_index]); - } - } - std::sort(final_chains_.begin(), final_chains_.end(), ChainComparator); - for (int route_index = 0; route_index < routes_.size(); ++route_index) { - if (!gtl::ContainsKey(deleted_routes_, route_index)) { - final_routes_.push_back(routes_[route_index]); - } - } - std::sort(final_routes_.begin(), final_routes_.end(), RouteComparator); - - const int extra_vehicles = std::max( - 0, static_cast(final_chains_.size()) - model_->vehicles()); - // Bind the Start and End of each chain - int chain_index = 0; - for (chain_index = extra_vehicles; chain_index < final_chains_.size(); - ++chain_index) { - if (chain_index - extra_vehicles >= model_->vehicles()) { - break; - } - const int start = final_chains_[chain_index].head; - const int end = final_chains_[chain_index].tail; - assignment_->Add( - model_->NextVar(model_->Start(chain_index - extra_vehicles))); - assignment_->SetValue( - model_->NextVar(model_->Start(chain_index - extra_vehicles)), start); - assignment_->Add(nexts_[end]); - assignment_->SetValue(nexts_[end], - model_->End(chain_index - extra_vehicles)); - } - - // Create the single order routes - for (int route_index = 0; route_index < final_routes_.size(); - ++route_index) { - if (chain_index - extra_vehicles >= model_->vehicles()) { - break; - } - DCHECK_LT(route_index, final_routes_.size()); - const int head = final_routes_[route_index].front(); - const int tail = final_routes_[route_index].back(); - if (head == tail && head < model_->Size()) { - assignment_->Add( - model_->NextVar(model_->Start(chain_index - extra_vehicles))); - assignment_->SetValue( - model_->NextVar(model_->Start(chain_index - extra_vehicles)), head); - assignment_->Add(nexts_[tail]); - assignment_->SetValue(nexts_[tail], - model_->End(chain_index - extra_vehicles)); - ++chain_index; - } - } - - // Unperformed - for (int index = 0; index < model_->Size(); ++index) { - IntVar* const next = nexts_[index]; - if (!assignment_->Contains(next)) { - assignment_->Add(next); - if (next->Contains(index)) { - assignment_->SetValue(next, index); - } - } - } - } - - const std::vector>& final_routes() const { - return final_routes_; - } - - private: - enum MergeStatus { FIRST_SECOND, SECOND_FIRST, NO_MERGE }; - - struct RouteSort { - bool operator()(const std::vector& route1, - const std::vector& route2) const { - return (route1.size() < route2.size()); - } - } RouteComparator; - - struct Chain { - int head; - int tail; - int nodes; - }; - - struct ChainSort { - bool operator()(const Chain& chain1, const Chain& chain2) const { - return (chain1.nodes < chain2.nodes); - } - } ChainComparator; - - bool Head(int node) const { - return (node == routes_[in_route_[node]].front()); - } - - bool Tail(int node) const { - return (node == routes_[in_route_[node]].back()); - } - - bool FeasibleRoute(const std::vector& route, int64 route_cumul, - int dimension_index) { - const RoutingDimension& dimension = *dimensions_[dimension_index]; - std::vector::const_iterator it = route.begin(); - int64 cumul = route_cumul; - while (it != route.end()) { - const int previous = *it; - const int64 cumul_previous = cumul; - gtl::InsertOrDie(&(new_possible_cumuls_[dimension_index]), previous, - cumul_previous); - ++it; - if (it == route.end()) { - return true; - } - const int next = *it; - int64 available_from_previous = - cumul_previous + dimension.GetTransitValue(previous, next, 0); - int64 available_cumul_next = - std::max(cumuls_[dimension_index][next], available_from_previous); - - const int64 slack = available_cumul_next - available_from_previous; - if (slack > dimension.SlackVar(previous)->Max()) { - available_cumul_next = - available_from_previous + dimension.SlackVar(previous)->Max(); - } - - if (available_cumul_next > dimension.CumulVar(next)->Max()) { - return false; - } - if (available_cumul_next <= cumuls_[dimension_index][next]) { - return true; - } - cumul = available_cumul_next; - } - return true; - } - - bool CheckRouteConnection(const std::vector& route1, - const std::vector& route2, int dimension_index, - int64 start_depot, int64 end_depot) { - const int tail1 = route1.back(); - const int head2 = route2.front(); - const int tail2 = route2.back(); - const RoutingDimension& dimension = *dimensions_[dimension_index]; - int non_depot_node = -1; - for (int node = 0; node < num_indices_; ++node) { - if (!model_->IsStart(node) && !model_->IsEnd(node)) { - non_depot_node = node; - break; - } - } - CHECK_GE(non_depot_node, 0); - const int64 depot_threshold = - std::max(dimension.SlackVar(non_depot_node)->Max(), - dimension.CumulVar(non_depot_node)->Max()); - - int64 available_from_tail1 = cumuls_[dimension_index][tail1] + - dimension.GetTransitValue(tail1, head2, 0); - int64 new_available_cumul_head2 = - std::max(cumuls_[dimension_index][head2], available_from_tail1); - - const int64 slack = new_available_cumul_head2 - available_from_tail1; - if (slack > dimension.SlackVar(tail1)->Max()) { - new_available_cumul_head2 = - available_from_tail1 + dimension.SlackVar(tail1)->Max(); - } - - bool feasible_route = true; - if (new_available_cumul_head2 > dimension.CumulVar(head2)->Max()) { - return false; - } - if (new_available_cumul_head2 <= cumuls_[dimension_index][head2]) { - return true; - } - - feasible_route = - FeasibleRoute(route2, new_available_cumul_head2, dimension_index); - const int64 new_possible_cumul_tail2 = - gtl::ContainsKey(new_possible_cumuls_[dimension_index], tail2) - ? new_possible_cumuls_[dimension_index][tail2] - : cumuls_[dimension_index][tail2]; - - if (!feasible_route || (new_possible_cumul_tail2 + - dimension.GetTransitValue(tail2, end_depot, 0) > - depot_threshold)) { - return false; - } - return true; - } - - bool FeasibleMerge(const std::vector& route1, - const std::vector& route2, int node1, int node2, - int route_index1, int route_index2, int vehicle_class, - int64 start_depot, int64 end_depot) { - if ((route_index1 == route_index2) || !(Tail(node1) && Head(node2))) { - return false; - } - - // Vehicle Class Check - if (!((index_to_vehicle_class_index_[node1] == -1 && - index_to_vehicle_class_index_[node2] == -1) || - (index_to_vehicle_class_index_[node1] == vehicle_class && - index_to_vehicle_class_index_[node2] == -1) || - (index_to_vehicle_class_index_[node1] == -1 && - index_to_vehicle_class_index_[node2] == vehicle_class) || - (index_to_vehicle_class_index_[node1] == vehicle_class && - index_to_vehicle_class_index_[node2] == vehicle_class))) { - return false; - } - - // Check Route1 -> Route2 connection for every dimension - bool merge = true; - for (int dimension_index = 0; dimension_index < dimensions_.size(); - ++dimension_index) { - new_possible_cumuls_[dimension_index].clear(); - merge = merge && CheckRouteConnection(route1, route2, dimension_index, - start_depot, end_depot); - if (!merge) { - return false; - } - } - return true; - } - - bool CheckTempAssignment(Assignment* const temp_assignment, - int new_chain_index, int old_chain_index, int head1, - int tail1, int head2, int tail2) { - // TODO(user): If the chain index is greater than the number of vehicles, - // use another vehicle instead. - if (new_chain_index >= model_->vehicles()) return false; - const int start = head1; - temp_assignment->Add(model_->NextVar(model_->Start(new_chain_index))); - temp_assignment->SetValue(model_->NextVar(model_->Start(new_chain_index)), - start); - temp_assignment->Add(nexts_[tail1]); - temp_assignment->SetValue(nexts_[tail1], head2); - temp_assignment->Add(nexts_[tail2]); - temp_assignment->SetValue(nexts_[tail2], model_->End(new_chain_index)); - for (int chain_index = 0; chain_index < chains_.size(); ++chain_index) { - if ((chain_index != new_chain_index) && - (chain_index != old_chain_index) && - (!gtl::ContainsKey(deleted_chains_, chain_index))) { - const int start = chains_[chain_index].head; - const int end = chains_[chain_index].tail; - temp_assignment->Add(model_->NextVar(model_->Start(chain_index))); - temp_assignment->SetValue(model_->NextVar(model_->Start(chain_index)), - start); - temp_assignment->Add(nexts_[end]); - temp_assignment->SetValue(nexts_[end], model_->End(chain_index)); - } - } - return solver_->Solve(solver_->MakeRestoreAssignment(temp_assignment)); - } - - bool UpdateAssignment(const std::vector& route1, - const std::vector& route2) { - bool feasible = true; - const int head1 = route1.front(); - const int tail1 = route1.back(); - const int head2 = route2.front(); - const int tail2 = route2.back(); - const int chain_index1 = index_to_chain_index_[head1]; - const int chain_index2 = index_to_chain_index_[head2]; - if (chain_index1 < 0 && chain_index2 < 0) { - const int chain_index = chains_.size(); - if (check_assignment_) { - Assignment* const temp_assignment = - solver_->MakeAssignment(assignment_); - feasible = CheckTempAssignment(temp_assignment, chain_index, -1, head1, - tail1, head2, tail2); - } - if (feasible) { - Chain chain; - chain.head = head1; - chain.tail = tail2; - chain.nodes = 2; - index_to_chain_index_[head1] = chain_index; - index_to_chain_index_[tail2] = chain_index; - chains_.push_back(chain); - } - } else if (chain_index1 >= 0 && chain_index2 < 0) { - if (check_assignment_) { - Assignment* const temp_assignment = - solver_->MakeAssignment(assignment_); - feasible = - CheckTempAssignment(temp_assignment, chain_index1, chain_index2, - head1, tail1, head2, tail2); - } - if (feasible) { - index_to_chain_index_[tail2] = chain_index1; - chains_[chain_index1].head = head1; - chains_[chain_index1].tail = tail2; - ++chains_[chain_index1].nodes; - } - } else if (chain_index1 < 0 && chain_index2 >= 0) { - if (check_assignment_) { - Assignment* const temp_assignment = - solver_->MakeAssignment(assignment_); - feasible = - CheckTempAssignment(temp_assignment, chain_index2, chain_index1, - head1, tail1, head2, tail2); - } - if (feasible) { - index_to_chain_index_[head1] = chain_index2; - chains_[chain_index2].head = head1; - chains_[chain_index2].tail = tail2; - ++chains_[chain_index2].nodes; - } - } else { - if (check_assignment_) { - Assignment* const temp_assignment = - solver_->MakeAssignment(assignment_); - feasible = - CheckTempAssignment(temp_assignment, chain_index1, chain_index2, - head1, tail1, head2, tail2); - } - if (feasible) { - index_to_chain_index_[tail2] = chain_index1; - chains_[chain_index1].head = head1; - chains_[chain_index1].tail = tail2; - chains_[chain_index1].nodes += chains_[chain_index2].nodes; - deleted_chains_.insert(chain_index2); - } - } - if (feasible) { - assignment_->Add(nexts_[tail1]); - assignment_->SetValue(nexts_[tail1], head2); - } - return feasible; - } - - bool Merge(bool merge, int index1, int index2) { - if (merge) { - if (UpdateAssignment(routes_[index1], routes_[index2])) { - // Connection Route1 -> Route2 - for (const int node : routes_[index2]) { - in_route_[node] = index1; - routes_[index1].push_back(node); - } - for (int dimension_index = 0; dimension_index < dimensions_.size(); - ++dimension_index) { - for (const std::pair new_possible_cumul : - new_possible_cumuls_[dimension_index]) { - cumuls_[dimension_index][new_possible_cumul.first] = - new_possible_cumul.second; - } - } - deleted_routes_.insert(index2); - return true; - } - } - return false; - } - - Assignment* const assignment_; - RoutingModel* const model_; - const bool check_assignment_; - Solver* const solver_; - const int64 num_indices_; - const std::vector links_list_; - std::vector nexts_; - std::vector dimensions_; // Not owned. - std::vector> cumuls_; - std::vector> new_possible_cumuls_; - std::vector> routes_; - std::vector in_route_; - absl::flat_hash_set deleted_routes_; - std::vector> final_routes_; - std::vector chains_; - absl::flat_hash_set deleted_chains_; - std::vector final_chains_; - std::vector index_to_chain_index_; - std::vector index_to_vehicle_class_index_; -}; - -#ifndef SWIG -struct SweepIndex { - SweepIndex(const int64 index, const double angle, const double distance) - : index(index), angle(angle), distance(distance) {} - ~SweepIndex() {} - - int64 index; - double angle; - double distance; -}; - -struct SweepIndexSortAngle { - bool operator()(const SweepIndex& node1, const SweepIndex& node2) const { - return (node1.angle < node2.angle); - } -} SweepIndexAngleComparator; - -struct SweepIndexSortDistance { - bool operator()(const SweepIndex& node1, const SweepIndex& node2) const { - return (node1.distance < node2.distance); - } -} SweepIndexDistanceComparator; - -SweepArranger::SweepArranger(const std::vector>& points) - : coordinates_(2 * points.size(), 0), sectors_(1) { - for (int64 i = 0; i < points.size(); ++i) { - coordinates_[2 * i] = points[i].first; - coordinates_[2 * i + 1] = points[i].second; - } -} - -// Splits the space of the indices into sectors and sorts the indices of each -// sector with ascending angle from the depot. -void SweepArranger::ArrangeIndices(std::vector* indices) { - const double pi_rad = 3.14159265; - // Suppose that the center is at x0, y0. - const int x0 = coordinates_[0]; - const int y0 = coordinates_[1]; - - std::vector sweep_indices; - for (int64 index = 0; index < static_cast(coordinates_.size()) / 2; - ++index) { - const int x = coordinates_[2 * index]; - const int y = coordinates_[2 * index + 1]; - const double x_delta = x - x0; - const double y_delta = y - y0; - double square_distance = x_delta * x_delta + y_delta * y_delta; - double angle = square_distance == 0 ? 0 : std::atan2(y_delta, x_delta); - angle = angle >= 0 ? angle : 2 * pi_rad + angle; - SweepIndex sweep_index(index, angle, square_distance); - sweep_indices.push_back(sweep_index); - } - std::sort(sweep_indices.begin(), sweep_indices.end(), - SweepIndexDistanceComparator); - - const int size = static_cast(sweep_indices.size()) / sectors_; - for (int sector = 0; sector < sectors_; ++sector) { - std::vector cluster; - std::vector::iterator begin = - sweep_indices.begin() + sector * size; - std::vector::iterator end = - sector == sectors_ - 1 ? sweep_indices.end() - : sweep_indices.begin() + (sector + 1) * size; - std::sort(begin, end, SweepIndexAngleComparator); - } - for (const SweepIndex& sweep_index : sweep_indices) { - indices->push_back(sweep_index.index); - } -} - -// Decision Builder building a first solution based on Sweep heuristic for -// Vehicle Routing Problem. -// Suitable only when distance is considered as the cost. -class SweepBuilder : public DecisionBuilder { - public: - SweepBuilder(RoutingModel* const model, bool check_assignment) - : model_(model), check_assignment_(check_assignment) {} - ~SweepBuilder() override {} - - Decision* Next(Solver* const solver) override { - // Setup the model of the instance for the Sweep Algorithm - ModelSetup(); - - // Build the assignment routes for the model - Assignment* const assignment = solver->MakeAssignment(); - route_constructor_ = absl::make_unique( - assignment, model_, check_assignment_, num_indices_, links_); - // This call might cause backtracking if the search limit is reached. - route_constructor_->Construct(); - route_constructor_.reset(nullptr); - // This call might cause backtracking if the solution is not feasible. - assignment->Restore(); - - return nullptr; - } - - private: - void ModelSetup() { - const int depot = model_->GetDepot(); - num_indices_ = model_->Size() + model_->vehicles(); - if (absl::GetFlag(FLAGS_sweep_sectors) > 0 && - absl::GetFlag(FLAGS_sweep_sectors) < num_indices_) { - model_->sweep_arranger()->SetSectors(absl::GetFlag(FLAGS_sweep_sectors)); - } - std::vector indices; - model_->sweep_arranger()->ArrangeIndices(&indices); - for (int i = 0; i < indices.size() - 1; ++i) { - const int64 first = indices[i]; - const int64 second = indices[i + 1]; - if ((model_->IsStart(first) || !model_->IsEnd(first)) && - (model_->IsStart(second) || !model_->IsEnd(second))) { - if (first != depot && second != depot) { - Link link(std::make_pair(first, second), 0, 0, depot, depot); - links_.push_back(link); - } - } - } - } - - RoutingModel* const model_; - std::unique_ptr route_constructor_; - const bool check_assignment_; - int64 num_indices_; - std::vector links_; -}; -#endif - -namespace { -// Decision builder to build a solution with all nodes inactive. It does no -// branching and may fail if some nodes cannot be made inactive. - -class AllUnperformed : public DecisionBuilder { - public: - // Does not take ownership of model. - explicit AllUnperformed(RoutingModel* const model) : model_(model) {} - ~AllUnperformed() override {} - Decision* Next(Solver* const solver) override { - // Solver::(Un)FreezeQueue is private, passing through the public API - // on PropagationBaseObject. - model_->CostVar()->FreezeQueue(); - for (int i = 0; i < model_->Size(); ++i) { - if (!model_->IsStart(i)) { - model_->ActiveVar(i)->SetValue(0); - } - } - model_->CostVar()->UnfreezeQueue(); - return nullptr; - } - - private: - RoutingModel* const model_; -}; -} // namespace - void RoutingModel::AddSearchMonitor(SearchMonitor* const monitor) { monitors_.push_back(monitor); } @@ -3153,7 +2561,8 @@ absl::Duration GetLnsTimeLimit(const RoutingSearchParameters& parameters) { } // namespace namespace { -void MakeAllUnperformed(const RoutingModel* model, Assignment* assignment) { +void MakeAllUnperformedInAssignment(const RoutingModel* model, + Assignment* assignment) { assignment->Clear(); for (int i = 0; i < model->Nexts().size(); ++i) { if (!model->IsStart(i)) { @@ -3183,7 +2592,7 @@ bool RoutingModel::AppendAssignmentIfFeasible( void RoutingModel::LogSolution(const RoutingSearchParameters& parameters, const std::string& description, - int64 solution_cost, int64 start_time_ms) { + int64_t solution_cost, int64_t start_time_ms) { const std::string memory_str = MemoryUsage(); const double cost_scaling_factor = parameters.log_cost_scaling_factor(); const double cost_offset = parameters.log_cost_offset(); @@ -3201,18 +2610,42 @@ void RoutingModel::LogSolution(const RoutingSearchParameters& parameters, const Assignment* RoutingModel::SolveFromAssignmentWithParameters( const Assignment* assignment, const RoutingSearchParameters& parameters, std::vector* solutions) { - const int64 start_time_ms = solver_->wall_time(); + return SolveFromAssignmentsWithParameters({assignment}, parameters, + solutions); +} + +const Assignment* RoutingModel::SolveFromAssignmentsWithParameters( + const std::vector& assignments, + const RoutingSearchParameters& parameters, + std::vector* solutions) { + const int64_t start_time_ms = solver_->wall_time(); QuietCloseModelWithParameters(parameters); VLOG(1) << "Search parameters:\n" << parameters.DebugString(); if (solutions != nullptr) solutions->clear(); if (status_ == ROUTING_INVALID) { return nullptr; } - limit_->UpdateLimits(GetTimeLimit(parameters), kint64max, kint64max, - parameters.solution_limit()); - ls_limit_->UpdateLimits(GetTimeLimit(parameters), kint64max, kint64max, 1); - lns_limit_->UpdateLimits(GetLnsTimeLimit(parameters), kint64max, kint64max, - kint64max); + const auto update_time_limits = [this, start_time_ms, ¶meters]() { + const absl::Duration elapsed_time = + absl::Milliseconds(solver_->wall_time() - start_time_ms); + const absl::Duration time_left = GetTimeLimit(parameters) - elapsed_time; + if (time_left >= absl::ZeroDuration()) { + limit_->UpdateLimits(time_left, std::numeric_limits::max(), + std::numeric_limits::max(), + parameters.solution_limit()); + ls_limit_->UpdateLimits(time_left, std::numeric_limits::max(), + std::numeric_limits::max(), 1); + return true; + } + return false; + }; + if (!update_time_limits()) { + status_ = ROUTING_FAIL_TIMEOUT; + return nullptr; + } + lns_limit_->UpdateLimits( + GetLnsTimeLimit(parameters), std::numeric_limits::max(), + std::numeric_limits::max(), std::numeric_limits::max()); // NOTE: Allow more time for the first solution's scheduling, since if it // fails, we won't have anything to build upon. // We set this time limit based on whether local/global dimension optimizers @@ -3223,12 +2656,17 @@ const Assignment* RoutingModel::SolveFromAssignmentWithParameters( const absl::Duration first_solution_lns_time_limit = std::max(GetTimeLimit(parameters) / time_limit_shares, GetLnsTimeLimit(parameters)); - first_solution_lns_limit_->UpdateLimits(first_solution_lns_time_limit, - kint64max, kint64max, kint64max); + first_solution_lns_limit_->UpdateLimits( + first_solution_lns_time_limit, std::numeric_limits::max(), + std::numeric_limits::max(), std::numeric_limits::max()); std::vector> solution_pool; + std::vector first_solution_assignments; + for (const Assignment* assignment : assignments) { + if (assignment != nullptr) first_solution_assignments.push_back(assignment); + } if (parameters.use_cp() == BOOL_TRUE) { - if (nullptr == assignment) { + if (first_solution_assignments.empty()) { bool solution_found = false; Assignment matching(solver_.get()); if (IsMatchingModel() && SolveMatchingModel(&matching, parameters) && @@ -3243,26 +2681,25 @@ const Assignment* RoutingModel::SolveFromAssignmentWithParameters( // Build trivial solutions to which we can come back too in case the // solver does not manage to build something better. Assignment unperformed(solver_.get()); - MakeAllUnperformed(this, &unperformed); + MakeAllUnperformedInAssignment(this, &unperformed); if (AppendAssignmentIfFeasible(unperformed, &solution_pool) && parameters.log_search()) { LogSolution(parameters, "All Unperformed Solution", solution_pool.back()->ObjectiveValue(), start_time_ms); } - const absl::Duration elapsed_time = - absl::Milliseconds(solver_->wall_time() - start_time_ms); - const absl::Duration time_left = - GetTimeLimit(parameters) - elapsed_time; - if (time_left >= absl::ZeroDuration()) { - limit_->UpdateLimits(time_left, kint64max, kint64max, - parameters.solution_limit()); - ls_limit_->UpdateLimits(time_left, kint64max, kint64max, 1); + if (update_time_limits()) { solver_->Solve(solve_db_, monitors_); } } } else { - assignment_->CopyIntersection(assignment); - solver_->Solve(improve_db_, monitors_); + for (const Assignment* assignment : first_solution_assignments) { + assignment_->CopyIntersection(assignment); + solver_->Solve(improve_db_, monitors_); + if (collect_assignments_->solution_count() >= 1 || + !update_time_limits()) { + break; + } + } } } @@ -3356,7 +2793,7 @@ void RoutingModel::SetAssignmentFromOtherModelAssignment( // This is a lower bound given the solution to assignment problem does not // necessarily produce a (set of) closed route(s) from a starting node to an // ending node. -int64 RoutingModel::ComputeLowerBound() { +int64_t RoutingModel::ComputeLowerBound() { if (!closed_) { LOG(WARNING) << "Non-closed model not supported."; return 0; @@ -3379,7 +2816,7 @@ int64 RoutingModel::ComputeLowerBound() { for (int tail = 0; tail < Size(); ++tail) { std::unique_ptr iterator( nexts_[tail]->MakeDomainIterator(false)); - for (const int64 head : InitAndGetValues(iterator.get())) { + for (const int64_t head : InitAndGetValues(iterator.get())) { // Given there are no disjunction constraints, a node cannot point to // itself. Doing this explicitly given that outside the search, // propagation hasn't removed this value from next variables yet. @@ -3472,9 +2909,9 @@ bool RoutingModel::ReplaceUnusedVehicle( return false; } if (contains_unused_vehicle_transit_var) { - const int64 old_unused_vehicle_transit = + const int64_t old_unused_vehicle_transit = compact_assignment->Value(unused_vehicle_transit_var); - const int64 old_active_vehicle_transit = + const int64_t old_active_vehicle_transit = compact_assignment->Value(active_vehicle_transit_var); compact_assignment->SetValue(unused_vehicle_transit_var, old_active_vehicle_transit); @@ -3488,9 +2925,9 @@ bool RoutingModel::ReplaceUnusedVehicle( cumul_variables[unused_vehicle_end]; IntVar* const active_vehicle_cumul_var = cumul_variables[active_vehicle_end]; - const int64 old_unused_vehicle_cumul = + const int64_t old_unused_vehicle_cumul = compact_assignment->Value(unused_vehicle_cumul_var); - const int64 old_active_vehicle_cumul = + const int64_t old_active_vehicle_cumul = compact_assignment->Value(active_vehicle_cumul_var); compact_assignment->SetValue(unused_vehicle_cumul_var, old_active_vehicle_cumul); @@ -3581,7 +3018,7 @@ Assignment* RoutingModel::CompactAssignmentInternal( } int RoutingModel::FindNextActive(int index, - const std::vector& indices) const { + const std::vector& indices) const { ++index; CHECK_LE(0, index); const int size = indices.size(); @@ -3591,7 +3028,7 @@ int RoutingModel::FindNextActive(int index, return index; } -IntVar* RoutingModel::ApplyLocks(const std::vector& locks) { +IntVar* RoutingModel::ApplyLocks(const std::vector& locks) { // TODO(user): Replace calls to this method with calls to // ApplyLocksToAllVehicles and remove this method? CHECK_EQ(vehicles_, 1); @@ -3613,12 +3050,12 @@ IntVar* RoutingModel::ApplyLocks(const std::vector& locks) { } bool RoutingModel::ApplyLocksToAllVehicles( - const std::vector>& locks, bool close_routes) { + const std::vector>& locks, bool close_routes) { preassignment_->Clear(); return RoutesToAssignment(locks, true, close_routes, preassignment_); } -int64 RoutingModel::GetNumberOfDecisionsInFirstSolution( +int64_t RoutingModel::GetNumberOfDecisionsInFirstSolution( const RoutingSearchParameters& parameters) const { IntVarFilteredDecisionBuilder* const decision_builder = GetFilteredFirstSolutionDecisionBuilderOrNull(parameters); @@ -3626,7 +3063,7 @@ int64 RoutingModel::GetNumberOfDecisionsInFirstSolution( : 0; } -int64 RoutingModel::GetNumberOfRejectsInFirstSolution( +int64_t RoutingModel::GetNumberOfRejectsInFirstSolution( const RoutingSearchParameters& parameters) const { IntVarFilteredDecisionBuilder* const decision_builder = GetFilteredFirstSolutionDecisionBuilderOrNull(parameters); @@ -3675,8 +3112,9 @@ Assignment* RoutingModel::DoRestoreAssignment() { } bool RoutingModel::RoutesToAssignment( - const std::vector>& routes, bool ignore_inactive_indices, - bool close_routes, Assignment* const assignment) const { + const std::vector>& routes, + bool ignore_inactive_indices, bool close_routes, + Assignment* const assignment) const { CHECK(assignment != nullptr); if (!closed_) { LOG(ERROR) << "The model is not closed yet"; @@ -3693,7 +3131,7 @@ bool RoutingModel::RoutesToAssignment( absl::flat_hash_set visited_indices; // Set value to NextVars based on the routes. for (int vehicle = 0; vehicle < num_routes; ++vehicle) { - const std::vector& route = routes[vehicle]; + const std::vector& route = routes[vehicle]; int from_index = Start(vehicle); std::pair::iterator, bool> insert_result = visited_indices.insert(from_index); @@ -3703,7 +3141,7 @@ bool RoutingModel::RoutesToAssignment( return false; } - for (const int64 to_index : route) { + for (const int64_t to_index : route) { if (to_index < 0 || to_index >= Size()) { LOG(ERROR) << "Invalid index: " << to_index; return false; @@ -3787,7 +3225,7 @@ bool RoutingModel::RoutesToAssignment( } Assignment* RoutingModel::ReadAssignmentFromRoutes( - const std::vector>& routes, + const std::vector>& routes, bool ignore_inactive_indices) { QuietCloseModel(); if (!RoutesToAssignment(routes, ignore_inactive_indices, true, assignment_)) { @@ -3801,14 +3239,14 @@ Assignment* RoutingModel::ReadAssignmentFromRoutes( void RoutingModel::AssignmentToRoutes( const Assignment& assignment, - std::vector>* const routes) const { + std::vector>* const routes) const { CHECK(closed_); CHECK(routes != nullptr); const int model_size = Size(); routes->resize(vehicles_); for (int vehicle = 0; vehicle < vehicles_; ++vehicle) { - std::vector* const vehicle_route = &routes->at(vehicle); + std::vector* const vehicle_route = &routes->at(vehicle); vehicle_route->clear(); int num_visited_indices = 0; @@ -3833,9 +3271,9 @@ void RoutingModel::AssignmentToRoutes( } #ifndef SWIG -std::vector> RoutingModel::GetRoutesFromAssignment( +std::vector> RoutingModel::GetRoutesFromAssignment( const Assignment& assignment) { - std::vector> route_indices(vehicles()); + std::vector> route_indices(vehicles()); for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { if (!assignment.Bound(NextVar(vehicle))) { LOG(DFATAL) << "GetRoutesFromAssignment() called on incomplete solution:" @@ -3843,7 +3281,7 @@ std::vector> RoutingModel::GetRoutesFromAssignment( } } for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { - int64 index = Start(vehicle); + int64_t index = Start(vehicle); route_indices[vehicle].push_back(index); while (!IsEnd(index)) { index = assignment.Value(NextVar(index)); @@ -3854,18 +3292,19 @@ std::vector> RoutingModel::GetRoutesFromAssignment( } #endif -int64 RoutingModel::GetArcCostForClassInternal( - int64 from_index, int64 to_index, CostClassIndex cost_class_index) const { +int64_t RoutingModel::GetArcCostForClassInternal( + int64_t from_index, int64_t to_index, + CostClassIndex cost_class_index) const { DCHECK(closed_); DCHECK_GE(cost_class_index, 0); DCHECK_LT(cost_class_index, cost_classes_.size()); CostCacheElement* const cache = &cost_cache_[from_index]; - // See the comment in CostCacheElement in the .h for the int64->int cast. + // See the comment in CostCacheElement in the .h for the int64_t->int cast. if (cache->index == static_cast(to_index) && cache->cost_class_index == cost_class_index) { return cache->cost; } - int64 cost = 0; + int64_t cost = 0; const CostClass& cost_class = cost_classes_[cost_class_index]; const auto& evaluator = transit_evaluators_[cost_class.evaluator_index]; if (!IsStart(from_index)) { @@ -3893,7 +3332,7 @@ int64 RoutingModel::GetArcCostForClassInternal( return cost; } -bool RoutingModel::IsStart(int64 index) const { +bool RoutingModel::IsStart(int64_t index) const { return !IsEnd(index) && index_to_vehicle_[index] != kUnassigned; } @@ -3907,7 +3346,7 @@ bool RoutingModel::IsVehicleUsed(const Assignment& assignment, return !IsEnd(assignment.Value(start_var)); } -int64 RoutingModel::Next(const Assignment& assignment, int64 index) const { +int64_t RoutingModel::Next(const Assignment& assignment, int64_t index) const { CHECK_EQ(solver_.get(), assignment.solver()); IntVar* const next_var = NextVar(index); CHECK(assignment.Contains(next_var)); @@ -3915,8 +3354,8 @@ int64 RoutingModel::Next(const Assignment& assignment, int64 index) const { return assignment.Value(next_var); } -int64 RoutingModel::GetArcCostForVehicle(int64 from_index, int64 to_index, - int64 vehicle) const { +int64_t RoutingModel::GetArcCostForVehicle(int64_t from_index, int64_t to_index, + int64_t vehicle) const { if (from_index != to_index && vehicle >= 0) { return GetArcCostForClassInternal(from_index, to_index, GetCostClassIndexOfVehicle(vehicle)); @@ -3925,9 +3364,9 @@ int64 RoutingModel::GetArcCostForVehicle(int64 from_index, int64 to_index, } } -int64 RoutingModel::GetArcCostForClass( - int64 from_index, int64 to_index, - int64 /*CostClassIndex*/ cost_class_index) const { +int64_t RoutingModel::GetArcCostForClass( + int64_t from_index, int64_t to_index, + int64_t /*CostClassIndex*/ cost_class_index) const { if (from_index != to_index) { return GetArcCostForClassInternal(from_index, to_index, CostClassIndex(cost_class_index)); @@ -3936,8 +3375,8 @@ int64 RoutingModel::GetArcCostForClass( } } -int64 RoutingModel::GetArcCostForFirstSolution(int64 from_index, - int64 to_index) const { +int64_t RoutingModel::GetArcCostForFirstSolution(int64_t from_index, + int64_t to_index) const { // Return high cost if connecting to an end (or bound-to-end) node; // this is used in the cost-based first solution strategies to avoid closing // routes too soon. @@ -3949,14 +3388,15 @@ int64 RoutingModel::GetArcCostForFirstSolution(int64 from_index, nexts_, active_, is_bound_to_end_, zero_transit)); is_bound_to_end_ct_added_.Switch(solver_.get()); } - if (is_bound_to_end_[to_index]->Min() == 1) return kint64max; + if (is_bound_to_end_[to_index]->Min() == 1) + return std::numeric_limits::max(); // TODO(user): Take vehicle into account. return GetHomogeneousCost(from_index, to_index); } -int64 RoutingModel::GetDimensionTransitCostSum( - int64 i, int64 j, const CostClass& cost_class) const { - int64 cost = 0; +int64_t RoutingModel::GetDimensionTransitCostSum( + int64_t i, int64_t j, const CostClass& cost_class) const { + int64_t cost = 0; for (const auto& evaluator_and_coefficient : cost_class.dimension_transit_evaluator_class_and_cost_coefficient) { DCHECK_GT(evaluator_and_coefficient.cost_coefficient, 0); @@ -3969,8 +3409,8 @@ int64 RoutingModel::GetDimensionTransitCostSum( return cost; } -bool RoutingModel::ArcIsMoreConstrainedThanArc(int64 from, int64 to1, - int64 to2) { +bool RoutingModel::ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, + int64_t to2) { // Deal with end nodes: never pick an end node over a non-end node. if (IsEnd(to1) || IsEnd(to2)) { if (IsEnd(to1) != IsEnd(to2)) return IsEnd(to2); @@ -3990,7 +3430,7 @@ bool RoutingModel::ArcIsMoreConstrainedThanArc(int64 from, int64 to1, // In case the source vehicle is bound, "src_vehicle" will be it. // Otherwise, it'll be set to some possible source vehicle that // isn't -1 (if possible). - const int64 src_vehicle = src_vehicle_var->Max(); + const int64_t src_vehicle = src_vehicle_var->Max(); if (src_vehicle_var->Bound()) { IntVar* const to1_vehicle_var = VehicleVar(to1); IntVar* const to2_vehicle_var = VehicleVar(to2); @@ -4006,8 +3446,8 @@ bool RoutingModel::ArcIsMoreConstrainedThanArc(int64 from, int64 to1, if (bound1 != bound2) return bound1; if (bound1) { // same as bound1 && bound2. // Min() will return kNoVehicle for optional nodes. Thus we use Max(). - const int64 vehicle1 = to1_vehicle_var->Max(); - const int64 vehicle2 = to2_vehicle_var->Max(); + const int64_t vehicle1 = to1_vehicle_var->Max(); + const int64_t vehicle2 = to2_vehicle_var->Max(); // Prefer a destination bound to the right vehicle. // TODO(user): cover this clause in a unit test. if ((vehicle1 == src_vehicle) != (vehicle2 == src_vehicle)) { @@ -4042,19 +3482,21 @@ bool RoutingModel::ArcIsMoreConstrainedThanArc(int64 from, int64 to1, // Break ties on equally constrained nodes with the (cost - unperformed // penalty). { - const /*CostClassIndex*/ int64 cost_class_index = + const /*CostClassIndex*/ int64_t cost_class_index = SafeGetCostClassInt64OfVehicle(src_vehicle); - const int64 cost1 = CapSub(GetArcCostForClass(from, to1, cost_class_index), - UnperformedPenalty(to1)); - const int64 cost2 = CapSub(GetArcCostForClass(from, to2, cost_class_index), - UnperformedPenalty(to2)); + const int64_t cost1 = + CapSub(GetArcCostForClass(from, to1, cost_class_index), + UnperformedPenalty(to1)); + const int64_t cost2 = + CapSub(GetArcCostForClass(from, to2, cost_class_index), + UnperformedPenalty(to2)); if (cost1 != cost2) return cost1 < cost2; } // Further break ties by looking at the size of the VehicleVar. { - const int64 num_vehicles1 = VehicleVar(to1)->Size(); - const int64 num_vehicles2 = VehicleVar(to2)->Size(); + const int64_t num_vehicles1 = VehicleVar(to1)->Size(); + const int64_t num_vehicles2 = VehicleVar(to2)->Size(); if (num_vehicles1 != num_vehicles2) return num_vehicles1 < num_vehicles2; } @@ -4062,7 +3504,8 @@ bool RoutingModel::ArcIsMoreConstrainedThanArc(int64 from, int64 to1, return to1 < to2; } -void RoutingModel::SetVisitType(int64 index, int type, VisitTypePolicy policy) { +void RoutingModel::SetVisitType(int64_t index, int type, + VisitTypePolicy policy) { CHECK_LT(index, index_to_visit_type_.size()); DCHECK_EQ(index_to_visit_type_.size(), index_to_type_policy_.size()); index_to_visit_type_[index] = type; @@ -4070,7 +3513,7 @@ void RoutingModel::SetVisitType(int64 index, int type, VisitTypePolicy policy) { num_visit_types_ = std::max(num_visit_types_, type + 1); } -int RoutingModel::GetVisitType(int64 index) const { +int RoutingModel::GetVisitType(int64_t index) const { CHECK_LT(index, index_to_visit_type_.size()); return index_to_visit_type_[index]; } @@ -4086,7 +3529,7 @@ const std::vector& RoutingModel::GetPairIndicesOfType(int type) const { } RoutingModel::VisitTypePolicy RoutingModel::GetVisitTypePolicy( - int64 index) const { + int64_t index) const { CHECK_LT(index, index_to_type_policy_.size()); return index_to_type_policy_[index]; } @@ -4221,13 +3664,14 @@ RoutingModel::GetRequiredTypeAlternativesWhenRemovingType(int type) const { return required_type_alternatives_when_removing_type_index_[type]; } -int64 RoutingModel::UnperformedPenalty(int64 var_index) const { +int64_t RoutingModel::UnperformedPenalty(int64_t var_index) const { return UnperformedPenaltyOrValue(0, var_index); } -int64 RoutingModel::UnperformedPenaltyOrValue(int64 default_value, - int64 var_index) const { - if (active_[var_index]->Min() == 1) return kint64max; // Forced active. +int64_t RoutingModel::UnperformedPenaltyOrValue(int64_t default_value, + int64_t var_index) const { + if (active_[var_index]->Min() == 1) + return std::numeric_limits::max(); // Forced active. const std::vector& disjunction_indices = GetDisjunctionIndices(var_index); if (disjunction_indices.size() != 1) return default_value; @@ -4235,7 +3679,7 @@ int64 RoutingModel::UnperformedPenaltyOrValue(int64 default_value, // The disjunction penalty can be kNoPenalty iff there is more than one node // in the disjunction; otherwise we would have caught it earlier (the node // would be forced active). - return std::max(int64{0}, disjunctions_[disjunction_index].value.penalty); + return std::max(int64_t{0}, disjunctions_[disjunction_index].value.penalty); } std::string RoutingModel::DebugOutputAssignment( @@ -4276,7 +3720,7 @@ std::string RoutingModel::DebugOutputAssignment( } if (vehicle < vehicles()) { absl::StrAppendFormat(&output, "Vehicle %d:", vehicle); - int64 index = Start(vehicle); + int64_t index = Start(vehicle); for (;;) { const IntVar* vehicle_var = VehicleVar(index); absl::StrAppendFormat(&output, "%d Vehicle(%d) ", index, @@ -4311,9 +3755,11 @@ std::string RoutingModel::DebugOutputAssignment( } #ifndef SWIG -std::vector>> RoutingModel::GetCumulBounds( - const Assignment& solution_assignment, const RoutingDimension& dimension) { - std::vector>> cumul_bounds(vehicles()); +std::vector>> +RoutingModel::GetCumulBounds(const Assignment& solution_assignment, + const RoutingDimension& dimension) { + std::vector>> cumul_bounds( + vehicles()); for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { if (!solution_assignment.Bound(NextVar(vehicle))) { LOG(DFATAL) << "GetCumulBounds() called on incomplete solution:" @@ -4322,7 +3768,7 @@ std::vector>> RoutingModel::GetCumulBounds( } for (int vehicle_id = 0; vehicle_id < vehicles(); ++vehicle_id) { - int64 index = Start(vehicle_id); + int64_t index = Start(vehicle_id); IntVar* dim_var = dimension.CumulVar(index); cumul_bounds[vehicle_id].emplace_back(solution_assignment.Min(dim_var), solution_assignment.Max(dim_var)); @@ -4359,26 +3805,30 @@ Assignment* RoutingModel::GetOrCreateTmpAssignment() { RegularLimit* RoutingModel::GetOrCreateLimit() { if (limit_ == nullptr) { - limit_ = solver_->MakeLimit(absl::InfiniteDuration(), kint64max, kint64max, - kint64max, /*smart_time_check=*/true); + limit_ = solver_->MakeLimit( + absl::InfiniteDuration(), std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), /*smart_time_check=*/true); } return limit_; } RegularLimit* RoutingModel::GetOrCreateLocalSearchLimit() { if (ls_limit_ == nullptr) { - ls_limit_ = - solver_->MakeLimit(absl::InfiniteDuration(), kint64max, kint64max, - /*solutions=*/1, /*smart_time_check=*/true); + ls_limit_ = solver_->MakeLimit(absl::InfiniteDuration(), + std::numeric_limits::max(), + std::numeric_limits::max(), + /*solutions=*/1, /*smart_time_check=*/true); } return ls_limit_; } RegularLimit* RoutingModel::GetOrCreateLargeNeighborhoodSearchLimit() { if (lns_limit_ == nullptr) { - lns_limit_ = - solver_->MakeLimit(absl::InfiniteDuration(), kint64max, kint64max, - kint64max, /*smart_time_check=*/false); + lns_limit_ = solver_->MakeLimit( + absl::InfiniteDuration(), std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), /*smart_time_check=*/false); } return lns_limit_; } @@ -4386,9 +3836,10 @@ RegularLimit* RoutingModel::GetOrCreateLargeNeighborhoodSearchLimit() { RegularLimit* RoutingModel::GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit() { if (first_solution_lns_limit_ == nullptr) { - first_solution_lns_limit_ = - solver_->MakeLimit(absl::InfiniteDuration(), kint64max, kint64max, - kint64max, /*smart_time_check=*/false); + first_solution_lns_limit_ = solver_->MakeLimit( + absl::InfiniteDuration(), std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), /*smart_time_check=*/false); } return first_solution_lns_limit_; } @@ -4500,9 +3951,9 @@ void RoutingModel::CreateNeighborhoodOperators( CreatePairOperator(); const auto arc_cost_for_path_start = - [this](int64 before_node, int64 after_node, int64 start_index) { + [this](int64_t before_node, int64_t after_node, int64_t start_index) { const int vehicle = index_to_vehicle_[start_index]; - const int64 arc_cost = + const int64_t arc_cost = GetArcCostForVehicle(before_node, after_node, vehicle); return (before_node != start_index || IsEnd(after_node)) ? arc_cost @@ -4730,14 +4181,14 @@ bool HasUnaryDimension(const std::vector& dimensions) { namespace { -void ConvertVectorInt64ToVectorInt(const std::vector& input, +void ConvertVectorInt64ToVectorInt(const std::vector& input, std::vector* output) { const int n = input.size(); output->resize(n); int* data = output->data(); for (int i = 0; i < n; ++i) { const int element = static_cast(input[i]); - DCHECK_EQ(input[i], static_cast(element)); + DCHECK_EQ(input[i], static_cast(element)); data[i] = element; } } @@ -4769,13 +4220,13 @@ RoutingModel::GetOrCreateLocalSearchFilters( if (filter_cost) { if (CostsAreHomogeneousAcrossVehicles()) { LocalSearchFilter* sum = solver_->MakeSumObjectiveFilter( - nexts_, [this](int64 i, int64 j) { return GetHomogeneousCost(i, j); }, + nexts_, [this](int64_t i, int64_t j) { return GetHomogeneousCost(i, j); }, Solver::LE); filters.push_back({sum, kAccept}); } else { LocalSearchFilter* sum = solver_->MakeSumObjectiveFilter( nexts_, vehicle_vars_, - [this](int64 i, int64 j, int64 k) { + [this](int64_t i, int64_t j, int64_t k) { return GetArcCostForVehicle(i, j, k); }, Solver::LE); @@ -4906,7 +4357,8 @@ void RoutingModel::StoreDimensionCumulOptimizers( dimension->SetOffsetForGlobalOptimizer(0); continue; } - int64 offset = vehicles() == 0 ? 0 : kint64max; + int64_t offset = + vehicles() == 0 ? 0 : std::numeric_limits::max(); for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { DCHECK_GE(dimension->CumulVar(Start(vehicle))->Min(), 0); offset = @@ -4916,12 +4368,13 @@ void RoutingModel::StoreDimensionCumulOptimizers( } else { bool has_span_cost = false; bool has_span_limit = false; - std::vector vehicle_offsets(vehicles()); + std::vector vehicle_offsets(vehicles()); for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { if (dimension->GetSpanCostCoefficientForVehicle(vehicle) > 0) { has_span_cost = true; } - if (dimension->GetSpanUpperBoundForVehicle(vehicle) < kint64max) { + if (dimension->GetSpanUpperBoundForVehicle(vehicle) < + std::numeric_limits::max()) { has_span_limit = true; } DCHECK_GE(dimension->CumulVar(Start(vehicle))->Min(), 0); @@ -5022,19 +4475,19 @@ DecisionBuilder* RoutingModel::CreateFinalizerForMinimizedAndMaximizedVariables() { std::stable_sort(finalizer_variable_cost_pairs_.begin(), finalizer_variable_cost_pairs_.end(), - [](const std::pair& var_cost1, - const std::pair& var_cost2) { + [](const std::pair& var_cost1, + const std::pair& var_cost2) { return var_cost1.second > var_cost2.second; }); const int num_variables = finalizer_variable_cost_pairs_.size() + finalizer_variable_target_pairs_.size(); std::vector variables; - std::vector targets; + std::vector targets; variables.reserve(num_variables); targets.reserve(num_variables); for (const auto& variable_cost : finalizer_variable_cost_pairs_) { variables.push_back(variable_cost.first); - targets.push_back(kint64min); + targets.push_back(std::numeric_limits::min()); } for (const auto& variable_target : finalizer_variable_target_pairs_) { variables.push_back(variable_target.first); @@ -5081,10 +4534,10 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( first_solution_decision_builders_ [FirstSolutionStrategy::GLOBAL_CHEAPEST_ARC] = solver_->MakePhase( nexts_, - [this](int64 i, int64 j) { return GetArcCostForFirstSolution(i, j); }, + [this](int64_t i, int64_t j) { return GetArcCostForFirstSolution(i, j); }, Solver::CHOOSE_STATIC_GLOBAL_BEST); // Cheapest addition heuristic. - Solver::IndexEvaluator2 eval = [this](int64 i, int64 j) { + Solver::IndexEvaluator2 eval = [this](int64_t i, int64_t j) { return GetArcCostForFirstSolution(i, j); }; first_solution_decision_builders_[FirstSolutionStrategy::LOCAL_CHEAPEST_ARC] = @@ -5098,7 +4551,7 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( solver_->RevAlloc(new IntVarFilteredDecisionBuilder( absl::make_unique( this, - [this](int64 i, int64 j) { + [this](int64_t i, int64_t j) { return GetArcCostForFirstSolution(i, j); }, GetOrCreateFeasibilityFilterManager(search_parameters)))); @@ -5110,7 +4563,7 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( [FirstSolutionStrategy::PATH_CHEAPEST_ARC]); } // Path-based most constrained arc addition heuristic. - Solver::VariableValueComparator comp = [this](int64 i, int64 j, int64 k) { + Solver::VariableValueComparator comp = [this](int64_t i, int64_t j, int64_t k) { return ArcIsMoreConstrainedThanArc(i, j, k); }; @@ -5142,11 +4595,12 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( } // All unperformed heuristic. first_solution_decision_builders_[FirstSolutionStrategy::ALL_UNPERFORMED] = - solver_->RevAlloc(new AllUnperformed(this)); + MakeAllUnperformed(this); // Best insertion heuristic. - RegularLimit* const ls_limit = - solver_->MakeLimit(GetTimeLimit(search_parameters), kint64max, kint64max, - kint64max, /*smart_time_check=*/true); + RegularLimit* const ls_limit = solver_->MakeLimit( + GetTimeLimit(search_parameters), std::numeric_limits::max(), + std::numeric_limits::max(), std::numeric_limits::max(), + /*smart_time_check=*/true); DecisionBuilder* const finalize = solver_->MakeSolveOnce( finalize_solution, GetOrCreateLargeNeighborhoodSearchLimit()); LocalSearchPhaseParameters* const insertion_parameters = @@ -5158,13 +4612,12 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( decision_vars.insert(decision_vars.end(), vehicle_vars_.begin(), vehicle_vars_.end()); } - const int64 optimization_step = std::max( + const int64_t optimization_step = std::max( MathUtil::FastInt64Round(search_parameters.optimization_step()), One()); first_solution_decision_builders_[FirstSolutionStrategy::BEST_INSERTION] = solver_->MakeNestedOptimize( - solver_->MakeLocalSearchPhase( - decision_vars, solver_->RevAlloc(new AllUnperformed(this)), - insertion_parameters), + solver_->MakeLocalSearchPhase(decision_vars, MakeAllUnperformed(this), + insertion_parameters), GetOrCreateAssignment(), false, optimization_step); first_solution_decision_builders_[FirstSolutionStrategy::BEST_INSERTION] = solver_->Compose(first_solution_decision_builders_ @@ -5181,7 +4634,9 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( search_parameters.cheapest_insertion_first_solution_neighbors_ratio(); gci_parameters.min_neighbors = search_parameters.cheapest_insertion_first_solution_min_neighbors(); - gci_parameters.use_neighbors_ratio_for_initialization = false; + gci_parameters.use_neighbors_ratio_for_initialization = + search_parameters + .cheapest_insertion_first_solution_use_neighbors_ratio_for_initialization(); // NOLINT gci_parameters.add_unperformed_entries = search_parameters.cheapest_insertion_add_unperformed_entries(); for (bool is_sequential : {false, true}) { @@ -5194,20 +4649,20 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( solver_->RevAlloc(new IntVarFilteredDecisionBuilder( absl::make_unique( this, - [this](int64 i, int64 j, int64 vehicle) { + [this](int64_t i, int64_t j, int64_t vehicle) { return GetArcCostForVehicle(i, j, vehicle); }, - [this](int64 i) { return UnperformedPenaltyOrValue(0, i); }, + [this](int64_t i) { return UnperformedPenaltyOrValue(0, i); }, GetOrCreateFeasibilityFilterManager(search_parameters), gci_parameters))); IntVarFilteredDecisionBuilder* const strong_gci = solver_->RevAlloc(new IntVarFilteredDecisionBuilder( absl::make_unique( this, - [this](int64 i, int64 j, int64 vehicle) { + [this](int64_t i, int64_t j, int64_t vehicle) { return GetArcCostForVehicle(i, j, vehicle); }, - [this](int64 i) { return UnperformedPenaltyOrValue(0, i); }, + [this](int64_t i) { return UnperformedPenaltyOrValue(0, i); }, GetOrCreateStrongFeasibilityFilterManager(search_parameters), gci_parameters))); first_solution_decision_builders_[first_solution_strategy] = solver_->Try( @@ -5222,7 +4677,7 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( solver_->RevAlloc(new IntVarFilteredDecisionBuilder( absl::make_unique( this, - [this](int64 i, int64 j, int64 vehicle) { + [this](int64_t i, int64_t j, int64_t vehicle) { return GetArcCostForVehicle(i, j, vehicle); }, GetOrCreateFeasibilityFilterManager(search_parameters)))); @@ -5230,7 +4685,7 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( solver_->RevAlloc(new IntVarFilteredDecisionBuilder( absl::make_unique( this, - [this](int64 i, int64 j, int64 vehicle) { + [this](int64_t i, int64_t j, int64_t vehicle) { return GetArcCostForVehicle(i, j, vehicle); }, GetOrCreateStrongFeasibilityFilterManager(search_parameters)))); @@ -5293,9 +4748,8 @@ void RoutingModel::CreateFirstSolutionDecisionBuilders( } // Sweep first_solution_decision_builders_[FirstSolutionStrategy::SWEEP] = - solver_->RevAlloc(new SweepBuilder(this, true)); - DecisionBuilder* sweep_builder = - solver_->RevAlloc(new SweepBuilder(this, false)); + MakeSweepDecisionBuilder(this, true); + DecisionBuilder* sweep_builder = MakeSweepDecisionBuilder(this, false); first_solution_decision_builders_[FirstSolutionStrategy::SWEEP] = solver_->Try( sweep_builder, @@ -5421,22 +4875,23 @@ void RoutingModel::SetupMetaheuristics( search_parameters.local_search_metaheuristic(); // Some metaheuristics will effectively never terminate; warn // user if they fail to set a time limit. - bool limit_too_long = !search_parameters.has_time_limit() && - search_parameters.solution_limit() == kint64max; - const int64 optimization_step = std::max( + bool limit_too_long = + !search_parameters.has_time_limit() && + search_parameters.solution_limit() == std::numeric_limits::max(); + const int64_t optimization_step = std::max( MathUtil::FastInt64Round(search_parameters.optimization_step()), One()); switch (metaheuristic) { case LocalSearchMetaheuristic::GUIDED_LOCAL_SEARCH: if (CostsAreHomogeneousAcrossVehicles()) { optimize = solver_->MakeGuidedLocalSearch( false, cost_, - [this](int64 i, int64 j) { return GetHomogeneousCost(i, j); }, + [this](int64_t i, int64_t j) { return GetHomogeneousCost(i, j); }, optimization_step, nexts_, search_parameters.guided_local_search_lambda_coefficient()); } else { optimize = solver_->MakeGuidedLocalSearch( false, cost_, - [this](int64 i, int64 j, int64 k) { + [this](int64_t i, int64_t j, int64_t k) { return GetArcCostForVehicle(i, j, k); }, optimization_step, nexts_, vehicle_vars_, @@ -5554,19 +5009,19 @@ bool RoutingModel::UsesLightPropagation( } void RoutingModel::AddWeightedVariableMinimizedByFinalizer(IntVar* var, - int64 cost) { + int64_t cost) { CHECK(var != nullptr); const int index = gtl::LookupOrInsert(&finalizer_variable_cost_index_, var, finalizer_variable_cost_pairs_.size()); if (index < finalizer_variable_cost_pairs_.size()) { - const int64 old_cost = finalizer_variable_cost_pairs_[index].second; + const int64_t old_cost = finalizer_variable_cost_pairs_[index].second; finalizer_variable_cost_pairs_[index].second = CapAdd(old_cost, cost); } else { finalizer_variable_cost_pairs_.emplace_back(var, cost); } } -void RoutingModel::AddVariableTargetToFinalizer(IntVar* var, int64 target) { +void RoutingModel::AddVariableTargetToFinalizer(IntVar* var, int64_t target) { CHECK(var != nullptr); if (finalizer_variable_target_set_.contains(var)) return; finalizer_variable_target_set_.insert(var); @@ -5574,11 +5029,11 @@ void RoutingModel::AddVariableTargetToFinalizer(IntVar* var, int64 target) { } void RoutingModel::AddVariableMaximizedByFinalizer(IntVar* var) { - AddVariableTargetToFinalizer(var, kint64max); + AddVariableTargetToFinalizer(var, std::numeric_limits::max()); } void RoutingModel::AddVariableMinimizedByFinalizer(IntVar* var) { - AddVariableTargetToFinalizer(var, kint64min); + AddVariableTargetToFinalizer(var, std::numeric_limits::min()); } void RoutingModel::SetupSearch( @@ -5670,21 +5125,27 @@ class PathSpansAndTotalSlacks : public Constraint { // to present both span and total_slack in terms of span and fixed transit. // This allows to use the same code whether there actually are variables // for span and total_slack or not. - int64 SpanMin(int vehicle, int64 sum_fixed_transits) { + int64_t SpanMin(int vehicle, int64_t sum_fixed_transits) { DCHECK_GE(sum_fixed_transits, 0); - const int64 span_min = spans_[vehicle] ? spans_[vehicle]->Min() : kint64max; - const int64 total_slack_min = - total_slacks_[vehicle] ? total_slacks_[vehicle]->Min() : kint64max; + const int64_t span_min = spans_[vehicle] + ? spans_[vehicle]->Min() + : std::numeric_limits::max(); + const int64_t total_slack_min = total_slacks_[vehicle] + ? total_slacks_[vehicle]->Min() + : std::numeric_limits::max(); return std::min(span_min, CapAdd(total_slack_min, sum_fixed_transits)); } - int64 SpanMax(int vehicle, int64 sum_fixed_transits) { + int64_t SpanMax(int vehicle, int64_t sum_fixed_transits) { DCHECK_GE(sum_fixed_transits, 0); - const int64 span_max = spans_[vehicle] ? spans_[vehicle]->Max() : kint64min; - const int64 total_slack_max = - total_slacks_[vehicle] ? total_slacks_[vehicle]->Max() : kint64min; + const int64_t span_max = spans_[vehicle] + ? spans_[vehicle]->Max() + : std::numeric_limits::min(); + const int64_t total_slack_max = total_slacks_[vehicle] + ? total_slacks_[vehicle]->Max() + : std::numeric_limits::min(); return std::max(span_max, CapAdd(total_slack_max, sum_fixed_transits)); } - void SetSpanMin(int vehicle, int64 min, int64 sum_fixed_transits) { + void SetSpanMin(int vehicle, int64_t min, int64_t sum_fixed_transits) { DCHECK_GE(sum_fixed_transits, 0); if (spans_[vehicle]) { spans_[vehicle]->SetMin(min); @@ -5693,7 +5154,7 @@ class PathSpansAndTotalSlacks : public Constraint { total_slacks_[vehicle]->SetMin(CapSub(min, sum_fixed_transits)); } } - void SetSpanMax(int vehicle, int64 max, int64 sum_fixed_transits) { + void SetSpanMax(int vehicle, int64_t max, int64_t sum_fixed_transits) { DCHECK_GE(sum_fixed_transits, 0); if (spans_[vehicle]) { spans_[vehicle]->SetMax(max); @@ -5704,7 +5165,7 @@ class PathSpansAndTotalSlacks : public Constraint { } // Propagates span == sum_fixed_transits + total_slack. // This should be called at least once during PropagateVehicle(). - void SynchronizeSpanAndTotalSlack(int vehicle, int64 sum_fixed_transits) { + void SynchronizeSpanAndTotalSlack(int vehicle, int64_t sum_fixed_transits) { DCHECK_GE(sum_fixed_transits, 0); IntVar* span = spans_[vehicle]; IntVar* total_slack = total_slacks_[vehicle]; @@ -5734,7 +5195,7 @@ class PathSpansAndTotalSlacks : public Constraint { } // Compute the sum of fixed transits. Fixed transit variables should all be // fixed, otherwise we wait to get called later when propagation does it. - int64 sum_fixed_transits = 0; + int64_t sum_fixed_transits = 0; for (const int node : path_) { const IntVar* fixed_transit_var = dimension_->FixedTransitVar(node); if (!fixed_transit_var->Bound()) return; @@ -5751,10 +5212,10 @@ class PathSpansAndTotalSlacks : public Constraint { // that would force more breaks in route than possible. if (dimension_->HasBreakConstraints() && !dimension_->GetBreakIntervalsOfVehicle(vehicle).empty()) { - const int64 vehicle_start_max = dimension_->CumulVar(start)->Max(); - const int64 vehicle_end_min = dimension_->CumulVar(end)->Min(); + const int64_t vehicle_start_max = dimension_->CumulVar(start)->Max(); + const int64_t vehicle_end_min = dimension_->CumulVar(end)->Min(); // Compute and propagate lower bound. - int64 min_break_duration = 0; + int64_t min_break_duration = 0; for (IntervalVar* br : dimension_->GetBreakIntervalsOfVehicle(vehicle)) { if (!br->MustBePerformed()) continue; if (vehicle_start_max < br->EndMin() && @@ -5769,9 +5230,10 @@ class PathSpansAndTotalSlacks : public Constraint { // must be after the route. // In the other cases, we cannot deduce a better bound on a CumulVar or // on a break, so we do nothing. - const int64 slack_max = + const int64_t slack_max = CapSub(SpanMax(vehicle, sum_fixed_transits), sum_fixed_transits); - const int64 max_additional_slack = CapSub(slack_max, min_break_duration); + const int64_t max_additional_slack = + CapSub(slack_max, min_break_duration); for (IntervalVar* br : dimension_->GetBreakIntervalsOfVehicle(vehicle)) { if (!br->MustBePerformed()) continue; // Break must be before end, detect whether it must be before start. @@ -5800,20 +5262,20 @@ class PathSpansAndTotalSlacks : public Constraint { { IntVar* start_cumul = dimension_->CumulVar(start); IntVar* end_cumul = dimension_->CumulVar(end); - const int64 start_min = start_cumul->Min(); - const int64 start_max = start_cumul->Max(); - const int64 end_min = end_cumul->Min(); - const int64 end_max = end_cumul->Max(); + const int64_t start_min = start_cumul->Min(); + const int64_t start_max = start_cumul->Max(); + const int64_t end_min = end_cumul->Min(); + const int64_t end_max = end_cumul->Max(); // Propagate from cumuls to span. - const int64 span_lb = CapSub(end_min, start_max); + const int64_t span_lb = CapSub(end_min, start_max); SetSpanMin(vehicle, span_lb, sum_fixed_transits); - const int64 span_ub = CapSub(end_max, start_min); + const int64_t span_ub = CapSub(end_max, start_min); SetSpanMax(vehicle, span_ub, sum_fixed_transits); // Propagate from span to cumuls. - const int64 span_min = SpanMin(vehicle, sum_fixed_transits); - const int64 span_max = SpanMax(vehicle, sum_fixed_transits); - const int64 slack_from_lb = CapSub(span_max, span_lb); - const int64 slack_from_ub = CapSub(span_ub, span_min); + const int64_t span_min = SpanMin(vehicle, sum_fixed_transits); + const int64_t span_max = SpanMax(vehicle, sum_fixed_transits); + const int64_t slack_from_lb = CapSub(span_max, span_lb); + const int64_t slack_from_ub = CapSub(span_ub, span_min); // start >= start_max - (span_max - span_lb). start_cumul->SetMin(CapSub(start_max, slack_from_lb)); // end <= end_min + (span_max - span_lb). @@ -5827,8 +5289,8 @@ class PathSpansAndTotalSlacks : public Constraint { // Propagate sum transits == span. { // Propagate from transits to span. - int64 span_lb = 0; - int64 span_ub = 0; + int64_t span_lb = 0; + int64_t span_ub = 0; for (const int node : path_) { span_lb = CapAdd(span_lb, dimension_->TransitVar(node)->Min()); span_ub = CapAdd(span_ub, dimension_->TransitVar(node)->Max()); @@ -5838,15 +5300,17 @@ class PathSpansAndTotalSlacks : public Constraint { // Propagate from span to transits. // transit[i] <= transit_i_min + (span_max - span_lb) // transit[i] >= transit_i_max - (span_ub - span_min) - const int64 span_min = SpanMin(vehicle, sum_fixed_transits); - const int64 span_max = SpanMax(vehicle, sum_fixed_transits); - const int64 slack_from_lb = CapSub(span_max, span_lb); - const int64 slack_from_ub = - span_ub < kint64max ? CapSub(span_ub, span_min) : kint64max; + const int64_t span_min = SpanMin(vehicle, sum_fixed_transits); + const int64_t span_max = SpanMax(vehicle, sum_fixed_transits); + const int64_t slack_from_lb = CapSub(span_max, span_lb); + const int64_t slack_from_ub = + span_ub < std::numeric_limits::max() + ? CapSub(span_ub, span_min) + : std::numeric_limits::max(); for (const int node : path_) { IntVar* transit_var = dimension_->TransitVar(node); - const int64 transit_i_min = transit_var->Min(); - const int64 transit_i_max = transit_var->Max(); + const int64_t transit_i_min = transit_var->Min(); + const int64_t transit_i_max = transit_var->Max(); // TRICKY: the first propagation might change transit_var->Max(), // but we must use the same value of transit_i_max in the computation // of transit[i]'s lower bound that was used for span_ub. @@ -5867,30 +5331,30 @@ class PathSpansAndTotalSlacks : public Constraint { // Then arrival time - departure time is a valid lower bound of span. // First reasoning: start - end - start { - int64 arrival_time = dimension_->CumulVar(start)->Min(); + int64_t arrival_time = dimension_->CumulVar(start)->Min(); for (int i = 1; i < path_.size(); ++i) { arrival_time = std::max(CapAdd(arrival_time, dimension_->FixedTransitVar(path_[i - 1])->Min()), dimension_->CumulVar(path_[i])->Min()); } - int64 departure_time = arrival_time; + int64_t departure_time = arrival_time; for (int i = path_.size() - 2; i >= 0; --i) { departure_time = std::min(CapSub(departure_time, dimension_->FixedTransitVar(path_[i])->Min()), dimension_->CumulVar(path_[i])->Max()); } - const int64 span_lb = CapSub(arrival_time, departure_time); + const int64_t span_lb = CapSub(arrival_time, departure_time); SetSpanMin(vehicle, span_lb, sum_fixed_transits); - const int64 maximum_deviation = + const int64_t maximum_deviation = CapSub(SpanMax(vehicle, sum_fixed_transits), span_lb); - const int64 start_lb = CapSub(departure_time, maximum_deviation); + const int64_t start_lb = CapSub(departure_time, maximum_deviation); dimension_->CumulVar(start)->SetMin(start_lb); } // Second reasoning: end - start - end { - int64 departure_time = dimension_->CumulVar(end)->Max(); + int64_t departure_time = dimension_->CumulVar(end)->Max(); for (int i = path_.size() - 2; i >= 0; --i) { const int curr_node = path_[i]; departure_time = @@ -5905,9 +5369,9 @@ class PathSpansAndTotalSlacks : public Constraint { dimension_->FixedTransitVar(path_[i - 1])->Min()), dimension_->CumulVar(path_[i])->Min()); } - const int64 span_lb = CapSub(arrival_time, departure_time); + const int64_t span_lb = CapSub(arrival_time, departure_time); SetSpanMin(vehicle, span_lb, sum_fixed_transits); - const int64 maximum_deviation = + const int64_t maximum_deviation = CapSub(SpanMax(vehicle, sum_fixed_transits), span_lb); dimension_->CumulVar(end)->SetMax( CapAdd(arrival_time, maximum_deviation)); @@ -5938,7 +5402,7 @@ const char RoutingModelVisitor::kLightElement2[] = "LightElement2"; const char RoutingModelVisitor::kRemoveValues[] = "RemoveValues"; RoutingDimension::RoutingDimension(RoutingModel* model, - std::vector vehicle_capacities, + std::vector vehicle_capacities, const std::string& name, const RoutingDimension* base_dimension) : vehicle_capacities_(std::move(vehicle_capacities)), @@ -5948,12 +5412,13 @@ RoutingDimension::RoutingDimension(RoutingModel* model, name_(name), global_optimizer_offset_(0) { CHECK(model != nullptr); - vehicle_span_upper_bounds_.assign(model->vehicles(), kint64max); + vehicle_span_upper_bounds_.assign(model->vehicles(), + std::numeric_limits::max()); vehicle_span_cost_coefficients_.assign(model->vehicles(), 0); } RoutingDimension::RoutingDimension(RoutingModel* model, - std::vector vehicle_capacities, + std::vector vehicle_capacities, const std::string& name, SelfBased) : RoutingDimension(model, std::move(vehicle_capacities), name, this) {} @@ -5964,7 +5429,7 @@ RoutingDimension::~RoutingDimension() { void RoutingDimension::Initialize( const std::vector& transit_evaluators, const std::vector& state_dependent_transit_evaluators, - int64 slack_max) { + int64_t slack_max) { InitializeCumuls(); InitializeTransits(transit_evaluators, state_dependent_transit_evaluators, slack_max); @@ -6046,13 +5511,13 @@ void RoutingDimension::InitializeCumuls() { const int size = model_->Size() + model_->vehicles(); const auto capacity_range = std::minmax_element(vehicle_capacities_.begin(), vehicle_capacities_.end()); - const int64 min_capacity = *capacity_range.first; + const int64_t min_capacity = *capacity_range.first; CHECK_GE(min_capacity, 0); - const int64 max_capacity = *capacity_range.second; + const int64_t max_capacity = *capacity_range.second; solver->MakeIntVarArray(size, 0, max_capacity, name_, &cumuls_); // Refine the min/max for vehicle start/ends based on vehicle capacities. for (int v = 0; v < model_->vehicles(); v++) { - const int64 vehicle_capacity = vehicle_capacities_[v]; + const int64_t vehicle_capacity = vehicle_capacities_[v]; cumuls_[model_->Start(v)]->SetMax(vehicle_capacity); cumuls_[model_->End(v)]->SetMax(vehicle_capacity); } @@ -6060,7 +5525,8 @@ void RoutingDimension::InitializeCumuls() { forbidden_intervals_.resize(size); capacity_vars_.clear(); if (min_capacity != max_capacity) { - solver->MakeIntVarArray(size, 0, kint64max, &capacity_vars_); + solver->MakeIntVarArray(size, 0, std::numeric_limits::max(), + &capacity_vars_); for (int i = 0; i < size; ++i) { IntVar* const capacity_var = capacity_vars_[i]; if (i < model_->Size()) { @@ -6078,19 +5544,19 @@ void RoutingDimension::InitializeCumuls() { } namespace { -template -int64 IthElementOrValue(const std::vector& v, int64 index) { +template +int64_t IthElementOrValue(const std::vector& v, int64_t index) { return index >= 0 ? v[index] : value; } void ComputeTransitClasses(const std::vector& evaluator_indices, std::vector* class_evaluators, - std::vector* vehicle_to_class) { + std::vector* vehicle_to_class) { CHECK(class_evaluators != nullptr); CHECK(vehicle_to_class != nullptr); class_evaluators->clear(); vehicle_to_class->resize(evaluator_indices.size(), -1); - absl::flat_hash_map evaluator_to_class; + absl::flat_hash_map evaluator_to_class; for (int i = 0; i < evaluator_indices.size(); ++i) { const int evaluator_index = evaluator_indices[i]; int evaluator_class = -1; @@ -6104,7 +5570,7 @@ void ComputeTransitClasses(const std::vector& evaluator_indices, } } // namespace -void RoutingDimension::InitializeTransitVariables(int64 slack_max) { +void RoutingDimension::InitializeTransitVariables(int64_t slack_max) { CHECK(!class_evaluators_.empty()); CHECK(base_dimension_ == nullptr || !state_dependent_class_evaluators_.empty()); @@ -6120,14 +5586,15 @@ void RoutingDimension::InitializeTransitVariables(int64 slack_max) { const std::string slack_name = name_ + " slack"; const std::string transit_name = name_ + " fixed transit"; - for (int64 i = 0; i < size; ++i) { - fixed_transits_[i] = - solver->MakeIntVar(kint64min, kint64max, absl::StrCat(transit_name, i)); + for (int64_t i = 0; i < size; ++i) { + fixed_transits_[i] = solver->MakeIntVar(std::numeric_limits::min(), + std::numeric_limits::max(), + absl::StrCat(transit_name, i)); // Setting dependent_transits_[i]. if (base_dimension_ != nullptr) { if (state_dependent_class_evaluators_.size() == 1) { std::vector transition_variables(cumuls_.size(), nullptr); - for (int64 j = 0; j < cumuls_.size(); ++j) { + for (int64_t j = 0; j < cumuls_.size(); ++j) { transition_variables[j] = MakeRangeMakeElementExpr( model_ @@ -6151,7 +5618,7 @@ void RoutingDimension::InitializeTransitVariables(int64 slack_max) { 1); for (int evaluator : state_dependent_class_evaluators_) { std::vector transition_variables(cumuls_.size(), nullptr); - for (int64 j = 0; j < cumuls_.size(); ++j) { + for (int64_t j = 0; j < cumuls_.size(); ++j) { transition_variables[j] = MakeRangeMakeElementExpr( model_->StateDependentTransitCallback(evaluator)(i, j) @@ -6192,7 +5659,7 @@ void RoutingDimension::InitializeTransitVariables(int64 slack_max) { void RoutingDimension::InitializeTransits( const std::vector& transit_evaluators, const std::vector& state_dependent_transit_evaluators, - int64 slack_max) { + int64_t slack_max) { CHECK_EQ(model_->vehicles(), transit_evaluators.size()); CHECK(base_dimension_ == nullptr || model_->vehicles() == state_dependent_transit_evaluators.size()); @@ -6212,9 +5679,9 @@ void RoutingDimension::InitializeTransits( InitializeTransitVariables(slack_max); } -void FillPathEvaluation(const std::vector& path, +void FillPathEvaluation(const std::vector& path, const RoutingModel::TransitCallback2& evaluator, - std::vector* values) { + std::vector* values) { const int num_nodes = path.size(); values->resize(num_nodes - 1); for (int i = 0; i < num_nodes - 1; ++i) { @@ -6226,7 +5693,7 @@ TypeRegulationsChecker::TypeRegulationsChecker(const RoutingModel& model) : model_(model), occurrences_of_type_(model.GetNumberOfVisitTypes()) {} bool TypeRegulationsChecker::CheckVehicle( - int vehicle, const std::function& next_accessor) { + int vehicle, const std::function& next_accessor) { if (!HasRegulationsToCheck()) { return true; } @@ -6234,7 +5701,7 @@ bool TypeRegulationsChecker::CheckVehicle( InitializeCheck(vehicle, next_accessor); for (int pos = 0; pos < current_route_visits_.size(); pos++) { - const int64 current_visit = current_route_visits_[pos]; + const int64_t current_visit = current_route_visits_[pos]; const int type = model_.GetVisitType(current_visit); if (type < 0) { continue; @@ -6270,7 +5737,7 @@ bool TypeRegulationsChecker::CheckVehicle( } void TypeRegulationsChecker::InitializeCheck( - int vehicle, const std::function& next_accessor) { + int vehicle, const std::function& next_accessor) { // Accumulates the count of types before the current node. // {0, 0, -1} does not compile on or-tools. std::fill(occurrences_of_type_.begin(), occurrences_of_type_.end(), @@ -6280,7 +5747,7 @@ void TypeRegulationsChecker::InitializeCheck( // time when there are no TYPE_ON_VEHICLE_UP_TO_VISIT policies on the route, // by passing a boolean to CheckVehicle() passed to InitializeCheck(). current_route_visits_.clear(); - for (int64 current = model_.Start(vehicle); !model_.IsEnd(current); + for (int64_t current = model_.Start(vehicle); !model_.IsEnd(current); current = next_accessor(current)) { const int type = model_.GetVisitType(current); if (type >= 0 && model_.GetVisitTypePolicy(current) == @@ -6434,7 +5901,7 @@ void TypeRegulationsConstraint::PropagateNodeRegulations(int node) { } void TypeRegulationsConstraint::CheckRegulationsOnVehicle(int vehicle) { - const auto next_accessor = [this, vehicle](int64 node) { + const auto next_accessor = [this, vehicle](int64_t node) { if (model_.NextVar(node)->Bound()) { return model_.NextVar(node)->Value(); } @@ -6470,8 +5937,9 @@ void TypeRegulationsConstraint::InitialPropagate() { void RoutingDimension::CloseModel(bool use_light_propagation) { Solver* const solver = model_->solver(); - const auto capacity_lambda = [this](int64 vehicle) { - return vehicle >= 0 ? vehicle_capacities_[vehicle] : kint64max; + const auto capacity_lambda = [this](int64_t vehicle) { + return vehicle >= 0 ? vehicle_capacities_[vehicle] + : std::numeric_limits::max(); }; for (int i = 0; i < capacity_vars_.size(); ++i) { IntVar* const vehicle_var = model_->VehicleVar(i); @@ -6486,14 +5954,11 @@ void RoutingDimension::CloseModel(bool use_light_propagation) { solver->MakeElement(capacity_lambda, vehicle_var)->Var())); } } - const Solver::IndexEvaluator1 vehicle_class_function = [this](int index) { - return IthElementOrValue<-1>(vehicle_to_class_, index); - }; for (int i = 0; i < fixed_transits_.size(); ++i) { IntVar* const next_var = model_->NextVar(i); IntVar* const fixed_transit = fixed_transits_[i]; - const auto transit_vehicle_evaluator = [this, i](int64 to, - int64 eval_index) { + const auto transit_vehicle_evaluator = [this, i](int64_t to, + int64_t eval_index) { return eval_index >= 0 ? transit_evaluator(eval_index)(i, to) : 0; }; if (use_light_propagation) { @@ -6504,7 +5969,7 @@ void RoutingDimension::CloseModel(bool use_light_propagation) { if (unary_callback == nullptr) { solver->AddConstraint(MakeLightElement( solver, fixed_transit, next_var, - [this, i](int64 to) { + [this, i](int64_t to) { return model_->TransitCallback(class_evaluators_[0])(i, to); }, [this]() { return model_->enable_deep_serialization_; })); @@ -6526,7 +5991,7 @@ void RoutingDimension::CloseModel(bool use_light_propagation) { solver->AddConstraint(solver->MakeEquality( fixed_transit, solver ->MakeElement( - [this, i](int64 to) { + [this, i](int64_t to) { return model_->TransitCallback( class_evaluators_[0])(i, to); }, @@ -6536,13 +6001,10 @@ void RoutingDimension::CloseModel(bool use_light_propagation) { fixed_transit->SetValue(unary_callback(i)); } } else { - IntVar* const vehicle_class_var = - solver->MakeElement(vehicle_class_function, model_->VehicleVar(i)) - ->Var(); solver->AddConstraint(solver->MakeEquality( fixed_transit, solver ->MakeElement(transit_vehicle_evaluator, - next_var, vehicle_class_var) + next_var, model_->VehicleVar(i)) ->Var())); } } @@ -6554,20 +6016,20 @@ void RoutingDimension::CloseModel(bool use_light_propagation) { } } -int64 RoutingDimension::GetTransitValue(int64 from_index, int64 to_index, - int64 vehicle) const { +int64_t RoutingDimension::GetTransitValue(int64_t from_index, int64_t to_index, + int64_t vehicle) const { DCHECK(transit_evaluator(vehicle) != nullptr); return transit_evaluator(vehicle)(from_index, to_index); } SortedDisjointIntervalList RoutingDimension::GetAllowedIntervalsInRange( - int64 index, int64 min_value, int64 max_value) const { + int64_t index, int64_t min_value, int64_t max_value) const { SortedDisjointIntervalList allowed; const SortedDisjointIntervalList& forbidden = forbidden_intervals_[index]; IntVar* const cumul_var = cumuls_[index]; - const int64 min = std::max(min_value, cumul_var->Min()); - const int64 max = std::min(max_value, cumul_var->Max()); - int64 next_start = min; + const int64_t min = std::max(min_value, cumul_var->Min()); + const int64_t max = std::min(max_value, cumul_var->Max()); + int64_t next_start = min; for (SortedDisjointIntervalList::Iterator interval = forbidden.FirstIntervalGreaterOrEqual(min); interval != forbidden.end(); ++interval) { @@ -6583,7 +6045,7 @@ SortedDisjointIntervalList RoutingDimension::GetAllowedIntervalsInRange( return allowed; } -void RoutingDimension::SetSpanUpperBoundForVehicle(int64 upper_bound, +void RoutingDimension::SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle) { CHECK_GE(vehicle, 0); CHECK_LT(vehicle, vehicle_span_upper_bounds_.size()); @@ -6591,7 +6053,7 @@ void RoutingDimension::SetSpanUpperBoundForVehicle(int64 upper_bound, vehicle_span_upper_bounds_[vehicle] = upper_bound; } -void RoutingDimension::SetSpanCostCoefficientForVehicle(int64 coefficient, +void RoutingDimension::SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle) { CHECK_GE(vehicle, 0); CHECK_LT(vehicle, vehicle_span_cost_coefficients_.size()); @@ -6599,18 +6061,19 @@ void RoutingDimension::SetSpanCostCoefficientForVehicle(int64 coefficient, vehicle_span_cost_coefficients_[vehicle] = coefficient; } -void RoutingDimension::SetSpanCostCoefficientForAllVehicles(int64 coefficient) { +void RoutingDimension::SetSpanCostCoefficientForAllVehicles( + int64_t coefficient) { CHECK_GE(coefficient, 0); vehicle_span_cost_coefficients_.assign(model_->vehicles(), coefficient); } -void RoutingDimension::SetGlobalSpanCostCoefficient(int64 coefficient) { +void RoutingDimension::SetGlobalSpanCostCoefficient(int64_t coefficient) { CHECK_GE(coefficient, 0); global_span_cost_coefficient_ = coefficient; } void RoutingDimension::SetCumulVarPiecewiseLinearCost( - int64 index, const PiecewiseLinearFunction& cost) { + int64_t index, const PiecewiseLinearFunction& cost) { if (!cost.IsNonDecreasing()) { LOG(WARNING) << "Only non-decreasing cost functions are supported."; return; @@ -6628,13 +6091,13 @@ void RoutingDimension::SetCumulVarPiecewiseLinearCost( piecewise_linear_cost.cost = absl::make_unique(cost); } -bool RoutingDimension::HasCumulVarPiecewiseLinearCost(int64 index) const { +bool RoutingDimension::HasCumulVarPiecewiseLinearCost(int64_t index) const { return (index < cumul_var_piecewise_linear_cost_.size() && cumul_var_piecewise_linear_cost_[index].var != nullptr); } const PiecewiseLinearFunction* RoutingDimension::GetCumulVarPiecewiseLinearCost( - int64 index) const { + int64_t index) const { if (index < cumul_var_piecewise_linear_cost_.size() && cumul_var_piecewise_linear_cost_[index].var != nullptr) { return cumul_var_piecewise_linear_cost_[index].cost.get(); @@ -6675,8 +6138,9 @@ void RoutingDimension::SetupCumulVarPiecewiseLinearCosts( } } -void RoutingDimension::SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, - int64 coefficient) { +void RoutingDimension::SetCumulVarSoftUpperBound(int64_t index, + int64_t upper_bound, + int64_t coefficient) { if (index >= cumul_var_soft_upper_bound_.size()) { cumul_var_soft_upper_bound_.resize(index + 1, {nullptr, 0, 0}); } @@ -6684,12 +6148,12 @@ void RoutingDimension::SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, coefficient}; } -bool RoutingDimension::HasCumulVarSoftUpperBound(int64 index) const { +bool RoutingDimension::HasCumulVarSoftUpperBound(int64_t index) const { return (index < cumul_var_soft_upper_bound_.size() && cumul_var_soft_upper_bound_[index].var != nullptr); } -int64 RoutingDimension::GetCumulVarSoftUpperBound(int64 index) const { +int64_t RoutingDimension::GetCumulVarSoftUpperBound(int64_t index) const { if (index < cumul_var_soft_upper_bound_.size() && cumul_var_soft_upper_bound_[index].var != nullptr) { return cumul_var_soft_upper_bound_[index].bound; @@ -6697,8 +6161,8 @@ int64 RoutingDimension::GetCumulVarSoftUpperBound(int64 index) const { return cumuls_[index]->Max(); } -int64 RoutingDimension::GetCumulVarSoftUpperBoundCoefficient( - int64 index) const { +int64_t RoutingDimension::GetCumulVarSoftUpperBoundCoefficient( + int64_t index) const { if (index < cumul_var_soft_upper_bound_.size() && cumul_var_soft_upper_bound_[index].var != nullptr) { return cumul_var_soft_upper_bound_[index].coefficient; @@ -6726,8 +6190,9 @@ void RoutingDimension::SetupCumulVarSoftUpperBoundCosts( } } -void RoutingDimension::SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, - int64 coefficient) { +void RoutingDimension::SetCumulVarSoftLowerBound(int64_t index, + int64_t lower_bound, + int64_t coefficient) { if (index >= cumul_var_soft_lower_bound_.size()) { cumul_var_soft_lower_bound_.resize(index + 1, {nullptr, 0, 0}); } @@ -6735,12 +6200,12 @@ void RoutingDimension::SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, coefficient}; } -bool RoutingDimension::HasCumulVarSoftLowerBound(int64 index) const { +bool RoutingDimension::HasCumulVarSoftLowerBound(int64_t index) const { return (index < cumul_var_soft_lower_bound_.size() && cumul_var_soft_lower_bound_[index].var != nullptr); } -int64 RoutingDimension::GetCumulVarSoftLowerBound(int64 index) const { +int64_t RoutingDimension::GetCumulVarSoftLowerBound(int64_t index) const { if (index < cumul_var_soft_lower_bound_.size() && cumul_var_soft_lower_bound_[index].var != nullptr) { return cumul_var_soft_lower_bound_[index].bound; @@ -6748,8 +6213,8 @@ int64 RoutingDimension::GetCumulVarSoftLowerBound(int64 index) const { return cumuls_[index]->Min(); } -int64 RoutingDimension::GetCumulVarSoftLowerBoundCoefficient( - int64 index) const { +int64_t RoutingDimension::GetCumulVarSoftLowerBoundCoefficient( + int64_t index) const { if (index < cumul_var_soft_lower_bound_.size() && cumul_var_soft_lower_bound_[index].var != nullptr) { return cumul_var_soft_lower_bound_[index].coefficient; @@ -6794,7 +6259,8 @@ void RoutingDimension::SetupGlobalSpanCost( max_end_cumul, global_span_cost_coefficient_); std::vector start_cumuls; for (int i = 0; i < model_->vehicles(); ++i) { - IntVar* global_span_cost_start_cumul = solver->MakeIntVar(0, kint64max); + IntVar* global_span_cost_start_cumul = + solver->MakeIntVar(0, std::numeric_limits::max()); solver->AddConstraint(solver->MakeIfThenElseCt( model_->vehicle_costs_considered_[i], cumuls_[model_->Start(i)], max_end_cumul, global_span_cost_start_cumul)); @@ -6834,10 +6300,10 @@ void RoutingDimension::SetupGlobalSpanCost( void RoutingDimension::SetBreakIntervalsOfVehicle( std::vector breaks, int vehicle, - std::vector node_visit_transits) { + std::vector node_visit_transits) { if (breaks.empty()) return; const int visit_evaluator = model()->RegisterTransitCallback( - [node_visit_transits = std::move(node_visit_transits)](int64 from, int64 to) { + [node_visit_transits](int64_t from, int64_t to) { return node_visit_transits[from]; }); SetBreakIntervalsOfVehicle(std::move(breaks), vehicle, visit_evaluator, -1); @@ -6845,11 +6311,11 @@ void RoutingDimension::SetBreakIntervalsOfVehicle( void RoutingDimension::SetBreakIntervalsOfVehicle( std::vector breaks, int vehicle, - std::vector node_visit_transits, - std::function delays) { + std::vector node_visit_transits, + std::function delays) { if (breaks.empty()) return; const int visit_evaluator = model()->RegisterTransitCallback( - [node_visit_transits](int64 from, int64 to) { + [node_visit_transits](int64_t from, int64_t to) { return node_visit_transits[from]; }); const int delay_evaluator = @@ -6875,16 +6341,16 @@ void RoutingDimension::SetBreakIntervalsOfVehicle( model_->AddVariableTargetToFinalizer(interval->PerformedExpr()->Var(), 0); } model_->AddVariableTargetToFinalizer(interval->SafeStartExpr(0)->Var(), - kint64min); + std::numeric_limits::min()); model_->AddVariableTargetToFinalizer(interval->SafeDurationExpr(0)->Var(), - kint64min); + std::numeric_limits::min()); } // When a vehicle has breaks, if its start and end are fixed, // then propagation keeps the cumuls min and max on its path feasible. model_->AddVariableTargetToFinalizer(CumulVar(model_->End(vehicle)), - kint64min); + std::numeric_limits::min()); model_->AddVariableTargetToFinalizer(CumulVar(model_->Start(vehicle)), - kint64max); + std::numeric_limits::max()); } void RoutingDimension::InitializeBreaks() { @@ -6920,8 +6386,8 @@ int RoutingDimension::GetPostTravelEvaluatorOfVehicle(int vehicle) const { return vehicle_post_travel_evaluators_[vehicle]; } -void RoutingDimension::SetBreakDistanceDurationOfVehicle(int64 distance, - int64 duration, +void RoutingDimension::SetBreakDistanceDurationOfVehicle(int64_t distance, + int64_t duration, int vehicle) { DCHECK_LE(0, vehicle); DCHECK_LT(vehicle, model_->vehicles()); @@ -6930,12 +6396,12 @@ void RoutingDimension::SetBreakDistanceDurationOfVehicle(int64 distance, // When a vehicle has breaks, if its start and end are fixed, // then propagation keeps the cumuls min and max on its path feasible. model_->AddVariableTargetToFinalizer(CumulVar(model_->End(vehicle)), - kint64min); + std::numeric_limits::min()); model_->AddVariableTargetToFinalizer(CumulVar(model_->Start(vehicle)), - kint64max); + std::numeric_limits::max()); } -const std::vector>& +const std::vector>& RoutingDimension::GetBreakDistanceDurationOfVehicle(int vehicle) const { DCHECK_LE(0, vehicle); DCHECK_LT(vehicle, vehicle_break_distance_duration_.size()); @@ -6956,19 +6422,19 @@ bool RoutingDimension::HasPickupToDeliveryLimits() const { return !pickup_to_delivery_limits_per_pair_index_.empty(); } -int64 RoutingDimension::GetPickupToDeliveryLimitForPair(int pair_index, - int pickup, - int delivery) const { +int64_t RoutingDimension::GetPickupToDeliveryLimitForPair(int pair_index, + int pickup, + int delivery) const { DCHECK_GE(pair_index, 0); if (pair_index >= pickup_to_delivery_limits_per_pair_index_.size()) { - return kint64max; + return std::numeric_limits::max(); } const PickupToDeliveryLimitFunction& pickup_to_delivery_limit_function = pickup_to_delivery_limits_per_pair_index_[pair_index]; if (!pickup_to_delivery_limit_function) { // No limit function set for this pair. - return kint64max; + return std::numeric_limits::max(); } DCHECK_GE(pickup, 0); DCHECK_GE(delivery, 0); @@ -7011,12 +6477,13 @@ void RoutingDimension::SetupSlackAndDependentTransitCosts() const { it != dimensions_with_relevant_slacks.rend(); ++it) { for (int i = 0; i < model_->vehicles(); ++i) { model_->AddVariableTargetToFinalizer((*it)->cumuls_[model_->End(i)], - kint64min); + std::numeric_limits::min()); model_->AddVariableTargetToFinalizer((*it)->cumuls_[model_->Start(i)], - kint64max); + std::numeric_limits::max()); } for (IntVar* const slack : (*it)->slacks_) { - model_->AddVariableTargetToFinalizer(slack, kint64min); + model_->AddVariableTargetToFinalizer(slack, + std::numeric_limits::min()); } } } diff --git a/ortools/constraint_solver/routing.h b/ortools/constraint_solver/routing.h index ddc1baa77c..9ce5906308 100644 --- a/ortools/constraint_solver/routing.h +++ b/ortools/constraint_solver/routing.h @@ -118,7 +118,7 @@ /// - Define a custom distance/cost function from an index to another; in this /// example just returns the sum of the indices: /// -/// int64 MyDistance(int64 from, int64 to) { +/// int64_t MyDistance(int64_t from, int64_t to) { /// return from + to; /// } /// @@ -128,7 +128,7 @@ /// RoutingIndexManager manager(...number of nodes..., 1); /// RoutingModel routing(manager); /// -/// - Set the cost function by registering an std::function +/// - Set the cost function by registering an std::function /// in the model and passing its index as the vehicle cost. /// /// const int cost = routing.RegisterTransitCallback(MyDistance); @@ -144,7 +144,7 @@ /// /// LOG(INFO) << "Cost " << solution->ObjectiveValue(); /// const int route_number = 0; -/// for (int64 node = routing.Start(route_number); +/// for (int64_t node = routing.Start(route_number); /// !routing.IsEnd(node); /// node = solution->Value(routing.NextVar(node))) { /// LOG(INFO) << manager.IndexToNode(node); @@ -157,58 +157,49 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ -#include +#include #include #include #include -#include +#include #include +#include #include #include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/bind_front.h" -#include "absl/hash/hash.h" +#include "absl/memory/memory.h" #include "absl/time/time.h" -#include "ortools/base/adjustable_priority_queue-inl.h" -#include "ortools/base/adjustable_priority_queue.h" -#include "ortools/base/commandlineflags.h" -#include "ortools/base/hash.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/strong_vector.h" #include "ortools/base/logging.h" #include "ortools/base/macros.h" -#include "ortools/base/mathutil.h" +#include "ortools/graph/graph.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/routing_enums.pb.h" #include "ortools/constraint_solver/routing_index_manager.h" #include "ortools/constraint_solver/routing_parameters.pb.h" #include "ortools/constraint_solver/routing_types.h" -#include "ortools/glop/lp_solver.h" -#include "ortools/glop/parameters.pb.h" -#include "ortools/graph/graph.h" -#include "ortools/lp_data/lp_data.h" -#include "ortools/lp_data/lp_types.h" #include "ortools/sat/theta_tree.h" #include "ortools/util/range_query_function.h" -#include "ortools/util/sorted_interval_list.h" namespace operations_research { class GlobalDimensionCumulOptimizer; class LocalDimensionCumulOptimizer; -class LocalSearchOperator; +class LocalSearchPhaseParameters; #ifndef SWIG -class IntVarFilteredDecisionBuilder; -class IntVarFilteredHeuristic; class IndexNeighborFinder; +class IntVarFilteredDecisionBuilder; #endif class RoutingDimension; #ifndef SWIG using util::ReverseArcListGraph; class SweepArranger; #endif -struct SweepIndex; class RoutingModel { public: @@ -250,7 +241,7 @@ class RoutingModel { #if !defined(SWIG) /// What follows is relevant for models with time/state dependent transits. - /// Such transits, say from node A to node B, are functions f: int64->int64 + /// Such transits, say from node A to node B, are functions f: int64_t->int64_t /// of the cumuls of a dimension. The user is free to implement the abstract /// RangeIntToIntFunction interface, but it is expected that the /// implementation of each method is quite fast. For performance-related @@ -265,7 +256,7 @@ class RoutingModel { RangeIntToIntFunction* transit; /// f(x) RangeMinMaxIndexFunction* transit_plus_identity; /// g(x) = f(x) + x }; - typedef std::function + typedef std::function VariableIndexEvaluator2; #endif // SWIG @@ -295,8 +286,8 @@ class RoutingModel { /// Index) and their span cost coefficient, we just store those. /// This is sorted by the natural operator < (and *not* by DimensionIndex). struct DimensionCost { - int64 transit_evaluator_class; - int64 cost_coefficient; + int64_t transit_evaluator_class; + int64_t cost_coefficient; const RoutingDimension* dimension; bool operator<(const DimensionCost& cost) const { if (transit_evaluator_class != cost.transit_evaluator_class) { @@ -325,7 +316,7 @@ class RoutingModel { /// The cost class of the vehicle. CostClassIndex cost_class_index; /// Contrarily to CostClass, here we need strict equivalence. - int64 fixed_cost; + int64_t fixed_cost; /// Vehicle start and end equivalence classes. Currently if two vehicles /// have different start/end nodes which are "physically" located at the /// same place, these two vehicles will be considered as non-equivalent @@ -336,16 +327,16 @@ class RoutingModel { int end_equivalence_class; /// Bounds of cumul variables at start and end vehicle nodes. /// dimension_{start,end}_cumuls_{min,max}[d] is the bound for dimension d. - absl::StrongVector dimension_start_cumuls_min; - absl::StrongVector dimension_start_cumuls_max; - absl::StrongVector dimension_end_cumuls_min; - absl::StrongVector dimension_end_cumuls_max; - absl::StrongVector dimension_capacities; + absl::StrongVector dimension_start_cumuls_min; + absl::StrongVector dimension_start_cumuls_max; + absl::StrongVector dimension_end_cumuls_min; + absl::StrongVector dimension_end_cumuls_max; + absl::StrongVector dimension_capacities; /// dimension_evaluators[d]->Run(from, to) is the transit value of arc /// from->to for a dimension d. - absl::StrongVector dimension_evaluator_classes; + absl::StrongVector dimension_evaluator_classes; /// Fingerprint of unvisitable non-start/end nodes. - uint64 unvisitable_nodes_fprint; + uint64_t unvisitable_nodes_fprint; /// Comparator for STL containers and algorithms. static bool LessThan(const VehicleClass& a, const VehicleClass& b); @@ -358,7 +349,7 @@ class RoutingModel { struct VehicleTypeContainer { struct VehicleClassEntry { int vehicle_class; - int64 fixed_cost; + int64_t fixed_cost; bool operator<(const VehicleClassEntry& other) const { return std::tie(fixed_cost, vehicle_class) < @@ -381,7 +372,7 @@ class RoutingModel { }; /// Constant used to express a hard constraint instead of a soft penalty. - static const int64 kNoPenalty; + static const int64_t kNoPenalty; /// Constant used to express the "no disjunction" index, returned when a node /// does not appear in any disjunction. @@ -400,12 +391,12 @@ class RoutingModel { ~RoutingModel(); /// Registers 'callback' and returns its index. - int RegisterUnaryTransitVector(std::vector values); + int RegisterUnaryTransitVector(std::vector values); int RegisterUnaryTransitCallback(TransitCallback1 callback); int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback); int RegisterTransitMatrix( - std::vector /*needed_for_swig*/> values); + std::vector /*needed_for_swig*/> values); int RegisterTransitCallback(TransitCallback2 callback); int RegisterPositiveTransitCallback(TransitCallback2 callback); @@ -446,18 +437,18 @@ class RoutingModel { /// Returns false if a dimension with the same name has already been created /// (and doesn't create the new dimension). /// Takes ownership of the callback 'evaluator'. - bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, + bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name); bool AddDimensionWithVehicleTransits( - const std::vector& evaluator_indices, int64 slack_max, - int64 capacity, bool fix_start_cumul_to_zero, const std::string& name); - bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, - std::vector vehicle_capacities, + const std::vector& evaluator_indices, int64_t slack_max, + int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name); + bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name); bool AddDimensionWithVehicleTransitAndCapacity( - const std::vector& evaluator_indices, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::vector& evaluator_indices, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name); /// Creates a dimension where the transit variable is constrained to be /// equal to 'value'; 'capacity' is the upper bound of the cumul variables. @@ -468,9 +459,9 @@ class RoutingModel { /// It is false if a dimension with the same name has already been created /// (and doesn't create the new dimension but still register a new callback). std::pair AddConstantDimensionWithSlack( - int64 value, int64 capacity, int64 slack_max, + int64_t value, int64_t capacity, int64_t slack_max, bool fix_start_cumul_to_zero, const std::string& name); - std::pair AddConstantDimension(int64 value, int64 capacity, + std::pair AddConstantDimension(int64_t value, int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name) { return AddConstantDimensionWithSlack(value, capacity, 0, @@ -485,8 +476,8 @@ class RoutingModel { /// callback and a bool denoting whether the dimension has been created. /// It is false if a dimension with the same name has already been created /// (and doesn't create the new dimension but still register a new callback). - std::pair AddVectorDimension(std::vector values, - int64 capacity, + std::pair AddVectorDimension(std::vector values, + int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name); /// Creates a dimension where the transit variable is constrained to be @@ -499,8 +490,8 @@ class RoutingModel { /// It is false if a dimension with the same name has already been created /// (and doesn't create the new dimension but still register a new callback). std::pair AddMatrixDimension( - std::vector /*needed_for_swig*/> values, - int64 capacity, bool fix_start_cumul_to_zero, const std::string& name); + std::vector /*needed_for_swig*/> values, + int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name); /// Creates a dimension with transits depending on the cumuls of another /// dimension. 'pure_transits' are the per-vehicle fixed transits as above. /// 'dependent_transits' is a vector containing for each vehicle an index to a @@ -510,8 +501,8 @@ class RoutingModel { bool AddDimensionDependentDimensionWithVehicleCapacity( const std::vector& pure_transits, const std::vector& dependent_transits, - const RoutingDimension* base_dimension, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name) { return AddDimensionDependentDimensionWithVehicleCapacityInternal( pure_transits, dependent_transits, base_dimension, slack_max, @@ -521,23 +512,23 @@ class RoutingModel { /// As above, but pure_transits are taken to be zero evaluators. bool AddDimensionDependentDimensionWithVehicleCapacity( const std::vector& transits, const RoutingDimension* base_dimension, - int64 slack_max, std::vector vehicle_capacities, + int64_t slack_max, std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name); /// Homogeneous versions of the functions above. bool AddDimensionDependentDimensionWithVehicleCapacity( - int transit, const RoutingDimension* base_dimension, int64 slack_max, - int64 vehicle_capacity, bool fix_start_cumul_to_zero, + int transit, const RoutingDimension* base_dimension, int64_t slack_max, + int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string& name); bool AddDimensionDependentDimensionWithVehicleCapacity( int pure_transit, int dependent_transit, - const RoutingDimension* base_dimension, int64 slack_max, - int64 vehicle_capacity, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string& name); /// Creates a cached StateDependentTransit from an std::function. static RoutingModel::StateDependentTransit MakeStateDependentTransit( - const std::function& f, int64 domain_start, - int64 domain_end); + const std::function& f, int64_t domain_start, + int64_t domain_end); /// For every vehicle of the routing model: /// - if total_slacks[vehicle] is not nullptr, constrains it to be the sum of @@ -624,12 +615,12 @@ class RoutingModel { /// performed, and therefore p == 0. /// Note: passing a vector with a single index will model an optional index /// with a penalty cost if it is not visited. - DisjunctionIndex AddDisjunction(const std::vector& indices, - int64 penalty = kNoPenalty, - int64 max_cardinality = 1); + DisjunctionIndex AddDisjunction(const std::vector& indices, + int64_t penalty = kNoPenalty, + int64_t max_cardinality = 1); /// Returns the indices of the disjunctions to which an index belongs. const std::vector& GetDisjunctionIndices( - int64 index) const { + int64_t index) const { return index_to_disjunctions_[index]; } /// Calls f for each variable index of indices in the same disjunctions as the @@ -637,10 +628,10 @@ class RoutingModel { /// cardinality 'cardinality' are considered. template void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex( - int64 index, int64 max_cardinality, F f) const { + int64_t index, int64_t max_cardinality, F f) const { for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) { if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) { - for (const int64 d_index : disjunctions_[disjunction].indices) { + for (const int64_t d_index : disjunctions_[disjunction].indices) { f(d_index); } } @@ -649,18 +640,18 @@ class RoutingModel { #if !defined(SWIGPYTHON) /// Returns the variable indices of the nodes in the disjunction of index /// 'index'. - const std::vector& GetDisjunctionIndices( + const std::vector& GetDisjunctionIndices( DisjunctionIndex index) const { return disjunctions_[index].indices; } #endif // !defined(SWIGPYTHON) /// Returns the penalty of the node disjunction of index 'index'. - int64 GetDisjunctionPenalty(DisjunctionIndex index) const { + int64_t GetDisjunctionPenalty(DisjunctionIndex index) const { return disjunctions_[index].value.penalty; } /// Returns the maximum number of possible active nodes of the node /// disjunction of index 'index'. - int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const { + int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const { return disjunctions_[index].value.max_cardinality; } /// Returns the number of node disjunctions in the model. @@ -669,7 +660,7 @@ class RoutingModel { /// indices: a disjunction is "perfect" when its variables do not appear in /// any other disjunction. Each pair is sorted (lowest variable index first), /// and the output vector is also sorted (lowest pairs first). - std::vector> GetPerfectBinaryDisjunctions() const; + std::vector> GetPerfectBinaryDisjunctions() const; /// SPECIAL: Makes the solver ignore all the disjunctions whose active /// variables are all trivially zero (i.e. Max() == 0), by setting their /// max_cardinality to 0. @@ -680,18 +671,18 @@ class RoutingModel { /// Adds a soft constraint to force a set of variable indices to be on the /// same vehicle. If all nodes are not on the same vehicle, each extra vehicle /// used adds 'cost' to the cost function. - void AddSoftSameVehicleConstraint(const std::vector& indices, - int64 cost); + void AddSoftSameVehicleConstraint(const std::vector& indices, + int64_t cost); /// Sets the vehicles which can visit a given node. If the node is in a /// disjunction, this will not prevent it from being unperformed. /// Specifying an empty vector of vehicles has no effect (all vehicles /// will be allowed to visit the node). void SetAllowedVehiclesForIndex(const std::vector& vehicles, - int64 index); + int64_t index); /// Returns true if a vehicle is allowed to visit a given node. - bool IsVehicleAllowedForIndex(int vehicle, int64 index) { + bool IsVehicleAllowedForIndex(int vehicle, int64_t index) { return allowed_vehicles_[index].empty() || allowed_vehicles_[index].find(vehicle) != allowed_vehicles_[index].end(); @@ -704,15 +695,15 @@ class RoutingModel { /// the vehicle variables of two node (including for instance pickup and /// delivery problems): /// Solver* const solver = routing.solver(); - /// int64 index1 = manager.NodeToIndex(node1); - /// int64 index2 = manager.NodeToIndex(node2); + /// int64_t index1 = manager.NodeToIndex(node1); + /// int64_t index2 = manager.NodeToIndex(node2); /// solver->AddConstraint(solver->MakeEquality( /// routing.VehicleVar(index1), /// routing.VehicleVar(index2))); /// routing.AddPickupAndDelivery(index1, index2); /// // TODO(user): Remove this when model introspection detects linked nodes. - void AddPickupAndDelivery(int64 pickup, int64 delivery); + void AddPickupAndDelivery(int64_t pickup, int64_t delivery); /// Same as AddPickupAndDelivery but notifying that the performed node from /// the disjunction of index 'pickup_disjunction' is on the same route as the /// performed node from the disjunction of index 'delivery_disjunction'. @@ -723,10 +714,10 @@ class RoutingModel { /// pair is the index in the pickup and delivery pairs list in which the /// pickup appears, the second element is its index in the pickups list. const std::vector >& - GetPickupIndexPairs(int64 node_index) const; + GetPickupIndexPairs(int64_t node_index) const; /// Same as above for deliveries. const std::vector >& - GetDeliveryIndexPairs(int64 node_index) const; + GetDeliveryIndexPairs(int64_t node_index) const; // clang-format on /// Sets the Pickup and delivery policy of all vehicles. It is equivalent to @@ -788,11 +779,11 @@ class RoutingModel { TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED }; // TODO(user): Support multiple visit types per node? - void SetVisitType(int64 index, int type, VisitTypePolicy type_policy); - int GetVisitType(int64 index) const; + void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy); + int GetVisitType(int64_t index) const; const std::vector& GetSingleNodesOfType(int type) const; const std::vector& GetPairIndicesOfType(int type) const; - VisitTypePolicy GetVisitTypePolicy(int64 index) const; + VisitTypePolicy GetVisitTypePolicy(int64_t index) const; /// This function should be called once all node visit types have been set and /// prior to adding any incompatibilities/requirements. // TODO(user): Reconsider the logic and potentially remove the need to @@ -883,15 +874,15 @@ class RoutingModel { /// node is only part of a single Disjunction involving only itself, and that /// disjunction has a penalty. In all other cases, including forced active /// nodes, this returns 0. - int64 UnperformedPenalty(int64 var_index) const; + int64_t UnperformedPenalty(int64_t var_index) const; /// Same as above except that it returns default_value instead of 0 when /// penalty is not well defined (default value is passed as first argument to /// simplify the usage of the method in a callback). - int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const; + int64_t UnperformedPenaltyOrValue(int64_t default_value, int64_t var_index) const; /// Returns the variable index of the first starting or ending node of all /// routes. If all routes start and end at the same node (single depot), this /// is the node returned. - int64 GetDepot() const; + int64_t GetDepot() const; /// Constrains the maximum number of active vehicles, aka the number of /// vehicles which do not have an empty route. For instance, this can be used @@ -910,13 +901,13 @@ class RoutingModel { void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle); /// Sets the fixed cost of all vehicle routes. It is equivalent to calling /// SetFixedCostOfVehicle on all vehicle routes. - void SetFixedCostOfAllVehicles(int64 cost); + void SetFixedCostOfAllVehicles(int64_t cost); /// Sets the fixed cost of one vehicle route. - void SetFixedCostOfVehicle(int64 cost, int vehicle); + void SetFixedCostOfVehicle(int64_t cost, int vehicle); /// Returns the route fixed cost taken into account if the route of the /// vehicle is not empty, aka there's at least one node on the route other /// than the first and last nodes. - int64 GetFixedCostOfVehicle(int vehicle) const; + int64_t GetFixedCostOfVehicle(int vehicle) const; /// The following methods set the linear and quadratic cost factors of /// vehicles (must be positive values). The default value of these parameters @@ -933,17 +924,17 @@ class RoutingModel { /// factor. This second term aims at making the routes as dense as possible. /// /// Sets the linear and quadratic cost factor of all vehicles. - void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor, - int64 quadratic_cost_factor); + void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor, + int64_t quadratic_cost_factor); /// Sets the linear and quadratic cost factor of the given vehicle. - void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, - int64 quadratic_cost_factor, + void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor, + int64_t quadratic_cost_factor, int vehicle); - const std::vector& GetAmortizedLinearCostFactorOfVehicles() const { + const std::vector& GetAmortizedLinearCostFactorOfVehicles() const { return linear_cost_factor_of_vehicle_; } - const std::vector& GetAmortizedQuadraticCostFactorOfVehicles() const { + const std::vector& GetAmortizedQuadraticCostFactorOfVehicles() const { return quadratic_cost_factor_of_vehicle_; } @@ -987,10 +978,10 @@ class RoutingModel { void AddVariableMaximizedByFinalizer(IntVar* var); /// Adds a variable to minimize in the solution finalizer, with a weighted /// priority: the higher the more priority it has. - void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost); + void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64_t cost); /// Add a variable to set the closest possible to the target value in the /// solution finalizer. - void AddVariableTargetToFinalizer(IntVar* var, int64 target); + void AddVariableTargetToFinalizer(IntVar* var, int64_t target); /// Closes the current routing model; after this method is called, no /// modification to the model can be done, but RoutesToAssignment becomes /// available. Note that CloseModel() is automatically called by Solve() and @@ -1019,10 +1010,18 @@ class RoutingModel { const Assignment* SolveWithParameters( const RoutingSearchParameters& search_parameters, std::vector* solutions = nullptr); + /// Same as above, except that if assignment is not null, it will be used as + /// the initial solution. const Assignment* SolveFromAssignmentWithParameters( const Assignment* assignment, const RoutingSearchParameters& search_parameters, std::vector* solutions = nullptr); + /// Same as above but will try all assignments in order as first solutions + /// until one succeeds. + const Assignment* SolveFromAssignmentsWithParameters( + const std::vector& assignments, + const RoutingSearchParameters& search_parameters, + std::vector* solutions = nullptr); /// Given a "source_model" and its "source_assignment", resets /// "target_assignment" with the IntVar variables (nexts_, and vehicle_vars_ /// if costs aren't homogeneous across vehicles) of "this" model, with the @@ -1037,7 +1036,7 @@ class RoutingModel { /// nodes) and non-homogenous costs are not supported (the method returns 0 in /// these cases). // TODO(user): Add support for non-homogeneous costs and disjunctions. - int64 ComputeLowerBound(); + int64_t ComputeLowerBound(); /// Returns the current status of the routing model. Status status() const { return status_; } /// Applies a lock chain to the next search. 'locks' represents an ordered @@ -1048,7 +1047,7 @@ class RoutingModel { /// Returns the next variable at the end of the locked chain; this variable is /// not locked. An assignment containing the locks can be obtained by calling /// PreAssignment(). - IntVar* ApplyLocks(const std::vector& locks); + IntVar* ApplyLocks(const std::vector& locks); /// Applies lock chains to all vehicles to the next search, such that locks[p] /// is the lock chain for route p. Returns false if the locks do not contain /// valid routes; expects that the routes do not contain the depots, @@ -1057,7 +1056,7 @@ class RoutingModel { /// vehicle and deactivates other nodes. /// An assignment containing the locks can be obtained by calling /// PreAssignment(). - bool ApplyLocksToAllVehicles(const std::vector>& locks, + bool ApplyLocksToAllVehicles(const std::vector>& locks, bool close_routes); /// Returns an assignment used to fix some of the variables of the problem. /// In practice, this assignment locks partial routes of the problem. This @@ -1082,7 +1081,7 @@ class RoutingModel { /// dimension variables; this may take considerable amount of time, especially /// when using dimensions with slack. Assignment* ReadAssignmentFromRoutes( - const std::vector>& routes, + const std::vector>& routes, bool ignore_inactive_indices); /// Fills an assignment from a specification of the routes of the /// vehicles. The routes are specified as lists of variable indices that @@ -1100,20 +1099,20 @@ class RoutingModel { /// loaded. However, such assignment still might not be a valid /// solution to the routing problem due to more complex constraints; /// it is advisible to call solver()->CheckSolution() afterwards. - bool RoutesToAssignment(const std::vector>& routes, + bool RoutesToAssignment(const std::vector>& routes, bool ignore_inactive_indices, bool close_routes, Assignment* const assignment) const; /// Converts the solution in the given assignment to routes for all vehicles. /// Expects that assignment contains a valid solution (i.e. routes for all /// vehicles end with an end index for that vehicle). void AssignmentToRoutes(const Assignment& assignment, - std::vector>* const routes) const; + std::vector>* const routes) const; /// Converts the solution in the given assignment to routes for all vehicles. /// If the returned vector is route_indices, route_indices[i][j] is the index /// for jth location visited on route i. Note that contrary to /// AssignmentToRoutes, the vectors do include start and end locations. #ifndef SWIG - std::vector> GetRoutesFromAssignment( + std::vector> GetRoutesFromAssignment( const Assignment& assignment); #endif /// Returns a compacted version of the given assignment, in which all vehicles @@ -1155,11 +1154,9 @@ class RoutingModel { const Assignment* original_assignment, absl::Duration duration_limit); #ifndef SWIG // TODO(user): Revisit if coordinates are added to the RoutingModel class. - void SetSweepArranger(SweepArranger* sweep_arranger) { - sweep_arranger_.reset(sweep_arranger); - } + void SetSweepArranger(SweepArranger* sweep_arranger); /// Returns the sweep arranger to be used by routing heuristics. - SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); } + SweepArranger* sweep_arranger() const; #endif /// Adds a custom local search filter to the list of filters used to speed up /// local search by pruning unfeasible variable assignments. @@ -1177,20 +1174,20 @@ class RoutingModel { /// Model inspection. /// Returns the variable index of the starting node of a vehicle route. - int64 Start(int vehicle) const { return starts_[vehicle]; } + int64_t Start(int vehicle) const { return starts_[vehicle]; } /// Returns the variable index of the ending node of a vehicle route. - int64 End(int vehicle) const { return ends_[vehicle]; } + int64_t End(int vehicle) const { return ends_[vehicle]; } /// Returns true if 'index' represents the first node of a route. - bool IsStart(int64 index) const; + bool IsStart(int64_t index) const; /// Returns true if 'index' represents the last node of a route. - bool IsEnd(int64 index) const { return index >= Size(); } + bool IsEnd(int64_t index) const { return index >= Size(); } /// Returns the vehicle of the given start/end index, and -1 if the given /// index is not a vehicle start/end. - int VehicleIndex(int64 index) const { return index_to_vehicle_[index]; } + int VehicleIndex(int64_t index) const { return index_to_vehicle_[index]; } /// Assignment inspection /// Returns the variable index of the node directly after the node /// corresponding to 'index' in 'assignment'. - int64 Next(const Assignment& assignment, int64 index) const; + int64_t Next(const Assignment& assignment, int64_t index) const; /// Returns true if the route of 'vehicle' is non empty in 'assignment'. bool IsVehicleUsed(const Assignment& assignment, int vehicle) const; @@ -1204,9 +1201,9 @@ class RoutingModel { #endif /// !defined(SWIGPYTHON) /// Returns the next variable of the node corresponding to index. Note that /// NextVar(index) == index is equivalent to ActiveVar(index) == 0. - IntVar* NextVar(int64 index) const { return nexts_[index]; } + IntVar* NextVar(int64_t index) const { return nexts_[index]; } /// Returns the active variable of the node corresponding to index. - IntVar* ActiveVar(int64 index) const { return active_[index]; } + IntVar* ActiveVar(int64_t index) const { return active_[index]; } /// Returns the active variable of the vehicle. It will be equal to 1 iff the /// route of the vehicle is not empty, 0 otherwise. IntVar* ActiveVehicleVar(int vehicle) const { @@ -1219,36 +1216,36 @@ class RoutingModel { } /// Returns the vehicle variable of the node corresponding to index. Note that /// VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0. - IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; } + IntVar* VehicleVar(int64_t index) const { return vehicle_vars_[index]; } /// Returns the global cost variable which is being minimized. IntVar* CostVar() const { return cost_; } /// Returns the cost of the transit arc between two nodes for a given vehicle. /// Input are variable indices of node. This returns 0 if vehicle < 0. - int64 GetArcCostForVehicle(int64 from_index, int64 to_index, - int64 vehicle) const; + int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index, + int64_t vehicle) const; /// Whether costs are homogeneous across all vehicles. bool CostsAreHomogeneousAcrossVehicles() const { return costs_are_homogeneous_across_vehicles_; } /// Returns the cost of the segment between two nodes supposing all vehicle /// costs are the same (returns the cost for the first vehicle otherwise). - int64 GetHomogeneousCost(int64 from_index, int64 to_index) const { + int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const { return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0); } /// Returns the cost of the arc in the context of the first solution strategy. /// This is typically a simplification of the actual cost; see the .cc. - int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const; + int64_t GetArcCostForFirstSolution(int64_t from_index, int64_t to_index) const; /// Returns the cost of the segment between two nodes for a given cost /// class. Input are variable indices of nodes and the cost class. /// Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the /// returned cost won't necessarily be zero: only some of the components /// of the cost that depend on the cost class will be omited. See the code /// for details. - int64 GetArcCostForClass(int64 from_index, int64 to_index, - int64 /*CostClassIndex*/ cost_class_index) const; + int64_t GetArcCostForClass(int64_t from_index, int64_t to_index, + int64_t /*CostClassIndex*/ cost_class_index) const; /// Get the cost class index of the given vehicle. - CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const { + CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const { DCHECK(closed_); DCHECK_GE(vehicle, 0); DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size()); @@ -1270,7 +1267,7 @@ class RoutingModel { int GetNonZeroCostClassesCount() const { return std::max(0, GetCostClassesCount() - 1); } - VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const { + VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const { DCHECK(closed_); return vehicle_class_index_of_vehicle_[vehicle]; } @@ -1305,7 +1302,7 @@ class RoutingModel { /// from: the variable index of the source node /// to1: the variable index of the first candidate destination node. /// to2: the variable index of the second candidate destination node. - bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2); + bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2); /// Print some debugging information about an assignment, including the /// feasible intervals of the CumulVar for dimension "dimension_to_print" /// at each step of the routes. @@ -1319,7 +1316,7 @@ class RoutingModel { /// - cumul_bounds[i][j].first is the minimum. /// - cumul_bounds[i][j].second is the maximum. #ifndef SWIG - std::vector>> GetCumulBounds( + std::vector>> GetCumulBounds( const Assignment& solution_assignment, const RoutingDimension& dimension); #endif /// Returns the underlying constraint solver. Can be used to add extra @@ -1344,13 +1341,13 @@ class RoutingModel { /// Returns the number of vehicle routes in the model. int vehicles() const { return vehicles_; } /// Returns the number of next variables in the model. - int64 Size() const { return nodes_ + vehicles_ - start_end_count_; } + int64_t Size() const { return nodes_ + vehicles_ - start_end_count_; } /// Returns statistics on first solution search, number of decisions sent to /// filters, number of decisions rejected by filters. - int64 GetNumberOfDecisionsInFirstSolution( + int64_t GetNumberOfDecisionsInFirstSolution( const RoutingSearchParameters& search_parameters) const; - int64 GetNumberOfRejectsInFirstSolution( + int64_t GetNumberOfRejectsInFirstSolution( const RoutingSearchParameters& search_parameters) const; /// Returns the automatic first solution strategy selected. operations_research::FirstSolutionStrategy::Value @@ -1385,7 +1382,7 @@ class RoutingModel { /// 1, slack[i] = x - 1, slack[i] = x + 2, etc. DecisionBuilder* MakeGuidedSlackFinalizer( const RoutingDimension* dimension, - std::function initializer); + std::function initializer); #ifndef SWIG // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h. /// Perhaps move it to constraint_solver.h. @@ -1457,44 +1454,44 @@ class RoutingModel { /// when unperformed). template struct ValuedNodes { - std::vector indices; + std::vector indices; T value; }; struct DisjunctionValues { - int64 penalty; - int64 max_cardinality; + int64_t penalty; + int64_t max_cardinality; }; typedef ValuedNodes Disjunction; /// Storage of a cost cache element corresponding to a cost arc ending at /// node 'index' and on the cost class 'cost_class'. struct CostCacheElement { - /// This is usually an int64, but using an int here decreases the RAM usage, + /// This is usually an int64_t, but using an int here decreases the RAM usage, /// and should be fine since in practice we never have more than 1<<31 vars. /// Note(user): on 2013-11, microbenchmarks on the arc costs callbacks - /// also showed a 2% speed-up thanks to using int rather than int64. + /// also showed a 2% speed-up thanks to using int rather than int64_t. int index; CostClassIndex cost_class_index; - int64 cost; + int64_t cost; }; /// Internal methods. void Initialize(); void AddNoCycleConstraintInternal(); bool AddDimensionWithCapacityInternal( - const std::vector& evaluator_indices, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::vector& evaluator_indices, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name); bool AddDimensionDependentDimensionWithVehicleCapacityInternal( const std::vector& pure_transits, const std::vector& dependent_transits, - const RoutingDimension* base_dimension, int64 slack_max, - std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const RoutingDimension* base_dimension, int64_t slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, const std::string& name); bool InitializeDimensionInternal( const std::vector& evaluator_indices, const std::vector& state_dependent_evaluator_indices, - int64 slack_max, bool fix_start_cumul_to_zero, + int64_t slack_max, bool fix_start_cumul_to_zero, RoutingDimension* dimension); DimensionIndex GetDimensionIndex(const std::string& dimension_name) const; @@ -1549,7 +1546,7 @@ class RoutingModel { void FinalizeVisitTypes(); // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_. void TopologicallySortVisitTypes(); - int64 GetArcCostForClassInternal(int64 from_index, int64 to_index, + int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index, CostClassIndex cost_class_index) const; void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters, int node_index, @@ -1558,25 +1555,25 @@ class RoutingModel { std::vector* cost_elements); Assignment* DoRestoreAssignment(); static const CostClassIndex kCostClassIndexOfZeroCost; - int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const { + int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle) const { DCHECK_LT(0, vehicles_); return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle) : kCostClassIndexOfZeroCost) .value(); } - int64 GetDimensionTransitCostSum(int64 i, int64 j, + int64_t GetDimensionTransitCostSum(int64_t i, int64_t j, const CostClass& cost_class) const; /// Returns nullptr if no penalty cost, otherwise returns penalty variable. IntVar* CreateDisjunction(DisjunctionIndex disjunction); /// Sets up pickup and delivery sets. - void AddPickupAndDeliverySetsInternal(const std::vector& pickups, - const std::vector& deliveries); + void AddPickupAndDeliverySetsInternal(const std::vector& pickups, + const std::vector& deliveries); /// Returns the cost variable related to the soft same vehicle constraint of /// index 'vehicle_index'. IntVar* CreateSameVehicleCost(int vehicle_index); /// Returns the first active variable index in 'indices' starting from index /// + 1. - int FindNextActive(int index, const std::vector& indices) const; + int FindNextActive(int index, const std::vector& indices) const; /// Checks that all nodes on the route starting at start_index (using the /// solution stored in assignment) can be visited by the given vehicle. @@ -1611,8 +1608,8 @@ class RoutingModel { #endif /// Log a solution. void LogSolution(const RoutingSearchParameters& parameters, - const std::string& description, int64 solution_cost, - int64 start_time_ms); + const std::string& description, int64_t solution_cost, + int64_t start_time_ms); /// See CompactAssignment. Checks the final solution if /// check_compact_assignement is true. Assignment* CompactAssignmentInternal(const Assignment& assignment, @@ -1705,7 +1702,7 @@ class RoutingModel { // implicit delivery is equal to -d. void DetectImplicitPickupAndDeliveries(); - int GetVehicleStartClass(int64 start) const; + int GetVehicleStartClass(int64_t start) const; void InitSameVehicleGroups(int number_of_groups) { same_vehicle_group_.assign(Size(), 0); @@ -1722,7 +1719,7 @@ class RoutingModel { int vehicles_; int max_active_vehicles_; Constraint* no_cycle_constraint_ = nullptr; - /// Decision variables: indexed by int64 var index. + /// Decision variables: indexed by int64_t var index. std::vector nexts_; std::vector vehicle_vars_; std::vector active_; @@ -1755,11 +1752,11 @@ class RoutingModel { /// Costs IntVar* cost_ = nullptr; std::vector vehicle_to_transit_cost_; - std::vector fixed_cost_of_vehicle_; + std::vector fixed_cost_of_vehicle_; std::vector cost_class_index_of_vehicle_; bool has_vehicle_with_zero_cost_class_; - std::vector linear_cost_factor_of_vehicle_; - std::vector quadratic_cost_factor_of_vehicle_; + std::vector linear_cost_factor_of_vehicle_; + std::vector quadratic_cost_factor_of_vehicle_; bool vehicle_amortized_cost_factors_set_; /// consider_empty_route_costs_[vehicle] determines if "vehicle" should be /// taken into account for costs (arc costs, span costs, etc.) even when the @@ -1783,12 +1780,12 @@ class RoutingModel { absl::StrongVector vehicle_classes_; #endif // SWIG VehicleTypeContainer vehicle_type_container_; - std::function vehicle_start_class_callback_; + std::function vehicle_start_class_callback_; /// Disjunctions absl::StrongVector disjunctions_; std::vector > index_to_disjunctions_; /// Same vehicle costs - std::vector > same_vehicle_costs_; + std::vector > same_vehicle_costs_; /// Allowed vehicles #ifndef SWIG std::vector> allowed_vehicles_; @@ -1861,8 +1858,8 @@ class RoutingModel { // to the constructors taking a RoutingIndexManager). std::vector index_to_equivalence_class_; std::vector index_to_vehicle_; - std::vector starts_; - std::vector ends_; + std::vector starts_; + std::vector ends_; // TODO(user): b/62478706 Once the port is done, this shouldn't be needed // anymore. RoutingIndexManager manager_; @@ -1899,8 +1896,8 @@ class RoutingModel { LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr; std::vector extra_filters_; #ifndef SWIG - std::vector> finalizer_variable_cost_pairs_; - std::vector> finalizer_variable_target_pairs_; + std::vector> finalizer_variable_cost_pairs_; + std::vector> finalizer_variable_target_pairs_; absl::flat_hash_map finalizer_variable_cost_index_; absl::flat_hash_set finalizer_variable_target_set_; std::unique_ptr sweep_arranger_; @@ -1911,8 +1908,8 @@ class RoutingModel { RegularLimit* lns_limit_ = nullptr; RegularLimit* first_solution_lns_limit_ = nullptr; - typedef std::pair CacheKey; - typedef absl::flat_hash_map TransitCallbackCache; + typedef std::pair CacheKey; + typedef absl::flat_hash_map TransitCallbackCache; typedef absl::flat_hash_map StateDependentTransitCallbackCache; @@ -1960,17 +1957,17 @@ class DisjunctivePropagator { /// some variants of classic propagators. struct Tasks { int num_chain_tasks = 0; - std::vector start_min; - std::vector start_max; - std::vector duration_min; - std::vector duration_max; - std::vector end_min; - std::vector end_max; + std::vector start_min; + std::vector start_max; + std::vector duration_min; + std::vector duration_max; + std::vector end_min; + std::vector end_max; std::vector is_preemptible; std::vector forbidden_intervals; - std::vector> distance_duration; - int64 span_min = 0; - int64 span_max = kint64max; + std::vector> distance_duration; + int64_t span_min = 0; + int64_t span_max = kint64max; void Clear() { start_min.clear(); @@ -2018,33 +2015,33 @@ class DisjunctivePropagator { private: /// The main algorithm uses Vilim's theta tree data structure. /// See Petr Vilim's PhD thesis "Global Constraints in Scheduling". - sat::ThetaLambdaTree theta_lambda_tree_; + sat::ThetaLambdaTree theta_lambda_tree_; /// Mappings between events and tasks. std::vector tasks_by_start_min_; std::vector tasks_by_end_max_; std::vector event_of_task_; std::vector nonchain_tasks_by_start_max_; /// Maps chain elements to the sum of chain task durations before them. - std::vector total_duration_before_; + std::vector total_duration_before_; }; struct TravelBounds { - std::vector min_travels; - std::vector max_travels; - std::vector pre_travels; - std::vector post_travels; + std::vector min_travels; + std::vector max_travels; + std::vector pre_travels; + std::vector post_travels; }; -void AppendTasksFromPath(const std::vector& path, +void AppendTasksFromPath(const std::vector& path, const TravelBounds& travel_bounds, const RoutingDimension& dimension, DisjunctivePropagator::Tasks* tasks); void AppendTasksFromIntervals(const std::vector& intervals, DisjunctivePropagator::Tasks* tasks); -void FillPathEvaluation(const std::vector& path, +void FillPathEvaluation(const std::vector& path, const RoutingModel::TransitCallback2& evaluator, - std::vector* values); -void FillTravelBoundsOfVehicle(int vehicle, const std::vector& path, + std::vector* values); +void FillTravelBoundsOfVehicle(int vehicle, const std::vector& path, const RoutingDimension& dimension, TravelBounds* travel_bounds); #endif // !defined(SWIG) @@ -2077,14 +2074,14 @@ class GlobalVehicleBreaksConstraint : public Constraint { const RoutingModel* model_; const RoutingDimension* const dimension_; std::vector vehicle_demons_; - std::vector path_; + std::vector path_; /// Sets path_ to be the longest sequence such that /// _ path_[0] is the start of the vehicle /// _ Next(path_[i-1]) is Bound() and has value path_[i], /// followed by the end of the vehicle if the last node was not an end. void FillPartialPathOfVehicle(int vehicle); - void FillPathTravels(const std::vector& path); + void FillPathTravels(const std::vector& path); /// This translates pruning information to solver variables. /// If constructed with an IntervalVar*, it follows the usual semantics of @@ -2098,40 +2095,40 @@ class GlobalVehicleBreaksConstraint : public Constraint { /// more dynamic allocation will be made. class TaskTranslator { public: - TaskTranslator(IntVar* start, int64 before_start, int64 after_start) + TaskTranslator(IntVar* start, int64_t before_start, int64_t after_start) : start_(start), before_start_(before_start), after_start_(after_start) {} explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {} TaskTranslator() {} - void SetStartMin(int64 value) { + void SetStartMin(int64_t value) { if (start_ != nullptr) { start_->SetMin(CapAdd(before_start_, value)); } else if (interval_ != nullptr) { interval_->SetStartMin(value); } } - void SetStartMax(int64 value) { + void SetStartMax(int64_t value) { if (start_ != nullptr) { start_->SetMax(CapAdd(before_start_, value)); } else if (interval_ != nullptr) { interval_->SetStartMax(value); } } - void SetDurationMin(int64 value) { + void SetDurationMin(int64_t value) { if (interval_ != nullptr) { interval_->SetDurationMin(value); } } - void SetEndMin(int64 value) { + void SetEndMin(int64_t value) { if (start_ != nullptr) { start_->SetMin(CapSub(value, after_start_)); } else if (interval_ != nullptr) { interval_->SetEndMin(value); } } - void SetEndMax(int64 value) { + void SetEndMax(int64_t value) { if (start_ != nullptr) { start_->SetMax(CapSub(value, after_start_)); } else if (interval_ != nullptr) { @@ -2141,8 +2138,8 @@ class GlobalVehicleBreaksConstraint : public Constraint { private: IntVar* start_ = nullptr; - int64 before_start_; - int64 after_start_; + int64_t before_start_; + int64_t after_start_; IntervalVar* interval_ = nullptr; }; @@ -2163,7 +2160,7 @@ class TypeRegulationsChecker { virtual ~TypeRegulationsChecker() {} bool CheckVehicle(int vehicle, - const std::function& next_accessor); + const std::function& next_accessor); protected: #ifndef SWIG @@ -2202,7 +2199,7 @@ class TypeRegulationsChecker { bool TypeCurrentlyOnRoute(int type, int pos) const; void InitializeCheck(int vehicle, - const std::function& next_accessor); + const std::function& next_accessor); virtual void OnInitializeCheck() {} virtual bool HasRegulationsToCheck() const = 0; virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, @@ -2213,7 +2210,7 @@ class TypeRegulationsChecker { private: std::vector occurrences_of_type_; - std::vector current_route_visits_; + std::vector current_route_visits_; }; /// Checker for type incompatibilities. @@ -2329,8 +2326,8 @@ class TypeRegulationsConstraint : public Constraint { class SimpleBoundCosts { public: struct BoundCost { - int64 bound; - int64 cost; + int64_t bound; + int64_t cost; }; SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost) : bound_costs_(num_bounds, default_bound_cost) {} @@ -2373,24 +2370,24 @@ class RoutingDimension { /// Returns the transition value for a given pair of nodes (as var index); /// this value is the one taken by the corresponding transit variable when /// the 'next' variable for 'from_index' is bound to 'to_index'. - int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const; + int64_t GetTransitValue(int64_t from_index, int64_t to_index, int64_t vehicle) const; /// Same as above but taking a vehicle class of the dimension instead of a /// vehicle (the class of a vehicle can be obtained with vehicle_to_class()). - int64 GetTransitValueFromClass(int64 from_index, int64 to_index, - int64 vehicle_class) const { + int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index, + int64_t vehicle_class) const { return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index, to_index); } /// Get the cumul, transit and slack variables for the given node (given as - /// int64 var index). - IntVar* CumulVar(int64 index) const { return cumuls_[index]; } - IntVar* TransitVar(int64 index) const { return transits_[index]; } - IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; } - IntVar* SlackVar(int64 index) const { return slacks_[index]; } + /// int64_t var index). + IntVar* CumulVar(int64_t index) const { return cumuls_[index]; } + IntVar* TransitVar(int64_t index) const { return transits_[index]; } + IntVar* FixedTransitVar(int64_t index) const { return fixed_transits_[index]; } + IntVar* SlackVar(int64_t index) const { return slacks_[index]; } #if !defined(SWIGPYTHON) /// Like CumulVar(), TransitVar(), SlackVar() but return the whole variable - /// vectors instead (indexed by int64 var index). + /// vectors instead (indexed by int64_t var index). const std::vector& cumuls() const { return cumuls_; } const std::vector& fixed_transits() const { return fixed_transits_; } const std::vector& transits() const { return transits_; } @@ -2401,13 +2398,13 @@ class RoutingDimension { return forbidden_intervals_; } /// Returns allowed intervals for a given node in a given interval. - SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index, - int64 min_value, - int64 max_value) const; + SortedDisjointIntervalList GetAllowedIntervalsInRange(int64_t index, + int64_t min_value, + int64_t max_value) const; /// Returns the smallest value outside the forbidden intervals of node 'index' /// that is greater than or equal to a given 'min_value'. - int64 GetFirstPossibleGreaterOrEqualValueForNode(int64 index, - int64 min_value) const { + int64_t GetFirstPossibleGreaterOrEqualValueForNode(int64_t index, + int64_t min_value) const { DCHECK_LT(index, forbidden_intervals_.size()); const SortedDisjointIntervalList& forbidden_intervals = forbidden_intervals_[index]; @@ -2425,8 +2422,8 @@ class RoutingDimension { /// that is less than or equal to a given 'max_value'. /// NOTE: If this method is called with a max_value lower than the node's /// cumul min, it will return -1. - int64 GetLastPossibleLessOrEqualValueForNode(int64 index, - int64 max_value) const { + int64_t GetLastPossibleLessOrEqualValueForNode(int64_t index, + int64_t max_value) const { DCHECK_LT(index, forbidden_intervals_.size()); const SortedDisjointIntervalList& forbidden_intervals = forbidden_intervals_[index]; @@ -2441,7 +2438,7 @@ class RoutingDimension { return max_value; } /// Returns the capacities for all vehicles. - const std::vector& vehicle_capacities() const { + const std::vector& vehicle_capacities() const { return vehicle_capacities_; } /// Returns the callback evaluating the transit value between two node indices @@ -2470,37 +2467,37 @@ class RoutingDimension { /// Sets an upper bound on the dimension span on a given vehicle. This is the /// preferred way to limit the "length" of the route of a vehicle according to /// a dimension. - void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle); + void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle); /// Sets a cost proportional to the dimension span on a given vehicle, /// or on all vehicles at once. "coefficient" must be nonnegative. /// This is handy to model costs proportional to idle time when the dimension /// represents time. /// The cost for a vehicle is /// span_cost = coefficient * (dimension end value - dimension start value). - void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle); - void SetSpanCostCoefficientForAllVehicles(int64 coefficient); + void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle); + void SetSpanCostCoefficientForAllVehicles(int64_t coefficient); /// Sets a cost proportional to the *global* dimension span, that is the /// difference between the largest value of route end cumul variables and /// the smallest value of route start cumul variables. /// In other words: /// global_span_cost = /// coefficient * (Max(dimension end value) - Min(dimension start value)). - void SetGlobalSpanCostCoefficient(int64 coefficient); + void SetGlobalSpanCostCoefficient(int64_t coefficient); #ifndef SWIG /// Sets a piecewise linear cost on the cumul variable of a given variable /// index. If f is a piecewise linear function, the resulting cost at 'index' /// will be f(CumulVar(index)). As of 3/2017, only non-decreasing positive /// cost functions are supported. - void SetCumulVarPiecewiseLinearCost(int64 index, + void SetCumulVarPiecewiseLinearCost(int64_t index, const PiecewiseLinearFunction& cost); /// Returns true if a piecewise linear cost has been set for a given variable /// index. - bool HasCumulVarPiecewiseLinearCost(int64 index) const; + bool HasCumulVarPiecewiseLinearCost(int64_t index) const; /// Returns the piecewise linear cost of a cumul variable for a given variable /// index. The returned pointer has the same validity as this class. const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost( - int64 index) const; + int64_t index) const; #endif /// Sets a soft upper bound to the cumul variable of a given variable index. @@ -2511,19 +2508,19 @@ class RoutingDimension { /// cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound) /// This is also handy to model tardiness costs when the dimension represents /// time. - void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, - int64 coefficient); + void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound, + int64_t coefficient); /// Returns true if a soft upper bound has been set for a given variable /// index. - bool HasCumulVarSoftUpperBound(int64 index) const; + bool HasCumulVarSoftUpperBound(int64_t index) const; /// Returns the soft upper bound of a cumul variable for a given variable /// index. The "hard" upper bound of the variable is returned if no soft upper /// bound has been set. - int64 GetCumulVarSoftUpperBound(int64 index) const; + int64_t GetCumulVarSoftUpperBound(int64_t index) const; /// Returns the cost coefficient of the soft upper bound of a cumul variable /// for a given variable index. If no soft upper bound has been set, 0 is /// returned. - int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const; + int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const; /// Sets a soft lower bound to the cumul variable of a given variable index. /// If the value of the cumul variable is less than the bound, a cost @@ -2534,19 +2531,19 @@ class RoutingDimension { /// cumulVar). /// This is also handy to model earliness costs when the dimension represents /// time. - void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, - int64 coefficient); + void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound, + int64_t coefficient); /// Returns true if a soft lower bound has been set for a given variable /// index. - bool HasCumulVarSoftLowerBound(int64 index) const; + bool HasCumulVarSoftLowerBound(int64_t index) const; /// Returns the soft lower bound of a cumul variable for a given variable /// index. The "hard" lower bound of the variable is returned if no soft lower /// bound has been set. - int64 GetCumulVarSoftLowerBound(int64 index) const; + int64_t GetCumulVarSoftLowerBound(int64_t index) const; /// Returns the cost coefficient of the soft lower bound of a cumul variable /// for a given variable index. If no soft lower bound has been set, 0 is /// returned. - int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const; + int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const; /// Sets the breaks for a given vehicle. Breaks are represented by /// IntervalVars. They may interrupt transits between nodes and increase /// the value of corresponding slack variables. @@ -2571,13 +2568,13 @@ class RoutingDimension { /// Deprecated, sets pre_travel(i, j) = node_visit_transit[i]. void SetBreakIntervalsOfVehicle(std::vector breaks, int vehicle, - std::vector node_visit_transits); + std::vector node_visit_transits); /// With breaks supposed to be consecutive, this forces the distance between /// breaks of size at least minimum_break_duration to be at most distance. /// This supposes that the time until route start and after route end are /// infinite breaks. - void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration, + void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration, int vehicle); /// Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, /// pre_travel_evaluators and post_travel_evaluators. @@ -2588,8 +2585,8 @@ class RoutingDimension { /// Deprecated, sets pre_travel(i, j) = node_visit_transit[i] /// and post_travel(i, j) = delays(i, j). void SetBreakIntervalsOfVehicle(std::vector breaks, int vehicle, - std::vector node_visit_transits, - std::function delays); + std::vector node_visit_transits, + std::function delays); /// Returns the break intervals set by SetBreakIntervalsOfVehicle(). const std::vector& GetBreakIntervalsOfVehicle( @@ -2597,7 +2594,7 @@ class RoutingDimension { /// Returns the pairs (distance, duration) specified by break distance /// constraints. // clang-format off - const std::vector >& + const std::vector >& GetBreakDistanceDurationOfVehicle(int vehicle) const; // clang-format on #endif /// !defined(SWIGPYTHON) @@ -2613,7 +2610,7 @@ class RoutingDimension { /// 2. next[node] and next[next[node]] (if exists) are fixed, /// the value of slack[node] for which cumul[next[node]] + transit[next[node]] /// is minimized can be found in O(1) using this function. - int64 ShortestTransitionSlack(int64 node) const; + int64_t ShortestTransitionSlack(int64_t node) const; /// Returns the name of the dimension. const std::string& name() const { return name_; } @@ -2634,20 +2631,20 @@ class RoutingDimension { /// set when each node index appears in at most one pickup/delivery pair, i.e. /// each pickup (delivery) index is in a single pickup/delivery pair.first /// (pair.second). - typedef std::function PickupToDeliveryLimitFunction; + typedef std::function PickupToDeliveryLimitFunction; void SetPickupToDeliveryLimitFunctionForPair( PickupToDeliveryLimitFunction limit_function, int pair_index); bool HasPickupToDeliveryLimits() const; #ifndef SWIG - int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, + int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const; struct NodePrecedence { - int64 first_node; - int64 second_node; - int64 offset; + int64_t first_node; + int64_t second_node; + int64_t offset; }; void AddNodePrecedence(NodePrecedence precedence) { @@ -2658,35 +2655,35 @@ class RoutingDimension { } #endif // SWIG - void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) { + void AddNodePrecedence(int64_t first_node, int64_t second_node, int64_t offset) { AddNodePrecedence({first_node, second_node, offset}); } - int64 GetSpanUpperBoundForVehicle(int vehicle) const { + int64_t GetSpanUpperBoundForVehicle(int vehicle) const { return vehicle_span_upper_bounds_[vehicle]; } #ifndef SWIG - const std::vector& vehicle_span_upper_bounds() const { + const std::vector& vehicle_span_upper_bounds() const { return vehicle_span_upper_bounds_; } #endif // SWIG - int64 GetSpanCostCoefficientForVehicle(int vehicle) const { + int64_t GetSpanCostCoefficientForVehicle(int vehicle) const { return vehicle_span_cost_coefficients_[vehicle]; } #ifndef SWIG - const std::vector& vehicle_span_cost_coefficients() const { + const std::vector& vehicle_span_cost_coefficients() const { return vehicle_span_cost_coefficients_; } #endif // SWIG - int64 global_span_cost_coefficient() const { + int64_t global_span_cost_coefficient() const { return global_span_cost_coefficient_; } - int64 GetGlobalOptimizerOffset() const { + int64_t GetGlobalOptimizerOffset() const { DCHECK_GE(global_optimizer_offset_, 0); return global_optimizer_offset_; } - int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const { + int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const { if (vehicle >= local_optimizer_offset_for_vehicle_.size()) { return 0; } @@ -2737,8 +2734,8 @@ class RoutingDimension { private: struct SoftBound { IntVar* var; - int64 bound; - int64 coefficient; + int64_t bound; + int64_t coefficient; }; struct PiecewiseLinearCost { @@ -2748,20 +2745,20 @@ class RoutingDimension { }; class SelfBased {}; - RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, + RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, const std::string& name, const RoutingDimension* base_dimension); - RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, + RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, const std::string& name, SelfBased); void Initialize(const std::vector& transit_evaluators, const std::vector& state_dependent_transit_evaluators, - int64 slack_max); + int64_t slack_max); void InitializeCumuls(); void InitializeTransits( const std::vector& transit_evaluators, const std::vector& state_dependent_transit_evaluators, - int64 slack_max); - void InitializeTransitVariables(int64 slack_max); + int64_t slack_max); + void InitializeTransitVariables(int64_t slack_max); /// Sets up the cost variables related to cumul soft upper bounds. void SetupCumulVarSoftUpperBoundCosts( std::vector* cost_elements) const; @@ -2777,27 +2774,27 @@ class RoutingDimension { /// Finalize the model of the dimension. void CloseModel(bool use_light_propagation); - void SetOffsetForGlobalOptimizer(int64 offset) { + void SetOffsetForGlobalOptimizer(int64_t offset) { global_optimizer_offset_ = std::max(Zero(), offset); } /// Moves elements of "offsets" into vehicle_offsets_for_local_optimizer_. - void SetVehicleOffsetsForLocalOptimizer(std::vector offsets) { + void SetVehicleOffsetsForLocalOptimizer(std::vector offsets) { /// Make sure all offsets are positive. std::transform(offsets.begin(), offsets.end(), offsets.begin(), - [](int64 offset) { return std::max(Zero(), offset); }); + [](int64_t offset) { return std::max(Zero(), offset); }); local_optimizer_offset_for_vehicle_ = std::move(offsets); } std::vector cumuls_; std::vector forbidden_intervals_; std::vector capacity_vars_; - const std::vector vehicle_capacities_; + const std::vector vehicle_capacities_; std::vector transits_; std::vector fixed_transits_; /// Values in class_evaluators_ correspond to the evaluators in /// RoutingModel::transit_evaluators_ for each vehicle class. std::vector class_evaluators_; - std::vector vehicle_to_class_; + std::vector vehicle_to_class_; #ifndef SWIG ReverseArcListGraph path_precedence_graph_; #endif @@ -2816,7 +2813,7 @@ class RoutingDimension { // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle // class. std::vector state_dependent_class_evaluators_; - std::vector state_dependent_vehicle_to_class_; + std::vector state_dependent_vehicle_to_class_; // For each pickup/delivery pair_index for which limits have been set, // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the @@ -2828,7 +2825,7 @@ class RoutingDimension { bool break_constraints_are_initialized_ = false; // clang-format off std::vector > vehicle_break_intervals_; - std::vector > > + std::vector > > vehicle_break_distance_duration_; // clang-format on // For each vehicle, stores the part of travel that is made directly @@ -2839,16 +2836,16 @@ class RoutingDimension { std::vector slacks_; std::vector dependent_transits_; - std::vector vehicle_span_upper_bounds_; - int64 global_span_cost_coefficient_; - std::vector vehicle_span_cost_coefficients_; + std::vector vehicle_span_upper_bounds_; + int64_t global_span_cost_coefficient_; + std::vector vehicle_span_cost_coefficients_; std::vector cumul_var_soft_upper_bound_; std::vector cumul_var_soft_lower_bound_; std::vector cumul_var_piecewise_linear_cost_; RoutingModel* const model_; const std::string name_; - int64 global_optimizer_offset_; - std::vector local_optimizer_offset_for_vehicle_; + int64_t global_optimizer_offset_; + std::vector local_optimizer_offset_for_vehicle_; /// nullptr if not defined. std::unique_ptr vehicle_soft_span_upper_bound_; std::unique_ptr @@ -2863,960 +2860,11 @@ class RoutingDimension { DISALLOW_COPY_AND_ASSIGN(RoutingDimension); }; -#ifndef SWIG -/// Class to arrange indices by by their distance and their angles from the -/// depot. Used in the Sweep first solution heuristic. -class SweepArranger { - public: - explicit SweepArranger(const std::vector>& points); - virtual ~SweepArranger() {} - void ArrangeIndices(std::vector* indices); - void SetSectors(int sectors) { sectors_ = sectors; } - - private: - std::vector coordinates_; - int sectors_; - - DISALLOW_COPY_AND_ASSIGN(SweepArranger); -}; -#endif - /// A decision builder which tries to assign values to variables as close as /// possible to target values first. DecisionBuilder* MakeSetValuesFromTargets(Solver* solver, std::vector variables, - std::vector targets); - -#ifndef SWIG -/// Helper class that manages vehicles. This class is based on the -/// RoutingModel::VehicleTypeContainer that sorts and stores vehicles based on -/// their "type". -class VehicleTypeCurator { - public: - explicit VehicleTypeCurator( - const RoutingModel::VehicleTypeContainer& vehicle_type_container) - : vehicle_type_container_(&vehicle_type_container) {} - - int NumTypes() const { return vehicle_type_container_->NumTypes(); } - - int Type(int vehicle) const { return vehicle_type_container_->Type(vehicle); } - - /// Resets the vehicles stored, storing only vehicles from the - /// vehicle_type_container_ for which store_vehicle() returns true. - void Reset(const std::function& store_vehicle); - - /// Goes through all the currently stored vehicles and removes vehicles for - /// which remove_vehicle() returns true. - void Update(const std::function& remove_vehicle); - - int GetLowestFixedCostVehicleOfType(int type) const { - DCHECK_LT(type, NumTypes()); - const std::set& vehicle_classes = - sorted_vehicle_classes_per_type_[type]; - if (vehicle_classes.empty()) { - return -1; - } - const int vehicle_class = (vehicle_classes.begin())->vehicle_class; - DCHECK(!vehicles_per_vehicle_class_[vehicle_class].empty()); - return vehicles_per_vehicle_class_[vehicle_class][0]; - } - - void ReinjectVehicleOfClass(int vehicle, int vehicle_class, - int64 fixed_cost) { - std::vector& vehicles = vehicles_per_vehicle_class_[vehicle_class]; - if (vehicles.empty()) { - /// Add the vehicle class entry to the set (it was removed when - /// vehicles_per_vehicle_class_[vehicle_class] got empty). - std::set& vehicle_classes = - sorted_vehicle_classes_per_type_[Type(vehicle)]; - const auto& insertion = - vehicle_classes.insert({vehicle_class, fixed_cost}); - DCHECK(insertion.second); - } - vehicles.push_back(vehicle); - } - - /// Searches for the best compatible vehicle of the given type, i.e. the first - /// vehicle v of type 'type' for which vehicle_is_compatible(v) returns true. - /// If a compatible *vehicle* is found, its index is removed from - /// vehicles_per_vehicle_class_ and the function returns {vehicle, -1}. - /// If for some *vehicle* 'stop_and_return_vehicle' returns true before a - /// compatible vehicle is found, the function simply returns {-1, vehicle}. - /// Returns {-1, -1} if no compatible vehicle is found and the stopping - /// condition is never met. - std::pair GetCompatibleVehicleOfType( - int type, std::function vehicle_is_compatible, - std::function stop_and_return_vehicle); - - private: - using VehicleClassEntry = - RoutingModel::VehicleTypeContainer::VehicleClassEntry; - const RoutingModel::VehicleTypeContainer* const vehicle_type_container_; - // clang-format off - std::vector > sorted_vehicle_classes_per_type_; - std::vector > vehicles_per_vehicle_class_; - // clang-format on -}; - -/// Decision builder building a solution using heuristics with local search -/// filters to evaluate its feasibility. This is very fast but can eventually -/// fail when the solution is restored if filters did not detect all -/// infeasiblities. -/// More details: -/// Using local search filters to build a solution. The approach is pretty -/// straight-forward: have a general assignment storing the current solution, -/// build delta assigment representing possible extensions to the current -/// solution and validate them with filters. -/// The tricky bit comes from using the assignment and filter APIs in a way -/// which avoids the lazy creation of internal hash_maps between variables -/// and indices. - -/// Generic filter-based decision builder using an IntVarFilteredHeuristic. -// TODO(user): Eventually move this to the core CP solver library -/// when the code is mature enough. -class IntVarFilteredDecisionBuilder : public DecisionBuilder { - public: - explicit IntVarFilteredDecisionBuilder( - std::unique_ptr heuristic); - - ~IntVarFilteredDecisionBuilder() override {} - - Decision* Next(Solver* solver) override; - - std::string DebugString() const override; - - /// Returns statistics from its underlying heuristic. - int64 number_of_decisions() const; - int64 number_of_rejects() const; - - private: - const std::unique_ptr heuristic_; -}; - -/// Generic filter-based heuristic applied to IntVars. -class IntVarFilteredHeuristic { - public: - IntVarFilteredHeuristic(Solver* solver, const std::vector& vars, - LocalSearchFilterManager* filter_manager); - - virtual ~IntVarFilteredHeuristic() {} - - /// Builds a solution. Returns the resulting assignment if a solution was - /// found, and nullptr otherwise. - Assignment* const BuildSolution(); - - /// Returns statistics on search, number of decisions sent to filters, number - /// of decisions rejected by filters. - int64 number_of_decisions() const { return number_of_decisions_; } - int64 number_of_rejects() const { return number_of_rejects_; } - - virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; } - - protected: - /// Resets the data members for a new solution. - void ResetSolution(); - /// Virtual method to initialize the solution. - virtual bool InitializeSolution() { return true; } - /// Virtual method to redefine how to build a solution. - virtual bool BuildSolutionInternal() = 0; - /// Commits the modifications to the current solution if these modifications - /// are "filter-feasible", returns false otherwise; in any case discards - /// all modifications. - bool Commit(); - /// Returns true if the search must be stopped. - virtual bool StopSearch() { return false; } - /// Modifies the current solution by setting the variable of index 'index' to - /// value 'value'. - void SetValue(int64 index, int64 value) { - if (!is_in_delta_[index]) { - delta_->FastAdd(vars_[index])->SetValue(value); - delta_indices_.push_back(index); - is_in_delta_[index] = true; - } else { - delta_->SetValue(vars_[index], value); - } - } - /// Returns the value of the variable of index 'index' in the last committed - /// solution. - int64 Value(int64 index) const { - return assignment_->IntVarContainer().Element(index).Value(); - } - /// Returns true if the variable of index 'index' is in the current solution. - bool Contains(int64 index) const { - return assignment_->IntVarContainer().Element(index).Var() != nullptr; - } - /// Returns the number of variables the decision builder is trying to - /// instantiate. - int Size() const { return vars_.size(); } - /// Returns the variable of index 'index'. - IntVar* Var(int64 index) const { return vars_[index]; } - /// Synchronizes filters with an assignment (the current solution). - void SynchronizeFilters(); - - Assignment* const assignment_; - - private: - /// Checks if filters accept a given modification to the current solution - /// (represented by delta). - bool FilterAccept(); - - Solver* solver_; - const std::vector vars_; - Assignment* const delta_; - std::vector delta_indices_; - std::vector is_in_delta_; - Assignment* const empty_; - LocalSearchFilterManager* filter_manager_; - /// Stats on search - int64 number_of_decisions_; - int64 number_of_rejects_; -}; - -/// Filter-based heuristic dedicated to routing. -class RoutingFilteredHeuristic : public IntVarFilteredHeuristic { - public: - RoutingFilteredHeuristic(RoutingModel* model, - LocalSearchFilterManager* filter_manager); - ~RoutingFilteredHeuristic() override {} - /// Builds a solution starting from the routes formed by the next accessor. - const Assignment* BuildSolutionFromRoutes( - const std::function& next_accessor); - RoutingModel* model() const { return model_; } - /// Returns the end of the start chain of vehicle, - int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; } - /// Returns the start of the end chain of vehicle, - int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; } - /// Make nodes in the same disjunction as 'node' unperformed. 'node' is a - /// variable index corresponding to a node. - 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(); } - virtual void SetVehicleIndex(int64 node, int vehicle) {} - virtual void ResetVehicleIndices() {} - bool VehicleIsEmpty(int vehicle) const { - return Value(model()->Start(vehicle)) == model()->End(vehicle); - } - - private: - /// Initializes the current solution with empty or partial vehicle routes. - bool InitializeSolution() override; - - RoutingModel* const model_; - std::vector start_chain_ends_; - std::vector end_chain_starts_; -}; - -class CheapestInsertionFilteredHeuristic : public RoutingFilteredHeuristic { - public: - /// Takes ownership of evaluator. - CheapestInsertionFilteredHeuristic( - RoutingModel* model, std::function evaluator, - std::function penalty_evaluator, - LocalSearchFilterManager* filter_manager); - ~CheapestInsertionFilteredHeuristic() override {} - - protected: - typedef std::pair ValuedPosition; - struct StartEndValue { - int64 distance; - int vehicle; - - bool operator<(const StartEndValue& other) const { - return std::tie(distance, vehicle) < - std::tie(other.distance, other.vehicle); - } - }; - typedef std::pair Seed; - - /// Computes and returns the distance of each uninserted node to every vehicle - /// in "vehicles" as a std::vector>, - /// start_end_distances_per_node. - /// For each node, start_end_distances_per_node[node] is sorted in decreasing - /// order. - // clang-format off - std::vector > - ComputeStartEndDistanceForVehicles(const std::vector& vehicles); - - /// Initializes the priority_queue by inserting the best entry corresponding - /// to each node, i.e. the last element of start_end_distances_per_node[node], - /// which is supposed to be sorted in decreasing order. - /// Queue is a priority queue containing Seeds. - template - void InitializePriorityQueue( - std::vector >* start_end_distances_per_node, - Queue* priority_queue); - // clang-format on - - /// Inserts 'node' just after 'predecessor', and just before 'successor', - /// resulting in the following subsequence: predecessor -> node -> successor. - /// If 'node' is part of a disjunction, other nodes of the disjunction are - /// made unperformed. - void InsertBetween(int64 node, int64 predecessor, int64 successor); - /// Helper method to the ComputeEvaluatorSortedPositions* methods. Finds all - /// possible insertion positions of node 'node_to_insert' in the partial route - /// starting at node 'start' and adds them to 'valued_position', a list of - /// unsorted pairs of (cost, position to insert the node). - void AppendEvaluatedPositionsAfter( - int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, - std::vector* valued_positions); - /// Returns the cost of inserting 'node_to_insert' between 'insert_after' and - /// 'insert_before' on the 'vehicle', i.e. - /// Cost(insert_after-->node) + Cost(node-->insert_before) - /// - Cost (insert_after-->insert_before). - // TODO(user): Replace 'insert_before' and 'insert_after' by 'predecessor' - // and 'successor' in the code. - int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert, - int64 insert_after, - int64 insert_before, - int vehicle) const; - /// Returns the cost of unperforming node 'node_to_insert'. Returns kint64max - /// if penalty callback is null or if the node cannot be unperformed. - int64 GetUnperformedValue(int64 node_to_insert) const; - - std::function evaluator_; - std::function penalty_evaluator_; -}; - -/// Filter-based decision builder which builds a solution by inserting -/// nodes at their cheapest position on any route; potentially several routes -/// can be built in parallel. The cost of a position is computed from an -/// arc-based cost callback. The node selected for insertion is the one which -/// minimizes insertion cost. If a non null penalty evaluator is passed, making -/// nodes unperformed is also taken into account with the corresponding penalty -/// cost. -class GlobalCheapestInsertionFilteredHeuristic - : public CheapestInsertionFilteredHeuristic { - public: - struct GlobalCheapestInsertionParameters { - /// Whether the routes are constructed sequentially or in parallel. - bool is_sequential; - /// The ratio of routes on which to insert farthest nodes as seeds before - /// starting the cheapest insertion. - double farthest_seeds_ratio; - /// If neighbors_ratio < 1 then for each node only this ratio of its - /// neighbors leading to the smallest arc costs are considered for - /// insertions, with a minimum of 'min_neighbors': - /// num_closest_neighbors = max(min_neighbors, neighbors_ratio*N), - /// where N is the number of non-start/end nodes in the model. - double neighbors_ratio; - int64 min_neighbors; - /// If true, only closest neighbors (see neighbors_ratio and min_neighbors) - /// are considered as insertion positions during initialization. Otherwise, - /// all possible insertion positions are considered. - bool use_neighbors_ratio_for_initialization; - /// If true, entries are created for making the nodes/pairs unperformed, and - /// when the cost of making a node unperformed is lower than all insertions, - /// the node/pair will be made unperformed. If false, only entries making - /// a node/pair performed are considered. - bool add_unperformed_entries; - }; - - /// Takes ownership of evaluators. - GlobalCheapestInsertionFilteredHeuristic( - RoutingModel* model, std::function evaluator, - std::function penalty_evaluator, - LocalSearchFilterManager* filter_manager, - GlobalCheapestInsertionParameters parameters); - ~GlobalCheapestInsertionFilteredHeuristic() override {} - bool BuildSolutionInternal() override; - std::string DebugString() const override { - return "GlobalCheapestInsertionFilteredHeuristic"; - } - - private: - class PairEntry; - class NodeEntry; - typedef absl::flat_hash_set PairEntries; - typedef absl::flat_hash_set NodeEntries; - - /// Inserts non-inserted single nodes or pickup/delivery pairs which have a - /// visit type in the type requirement graph, i.e. required for or requiring - /// another type for insertions. - /// These nodes are inserted iff the requirement graph is acyclic, in which - /// case nodes are inserted based on the topological order of their type, - /// given by the routing model's GetTopologicallySortedVisitTypes() method. - void InsertPairsAndNodesByRequirementTopologicalOrder(); - - /// Inserts non-inserted pickup and delivery pairs. Maintains a priority - /// queue of possible pair insertions, which is incrementally updated when a - /// pair insertion is committed. Incrementality is obtained by updating pair - /// insertion positions on the four newly modified route arcs: after the - /// pickup insertion position, after the pickup position, after the delivery - /// insertion position and after the delivery position. - void InsertPairs(const std::vector& pair_indices); - - /// If the vehicle of the given 'pair_entry' is empty, tries to insert the - /// pickup/delivery pair on a vehicle of the same type and same fixed cost as - /// the pair_entry.vehicle() using the empty_vehicle_type_curator_, or update - /// the pair_entry accordingly if the insertion was not possible. - /// Returns true iff the empty_vehicle_type_curator_ is used for the - /// insertion, i.e. iff the pair_entry.vehicle() was empty. - bool InsertPairEntryUsingEmptyVehicleTypeCurator( - const std::vector& pair_indices, PairEntry* const pair_entry, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - - /// Inserts non-inserted individual nodes on the given routes (or all routes - /// if "vehicles" is an empty vector), by constructing routes in parallel. - /// Maintains a priority queue of possible insertions, which is incrementally - /// updated when an insertion is committed. - /// Incrementality is obtained by updating insertion positions on the two - /// newly modified route arcs: after the node insertion position and after the - /// node position. - void InsertNodesOnRoutes(const std::vector& nodes, - const absl::flat_hash_set& vehicles); - - /// If the vehicle of the given 'node_entry' is empty, tries to insert the - /// node on a vehicle of the same type and same fixed cost as the - /// node_entry.vehicle() using the empty_vehicle_type_curator_, or update the - /// node_entry accordingly if the insertion was not possible. - /// Returns true iff the empty_vehicle_type_curator_ is used for the - /// insertion, i.e. iff 'all_vehicles' is true and the node_entry.vehicle() - /// was empty. - bool InsertNodeEntryUsingEmptyVehicleTypeCurator( - const std::vector& nodes, bool all_vehicles, - NodeEntry* const node_entry, - AdjustablePriorityQueue* priority_queue, - std::vector* position_to_node_entries); - - /// Inserts non-inserted individual nodes on routes by constructing routes - /// sequentially. - /// For each new route, the vehicle to use and the first node to insert on it - /// are given by calling InsertSeedNode(). The route is then completed with - /// other nodes by calling InsertNodesOnRoutes({vehicle}). - void SequentialInsertNodes(const std::vector& nodes); - - /// Goes through all vehicles in the model to check if they are already used - /// (i.e. Value(start) != end) or not. - /// Updates the three passed vectors accordingly. - void DetectUsedVehicles(std::vector* is_vehicle_used, - std::vector* unused_vehicles, - absl::flat_hash_set* used_vehicles); - - /// Inserts the (farthest_seeds_ratio_ * model()->vehicles()) nodes farthest - /// from the start/ends of the available vehicle routes as seeds on their - /// closest route. - void InsertFarthestNodesAsSeeds(); - - /// Inserts a "seed node" based on the given priority_queue of Seeds. - /// A "seed" is the node used in order to start a new route. - /// If the Seed at the top of the priority queue cannot be inserted, - /// (node already inserted in the model, corresponding vehicle already used, - /// or unsuccessful Commit()), start_end_distances_per_node is updated and - /// used to insert a new entry for that node if necessary (next best vehicle). - /// If a seed node is successfully inserted, updates is_vehicle_used and - /// returns the vehice of the corresponding route. Returns -1 otherwise. - template - int InsertSeedNode( - std::vector>* start_end_distances_per_node, - Queue* priority_queue, std::vector* is_vehicle_used); - // clang-format on - - /// Initializes the priority queue and the pair entries for the given pair - /// indices with the current state of the solution. - void InitializePairPositions( - const std::vector& pair_indices, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Adds insertion entries performing the 'pickup' and 'delivery', and updates - /// 'priority_queue', pickup_to_entries and delivery_to_entries accordingly. - /// Based on gci_params_.use_neighbors_ratio_for_initialization, either all - /// contained nodes are considered as insertion positions, or only the - /// closest neighbors of 'pickup' and/or 'delivery'. - void InitializeInsertionEntriesPerformingPair( - int64 pickup, int64 delivery, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Performs all the necessary updates after a pickup/delivery pair was - /// successfully inserted on the 'vehicle', respectively after - /// 'pickup_position' and 'delivery_position'. - void UpdateAfterPairInsertion( - const std::vector& pair_indices, int vehicle, int64 pickup, - int64 pickup_position, int64 delivery, int64 delivery_position, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Updates all pair entries inserting a node after node "insert_after" and - /// updates the priority queue accordingly. - void UpdatePairPositions(const std::vector& pair_indices, int vehicle, - int64 insert_after, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries) { - UpdatePickupPositions(pair_indices, vehicle, insert_after, priority_queue, - pickup_to_entries, delivery_to_entries); - UpdateDeliveryPositions(pair_indices, vehicle, insert_after, priority_queue, - pickup_to_entries, delivery_to_entries); - } - /// Updates all pair entries inserting their pickup node after node - /// "insert_after" and updates the priority queue accordingly. - void UpdatePickupPositions(const std::vector& pair_indices, int vehicle, - int64 pickup_insert_after, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Updates all pair entries inserting their delivery node after node - /// "insert_after" and updates the priority queue accordingly. - void UpdateDeliveryPositions( - const std::vector& pair_indices, int vehicle, - int64 delivery_insert_after, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Deletes an entry, removing it from the priority queue and the appropriate - /// pickup and delivery entry sets. - void DeletePairEntry(PairEntry* entry, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_to_entries, - std::vector* delivery_to_entries); - /// Creates a PairEntry corresponding to the insertion of 'pickup' and - /// 'delivery' respectively after 'pickup_insert_after' and - /// 'delivery_insert_after', and adds it to the 'priority_queue', - /// 'pickup_entries' and 'delivery_entries'. - void AddPairEntry(int64 pickup, int64 pickup_insert_after, int64 delivery, - int64 delivery_insert_after, int vehicle, - AdjustablePriorityQueue* priority_queue, - std::vector* pickup_entries, - std::vector* delivery_entries) const; - /// Updates the pair entry's value and rearranges the priority queue - /// accordingly. - void UpdatePairEntry( - PairEntry* const pair_entry, - AdjustablePriorityQueue* priority_queue) const; - /// Computes and returns the insertion value of inserting 'pickup' and - /// 'delivery' respectively after 'pickup_insert_after' and - /// 'delivery_insert_after' on 'vehicle'. - int64 GetInsertionValueForPairAtPositions(int64 pickup, - int64 pickup_insert_after, - int64 delivery, - int64 delivery_insert_after, - int vehicle) const; - - /// Initializes the priority queue and the node entries with the current state - /// of the solution on the given vehicle routes. - void InitializePositions(const std::vector& nodes, - const absl::flat_hash_set& vehicles, - AdjustablePriorityQueue* priority_queue, - std::vector* position_to_node_entries); - /// Adds insertion entries performing 'node', and updates 'priority_queue' and - /// position_to_node_entries accordingly. - /// Based on gci_params_.use_neighbors_ratio_for_initialization, either all - /// contained nodes are considered as insertion positions, or only the - /// closest neighbors of 'node'. - void InitializeInsertionEntriesPerformingNode( - int64 node, const absl::flat_hash_set& vehicles, - AdjustablePriorityQueue* priority_queue, - std::vector* position_to_node_entries); - /// Updates all node entries inserting a node after node "insert_after" and - /// updates the priority queue accordingly. - void UpdatePositions(const std::vector& nodes, int vehicle, - int64 insert_after, bool all_vehicles, - AdjustablePriorityQueue* priority_queue, - std::vector* node_entries); - /// Deletes an entry, removing it from the priority queue and the appropriate - /// node entry sets. - void DeleteNodeEntry(NodeEntry* entry, - AdjustablePriorityQueue* priority_queue, - std::vector* node_entries); - - /// Creates a NodeEntry corresponding to the insertion of 'node' after - /// 'insert_after' on 'vehicle' and adds it to the 'priority_queue' and - /// 'node_entries'. - void AddNodeEntry(int64 node, int64 insert_after, int vehicle, - bool all_vehicles, - AdjustablePriorityQueue* priority_queue, - std::vector* node_entries) const; - /// Updates the given node_entry's value and rearranges the priority queue - /// accordingly. - void UpdateNodeEntry( - NodeEntry* const node_entry, - AdjustablePriorityQueue* priority_queue) const; - - /// Computes the neighborhood of all nodes for every cost class, if needed and - /// not done already. - void ComputeNeighborhoods(); - - /// Returns true iff neighbor_index is in node_index's neighbors list - /// corresponding to neighbor_is_pickup and neighbor_is_delivery. - bool IsNeighborForCostClass(int cost_class, int64 node_index, - int64 neighbor_index) const; - - /// Returns the neighbors of the given node for the given cost_class. - const std::vector& GetNeighborsOfNodeForCostClass( - int cost_class, int64 node_index) const { - return gci_params_.neighbors_ratio == 1 - ? all_nodes_ - : node_index_to_neighbors_by_cost_class_[node_index][cost_class] - ->PositionsSetAtLeastOnce(); - } - - int64 NumNonStartEndNodes() const { - return model()->Size() - model()->vehicles(); - } - - int64 NumNeighbors() const { - return std::max(gci_params_.min_neighbors, - MathUtil::FastInt64Round(gci_params_.neighbors_ratio * - NumNonStartEndNodes())); - } - - void ResetVehicleIndices() override { - node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1); - } - - void SetVehicleIndex(int64 node, int vehicle) override { - DCHECK_LT(node, node_index_to_vehicle_.size()); - node_index_to_vehicle_[node] = vehicle; - } - - /// Function that verifies node_index_to_vehicle_ is correctly filled for all - /// nodes given the current routes. - bool CheckVehicleIndices() const; - - GlobalCheapestInsertionParameters gci_params_; - /// Stores the vehicle index of each node in the current assignment. - std::vector node_index_to_vehicle_; - - // clang-format off - std::vector > > > - node_index_to_neighbors_by_cost_class_; - // clang-format on - - std::unique_ptr empty_vehicle_type_curator_; - - /// When neighbors_ratio is 1, we don't compute the neighborhood matrix - /// above, and use the following vector in the code to avoid unnecessary - /// computations and decrease the time and space complexities. - std::vector all_nodes_; -}; - -/// Filter-base decision builder which builds a solution by inserting -/// nodes at their cheapest position. The cost of a position is computed -/// an arc-based cost callback. Node selected for insertion are considered in -/// decreasing order of distance to the start/ends of the routes, i.e. farthest -/// nodes are inserted first. -class LocalCheapestInsertionFilteredHeuristic - : public CheapestInsertionFilteredHeuristic { - public: - /// Takes ownership of evaluator. - LocalCheapestInsertionFilteredHeuristic( - RoutingModel* model, std::function evaluator, - LocalSearchFilterManager* filter_manager); - ~LocalCheapestInsertionFilteredHeuristic() override {} - bool BuildSolutionInternal() override; - std::string DebugString() const override { - return "LocalCheapestInsertionFilteredHeuristic"; - } - - private: - /// Computes the possible insertion positions of 'node' and sorts them - /// according to the current cost evaluator. - /// 'node' is a variable index corresponding to a node, 'sorted_positions' is - /// a vector of variable indices corresponding to nodes after which 'node' can - /// be inserted. - void ComputeEvaluatorSortedPositions(int64 node, - std::vector* sorted_positions); - /// Like ComputeEvaluatorSortedPositions, subject to the additional - /// restrictions that the node may only be inserted after node 'start' on the - /// route. For convenience, this method also needs the node that is right - /// after 'start' on the route. - void ComputeEvaluatorSortedPositionsOnRouteAfter( - int64 node, int64 start, int64 next_after_start, - std::vector* sorted_positions); - - std::vector> start_end_distances_per_node_; -}; - -/// Filtered-base decision builder based on the addition heuristic, extending -/// a path from its start node with the cheapest arc. -class CheapestAdditionFilteredHeuristic : public RoutingFilteredHeuristic { - public: - CheapestAdditionFilteredHeuristic(RoutingModel* model, - LocalSearchFilterManager* filter_manager); - ~CheapestAdditionFilteredHeuristic() override {} - bool BuildSolutionInternal() override; - - private: - class PartialRoutesAndLargeVehicleIndicesFirst { - public: - explicit PartialRoutesAndLargeVehicleIndicesFirst( - const CheapestAdditionFilteredHeuristic& builder) - : builder_(builder) {} - bool operator()(int vehicle1, int vehicle2) const; - - private: - const CheapestAdditionFilteredHeuristic& builder_; - }; - /// Returns a vector of possible next indices of node from an iterator. - template - std::vector GetPossibleNextsFromIterator(int64 node, Iterator start, - Iterator end) const { - const int size = model()->Size(); - std::vector nexts; - for (Iterator it = start; it != end; ++it) { - const int64 next = *it; - if (next != node && (next >= size || !Contains(next))) { - nexts.push_back(next); - } - } - return nexts; - } - /// Sorts a vector of successors of node. - virtual void SortSuccessors(int64 node, std::vector* successors) = 0; - virtual int64 FindTopSuccessor(int64 node, - const std::vector& successors) = 0; -}; - -/// A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' -/// comes from an arc evaluator. -class EvaluatorCheapestAdditionFilteredHeuristic - : public CheapestAdditionFilteredHeuristic { - public: - /// Takes ownership of evaluator. - EvaluatorCheapestAdditionFilteredHeuristic( - RoutingModel* model, std::function evaluator, - LocalSearchFilterManager* filter_manager); - ~EvaluatorCheapestAdditionFilteredHeuristic() override {} - std::string DebugString() const override { - return "EvaluatorCheapestAdditionFilteredHeuristic"; - } - - private: - /// Next nodes are sorted according to the current evaluator. - void SortSuccessors(int64 node, std::vector* successors) override; - int64 FindTopSuccessor(int64 node, - const std::vector& successors) override; - - std::function evaluator_; -}; - -/// A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' -/// comes from an arc comparator. -class ComparatorCheapestAdditionFilteredHeuristic - : public CheapestAdditionFilteredHeuristic { - public: - /// Takes ownership of evaluator. - ComparatorCheapestAdditionFilteredHeuristic( - RoutingModel* model, Solver::VariableValueComparator comparator, - LocalSearchFilterManager* filter_manager); - ~ComparatorCheapestAdditionFilteredHeuristic() override {} - std::string DebugString() const override { - return "ComparatorCheapestAdditionFilteredHeuristic"; - } - - private: - /// Next nodes are sorted according to the current comparator. - void SortSuccessors(int64 node, std::vector* successors) override; - int64 FindTopSuccessor(int64 node, - const std::vector& successors) override; - - Solver::VariableValueComparator comparator_; -}; - -/// Filter-based decision builder which builds a solution by using -/// Clarke & Wright's Savings heuristic. For each pair of nodes, the savings -/// value is the difference between the cost of two routes visiting one node -/// each and one route visiting both nodes. Routes are built sequentially, each -/// route being initialized from the pair with the best avalaible savings value -/// then extended by selecting the nodes with best savings on both ends of the -/// partial route. Cost is based on the arc cost function of the routing model -/// and cost classes are taken into account. -class SavingsFilteredHeuristic : public RoutingFilteredHeuristic { - public: - struct SavingsParameters { - /// If neighbors_ratio < 1 then for each node only this ratio of its - /// neighbors leading to the smallest arc costs are considered. - double neighbors_ratio = 1.0; - /// The number of neighbors considered for each node is also adapted so that - /// the stored Savings don't use up more than max_memory_usage_bytes bytes. - double max_memory_usage_bytes = 6e9; - /// If add_reverse_arcs is true, the neighborhood relationships are - /// considered symmetrically. - bool add_reverse_arcs = false; - /// arc_coefficient is a strictly positive parameter indicating the - /// coefficient of the arc being considered in the Saving formula. - double arc_coefficient = 1.0; - }; - - SavingsFilteredHeuristic(RoutingModel* model, - const RoutingIndexManager* manager, - SavingsParameters parameters, - LocalSearchFilterManager* filter_manager); - ~SavingsFilteredHeuristic() override; - bool BuildSolutionInternal() override; - - protected: - typedef std::pair Saving; - - template - class SavingsContainer; - - virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0; - - virtual void BuildRoutesFromSavings() = 0; - - /// Returns the cost class from a saving. - int64 GetVehicleTypeFromSaving(const Saving& saving) const { - return saving.second / size_squared_; - } - /// Returns the "before node" from a saving. - int64 GetBeforeNodeFromSaving(const Saving& saving) const { - return (saving.second % size_squared_) / Size(); - } - /// Returns the "after node" from a saving. - int64 GetAfterNodeFromSaving(const Saving& saving) const { - return (saving.second % size_squared_) % Size(); - } - /// Returns the saving value from a saving. - int64 GetSavingValue(const Saving& saving) const { return saving.first; } - - /// Finds the best available vehicle of type "type" to start a new route to - /// serve the arc before_node-->after_node. - /// Since there are different vehicle classes for each vehicle type, each - /// vehicle class having its own capacity constraints, we go through all - /// vehicle types (in each case only studying the first available vehicle) to - /// make sure this Saving is inserted if possible. - /// If possible, the arc is committed to the best vehicle, and the vehicle - /// index is returned. If this arc can't be served by any vehicle of this - /// type, the function returns -1. - int StartNewRouteWithBestVehicleOfType(int type, int64 before_node, - int64 after_node); - - // clang-format off - std::unique_ptr > savings_container_; - // clang-format on - std::unique_ptr vehicle_type_curator_; - - private: - /// Used when add_reverse_arcs_ is true. - /// Given the vector of adjacency lists of a graph, adds symmetric arcs not - /// already in the graph to the adjacencies (i.e. if n1-->n2 is present and - /// not n2-->n1, then n1 is added to adjacency_matrix[n2]. - // clang-format off - void AddSymmetricArcsToAdjacencyLists( - std::vector >* adjacency_lists); - // clang-format on - - /// Computes saving values for node pairs (see MaxNumNeighborsPerNode()) and - /// all vehicle types (see ComputeVehicleTypes()). - /// The saving index attached to each saving value is an index used to - /// store and recover the node pair to which the value is linked (cf. the - /// index conversion methods below). - /// The computed savings are stored and sorted using the savings_container_. - void ComputeSavings(); - /// Builds a saving from a saving value, a vehicle type and two nodes. - Saving BuildSaving(int64 saving, int vehicle_type, int before_node, - int after_node) const { - return std::make_pair(saving, vehicle_type * size_squared_ + - before_node * Size() + after_node); - } - - /// Computes and returns the maximum number of (closest) neighbors to consider - /// for each node when computing Savings, based on the neighbors ratio and max - /// memory usage specified by the savings_params_. - int64 MaxNumNeighborsPerNode(int num_vehicle_types) const; - - const RoutingIndexManager* const manager_; - const SavingsParameters savings_params_; - int64 size_squared_; - - friend class SavingsFilteredHeuristicTestPeer; -}; - -class SequentialSavingsFilteredHeuristic : public SavingsFilteredHeuristic { - public: - SequentialSavingsFilteredHeuristic(RoutingModel* model, - const RoutingIndexManager* manager, - SavingsParameters parameters, - LocalSearchFilterManager* filter_manager) - : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {} - ~SequentialSavingsFilteredHeuristic() override{}; - std::string DebugString() const override { - return "SequentialSavingsFilteredHeuristic"; - } - - private: - /// Builds routes sequentially. - /// Once a Saving is used to start a new route, we extend this route as much - /// as possible from both ends by gradually inserting the best Saving at - /// either end of the route. - void BuildRoutesFromSavings() override; - double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; } -}; - -class ParallelSavingsFilteredHeuristic : public SavingsFilteredHeuristic { - public: - ParallelSavingsFilteredHeuristic(RoutingModel* model, - const RoutingIndexManager* manager, - SavingsParameters parameters, - LocalSearchFilterManager* filter_manager) - : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {} - ~ParallelSavingsFilteredHeuristic() override{}; - std::string DebugString() const override { - return "ParallelSavingsFilteredHeuristic"; - } - - private: - /// Goes through the ordered computed Savings to build routes in parallel. - /// Given a Saving for a before-->after arc : - /// -- If both before and after are uncontained, we start a new route. - /// -- If only before is served and is the last node on its route, we try - /// adding after at the end of the route. - /// -- If only after is served and is first on its route, we try adding before - /// as first node on this route. - /// -- If both nodes are contained and are respectively the last and first - /// nodes on their (different) routes, we merge the routes of the two nodes - /// into one if possible. - void BuildRoutesFromSavings() override; - - double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; } - - /// Merges the routes of first_vehicle and second_vehicle onto the vehicle - /// with lower fixed cost. The routes respectively end at before_node and - /// start at after_node, and are merged into one by adding the arc - /// before_node-->after_node. - void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node, - int64 after_node); - - /// First and last non start/end nodes served by each vehicle. - std::vector first_node_on_route_; - std::vector last_node_on_route_; - /// For each first/last node served by a vehicle (besides start/end nodes of - /// vehicle), this vector contains the index of the vehicle serving them. - /// For other (intermediary) nodes, contains -1. - std::vector vehicle_of_first_or_last_node_; -}; - -/// Christofides addition heuristic. Initially created to solve TSPs, extended -/// to support any model by extending routes as much as possible following the -/// path found by the heuristic, before starting a new route. - -class ChristofidesFilteredHeuristic : public RoutingFilteredHeuristic { - public: - ChristofidesFilteredHeuristic(RoutingModel* model, - LocalSearchFilterManager* filter_manager, - bool use_minimum_matching); - ~ChristofidesFilteredHeuristic() override {} - bool BuildSolutionInternal() override; - std::string DebugString() const override { - return "ChristofidesFilteredHeuristic"; - } - - private: - const bool use_minimum_matching_; -}; -#endif // SWIG + std::vector targets); /// Attempts to solve the model using the cp-sat solver. As of 5/2019, will /// solve the TSP corresponding to the model if it has a single vehicle. @@ -3827,139 +2875,9 @@ bool SolveModelWithSat(const RoutingModel& model, const Assignment* initial_solution, Assignment* solution); -/// Generic path-based filter class. - -class BasePathFilter : public IntVarLocalSearchFilter { - public: - BasePathFilter(const std::vector& nexts, int next_domain_size); - ~BasePathFilter() override {} - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override; - void OnSynchronize(const Assignment* delta) override; - - protected: - static const int64 kUnassigned; - - int64 GetNext(int64 node) const { - return (new_nexts_[node] == kUnassigned) - ? (IsVarSynced(node) ? Value(node) : kUnassigned) - : new_nexts_[node]; - } - int NumPaths() const { return starts_.size(); } - int64 Start(int i) const { return starts_[i]; } - int GetPath(int64 node) const { return paths_[node]; } - int Rank(int64 node) const { return ranks_[node]; } - bool IsDisabled() const { return status_ == DISABLED; } - const std::vector& GetTouchedPathStarts() const { - return touched_paths_.PositionsSetAtLeastOnce(); - } - const std::vector& GetNewSynchronizedUnperformedNodes() const { - return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce(); - } - - private: - enum Status { UNKNOWN, ENABLED, DISABLED }; - - virtual bool DisableFiltering() const { return false; } - virtual void OnBeforeSynchronizePaths() {} - virtual void OnAfterSynchronizePaths() {} - virtual void OnSynchronizePathFromStart(int64 start) {} - virtual void InitializeAcceptPath() {} - virtual bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) = 0; - virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min, - int64 objective_max) { - return true; - } - /// Detects path starts, used to track which node belongs to which path. - void ComputePathStarts(std::vector* path_starts, - std::vector* index_to_path); - bool HavePathsChanged(); - void SynchronizeFullAssignment(); - void UpdateAllRanks(); - void UpdatePathRanksFromStart(int start); - - std::vector node_path_starts_; - std::vector starts_; - std::vector paths_; - SparseBitset new_synchronized_unperformed_nodes_; - std::vector new_nexts_; - std::vector delta_touched_; - SparseBitset<> touched_paths_; - // clang-format off - std::vector > touched_path_chain_start_ends_; - // clang-format on - std::vector ranks_; - - Status status_; -}; - -/// This filter accepts deltas for which the assignment satisfies the -/// constraints of the Solver. This is verified by keeping an internal copy of -/// the assignment with all Next vars and their updated values, and calling -/// RestoreAssignment() on the assignment+delta. -// TODO(user): Also call the solution finalizer on variables, with the -/// exception of Next Vars (woud fail on large instances). -/// WARNING: In the case of mandatory nodes, when all vehicles are currently -/// being used in the solution but uninserted nodes still remain, this filter -/// will reject the solution, even if the node could be inserted on one of these -/// routes, because all Next vars of vehicle starts are already instantiated. -// TODO(user): Avoid such false negatives. -class CPFeasibilityFilter : public IntVarLocalSearchFilter { - public: - explicit CPFeasibilityFilter(RoutingModel* routing_model); - ~CPFeasibilityFilter() override {} - std::string DebugString() const override { return "CPFeasibilityFilter"; } - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override; - void OnSynchronize(const Assignment* delta) override; - - private: - void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment); - - static const int64 kUnassigned; - const RoutingModel* const model_; - Solver* const solver_; - Assignment* const assignment_; - Assignment* const temp_assignment_; - DecisionBuilder* const restore_; - SearchLimit* const limit_; -}; - #if !defined(SWIG) -IntVarLocalSearchFilter* MakeMaxActiveVehiclesFilter( - const RoutingModel& routing_model); -IntVarLocalSearchFilter* MakeNodeDisjunctionFilter( - const RoutingModel& routing_model); -IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter( - const RoutingModel& routing_model); -IntVarLocalSearchFilter* MakeTypeRegulationsFilter( - const RoutingModel& routing_model); -void AppendDimensionCumulFilters( - const std::vector& dimensions, - const RoutingSearchParameters& parameters, bool filter_objective_cost, - std::vector* filters); -void AppendLightWeightDimensionFilters( - const PathState* path_state, - const std::vector& dimensions, - std::vector* filters); -IntVarLocalSearchFilter* MakePathCumulFilter( - const RoutingDimension& dimension, - const RoutingSearchParameters& parameters, - bool propagate_own_objective_value, bool filter_objective_cost, - bool can_use_lp = true); -IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter( - const RoutingDimension& dimension); -IntVarLocalSearchFilter* MakeGlobalLPCumulFilter( - GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost); -IntVarLocalSearchFilter* MakePickupDeliveryFilter( - const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs, - const std::vector& vehicle_policies); -IntVarLocalSearchFilter* MakeVehicleVarFilter( - const RoutingModel& routing_model); IntVarLocalSearchFilter* MakeVehicleBreaksFilter( const RoutingModel& routing_model, const RoutingDimension& dimension); -IntVarLocalSearchFilter* MakeCPFeasibilityFilter(RoutingModel* routing_model); #endif } // namespace operations_research diff --git a/ortools/constraint_solver/routing_breaks.cc b/ortools/constraint_solver/routing_breaks.cc index e0eae27244..211db8e911 100644 --- a/ortools/constraint_solver/routing_breaks.cc +++ b/ortools/constraint_solver/routing_breaks.cc @@ -12,8 +12,24 @@ // limitations under the License. #include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_filters.h" +#include "ortools/sat/theta_tree.h" +#include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" namespace operations_research { @@ -52,7 +68,7 @@ bool DisjunctivePropagator::Precedences(Tasks* tasks) { const int num_chain_tasks = tasks->num_chain_tasks; if (num_chain_tasks > 0) { // Propagate forwards. - int64 time = tasks->start_min[0]; + int64_t time = tasks->start_min[0]; for (int task = 0; task < num_chain_tasks; ++task) { time = std::max(tasks->start_min[task], time); tasks->start_min[task] = time; @@ -107,13 +123,13 @@ bool DisjunctivePropagator::MirrorTasks(Tasks* tasks) { const int num_tasks = tasks->start_min.size(); // For all tasks, start_min := -end_max and end_max := -start_min. for (int task = 0; task < num_tasks; ++task) { - const int64 t = -tasks->start_min[task]; + const int64_t t = -tasks->start_min[task]; tasks->start_min[task] = -tasks->end_max[task]; tasks->end_max[task] = t; } // For all tasks, start_max := -end_min and end_min := -start_max. for (int task = 0; task < num_tasks; ++task) { - const int64 t = -tasks->start_max[task]; + const int64_t t = -tasks->start_max[task]; tasks->start_max[task] = -tasks->end_min[task]; tasks->end_min[task] = t; } @@ -169,12 +185,12 @@ bool DisjunctivePropagator::EdgeFinding(Tasks* tasks) { // theta to lambda. for (int i = num_tasks - 1; i >= 0; --i) { const int task = tasks_by_end_max_[i]; - const int64 envelope = theta_lambda_tree_.GetEnvelope(); + const int64_t envelope = theta_lambda_tree_.GetEnvelope(); // If a nonpreemptible optional would overload end_max, push to envelope. while (theta_lambda_tree_.GetOptionalEnvelope() > tasks->end_max[task]) { int critical_event; // Dummy value. int optional_event; - int64 available_energy; // Dummy value. + int64_t available_energy; // Dummy value. theta_lambda_tree_.GetEventsWithOptionalEnvelopeGreaterThan( tasks->end_max[task], &critical_event, &optional_event, &available_energy); @@ -237,7 +253,7 @@ bool DisjunctivePropagator::DetectablePrecedencesWithChain(Tasks* tasks) { } } // All chain and nonchain tasks before i are now in the tree, push i. - const int64 new_start_min = theta_lambda_tree_.GetEnvelope(); + const int64_t new_start_min = theta_lambda_tree_.GetEnvelope(); // Add i to the tree before updating it. theta_lambda_tree_.AddOrUpdateEvent(event_of_task_[i], tasks->start_min[i], tasks->duration_min[i], @@ -265,7 +281,7 @@ bool DisjunctivePropagator::ForbiddenIntervals(Tasks* tasks) { } // If end_max forbidden, push to next feasible value. { - const int64 start_max = + const int64_t start_max = CapSub(tasks->end_max[task], tasks->duration_min[task]); const auto& interval = tasks->forbidden_intervals[task]->LastIntervalLessOrEqual(start_max); @@ -290,8 +306,8 @@ bool DisjunctivePropagator::DistanceDuration(Tasks* tasks) { const int route_end = tasks->num_chain_tasks - 1; const int num_tasks = tasks->start_min.size(); for (int i = 0; i < tasks->distance_duration.size(); ++i) { - const int64 max_distance = tasks->distance_duration[i].first; - const int64 minimum_break_duration = tasks->distance_duration[i].second; + const int64_t max_distance = tasks->distance_duration[i].first; + const int64_t minimum_break_duration = tasks->distance_duration[i].second; // This is a sweeping algorithm that looks whether the union of intervals // defined by breaks and route start/end is (-infty, +infty). @@ -338,16 +354,16 @@ bool DisjunctivePropagator::DistanceDuration(Tasks* tasks) { // unique break to cover it. // Route start and end get a special treatment, not sure generalizing // would be better. - int64 xor_active_tasks = route_start; + int64_t xor_active_tasks = route_start; int num_active_tasks = 1; - int64 previous_time = kint64min; - const int64 route_start_time = + int64_t previous_time = std::numeric_limits::min(); + const int64_t route_start_time = CapAdd(tasks->end_max[route_start], max_distance); - const int64 route_end_time = tasks->start_min[route_end]; + const int64_t route_end_time = tasks->start_min[route_end]; int index_break_by_smin = tasks->num_chain_tasks; while (index_break_by_emax < num_tasks) { // Find next time point among start/end of covering intervals. - int64 current_time = + int64_t current_time = CapAdd(tasks->end_max[index_break_by_emax], max_distance); if (index_break_by_smin < num_tasks) { current_time = @@ -433,13 +449,13 @@ bool DisjunctivePropagator::ChainSpanMin(Tasks* tasks) { // The duration of the chain plus that of nonchain tasks that must be // performed during the chain is a lower bound of the chain span. { - int64 sum_chain_durations = 0; + int64_t sum_chain_durations = 0; const auto duration_start = tasks->duration_min.begin(); const auto duration_end = tasks->duration_min.begin() + num_chain_tasks; for (auto it = duration_start; it != duration_end; ++it) { sum_chain_durations = CapAdd(sum_chain_durations, *it); } - int64 sum_forced_nonchain_durations = 0; + int64_t sum_forced_nonchain_durations = 0; for (int i = num_chain_tasks; i < tasks->start_min.size(); ++i) { // Tasks that can be executed before or after are skipped. if (tasks->end_min[i] <= tasks->start_max[0] || @@ -455,7 +471,7 @@ bool DisjunctivePropagator::ChainSpanMin(Tasks* tasks) { } // The difference end of the chain - start of the chain is a lower bound. { - const int64 end_minus_start = + const int64_t end_minus_start = CapSub(tasks->end_min[num_chain_tasks - 1], tasks->start_max[0]); tasks->span_min = std::max(tasks->span_min, end_minus_start); } @@ -473,10 +489,10 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { if (num_chain_tasks == tasks->start_min.size()) return true; const int task_index = num_chain_tasks; if (!Precedences(tasks)) return false; - const int64 min_possible_chain_end = tasks->end_min[num_chain_tasks - 1]; - const int64 max_possible_chain_start = tasks->start_max[0]; + const int64_t min_possible_chain_end = tasks->end_min[num_chain_tasks - 1]; + const int64_t max_possible_chain_start = tasks->start_max[0]; // For each chain task i, compute cumulated duration of chain tasks before it. - int64 total_duration = 0; + int64_t total_duration = 0; { total_duration_before_.resize(num_chain_tasks); for (int i = 0; i < num_chain_tasks; ++i) { @@ -490,7 +506,7 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { // chain span because of chain precedence constraints, // i.e. min_possible_chain_end - total_duration. { - const int64 chain_span_min = + const int64_t chain_span_min = min_possible_chain_end - std::min(tasks->start_max[0], min_possible_chain_end - total_duration); if (chain_span_min > tasks->span_max) { @@ -507,17 +523,17 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { } // Scan all possible preemption positions of the nontask chain, // keep the one that yields the minimum span. - int64 span_min = kint64max; + int64_t span_min = std::numeric_limits::max(); bool schedule_is_feasible = false; for (int i = 0; i < num_chain_tasks; ++i) { if (!tasks->is_preemptible[i]) continue; // Estimate span min if tasks is performed during i. // For all possible minimal-span schedules, there is a schedule where task i // and nonchain task form a single block. Thus, we only consider those. - const int64 block_start_min = + const int64_t block_start_min = std::max(tasks->start_min[i], tasks->start_min[task_index] - tasks->duration_min[i]); - const int64 block_start_max = + const int64_t block_start_max = std::min(tasks->start_max[task_index], tasks->start_max[i] - tasks->duration_min[task_index]); if (block_start_min > block_start_max) continue; @@ -534,13 +550,13 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { // an inflection point at which it stays constant. That inflection value // is the one where the precedence constraints force the chain start to // decrease because of durations. - const int64 head_inflection = + const int64_t head_inflection = max_possible_chain_start + total_duration_before_[i]; // The map from block start to minimal tail length also has an inflection // point, that additionally depends on the nonchain task's duration. - const int64 tail_inflection = min_possible_chain_end - - (total_duration - total_duration_before_[i]) - - tasks->duration_min[task_index]; + const int64_t tail_inflection = + min_possible_chain_end - (total_duration - total_duration_before_[i]) - + tasks->duration_min[task_index]; // All block start values between these two yield the same minimal span. // Indeed, first, mind that the inflection points might be in any order. // - if head_inflection < tail_inflection, then inside the interval @@ -553,13 +569,13 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { // In both cases, outside of the interval, one part is constant and the // other increases as much as the distance to the interval. // We can abstract inflection point to the interval they form. - const int64 optimal_interval_min_start = + const int64_t optimal_interval_min_start = std::min(head_inflection, tail_inflection); - const int64 optimal_interval_max_start = + const int64_t optimal_interval_max_start = std::max(head_inflection, tail_inflection); // If the optimal interval for block start intersects the feasible interval, // we can select any point within it, for instance the earliest one. - int64 block_start = std::max(optimal_interval_min_start, block_start_min); + int64_t block_start = std::max(optimal_interval_min_start, block_start_min); // If the intervals do not intersect, the feasible value closest to the // optimal interval has the minimal span, because the span increases as // much as the distance to the optimal interval. @@ -571,11 +587,11 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { block_start = block_start_max; } // Compute span for the chosen block start. - const int64 head_duration = + const int64_t head_duration = std::max(block_start, head_inflection) - max_possible_chain_start; - const int64 tail_duration = + const int64_t tail_duration = min_possible_chain_end - std::min(block_start, tail_inflection); - const int64 optimal_span_at_i = head_duration + tail_duration; + const int64_t optimal_span_at_i = head_duration + tail_duration; span_min = std::min(span_min, optimal_span_at_i); schedule_is_feasible = true; } @@ -587,7 +603,7 @@ bool DisjunctivePropagator::ChainSpanMinDynamic(Tasks* tasks) { } } -void AppendTasksFromPath(const std::vector& path, +void AppendTasksFromPath(const std::vector& path, const TravelBounds& travel_bounds, const RoutingDimension& dimension, DisjunctivePropagator::Tasks* tasks) { @@ -595,15 +611,15 @@ void AppendTasksFromPath(const std::vector& path, DCHECK_EQ(travel_bounds.pre_travels.size(), num_nodes - 1); DCHECK_EQ(travel_bounds.post_travels.size(), num_nodes - 1); for (int i = 0; i < num_nodes; ++i) { - const int64 cumul_min = dimension.CumulVar(path[i])->Min(); - const int64 cumul_max = dimension.CumulVar(path[i])->Max(); + const int64_t cumul_min = dimension.CumulVar(path[i])->Min(); + const int64_t cumul_max = dimension.CumulVar(path[i])->Max(); // Add task associated to visit i. // Visits start at Cumul(path[i]) - before_visit // and end at Cumul(path[i]) + after_visit { - const int64 before_visit = + const int64_t before_visit = (i == 0) ? 0 : travel_bounds.post_travels[i - 1]; - const int64 after_visit = + const int64_t after_visit = (i == num_nodes - 1) ? 0 : travel_bounds.pre_travels[i]; tasks->start_min.push_back(CapSub(cumul_min, before_visit)); @@ -621,18 +637,18 @@ void AppendTasksFromPath(const std::vector& path, // last for FixedTransitVar(path[i]) - pre_travel - post_travel, // and must end at the latest at Cumul(path[i+1]) - post_travel. { - const int64 pre_travel = travel_bounds.pre_travels[i]; - const int64 post_travel = travel_bounds.post_travels[i]; + const int64_t pre_travel = travel_bounds.pre_travels[i]; + const int64_t post_travel = travel_bounds.post_travels[i]; tasks->start_min.push_back(CapAdd(cumul_min, pre_travel)); tasks->start_max.push_back(CapAdd(cumul_max, pre_travel)); tasks->duration_min.push_back( - std::max(0, CapSub(travel_bounds.min_travels[i], - CapAdd(pre_travel, post_travel)))); + std::max(0, CapSub(travel_bounds.min_travels[i], + CapAdd(pre_travel, post_travel)))); tasks->duration_max.push_back( - travel_bounds.max_travels[i] == kint64max - ? kint64max - : std::max(0, CapSub(travel_bounds.max_travels[i], - CapAdd(pre_travel, post_travel)))); + travel_bounds.max_travels[i] == std::numeric_limits::max() + ? std::numeric_limits::max() + : std::max(0, CapSub(travel_bounds.max_travels[i], + CapAdd(pre_travel, post_travel)))); tasks->end_min.push_back( CapSub(dimension.CumulVar(path[i + 1])->Min(), post_travel)); tasks->end_max.push_back( @@ -642,14 +658,15 @@ void AppendTasksFromPath(const std::vector& path, } } -void FillTravelBoundsOfVehicle(int vehicle, const std::vector& path, +void FillTravelBoundsOfVehicle(int vehicle, const std::vector& path, const RoutingDimension& dimension, TravelBounds* travel_bounds) { // Fill path and min/max/pre/post travel bounds. FillPathEvaluation(path, dimension.transit_evaluator(vehicle), &travel_bounds->min_travels); const int num_travels = travel_bounds->min_travels.size(); - travel_bounds->max_travels.assign(num_travels, kint64max); + travel_bounds->max_travels.assign(num_travels, + std::numeric_limits::max()); { const int index = dimension.GetPreTravelEvaluatorOfVehicle(vehicle); if (index == -1) { @@ -753,7 +770,7 @@ void GlobalVehicleBreaksConstraint::FillPartialPathOfVehicle(int vehicle) { } void GlobalVehicleBreaksConstraint::FillPathTravels( - const std::vector& path) { + const std::vector& path) { const int num_travels = path.size() - 1; travel_bounds_.min_travels.resize(num_travels); travel_bounds_.max_travels.resize(num_travels); @@ -791,7 +808,7 @@ void GlobalVehicleBreaksConstraint::PropagateVehicle(int vehicle) { // The last travel might not be fixed: in that case, relax its information. if (!model_->NextVar(path_[num_nodes - 2])->Bound()) { travel_bounds_.min_travels.back() = 0; - travel_bounds_.max_travels.back() = kint64max; + travel_bounds_.max_travels.back() = std::numeric_limits::max(); travel_bounds_.pre_travels.back() = 0; travel_bounds_.post_travels.back() = 0; } @@ -811,9 +828,9 @@ void GlobalVehicleBreaksConstraint::PropagateVehicle(int vehicle) { // Make task translators to help set new bounds of CP variables. task_translators_.clear(); for (int i = 0; i < num_nodes; ++i) { - const int64 before_visit = + const int64_t before_visit = (i == 0) ? 0 : travel_bounds_.post_travels[i - 1]; - const int64 after_visit = + const int64_t after_visit = (i == num_nodes - 1) ? 0 : travel_bounds_.pre_travels[i]; task_translators_.emplace_back(dimension_->CumulVar(path_[i]), before_visit, after_visit); @@ -841,22 +858,22 @@ void GlobalVehicleBreaksConstraint::PropagateVehicle(int vehicle) { // TODO(user): Make a version more efficient than O(n^2). if (dimension_->GetBreakIntervalsOfVehicle(vehicle).empty()) return; // If the last arc of the path was not bound, do not change slack. - const int64 last_bound_arc = + const int64_t last_bound_arc = num_nodes - 2 - (model_->NextVar(path_[num_nodes - 2])->Bound() ? 0 : 1); for (int i = 0; i <= last_bound_arc; ++i) { - const int64 arc_start_max = + const int64_t arc_start_max = CapSub(dimension_->CumulVar(path_[i])->Max(), i > 0 ? travel_bounds_.post_travels[i - 1] : 0); - const int64 arc_end_min = + const int64_t arc_end_min = CapAdd(dimension_->CumulVar(path_[i + 1])->Min(), i < num_nodes - 2 ? travel_bounds_.pre_travels[i + 1] : 0); - int64 total_break_inside_arc = 0; + int64_t total_break_inside_arc = 0; for (IntervalVar* interval : dimension_->GetBreakIntervalsOfVehicle(vehicle)) { if (!interval->MustBePerformed()) continue; - const int64 interval_start_max = interval->StartMax(); - const int64 interval_end_min = interval->EndMin(); - const int64 interval_duration_min = interval->DurationMin(); + const int64_t interval_start_max = interval->StartMax(); + const int64_t interval_end_min = interval->EndMin(); + const int64_t interval_duration_min = interval->DurationMin(); // If interval cannot end before the arc's from node and // cannot start after the 'to' node, then it must be inside the arc. if (arc_start_max < interval_end_min && @@ -883,33 +900,33 @@ void GlobalVehicleBreaksConstraint::PropagateVehicle(int vehicle) { const std::vector& break_intervals = dimension_->GetBreakIntervalsOfVehicle(vehicle); for (int pos = 0; pos < num_nodes - 1; ++pos) { - const int64 current_slack_max = dimension_->SlackVar(path_[pos])->Max(); - const int64 visit_start_offset = + const int64_t current_slack_max = dimension_->SlackVar(path_[pos])->Max(); + const int64_t visit_start_offset = pos > 0 ? travel_bounds_.post_travels[pos - 1] : 0; - const int64 visit_start_max = + const int64_t visit_start_max = CapSub(dimension_->CumulVar(path_[pos])->Max(), visit_start_offset); - const int64 visit_end_offset = + const int64_t visit_end_offset = (pos < num_nodes - 1) ? travel_bounds_.pre_travels[pos] : 0; - const int64 visit_end_min = + const int64_t visit_end_min = CapAdd(dimension_->CumulVar(path_[pos])->Min(), visit_end_offset); for (IntervalVar* interval : break_intervals) { if (!interval->MayBePerformed()) continue; const bool interval_is_performed = interval->MustBePerformed(); - const int64 interval_start_max = interval->StartMax(); - const int64 interval_end_min = interval->EndMin(); - const int64 interval_duration_min = interval->DurationMin(); + const int64_t interval_start_max = interval->StartMax(); + const int64_t interval_end_min = interval->EndMin(); + const int64_t interval_duration_min = interval->DurationMin(); // When interval cannot fit inside current arc, // do disjunctive reasoning on full arc. if (pos < num_nodes - 1 && interval_duration_min > current_slack_max) { // The arc lasts from CumulVar(path_[pos]) - post_travel_[pos] to // CumulVar(path_[pos+1]) + pre_travel_[pos+1]. - const int64 arc_start_offset = + const int64_t arc_start_offset = pos > 0 ? travel_bounds_.post_travels[pos - 1] : 0; - const int64 arc_start_max = visit_start_max; - const int64 arc_end_offset = + const int64_t arc_start_max = visit_start_max; + const int64_t arc_end_offset = (pos < num_nodes - 2) ? travel_bounds_.pre_travels[pos + 1] : 0; - const int64 arc_end_min = + const int64_t arc_end_min = CapAdd(dimension_->CumulVar(path_[pos + 1])->Min(), arc_end_offset); // Interval not before. if (arc_start_max < interval_end_min) { @@ -957,13 +974,13 @@ class VehicleBreaksFilter : public BasePathFilter { VehicleBreaksFilter(const RoutingModel& routing_model, const RoutingDimension& dimension); std::string DebugString() const override { return "VehicleBreaksFilter"; } - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; private: // Fills path_ with the path of vehicle, start to end. - void FillPathOfVehicle(int64 vehicle); - std::vector path_; + void FillPathOfVehicle(int64_t vehicle); + std::vector path_; // Handles to model. const RoutingModel& model_; const RoutingDimension& dimension_; @@ -971,10 +988,10 @@ class VehicleBreaksFilter : public BasePathFilter { DisjunctivePropagator disjunctive_propagator_; DisjunctivePropagator::Tasks tasks_; // Used to check whether propagation changed a vector. - std::vector old_start_min_; - std::vector old_start_max_; - std::vector old_end_min_; - std::vector old_end_max_; + std::vector old_start_min_; + std::vector old_start_max_; + std::vector old_end_min_; + std::vector old_end_max_; std::vector start_to_vehicle_; TravelBounds travel_bounds_; @@ -993,7 +1010,7 @@ VehicleBreaksFilter::VehicleBreaksFilter(const RoutingModel& routing_model, } } -void VehicleBreaksFilter::FillPathOfVehicle(int64 vehicle) { +void VehicleBreaksFilter::FillPathOfVehicle(int64_t vehicle) { path_.clear(); int current = model_.Start(vehicle); while (!model_.IsEnd(current)) { @@ -1003,8 +1020,8 @@ void VehicleBreaksFilter::FillPathOfVehicle(int64 vehicle) { path_.push_back(current); } -bool VehicleBreaksFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { +bool VehicleBreaksFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { const int vehicle = start_to_vehicle_[path_start]; if (dimension_.GetBreakIntervalsOfVehicle(vehicle).empty() && dimension_.GetBreakDistanceDurationOfVehicle(vehicle).empty()) { @@ -1021,7 +1038,7 @@ bool VehicleBreaksFilter::AcceptPath(int64 path_start, int64 chain_start, &tasks_); // Add forbidden intervals only if a node has some. tasks_.forbidden_intervals.clear(); - if (std::any_of(path_.begin(), path_.end(), [this](int64 node) { + if (std::any_of(path_.begin(), path_.end(), [this](int64_t node) { return dimension_.forbidden_intervals()[node].NumIntervals() > 0; })) { tasks_.forbidden_intervals.assign(tasks_.start_min.size(), nullptr); diff --git a/ortools/constraint_solver/routing_filters.cc b/ortools/constraint_solver/routing_filters.cc new file mode 100644 index 0000000000..008f0300a3 --- /dev/null +++ b/ortools/constraint_solver/routing_filters.cc @@ -0,0 +1,2814 @@ +// Copyright 2010-2018 Google LLC +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Implementation of local search filters for routing models. + +#include "ortools/constraint_solver/routing_filters.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/flags/flag.h" +#include "absl/memory/memory.h" +#include "absl/strings/string_view.h" +#include "ortools/base/int_type.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/map_util.h" +#include "ortools/base/small_map.h" +#include "ortools/base/small_ordered_set.h" +#include "ortools/base/strong_vector.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_lp_scheduling.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/util/bitset.h" +#include "ortools/util/piecewise_linear_function.h" +#include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" + +ABSL_FLAG(bool, routing_strong_debug_checks, false, + "Run stronger checks in debug; these stronger tests might change " + "the complexity of the code in particular."); + +namespace operations_research { + +namespace { + +// Max active vehicles filter. + +class MaxActiveVehiclesFilter : public IntVarLocalSearchFilter { + public: + explicit MaxActiveVehiclesFilter(const RoutingModel& routing_model) + : IntVarLocalSearchFilter(routing_model.Nexts()), + routing_model_(routing_model), + is_active_(routing_model.vehicles(), false), + active_vehicles_(0) {} + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override { + const int64_t kUnassigned = -1; + const Assignment::IntContainer& container = delta->IntVarContainer(); + const int delta_size = container.Size(); + int current_active_vehicles = active_vehicles_; + for (int i = 0; i < delta_size; ++i) { + const IntVarElement& new_element = container.Element(i); + IntVar* const var = new_element.Var(); + int64_t index = kUnassigned; + if (FindIndex(var, &index) && routing_model_.IsStart(index)) { + if (new_element.Min() != new_element.Max()) { + // LNS detected. + return true; + } + const int vehicle = routing_model_.VehicleIndex(index); + const bool is_active = + (new_element.Min() != routing_model_.End(vehicle)); + if (is_active && !is_active_[vehicle]) { + ++current_active_vehicles; + } else if (!is_active && is_active_[vehicle]) { + --current_active_vehicles; + } + } + } + return current_active_vehicles <= + routing_model_.GetMaximumNumberOfActiveVehicles(); + } + + private: + void OnSynchronize(const Assignment* delta) override { + active_vehicles_ = 0; + for (int i = 0; i < routing_model_.vehicles(); ++i) { + const int index = routing_model_.Start(i); + if (IsVarSynced(index) && Value(index) != routing_model_.End(i)) { + is_active_[i] = true; + ++active_vehicles_; + } else { + is_active_[i] = false; + } + } + } + + const RoutingModel& routing_model_; + std::vector is_active_; + int active_vehicles_; +}; +} // namespace + +IntVarLocalSearchFilter* MakeMaxActiveVehiclesFilter( + const RoutingModel& routing_model) { + return routing_model.solver()->RevAlloc( + new MaxActiveVehiclesFilter(routing_model)); +} + +namespace { + +// Node disjunction filter class. + +class NodeDisjunctionFilter : public IntVarLocalSearchFilter { + public: + explicit NodeDisjunctionFilter(const RoutingModel& routing_model) + : IntVarLocalSearchFilter(routing_model.Nexts()), + routing_model_(routing_model), + active_per_disjunction_(routing_model.GetNumberOfDisjunctions(), 0), + inactive_per_disjunction_(routing_model.GetNumberOfDisjunctions(), 0), + synchronized_objective_value_(std::numeric_limits::min()), + accepted_objective_value_(std::numeric_limits::min()) {} + + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override { + const int64_t kUnassigned = -1; + const Assignment::IntContainer& container = delta->IntVarContainer(); + const int delta_size = container.Size(); + gtl::small_map> + disjunction_active_deltas; + gtl::small_map> + disjunction_inactive_deltas; + bool lns_detected = false; + // Update active/inactive count per disjunction for each element of delta. + for (int i = 0; i < delta_size; ++i) { + const IntVarElement& new_element = container.Element(i); + IntVar* const var = new_element.Var(); + int64_t index = kUnassigned; + if (FindIndex(var, &index)) { + const bool is_inactive = + (new_element.Min() <= index && new_element.Max() >= index); + if (new_element.Min() != new_element.Max()) { + lns_detected = true; + } + for (const RoutingModel::DisjunctionIndex disjunction_index : + routing_model_.GetDisjunctionIndices(index)) { + const bool active_state_changed = + !IsVarSynced(index) || (Value(index) == index) != is_inactive; + if (active_state_changed) { + if (!is_inactive) { + ++gtl::LookupOrInsert(&disjunction_active_deltas, + disjunction_index, 0); + if (IsVarSynced(index)) { + --gtl::LookupOrInsert(&disjunction_inactive_deltas, + disjunction_index, 0); + } + } else { + ++gtl::LookupOrInsert(&disjunction_inactive_deltas, + disjunction_index, 0); + if (IsVarSynced(index)) { + --gtl::LookupOrInsert(&disjunction_active_deltas, + disjunction_index, 0); + } + } + } + } + } + } + // Check if any disjunction has too many active nodes. + for (const std::pair + disjunction_active_delta : disjunction_active_deltas) { + const int current_active_nodes = + active_per_disjunction_[disjunction_active_delta.first]; + const int active_nodes = + current_active_nodes + disjunction_active_delta.second; + const int max_cardinality = routing_model_.GetDisjunctionMaxCardinality( + disjunction_active_delta.first); + // Too many active nodes. + if (active_nodes > max_cardinality) { + return false; + } + } + // Update penalty costs for disjunctions. + accepted_objective_value_ = synchronized_objective_value_; + for (const std::pair + disjunction_inactive_delta : disjunction_inactive_deltas) { + const int64_t penalty = routing_model_.GetDisjunctionPenalty( + disjunction_inactive_delta.first); + if (penalty != 0 && !lns_detected) { + const RoutingModel::DisjunctionIndex disjunction_index = + disjunction_inactive_delta.first; + const int current_inactive_nodes = + inactive_per_disjunction_[disjunction_index]; + const int inactive_nodes = + current_inactive_nodes + disjunction_inactive_delta.second; + const int max_inactive_cardinality = + routing_model_.GetDisjunctionIndices(disjunction_index).size() - + routing_model_.GetDisjunctionMaxCardinality(disjunction_index); + // Too many inactive nodes. + if (inactive_nodes > max_inactive_cardinality) { + if (penalty < 0) { + // Nodes are mandatory, i.e. exactly max_cardinality nodes must be + // performed, so the move is not acceptable. + return false; + } else if (current_inactive_nodes <= max_inactive_cardinality) { + // Add penalty if there were not too many inactive nodes before the + // move. + accepted_objective_value_ = + CapAdd(accepted_objective_value_, penalty); + } + } else if (current_inactive_nodes > max_inactive_cardinality) { + // Remove penalty if there were too many inactive nodes before the + // move and there are not too many after the move. + accepted_objective_value_ = + CapSub(accepted_objective_value_, penalty); + } + } + } + if (lns_detected) { + accepted_objective_value_ = 0; + return true; + } else { + // Only compare to max as a cost lower bound is computed. + return accepted_objective_value_ <= objective_max; + } + } + std::string DebugString() const override { return "NodeDisjunctionFilter"; } + int64_t GetSynchronizedObjectiveValue() const override { + return synchronized_objective_value_; + } + int64_t GetAcceptedObjectiveValue() const override { + return accepted_objective_value_; + } + + private: + void OnSynchronize(const Assignment* delta) override { + synchronized_objective_value_ = 0; + for (RoutingModel::DisjunctionIndex i(0); + i < active_per_disjunction_.size(); ++i) { + active_per_disjunction_[i] = 0; + inactive_per_disjunction_[i] = 0; + const std::vector& disjunction_indices = + routing_model_.GetDisjunctionIndices(i); + for (const int64_t index : disjunction_indices) { + const bool index_synced = IsVarSynced(index); + if (index_synced) { + if (Value(index) != index) { + ++active_per_disjunction_[i]; + } else { + ++inactive_per_disjunction_[i]; + } + } + } + const int64_t penalty = routing_model_.GetDisjunctionPenalty(i); + const int max_cardinality = + routing_model_.GetDisjunctionMaxCardinality(i); + if (inactive_per_disjunction_[i] > + disjunction_indices.size() - max_cardinality && + penalty > 0) { + synchronized_objective_value_ = + CapAdd(synchronized_objective_value_, penalty); + } + } + } + + const RoutingModel& routing_model_; + + absl::StrongVector + active_per_disjunction_; + absl::StrongVector + inactive_per_disjunction_; + int64_t synchronized_objective_value_; + int64_t accepted_objective_value_; +}; +} // namespace + +IntVarLocalSearchFilter* MakeNodeDisjunctionFilter( + const RoutingModel& routing_model) { + return routing_model.solver()->RevAlloc( + new NodeDisjunctionFilter(routing_model)); +} + +const int64_t BasePathFilter::kUnassigned = -1; + +BasePathFilter::BasePathFilter(const std::vector& nexts, + int next_domain_size) + : IntVarLocalSearchFilter(nexts), + node_path_starts_(next_domain_size, kUnassigned), + paths_(nexts.size(), -1), + new_synchronized_unperformed_nodes_(nexts.size()), + new_nexts_(nexts.size(), kUnassigned), + touched_paths_(nexts.size()), + touched_path_chain_start_ends_(nexts.size(), {kUnassigned, kUnassigned}), + ranks_(next_domain_size, -1), + status_(BasePathFilter::UNKNOWN) {} + +bool BasePathFilter::Accept(const Assignment* delta, + const Assignment* deltadelta, int64_t objective_min, + int64_t objective_max) { + if (IsDisabled()) return true; + for (const int touched : delta_touched_) { + new_nexts_[touched] = kUnassigned; + } + delta_touched_.clear(); + const Assignment::IntContainer& container = delta->IntVarContainer(); + const int delta_size = container.Size(); + delta_touched_.reserve(delta_size); + // Determining touched paths and their touched chain start and ends (a node is + // touched if it corresponds to an element of delta or that an element of + // delta points to it). + // The start and end of a touched path subchain will have remained on the same + // path and will correspond to the min and max ranks of touched nodes in the + // current assignment. + for (int64_t touched_path : touched_paths_.PositionsSetAtLeastOnce()) { + touched_path_chain_start_ends_[touched_path] = {kUnassigned, kUnassigned}; + } + touched_paths_.SparseClearAll(); + + const auto update_touched_path_chain_start_end = [this](int64_t index) { + const int64_t start = node_path_starts_[index]; + if (start == kUnassigned) return; + touched_paths_.Set(start); + + int64_t& chain_start = touched_path_chain_start_ends_[start].first; + if (chain_start == kUnassigned || ranks_[index] < ranks_[chain_start]) { + chain_start = index; + } + + int64_t& chain_end = touched_path_chain_start_ends_[start].second; + if (chain_end == kUnassigned || ranks_[index] > ranks_[chain_end]) { + chain_end = index; + } + }; + + for (int i = 0; i < delta_size; ++i) { + const IntVarElement& new_element = container.Element(i); + IntVar* const var = new_element.Var(); + int64_t index = kUnassigned; + if (FindIndex(var, &index)) { + if (!new_element.Bound()) { + // LNS detected + return true; + } + new_nexts_[index] = new_element.Value(); + delta_touched_.push_back(index); + update_touched_path_chain_start_end(index); + update_touched_path_chain_start_end(new_nexts_[index]); + } + } + // Checking feasibility of touched paths. + InitializeAcceptPath(); + bool accept = true; + for (const int64_t touched_start : touched_paths_.PositionsSetAtLeastOnce()) { + const std::pair start_end = + touched_path_chain_start_ends_[touched_start]; + if (!AcceptPath(touched_start, start_end.first, start_end.second)) { + accept = false; + break; + } + } + // NOTE: FinalizeAcceptPath() is only called if all paths are accepted. + return accept && FinalizeAcceptPath(delta, objective_min, objective_max); +} + +void BasePathFilter::ComputePathStarts(std::vector* path_starts, + std::vector* index_to_path) { + path_starts->clear(); + const int nexts_size = Size(); + index_to_path->assign(nexts_size, kUnassigned); + Bitset64<> has_prevs(nexts_size); + for (int i = 0; i < nexts_size; ++i) { + if (!IsVarSynced(i)) { + has_prevs.Set(i); + } else { + const int next = Value(i); + if (next < nexts_size) { + has_prevs.Set(next); + } + } + } + for (int i = 0; i < nexts_size; ++i) { + if (!has_prevs[i]) { + (*index_to_path)[i] = path_starts->size(); + path_starts->push_back(i); + } + } +} + +bool BasePathFilter::HavePathsChanged() { + std::vector path_starts; + std::vector index_to_path(Size(), kUnassigned); + ComputePathStarts(&path_starts, &index_to_path); + if (path_starts.size() != starts_.size()) { + return true; + } + for (int i = 0; i < path_starts.size(); ++i) { + if (path_starts[i] != starts_[i]) { + return true; + } + } + for (int i = 0; i < Size(); ++i) { + if (index_to_path[i] != paths_[i]) { + return true; + } + } + return false; +} + +void BasePathFilter::SynchronizeFullAssignment() { + // Subclasses of BasePathFilter might not propagate injected objective values + // so making sure it is done here (can be done again by the subclass if + // needed). + ComputePathStarts(&starts_, &paths_); + for (int64_t index = 0; index < Size(); index++) { + if (IsVarSynced(index) && Value(index) == index && + node_path_starts_[index] != kUnassigned) { + // index was performed before and is now unperformed. + new_synchronized_unperformed_nodes_.Set(index); + } + } + // Marking unactive nodes (which are not on a path). + node_path_starts_.assign(node_path_starts_.size(), kUnassigned); + // Marking nodes on a path and storing next values. + const int nexts_size = Size(); + for (const int64_t start : starts_) { + int node = start; + node_path_starts_[node] = start; + DCHECK(IsVarSynced(node)); + int next = Value(node); + while (next < nexts_size) { + node = next; + node_path_starts_[node] = start; + DCHECK(IsVarSynced(node)); + next = Value(node); + } + node_path_starts_[next] = start; + } + OnBeforeSynchronizePaths(); + UpdateAllRanks(); + OnAfterSynchronizePaths(); +} + +void BasePathFilter::OnSynchronize(const Assignment* delta) { + if (status_ == BasePathFilter::UNKNOWN) { + status_ = + DisableFiltering() ? BasePathFilter::DISABLED : BasePathFilter::ENABLED; + } + if (IsDisabled()) return; + new_synchronized_unperformed_nodes_.ClearAll(); + if (delta == nullptr || delta->Empty() || starts_.empty()) { + SynchronizeFullAssignment(); + return; + } + // Subclasses of BasePathFilter might not propagate injected objective values + // so making sure it is done here (can be done again by the subclass if + // needed). + // This code supposes that path starts didn't change. + DCHECK(!absl::GetFlag(FLAGS_routing_strong_debug_checks) || + !HavePathsChanged()); + const Assignment::IntContainer& container = delta->IntVarContainer(); + touched_paths_.SparseClearAll(); + for (int i = 0; i < container.Size(); ++i) { + const IntVarElement& new_element = container.Element(i); + int64_t index = kUnassigned; + if (FindIndex(new_element.Var(), &index)) { + const int64_t start = node_path_starts_[index]; + if (start != kUnassigned) { + touched_paths_.Set(start); + if (Value(index) == index) { + // New unperformed node (its previous start isn't unassigned). + DCHECK_LT(index, new_nexts_.size()); + new_synchronized_unperformed_nodes_.Set(index); + node_path_starts_[index] = kUnassigned; + } + } + } + } + OnBeforeSynchronizePaths(); + for (const int64_t touched_start : touched_paths_.PositionsSetAtLeastOnce()) { + int64_t node = touched_start; + while (node < Size()) { + node_path_starts_[node] = touched_start; + node = Value(node); + } + node_path_starts_[node] = touched_start; + UpdatePathRanksFromStart(touched_start); + OnSynchronizePathFromStart(touched_start); + } + OnAfterSynchronizePaths(); +} + +void BasePathFilter::UpdateAllRanks() { + for (int i = 0; i < ranks_.size(); ++i) { + ranks_[i] = kUnassigned; + } + for (int r = 0; r < NumPaths(); ++r) { + UpdatePathRanksFromStart(Start(r)); + OnSynchronizePathFromStart(Start(r)); + } +} + +void BasePathFilter::UpdatePathRanksFromStart(int start) { + int rank = 0; + int64_t node = start; + while (node < Size()) { + ranks_[node] = rank; + rank++; + node = Value(node); + } + ranks_[node] = rank; +} + +namespace { + +class VehicleAmortizedCostFilter : public BasePathFilter { + public: + explicit VehicleAmortizedCostFilter(const RoutingModel& routing_model); + ~VehicleAmortizedCostFilter() override {} + std::string DebugString() const override { + return "VehicleAmortizedCostFilter"; + } + int64_t GetSynchronizedObjectiveValue() const override { + return current_vehicle_cost_; + } + int64_t GetAcceptedObjectiveValue() const override { + return delta_vehicle_cost_; + } + + private: + void OnSynchronizePathFromStart(int64_t start) override; + void OnAfterSynchronizePaths() override; + void InitializeAcceptPath() override; + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + bool FinalizeAcceptPath(const Assignment* delta, int64_t objective_min, + int64_t objective_max) override; + + int64_t current_vehicle_cost_; + int64_t delta_vehicle_cost_; + std::vector current_route_lengths_; + std::vector start_to_end_; + std::vector start_to_vehicle_; + std::vector vehicle_to_start_; + const std::vector& linear_cost_factor_of_vehicle_; + const std::vector& quadratic_cost_factor_of_vehicle_; +}; + +VehicleAmortizedCostFilter::VehicleAmortizedCostFilter( + const RoutingModel& routing_model) + : BasePathFilter(routing_model.Nexts(), + routing_model.Size() + routing_model.vehicles()), + current_vehicle_cost_(0), + delta_vehicle_cost_(0), + current_route_lengths_(Size(), -1), + linear_cost_factor_of_vehicle_( + routing_model.GetAmortizedLinearCostFactorOfVehicles()), + quadratic_cost_factor_of_vehicle_( + routing_model.GetAmortizedQuadraticCostFactorOfVehicles()) { + start_to_end_.resize(Size(), -1); + start_to_vehicle_.resize(Size(), -1); + vehicle_to_start_.resize(routing_model.vehicles()); + for (int v = 0; v < routing_model.vehicles(); v++) { + const int64_t start = routing_model.Start(v); + start_to_vehicle_[start] = v; + start_to_end_[start] = routing_model.End(v); + vehicle_to_start_[v] = start; + } +} + +void VehicleAmortizedCostFilter::OnSynchronizePathFromStart(int64_t start) { + const int64_t end = start_to_end_[start]; + CHECK_GE(end, 0); + const int route_length = Rank(end) - 1; + CHECK_GE(route_length, 0); + current_route_lengths_[start] = route_length; +} + +void VehicleAmortizedCostFilter::OnAfterSynchronizePaths() { + current_vehicle_cost_ = 0; + for (int vehicle = 0; vehicle < vehicle_to_start_.size(); vehicle++) { + const int64_t start = vehicle_to_start_[vehicle]; + DCHECK_EQ(vehicle, start_to_vehicle_[start]); + + const int route_length = current_route_lengths_[start]; + DCHECK_GE(route_length, 0); + + if (route_length == 0) { + // The path is empty. + continue; + } + + const int64_t linear_cost_factor = linear_cost_factor_of_vehicle_[vehicle]; + const int64_t route_length_cost = + CapProd(quadratic_cost_factor_of_vehicle_[vehicle], + route_length * route_length); + + current_vehicle_cost_ = CapAdd( + current_vehicle_cost_, CapSub(linear_cost_factor, route_length_cost)); + } +} + +void VehicleAmortizedCostFilter::InitializeAcceptPath() { + delta_vehicle_cost_ = current_vehicle_cost_; +} + +bool VehicleAmortizedCostFilter::AcceptPath(int64_t path_start, + int64_t chain_start, + int64_t chain_end) { + // Number of nodes previously between chain_start and chain_end + const int previous_chain_nodes = Rank(chain_end) - 1 - Rank(chain_start); + CHECK_GE(previous_chain_nodes, 0); + int new_chain_nodes = 0; + int64_t node = GetNext(chain_start); + while (node != chain_end) { + new_chain_nodes++; + node = GetNext(node); + } + + const int previous_route_length = current_route_lengths_[path_start]; + CHECK_GE(previous_route_length, 0); + const int new_route_length = + previous_route_length - previous_chain_nodes + new_chain_nodes; + + const int vehicle = start_to_vehicle_[path_start]; + CHECK_GE(vehicle, 0); + DCHECK_EQ(path_start, vehicle_to_start_[vehicle]); + + // Update the cost related to used vehicles. + // TODO(user): Handle possible overflows. + if (previous_route_length == 0) { + // The route was empty before, it is no longer the case (changed path). + CHECK_GT(new_route_length, 0); + delta_vehicle_cost_ = + CapAdd(delta_vehicle_cost_, linear_cost_factor_of_vehicle_[vehicle]); + } else if (new_route_length == 0) { + // The route is now empty. + delta_vehicle_cost_ = + CapSub(delta_vehicle_cost_, linear_cost_factor_of_vehicle_[vehicle]); + } + + // Update the cost related to the sum of the squares of the route lengths. + const int64_t quadratic_cost_factor = + quadratic_cost_factor_of_vehicle_[vehicle]; + delta_vehicle_cost_ = + CapAdd(delta_vehicle_cost_, + CapProd(quadratic_cost_factor, + previous_route_length * previous_route_length)); + delta_vehicle_cost_ = CapSub( + delta_vehicle_cost_, + CapProd(quadratic_cost_factor, new_route_length * new_route_length)); + + return true; +} + +bool VehicleAmortizedCostFilter::FinalizeAcceptPath(const Assignment* delta, + int64_t objective_min, + int64_t objective_max) { + return delta_vehicle_cost_ <= objective_max; +} + +} // namespace + +IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter( + const RoutingModel& routing_model) { + return routing_model.solver()->RevAlloc( + new VehicleAmortizedCostFilter(routing_model)); +} + +namespace { + +class TypeRegulationsFilter : public BasePathFilter { + public: + explicit TypeRegulationsFilter(const RoutingModel& model); + ~TypeRegulationsFilter() override {} + std::string DebugString() const override { return "TypeRegulationsFilter"; } + + private: + void OnSynchronizePathFromStart(int64_t start) override; + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + + bool HardIncompatibilitiesRespected(int vehicle, int64_t chain_start, + int64_t chain_end); + + const RoutingModel& routing_model_; + std::vector start_to_vehicle_; + // The following vector is used to keep track of the type counts for hard + // incompatibilities. + std::vector> hard_incompatibility_type_counts_per_vehicle_; + // Used to verify the temporal incompatibilities and requirements. + TypeIncompatibilityChecker temporal_incompatibility_checker_; + TypeRequirementChecker requirement_checker_; +}; + +TypeRegulationsFilter::TypeRegulationsFilter(const RoutingModel& model) + : BasePathFilter(model.Nexts(), model.Size() + model.vehicles()), + routing_model_(model), + start_to_vehicle_(model.Size(), -1), + temporal_incompatibility_checker_(model, + /*check_hard_incompatibilities*/ false), + requirement_checker_(model) { + const int num_vehicles = model.vehicles(); + const bool has_hard_type_incompatibilities = + model.HasHardTypeIncompatibilities(); + if (has_hard_type_incompatibilities) { + hard_incompatibility_type_counts_per_vehicle_.resize(num_vehicles); + } + const int num_visit_types = model.GetNumberOfVisitTypes(); + for (int vehicle = 0; vehicle < num_vehicles; vehicle++) { + const int64_t start = model.Start(vehicle); + start_to_vehicle_[start] = vehicle; + if (has_hard_type_incompatibilities) { + hard_incompatibility_type_counts_per_vehicle_[vehicle].resize( + num_visit_types, 0); + } + } +} + +void TypeRegulationsFilter::OnSynchronizePathFromStart(int64_t start) { + if (!routing_model_.HasHardTypeIncompatibilities()) return; + + const int vehicle = start_to_vehicle_[start]; + CHECK_GE(vehicle, 0); + std::vector& type_counts = + hard_incompatibility_type_counts_per_vehicle_[vehicle]; + std::fill(type_counts.begin(), type_counts.end(), 0); + const int num_types = type_counts.size(); + + int64_t node = start; + while (node < Size()) { + DCHECK(IsVarSynced(node)); + const int type = routing_model_.GetVisitType(node); + if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != + RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { + CHECK_LT(type, num_types); + type_counts[type]++; + } + node = Value(node); + } +} + +bool TypeRegulationsFilter::HardIncompatibilitiesRespected(int vehicle, + int64_t chain_start, + int64_t chain_end) { + if (!routing_model_.HasHardTypeIncompatibilities()) return true; + + const std::vector& previous_type_counts = + hard_incompatibility_type_counts_per_vehicle_[vehicle]; + + absl::flat_hash_map new_type_counts; + absl::flat_hash_set types_to_check; + + // Go through the new nodes on the path and increment their type counts. + int64_t node = GetNext(chain_start); + while (node != chain_end) { + const int type = routing_model_.GetVisitType(node); + if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != + RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { + DCHECK_LT(type, previous_type_counts.size()); + int& type_count = gtl::LookupOrInsert(&new_type_counts, type, + previous_type_counts[type]); + if (type_count++ == 0) { + // New type on the route, mark to check its incompatibilities. + types_to_check.insert(type); + } + } + node = GetNext(node); + } + + // Update new_type_counts by decrementing the occurrence of the types of the + // nodes no longer on the route. + node = Value(chain_start); + while (node != chain_end) { + const int type = routing_model_.GetVisitType(node); + if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != + RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { + DCHECK_LT(type, previous_type_counts.size()); + int& type_count = gtl::LookupOrInsert(&new_type_counts, type, + previous_type_counts[type]); + CHECK_GE(type_count, 1); + type_count--; + } + node = Value(node); + } + + // Check the incompatibilities for types in types_to_check. + for (int type : types_to_check) { + for (int incompatible_type : + routing_model_.GetHardTypeIncompatibilitiesOfType(type)) { + if (gtl::FindWithDefault(new_type_counts, incompatible_type, + previous_type_counts[incompatible_type]) > 0) { + return false; + } + } + } + return true; +} + +bool TypeRegulationsFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { + const int vehicle = start_to_vehicle_[path_start]; + CHECK_GE(vehicle, 0); + const auto next_accessor = [this](int64_t node) { return GetNext(node); }; + return HardIncompatibilitiesRespected(vehicle, chain_start, chain_end) && + temporal_incompatibility_checker_.CheckVehicle(vehicle, + next_accessor) && + requirement_checker_.CheckVehicle(vehicle, next_accessor); +} + +} // namespace + +IntVarLocalSearchFilter* MakeTypeRegulationsFilter( + const RoutingModel& routing_model) { + return routing_model.solver()->RevAlloc( + new TypeRegulationsFilter(routing_model)); +} + +namespace { + +// ChainCumul filter. Version of dimension path filter which is O(delta) rather +// than O(length of touched paths). Currently only supports dimensions without +// costs (global and local span cost, soft bounds) and with unconstrained +// cumul variables except overall capacity and cumul variables of path ends. + +class ChainCumulFilter : public BasePathFilter { + public: + ChainCumulFilter(const RoutingModel& routing_model, + const RoutingDimension& dimension); + ~ChainCumulFilter() override {} + std::string DebugString() const override { + return "ChainCumulFilter(" + name_ + ")"; + } + + private: + void OnSynchronizePathFromStart(int64_t start) override; + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + + const std::vector cumuls_; + std::vector start_to_vehicle_; + std::vector start_to_end_; + std::vector evaluators_; + const std::vector vehicle_capacities_; + std::vector current_path_cumul_mins_; + std::vector current_max_of_path_end_cumul_mins_; + std::vector old_nexts_; + std::vector old_vehicles_; + std::vector current_transits_; + const std::string name_; +}; + +ChainCumulFilter::ChainCumulFilter(const RoutingModel& routing_model, + const RoutingDimension& dimension) + : BasePathFilter(routing_model.Nexts(), dimension.cumuls().size()), + cumuls_(dimension.cumuls()), + evaluators_(routing_model.vehicles(), nullptr), + vehicle_capacities_(dimension.vehicle_capacities()), + current_path_cumul_mins_(dimension.cumuls().size(), 0), + current_max_of_path_end_cumul_mins_(dimension.cumuls().size(), 0), + old_nexts_(routing_model.Size(), kUnassigned), + old_vehicles_(routing_model.Size(), kUnassigned), + current_transits_(routing_model.Size(), 0), + name_(dimension.name()) { + start_to_vehicle_.resize(Size(), -1); + start_to_end_.resize(Size(), -1); + for (int i = 0; i < routing_model.vehicles(); ++i) { + start_to_vehicle_[routing_model.Start(i)] = i; + start_to_end_[routing_model.Start(i)] = routing_model.End(i); + evaluators_[i] = &dimension.transit_evaluator(i); + } +} + +// On synchronization, maintain "propagated" cumul mins and max level of cumul +// from each node to the end of the path; to be used by AcceptPath to +// incrementally check feasibility. +void ChainCumulFilter::OnSynchronizePathFromStart(int64_t start) { + const int vehicle = start_to_vehicle_[start]; + std::vector path_nodes; + int64_t node = start; + int64_t cumul = cumuls_[node]->Min(); + while (node < Size()) { + path_nodes.push_back(node); + current_path_cumul_mins_[node] = cumul; + const int64_t next = Value(node); + if (next != old_nexts_[node] || vehicle != old_vehicles_[node]) { + old_nexts_[node] = next; + old_vehicles_[node] = vehicle; + current_transits_[node] = (*evaluators_[vehicle])(node, next); + } + cumul = CapAdd(cumul, current_transits_[node]); + cumul = std::max(cumuls_[next]->Min(), cumul); + node = next; + } + path_nodes.push_back(node); + current_path_cumul_mins_[node] = cumul; + int64_t max_cumuls = cumul; + for (int i = path_nodes.size() - 1; i >= 0; --i) { + const int64_t node = path_nodes[i]; + max_cumuls = std::max(max_cumuls, current_path_cumul_mins_[node]); + current_max_of_path_end_cumul_mins_[node] = max_cumuls; + } +} + +// The complexity of the method is O(size of chain (chain_start...chain_end). +bool ChainCumulFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { + const int vehicle = start_to_vehicle_[path_start]; + const int64_t capacity = vehicle_capacities_[vehicle]; + int64_t node = chain_start; + int64_t cumul = current_path_cumul_mins_[node]; + while (node != chain_end) { + const int64_t next = GetNext(node); + if (IsVarSynced(node) && next == Value(node) && + vehicle == old_vehicles_[node]) { + cumul = CapAdd(cumul, current_transits_[node]); + } else { + cumul = CapAdd(cumul, (*evaluators_[vehicle])(node, next)); + } + cumul = std::max(cumuls_[next]->Min(), cumul); + if (cumul > capacity) return false; + node = next; + } + const int64_t end = start_to_end_[path_start]; + const int64_t end_cumul_delta = + CapSub(current_path_cumul_mins_[end], current_path_cumul_mins_[node]); + const int64_t after_chain_cumul_delta = + CapSub(current_max_of_path_end_cumul_mins_[node], + current_path_cumul_mins_[node]); + return CapAdd(cumul, after_chain_cumul_delta) <= capacity && + CapAdd(cumul, end_cumul_delta) <= cumuls_[end]->Max(); +} + +// PathCumul filter. + +class PathCumulFilter : public BasePathFilter { + public: + PathCumulFilter(const RoutingModel& routing_model, + const RoutingDimension& dimension, + const RoutingSearchParameters& parameters, + bool propagate_own_objective_value, + bool filter_objective_cost, bool can_use_lp); + ~PathCumulFilter() override {} + std::string DebugString() const override { + return "PathCumulFilter(" + name_ + ")"; + } + int64_t GetSynchronizedObjectiveValue() const override { + return propagate_own_objective_value_ ? synchronized_objective_value_ : 0; + } + int64_t GetAcceptedObjectiveValue() const override { + return propagate_own_objective_value_ ? accepted_objective_value_ : 0; + } + + private: + // This structure stores the "best" path cumul value for a solution, the path + // supporting this value, and the corresponding path cumul values for all + // paths. + struct SupportedPathCumul { + SupportedPathCumul() : cumul_value(0), cumul_value_support(0) {} + int64_t cumul_value; + int cumul_value_support; + std::vector path_values; + }; + + struct SoftBound { + SoftBound() : bound(-1), coefficient(0) {} + int64_t bound; + int64_t coefficient; + }; + + // This class caches transit values between nodes of paths. Transit and path + // nodes are to be added in the order in which they appear on a path. + class PathTransits { + public: + void Clear() { + paths_.clear(); + transits_.clear(); + } + void ClearPath(int path) { + paths_[path].clear(); + transits_[path].clear(); + } + int AddPaths(int num_paths) { + const int first_path = paths_.size(); + paths_.resize(first_path + num_paths); + transits_.resize(first_path + num_paths); + return first_path; + } + void ReserveTransits(int path, int number_of_route_arcs) { + transits_[path].reserve(number_of_route_arcs); + paths_[path].reserve(number_of_route_arcs + 1); + } + // Stores the transit between node and next on path. For a given non-empty + // path, node must correspond to next in the previous call to PushTransit. + void PushTransit(int path, int node, int next, int64_t transit) { + transits_[path].push_back(transit); + if (paths_[path].empty()) { + paths_[path].push_back(node); + } + DCHECK_EQ(paths_[path].back(), node); + paths_[path].push_back(next); + } + int NumPaths() const { return paths_.size(); } + int PathSize(int path) const { return paths_[path].size(); } + int Node(int path, int position) const { return paths_[path][position]; } + int64_t Transit(int path, int position) const { + return transits_[path][position]; + } + + private: + // paths_[r][i] is the ith node on path r. + std::vector> paths_; + // transits_[r][i] is the transit value between nodes path_[i] and + // path_[i+1] on path r. + std::vector> transits_; + }; + + void InitializeAcceptPath() override { + cumul_cost_delta_ = total_current_cumul_cost_value_; + node_with_precedence_to_delta_min_max_cumuls_.clear(); + // Cleaning up for the new delta. + delta_max_end_cumul_ = std::numeric_limits::min(); + delta_paths_.clear(); + delta_path_transits_.Clear(); + lns_detected_ = false; + delta_nodes_with_precedences_and_changed_cumul_.ClearAll(); + } + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + bool FinalizeAcceptPath(const Assignment* delta, int64_t objective_min, + int64_t objective_max) override; + void OnBeforeSynchronizePaths() override; + + bool FilterSpanCost() const { return global_span_cost_coefficient_ != 0; } + + bool FilterSlackCost() const { + return has_nonzero_vehicle_span_cost_coefficients_ || + has_vehicle_span_upper_bounds_; + } + + bool FilterBreakCost(int vehicle) const { + return dimension_.HasBreakConstraints() && + !dimension_.GetBreakIntervalsOfVehicle(vehicle).empty(); + } + + bool FilterCumulSoftBounds() const { return !cumul_soft_bounds_.empty(); } + + int64_t GetCumulSoftCost(int64_t node, int64_t cumul_value) const; + + bool FilterCumulPiecewiseLinearCosts() const { + return !cumul_piecewise_linear_costs_.empty(); + } + + bool FilterWithDimensionCumulOptimizerForVehicle(int vehicle) const { + if (!can_use_lp_ || FilterCumulPiecewiseLinearCosts()) { + return false; + } + + int num_linear_constraints = 0; + if (dimension_.GetSpanCostCoefficientForVehicle(vehicle) > 0) + ++num_linear_constraints; + if (FilterSoftSpanCost(vehicle)) ++num_linear_constraints; + if (FilterCumulSoftLowerBounds()) ++num_linear_constraints; + if (FilterCumulSoftBounds()) ++num_linear_constraints; + if (vehicle_span_upper_bounds_[vehicle] < + std::numeric_limits::max()) + ++num_linear_constraints; + const bool has_breaks = FilterBreakCost(vehicle); + if (has_breaks) ++num_linear_constraints; + + // The DimensionCumulOptimizer is used to compute a more precise value of + // the cost related to the cumul values (soft bounds and span costs). + // It is also used to garantee feasibility with complex mixes of constraints + // and in particular in the presence of break requests along other + // constraints. + // Therefore, without breaks, we only use the optimizer when the costs are + // actually used to filter the solutions, i.e. when filter_objective_cost_ + // is true. + return num_linear_constraints >= 2 && + (has_breaks || filter_objective_cost_); + } + + bool FilterDimensionForbiddenIntervals() const { + for (const SortedDisjointIntervalList& intervals : + dimension_.forbidden_intervals()) { + // TODO(user): Change the following test to check intervals within + // the domain of the corresponding variables. + if (intervals.NumIntervals() > 0) { + return true; + } + } + return false; + } + + int64_t GetCumulPiecewiseLinearCost(int64_t node, int64_t cumul_value) const; + + bool FilterCumulSoftLowerBounds() const { + return !cumul_soft_lower_bounds_.empty(); + } + + bool FilterPrecedences() const { return !node_index_to_precedences_.empty(); } + + bool FilterSoftSpanCost() const { + return dimension_.HasSoftSpanUpperBounds(); + } + bool FilterSoftSpanCost(int vehicle) const { + return dimension_.HasSoftSpanUpperBounds() && + dimension_.GetSoftSpanUpperBoundForVehicle(vehicle).cost > 0; + } + bool FilterSoftSpanQuadraticCost() const { + return dimension_.HasQuadraticCostSoftSpanUpperBounds(); + } + bool FilterSoftSpanQuadraticCost(int vehicle) const { + return dimension_.HasQuadraticCostSoftSpanUpperBounds() && + dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle) + .cost > 0; + } + + int64_t GetCumulSoftLowerBoundCost(int64_t node, int64_t cumul_value) const; + + int64_t GetPathCumulSoftLowerBoundCost(const PathTransits& path_transits, + int path) const; + + void InitializeSupportedPathCumul(SupportedPathCumul* supported_cumul, + int64_t default_value); + + // Given the vector of minimum cumuls on the path, determines if the pickup to + // delivery limits for this dimension (if there are any) can be respected by + // this path. + // Returns true if for every pickup/delivery nodes visited on this path, + // min_cumul_value(delivery) - max_cumul_value(pickup) is less than the limit + // set for this pickup to delivery. + // TODO(user): Verify if we should filter the pickup/delivery limits using + // the LP, for a perfect filtering. + bool PickupToDeliveryLimitsRespected( + const PathTransits& path_transits, int path, + const std::vector& min_path_cumuls) const; + + // Computes the maximum cumul value of nodes along the path using + // [current|delta]_path_transits_, and stores the min/max cumul + // related to each node in the corresponding vector + // [current|delta]_[min|max]_node_cumuls_. + // The boolean is_delta indicates if the computations should take place on the + // "delta" or "current" members. When true, the nodes for which the min/max + // cumul has changed from the current value are marked in + // delta_nodes_with_precedences_and_changed_cumul_. + void StoreMinMaxCumulOfNodesOnPath( + int path, const std::vector& min_path_cumuls, bool is_delta); + + // Compute the max start cumul value for a given path and a given minimal end + // cumul value. + // NOTE: Since this function is used to compute a lower bound on the span of + // the routes, we don't "jump" over the forbidden intervals with this min end + // cumul value. We do however concurrently compute the max possible start + // given the max end cumul, for which we can "jump" over forbidden intervals, + // and return the minimum of the two. + int64_t ComputePathMaxStartFromEndCumul(const PathTransits& path_transits, + int path, int64_t path_start, + int64_t min_end_cumul) const; + + const RoutingModel& routing_model_; + const RoutingDimension& dimension_; + const std::vector cumuls_; + const std::vector slacks_; + std::vector start_to_vehicle_; + std::vector evaluators_; + std::vector vehicle_span_upper_bounds_; + bool has_vehicle_span_upper_bounds_; + int64_t total_current_cumul_cost_value_; + int64_t synchronized_objective_value_; + int64_t accepted_objective_value_; + // Map between paths and path soft cumul bound costs. The paths are indexed + // by the index of the start node of the path. + absl::flat_hash_map current_cumul_cost_values_; + int64_t cumul_cost_delta_; + // Cumul cost values for paths in delta, indexed by vehicle. + std::vector delta_path_cumul_cost_values_; + const int64_t global_span_cost_coefficient_; + std::vector cumul_soft_bounds_; + std::vector cumul_soft_lower_bounds_; + std::vector cumul_piecewise_linear_costs_; + std::vector vehicle_span_cost_coefficients_; + bool has_nonzero_vehicle_span_cost_coefficients_; + const std::vector vehicle_capacities_; + // node_index_to_precedences_[node_index] contains all NodePrecedence elements + // with node_index as either "first_node" or "second_node". + // This vector is empty if there are no precedences on the dimension_. + std::vector> + node_index_to_precedences_; + // Data reflecting information on paths and cumul variables for the solution + // to which the filter was synchronized. + SupportedPathCumul current_min_start_; + SupportedPathCumul current_max_end_; + PathTransits current_path_transits_; + // Current min/max cumul values, indexed by node. + std::vector> current_min_max_node_cumuls_; + // Data reflecting information on paths and cumul variables for the "delta" + // solution (aka neighbor solution) being examined. + PathTransits delta_path_transits_; + int64_t delta_max_end_cumul_; + SparseBitset delta_nodes_with_precedences_and_changed_cumul_; + absl::flat_hash_map> + node_with_precedence_to_delta_min_max_cumuls_; + // Note: small_ordered_set only support non-hash sets. + gtl::small_ordered_set> delta_paths_; + const std::string name_; + + LocalDimensionCumulOptimizer* optimizer_; + std::unique_ptr internal_optimizer_; + LocalDimensionCumulOptimizer* mp_optimizer_; + std::unique_ptr internal_mp_optimizer_; + const bool filter_objective_cost_; + // This boolean indicates if the LP optimizer can be used if necessary to + // optimize the dimension cumuls, and is only used for testing purposes. + const bool can_use_lp_; + const bool propagate_own_objective_value_; + + // Used to do span lower bounding in presence of vehicle breaks. + DisjunctivePropagator disjunctive_propagator_; + DisjunctivePropagator::Tasks tasks_; + TravelBounds travel_bounds_; + std::vector current_path_; + + bool lns_detected_; +}; + +PathCumulFilter::PathCumulFilter(const RoutingModel& routing_model, + const RoutingDimension& dimension, + const RoutingSearchParameters& parameters, + bool propagate_own_objective_value, + bool filter_objective_cost, bool can_use_lp) + : BasePathFilter(routing_model.Nexts(), dimension.cumuls().size()), + routing_model_(routing_model), + dimension_(dimension), + cumuls_(dimension.cumuls()), + slacks_(dimension.slacks()), + evaluators_(routing_model.vehicles(), nullptr), + vehicle_span_upper_bounds_(dimension.vehicle_span_upper_bounds()), + has_vehicle_span_upper_bounds_(false), + total_current_cumul_cost_value_(0), + synchronized_objective_value_(0), + accepted_objective_value_(0), + current_cumul_cost_values_(), + cumul_cost_delta_(0), + delta_path_cumul_cost_values_(routing_model.vehicles(), + std::numeric_limits::min()), + global_span_cost_coefficient_(dimension.global_span_cost_coefficient()), + vehicle_span_cost_coefficients_( + dimension.vehicle_span_cost_coefficients()), + has_nonzero_vehicle_span_cost_coefficients_(false), + vehicle_capacities_(dimension.vehicle_capacities()), + delta_max_end_cumul_(0), + delta_nodes_with_precedences_and_changed_cumul_(routing_model.Size()), + name_(dimension.name()), + optimizer_(routing_model.GetMutableLocalCumulOptimizer(dimension)), + mp_optimizer_(routing_model.GetMutableLocalCumulMPOptimizer(dimension)), + filter_objective_cost_(filter_objective_cost), + can_use_lp_(can_use_lp), + propagate_own_objective_value_(propagate_own_objective_value), + lns_detected_(false) { + for (const int64_t upper_bound : vehicle_span_upper_bounds_) { + if (upper_bound != std::numeric_limits::max()) { + has_vehicle_span_upper_bounds_ = true; + break; + } + } + for (const int64_t coefficient : vehicle_span_cost_coefficients_) { + if (coefficient != 0) { + has_nonzero_vehicle_span_cost_coefficients_ = true; + break; + } + } + cumul_soft_bounds_.resize(cumuls_.size()); + cumul_soft_lower_bounds_.resize(cumuls_.size()); + cumul_piecewise_linear_costs_.resize(cumuls_.size()); + bool has_cumul_soft_bounds = false; + bool has_cumul_soft_lower_bounds = false; + bool has_cumul_piecewise_linear_costs = false; + bool has_cumul_hard_bounds = false; + for (const IntVar* const slack : slacks_) { + if (slack->Min() > 0) { + has_cumul_hard_bounds = true; + break; + } + } + for (int i = 0; i < cumuls_.size(); ++i) { + if (dimension.HasCumulVarSoftUpperBound(i)) { + has_cumul_soft_bounds = true; + cumul_soft_bounds_[i].bound = dimension.GetCumulVarSoftUpperBound(i); + cumul_soft_bounds_[i].coefficient = + dimension.GetCumulVarSoftUpperBoundCoefficient(i); + } + if (dimension.HasCumulVarSoftLowerBound(i)) { + has_cumul_soft_lower_bounds = true; + cumul_soft_lower_bounds_[i].bound = + dimension.GetCumulVarSoftLowerBound(i); + cumul_soft_lower_bounds_[i].coefficient = + dimension.GetCumulVarSoftLowerBoundCoefficient(i); + } + if (dimension.HasCumulVarPiecewiseLinearCost(i)) { + has_cumul_piecewise_linear_costs = true; + cumul_piecewise_linear_costs_[i] = + dimension.GetCumulVarPiecewiseLinearCost(i); + } + IntVar* const cumul_var = cumuls_[i]; + if (cumul_var->Min() > 0 || + cumul_var->Max() < std::numeric_limits::max()) { + has_cumul_hard_bounds = true; + } + } + if (!has_cumul_soft_bounds) { + cumul_soft_bounds_.clear(); + } + if (!has_cumul_soft_lower_bounds) { + cumul_soft_lower_bounds_.clear(); + } + if (!has_cumul_piecewise_linear_costs) { + cumul_piecewise_linear_costs_.clear(); + } + if (!has_cumul_hard_bounds) { + // Slacks don't need to be constrained if the cumuls don't have hard bounds; + // therefore we can ignore the vehicle span cost coefficient (note that the + // transit part is already handled by the arc cost filters). + // This doesn't concern the global span filter though. + vehicle_span_cost_coefficients_.assign(routing_model.vehicles(), 0); + has_nonzero_vehicle_span_cost_coefficients_ = false; + } + start_to_vehicle_.resize(Size(), -1); + for (int i = 0; i < routing_model.vehicles(); ++i) { + start_to_vehicle_[routing_model.Start(i)] = i; + evaluators_[i] = &dimension.transit_evaluator(i); + } + + const std::vector& node_precedences = + dimension.GetNodePrecedences(); + if (!node_precedences.empty()) { + current_min_max_node_cumuls_.resize(cumuls_.size(), {-1, -1}); + node_index_to_precedences_.resize(cumuls_.size()); + for (const auto& node_precedence : node_precedences) { + node_index_to_precedences_[node_precedence.first_node].push_back( + node_precedence); + node_index_to_precedences_[node_precedence.second_node].push_back( + node_precedence); + } + } + // NOTE(user): The model's local optimizer for this dimension could be + // null because the finalizer is using a global optimizer, so we create a + // separate optimizer for the PathCumulFilter if we need it. + if (can_use_lp_ && optimizer_ == nullptr) { + DCHECK(mp_optimizer_ == nullptr); + for (int vehicle = 0; vehicle < routing_model.vehicles(); vehicle++) { + if (!FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { + continue; + } + if (optimizer_ == nullptr) { + // NOTE: The optimizer_ might have already been set in the for loop, + // since we continue scanning vehicles in case one of them needs the + // the mp_optimizer_ for break constraints. + internal_optimizer_ = absl::make_unique( + &dimension, parameters.continuous_scheduling_solver()); + optimizer_ = internal_optimizer_.get(); + } + if (FilterBreakCost(vehicle) || FilterDimensionForbiddenIntervals()) { + internal_mp_optimizer_ = + absl::make_unique( + &dimension, parameters.mixed_integer_scheduling_solver()); + mp_optimizer_ = internal_mp_optimizer_.get(); + break; + } + } + } +} + +int64_t PathCumulFilter::GetCumulSoftCost(int64_t node, + int64_t cumul_value) const { + if (node < cumul_soft_bounds_.size()) { + const int64_t bound = cumul_soft_bounds_[node].bound; + const int64_t coefficient = cumul_soft_bounds_[node].coefficient; + if (coefficient > 0 && bound < cumul_value) { + return CapProd(CapSub(cumul_value, bound), coefficient); + } + } + return 0; +} + +int64_t PathCumulFilter::GetCumulPiecewiseLinearCost( + int64_t node, int64_t cumul_value) const { + if (node < cumul_piecewise_linear_costs_.size()) { + const PiecewiseLinearFunction* cost = cumul_piecewise_linear_costs_[node]; + if (cost != nullptr) { + return cost->Value(cumul_value); + } + } + return 0; +} + +int64_t PathCumulFilter::GetCumulSoftLowerBoundCost(int64_t node, + int64_t cumul_value) const { + if (node < cumul_soft_lower_bounds_.size()) { + const int64_t bound = cumul_soft_lower_bounds_[node].bound; + const int64_t coefficient = cumul_soft_lower_bounds_[node].coefficient; + if (coefficient > 0 && bound > cumul_value) { + return CapProd(CapSub(bound, cumul_value), coefficient); + } + } + return 0; +} + +int64_t PathCumulFilter::GetPathCumulSoftLowerBoundCost( + const PathTransits& path_transits, int path) const { + int64_t node = path_transits.Node(path, path_transits.PathSize(path) - 1); + int64_t cumul = cumuls_[node]->Max(); + int64_t current_cumul_cost_value = GetCumulSoftLowerBoundCost(node, cumul); + for (int i = path_transits.PathSize(path) - 2; i >= 0; --i) { + node = path_transits.Node(path, i); + cumul = CapSub(cumul, path_transits.Transit(path, i)); + cumul = std::min(cumuls_[node]->Max(), cumul); + current_cumul_cost_value = CapAdd(current_cumul_cost_value, + GetCumulSoftLowerBoundCost(node, cumul)); + } + return current_cumul_cost_value; +} + +void PathCumulFilter::OnBeforeSynchronizePaths() { + total_current_cumul_cost_value_ = 0; + cumul_cost_delta_ = 0; + current_cumul_cost_values_.clear(); + if (NumPaths() > 0 && + (FilterSpanCost() || FilterCumulSoftBounds() || FilterSlackCost() || + FilterCumulSoftLowerBounds() || FilterCumulPiecewiseLinearCosts() || + FilterPrecedences() || FilterSoftSpanCost() || + FilterSoftSpanQuadraticCost())) { + InitializeSupportedPathCumul(¤t_min_start_, + std::numeric_limits::max()); + InitializeSupportedPathCumul(¤t_max_end_, + std::numeric_limits::min()); + current_path_transits_.Clear(); + current_path_transits_.AddPaths(NumPaths()); + // For each path, compute the minimum end cumul and store the max of these. + for (int r = 0; r < NumPaths(); ++r) { + int64_t node = Start(r); + const int vehicle = start_to_vehicle_[Start(r)]; + // First pass: evaluating route length to reserve memory to store route + // information. + int number_of_route_arcs = 0; + while (node < Size()) { + ++number_of_route_arcs; + node = Value(node); + } + current_path_transits_.ReserveTransits(r, number_of_route_arcs); + // Second pass: update cumul, transit and cost values. + node = Start(r); + int64_t cumul = cumuls_[node]->Min(); + std::vector min_path_cumuls; + min_path_cumuls.reserve(number_of_route_arcs + 1); + min_path_cumuls.push_back(cumul); + + int64_t current_cumul_cost_value = GetCumulSoftCost(node, cumul); + current_cumul_cost_value = CapAdd( + current_cumul_cost_value, GetCumulPiecewiseLinearCost(node, cumul)); + + int64_t total_transit = 0; + while (node < Size()) { + const int64_t next = Value(node); + const int64_t transit = (*evaluators_[vehicle])(node, next); + total_transit = CapAdd(total_transit, transit); + const int64_t transit_slack = CapAdd(transit, slacks_[node]->Min()); + current_path_transits_.PushTransit(r, node, next, transit_slack); + cumul = CapAdd(cumul, transit_slack); + cumul = + dimension_.GetFirstPossibleGreaterOrEqualValueForNode(next, cumul); + cumul = std::max(cumuls_[next]->Min(), cumul); + min_path_cumuls.push_back(cumul); + node = next; + current_cumul_cost_value = + CapAdd(current_cumul_cost_value, GetCumulSoftCost(node, cumul)); + current_cumul_cost_value = CapAdd( + current_cumul_cost_value, GetCumulPiecewiseLinearCost(node, cumul)); + } + if (FilterPrecedences()) { + StoreMinMaxCumulOfNodesOnPath(/*path=*/r, min_path_cumuls, + /*is_delta=*/false); + } + if (number_of_route_arcs == 1 && + !routing_model_.AreEmptyRouteCostsConsideredForVehicle(vehicle)) { + // This is an empty route (single start->end arc) which we don't take + // into account for costs. + current_cumul_cost_values_[Start(r)] = 0; + current_path_transits_.ClearPath(r); + continue; + } + if (FilterSlackCost() || FilterSoftSpanCost() || + FilterSoftSpanQuadraticCost()) { + const int64_t start = ComputePathMaxStartFromEndCumul( + current_path_transits_, r, Start(r), cumul); + const int64_t span_lower_bound = CapSub(cumul, start); + if (FilterSlackCost()) { + current_cumul_cost_value = + CapAdd(current_cumul_cost_value, + CapProd(vehicle_span_cost_coefficients_[vehicle], + CapSub(span_lower_bound, total_transit))); + } + if (FilterSoftSpanCost()) { + const SimpleBoundCosts::BoundCost bound_cost = + dimension_.GetSoftSpanUpperBoundForVehicle(vehicle); + if (bound_cost.bound < span_lower_bound) { + const int64_t violation = + CapSub(span_lower_bound, bound_cost.bound); + current_cumul_cost_value = CapAdd( + current_cumul_cost_value, CapProd(bound_cost.cost, violation)); + } + } + if (FilterSoftSpanQuadraticCost()) { + const SimpleBoundCosts::BoundCost bound_cost = + dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle); + if (bound_cost.bound < span_lower_bound) { + const int64_t violation = + CapSub(span_lower_bound, bound_cost.bound); + current_cumul_cost_value = + CapAdd(current_cumul_cost_value, + CapProd(bound_cost.cost, CapProd(violation, violation))); + } + } + } + if (FilterCumulSoftLowerBounds()) { + current_cumul_cost_value = + CapAdd(current_cumul_cost_value, + GetPathCumulSoftLowerBoundCost(current_path_transits_, r)); + } + if (FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { + // TODO(user): Return a status from the optimizer to detect failures + // The only admissible failures here are because of LP timeout. + int64_t lp_cumul_cost_value = 0; + LocalDimensionCumulOptimizer* const optimizer = + FilterBreakCost(vehicle) ? mp_optimizer_ : optimizer_; + DCHECK(optimizer != nullptr); + const DimensionSchedulingStatus status = + optimizer->ComputeRouteCumulCostWithoutFixedTransits( + vehicle, [this](int64_t node) { return Value(node); }, + &lp_cumul_cost_value); + switch (status) { + case DimensionSchedulingStatus::INFEASIBLE: + lp_cumul_cost_value = 0; + break; + 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) == + DimensionSchedulingStatus::INFEASIBLE) { + lp_cumul_cost_value = 0; + } + break; + default: + DCHECK(status == DimensionSchedulingStatus::OPTIMAL); + } + current_cumul_cost_value = + std::max(current_cumul_cost_value, lp_cumul_cost_value); + } + current_cumul_cost_values_[Start(r)] = current_cumul_cost_value; + current_max_end_.path_values[r] = cumul; + if (current_max_end_.cumul_value < cumul) { + current_max_end_.cumul_value = cumul; + current_max_end_.cumul_value_support = r; + } + total_current_cumul_cost_value_ = + CapAdd(total_current_cumul_cost_value_, current_cumul_cost_value); + } + if (FilterPrecedences()) { + // Update the min/max node cumuls of new unperformed nodes. + for (int64_t node : GetNewSynchronizedUnperformedNodes()) { + current_min_max_node_cumuls_[node] = {-1, -1}; + } + } + // Use the max of the path end cumul mins to compute the corresponding + // maximum start cumul of each path; store the minimum of these. + for (int r = 0; r < NumPaths(); ++r) { + const int64_t start = ComputePathMaxStartFromEndCumul( + current_path_transits_, r, Start(r), current_max_end_.cumul_value); + current_min_start_.path_values[r] = start; + if (current_min_start_.cumul_value > start) { + current_min_start_.cumul_value = start; + current_min_start_.cumul_value_support = r; + } + } + } + // Initialize this before considering any deltas (neighbor). + delta_max_end_cumul_ = std::numeric_limits::min(); + lns_detected_ = false; + + DCHECK_GE(current_max_end_.cumul_value, current_min_start_.cumul_value); + synchronized_objective_value_ = + CapAdd(total_current_cumul_cost_value_, + CapProd(global_span_cost_coefficient_, + CapSub(current_max_end_.cumul_value, + current_min_start_.cumul_value))); +} + +bool PathCumulFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { + int64_t node = path_start; + int64_t cumul = cumuls_[node]->Min(); + int64_t cumul_cost_delta = 0; + int64_t total_transit = 0; + const int path = delta_path_transits_.AddPaths(1); + const int vehicle = start_to_vehicle_[path_start]; + const int64_t capacity = vehicle_capacities_[vehicle]; + const bool filter_vehicle_costs = + !routing_model_.IsEnd(GetNext(node)) || + routing_model_.AreEmptyRouteCostsConsideredForVehicle(vehicle); + if (filter_vehicle_costs) { + cumul_cost_delta = CapAdd(GetCumulSoftCost(node, cumul), + GetCumulPiecewiseLinearCost(node, cumul)); + } + // Evaluating route length to reserve memory to store transit information. + int number_of_route_arcs = 0; + while (node < Size()) { + const int64_t next = GetNext(node); + // TODO(user): This shouldn't be needed anymore as such deltas should + // have been filtered already. + if (next == kUnassigned) { + // LNS detected, return true since other paths were ok up to now. + lns_detected_ = true; + return true; + } + ++number_of_route_arcs; + node = next; + } + delta_path_transits_.ReserveTransits(path, number_of_route_arcs); + std::vector min_path_cumuls; + min_path_cumuls.reserve(number_of_route_arcs + 1); + min_path_cumuls.push_back(cumul); + // Check that the path is feasible with regards to cumul bounds, scanning + // the paths from start to end (caching path node sequences and transits + // for further span cost filtering). + node = path_start; + while (node < Size()) { + const int64_t next = GetNext(node); + const int64_t transit = (*evaluators_[vehicle])(node, next); + total_transit = CapAdd(total_transit, transit); + const int64_t transit_slack = CapAdd(transit, slacks_[node]->Min()); + delta_path_transits_.PushTransit(path, node, next, transit_slack); + cumul = CapAdd(cumul, transit_slack); + cumul = dimension_.GetFirstPossibleGreaterOrEqualValueForNode(next, cumul); + if (cumul > std::min(capacity, cumuls_[next]->Max())) { + return false; + } + cumul = std::max(cumuls_[next]->Min(), cumul); + min_path_cumuls.push_back(cumul); + node = next; + if (filter_vehicle_costs) { + cumul_cost_delta = + CapAdd(cumul_cost_delta, GetCumulSoftCost(node, cumul)); + cumul_cost_delta = + CapAdd(cumul_cost_delta, GetCumulPiecewiseLinearCost(node, cumul)); + } + } + const int64_t min_end = cumul; + + if (!PickupToDeliveryLimitsRespected(delta_path_transits_, path, + min_path_cumuls)) { + return false; + } + if (FilterSlackCost() || FilterBreakCost(vehicle) || + FilterSoftSpanCost(vehicle) || FilterSoftSpanQuadraticCost(vehicle)) { + int64_t slack_max = std::numeric_limits::max(); + if (vehicle_span_upper_bounds_[vehicle] < + std::numeric_limits::max()) { + const int64_t span_max = vehicle_span_upper_bounds_[vehicle]; + slack_max = std::min(slack_max, CapSub(span_max, total_transit)); + } + const int64_t max_start_from_min_end = ComputePathMaxStartFromEndCumul( + delta_path_transits_, path, path_start, min_end); + const int64_t span_lb = CapSub(min_end, max_start_from_min_end); + int64_t min_total_slack = CapSub(span_lb, total_transit); + if (min_total_slack > slack_max) return false; + + if (dimension_.HasBreakConstraints()) { + for (const auto [limit, min_break_duration] : + dimension_.GetBreakDistanceDurationOfVehicle(vehicle)) { + // Minimal number of breaks depends on total transit: + // 0 breaks for 0 <= total transit <= limit, + // 1 break for limit + 1 <= total transit <= 2 * limit, + // i breaks for i * limit + 1 <= total transit <= (i+1) * limit, ... + if (limit == 0 || total_transit == 0) continue; + const int num_breaks_lb = (total_transit - 1) / limit; + const int64_t slack_lb = CapProd(num_breaks_lb, min_break_duration); + if (slack_lb > slack_max) return false; + min_total_slack = std::max(min_total_slack, slack_lb); + } + // Compute a lower bound of the amount of break that must be made inside + // the route. We compute a mandatory interval (might be empty) + // [max_start, min_end[ during which the route will have to happen, + // then the duration of break that must happen during this interval. + int64_t min_total_break = 0; + int64_t max_path_end = cumuls_[routing_model_.End(vehicle)]->Max(); + const int64_t max_start = ComputePathMaxStartFromEndCumul( + delta_path_transits_, path, path_start, max_path_end); + for (const IntervalVar* br : + dimension_.GetBreakIntervalsOfVehicle(vehicle)) { + if (!br->MustBePerformed()) continue; + if (max_start < br->EndMin() && br->StartMax() < min_end) { + min_total_break = CapAdd(min_total_break, br->DurationMin()); + } + } + if (min_total_break > slack_max) return false; + min_total_slack = std::max(min_total_slack, min_total_break); + } + if (filter_vehicle_costs) { + cumul_cost_delta = CapAdd( + cumul_cost_delta, + CapProd(vehicle_span_cost_coefficients_[vehicle], min_total_slack)); + const int64_t span_lower_bound = CapAdd(total_transit, min_total_slack); + if (FilterSoftSpanCost()) { + const SimpleBoundCosts::BoundCost bound_cost = + dimension_.GetSoftSpanUpperBoundForVehicle(vehicle); + if (bound_cost.bound < span_lower_bound) { + const int64_t violation = CapSub(span_lower_bound, bound_cost.bound); + cumul_cost_delta = + CapAdd(cumul_cost_delta, CapProd(bound_cost.cost, violation)); + } + } + if (FilterSoftSpanQuadraticCost()) { + const SimpleBoundCosts::BoundCost bound_cost = + dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle); + if (bound_cost.bound < span_lower_bound) { + const int64_t violation = CapSub(span_lower_bound, bound_cost.bound); + cumul_cost_delta = + CapAdd(cumul_cost_delta, + CapProd(bound_cost.cost, CapProd(violation, violation))); + } + } + } + if (CapAdd(total_transit, min_total_slack) > + vehicle_span_upper_bounds_[vehicle]) { + return false; + } + } + if (FilterCumulSoftLowerBounds() && filter_vehicle_costs) { + cumul_cost_delta = + CapAdd(cumul_cost_delta, + GetPathCumulSoftLowerBoundCost(delta_path_transits_, path)); + } + if (FilterPrecedences()) { + StoreMinMaxCumulOfNodesOnPath(path, min_path_cumuls, /*is_delta=*/true); + } + if (!filter_vehicle_costs) { + // If this route's costs should't be taken into account, reset the + // cumul_cost_delta and delta_path_transits_ for this path. + cumul_cost_delta = 0; + delta_path_transits_.ClearPath(path); + } + if (FilterSpanCost() || FilterCumulSoftBounds() || FilterSlackCost() || + FilterCumulSoftLowerBounds() || FilterCumulPiecewiseLinearCosts() || + FilterSoftSpanCost(vehicle) || FilterSoftSpanQuadraticCost(vehicle)) { + delta_paths_.insert(GetPath(path_start)); + delta_path_cumul_cost_values_[vehicle] = cumul_cost_delta; + cumul_cost_delta = + CapSub(cumul_cost_delta, current_cumul_cost_values_[path_start]); + if (filter_vehicle_costs) { + delta_max_end_cumul_ = std::max(delta_max_end_cumul_, min_end); + } + } + cumul_cost_delta_ = CapAdd(cumul_cost_delta_, cumul_cost_delta); + return true; +} + +bool PathCumulFilter::FinalizeAcceptPath(const Assignment* delta, + int64_t objective_min, + int64_t objective_max) { + if ((!FilterSpanCost() && !FilterCumulSoftBounds() && !FilterSlackCost() && + !FilterCumulSoftLowerBounds() && !FilterCumulPiecewiseLinearCosts() && + !FilterPrecedences() && !FilterSoftSpanCost() && + !FilterSoftSpanQuadraticCost()) || + lns_detected_) { + return true; + } + if (FilterPrecedences()) { + for (int64_t node : delta_nodes_with_precedences_and_changed_cumul_ + .PositionsSetAtLeastOnce()) { + const std::pair node_min_max_cumul_in_delta = + gtl::FindWithDefault(node_with_precedence_to_delta_min_max_cumuls_, + node, {-1, -1}); + // NOTE: This node was seen in delta, so its delta min/max cumul should be + // stored in the map. + DCHECK(node_min_max_cumul_in_delta.first >= 0 && + node_min_max_cumul_in_delta.second >= 0); + for (const RoutingDimension::NodePrecedence& precedence : + node_index_to_precedences_[node]) { + const bool node_is_first = (precedence.first_node == node); + const int64_t other_node = + node_is_first ? precedence.second_node : precedence.first_node; + if (GetNext(other_node) == kUnassigned || + GetNext(other_node) == other_node) { + // The other node is unperformed, so the precedence constraint is + // inactive. + continue; + } + // max_cumul[second_node] should be greater or equal than + // min_cumul[first_node] + offset. + const std::pair& other_min_max_cumul_in_delta = + gtl::FindWithDefault(node_with_precedence_to_delta_min_max_cumuls_, + other_node, + current_min_max_node_cumuls_[other_node]); + + const int64_t first_min_cumul = + node_is_first ? node_min_max_cumul_in_delta.first + : other_min_max_cumul_in_delta.first; + const int64_t second_max_cumul = + node_is_first ? other_min_max_cumul_in_delta.second + : node_min_max_cumul_in_delta.second; + + if (second_max_cumul < first_min_cumul + precedence.offset) { + return false; + } + } + } + } + int64_t new_max_end = delta_max_end_cumul_; + int64_t new_min_start = std::numeric_limits::max(); + if (FilterSpanCost()) { + if (new_max_end < current_max_end_.cumul_value) { + // Delta max end is lower than the current solution one. + // If the path supporting the current max end has been modified, we need + // to check all paths to find the largest max end. + if (!gtl::ContainsKey(delta_paths_, + current_max_end_.cumul_value_support)) { + new_max_end = current_max_end_.cumul_value; + } else { + for (int i = 0; i < current_max_end_.path_values.size(); ++i) { + if (current_max_end_.path_values[i] > new_max_end && + !gtl::ContainsKey(delta_paths_, i)) { + new_max_end = current_max_end_.path_values[i]; + } + } + } + } + // Now that the max end cumul has been found, compute the corresponding + // min start cumul, first from the delta, then if the max end cumul has + // changed, from the unchanged paths as well. + for (int r = 0; r < delta_path_transits_.NumPaths(); ++r) { + new_min_start = + std::min(ComputePathMaxStartFromEndCumul(delta_path_transits_, r, + Start(r), new_max_end), + new_min_start); + } + if (new_max_end != current_max_end_.cumul_value) { + for (int r = 0; r < NumPaths(); ++r) { + if (gtl::ContainsKey(delta_paths_, r)) { + continue; + } + new_min_start = std::min(new_min_start, ComputePathMaxStartFromEndCumul( + current_path_transits_, r, + Start(r), new_max_end)); + } + } else if (new_min_start > current_min_start_.cumul_value) { + // Delta min start is greater than the current solution one. + // If the path supporting the current min start has been modified, we need + // to check all paths to find the smallest min start. + if (!gtl::ContainsKey(delta_paths_, + current_min_start_.cumul_value_support)) { + new_min_start = current_min_start_.cumul_value; + } else { + for (int i = 0; i < current_min_start_.path_values.size(); ++i) { + if (current_min_start_.path_values[i] < new_min_start && + !gtl::ContainsKey(delta_paths_, i)) { + new_min_start = current_min_start_.path_values[i]; + } + } + } + } + } + + // Filtering on objective value, calling LPs and MIPs if needed.. + accepted_objective_value_ = + CapAdd(cumul_cost_delta_, CapProd(global_span_cost_coefficient_, + CapSub(new_max_end, new_min_start))); + + if (can_use_lp_ && optimizer_ != nullptr && + accepted_objective_value_ <= objective_max) { + const size_t num_touched_paths = GetTouchedPathStarts().size(); + std::vector path_delta_cost_values(num_touched_paths, 0); + std::vector requires_mp(num_touched_paths, false); + for (int i = 0; i < num_touched_paths; ++i) { + const int64_t start = GetTouchedPathStarts()[i]; + const int vehicle = start_to_vehicle_[start]; + if (!FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { + continue; + } + 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); + if (status == DimensionSchedulingStatus::INFEASIBLE) { + return false; + } + DCHECK(gtl::ContainsKey(delta_paths_, GetPath(start))); + const int64_t path_cost_diff_with_lp = CapSub( + path_delta_cost_with_lp, delta_path_cumul_cost_values_[vehicle]); + if (path_cost_diff_with_lp > 0) { + path_delta_cost_values[i] = path_delta_cost_with_lp; + accepted_objective_value_ = + CapAdd(accepted_objective_value_, path_cost_diff_with_lp); + if (accepted_objective_value_ > objective_max) { + return false; + } + } else { + path_delta_cost_values[i] = delta_path_cumul_cost_values_[vehicle]; + } + if (mp_optimizer_ != nullptr) { + requires_mp[i] = + FilterBreakCost(vehicle) || + (status == DimensionSchedulingStatus::RELAXED_OPTIMAL_ONLY); + } + } + if (mp_optimizer_ == nullptr) { + return accepted_objective_value_ <= objective_max; + } + for (int i = 0; i < num_touched_paths; ++i) { + if (!requires_mp[i]) { + continue; + } + const int64_t start = GetTouchedPathStarts()[i]; + 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) == + DimensionSchedulingStatus::INFEASIBLE) { + return false; + } + DCHECK(gtl::ContainsKey(delta_paths_, GetPath(start))); + const int64_t path_cost_diff_with_mp = + CapSub(path_delta_cost_with_mp, path_delta_cost_values[i]); + if (path_cost_diff_with_mp > 0) { + accepted_objective_value_ = + CapAdd(accepted_objective_value_, path_cost_diff_with_mp); + if (accepted_objective_value_ > objective_max) { + return false; + } + } + } + } + + return accepted_objective_value_ <= objective_max; +} + +void PathCumulFilter::InitializeSupportedPathCumul( + SupportedPathCumul* supported_cumul, int64_t default_value) { + supported_cumul->cumul_value = default_value; + supported_cumul->cumul_value_support = -1; + supported_cumul->path_values.resize(NumPaths(), default_value); +} + +bool PathCumulFilter::PickupToDeliveryLimitsRespected( + const PathTransits& path_transits, int path, + const std::vector& min_path_cumuls) const { + if (!dimension_.HasPickupToDeliveryLimits()) { + return true; + } + const int num_pairs = routing_model_.GetPickupAndDeliveryPairs().size(); + DCHECK_GT(num_pairs, 0); + std::vector> visited_delivery_and_min_cumul_per_pair( + num_pairs, {-1, -1}); + + const int path_size = path_transits.PathSize(path); + CHECK_EQ(min_path_cumuls.size(), path_size); + + int64_t max_cumul = min_path_cumuls.back(); + for (int i = path_transits.PathSize(path) - 2; i >= 0; i--) { + const int node_index = path_transits.Node(path, i); + max_cumul = CapSub(max_cumul, path_transits.Transit(path, i)); + max_cumul = std::min(cumuls_[node_index]->Max(), max_cumul); + + const std::vector>& pickup_index_pairs = + routing_model_.GetPickupIndexPairs(node_index); + const std::vector>& delivery_index_pairs = + routing_model_.GetDeliveryIndexPairs(node_index); + if (!pickup_index_pairs.empty()) { + // The node is a pickup. Check that it is not a delivery and that it + // appears in a single pickup/delivery pair (as required when limits are + // set on dimension cumuls for pickup and deliveries). + DCHECK(delivery_index_pairs.empty()); + DCHECK_EQ(pickup_index_pairs.size(), 1); + const int pair_index = pickup_index_pairs[0].first; + // Get the delivery visited for this pair. + const int delivery_index = + visited_delivery_and_min_cumul_per_pair[pair_index].first; + if (delivery_index < 0) { + // No delivery visited after this pickup for this pickup/delivery pair. + continue; + } + const int64_t cumul_diff_limit = + dimension_.GetPickupToDeliveryLimitForPair( + pair_index, pickup_index_pairs[0].second, delivery_index); + if (CapSub(visited_delivery_and_min_cumul_per_pair[pair_index].second, + max_cumul) > cumul_diff_limit) { + return false; + } + } + if (!delivery_index_pairs.empty()) { + // The node is a delivery. Check that it's not a pickup and it belongs to + // a single pair. + DCHECK(pickup_index_pairs.empty()); + DCHECK_EQ(delivery_index_pairs.size(), 1); + const int pair_index = delivery_index_pairs[0].first; + std::pair& delivery_index_and_cumul = + visited_delivery_and_min_cumul_per_pair[pair_index]; + int& delivery_index = delivery_index_and_cumul.first; + DCHECK_EQ(delivery_index, -1); + delivery_index = delivery_index_pairs[0].second; + delivery_index_and_cumul.second = min_path_cumuls[i]; + } + } + return true; +} + +void PathCumulFilter::StoreMinMaxCumulOfNodesOnPath( + int path, const std::vector& min_path_cumuls, bool is_delta) { + const PathTransits& path_transits = + is_delta ? delta_path_transits_ : current_path_transits_; + + const int path_size = path_transits.PathSize(path); + DCHECK_EQ(min_path_cumuls.size(), path_size); + + int64_t max_cumul = cumuls_[path_transits.Node(path, path_size - 1)]->Max(); + for (int i = path_size - 1; i >= 0; i--) { + const int node_index = path_transits.Node(path, i); + + if (i < path_size - 1) { + max_cumul = CapSub(max_cumul, path_transits.Transit(path, i)); + max_cumul = std::min(cumuls_[node_index]->Max(), max_cumul); + } + + if (is_delta && node_index_to_precedences_[node_index].empty()) { + // No need to update the delta cumul map for nodes without precedences. + continue; + } + + std::pair& min_max_cumuls = + is_delta ? node_with_precedence_to_delta_min_max_cumuls_[node_index] + : current_min_max_node_cumuls_[node_index]; + min_max_cumuls.first = min_path_cumuls[i]; + min_max_cumuls.second = max_cumul; + + if (is_delta && !routing_model_.IsEnd(node_index) && + (min_max_cumuls.first != + current_min_max_node_cumuls_[node_index].first || + max_cumul != current_min_max_node_cumuls_[node_index].second)) { + delta_nodes_with_precedences_and_changed_cumul_.Set(node_index); + } + } +} + +int64_t PathCumulFilter::ComputePathMaxStartFromEndCumul( + const PathTransits& path_transits, int path, int64_t path_start, + int64_t min_end_cumul) const { + int64_t cumul_from_min_end = min_end_cumul; + int64_t cumul_from_max_end = + cumuls_[routing_model_.End(start_to_vehicle_[path_start])]->Max(); + for (int i = path_transits.PathSize(path) - 2; i >= 0; --i) { + const int64_t transit = path_transits.Transit(path, i); + const int64_t node = path_transits.Node(path, i); + cumul_from_min_end = + std::min(cumuls_[node]->Max(), CapSub(cumul_from_min_end, transit)); + cumul_from_max_end = dimension_.GetLastPossibleLessOrEqualValueForNode( + node, CapSub(cumul_from_max_end, transit)); + } + return std::min(cumul_from_min_end, cumul_from_max_end); +} + +} // namespace + +IntVarLocalSearchFilter* MakePathCumulFilter( + const RoutingDimension& dimension, + const RoutingSearchParameters& parameters, + bool propagate_own_objective_value, bool filter_objective_cost, + bool can_use_lp) { + RoutingModel& model = *dimension.model(); + return model.solver()->RevAlloc(new PathCumulFilter( + model, dimension, parameters, propagate_own_objective_value, + filter_objective_cost, can_use_lp)); +} + +namespace { + +bool DimensionHasCumulCost(const RoutingDimension& dimension) { + if (dimension.global_span_cost_coefficient() != 0) return true; + if (dimension.HasSoftSpanUpperBounds()) return true; + if (dimension.HasQuadraticCostSoftSpanUpperBounds()) return true; + for (const int64_t coefficient : dimension.vehicle_span_cost_coefficients()) { + if (coefficient != 0) return true; + } + for (int i = 0; i < dimension.cumuls().size(); ++i) { + if (dimension.HasCumulVarSoftUpperBound(i)) return true; + if (dimension.HasCumulVarSoftLowerBound(i)) return true; + if (dimension.HasCumulVarPiecewiseLinearCost(i)) return true; + } + return false; +} + +bool DimensionHasCumulConstraint(const RoutingDimension& dimension) { + if (dimension.HasBreakConstraints()) return true; + if (dimension.HasPickupToDeliveryLimits()) return true; + if (!dimension.GetNodePrecedences().empty()) return true; + for (const int64_t upper_bound : dimension.vehicle_span_upper_bounds()) { + if (upper_bound != std::numeric_limits::max()) return true; + } + for (const IntVar* const slack : dimension.slacks()) { + if (slack->Min() > 0) return true; + } + const std::vector& cumuls = dimension.cumuls(); + for (int i = 0; i < cumuls.size(); ++i) { + IntVar* const cumul_var = cumuls[i]; + if (cumul_var->Min() > 0 && + cumul_var->Max() < std::numeric_limits::max() && + !dimension.model()->IsEnd(i)) { + return true; + } + if (dimension.forbidden_intervals()[i].NumIntervals() > 0) return true; + } + return false; +} + +} // namespace + +void AppendLightWeightDimensionFilters( + const PathState* path_state, + const std::vector& dimensions, + std::vector* filters) { + // For every dimension that fits, add a UnaryDimensionChecker. + for (const RoutingDimension* dimension : dimensions) { + // Skip dimension if not unary. + if (dimension->GetUnaryTransitEvaluator(0) == nullptr) continue; + + using Intervals = std::vector; + // Fill path capacities and classes. + const int num_vehicles = dimension->model()->vehicles(); + Intervals path_capacity(num_vehicles); + std::vector path_class(num_vehicles); + for (int v = 0; v < num_vehicles; ++v) { + const auto& vehicle_capacities = dimension->vehicle_capacities(); + path_capacity[v] = {0, vehicle_capacities[v]}; + path_class[v] = dimension->vehicle_to_class(v); + } + // For each class, retrieve the demands of each node. + // Dimension store evaluators with a double indirection for compacity: + // vehicle -> vehicle_class -> evaluator_index. + // We replicate this in UnaryDimensionChecker, + // except we expand evaluator_index to an array of values for all nodes. + const int num_vehicle_classes = + 1 + *std::max_element(path_class.begin(), path_class.end()); + std::vector demands(num_vehicle_classes); + const int num_cumuls = dimension->cumuls().size(); + const int num_slacks = dimension->slacks().size(); + for (int vehicle = 0; vehicle < num_vehicles; ++vehicle) { + const int vehicle_class = path_class[vehicle]; + if (!demands[vehicle_class].empty()) continue; + const auto& evaluator = dimension->GetUnaryTransitEvaluator(vehicle); + Intervals class_demands(num_cumuls); + for (int node = 0; node < num_cumuls; ++node) { + if (node < num_slacks) { + const int64_t demand_min = evaluator(node); + const int64_t slack_max = dimension->SlackVar(node)->Max(); + class_demands[node] = {demand_min, CapAdd(demand_min, slack_max)}; + } else { + class_demands[node] = {0, 0}; + } + } + demands[vehicle_class] = std::move(class_demands); + } + // Fill node capacities. + Intervals node_capacity(num_cumuls); + for (int node = 0; node < num_cumuls; ++node) { + const IntVar* cumul = dimension->CumulVar(node); + node_capacity[node] = {cumul->Min(), cumul->Max()}; + } + // Make the dimension checker and pass ownership to the filter. + auto checker = absl::make_unique( + path_state, std::move(path_capacity), std::move(path_class), + std::move(demands), std::move(node_capacity)); + const auto kAccept = LocalSearchFilterManager::FilterEventType::kAccept; + LocalSearchFilter* filter = MakeUnaryDimensionFilter( + dimension->model()->solver(), std::move(checker)); + filters->push_back({filter, kAccept}); + } +} + +void AppendDimensionCumulFilters( + const std::vector& dimensions, + const RoutingSearchParameters& parameters, bool filter_objective_cost, + std::vector* filters) { + const auto kAccept = LocalSearchFilterManager::FilterEventType::kAccept; + // NOTE: We first sort the dimensions by increasing complexity of filtering: + // - Dimensions without any cumul-related costs or constraints will have a + // ChainCumulFilter. + // - Dimensions with cumul costs or constraints, but no global span cost + // and/or precedences will have a PathCumulFilter. + // - Dimensions with a global span cost coefficient and/or precedences will + // have a global LP filter. + const int num_dimensions = dimensions.size(); + + std::vector use_path_cumul_filter(num_dimensions); + std::vector use_cumul_bounds_propagator_filter(num_dimensions); + std::vector use_global_lp_filter(num_dimensions); + std::vector filtering_difficulty(num_dimensions); + for (int d = 0; d < num_dimensions; d++) { + const RoutingDimension& dimension = *dimensions[d]; + const bool has_cumul_cost = DimensionHasCumulCost(dimension); + use_path_cumul_filter[d] = + has_cumul_cost || DimensionHasCumulConstraint(dimension); + + const bool can_use_cumul_bounds_propagator_filter = + !dimension.HasBreakConstraints() && + (!filter_objective_cost || !has_cumul_cost); + const bool has_precedences = !dimension.GetNodePrecedences().empty(); + use_global_lp_filter[d] = + (has_precedences && !can_use_cumul_bounds_propagator_filter) || + (filter_objective_cost && dimension.global_span_cost_coefficient() > 0); + + use_cumul_bounds_propagator_filter[d] = + has_precedences && !use_global_lp_filter[d]; + + filtering_difficulty[d] = 4 * use_global_lp_filter[d] + + 2 * use_cumul_bounds_propagator_filter[d] + + use_path_cumul_filter[d]; + } + + std::vector sorted_dimension_indices(num_dimensions); + std::iota(sorted_dimension_indices.begin(), sorted_dimension_indices.end(), + 0); + std::sort(sorted_dimension_indices.begin(), sorted_dimension_indices.end(), + [&filtering_difficulty](int d1, int d2) { + return filtering_difficulty[d1] < filtering_difficulty[d2]; + }); + + for (const int d : sorted_dimension_indices) { + const RoutingDimension& dimension = *dimensions[d]; + const RoutingModel& model = *dimension.model(); + // NOTE: We always add the [Chain|Path]CumulFilter to filter each route's + // feasibility separately to try and cut bad decisions earlier in the + // search, but we don't propagate the computed cost if the LPCumulFilter is + // already doing it. + const bool use_global_lp = use_global_lp_filter[d]; + if (use_path_cumul_filter[d]) { + filters->push_back( + {MakePathCumulFilter(dimension, parameters, !use_global_lp, + filter_objective_cost), + kAccept}); + } else { + filters->push_back( + {model.solver()->RevAlloc(new ChainCumulFilter(model, dimension)), + kAccept}); + } + + if (use_global_lp) { + DCHECK(model.GetMutableGlobalCumulOptimizer(dimension) != nullptr); + filters->push_back({MakeGlobalLPCumulFilter( + model.GetMutableGlobalCumulOptimizer(dimension), + filter_objective_cost), + kAccept}); + } else if (use_cumul_bounds_propagator_filter[d]) { + filters->push_back({MakeCumulBoundsPropagatorFilter(dimension), kAccept}); + } + } +} + +namespace { + +// Filter for pickup/delivery precedences. +class PickupDeliveryFilter : public BasePathFilter { + public: + PickupDeliveryFilter(const std::vector& nexts, int next_domain_size, + const RoutingModel::IndexPairs& pairs, + const std::vector& + vehicle_policies); + ~PickupDeliveryFilter() override {} + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + std::string DebugString() const override { return "PickupDeliveryFilter"; } + + private: + bool AcceptPathDefault(int64_t path_start); + template + bool AcceptPathOrdered(int64_t path_start); + + std::vector pair_firsts_; + std::vector pair_seconds_; + const RoutingModel::IndexPairs pairs_; + SparseBitset<> visited_; + std::deque visited_deque_; + const std::vector vehicle_policies_; +}; + +PickupDeliveryFilter::PickupDeliveryFilter( + const std::vector& nexts, int next_domain_size, + const RoutingModel::IndexPairs& pairs, + const std::vector& vehicle_policies) + : BasePathFilter(nexts, next_domain_size), + pair_firsts_(next_domain_size, kUnassigned), + pair_seconds_(next_domain_size, kUnassigned), + pairs_(pairs), + visited_(Size()), + vehicle_policies_(vehicle_policies) { + for (int i = 0; i < pairs.size(); ++i) { + const auto& index_pair = pairs[i]; + for (int first : index_pair.first) { + pair_firsts_[first] = i; + } + for (int second : index_pair.second) { + pair_seconds_[second] = i; + } + } +} + +bool PickupDeliveryFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { + switch (vehicle_policies_[GetPath(path_start)]) { + case RoutingModel::PICKUP_AND_DELIVERY_NO_ORDER: + return AcceptPathDefault(path_start); + case RoutingModel::PICKUP_AND_DELIVERY_LIFO: + return AcceptPathOrdered(path_start); + case RoutingModel::PICKUP_AND_DELIVERY_FIFO: + return AcceptPathOrdered(path_start); + default: + return true; + } +} + +bool PickupDeliveryFilter::AcceptPathDefault(int64_t path_start) { + visited_.ClearAll(); + int64_t node = path_start; + int64_t path_length = 1; + while (node < Size()) { + // Detect sub-cycles (path is longer than longest possible path). + if (path_length > Size()) { + return false; + } + if (pair_firsts_[node] != kUnassigned) { + // Checking on pair firsts is not actually necessary (inconsistencies + // will get caught when checking pair seconds); doing it anyway to + // cut checks early. + for (int second : pairs_[pair_firsts_[node]].second) { + if (visited_[second]) { + return false; + } + } + } + if (pair_seconds_[node] != kUnassigned) { + bool found_first = false; + bool some_synced = false; + for (int first : pairs_[pair_seconds_[node]].first) { + if (visited_[first]) { + found_first = true; + break; + } + if (IsVarSynced(first)) { + some_synced = true; + } + } + if (!found_first && some_synced) { + return false; + } + } + visited_.Set(node); + const int64_t next = GetNext(node); + if (next == kUnassigned) { + // LNS detected, return true since path was ok up to now. + return true; + } + node = next; + ++path_length; + } + for (const int64_t node : visited_.PositionsSetAtLeastOnce()) { + if (pair_firsts_[node] != kUnassigned) { + bool found_second = false; + bool some_synced = false; + for (int second : pairs_[pair_firsts_[node]].second) { + if (visited_[second]) { + found_second = true; + break; + } + if (IsVarSynced(second)) { + some_synced = true; + } + } + if (!found_second && some_synced) { + return false; + } + } + } + return true; +} + +template +bool PickupDeliveryFilter::AcceptPathOrdered(int64_t path_start) { + visited_deque_.clear(); + int64_t node = path_start; + int64_t path_length = 1; + while (node < Size()) { + // Detect sub-cycles (path is longer than longest possible path). + if (path_length > Size()) { + return false; + } + if (pair_firsts_[node] != kUnassigned) { + if (lifo) { + visited_deque_.push_back(node); + } else { + visited_deque_.push_front(node); + } + } + if (pair_seconds_[node] != kUnassigned) { + bool found_first = false; + bool some_synced = false; + for (int first : pairs_[pair_seconds_[node]].first) { + if (!visited_deque_.empty() && visited_deque_.back() == first) { + found_first = true; + break; + } + if (IsVarSynced(first)) { + some_synced = true; + } + } + if (!found_first && some_synced) { + return false; + } else if (!visited_deque_.empty()) { + visited_deque_.pop_back(); + } + } + const int64_t next = GetNext(node); + if (next == kUnassigned) { + // LNS detected, return true since path was ok up to now. + return true; + } + node = next; + ++path_length; + } + while (!visited_deque_.empty()) { + for (int second : pairs_[pair_firsts_[visited_deque_.back()]].second) { + if (IsVarSynced(second)) { + return false; + } + } + visited_deque_.pop_back(); + } + return true; +} + +} // namespace + +IntVarLocalSearchFilter* MakePickupDeliveryFilter( + const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs, + const std::vector& + vehicle_policies) { + return routing_model.solver()->RevAlloc(new PickupDeliveryFilter( + routing_model.Nexts(), routing_model.Size() + routing_model.vehicles(), + pairs, vehicle_policies)); +} + +namespace { + +// Vehicle variable filter +class VehicleVarFilter : public BasePathFilter { + public: + explicit VehicleVarFilter(const RoutingModel& routing_model); + ~VehicleVarFilter() override {} + bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) override; + std::string DebugString() const override { return "VehicleVariableFilter"; } + + private: + bool DisableFiltering() const override; + bool IsVehicleVariableConstrained(int index) const; + + std::vector start_to_vehicle_; + std::vector vehicle_vars_; + const int64_t unconstrained_vehicle_var_domain_size_; +}; + +VehicleVarFilter::VehicleVarFilter(const RoutingModel& routing_model) + : BasePathFilter(routing_model.Nexts(), + routing_model.Size() + routing_model.vehicles()), + vehicle_vars_(routing_model.VehicleVars()), + unconstrained_vehicle_var_domain_size_(routing_model.vehicles()) { + start_to_vehicle_.resize(Size(), -1); + for (int i = 0; i < routing_model.vehicles(); ++i) { + start_to_vehicle_[routing_model.Start(i)] = i; + } +} + +bool VehicleVarFilter::AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) { + const int64_t vehicle = start_to_vehicle_[path_start]; + int64_t node = chain_start; + while (node != chain_end) { + if (!vehicle_vars_[node]->Contains(vehicle)) { + return false; + } + node = GetNext(node); + } + return vehicle_vars_[node]->Contains(vehicle); +} + +bool VehicleVarFilter::DisableFiltering() const { + for (int i = 0; i < vehicle_vars_.size(); ++i) { + if (IsVehicleVariableConstrained(i)) return false; + } + return true; +} + +bool VehicleVarFilter::IsVehicleVariableConstrained(int index) const { + const IntVar* const vehicle_var = vehicle_vars_[index]; + // If vehicle variable contains -1 (optional node), then we need to + // add it to the "unconstrained" domain. Impact we don't filter mandatory + // nodes made inactive here, but it is covered by other filters. + const int adjusted_unconstrained_vehicle_var_domain_size = + vehicle_var->Min() >= 0 ? unconstrained_vehicle_var_domain_size_ + : unconstrained_vehicle_var_domain_size_ + 1; + return vehicle_var->Size() != adjusted_unconstrained_vehicle_var_domain_size; +} + +} // namespace + +IntVarLocalSearchFilter* MakeVehicleVarFilter( + const RoutingModel& routing_model) { + return routing_model.solver()->RevAlloc(new VehicleVarFilter(routing_model)); +} + +namespace { + +class CumulBoundsPropagatorFilter : public IntVarLocalSearchFilter { + public: + explicit CumulBoundsPropagatorFilter(const RoutingDimension& dimension); + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override; + std::string DebugString() const override { + return "CumulBoundsPropagatorFilter(" + propagator_.dimension().name() + + ")"; + } + + private: + CumulBoundsPropagator propagator_; + const int64_t cumul_offset_; + SparseBitset delta_touched_; + std::vector delta_nexts_; +}; + +CumulBoundsPropagatorFilter::CumulBoundsPropagatorFilter( + const RoutingDimension& dimension) + : IntVarLocalSearchFilter(dimension.model()->Nexts()), + propagator_(&dimension), + cumul_offset_(dimension.GetGlobalOptimizerOffset()), + delta_touched_(Size()), + delta_nexts_(Size()) {} + +bool CumulBoundsPropagatorFilter::Accept(const Assignment* delta, + const Assignment* deltadelta, + int64_t objective_min, + int64_t objective_max) { + delta_touched_.ClearAll(); + for (const IntVarElement& delta_element : + delta->IntVarContainer().elements()) { + int64_t index = -1; + if (FindIndex(delta_element.Var(), &index)) { + if (!delta_element.Bound()) { + // LNS detected + return true; + } + delta_touched_.Set(index); + delta_nexts_[index] = delta_element.Value(); + } + } + const auto& next_accessor = [this](int64_t index) { + return delta_touched_[index] ? delta_nexts_[index] : Value(index); + }; + + return propagator_.PropagateCumulBounds(next_accessor, cumul_offset_); +} + +} // namespace + +IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter( + const RoutingDimension& dimension) { + return dimension.model()->solver()->RevAlloc( + new CumulBoundsPropagatorFilter(dimension)); +} + +namespace { + +class LPCumulFilter : public IntVarLocalSearchFilter { + public: + LPCumulFilter(const std::vector& nexts, + GlobalDimensionCumulOptimizer* optimizer, + bool filter_objective_cost); + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override; + int64_t GetAcceptedObjectiveValue() const override; + void OnSynchronize(const Assignment* delta) override; + int64_t GetSynchronizedObjectiveValue() const override; + std::string DebugString() const override { + return "LPCumulFilter(" + optimizer_.dimension()->name() + ")"; + } + + private: + GlobalDimensionCumulOptimizer& optimizer_; + const bool filter_objective_cost_; + int64_t synchronized_cost_without_transit_; + int64_t delta_cost_without_transit_; + SparseBitset delta_touched_; + std::vector delta_nexts_; +}; + +LPCumulFilter::LPCumulFilter(const std::vector& nexts, + GlobalDimensionCumulOptimizer* optimizer, + bool filter_objective_cost) + : IntVarLocalSearchFilter(nexts), + optimizer_(*optimizer), + filter_objective_cost_(filter_objective_cost), + synchronized_cost_without_transit_(-1), + delta_cost_without_transit_(-1), + delta_touched_(Size()), + delta_nexts_(Size()) {} + +bool LPCumulFilter::Accept(const Assignment* delta, + const Assignment* deltadelta, int64_t objective_min, + int64_t objective_max) { + delta_touched_.ClearAll(); + for (const IntVarElement& delta_element : + delta->IntVarContainer().elements()) { + int64_t index = -1; + if (FindIndex(delta_element.Var(), &index)) { + if (!delta_element.Bound()) { + // LNS detected + return true; + } + delta_touched_.Set(index); + delta_nexts_[index] = delta_element.Value(); + } + } + const auto& next_accessor = [this](int64_t index) { + return delta_touched_[index] ? delta_nexts_[index] : Value(index); + }; + + if (!filter_objective_cost_) { + // No need to compute the cost of the LP, only verify its feasibility. + delta_cost_without_transit_ = 0; + return optimizer_.IsFeasible(next_accessor); + } + + if (!optimizer_.ComputeCumulCostWithoutFixedTransits( + next_accessor, &delta_cost_without_transit_)) { + // Infeasible. + delta_cost_without_transit_ = std::numeric_limits::max(); + return false; + } + return delta_cost_without_transit_ <= objective_max; +} + +int64_t LPCumulFilter::GetAcceptedObjectiveValue() const { + return delta_cost_without_transit_; +} + +void LPCumulFilter::OnSynchronize(const Assignment* delta) { + // TODO(user): Try to optimize this so the LP is not called when the last + // computed delta cost corresponds to the solution being synchronized. + const RoutingModel& model = *optimizer_.dimension()->model(); + if (!optimizer_.ComputeCumulCostWithoutFixedTransits( + [this, &model](int64_t index) { + return IsVarSynced(index) ? Value(index) + : model.IsStart(index) ? model.End(model.VehicleIndex(index)) + : index; + }, + &synchronized_cost_without_transit_)) { + // TODO(user): This should only happen if the LP solver times out. + // DCHECK the fail wasn't due to an infeasible model. + synchronized_cost_without_transit_ = 0; + } +} + +int64_t LPCumulFilter::GetSynchronizedObjectiveValue() const { + return synchronized_cost_without_transit_; +} + +} // namespace + +IntVarLocalSearchFilter* MakeGlobalLPCumulFilter( + GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost) { + const RoutingModel& model = *optimizer->dimension()->model(); + return model.solver()->RevAlloc( + new LPCumulFilter(model.Nexts(), optimizer, filter_objective_cost)); +} + +namespace { + +// This filter accepts deltas for which the assignment satisfies the +// constraints of the Solver. This is verified by keeping an internal copy of +// the assignment with all Next vars and their updated values, and calling +// RestoreAssignment() on the assignment+delta. +// TODO(user): Also call the solution finalizer on variables, with the +// exception of Next Vars (woud fail on large instances). +// WARNING: In the case of mandatory nodes, when all vehicles are currently +// being used in the solution but uninserted nodes still remain, this filter +// will reject the solution, even if the node could be inserted on one of these +// routes, because all Next vars of vehicle starts are already instantiated. +// TODO(user): Avoid such false negatives. + +class CPFeasibilityFilter : public IntVarLocalSearchFilter { + public: + explicit CPFeasibilityFilter(RoutingModel* routing_model); + ~CPFeasibilityFilter() override {} + std::string DebugString() const override { return "CPFeasibilityFilter"; } + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override; + void OnSynchronize(const Assignment* delta) override; + + private: + void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment); + + static const int64_t kUnassigned; + const RoutingModel* const model_; + Solver* const solver_; + Assignment* const assignment_; + Assignment* const temp_assignment_; + DecisionBuilder* const restore_; + SearchLimit* const limit_; +}; + +const int64_t CPFeasibilityFilter::kUnassigned = -1; + +CPFeasibilityFilter::CPFeasibilityFilter(RoutingModel* routing_model) + : IntVarLocalSearchFilter(routing_model->Nexts()), + model_(routing_model), + solver_(routing_model->solver()), + assignment_(solver_->MakeAssignment()), + temp_assignment_(solver_->MakeAssignment()), + restore_(solver_->MakeRestoreAssignment(temp_assignment_)), + limit_(solver_->MakeCustomLimit( + [routing_model]() { return routing_model->CheckLimit(); })) { + assignment_->Add(routing_model->Nexts()); +} + +bool CPFeasibilityFilter::Accept(const Assignment* delta, + const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) { + temp_assignment_->Copy(assignment_); + AddDeltaToAssignment(delta, temp_assignment_); + + return solver_->Solve(restore_, limit_); +} + +void CPFeasibilityFilter::OnSynchronize(const Assignment* delta) { + AddDeltaToAssignment(delta, assignment_); +} + +void CPFeasibilityFilter::AddDeltaToAssignment(const Assignment* delta, + Assignment* assignment) { + if (delta == nullptr) { + return; + } + Assignment::IntContainer* const container = + assignment->MutableIntVarContainer(); + const Assignment::IntContainer& delta_container = delta->IntVarContainer(); + const int delta_size = delta_container.Size(); + + for (int i = 0; i < delta_size; i++) { + const IntVarElement& delta_element = delta_container.Element(i); + IntVar* const var = delta_element.Var(); + int64_t index = kUnassigned; + CHECK(FindIndex(var, &index)); + DCHECK_EQ(var, Var(index)); + const int64_t value = delta_element.Value(); + + container->AddAtPosition(var, index)->SetValue(value); + if (model_->IsStart(index)) { + if (model_->IsEnd(value)) { + // Do not restore unused routes. + container->MutableElement(index)->Deactivate(); + } else { + // Re-activate the route's start in case it was deactivated before. + container->MutableElement(index)->Activate(); + } + } + } +} + +} // namespace + +IntVarLocalSearchFilter* MakeCPFeasibilityFilter(RoutingModel* routing_model) { + return routing_model->solver()->RevAlloc( + new CPFeasibilityFilter(routing_model)); +} + +// TODO(user): Implement same-vehicle filter. Could be merged with node +// precedence filter. + +} // namespace operations_research diff --git a/ortools/constraint_solver/routing_filters.h b/ortools/constraint_solver/routing_filters.h new file mode 100644 index 0000000000..b18acff682 --- /dev/null +++ b/ortools/constraint_solver/routing_filters.h @@ -0,0 +1,155 @@ +// Copyright 2010-2018 Google LLC +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTERS_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTERS_H_ + +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_lp_scheduling.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/util/bitset.h" + +namespace operations_research { + +/// Returns a filter ensuring that max active vehicles constraints are enforced. +IntVarLocalSearchFilter* MakeMaxActiveVehiclesFilter( + const RoutingModel& routing_model); + +/// Returns a filter ensuring that node disjunction constraints are enforced. +IntVarLocalSearchFilter* MakeNodeDisjunctionFilter( + const RoutingModel& routing_model); + +/// Returns a filter computing vehicle amortized costs. +IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter( + const RoutingModel& routing_model); + +/// Returns a filter ensuring type regulation constraints are enforced. +IntVarLocalSearchFilter* MakeTypeRegulationsFilter( + const RoutingModel& routing_model); + +/// Returns a filter enforcing pickup and delivery constraints for the given +/// pair of nodes and given policies. +IntVarLocalSearchFilter* MakePickupDeliveryFilter( + const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs, + const std::vector& vehicle_policies); + +/// Returns a filter checking that vehicle variable domains are respected. +IntVarLocalSearchFilter* MakeVehicleVarFilter( + const RoutingModel& routing_model); + +/// Returns a filter handling dimension costs and constraints. +IntVarLocalSearchFilter* MakePathCumulFilter( + const RoutingDimension& dimension, + const RoutingSearchParameters& parameters, + bool propagate_own_objective_value, bool filter_objective_cost, + bool can_use_lp = true); + +/// Returns a filter handling dimension cumul bounds. +IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter( + const RoutingDimension& dimension); + +/// Returns a filter checking global linear constraints and costs. +IntVarLocalSearchFilter* MakeGlobalLPCumulFilter( + GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost); + +/// Returns a filter checking the current solution using CP propagation. +IntVarLocalSearchFilter* MakeCPFeasibilityFilter(RoutingModel* routing_model); + +/// Appends dimension-based filters to the given list of filters using a path +/// state. +void AppendLightWeightDimensionFilters( + const PathState* path_state, + const std::vector& dimensions, + std::vector* filters); + +void AppendDimensionCumulFilters( + const std::vector& dimensions, + const RoutingSearchParameters& parameters, bool filter_objective_cost, + std::vector* filters); + +/// Generic path-based filter class. + +class BasePathFilter : public IntVarLocalSearchFilter { + public: + BasePathFilter(const std::vector& nexts, int next_domain_size); + ~BasePathFilter() override {} + bool Accept(const Assignment* delta, const Assignment* deltadelta, + int64_t objective_min, int64_t objective_max) override; + void OnSynchronize(const Assignment* delta) override; + + protected: + static const int64_t kUnassigned; + + int64_t GetNext(int64_t node) const { + return (new_nexts_[node] == kUnassigned) + ? (IsVarSynced(node) ? Value(node) : kUnassigned) + : new_nexts_[node]; + } + int NumPaths() const { return starts_.size(); } + int64_t Start(int i) const { return starts_[i]; } + int GetPath(int64_t node) const { return paths_[node]; } + int Rank(int64_t node) const { return ranks_[node]; } + bool IsDisabled() const { return status_ == DISABLED; } + const std::vector& GetTouchedPathStarts() const { + return touched_paths_.PositionsSetAtLeastOnce(); + } + const std::vector& GetNewSynchronizedUnperformedNodes() const { + return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce(); + } + + private: + enum Status { UNKNOWN, ENABLED, DISABLED }; + + virtual bool DisableFiltering() const { return false; } + virtual void OnBeforeSynchronizePaths() {} + virtual void OnAfterSynchronizePaths() {} + virtual void OnSynchronizePathFromStart(int64_t start) {} + virtual void InitializeAcceptPath() {} + virtual bool AcceptPath(int64_t path_start, int64_t chain_start, + int64_t chain_end) = 0; + virtual bool FinalizeAcceptPath(const Assignment* delta, int64_t objective_min, + int64_t objective_max) { + return true; + } + /// Detects path starts, used to track which node belongs to which path. + void ComputePathStarts(std::vector* path_starts, + std::vector* index_to_path); + bool HavePathsChanged(); + void SynchronizeFullAssignment(); + void UpdateAllRanks(); + void UpdatePathRanksFromStart(int start); + + std::vector node_path_starts_; + std::vector starts_; + std::vector paths_; + SparseBitset new_synchronized_unperformed_nodes_; + std::vector new_nexts_; + std::vector delta_touched_; + SparseBitset<> touched_paths_; + // clang-format off + std::vector > touched_path_chain_start_ends_; + // clang-format on + std::vector ranks_; + + Status status_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTERS_H_ diff --git a/ortools/constraint_solver/routing_flags.cc b/ortools/constraint_solver/routing_flags.cc index 2bd5f61cd6..d2df4e8927 100644 --- a/ortools/constraint_solver/routing_flags.cc +++ b/ortools/constraint_solver/routing_flags.cc @@ -13,6 +13,8 @@ #include "ortools/constraint_solver/routing_flags.h" +#include +#include #include #include @@ -75,10 +77,11 @@ ABSL_FLAG(bool, routing_generic_tabu_search, false, "Routing: use tabu search based on a list of values."); // Search limits -ABSL_FLAG(int64, routing_solution_limit, kint64max, +ABSL_FLAG(int64_t, routing_solution_limit, std::numeric_limits::max(), "Routing: number of solutions limit."); -ABSL_FLAG(int64, routing_time_limit, kint64max, "Routing: time limit in ms."); -ABSL_FLAG(int64, routing_lns_time_limit, 100, +ABSL_FLAG(int64_t, routing_time_limit, std::numeric_limits::max(), + "Routing: time limit in ms."); +ABSL_FLAG(int64_t, routing_lns_time_limit, 100, "Routing: time limit in ms for LNS sub-decisionbuilder."); // Search control @@ -117,7 +120,7 @@ ABSL_FLAG(bool, routing_use_light_propagation, true, // Cache settings. ABSL_FLAG(bool, routing_cache_callbacks, false, "Cache callback calls."); -ABSL_FLAG(int64, routing_max_cache_size, 1000, +ABSL_FLAG(int64_t, routing_max_cache_size, 1000, "Maximum cache size when callback caching is on."); // Misc @@ -285,12 +288,14 @@ void SetSearchLimitsFromFlags(RoutingSearchParameters* parameters) { parameters->set_number_of_solutions_to_collect( absl::GetFlag(FLAGS_routing_number_of_solutions_to_collect)); parameters->set_solution_limit(absl::GetFlag(FLAGS_routing_solution_limit)); - if (absl::GetFlag(FLAGS_routing_time_limit) != kint64max) { + if (absl::GetFlag(FLAGS_routing_time_limit) != + std::numeric_limits::max()) { CHECK_OK(util_time::EncodeGoogleApiProto( absl::Milliseconds(absl::GetFlag(FLAGS_routing_time_limit)), parameters->mutable_time_limit())); } - if (absl::GetFlag(FLAGS_routing_lns_time_limit) != kint64max) { + if (absl::GetFlag(FLAGS_routing_lns_time_limit) != + std::numeric_limits::max()) { CHECK_OK(util_time::EncodeGoogleApiProto( absl::Milliseconds(absl::GetFlag(FLAGS_routing_lns_time_limit)), parameters->mutable_lns_time_limit())); diff --git a/ortools/constraint_solver/routing_flags.h b/ortools/constraint_solver/routing_flags.h index 2374f3afef..c954be8ed6 100644 --- a/ortools/constraint_solver/routing_flags.h +++ b/ortools/constraint_solver/routing_flags.h @@ -14,6 +14,7 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FLAGS_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FLAGS_H_ +#include #include #include "ortools/base/commandlineflags.h" @@ -47,9 +48,9 @@ ABSL_DECLARE_FLAG(bool, routing_tabu_search); ABSL_DECLARE_FLAG(bool, routing_generic_tabu_search); /// Search limits -ABSL_DECLARE_FLAG(int64, routing_solution_limit); -ABSL_DECLARE_FLAG(int64, routing_time_limit); -ABSL_DECLARE_FLAG(int64, routing_lns_time_limit); +ABSL_DECLARE_FLAG(int64_t, routing_solution_limit); +ABSL_DECLARE_FLAG(int64_t, routing_time_limit); +ABSL_DECLARE_FLAG(int64_t, routing_lns_time_limit); /// Search control ABSL_DECLARE_FLAG(std::string, routing_first_solution); @@ -69,7 +70,7 @@ ABSL_DECLARE_FLAG(bool, routing_use_light_propagation); /// Cache settings. ABSL_DECLARE_FLAG(bool, routing_cache_callbacks); -ABSL_DECLARE_FLAG(int64, routing_max_cache_size); +ABSL_DECLARE_FLAG(int64_t, routing_max_cache_size); /// Misc ABSL_DECLARE_FLAG(bool, routing_trace); diff --git a/ortools/constraint_solver/routing_flow.cc b/ortools/constraint_solver/routing_flow.cc index 42bd707cb1..80b87dd18e 100644 --- a/ortools/constraint_solver/routing_flow.cc +++ b/ortools/constraint_solver/routing_flow.cc @@ -11,9 +11,30 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "ortools/base/int_type.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/map_util.h" +#include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/routing.h" #include "ortools/constraint_solver/routing_lp_scheduling.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/graph/ebert_graph.h" #include "ortools/graph/min_cost_flow.h" +#include "ortools/util/saturated_arithmetic.h" namespace operations_research { @@ -21,9 +42,9 @@ namespace { // Compute set of disjunctions involved in a pickup and delivery pair. template void AddDisjunctionsFromNodes(const RoutingModel& model, - const std::vector& nodes, + const std::vector& nodes, Disjunctions* disjunctions) { - for (int64 node : nodes) { + for (int64_t node : nodes) { for (const auto disjunction : model.GetDisjunctionIndices(node)) { disjunctions->insert(disjunction); } @@ -37,7 +58,7 @@ bool RoutingModel::IsMatchingModel() const { absl::flat_hash_set disjunction_nodes; for (DisjunctionIndex i(0); i < GetNumberOfDisjunctions(); ++i) { if (GetDisjunctionMaxCardinality(i) > 1) return false; - for (int64 node : GetDisjunctionIndices(i)) { + for (int64_t node : GetDisjunctionIndices(i)) { if (!disjunction_nodes.insert(node).second) return false; } } @@ -62,17 +83,18 @@ bool RoutingModel::IsMatchingModel() const { if (transit == nullptr) { continue; } - int64 max_vehicle_capacity = 0; - for (int64 vehicle_capacity : dimension->vehicle_capacities()) { + int64_t max_vehicle_capacity = 0; + for (int64_t vehicle_capacity : dimension->vehicle_capacities()) { max_vehicle_capacity = std::max(max_vehicle_capacity, vehicle_capacity); } - std::vector transits(nexts_.size(), kint64max); + std::vector transits(nexts_.size(), + std::numeric_limits::max()); for (int i = 0; i < nexts_.size(); ++i) { if (!IsStart(i) && !IsEnd(i)) { transits[i] = std::min(transits[i], transit(i)); } } - int64 min_transit = kint64max; + int64_t min_transit = std::numeric_limits::max(); // Find the minimal accumulated value resulting from a pickup and delivery // pair. for (const auto& pd_pairs : GetPickupAndDeliveryPairs()) { @@ -124,10 +146,10 @@ bool RoutingModel::IsMatchingModel() const { namespace { struct FlowArc { - int64 tail; - int64 head; - int64 capacity; - int64 cost; + int64_t tail; + int64_t head; + int64_t capacity; + int64_t cost; }; } // namespace @@ -149,21 +171,21 @@ bool RoutingModel::SolveMatchingModel( } int num_flow_nodes = 0; - std::vector> disjunction_to_flow_nodes; - std::vector disjunction_penalties; + std::vector> disjunction_to_flow_nodes; + std::vector disjunction_penalties; std::vector in_disjunction(Size(), false); // Create pickup and delivery pair flow nodes. // TODO(user): Check pair alternatives correspond exactly to at most two // disjunctions. - absl::flat_hash_map> flow_to_pd; + absl::flat_hash_map> flow_to_pd; for (const auto& pd_pairs : GetPickupAndDeliveryPairs()) { disjunction_to_flow_nodes.push_back({}); absl::flat_hash_set disjunctions; AddDisjunctionsFromNodes(*this, pd_pairs.first, &disjunctions); AddDisjunctionsFromNodes(*this, pd_pairs.second, &disjunctions); - for (int64 pickup : pd_pairs.first) { + for (int64_t pickup : pd_pairs.first) { in_disjunction[pickup] = true; - for (int64 delivery : pd_pairs.second) { + for (int64_t delivery : pd_pairs.second) { in_disjunction[delivery] = true; flow_to_pd[num_flow_nodes] = {pickup, delivery}; disjunction_to_flow_nodes.back().push_back(num_flow_nodes); @@ -171,12 +193,12 @@ bool RoutingModel::SolveMatchingModel( } } DCHECK_LE(disjunctions.size(), 2); - int64 penalty = 0; + int64_t penalty = 0; if (disjunctions.size() < 2) { penalty = kNoPenalty; } else { for (DisjunctionIndex index : disjunctions) { - const int64 d_penalty = GetDisjunctionPenalty(index); + const int64_t d_penalty = GetDisjunctionPenalty(index); if (d_penalty == kNoPenalty) { penalty = kNoPenalty; break; @@ -187,7 +209,7 @@ bool RoutingModel::SolveMatchingModel( disjunction_penalties.push_back(penalty); } // Create non-pickup and delivery flow nodes. - absl::flat_hash_map flow_to_non_pd; + absl::flat_hash_map flow_to_non_pd; for (int node = 0; node < Size(); ++node) { if (IsStart(node) || in_disjunction[node]) continue; const std::vector& disjunctions = @@ -219,12 +241,12 @@ bool RoutingModel::SolveMatchingModel( // capacity is one (only one of the nodes in the disjunction is performed). absl::flat_hash_map flow_to_disjunction; for (int i = 0; i < disjunction_to_flow_nodes.size(); ++i) { - const std::vector& flow_nodes = disjunction_to_flow_nodes[i]; + const std::vector& flow_nodes = disjunction_to_flow_nodes[i]; if (flow_nodes.size() == 1) { flow_to_disjunction[flow_nodes.back()] = i; } else { flow_to_disjunction[num_flow_nodes] = i; - for (int64 flow_node : flow_nodes) { + for (int64_t flow_node : flow_nodes) { arcs.push_back({flow_node, num_flow_nodes, 1, 0}); } num_flow_nodes++; @@ -239,17 +261,17 @@ bool RoutingModel::SolveMatchingModel( std::vector vehicle_to_flow; absl::flat_hash_map flow_to_vehicle; for (int vehicle = 0; vehicle < vehicles(); ++vehicle) { - const int64 start = Start(vehicle); - const int64 end = End(vehicle); - for (const std::vector& flow_nodes : disjunction_to_flow_nodes) { - for (int64 flow_node : flow_nodes) { - std::pair pd_pair; - int64 node = -1; - int64 cost = 0; + const int64_t start = Start(vehicle); + const int64_t end = End(vehicle); + for (const std::vector& flow_nodes : disjunction_to_flow_nodes) { + for (int64_t flow_node : flow_nodes) { + std::pair pd_pair; + int64_t node = -1; + int64_t cost = 0; bool add_arc = false; if (gtl::FindCopy(flow_to_pd, flow_node, &pd_pair)) { - const int64 pickup = pd_pair.first; - const int64 delivery = pd_pair.second; + const int64_t pickup = pd_pair.first; + const int64_t delivery = pd_pair.second; if (IsVehicleAllowedForIndex(vehicle, pickup) && IsVehicleAllowedForIndex(vehicle, delivery)) { add_arc = true; @@ -257,15 +279,15 @@ bool RoutingModel::SolveMatchingModel( CapAdd(GetArcCostForVehicle(start, pickup, vehicle), CapAdd(GetArcCostForVehicle(pickup, delivery, vehicle), GetArcCostForVehicle(delivery, end, vehicle))); - const absl::flat_hash_map nexts = { + const absl::flat_hash_map nexts = { {start, pickup}, {pickup, delivery}, {delivery, end}}; for (LocalDimensionCumulOptimizer& optimizer : optimizers) { - int64 cumul_cost_value = 0; + int64_t cumul_cost_value = 0; // TODO(user): if the result is RELAXED_OPTIMAL_ONLY, do a // second pass with an MP solver. if (optimizer.ComputeRouteCumulCostWithoutFixedTransits( vehicle, - [&nexts](int64 node) { return nexts.find(node)->second; }, + [&nexts](int64_t node) { return nexts.find(node)->second; }, &cumul_cost_value) != DimensionSchedulingStatus::INFEASIBLE) { cost = CapAdd(cost, cumul_cost_value); @@ -280,15 +302,15 @@ bool RoutingModel::SolveMatchingModel( add_arc = true; cost = CapAdd(GetArcCostForVehicle(start, node, vehicle), GetArcCostForVehicle(node, end, vehicle)); - const absl::flat_hash_map nexts = {{start, node}, - {node, end}}; + const absl::flat_hash_map nexts = {{start, node}, + {node, end}}; for (LocalDimensionCumulOptimizer& optimizer : optimizers) { - int64 cumul_cost_value = 0; + int64_t cumul_cost_value = 0; // TODO(user): if the result is RELAXED_OPTIMAL_ONLY, do a // second pass with an MP solver. if (optimizer.ComputeRouteCumulCostWithoutFixedTransits( vehicle, - [&nexts](int64 node) { return nexts.find(node)->second; }, + [&nexts](int64_t node) { return nexts.find(node)->second; }, &cumul_cost_value) != DimensionSchedulingStatus::INFEASIBLE) { cost = CapAdd(cost, cumul_cost_value); @@ -320,11 +342,11 @@ bool RoutingModel::SolveMatchingModel( // Handle unperformed nodes. // Create a node to catch unperformed nodes and connect it to source. const int unperformed = num_flow_nodes; - const int64 flow_supply = disjunction_to_flow_nodes.size(); + const int64_t flow_supply = disjunction_to_flow_nodes.size(); arcs.push_back({source, unperformed, flow_supply, 0}); for (const auto& flow_disjunction_element : flow_to_disjunction) { const int flow_node = flow_disjunction_element.first; - const int64 penalty = + const int64_t penalty = disjunction_penalties[flow_disjunction_element.second]; if (penalty != kNoPenalty) { arcs.push_back({unperformed, flow_node, 1, penalty}); @@ -337,7 +359,7 @@ bool RoutingModel::SolveMatchingModel( // push-relabel flow algorithm is max_arc_cost * (num_nodes+1) * (num_nodes+1) // (cost-scaling multiplies arc costs by num_nodes+1 and the flow itself can // accumulate num_nodes+1 such arcs (with capacity being 1 for costed arcs)). - int64 scale_factor = 1; + int64_t scale_factor = 1; const FlowArc& arc_with_max_cost = *std::max_element( arcs.begin(), arcs.end(), [](const FlowArc& a, const FlowArc& b) { return a.cost < b.cost; }); @@ -346,7 +368,7 @@ bool RoutingModel::SolveMatchingModel( const int actual_flow_num_nodes = num_flow_nodes + 3; if (log(static_cast(arc_with_max_cost.cost) + 1) + 2 * log(actual_flow_num_nodes) > - log(std::numeric_limits::max())) { + log(std::numeric_limits::max())) { scale_factor = CapProd(actual_flow_num_nodes, actual_flow_num_nodes); } @@ -372,7 +394,7 @@ bool RoutingModel::SolveMatchingModel( for (int i = 0; i < flow.NumArcs(); ++i) { if (flow.Flow(i) > 0 && flow.Tail(i) != source && flow.Head(i) != sink) { std::vector nodes; - std::pair pd_pair; + std::pair pd_pair; int node = -1; int index = -1; if (gtl::FindCopy(flow_to_pd, flow.Head(i), &pd_pair)) { @@ -381,7 +403,7 @@ bool RoutingModel::SolveMatchingModel( } else if (gtl::FindCopy(flow_to_non_pd, flow.Head(i), &node)) { nodes.push_back(node); } else if (gtl::FindCopy(flow_to_disjunction, flow.Head(i), &index)) { - for (int64 flow_node : disjunction_to_flow_nodes[index]) { + for (int64_t flow_node : disjunction_to_flow_nodes[index]) { if (gtl::FindCopy(flow_to_pd, flow_node, &pd_pair)) { nodes.push_back(pd_pair.first); nodes.push_back(pd_pair.second); diff --git a/ortools/constraint_solver/routing_index_manager.cc b/ortools/constraint_solver/routing_index_manager.cc index 197e547d45..de33985e2c 100644 --- a/ortools/constraint_solver/routing_index_manager.cc +++ b/ortools/constraint_solver/routing_index_manager.cc @@ -13,6 +13,7 @@ #include "ortools/constraint_solver/routing_index_manager.h" +#include #include #include "absl/container/flat_hash_set.h" @@ -21,7 +22,7 @@ namespace operations_research { -const int64 RoutingIndexManager::kUnassigned = -1; +const int64_t RoutingIndexManager::kUnassigned = -1; RoutingIndexManager::RoutingIndexManager(int num_nodes, int num_vehicles, NodeIndex depot) @@ -77,7 +78,7 @@ void RoutingIndexManager::Initialize( node_to_index_.resize(num_nodes_, kUnassigned); vehicle_to_start_.resize(num_vehicles_); vehicle_to_end_.resize(num_vehicles_); - int64 index = 0; + int64_t index = 0; for (NodeIndex i = kZeroNode; i < num_nodes_; ++i) { if (gtl::ContainsKey(starts, i) || !gtl::ContainsKey(ends, i)) { index_to_node_[index] = i; @@ -90,7 +91,7 @@ void RoutingIndexManager::Initialize( const NodeIndex start = starts_ends[i].first; if (!gtl::ContainsKey(seen_starts, start)) { seen_starts.insert(start); - const int64 start_index = node_to_index_[start]; + const int64_t start_index = node_to_index_[start]; vehicle_to_start_[i] = start_index; CHECK_NE(kUnassigned, start_index); } else { @@ -110,7 +111,7 @@ void RoutingIndexManager::Initialize( // Logging model information. VLOG(1) << "Number of nodes: " << num_nodes_; VLOG(1) << "Number of vehicles: " << num_vehicles_; - for (int64 index = 0; index < index_to_node_.size(); ++index) { + for (int64_t index = 0; index < index_to_node_.size(); ++index) { VLOG(2) << "Variable index " << index << " -> Node index " << index_to_node_[index]; } @@ -120,12 +121,12 @@ void RoutingIndexManager::Initialize( } } -std::vector RoutingIndexManager::NodesToIndices( +std::vector RoutingIndexManager::NodesToIndices( const std::vector& nodes) const { - std::vector indices; + std::vector indices; indices.reserve(nodes.size()); for (const NodeIndex node : nodes) { - const int64 index = NodeToIndex(node); + const int64_t index = NodeToIndex(node); CHECK_NE(kUnassigned, index); indices.push_back(index); } @@ -133,10 +134,10 @@ std::vector RoutingIndexManager::NodesToIndices( } std::vector RoutingIndexManager::IndicesToNodes( - const std::vector& indices) const { + const std::vector& indices) const { std::vector nodes; nodes.reserve(indices.size()); - for (const int64 index : indices) { + for (const int64_t index : indices) { nodes.push_back(IndexToNode(index)); } return nodes; diff --git a/ortools/constraint_solver/routing_index_manager.h b/ortools/constraint_solver/routing_index_manager.h index 7685fd2d0e..df30ab77ed 100644 --- a/ortools/constraint_solver/routing_index_manager.h +++ b/ortools/constraint_solver/routing_index_manager.h @@ -14,9 +14,10 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_INDEX_MANAGER_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_INDEX_MANAGER_H_ -#include +#include #include +#include "ortools/base/integral_types.h" #include "ortools/base/logging.h" #include "ortools/base/strong_vector.h" #include "ortools/constraint_solver/routing_types.h" @@ -48,7 +49,7 @@ namespace operations_research { class RoutingIndexManager { public: typedef RoutingNodeIndex NodeIndex; - static const int64 kUnassigned; + static const int64_t kUnassigned; /// Creates a NodeIndex to variable index mapping for a problem containing /// 'num_nodes', 'num_vehicles' and the given starts and ends for each @@ -70,35 +71,35 @@ class RoutingIndexManager { // Returns the number of indices mapped to nodes. int num_indices() const { return index_to_node_.size(); } // Returns start and end indices of the given vehicle. - int64 GetStartIndex(int vehicle) const { return vehicle_to_start_[vehicle]; } - int64 GetEndIndex(int vehicle) const { return vehicle_to_end_[vehicle]; } + int64_t GetStartIndex(int vehicle) const { return vehicle_to_start_[vehicle]; } + int64_t GetEndIndex(int vehicle) const { return vehicle_to_end_[vehicle]; } // Returns the index of a node. A node can correspond to multiple indices if // it's a start or end node. As of 03/2020, kUnassigned will be returned for // all end nodes. If a node appears more than once as a start node, the index // of the first node in the list of start nodes is returned. - int64 NodeToIndex(NodeIndex node) const { + int64_t NodeToIndex(NodeIndex node) const { DCHECK_GE(node.value(), 0); DCHECK_LT(node.value(), node_to_index_.size()); return node_to_index_[node]; } // Same as NodeToIndex but for a given vector of nodes. - std::vector NodesToIndices(const std::vector& nodes) const; + std::vector NodesToIndices(const std::vector& nodes) const; // Returns the node corresponding to an index. A node may appear more than // once if it is used as the start or the end node of multiple vehicles. - NodeIndex IndexToNode(int64 index) const { + NodeIndex IndexToNode(int64_t index) const { DCHECK_GE(index, 0); DCHECK_LT(index, index_to_node_.size()); return index_to_node_[index]; } // Same as IndexToNode but for a given vector of indices. std::vector IndicesToNodes( - const std::vector& indices) const; + const std::vector& indices) const; // TODO(user) Add unit tests for NodesToIndices and IndicesToNodes. // TODO(user): Remove when removal of NodeIndex from RoutingModel is /// complete. int num_unique_depots() const { return num_unique_depots_; } std::vector GetIndexToNodeMap() const { return index_to_node_; } - absl::StrongVector GetNodeToIndexMap() const { + absl::StrongVector GetNodeToIndexMap() const { return node_to_index_; } @@ -108,9 +109,9 @@ class RoutingIndexManager { const std::vector >& starts_ends); std::vector index_to_node_; - absl::StrongVector node_to_index_; - std::vector vehicle_to_start_; - std::vector vehicle_to_end_; + absl::StrongVector node_to_index_; + std::vector vehicle_to_start_; + std::vector vehicle_to_end_; int num_nodes_; int num_vehicles_; int num_unique_depots_; diff --git a/ortools/constraint_solver/routing_lp_scheduling.cc b/ortools/constraint_solver/routing_lp_scheduling.cc index fdc3be10da..d1f4bcebec 100644 --- a/ortools/constraint_solver/routing_lp_scheduling.cc +++ b/ortools/constraint_solver/routing_lp_scheduling.cc @@ -13,15 +13,25 @@ #include "ortools/constraint_solver/routing_lp_scheduling.h" +#include +#include +#include +#include +#include +#include #include +#include +#include -#include "absl/container/flat_hash_set.h" -#include "absl/time/time.h" -#include "ortools/base/integral_types.h" -#include "ortools/base/map_util.h" +#include "absl/memory/memory.h" +#include "ortools/base/logging.h" +#include "ortools/base/mathutil.h" +#include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/routing.h" -#include "ortools/glop/lp_solver.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/glop/parameters.pb.h" #include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" namespace operations_research { @@ -43,8 +53,8 @@ glop::GlopParameters GetGlopParametersForGlobalLP() { } bool GetCumulBoundsWithOffset(const RoutingDimension& dimension, - int64 node_index, int64 cumul_offset, - int64* lower_bound, int64* upper_bound) { + int64_t node_index, int64_t cumul_offset, + int64_t* lower_bound, int64_t* upper_bound) { DCHECK(lower_bound != nullptr); DCHECK(upper_bound != nullptr); @@ -54,15 +64,15 @@ bool GetCumulBoundsWithOffset(const RoutingDimension& dimension, return false; } - const int64 first_after_offset = + const int64_t first_after_offset = std::max(dimension.GetFirstPossibleGreaterOrEqualValueForNode( node_index, cumul_offset), cumul_var.Min()); - DCHECK_LT(first_after_offset, kint64max); + DCHECK_LT(first_after_offset, std::numeric_limits::max()); *lower_bound = CapSub(first_after_offset, cumul_offset); DCHECK_GE(*lower_bound, 0); - if (*upper_bound == kint64max) { + if (*upper_bound == std::numeric_limits::max()) { return true; } *upper_bound = CapSub(*upper_bound, cumul_offset); @@ -70,20 +80,18 @@ bool GetCumulBoundsWithOffset(const RoutingDimension& dimension, return true; } -int64 GetFirstPossibleValueForCumulWithOffset(const RoutingDimension& dimension, - int64 node_index, - int64 lower_bound_without_offset, - int64 cumul_offset) { +int64_t GetFirstPossibleValueForCumulWithOffset( + const RoutingDimension& dimension, int64_t node_index, + int64_t lower_bound_without_offset, int64_t cumul_offset) { return CapSub( dimension.GetFirstPossibleGreaterOrEqualValueForNode( node_index, CapAdd(lower_bound_without_offset, cumul_offset)), cumul_offset); } -int64 GetLastPossibleValueForCumulWithOffset(const RoutingDimension& dimension, - int64 node_index, - int64 upper_bound_without_offset, - int64 cumul_offset) { +int64_t GetLastPossibleValueForCumulWithOffset( + const RoutingDimension& dimension, int64_t node_index, + int64_t upper_bound_without_offset, int64_t cumul_offset) { return CapSub( dimension.GetLastPossibleLessOrEqualValueForNode( node_index, CapAdd(upper_bound_without_offset, cumul_offset)), @@ -97,16 +105,16 @@ int64 GetLastPossibleValueForCumulWithOffset(const RoutingDimension& dimension, // sized and initialized to {-1, -1} for all pairs. void StoreVisitedPickupDeliveryPairsOnRoute( const RoutingDimension& dimension, int vehicle, - const std::function& next_accessor, + const std::function& next_accessor, std::vector* visited_pairs, - std::vector>* + std::vector>* visited_pickup_delivery_indices_for_pair) { // visited_pickup_delivery_indices_for_pair must be all {-1, -1}. DCHECK_EQ(visited_pickup_delivery_indices_for_pair->size(), dimension.model()->GetPickupAndDeliveryPairs().size()); DCHECK(std::all_of(visited_pickup_delivery_indices_for_pair->begin(), visited_pickup_delivery_indices_for_pair->end(), - [](std::pair p) { + [](std::pair p) { return p.first == -1 && p.second == -1; })); visited_pairs->clear(); @@ -115,7 +123,7 @@ void StoreVisitedPickupDeliveryPairsOnRoute( } const RoutingModel& model = *dimension.model(); - int64 node_index = model.Start(vehicle); + int64_t node_index = model.Start(vehicle); while (!model.IsEnd(node_index)) { const std::vector>& pickup_index_pairs = model.GetPickupIndexPairs(node_index); @@ -135,7 +143,7 @@ void StoreVisitedPickupDeliveryPairsOnRoute( // visited for this pair. DCHECK_EQ(delivery_index_pairs.size(), 1); const int pair_index = delivery_index_pairs[0].first; - std::pair& pickup_delivery_index = + std::pair& pickup_delivery_index = (*visited_pickup_delivery_indices_for_pair)[pair_index]; if (pickup_delivery_index.first < 0) { // This case should not happen, as a delivery must have its pickup @@ -179,8 +187,8 @@ LocalDimensionCumulOptimizer::LocalDimensionCumulOptimizer( } DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputeRouteCumulCost( - int vehicle, const std::function& next_accessor, - int64* optimal_cost) { + int vehicle, const std::function& next_accessor, + int64_t* optimal_cost) { return optimizer_core_.OptimizeSingleRoute(vehicle, next_accessor, solver_[vehicle].get(), nullptr, nullptr, optimal_cost, nullptr); @@ -188,10 +196,10 @@ DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputeRouteCumulCost( DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputeRouteCumulCostWithoutFixedTransits( - int vehicle, const std::function& next_accessor, - int64* optimal_cost_without_transits) { - int64 cost = 0; - int64 transit_cost = 0; + int vehicle, const std::function& next_accessor, + int64_t* optimal_cost_without_transits) { + int64_t cost = 0; + int64_t transit_cost = 0; const DimensionSchedulingStatus status = optimizer_core_.OptimizeSingleRoute( vehicle, next_accessor, solver_[vehicle].get(), nullptr, nullptr, &cost, &transit_cost); @@ -203,8 +211,9 @@ LocalDimensionCumulOptimizer::ComputeRouteCumulCostWithoutFixedTransits( } DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputeRouteCumuls( - int vehicle, const std::function& next_accessor, - std::vector* optimal_cumuls, std::vector* optimal_breaks) { + int vehicle, const std::function& next_accessor, + std::vector* optimal_cumuls, + std::vector* optimal_breaks) { return optimizer_core_.OptimizeSingleRoute( vehicle, next_accessor, solver_[vehicle].get(), optimal_cumuls, optimal_breaks, nullptr, nullptr); @@ -212,8 +221,8 @@ DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputeRouteCumuls( DimensionSchedulingStatus LocalDimensionCumulOptimizer::ComputePackedRouteCumuls( - int vehicle, const std::function& next_accessor, - std::vector* packed_cumuls, std::vector* packed_breaks) { + int vehicle, const std::function& next_accessor, + std::vector* packed_cumuls, std::vector* packed_breaks) { return optimizer_core_.OptimizeAndPackSingleRoute( vehicle, next_accessor, solver_[vehicle].get(), packed_cumuls, packed_breaks); @@ -233,7 +242,7 @@ CumulBoundsPropagator::CumulBoundsPropagator(const RoutingDimension* dimension) } void CumulBoundsPropagator::AddArcs(int first_index, int second_index, - int64 offset) { + int64_t offset) { // Add arc first_index + offset <= second_index outgoing_arcs_[PositiveNode(first_index)].push_back( {PositiveNode(second_index), offset}); @@ -245,29 +254,30 @@ void CumulBoundsPropagator::AddArcs(int first_index, int second_index, } bool CumulBoundsPropagator::InitializeArcsAndBounds( - const std::function& next_accessor, int64 cumul_offset) { - propagated_bounds_.assign(num_nodes_, kint64min); + const std::function& next_accessor, + int64_t cumul_offset) { + propagated_bounds_.assign(num_nodes_, std::numeric_limits::min()); for (std::vector& arcs : outgoing_arcs_) { arcs.clear(); } RoutingModel* const model = dimension_.model(); - std::vector& lower_bounds = propagated_bounds_; + std::vector& lower_bounds = propagated_bounds_; for (int vehicle = 0; vehicle < model->vehicles(); vehicle++) { - const std::function& transit_accessor = + const std::function& transit_accessor = dimension_.transit_evaluator(vehicle); int node = model->Start(vehicle); while (true) { - int64 cumul_lb, cumul_ub; + int64_t cumul_lb, cumul_ub; if (!GetCumulBoundsWithOffset(dimension_, node, cumul_offset, &cumul_lb, &cumul_ub)) { return false; } lower_bounds[PositiveNode(node)] = cumul_lb; - if (cumul_ub < kint64max) { + if (cumul_ub < std::numeric_limits::max()) { lower_bounds[NegativeNode(node)] = -cumul_ub; } @@ -276,12 +286,12 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( } const int next = next_accessor(node); - const int64 transit = transit_accessor(node, next); + const int64_t transit = transit_accessor(node, next); const IntVar& slack_var = *dimension_.SlackVar(node); // node + transit + slack_var == next // Add arcs for node + transit + slack_min <= next AddArcs(node, next, CapAdd(transit, slack_var.Min())); - if (slack_var.Max() < kint64max) { + if (slack_var.Max() < std::numeric_limits::max()) { // Add arcs for node + transit + slack_max >= next. AddArcs(next, node, CapSub(-slack_var.Max(), transit)); } @@ -290,8 +300,8 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( } // Add vehicle span upper bound: end - span_ub <= start. - const int64 span_ub = dimension_.GetSpanUpperBoundForVehicle(vehicle); - if (span_ub < kint64max) { + const int64_t span_ub = dimension_.GetSpanUpperBoundForVehicle(vehicle); + if (span_ub < std::numeric_limits::max()) { AddArcs(model->End(vehicle), model->Start(vehicle), -span_ub); } @@ -301,9 +311,9 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( dimension_, vehicle, next_accessor, &visited_pairs, &visited_pickup_delivery_indices_for_pair_); for (int pair_index : visited_pairs) { - const int64 pickup_index = + const int64_t pickup_index = visited_pickup_delivery_indices_for_pair_[pair_index].first; - const int64 delivery_index = + const int64_t delivery_index = visited_pickup_delivery_indices_for_pair_[pair_index].second; visited_pickup_delivery_indices_for_pair_[pair_index] = {-1, -1}; @@ -313,10 +323,10 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( continue; } - const int64 limit = dimension_.GetPickupToDeliveryLimitForPair( + const int64_t limit = dimension_.GetPickupToDeliveryLimitForPair( pair_index, model->GetPickupIndexPairs(pickup_index)[0].second, model->GetDeliveryIndexPairs(delivery_index)[0].second); - if (limit < kint64max) { + if (limit < std::numeric_limits::max()) { // delivery_cumul - limit <= pickup_cumul. AddArcs(delivery_index, pickup_index, -limit); } @@ -327,8 +337,10 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( dimension_.GetNodePrecedences()) { const int first_index = precedence.first_node; const int second_index = precedence.second_node; - if (lower_bounds[PositiveNode(first_index)] == kint64min || - lower_bounds[PositiveNode(second_index)] == kint64min) { + if (lower_bounds[PositiveNode(first_index)] == + std::numeric_limits::min() || + lower_bounds[PositiveNode(second_index)] == + std::numeric_limits::min()) { // One of the nodes is unperformed, so the precedence rule doesn't apply. continue; } @@ -339,8 +351,8 @@ bool CumulBoundsPropagator::InitializeArcsAndBounds( } bool CumulBoundsPropagator::UpdateCurrentLowerBoundOfNode(int node, - int64 new_lb, - int64 offset) { + int64_t new_lb, + int64_t offset) { const int cumul_var_index = node / 2; if (node == PositiveNode(cumul_var_index)) { @@ -349,17 +361,17 @@ bool CumulBoundsPropagator::UpdateCurrentLowerBoundOfNode(int node, dimension_, cumul_var_index, new_lb, offset); } else { // -new_lb is an upper bound of the cumul of variable 'cumul_var_index'. - const int64 new_ub = CapSub(0, new_lb); + const int64_t new_ub = CapSub(0, new_lb); propagated_bounds_[node] = CapSub(0, GetLastPossibleValueForCumulWithOffset( dimension_, cumul_var_index, new_ub, offset)); } // Test that the lower/upper bounds do not cross each other. - const int64 cumul_lower_bound = + const int64_t cumul_lower_bound = propagated_bounds_[PositiveNode(cumul_var_index)]; - const int64 negated_cumul_upper_bound = + const int64_t negated_cumul_upper_bound = propagated_bounds_[NegativeNode(cumul_var_index)]; return CapAdd(negated_cumul_upper_bound, cumul_lower_bound) <= 0; @@ -383,7 +395,8 @@ bool CumulBoundsPropagator::DisassembleSubtree(int source, int target) { } bool CumulBoundsPropagator::PropagateCumulBounds( - const std::function& next_accessor, int64 cumul_offset) { + const std::function& next_accessor, + int64_t cumul_offset) { tree_parent_node_of_.assign(num_nodes_, kNoParent); DCHECK(std::none_of(node_in_queue_.begin(), node_in_queue_.end(), [](bool b) { return b; })); @@ -393,7 +406,7 @@ bool CumulBoundsPropagator::PropagateCumulBounds( return CleanupAndReturnFalse(); } - std::vector& current_lb = propagated_bounds_; + std::vector& current_lb = propagated_bounds_; // Bellman-Ford-Tarjan algorithm. while (!bf_queue_.empty()) { @@ -407,13 +420,14 @@ bool CumulBoundsPropagator::PropagateCumulBounds( continue; } - const int64 lower_bound = current_lb[node]; + const int64_t lower_bound = current_lb[node]; for (const ArcInfo& arc : outgoing_arcs_[node]) { // NOTE: kint64min as a lower bound means no lower bound at all, so we // don't use this value to propagate. - const int64 induced_lb = (lower_bound == kint64min) - ? kint64min - : CapAdd(lower_bound, arc.offset); + const int64_t induced_lb = + (lower_bound == std::numeric_limits::min()) + ? std::numeric_limits::min() + : CapAdd(lower_bound, arc.offset); const int head_node = arc.head; if (induced_lb <= current_lb[head_node]) { @@ -460,9 +474,9 @@ DimensionCumulOptimizerCore::DimensionCumulOptimizerCore( } DimensionSchedulingStatus DimensionCumulOptimizerCore::OptimizeSingleRoute( - int vehicle, const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values, int64* cost, int64* transit_cost, + int vehicle, const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values, int64_t* cost, int64_t* transit_cost, bool clear_lp) { InitOptimizer(solver); // Make sure SetRouteCumulConstraints will properly set the cumul bounds by @@ -474,9 +488,9 @@ DimensionSchedulingStatus DimensionCumulOptimizerCore::OptimizeSingleRoute( (cumul_values != nullptr || cost != nullptr) && (!model->IsEnd(next_accessor(model->Start(vehicle))) || model->AreEmptyRouteCostsConsideredForVehicle(vehicle)); - const int64 cumul_offset = + const int64_t cumul_offset = dimension_->GetLocalOptimizerOffsetForVehicle(vehicle); - int64 cost_offset = 0; + int64_t cost_offset = 0; if (!SetRouteCumulConstraints(vehicle, next_accessor, cumul_offset, optimize_vehicle_costs, solver, transit_cost, &cost_offset)) { @@ -503,9 +517,9 @@ DimensionSchedulingStatus DimensionCumulOptimizerCore::OptimizeSingleRoute( } bool DimensionCumulOptimizerCore::Optimize( - const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values, int64* cost, int64* transit_cost, + const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values, int64_t* cost, int64_t* transit_cost, bool clear_lp) { InitOptimizer(solver); @@ -514,19 +528,19 @@ bool DimensionCumulOptimizerCore::Optimize( const bool optimize_costs = (cumul_values != nullptr) || (cost != nullptr); bool has_vehicles_being_optimized = false; - const int64 cumul_offset = dimension_->GetGlobalOptimizerOffset(); + const int64_t cumul_offset = dimension_->GetGlobalOptimizerOffset(); if (propagator_ != nullptr && !propagator_->PropagateCumulBounds(next_accessor, cumul_offset)) { return false; } - int64 total_transit_cost = 0; - int64 total_cost_offset = 0; + int64_t total_transit_cost = 0; + int64_t total_cost_offset = 0; const RoutingModel* model = dimension()->model(); for (int vehicle = 0; vehicle < model->vehicles(); vehicle++) { - int64 route_transit_cost = 0; - int64 route_cost_offset = 0; + int64_t route_transit_cost = 0; + int64_t route_cost_offset = 0; const bool optimize_vehicle_costs = optimize_costs && (!model->IsEnd(next_accessor(model->Start(vehicle))) || @@ -565,12 +579,12 @@ bool DimensionCumulOptimizerCore::Optimize( } bool DimensionCumulOptimizerCore::OptimizeAndPack( - const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values) { + const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values) { // Note: We pass a non-nullptr cost to the Optimize() method so the costs are // optimized by the LP. - int64 cost = 0; + int64_t cost = 0; if (!Optimize(next_accessor, solver, /*cumul_values=*/nullptr, /*break_values=*/nullptr, &cost, /*transit_cost=*/nullptr, /*clear_lp=*/false)) { @@ -583,7 +597,7 @@ bool DimensionCumulOptimizerCore::OptimizeAndPack( DimensionSchedulingStatus::INFEASIBLE) { return false; } - const int64 global_offset = dimension_->GetGlobalOptimizerOffset(); + const int64_t global_offset = dimension_->GetGlobalOptimizerOffset(); SetValuesFromLP(index_to_cumul_variable_, global_offset, solver, cumul_values); SetValuesFromLP(all_break_variables_, global_offset, solver, break_values); @@ -593,12 +607,12 @@ bool DimensionCumulOptimizerCore::OptimizeAndPack( DimensionSchedulingStatus DimensionCumulOptimizerCore::OptimizeAndPackSingleRoute( - int vehicle, const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values) { + int vehicle, const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values) { // Note: We pass a non-nullptr cost to the OptimizeSingleRoute() method so the // costs are optimized by the LP. - int64 cost = 0; + int64_t cost = 0; if (OptimizeSingleRoute(vehicle, next_accessor, solver, /*cumul_values=*/nullptr, /*break_values=*/nullptr, &cost, /*transit_cost=*/nullptr, @@ -610,7 +624,7 @@ DimensionCumulOptimizerCore::OptimizeAndPackSingleRoute( if (status == DimensionSchedulingStatus::INFEASIBLE) { return DimensionSchedulingStatus::INFEASIBLE; } - const int64 local_offset = + const int64_t local_offset = dimension_->GetLocalOptimizerOffsetForVehicle(vehicle); SetValuesFromLP(current_route_cumul_variables_, local_offset, solver, cumul_values); @@ -682,14 +696,14 @@ void DimensionCumulOptimizerCore::InitOptimizer( } bool DimensionCumulOptimizerCore::ComputeRouteCumulBounds( - const std::vector& route, const std::vector& fixed_transits, - int64 cumul_offset) { + const std::vector& route, + const std::vector& fixed_transits, int64_t cumul_offset) { const int route_size = route.size(); current_route_min_cumuls_.resize(route_size); current_route_max_cumuls_.resize(route_size); if (propagator_ != nullptr) { for (int pos = 0; pos < route_size; pos++) { - const int64 node = route[pos]; + const int64_t node = route[pos]; current_route_min_cumuls_[pos] = propagator_->CumulMin(node); DCHECK_GE(current_route_min_cumuls_[pos], 0); current_route_max_cumuls_[pos] = propagator_->CumulMax(node); @@ -710,7 +724,7 @@ bool DimensionCumulOptimizerCore::ComputeRouteCumulBounds( // Refine cumul bounds using // cumul[i+1] >= cumul[i] + fixed_transit[i] + slack[i]. for (int pos = 1; pos < route_size; ++pos) { - const int64 slack_min = dimension_->SlackVar(route[pos - 1])->Min(); + const int64_t slack_min = dimension_->SlackVar(route[pos - 1])->Min(); current_route_min_cumuls_[pos] = std::max( current_route_min_cumuls_[pos], CapAdd( @@ -726,8 +740,9 @@ bool DimensionCumulOptimizerCore::ComputeRouteCumulBounds( for (int pos = route_size - 2; pos >= 0; --pos) { // If cumul_max[pos+1] is kint64max, it will be translated to // double +infinity, so it must not constrain cumul_max[pos]. - if (current_route_max_cumuls_[pos + 1] < kint64max) { - const int64 slack_min = dimension_->SlackVar(route[pos])->Min(); + if (current_route_max_cumuls_[pos + 1] < + std::numeric_limits::max()) { + const int64_t slack_min = dimension_->SlackVar(route[pos])->Min(); current_route_max_cumuls_[pos] = std::min( current_route_max_cumuls_[pos], CapSub( @@ -745,12 +760,13 @@ bool DimensionCumulOptimizerCore::ComputeRouteCumulBounds( } bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( - int vehicle, const std::function& next_accessor, - int64 cumul_offset, bool optimize_costs, RoutingLinearSolverWrapper* solver, - int64* route_transit_cost, int64* route_cost_offset) { + int vehicle, const std::function& next_accessor, + int64_t cumul_offset, bool optimize_costs, + RoutingLinearSolverWrapper* solver, int64_t* route_transit_cost, + int64_t* route_cost_offset) { RoutingModel* const model = dimension_->model(); // Extract the vehicle's path from next_accessor. - std::vector path; + std::vector path; { int node = model->Start(vehicle); path.push_back(node); @@ -762,9 +778,9 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( } const int path_size = path.size(); - std::vector fixed_transit(path_size - 1); + std::vector fixed_transit(path_size - 1); { - const std::function& transit_accessor = + const std::function& transit_accessor = dimension_->transit_evaluator(vehicle); for (int pos = 1; pos < path_size; ++pos) { fixed_transit[pos - 1] = transit_accessor(path[pos - 1], path[pos]); @@ -790,8 +806,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( const SortedDisjointIntervalList& forbidden = dimension_->forbidden_intervals()[path[pos]]; if (forbidden.NumIntervals() > 0) { - std::vector starts; - std::vector ends; + std::vector starts; + std::vector ends; for (const ClosedInterval interval : dimension_->GetAllowedIntervalsInRange( path[pos], CapAdd(current_route_min_cumuls_[pos], cumul_offset), @@ -829,16 +845,16 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // Add soft upper bounds. for (int pos = 0; pos < path_size; ++pos) { if (!dimension_->HasCumulVarSoftUpperBound(path[pos])) continue; - const int64 coef = + const int64_t coef = dimension_->GetCumulVarSoftUpperBoundCoefficient(path[pos]); if (coef == 0) continue; - int64 bound = dimension_->GetCumulVarSoftUpperBound(path[pos]); + int64_t bound = dimension_->GetCumulVarSoftUpperBound(path[pos]); if (bound < cumul_offset && route_cost_offset != nullptr) { // Add coef * (cumul_offset - bound) to the cost offset. *route_cost_offset = CapAdd(*route_cost_offset, CapProd(CapSub(cumul_offset, bound), coef)); } - bound = std::max(0, CapSub(bound, cumul_offset)); + bound = std::max(0, CapSub(bound, cumul_offset)); if (current_route_max_cumuls_[pos] <= bound) { // constraint is never violated. continue; @@ -846,17 +862,18 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( const int soft_ub_diff = solver->CreateNewPositiveVariable(); solver->SetObjectiveCoefficient(soft_ub_diff, coef); // cumul - soft_ub_diff <= bound. - const int ct = solver->CreateNewConstraint(kint64min, bound); + const int ct = solver->CreateNewConstraint( + std::numeric_limits::min(), bound); solver->SetCoefficient(ct, lp_cumuls[pos], 1); solver->SetCoefficient(ct, soft_ub_diff, -1); } // Add soft lower bounds. for (int pos = 0; pos < path_size; ++pos) { if (!dimension_->HasCumulVarSoftLowerBound(path[pos])) continue; - const int64 coef = + const int64_t coef = dimension_->GetCumulVarSoftLowerBoundCoefficient(path[pos]); if (coef == 0) continue; - const int64 bound = std::max( + const int64_t bound = std::max( 0, CapSub(dimension_->GetCumulVarSoftLowerBound(path[pos]), cumul_offset)); if (current_route_min_cumuls_[pos] >= bound) { @@ -866,7 +883,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( const int soft_lb_diff = solver->CreateNewPositiveVariable(); solver->SetObjectiveCoefficient(soft_lb_diff, coef); // bound - cumul <= soft_lb_diff - const int ct = solver->CreateNewConstraint(bound, kint64max); + const int ct = solver->CreateNewConstraint( + bound, std::numeric_limits::max()); solver->SetCoefficient(ct, lp_cumuls[pos], 1); solver->SetCoefficient(ct, soft_lb_diff, 1); } @@ -877,9 +895,9 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( *dimension_, vehicle, next_accessor, &visited_pairs, &visited_pickup_delivery_indices_for_pair_); for (int pair_index : visited_pairs) { - const int64 pickup_index = + const int64_t pickup_index = visited_pickup_delivery_indices_for_pair_[pair_index].first; - const int64 delivery_index = + const int64_t delivery_index = visited_pickup_delivery_indices_for_pair_[pair_index].second; visited_pickup_delivery_indices_for_pair_[pair_index] = {-1, -1}; @@ -889,27 +907,29 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( continue; } - const int64 limit = dimension_->GetPickupToDeliveryLimitForPair( + const int64_t limit = dimension_->GetPickupToDeliveryLimitForPair( pair_index, model->GetPickupIndexPairs(pickup_index)[0].second, model->GetDeliveryIndexPairs(delivery_index)[0].second); - if (limit < kint64max) { + if (limit < std::numeric_limits::max()) { // delivery_cumul - pickup_cumul <= limit. - const int ct = solver->CreateNewConstraint(kint64min, limit); + const int ct = solver->CreateNewConstraint( + std::numeric_limits::min(), limit); solver->SetCoefficient(ct, index_to_cumul_variable_[delivery_index], 1); solver->SetCoefficient(ct, index_to_cumul_variable_[pickup_index], -1); } } // Add span bound constraint. - const int64 span_bound = dimension_->GetSpanUpperBoundForVehicle(vehicle); - if (span_bound < kint64max) { + const int64_t span_bound = dimension_->GetSpanUpperBoundForVehicle(vehicle); + if (span_bound < std::numeric_limits::max()) { // end_cumul - start_cumul <= bound - const int ct = solver->CreateNewConstraint(kint64min, span_bound); + const int ct = solver->CreateNewConstraint( + std::numeric_limits::min(), span_bound); solver->SetCoefficient(ct, lp_cumuls.back(), 1); solver->SetCoefficient(ct, lp_cumuls.front(), -1); } // Add span cost. - const int64 span_cost_coef = + const int64_t span_cost_coef = dimension_->GetSpanCostCoefficientForVehicle(vehicle); if (optimize_costs && span_cost_coef > 0) { solver->SetObjectiveCoefficient(lp_cumuls.back(), span_cost_coef); @@ -919,11 +939,12 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( if (optimize_costs && dimension_->HasSoftSpanUpperBounds()) { SimpleBoundCosts::BoundCost bound_cost = dimension_->GetSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.bound < kint64max && bound_cost.cost > 0) { + if (bound_cost.bound < std::numeric_limits::max() && + bound_cost.cost > 0) { const int span_violation = solver->CreateNewPositiveVariable(); // end - start <= bound + span_violation - const int violation = - solver->CreateNewConstraint(kint64min, bound_cost.bound); + const int violation = solver->CreateNewConstraint( + std::numeric_limits::min(), bound_cost.bound); solver->SetCoefficient(violation, lp_cumuls.back(), 1.0); solver->SetCoefficient(violation, lp_cumuls.front(), -1.0); solver->SetCoefficient(violation, span_violation, -1.0); @@ -934,18 +955,19 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // Add global span constraint. if (optimize_costs && dimension_->global_span_cost_coefficient() > 0) { // min_start_cumul_ <= cumuls[start] - int ct = solver->CreateNewConstraint(kint64min, 0); + int ct = + solver->CreateNewConstraint(std::numeric_limits::min(), 0); solver->SetCoefficient(ct, min_start_cumul_, 1); solver->SetCoefficient(ct, lp_cumuls.front(), -1); // max_end_cumul_ >= cumuls[end] - ct = solver->CreateNewConstraint(0, kint64max); + ct = solver->CreateNewConstraint(0, std::numeric_limits::max()); solver->SetCoefficient(ct, max_end_cumul_, 1); solver->SetCoefficient(ct, lp_cumuls.back(), -1); } // Fill transit cost if specified. if (route_transit_cost != nullptr) { if (optimize_costs && span_cost_coef > 0) { - const int64 total_fixed_transit = std::accumulate( + const int64_t total_fixed_transit = std::accumulate( fixed_transit.begin(), fixed_transit.end(), 0, CapAdd); *route_transit_cost = CapProd(total_fixed_transit, span_cost_coef); } else { @@ -966,14 +988,15 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // and it reduces to a span maximum. // TODO(user): Also add the case where no breaks can intersect the route. if (num_breaks == 0) { - int64 maximum_route_span = kint64max; + int64_t maximum_route_span = std::numeric_limits::max(); for (const auto& distance_duration : dimension_->GetBreakDistanceDurationOfVehicle(vehicle)) { maximum_route_span = std::min(maximum_route_span, distance_duration.first); } - if (maximum_route_span < kint64max) { - const int ct = solver->CreateNewConstraint(kint64min, maximum_route_span); + if (maximum_route_span < std::numeric_limits::max()) { + const int ct = solver->CreateNewConstraint( + std::numeric_limits::min(), maximum_route_span); solver->SetCoefficient(ct, lp_cumuls.back(), 1); solver->SetCoefficient(ct, lp_cumuls.front(), -1); } @@ -982,8 +1005,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // Gather visit information: the visit of node i has [start, end) = // [cumul[i] - post_travel[i-1], cumul[i] + pre_travel[i]). // Breaks cannot overlap those visit intervals. - std::vector pre_travel(path_size - 1, 0); - std::vector post_travel(path_size - 1, 0); + std::vector pre_travel(path_size - 1, 0); + std::vector post_travel(path_size - 1, 0); { const int pre_travel_index = dimension_->GetPreTravelEvaluatorOfVehicle(vehicle); @@ -1014,21 +1037,21 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( std::vector slack_exact_lower_bound_ct(path_size - 1, -1); std::vector slack_linear_lower_bound_ct(path_size - 1, -1); - const int64 vehicle_start_min = current_route_min_cumuls_.front(); - const int64 vehicle_start_max = current_route_max_cumuls_.front(); - const int64 vehicle_end_min = current_route_min_cumuls_.back(); - const int64 vehicle_end_max = current_route_max_cumuls_.back(); + const int64_t vehicle_start_min = current_route_min_cumuls_.front(); + const int64_t vehicle_start_max = current_route_max_cumuls_.front(); + const int64_t vehicle_end_min = current_route_min_cumuls_.back(); + const int64_t vehicle_end_max = current_route_max_cumuls_.back(); const int all_break_variables_offset = vehicle_to_all_break_variables_offset_[vehicle]; for (int br = 0; br < num_breaks; ++br) { const IntervalVar& break_var = *breaks[br]; if (!break_var.MustBePerformed()) continue; - const int64 break_start_min = CapSub(break_var.StartMin(), cumul_offset); - const int64 break_start_max = CapSub(break_var.StartMax(), cumul_offset); - const int64 break_end_min = CapSub(break_var.EndMin(), cumul_offset); - const int64 break_end_max = CapSub(break_var.EndMax(), cumul_offset); - const int64 break_duration_min = break_var.DurationMin(); - const int64 break_duration_max = break_var.DurationMax(); + const int64_t break_start_min = CapSub(break_var.StartMin(), cumul_offset); + const int64_t break_start_max = CapSub(break_var.StartMax(), cumul_offset); + const int64_t break_end_min = CapSub(break_var.EndMin(), cumul_offset); + const int64_t break_end_max = CapSub(break_var.EndMax(), cumul_offset); + const int64_t break_duration_min = break_var.DurationMin(); + const int64_t break_duration_max = break_var.DurationMax(); // The CPSAT solver encodes all breaks that can intersect the route, // the LP solver only encodes the breaks that must intersect the route. if (solver->IsCPSATSolver()) { @@ -1073,7 +1096,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // Break can be before route. if (break_end_min <= vehicle_start_max) { const int ct = solver->AddLinearConstraint( - 0, kint64max, {{lp_cumuls.front(), 1}, {lp_break_end[br], -1}}); + 0, std::numeric_limits::max(), + {{lp_cumuls.front(), 1}, {lp_break_end[br], -1}}); const int break_is_before_route = solver->AddVariable(0, 1); solver->SetEnforcementLiteral(ct, break_is_before_route); solver->SetCoefficient(break_in_one_slack_ct, break_is_before_route, 1); @@ -1081,7 +1105,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // Break can be after route. if (vehicle_end_min <= break_start_max) { const int ct = solver->AddLinearConstraint( - 0, kint64max, {{lp_break_start[br], 1}, {lp_cumuls.back(), -1}}); + 0, std::numeric_limits::max(), + {{lp_break_start[br], 1}, {lp_cumuls.back(), -1}}); const int break_is_after_route = solver->AddVariable(0, 1); solver->SetEnforcementLiteral(ct, break_is_after_route); solver->SetCoefficient(break_in_one_slack_ct, break_is_after_route, 1); @@ -1092,13 +1117,13 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( for (int pos = 0; pos < path_size - 1; ++pos) { // Pass on slacks that cannot start before, cannot end after, // or are not long enough to contain the break. - const int64 slack_start_min = + const int64_t slack_start_min = CapAdd(current_route_min_cumuls_[pos], pre_travel[pos]); if (slack_start_min > break_start_max) break; - const int64 slack_end_max = + const int64_t slack_end_max = CapSub(current_route_max_cumuls_[pos + 1], post_travel[pos]); if (break_end_min > slack_end_max) continue; - const int64 slack_duration_max = + const int64_t slack_duration_max = std::min(CapSub(CapSub(current_route_max_cumuls_[pos + 1], current_route_min_cumuls_[pos]), fixed_transit[pos]), @@ -1113,8 +1138,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( const int break_in_slack = solver->AddVariable(0, 1); solver->SetCoefficient(break_in_one_slack_ct, break_in_slack, 1); if (slack_linear_lower_bound_ct[pos] == -1) { - slack_linear_lower_bound_ct[pos] = - solver->AddLinearConstraint(kint64min, 0, {{lp_slacks[pos], -1}}); + slack_linear_lower_bound_ct[pos] = solver->AddLinearConstraint( + std::numeric_limits::min(), 0, {{lp_slacks[pos], -1}}); } solver->SetCoefficient(slack_linear_lower_bound_ct[pos], break_in_slack, break_duration_min); @@ -1128,21 +1153,21 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( solver->AddProductConstraint(break_duration_in_slack, {break_in_slack, lp_break_duration[br]}); if (slack_exact_lower_bound_ct[pos] == -1) { - slack_exact_lower_bound_ct[pos] = - solver->AddLinearConstraint(kint64min, 0, {{lp_slacks[pos], -1}}); + slack_exact_lower_bound_ct[pos] = solver->AddLinearConstraint( + std::numeric_limits::min(), 0, {{lp_slacks[pos], -1}}); } solver->SetCoefficient(slack_exact_lower_bound_ct[pos], break_duration_in_slack, 1); // If break_in_slack_i == 1, then // 1) break_start >= cumul[pos] + pre_travel[pos] const int break_start_after_current_ct = solver->AddLinearConstraint( - pre_travel[pos], kint64max, + pre_travel[pos], std::numeric_limits::max(), {{lp_break_start[br], 1}, {lp_cumuls[pos], -1}}); solver->SetEnforcementLiteral(break_start_after_current_ct, break_in_slack); // 2) break_end <= cumul[pos+1] - post_travel[pos] const int break_ends_before_next_ct = solver->AddLinearConstraint( - post_travel[pos], kint64max, + post_travel[pos], std::numeric_limits::max(), {{lp_cumuls[pos + 1], 1}, {lp_break_end[br], -1}}); solver->SetEnforcementLiteral(break_ends_before_next_ct, break_in_slack); @@ -1161,13 +1186,14 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( // When this feature is used, breaks are in sorted order. for (int br = 1; br < num_breaks; ++br) { solver->AddLinearConstraint( - 0, kint64max, {{lp_break_end[br - 1], -1}, {lp_break_start[br], 1}}); + 0, std::numeric_limits::max(), + {{lp_break_end[br - 1], -1}, {lp_break_start[br], 1}}); } } for (const auto& distance_duration : dimension_->GetBreakDistanceDurationOfVehicle(vehicle)) { - const int64 limit = distance_duration.first; - const int64 min_break_duration = distance_duration.second; + const int64_t limit = distance_duration.first; + const int64_t min_break_duration = distance_duration.second; // Interbreak limit constraint: breaks are interpreted as being in sorted // order, and the maximum duration between two consecutive // breaks of duration more than 'min_break_duration' is 'limit'. This @@ -1201,8 +1227,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( {{previous_cover, 1}, {lp_cumuls.front(), -1}}); for (int br = 0; br < num_breaks; ++br) { if (lp_break_start[br] == -1) continue; - const int64 break_end_min = CapSub(breaks[br]->EndMin(), cumul_offset); - const int64 break_end_max = CapSub(breaks[br]->EndMax(), cumul_offset); + const int64_t break_end_min = CapSub(breaks[br]->EndMin(), cumul_offset); + const int64_t break_end_max = CapSub(breaks[br]->EndMax(), cumul_offset); // break_is_eligible <=> // break_end - break_start >= break_minimum_duration. const int break_is_eligible = solver->AddVariable(0, 1); @@ -1211,11 +1237,11 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( solver->AddLinearConstraint( 1, 1, {{break_is_eligible, 1}, {break_is_not_eligible, 1}}); const int positive_ct = solver->AddLinearConstraint( - min_break_duration, kint64max, + min_break_duration, std::numeric_limits::max(), {{lp_break_end[br], 1}, {lp_break_start[br], -1}}); solver->SetEnforcementLiteral(positive_ct, break_is_eligible); const int negative_ct = solver->AddLinearConstraint( - kint64min, min_break_duration - 1, + std::numeric_limits::min(), min_break_duration - 1, {{lp_break_end[br], 1}, {lp_break_start[br], -1}}); solver->SetEnforcementLiteral(negative_ct, break_is_not_eligible); } @@ -1236,20 +1262,23 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints( solver->SetEnforcementLiteral(empty_cover_ct, break_is_not_eligible); const int cover = - solver->AddVariable(CapAdd(vehicle_start_min, limit), kint64max); + solver->AddVariable(CapAdd(vehicle_start_min, limit), + std::numeric_limits::max()); solver->AddMaximumConstraint(cover, {previous_cover, break_cover}); // Cover chaining. If route end is not covered, break start must be: // cover_{i-1} < route_end => s_i <= cover_{i-1} const int route_end_is_not_covered = solver->AddReifiedLinearConstraint( - 1, kint64max, {{lp_cumuls.back(), 1}, {previous_cover, -1}}); + 1, std::numeric_limits::max(), + {{lp_cumuls.back(), 1}, {previous_cover, -1}}); const int break_start_cover_ct = solver->AddLinearConstraint( - 0, kint64max, {{previous_cover, 1}, {lp_break_start[br], -1}}); + 0, std::numeric_limits::max(), + {{previous_cover, 1}, {lp_break_start[br], -1}}); solver->SetEnforcementLiteral(break_start_cover_ct, route_end_is_not_covered); previous_cover = cover; } - solver->AddLinearConstraint(0, kint64max, + solver->AddLinearConstraint(0, std::numeric_limits::max(), {{previous_cover, 1}, {lp_cumuls.back(), -1}}); } @@ -1260,7 +1289,7 @@ void DimensionCumulOptimizerCore::SetGlobalConstraints( bool optimize_costs, RoutingLinearSolverWrapper* solver) { // Global span cost = // global_span_cost_coefficient * (max_end_cumul - min_start_cumul). - const int64 global_span_coeff = dimension_->global_span_cost_coefficient(); + const int64_t global_span_coeff = dimension_->global_span_cost_coefficient(); if (optimize_costs && global_span_coeff > 0) { solver->SetObjectiveCoefficient(max_end_cumul_, global_span_coeff); solver->SetObjectiveCoefficient(min_start_cumul_, -global_span_coeff); @@ -1282,24 +1311,25 @@ void DimensionCumulOptimizerCore::SetGlobalConstraints( << " has a self-precedence on node " << precedence.first_node << "."; // cumul[second_node] - cumul[first_node] >= offset. - const int ct = solver->CreateNewConstraint(precedence.offset, kint64max); + const int ct = solver->CreateNewConstraint( + precedence.offset, std::numeric_limits::max()); solver->SetCoefficient(ct, second_cumul_var, 1); solver->SetCoefficient(ct, first_cumul_var, -1); } } void DimensionCumulOptimizerCore::SetValuesFromLP( - const std::vector& lp_variables, int64 offset, - RoutingLinearSolverWrapper* solver, std::vector* lp_values) { + const std::vector& lp_variables, int64_t offset, + RoutingLinearSolverWrapper* solver, std::vector* lp_values) { if (lp_values == nullptr) return; - lp_values->assign(lp_variables.size(), kint64min); + lp_values->assign(lp_variables.size(), std::numeric_limits::min()); for (int i = 0; i < lp_variables.size(); i++) { const int cumul_var = lp_variables[i]; if (cumul_var < 0) continue; // Keep default value, kint64min. const double lp_value_double = solver->GetValue(cumul_var); - const int64 lp_value_int64 = - (lp_value_double >= kint64max) - ? kint64max + const int64_t lp_value_int64 = + (lp_value_double >= std::numeric_limits::max()) + ? std::numeric_limits::max() : MathUtil::FastInt64Round(lp_value_double); (*lp_values)[i] = CapAdd(lp_value_int64, offset); } @@ -1315,10 +1345,10 @@ GlobalDimensionCumulOptimizer::GlobalDimensionCumulOptimizer( } bool GlobalDimensionCumulOptimizer::ComputeCumulCostWithoutFixedTransits( - const std::function& next_accessor, - int64* optimal_cost_without_transits) { - int64 cost = 0; - int64 transit_cost = 0; + const std::function& next_accessor, + int64_t* optimal_cost_without_transits) { + int64_t cost = 0; + int64_t transit_cost = 0; if (optimizer_core_.Optimize(next_accessor, solver_.get(), nullptr, nullptr, &cost, &transit_cost)) { if (optimal_cost_without_transits != nullptr) { @@ -1330,21 +1360,22 @@ bool GlobalDimensionCumulOptimizer::ComputeCumulCostWithoutFixedTransits( } bool GlobalDimensionCumulOptimizer::ComputeCumuls( - const std::function& next_accessor, - std::vector* optimal_cumuls, std::vector* optimal_breaks) { + const std::function& next_accessor, + std::vector* optimal_cumuls, + std::vector* optimal_breaks) { return optimizer_core_.Optimize(next_accessor, solver_.get(), optimal_cumuls, optimal_breaks, nullptr, nullptr); } bool GlobalDimensionCumulOptimizer::IsFeasible( - const std::function& next_accessor) { + const std::function& next_accessor) { return optimizer_core_.Optimize(next_accessor, solver_.get(), nullptr, nullptr, nullptr, nullptr); } bool GlobalDimensionCumulOptimizer::ComputePackedCumuls( - const std::function& next_accessor, - std::vector* packed_cumuls, std::vector* packed_breaks) { + const std::function& next_accessor, + std::vector* packed_cumuls, std::vector* packed_breaks) { return optimizer_core_.OptimizeAndPack(next_accessor, solver_.get(), packed_cumuls, packed_breaks); } diff --git a/ortools/constraint_solver/routing_lp_scheduling.h b/ortools/constraint_solver/routing_lp_scheduling.h index 27c21ab4fb..eba29cc5ae 100644 --- a/ortools/constraint_solver/routing_lp_scheduling.h +++ b/ortools/constraint_solver/routing_lp_scheduling.h @@ -14,15 +14,34 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "absl/container/flat_hash_map.h" #include "absl/memory/memory.h" +#include "absl/time/time.h" +#include "ortools/base/logging.h" #include "ortools/base/mathutil.h" #include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" #include "ortools/glop/lp_solver.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/lp_data/lp_data.h" #include "ortools/lp_data/lp_types.h" -#include "ortools/sat/cp_model.h" #include "ortools/sat/cp_model.pb.h" +#include "ortools/sat/cp_model_solver.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_parameters.pb.h" #include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" namespace operations_research { @@ -41,16 +60,19 @@ class CumulBoundsPropagator { // Returns false iff the precedences are infeasible with the given routes. // Otherwise, the user can call CumulMin() and CumulMax() to retrieve the new // bounds of an index. - bool PropagateCumulBounds(const std::function& next_accessor, - int64 cumul_offset); + bool PropagateCumulBounds( + const std::function& next_accessor, + int64_t cumul_offset); - int64 CumulMin(int index) const { + int64_t CumulMin(int index) const { return propagated_bounds_[PositiveNode(index)]; } - int64 CumulMax(int index) const { - const int64 negated_upper_bound = propagated_bounds_[NegativeNode(index)]; - return negated_upper_bound == kint64min ? kint64max : -negated_upper_bound; + int64_t CumulMax(int index) const { + const int64_t negated_upper_bound = propagated_bounds_[NegativeNode(index)]; + return negated_upper_bound == std::numeric_limits::min() + ? std::numeric_limits::max() + : -negated_upper_bound; } const RoutingDimension& dimension() const { return dimension_; } @@ -61,7 +83,7 @@ class CumulBoundsPropagator { // As arcs are stored by tail, we don't store it in the struct. struct ArcInfo { int head; - int64 offset; + int64_t offset; }; static const int kNoParent; static const int kParentToBePropagated; @@ -81,12 +103,13 @@ class CumulBoundsPropagator { // Adds the relation first_index + offset <= second_index, by adding arcs // first_index --offset--> second_index and // -second_index --offset--> -first_index. - void AddArcs(int first_index, int second_index, int64 offset); + void AddArcs(int first_index, int second_index, int64_t offset); - bool InitializeArcsAndBounds(const std::function& next_accessor, - int64 cumul_offset); + bool InitializeArcsAndBounds( + const std::function& next_accessor, + int64_t cumul_offset); - bool UpdateCurrentLowerBoundOfNode(int node, int64 new_lb, int64 offset); + bool UpdateCurrentLowerBoundOfNode(int node, int64_t new_lb, int64_t offset); bool DisassembleSubtree(int source, int target); @@ -100,7 +123,7 @@ class CumulBoundsPropagator { } const RoutingDimension& dimension_; - const int64 num_nodes_; + const int64_t num_nodes_; // TODO(user): Investigate if all arcs for a given tail can be created // at the same time, in which case outgoing_arcs_ could point to an absl::Span @@ -113,13 +136,13 @@ class CumulBoundsPropagator { // After calling PropagateCumulBounds(), for each node index n, // propagated_bounds_[2*n] and -propagated_bounds_[2*n+1] respectively contain // the propagated lower and upper bounds of n's cumul variable. - std::vector propagated_bounds_; + std::vector propagated_bounds_; // Vector used in DisassembleSubtree() to avoid memory reallocation. std::vector tmp_dfs_stack_; // Used to store the pickup/delivery pairs encountered on the routes. - std::vector> + std::vector> visited_pickup_delivery_indices_for_pair_; }; @@ -138,29 +161,29 @@ class RoutingLinearSolverWrapper { virtual ~RoutingLinearSolverWrapper() {} virtual void Clear() = 0; virtual int CreateNewPositiveVariable() = 0; - virtual bool SetVariableBounds(int index, int64 lower_bound, - int64 upper_bound) = 0; + virtual bool SetVariableBounds(int index, int64_t lower_bound, + int64_t upper_bound) = 0; virtual void SetVariableDisjointBounds(int index, - const std::vector& starts, - const std::vector& ends) = 0; - virtual int64 GetVariableLowerBound(int index) const = 0; + const std::vector& starts, + const std::vector& ends) = 0; + virtual int64_t GetVariableLowerBound(int index) const = 0; virtual void SetObjectiveCoefficient(int index, double coefficient) = 0; virtual double GetObjectiveCoefficient(int index) const = 0; virtual void ClearObjective() = 0; virtual int NumVariables() const = 0; - virtual int CreateNewConstraint(int64 lower_bound, int64 upper_bound) = 0; + virtual int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) = 0; virtual void SetCoefficient(int ct, int index, double coefficient) = 0; virtual bool IsCPSATSolver() = 0; virtual void AddMaximumConstraint(int max_var, std::vector vars) = 0; virtual void AddProductConstraint(int product_var, std::vector vars) = 0; virtual void SetEnforcementLiteral(int ct, int condition) = 0; virtual DimensionSchedulingStatus Solve(absl::Duration duration_limit) = 0; - virtual int64 GetObjectiveValue() const = 0; + virtual int64_t GetObjectiveValue() const = 0; virtual double GetValue(int index) const = 0; virtual bool SolutionIsInteger() const = 0; // Adds a variable with bounds [lower_bound, upper_bound]. - int AddVariable(int64 lower_bound, int64 upper_bound) { + int AddVariable(int64_t lower_bound, int64_t upper_bound) { CHECK_LE(lower_bound, upper_bound); const int variable = CreateNewPositiveVariable(); SetVariableBounds(variable, lower_bound, upper_bound); @@ -170,7 +193,7 @@ class RoutingLinearSolverWrapper { // lower_bound <= sum variable * coeff <= upper_bound, // and returns the identifier of that constraint. int AddLinearConstraint( - int64 lower_bound, int64 upper_bound, + int64_t lower_bound, int64_t upper_bound, const std::vector>& variable_coeffs) { CHECK_LE(lower_bound, upper_bound); const int ct = CreateNewConstraint(lower_bound, upper_bound); @@ -183,21 +206,23 @@ class RoutingLinearSolverWrapper { // lower_bound <= sum variable * coeff <= upper_bound, // and returns the identifier of that variable. int AddReifiedLinearConstraint( - int64 lower_bound, int64 upper_bound, + int64_t lower_bound, int64_t upper_bound, const std::vector>& weighted_variables) { const int reification_ct = AddLinearConstraint(1, 1, {}); - if (kint64min < lower_bound) { + if (std::numeric_limits::min() < lower_bound) { const int under_lower_bound = AddVariable(0, 1); SetCoefficient(reification_ct, under_lower_bound, 1); const int under_lower_bound_ct = - AddLinearConstraint(kint64min, lower_bound - 1, weighted_variables); + AddLinearConstraint(std::numeric_limits::min(), + lower_bound - 1, weighted_variables); SetEnforcementLiteral(under_lower_bound_ct, under_lower_bound); } - if (upper_bound < kint64max) { + if (upper_bound < std::numeric_limits::max()) { const int above_upper_bound = AddVariable(0, 1); SetCoefficient(reification_ct, above_upper_bound, 1); - const int above_upper_bound_ct = - AddLinearConstraint(upper_bound + 1, kint64max, weighted_variables); + const int above_upper_bound_ct = AddLinearConstraint( + upper_bound + 1, std::numeric_limits::max(), + weighted_variables); SetEnforcementLiteral(above_upper_bound_ct, above_upper_bound); } const int within_bounds = AddVariable(0, 1); @@ -223,13 +248,13 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { int CreateNewPositiveVariable() override { return linear_program_.CreateNewVariable().value(); } - bool SetVariableBounds(int index, int64 lower_bound, - int64 upper_bound) override { + bool SetVariableBounds(int index, int64_t lower_bound, + int64_t upper_bound) override { DCHECK_GE(lower_bound, 0); // When variable upper bounds are greater than this threshold, precision // issues arise in GLOP. In this case we are just going to suppose that // these high bound values are infinite and not set the upper bound. - const int64 kMaxValue = 1e10; + const int64_t kMaxValue = 1e10; const double lp_min = lower_bound; const double lp_max = (upper_bound > kMaxValue) ? glop::kInfinity : upper_bound; @@ -241,8 +266,8 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { // lp_min > lp_max case, so we must detect infeasibility here. return false; } - void SetVariableDisjointBounds(int index, const std::vector& starts, - const std::vector& ends) override { + void SetVariableDisjointBounds(int index, const std::vector& starts, + const std::vector& ends) override { // TODO(user): Investigate if we can avoid rebuilding the interval list // each time (we could keep a reference to the forbidden interval list in // RoutingDimension but we would need to store cumul offsets and use them @@ -250,7 +275,7 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { allowed_intervals_[index] = absl::make_unique(starts, ends); } - int64 GetVariableLowerBound(int index) const override { + int64_t GetVariableLowerBound(int index) const override { return linear_program_.variable_lower_bounds()[glop::ColIndex(index)]; } void SetObjectiveCoefficient(int index, double coefficient) override { @@ -267,11 +292,14 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { int NumVariables() const override { return linear_program_.num_variables().value(); } - int CreateNewConstraint(int64 lower_bound, int64 upper_bound) override { + int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override { const glop::RowIndex ct = linear_program_.CreateNewConstraint(); linear_program_.SetConstraintBounds( - ct, (lower_bound == kint64min) ? -glop::kInfinity : lower_bound, - (upper_bound == kint64max) ? glop::kInfinity : upper_bound); + ct, + (lower_bound == std::numeric_limits::min()) ? -glop::kInfinity + : lower_bound, + (upper_bound == std::numeric_limits::max()) ? glop::kInfinity + : upper_bound); return ct.value(); } void SetCoefficient(int ct, int index, double coefficient) override { @@ -301,9 +329,10 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { } for (const auto& allowed_interval : allowed_intervals_) { const double value_double = GetValue(allowed_interval.first); - const int64 value = (value_double >= kint64max) - ? kint64max - : MathUtil::FastInt64Round(value_double); + const int64_t value = + (value_double >= std::numeric_limits::max()) + ? std::numeric_limits::max() + : MathUtil::FastInt64Round(value_double); const SortedDisjointIntervalList* const interval_list = allowed_interval.second.get(); const auto it = interval_list->FirstIntervalGreaterOrEqual(value); @@ -313,7 +342,7 @@ class RoutingGlopWrapper : public RoutingLinearSolverWrapper { } return DimensionSchedulingStatus::OPTIMAL; } - int64 GetObjectiveValue() const override { + int64_t GetObjectiveValue() const override { return MathUtil::FastInt64Round(lp_solver_.GetObjectiveValue()); } double GetValue(int index) const override { @@ -360,20 +389,20 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { } sat::IntegerVariableProto* const variable = model_.add_variables(); variable->add_domain(0); - variable->add_domain(static_cast(parameters_.mip_max_bound())); + variable->add_domain(static_cast(parameters_.mip_max_bound())); return index; } - bool SetVariableBounds(int index, int64 lower_bound, - int64 upper_bound) override { + bool SetVariableBounds(int index, int64_t lower_bound, + int64_t upper_bound) override { DCHECK_GE(lower_bound, 0); // TODO(user): Find whether there is a way to make the offsetting // system work with other CP-SAT constraints than linear constraints. // variable_offset_[index] = lower_bound; variable_offset_[index] = 0; - const int64 offset_upper_bound = - std::min(CapSub(upper_bound, variable_offset_[index]), - parameters_.mip_max_bound()); - const int64 offset_lower_bound = + const int64_t offset_upper_bound = + std::min(CapSub(upper_bound, variable_offset_[index]), + parameters_.mip_max_bound()); + const int64_t offset_lower_bound = CapSub(lower_bound, variable_offset_[index]); if (offset_lower_bound > offset_upper_bound) return false; sat::IntegerVariableProto* const variable = model_.mutable_variables(index); @@ -381,8 +410,8 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { variable->set_domain(1, offset_upper_bound); return true; } - void SetVariableDisjointBounds(int index, const std::vector& starts, - const std::vector& ends) override { + void SetVariableDisjointBounds(int index, const std::vector& starts, + const std::vector& ends) override { DCHECK_EQ(starts.size(), ends.size()); const int ct = CreateNewConstraint(1, 1); for (int i = 0; i < starts.size(); ++i) { @@ -394,7 +423,7 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { model_.mutable_constraints(window_ct)->add_enforcement_literal(variable); } } - int64 GetVariableLowerBound(int index) const override { + int64_t GetVariableLowerBound(int index) const override { return CapAdd(model_.variables(index).domain(0), variable_offset_[index]); } void SetObjectiveCoefficient(int index, double coefficient) override { @@ -419,7 +448,7 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { objective_offset_ = 0; } int NumVariables() const override { return model_.variables_size(); } - int CreateNewConstraint(int64 lower_bound, int64 upper_bound) override { + int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override { const int ct_index = model_.constraints_size(); if (ct_index >= constraint_offset_.size()) { constraint_offset_.resize(ct_index + 1, 0); @@ -497,7 +526,7 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { } return DimensionSchedulingStatus::INFEASIBLE; } - int64 GetObjectiveValue() const override { + int64_t GetObjectiveValue() const override { return MathUtil::FastInt64Round(response_.objective_value() + objective_offset_); } @@ -512,8 +541,8 @@ class RoutingCPSatWrapper : public RoutingLinearSolverWrapper { sat::SatParameters parameters_; std::vector objective_coefficients_; double objective_offset_; - std::vector variable_offset_; - std::vector constraint_offset_; + std::vector variable_offset_; + std::vector constraint_offset_; int first_constraint_to_offset_; sat::PartialVariableAssignment hint_; }; @@ -530,26 +559,26 @@ class DimensionCumulOptimizerCore { // first feasible solution in the linear solver (since in this case only // feasibility is of interest). DimensionSchedulingStatus OptimizeSingleRoute( - int vehicle, const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values, int64* cost, int64* transit_cost, + int vehicle, const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values, int64_t* cost, int64_t* transit_cost, bool clear_lp = true); - bool Optimize(const std::function& next_accessor, + bool Optimize(const std::function& next_accessor, RoutingLinearSolverWrapper* solver, - std::vector* cumul_values, - std::vector* break_values, int64* cost, - int64* transit_cost, bool clear_lp = true); + std::vector* cumul_values, + std::vector* break_values, int64_t* cost, + int64_t* transit_cost, bool clear_lp = true); - bool OptimizeAndPack(const std::function& next_accessor, + bool OptimizeAndPack(const std::function& next_accessor, RoutingLinearSolverWrapper* solver, - std::vector* cumul_values, - std::vector* break_values); + std::vector* cumul_values, + std::vector* break_values); DimensionSchedulingStatus OptimizeAndPackSingleRoute( - int vehicle, const std::function& next_accessor, - RoutingLinearSolverWrapper* solver, std::vector* cumul_values, - std::vector* break_values); + int vehicle, const std::function& next_accessor, + RoutingLinearSolverWrapper* solver, std::vector* cumul_values, + std::vector* break_values); const RoutingDimension* dimension() const { return dimension_; } @@ -564,19 +593,19 @@ class DimensionCumulOptimizerCore { // propagator. // Otherwise, the bounds are computed by going over the nodes on the route // using the CP bounds, and the fixed transits are used to tighten them. - bool ComputeRouteCumulBounds(const std::vector& route, - const std::vector& fixed_transits, - int64 cumul_offset); + bool ComputeRouteCumulBounds(const std::vector& route, + const std::vector& fixed_transits, + int64_t cumul_offset); // Sets the constraints for all nodes on "vehicle"'s route according to // "next_accessor". If optimize_costs is true, also sets the objective // coefficients for the LP. // Returns false if some infeasibility was detected, true otherwise. bool SetRouteCumulConstraints( - int vehicle, const std::function& next_accessor, - int64 cumul_offset, bool optimize_costs, - RoutingLinearSolverWrapper* solver, int64* route_transit_cost, - int64* route_cost_offset); + int vehicle, const std::function& next_accessor, + int64_t cumul_offset, bool optimize_costs, + RoutingLinearSolverWrapper* solver, int64_t* route_transit_cost, + int64_t* route_cost_offset); // Sets the global constraints on the dimension, and adds global objective // cost coefficients if optimize_costs is true. @@ -587,9 +616,9 @@ class DimensionCumulOptimizerCore { void SetGlobalConstraints(bool optimize_costs, RoutingLinearSolverWrapper* solver); - void SetValuesFromLP(const std::vector& lp_variables, int64 offset, + void SetValuesFromLP(const std::vector& lp_variables, int64_t offset, RoutingLinearSolverWrapper* solver, - std::vector* lp_values); + std::vector* lp_values); // This function packs the routes of the given vehicles while keeping the cost // of the LP lower than its current (supposed optimal) objective value. @@ -601,8 +630,8 @@ class DimensionCumulOptimizerCore { RoutingLinearSolverWrapper* solver); std::unique_ptr propagator_; - std::vector current_route_min_cumuls_; - std::vector current_route_max_cumuls_; + std::vector current_route_min_cumuls_; + std::vector current_route_max_cumuls_; const RoutingDimension* const dimension_; // Scheduler variables for current route cumuls and for all nodes cumuls. std::vector current_route_cumul_variables_; @@ -623,7 +652,7 @@ class DimensionCumulOptimizerCore { int max_end_cumul_; int min_start_cumul_; - std::vector> + std::vector> visited_pickup_delivery_indices_for_pair_; }; @@ -643,14 +672,14 @@ class LocalDimensionCumulOptimizer { // and stores it in "optimal_cost" (if not null). // Returns true iff the route respects all constraints. DimensionSchedulingStatus ComputeRouteCumulCost( - int vehicle, const std::function& next_accessor, - int64* optimal_cost); + int vehicle, const std::function& next_accessor, + int64_t* optimal_cost); // Same as ComputeRouteCumulCost, but the cost computed does not contain // the part of the vehicle span cost due to fixed transits. DimensionSchedulingStatus ComputeRouteCumulCostWithoutFixedTransits( - int vehicle, const std::function& next_accessor, - int64* optimal_cost_without_transits); + int vehicle, const std::function& next_accessor, + int64_t* optimal_cost_without_transits); // If feasible, computes the optimal values for cumul and break variables // of the route performed by a vehicle, minimizing cumul soft lower, upper @@ -658,15 +687,16 @@ class LocalDimensionCumulOptimizer { // (if not null), and optimal_breaks, and returns true. // Returns false if the route is not feasible. DimensionSchedulingStatus ComputeRouteCumuls( - int vehicle, const std::function& next_accessor, - std::vector* optimal_cumuls, std::vector* optimal_breaks); + int vehicle, const std::function& next_accessor, + std::vector* optimal_cumuls, + std::vector* optimal_breaks); // Similar to ComputeRouteCumuls, but also tries to pack the cumul values on // the route, such that the cost remains the same, the cumul of route end is // minimized, and then the cumul of the start of the route is maximized. DimensionSchedulingStatus ComputePackedRouteCumuls( - int vehicle, const std::function& next_accessor, - std::vector* packed_cumuls, std::vector* packed_breaks); + int vehicle, const std::function& next_accessor, + std::vector* packed_cumuls, std::vector* packed_breaks); const RoutingDimension* dimension() const { return optimizer_core_.dimension(); @@ -686,27 +716,27 @@ class GlobalDimensionCumulOptimizer { // (if not null). // Returns true iff all the constraints can be respected. bool ComputeCumulCostWithoutFixedTransits( - const std::function& next_accessor, - int64* optimal_cost_without_transits); + const std::function& next_accessor, + int64_t* optimal_cost_without_transits); // If feasible, computes the optimal values for cumul and break variables, // minimizing cumul soft lower/upper bound costs and vehicle/global span // costs, stores them in "optimal_cumuls" (if not null) and optimal breaks, // and returns true. // Returns false if the routes are not feasible. - bool ComputeCumuls(const std::function& next_accessor, - std::vector* optimal_cumuls, - std::vector* optimal_breaks); + bool ComputeCumuls(const std::function& next_accessor, + std::vector* optimal_cumuls, + std::vector* optimal_breaks); // Returns true iff the routes resulting from the next_accessor are feasible // wrt the constraints on the optimizer_core_.dimension()'s cumuls. - bool IsFeasible(const std::function& next_accessor); + bool IsFeasible(const std::function& next_accessor); // Similar to ComputeCumuls, but also tries to pack the cumul values on all // routes, such that the cost remains the same, the cumuls of route ends are // minimized, and then the cumuls of the starts of the routes are maximized. - bool ComputePackedCumuls(const std::function& next_accessor, - std::vector* packed_cumuls, - std::vector* packed_breaks); + bool ComputePackedCumuls(const std::function& next_accessor, + std::vector* packed_cumuls, + std::vector* packed_breaks); const RoutingDimension* dimension() const { return optimizer_core_.dimension(); diff --git a/ortools/constraint_solver/routing_neighborhoods.cc b/ortools/constraint_solver/routing_neighborhoods.cc index f463b19e06..e01ecacb50 100644 --- a/ortools/constraint_solver/routing_neighborhoods.cc +++ b/ortools/constraint_solver/routing_neighborhoods.cc @@ -14,30 +14,44 @@ #include "ortools/constraint_solver/routing_neighborhoods.h" #include +#include #include +#include +#include +#include +#include +#include +#include -#include "absl/container/flat_hash_set.h" +#include "ortools/base/int_type.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_search.h" +#include "ortools/constraint_solver/routing_types.h" +#include "ortools/util/bitset.h" namespace operations_research { MakeRelocateNeighborsOperator::MakeRelocateNeighborsOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, RoutingTransitCallback2 arc_evaluator) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)), arc_evaluator_(std::move(arc_evaluator)) {} bool MakeRelocateNeighborsOperator::MakeNeighbor() { - const int64 before_chain = BaseNode(0); - int64 chain_end = Next(before_chain); + const int64_t before_chain = BaseNode(0); + int64_t chain_end = Next(before_chain); if (IsPathEnd(chain_end)) return false; - const int64 destination = BaseNode(1); + const int64_t destination = BaseNode(1); if (chain_end == destination) return false; - const int64 max_arc_value = arc_evaluator_(destination, chain_end); - int64 next = Next(chain_end); + const int64_t max_arc_value = arc_evaluator_(destination, chain_end); + int64_t next = Next(chain_end); while (!IsPathEnd(next) && arc_evaluator_(chain_end, next) <= max_arc_value) { if (next == destination) return false; chain_end = next; @@ -46,13 +60,13 @@ bool MakeRelocateNeighborsOperator::MakeNeighbor() { return MoveChainAndRepair(before_chain, chain_end, destination); } -bool MakeRelocateNeighborsOperator::MoveChainAndRepair(int64 before_chain, - int64 chain_end, - int64 destination) { +bool MakeRelocateNeighborsOperator::MoveChainAndRepair(int64_t before_chain, + int64_t chain_end, + int64_t destination) { if (MoveChain(before_chain, chain_end, destination)) { if (!IsPathStart(destination)) { - int64 current = Prev(destination); - int64 last = chain_end; + int64_t current = Prev(destination); + int64_t last = chain_end; if (current == last) { // chain was just before destination current = before_chain; } @@ -66,15 +80,15 @@ bool MakeRelocateNeighborsOperator::MoveChainAndRepair(int64 before_chain, return false; } -int64 MakeRelocateNeighborsOperator::Reposition(int64 before_to_move, - int64 up_to) { - const int64 kNoChange = -1; - const int64 to_move = Next(before_to_move); - int64 next = Next(to_move); +int64_t MakeRelocateNeighborsOperator::Reposition(int64_t before_to_move, + int64_t up_to) { + const int64_t kNoChange = -1; + const int64_t to_move = Next(before_to_move); + int64_t next = Next(to_move); if (Var(to_move)->Contains(next)) { return kNoChange; } - int64 prev = next; + int64_t prev = next; next = Next(next); while (prev != up_to) { if (Var(prev)->Contains(to_move) && Var(to_move)->Contains(next)) { @@ -94,7 +108,7 @@ int64 MakeRelocateNeighborsOperator::Reposition(int64 before_to_move, MakePairActiveOperator::MakePairActiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs) : PathOperator(vars, secondary_vars, 2, false, true, std::move(start_empty_path_class)), @@ -135,7 +149,7 @@ bool MakePairActiveOperator::MakeNeighbor() { BaseNode(0)); } -int64 MakePairActiveOperator::GetBaseNodeRestartPosition(int base_index) { +int64_t MakePairActiveOperator::GetBaseNodeRestartPosition(int base_index) { // Base node 1 must be after base node 0 if they are both on the same path. if (base_index == 0 || StartNode(base_index) != StartNode(base_index - 1)) { return StartNode(base_index); @@ -161,8 +175,8 @@ int MakePairActiveOperator::FindNextInactivePair(int pair_index) const { } bool MakePairActiveOperator::ContainsActiveNodes( - const std::vector& nodes) const { - for (int64 node : nodes) { + const std::vector& nodes) const { + for (int64_t node : nodes) { if (!IsInactive(node)) return true; } return false; @@ -171,7 +185,7 @@ bool MakePairActiveOperator::ContainsActiveNodes( MakePairInactiveOperator::MakePairInactiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 1, true, false, std::move(start_empty_path_class)) { @@ -179,9 +193,9 @@ MakePairInactiveOperator::MakePairInactiveOperator( } bool MakePairInactiveOperator::MakeNeighbor() { - const int64 base = BaseNode(0); - const int64 first_index = Next(base); - const int64 second_index = GetActiveAlternativeSibling(first_index); + const int64_t base = BaseNode(0); + const int64_t first_index = Next(base); + const int64_t second_index = GetActiveAlternativeSibling(first_index); if (second_index < 0) { return false; } @@ -192,7 +206,7 @@ bool MakePairInactiveOperator::MakeNeighbor() { PairRelocateOperator::PairRelocateOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 3, true, false, std::move(start_empty_path_class)) { @@ -201,25 +215,25 @@ PairRelocateOperator::PairRelocateOperator( bool PairRelocateOperator::MakeNeighbor() { DCHECK_EQ(StartNode(1), StartNode(2)); - const int64 first_pair_node = BaseNode(kPairFirstNode); + const int64_t first_pair_node = BaseNode(kPairFirstNode); if (IsPathStart(first_pair_node)) { return false; } - int64 first_prev = Prev(first_pair_node); + int64_t first_prev = Prev(first_pair_node); const int second_pair_node = GetActiveAlternativeSibling(first_pair_node); if (second_pair_node < 0 || IsPathEnd(second_pair_node) || IsPathStart(second_pair_node)) { return false; } - const int64 second_prev = Prev(second_pair_node); + const int64_t second_prev = Prev(second_pair_node); - const int64 first_node_destination = BaseNode(kPairFirstNodeDestination); + const int64_t first_node_destination = BaseNode(kPairFirstNodeDestination); if (first_node_destination == second_pair_node) { // The second_pair_node -> first_pair_node link is forbidden. return false; } - const int64 second_node_destination = BaseNode(kPairSecondNodeDestination); + const int64_t second_node_destination = BaseNode(kPairSecondNodeDestination); if (second_prev == first_pair_node && first_node_destination == first_prev && second_node_destination == first_prev) { // If the current sequence is first_prev -> first_pair_node -> @@ -248,7 +262,7 @@ bool PairRelocateOperator::MakeNeighbor() { return moved_first_pair_node || moved_second_pair_node; } -int64 PairRelocateOperator::GetBaseNodeRestartPosition(int base_index) { +int64_t PairRelocateOperator::GetBaseNodeRestartPosition(int base_index) { // Destination node of the second node of a pair must be after the // destination node of the first node of a pair. if (base_index == kPairSecondNodeDestination) { @@ -261,7 +275,7 @@ int64 PairRelocateOperator::GetBaseNodeRestartPosition(int base_index) { LightPairRelocateOperator::LightPairRelocateOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)) { @@ -269,14 +283,14 @@ LightPairRelocateOperator::LightPairRelocateOperator( } bool LightPairRelocateOperator::MakeNeighbor() { - const int64 prev1 = BaseNode(0); - const int64 node1 = Next(prev1); + const int64_t prev1 = BaseNode(0); + const int64_t node1 = Next(prev1); if (IsPathEnd(node1)) return false; - const int64 sibling1 = GetActiveAlternativeSibling(node1); + const int64_t sibling1 = GetActiveAlternativeSibling(node1); if (sibling1 == -1) return false; - const int64 node2 = BaseNode(1); + const int64_t node2 = BaseNode(1); if (node2 == sibling1) return false; - const int64 sibling2 = GetActiveAlternativeSibling(node2); + const int64_t sibling2 = GetActiveAlternativeSibling(node2); if (sibling2 == -1) return false; // Note: MoveChain will return false if it is a no-op (moving the chain to its // current position). However we want to accept the move if at least node1 or @@ -289,7 +303,7 @@ bool LightPairRelocateOperator::MakeNeighbor() { PairExchangeOperator::PairExchangeOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 2, true, true, std::move(start_empty_path_class)) { @@ -297,13 +311,13 @@ PairExchangeOperator::PairExchangeOperator( } bool PairExchangeOperator::MakeNeighbor() { - const int64 node1 = BaseNode(0); - int64 prev1, sibling1, sibling_prev1 = -1; + const int64_t node1 = BaseNode(0); + int64_t prev1, sibling1, sibling_prev1 = -1; if (!GetPreviousAndSibling(node1, &prev1, &sibling1, &sibling_prev1)) { return false; } - const int64 node2 = BaseNode(1); - int64 prev2, sibling2, sibling_prev2 = -1; + const int64_t node2 = BaseNode(1); + int64_t prev2, sibling2, sibling_prev2 = -1; if (!GetPreviousAndSibling(node2, &prev2, &sibling2, &sibling_prev2)) { return false; } @@ -349,8 +363,8 @@ bool PairExchangeOperator::MakeNeighbor() { } bool PairExchangeOperator::GetPreviousAndSibling( - int64 node, int64* previous, int64* sibling, - int64* sibling_previous) const { + int64_t node, int64_t* previous, int64_t* sibling, + int64_t* sibling_previous) const { if (IsPathStart(node)) return false; *previous = Prev(node); *sibling = GetActiveAlternativeSibling(node); @@ -361,7 +375,7 @@ bool PairExchangeOperator::GetPreviousAndSibling( PairExchangeRelocateOperator::PairExchangeRelocateOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 6, true, false, std::move(start_empty_path_class)) { @@ -382,9 +396,9 @@ bool PairExchangeRelocateOperator::MakeNeighbor() { } // Through this method, [X][Y] represent the variable for the // node Y of pair X. is in node, prev, dest. - int64 nodes[2][2]; - int64 prev[2][2]; - int64 dest[2][2]; + int64_t nodes[2][2]; + int64_t prev[2][2]; + int64_t dest[2][2]; nodes[0][0] = BaseNode(kFirstPairFirstNode); nodes[1][0] = BaseNode(kSecondPairFirstNode); if (nodes[1][0] <= nodes[0][0]) { @@ -440,8 +454,9 @@ bool PairExchangeRelocateOperator::MakeNeighbor() { } bool PairExchangeRelocateOperator::MoveNode(int pair, int node, - int64 nodes[2][2], int64 dest[2][2], - int64 prev[2][2]) { + int64_t nodes[2][2], + int64_t dest[2][2], + int64_t prev[2][2]) { if (!MoveChain(prev[pair][node], nodes[pair][node], dest[pair][node])) { return false; } @@ -456,16 +471,17 @@ bool PairExchangeRelocateOperator::MoveNode(int pair, int node, } bool PairExchangeRelocateOperator::LoadAndCheckDest(int pair, int node, - int64 base_node, - int64 nodes[2][2], - int64 dest[2][2]) const { + int64_t base_node, + int64_t nodes[2][2], + int64_t dest[2][2]) const { dest[pair][node] = BaseNode(base_node); // A destination cannot be a node that will be moved. return !(nodes[0][0] == dest[pair][node] || nodes[0][1] == dest[pair][node] || nodes[1][0] == dest[pair][node] || nodes[1][1] == dest[pair][node]); } -bool PairExchangeRelocateOperator::OnSamePathAsPreviousBase(int64 base_index) { +bool PairExchangeRelocateOperator::OnSamePathAsPreviousBase( + int64_t base_index) { // Ensuring the destination of the first pair is on the route of the second. // pair. // Ensuring that destination of both nodes of a pair are on the same route. @@ -474,7 +490,8 @@ bool PairExchangeRelocateOperator::OnSamePathAsPreviousBase(int64 base_index) { base_index == kSecondPairSecondNodeDestination; } -int64 PairExchangeRelocateOperator::GetBaseNodeRestartPosition(int base_index) { +int64_t PairExchangeRelocateOperator::GetBaseNodeRestartPosition( + int base_index) { if (base_index == kFirstPairSecondNodeDestination || base_index == kSecondPairSecondNodeDestination) { return BaseNode(base_index - 1); @@ -484,8 +501,8 @@ int64 PairExchangeRelocateOperator::GetBaseNodeRestartPosition(int base_index) { } bool PairExchangeRelocateOperator::GetPreviousAndSibling( - int64 node, int64* previous, int64* sibling, - int64* sibling_previous) const { + int64_t node, int64_t* previous, int64_t* sibling, + int64_t* sibling_previous) const { if (IsPathStart(node)) return false; *previous = Prev(node); *sibling = GetActiveAlternativeSibling(node); @@ -495,7 +512,7 @@ bool PairExchangeRelocateOperator::GetPreviousAndSibling( SwapIndexPairOperator::SwapIndexPairOperator( const std::vector& vars, const std::vector& path_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : IntVarLocalSearchOperator(vars), index_pairs_(index_pairs), @@ -511,34 +528,35 @@ SwapIndexPairOperator::SwapIndexPairOperator( bool SwapIndexPairOperator::MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) { - const int64 kNoPath = -1; + const int64_t kNoPath = -1; CHECK(delta != nullptr); while (true) { RevertChanges(true); if (pair_index_ < index_pairs_.size()) { - const int64 path = + const int64_t path = ignore_path_vars_ ? 0LL : Value(first_active_ + number_of_nexts_); - const int64 prev_first = prevs_[first_active_]; - const int64 next_first = Value(first_active_); + const int64_t prev_first = prevs_[first_active_]; + const int64_t next_first = Value(first_active_); // Making current active "pickup" unperformed. SetNext(first_active_, first_active_, kNoPath); // Inserting "pickup" alternative at the same position. - const int64 insert_first = index_pairs_[pair_index_].first[first_index_]; + const int64_t insert_first = + index_pairs_[pair_index_].first[first_index_]; SetNext(prev_first, insert_first, path); SetNext(insert_first, next_first, path); - int64 prev_second = prevs_[second_active_]; + int64_t prev_second = prevs_[second_active_]; if (prev_second == first_active_) { prev_second = insert_first; } DCHECK_EQ(path, ignore_path_vars_ - ? int64{0} + ? int64_t{0} : Value(second_active_ + number_of_nexts_)); - const int64 next_second = Value(second_active_); + const int64_t next_second = Value(second_active_); // Making current active "delivery" unperformed. SetNext(second_active_, second_active_, kNoPath); // Inserting "delivery" alternative at the same position. - const int64 insert_second = + const int64_t insert_second = index_pairs_[pair_index_].second[second_index_]; SetNext(prev_second, insert_second, path); SetNext(insert_second, next_second, path); @@ -568,7 +586,7 @@ bool SwapIndexPairOperator::MakeNextNeighbor(Assignment* delta, void SwapIndexPairOperator::OnStart() { prevs_.resize(number_of_nexts_, -1); for (int index = 0; index < number_of_nexts_; ++index) { - const int64 next = Value(index); + const int64_t next = Value(index); if (next >= prevs_.size()) prevs_.resize(next + 1, -1); prevs_[next] = index; } @@ -588,13 +606,13 @@ void SwapIndexPairOperator::OnStart() { bool SwapIndexPairOperator::UpdateActiveNodes() { if (pair_index_ < index_pairs_.size()) { - for (const int64 first : index_pairs_[pair_index_].first) { + for (const int64_t first : index_pairs_[pair_index_].first) { if (Value(first) != first) { first_active_ = first; break; } } - for (const int64 second : index_pairs_[pair_index_].second) { + for (const int64_t second : index_pairs_[pair_index_].second) { if (Value(second) != second) { second_active_ = second; break; @@ -608,7 +626,7 @@ bool SwapIndexPairOperator::UpdateActiveNodes() { IndexPairSwapActiveOperator::IndexPairSwapActiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 1, true, false, std::move(start_empty_path_class)), @@ -631,9 +649,9 @@ bool IndexPairSwapActiveOperator::MakeNextNeighbor(Assignment* delta, } bool IndexPairSwapActiveOperator::MakeNeighbor() { - const int64 base = BaseNode(0); - const int64 next = Next(base); - const int64 other = GetActiveAlternativeSibling(next); + const int64_t base = BaseNode(0); + const int64_t next = Next(base); + const int64_t other = GetActiveAlternativeSibling(next); if (other != -1) { return MakeChainInactive(Prev(other), other) && MakeChainInactive(base, next) && MakeActive(inactive_node_, base); @@ -682,7 +700,7 @@ bool FilteredHeuristicLocalSearchOperator::MakeOneNeighbor() { bool FilteredHeuristicLocalSearchOperator::MakeChangesAndInsertNodes() { removed_nodes_.SparseClearAll(); - const std::function next_accessor = + const std::function next_accessor = SetupNextAccessorForNeighbor(); if (next_accessor == nullptr) { return false; @@ -698,17 +716,17 @@ bool FilteredHeuristicLocalSearchOperator::MakeChangesAndInsertNodes() { const std::vector& elements = result_assignment->IntVarContainer().elements(); for (int vehicle = 0; vehicle < model_.vehicles(); vehicle++) { - int64 node_index = model_.Start(vehicle); + int64_t node_index = model_.Start(vehicle); while (!model_.IsEnd(node_index)) { // NOTE: When building the solution in the heuristic, Next vars are added // to the assignment at the position corresponding to their index. const IntVarElement& node_element = elements[node_index]; DCHECK_EQ(node_element.Var(), model_.NextVar(node_index)); - const int64 new_node_value = node_element.Value(); + const int64_t new_node_value = node_element.Value(); DCHECK_NE(new_node_value, node_index); - const int64 vehicle_var_index = VehicleVarIndex(node_index); + const int64_t vehicle_var_index = VehicleVarIndex(node_index); if (OldValue(node_index) != new_node_value || (consider_vehicle_vars_ && OldValue(vehicle_var_index) != vehicle)) { has_change = true; @@ -722,7 +740,7 @@ bool FilteredHeuristicLocalSearchOperator::MakeChangesAndInsertNodes() { } // Check for newly unperformed nodes among the ones removed for insertion by // the heuristic. - for (int64 node : removed_nodes_.PositionsSetAtLeastOnce()) { + for (int64_t node : removed_nodes_.PositionsSetAtLeastOnce()) { const IntVarElement& node_element = elements[node]; DCHECK_EQ(node_element.Var(), model_.NextVar(node)); if (node_element.Value() == node) { @@ -730,7 +748,7 @@ bool FilteredHeuristicLocalSearchOperator::MakeChangesAndInsertNodes() { has_change = true; SetValue(node, node); if (consider_vehicle_vars_) { - const int64 vehicle_var_index = VehicleVarIndex(node); + const int64_t vehicle_var_index = VehicleVarIndex(node); DCHECK_NE(OldValue(vehicle_var_index), -1); SetValue(vehicle_var_index, -1); } @@ -782,18 +800,18 @@ void FilteredHeuristicPathLNSOperator::IncrementCurrentRouteToNextNonEmpty() { } while (CurrentRouteIsEmpty()); } -std::function +std::function FilteredHeuristicPathLNSOperator::SetupNextAccessorForNeighbor() { - const int64 start_node = model_.Start(current_route_); - const int64 end_node = model_.End(current_route_); + const int64_t start_node = model_.Start(current_route_); + const int64_t end_node = model_.End(current_route_); - int64 node = Value(start_node); + int64_t node = Value(start_node); while (node != end_node) { removed_nodes_.Set(node); node = Value(node); } - return [this, start_node, end_node](int64 node) { + return [this, start_node, end_node](int64_t node) { if (node == start_node) return end_node; return Value(node); }; @@ -816,8 +834,8 @@ void RelocatePathAndHeuristicInsertUnperformedOperator::OnStart() { empty_routes_.clear(); std::vector empty_vehicle_of_vehicle_class_added( model_.GetVehicleClassesCount(), false); - for (int64 node = 0; node < model_.Size(); node++) { - const int64 next = OldValue(node); + for (int64_t node = 0; node < model_.Size(); node++) { + const int64_t next = OldValue(node); if (next == node) { has_unperformed_nodes_ = true; continue; @@ -828,7 +846,7 @@ void RelocatePathAndHeuristicInsertUnperformedOperator::OnStart() { } for (int vehicle = 0; vehicle < model_.vehicles(); vehicle++) { - const int64 next = OldValue(model_.Start(vehicle)); + const int64_t next = OldValue(model_.Start(vehicle)); if (!model_.IsEnd(next)) { routes_to_relocate_.push_back(vehicle); continue; @@ -874,7 +892,8 @@ bool RelocatePathAndHeuristicInsertUnperformedOperator::IncrementRoutes() { return route_to_relocate_index_ != last_route_to_relocate_index_; } -std::function RelocatePathAndHeuristicInsertUnperformedOperator:: +std::function +RelocatePathAndHeuristicInsertUnperformedOperator:: SetupNextAccessorForNeighbor() { const int empty_route = empty_routes_[empty_route_index_]; const int relocated_route = routes_to_relocate_[route_to_relocate_index_]; @@ -884,17 +903,17 @@ std::function RelocatePathAndHeuristicInsertUnperformedOperator:: return nullptr; } - const int64 empty_start_node = model_.Start(empty_route); - const int64 empty_end_node = model_.End(empty_route); + const int64_t empty_start_node = model_.Start(empty_route); + const int64_t empty_end_node = model_.End(empty_route); - const int64 relocated_route_start = model_.Start(relocated_route); - const int64 first_relocated_node = OldValue(relocated_route_start); - const int64 last_relocated_node = last_node_on_route_[relocated_route]; - const int64 relocated_route_end = model_.End(relocated_route); + const int64_t relocated_route_start = model_.Start(relocated_route); + const int64_t first_relocated_node = OldValue(relocated_route_start); + const int64_t last_relocated_node = last_node_on_route_[relocated_route]; + const int64_t relocated_route_end = model_.End(relocated_route); return [this, empty_start_node, empty_end_node, first_relocated_node, last_relocated_node, relocated_route_start, - relocated_route_end](int64 node) { + relocated_route_end](int64_t node) { if (node == relocated_route_start) return relocated_route_end; if (node == empty_start_node) return first_relocated_node; if (node == last_relocated_node) return empty_end_node; @@ -916,23 +935,24 @@ FilteredHeuristicCloseNodesLNSOperator::FilteredHeuristicCloseNodesLNSOperator( changed_nexts_(model_.Size()), new_prevs_(model_.Size()), changed_prevs_(model_.Size()) { - const int64 size = model_.Size(); - const int64 max_num_neighbors = - std::max(0, size - 1 - model_.vehicles()); - const int64 num_closest_neighbors = - std::min(num_close_nodes, max_num_neighbors); + const int64_t size = model_.Size(); + const int64_t max_num_neighbors = + std::max(0, size - 1 - model_.vehicles()); + const int64_t num_closest_neighbors = + std::min(num_close_nodes, max_num_neighbors); DCHECK_GE(num_closest_neighbors, 0); if (num_closest_neighbors == 0) return; - const int64 num_cost_classes = model_.GetCostClassesCount(); + const int64_t num_cost_classes = model_.GetCostClassesCount(); - for (int64 node = 0; node < size; node++) { + for (int64_t node = 0; node < size; node++) { if (model_.IsStart(node) || model_.IsEnd(node)) continue; - std::vector> costed_after_nodes; + std::vector> + costed_after_nodes; costed_after_nodes.reserve(size); - for (int64 after_node = 0; after_node < size; after_node++) { + for (int64_t after_node = 0; after_node < size; after_node++) { if (model_.IsStart(after_node) || model_.IsEnd(after_node) || after_node == node) { continue; @@ -949,7 +969,7 @@ FilteredHeuristicCloseNodesLNSOperator::FilteredHeuristicCloseNodesLNSOperator( std::nth_element(costed_after_nodes.begin(), costed_after_nodes.begin() + num_closest_neighbors - 1, costed_after_nodes.end()); - std::vector& neighbors = close_nodes_[node]; + std::vector& neighbors = close_nodes_[node]; neighbors.reserve(num_closest_neighbors); for (int index = 0; index < num_closest_neighbors; index++) { neighbors.push_back(costed_after_nodes[index].second); @@ -971,14 +991,14 @@ bool FilteredHeuristicCloseNodesLNSOperator::IncrementPosition() { return current_node_ != last_node_; } -void FilteredHeuristicCloseNodesLNSOperator::RemoveNode(int64 node) { +void FilteredHeuristicCloseNodesLNSOperator::RemoveNode(int64_t node) { DCHECK(!model_.IsEnd(node) && !model_.IsStart(node)); DCHECK_NE(Value(node), node); DCHECK(IsActive(node)); removed_nodes_.Set(node); - const int64 prev = Prev(node); - const int64 next = Next(node); + const int64_t prev = Prev(node); + const int64_t next = Next(node); changed_nexts_.Set(prev); new_nexts_[prev] = next; if (next < model_.Size()) { @@ -988,25 +1008,26 @@ void FilteredHeuristicCloseNodesLNSOperator::RemoveNode(int64 node) { } void FilteredHeuristicCloseNodesLNSOperator::RemoveNodeAndActiveSibling( - int64 node) { + int64_t node) { if (!IsActive(node)) return; RemoveNode(node); - for (int64 sibling_node : GetActiveSiblings(node)) { + for (int64_t sibling_node : GetActiveSiblings(node)) { if (!model_.IsStart(sibling_node) && !model_.IsEnd(sibling_node)) { RemoveNode(sibling_node); } } } -std::vector FilteredHeuristicCloseNodesLNSOperator::GetActiveSiblings( - int64 node) const { +std::vector FilteredHeuristicCloseNodesLNSOperator::GetActiveSiblings( + int64_t node) const { // NOTE: In most use-cases, where each node is a pickup or delivery in a // single index pair, this function is in O(k) where k is the number of // alternative deliveries or pickups for this index pair. - std::vector active_siblings; - for (std::pair index_pair : model_.GetPickupIndexPairs(node)) { - for (int64 sibling_delivery : + std::vector active_siblings; + for (std::pair index_pair : + model_.GetPickupIndexPairs(node)) { + for (int64_t sibling_delivery : pickup_delivery_pairs_[index_pair.first].second) { if (IsActive(sibling_delivery)) { active_siblings.push_back(sibling_delivery); @@ -1014,9 +1035,9 @@ std::vector FilteredHeuristicCloseNodesLNSOperator::GetActiveSiblings( } } } - for (std::pair index_pair : + for (std::pair index_pair : model_.GetDeliveryIndexPairs(node)) { - for (int64 sibling_pickup : + for (int64_t sibling_pickup : pickup_delivery_pairs_[index_pair.first].first) { if (IsActive(sibling_pickup)) { active_siblings.push_back(sibling_pickup); @@ -1027,7 +1048,7 @@ std::vector FilteredHeuristicCloseNodesLNSOperator::GetActiveSiblings( return active_siblings; } -std::function +std::function FilteredHeuristicCloseNodesLNSOperator::SetupNextAccessorForNeighbor() { if (model_.IsStart(current_node_)) { return nullptr; @@ -1039,11 +1060,11 @@ FilteredHeuristicCloseNodesLNSOperator::SetupNextAccessorForNeighbor() { RemoveNodeAndActiveSibling(current_node_); - for (int64 neighbor : close_nodes_[current_node_]) { + for (int64_t neighbor : close_nodes_[current_node_]) { RemoveNodeAndActiveSibling(neighbor); } - return [this](int64 node) { return Next(node); }; + return [this](int64_t node) { return Next(node); }; } // FilteredHeuristicExpensiveChainLNSOperator @@ -1052,7 +1073,8 @@ FilteredHeuristicExpensiveChainLNSOperator:: FilteredHeuristicExpensiveChainLNSOperator( std::unique_ptr heuristic, int num_arcs_to_consider, - std::function arc_cost_for_route_start) + std::function + arc_cost_for_route_start) : FilteredHeuristicLocalSearchOperator(std::move(heuristic)), current_route_(0), last_route_(0), @@ -1079,7 +1101,7 @@ bool FilteredHeuristicExpensiveChainLNSOperator::IncrementPosition() { return IncrementRoute() && FindMostExpensiveChainsOnRemainingRoutes(); } -std::function +std::function FilteredHeuristicExpensiveChainLNSOperator::SetupNextAccessorForNeighbor() { const int first_arc_index = current_expensive_arc_indices_.first; const int second_arc_index = current_expensive_arc_indices_.second; @@ -1091,7 +1113,7 @@ FilteredHeuristicExpensiveChainLNSOperator::SetupNextAccessorForNeighbor() { most_expensive_arc_starts_and_ranks_[first_arc_index]; const std::pair& second_start_and_rank = most_expensive_arc_starts_and_ranks_[second_arc_index]; - int64 before_chain, after_chain; + int64_t before_chain, after_chain; if (first_start_and_rank.second < second_start_and_rank.second) { before_chain = first_start_and_rank.first; after_chain = OldValue(second_start_and_rank.first); @@ -1106,7 +1128,7 @@ FilteredHeuristicExpensiveChainLNSOperator::SetupNextAccessorForNeighbor() { node = Value(node); } - return [this, before_chain, after_chain](int64 node) { + return [this, before_chain, after_chain](int64_t node) { if (node == before_chain) return after_chain; return OldValue(node); }; @@ -1137,10 +1159,12 @@ namespace { // most_expensive_arc_starts_and_ranks and first_expensive_arc_indices according // to the most expensive chains on the route, and returns true. bool FindMostExpensiveArcsOnRoute( - int num_arcs, int64 start, const std::function& next_accessor, - const std::function& is_end, - const std::function& arc_cost_for_route_start, - std::vector>* most_expensive_arc_starts_and_ranks, + int num_arcs, int64_t start, + const std::function& next_accessor, + const std::function& is_end, + const std::function& + arc_cost_for_route_start, + std::vector>* most_expensive_arc_starts_and_ranks, std::pair* first_expensive_arc_indices) { if (is_end(next_accessor(start))) { // Empty route. @@ -1150,17 +1174,17 @@ bool FindMostExpensiveArcsOnRoute( // NOTE: The negative ranks are so that for a given cost, lower ranks are // given higher priority. - using ArcCostNegativeRankStart = std::tuple; + using ArcCostNegativeRankStart = std::tuple; std::priority_queue, std::greater> arc_info_pq; - int64 before_node = start; + int64_t before_node = start; int rank = 0; while (!is_end(before_node)) { - const int64 after_node = next_accessor(before_node); - const int64 arc_cost = + const int64_t after_node = next_accessor(before_node); + const int64_t arc_cost = arc_cost_for_route_start(before_node, after_node, start); arc_info_pq.emplace(arc_cost, -rank, before_node); @@ -1196,8 +1220,8 @@ bool FilteredHeuristicExpensiveChainLNSOperator:: do { if (FindMostExpensiveArcsOnRoute( num_arcs_to_consider_, model_.Start(current_route_), - [this](int64 i) { return OldValue(i); }, - [this](int64 node) { return model_.IsEnd(node); }, + [this](int64_t i) { return OldValue(i); }, + [this](int64_t node) { return model_.IsEnd(node); }, arc_cost_for_route_start_, &most_expensive_arc_starts_and_ranks_, ¤t_expensive_arc_indices_)) { return true; @@ -1210,8 +1234,9 @@ bool FilteredHeuristicExpensiveChainLNSOperator:: RelocateExpensiveChain::RelocateExpensiveChain( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, int num_arcs_to_consider, - std::function arc_cost_for_path_start) + std::function start_empty_path_class, + int num_arcs_to_consider, + std::function arc_cost_for_path_start) : PathOperator(vars, secondary_vars, 1, false, false, std::move(start_empty_path_class)), num_arcs_to_consider_(num_arcs_to_consider), @@ -1301,8 +1326,8 @@ bool RelocateExpensiveChain::FindMostExpensiveChainsOnRemainingPaths() { do { if (FindMostExpensiveArcsOnRoute( num_arcs_to_consider_, path_starts()[current_path_], - [this](int64 i) { return OldNext(i); }, - [this](int64 node) { return IsPathEnd(node); }, + [this](int64_t i) { return OldNext(i); }, + [this](int64_t node) { return IsPathEnd(node); }, arc_cost_for_path_start_, &most_expensive_arc_starts_and_ranks_, ¤t_expensive_arc_indices_)) { return true; @@ -1315,7 +1340,7 @@ bool RelocateExpensiveChain::FindMostExpensiveChainsOnRemainingPaths() { RelocateSubtrip::RelocateSubtrip( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs) : PathOperator(vars, secondary_vars, /*number_of_base_nodes*/ 2, true, false, @@ -1336,8 +1361,8 @@ RelocateSubtrip::RelocateSubtrip( opened_pairs_bitset_.resize(pairs.size(), false); } -bool RelocateSubtrip::RelocateSubTripFromPickup(const int64 chain_first_node, - const int64 insertion_node) { +bool RelocateSubtrip::RelocateSubTripFromPickup(const int64_t chain_first_node, + const int64_t insertion_node) { if (IsPathEnd(insertion_node)) return false; if (Prev(chain_first_node) == insertion_node) return false; // Skip null move. @@ -1373,19 +1398,19 @@ bool RelocateSubtrip::RelocateSubTripFromPickup(const int64 chain_first_node, subtrip_nodes_.push_back(Next(insertion_node)); // Set new paths. - const int64 rejected_path = Path(chain_first_node); + const int64_t rejected_path = Path(chain_first_node); for (int i = 1; i < rejected_nodes_.size(); ++i) { SetNext(rejected_nodes_[i - 1], rejected_nodes_[i], rejected_path); } - const int64 insertion_path = Path(insertion_node); + const int64_t insertion_path = Path(insertion_node); for (int i = 1; i < subtrip_nodes_.size(); ++i) { SetNext(subtrip_nodes_[i - 1], subtrip_nodes_[i], insertion_path); } return true; } -bool RelocateSubtrip::RelocateSubTripFromDelivery(const int64 chain_last_node, - const int64 insertion_node) { +bool RelocateSubtrip::RelocateSubTripFromDelivery( + const int64_t chain_last_node, const int64_t insertion_node) { if (IsPathEnd(insertion_node)) return false; // opened_pairs_bitset_ should be all false. @@ -1427,11 +1452,11 @@ bool RelocateSubtrip::RelocateSubTripFromDelivery(const int64 chain_last_node, std::reverse(subtrip_nodes_.begin(), subtrip_nodes_.end()); // Set new paths. - const int64 rejected_path = Path(chain_last_node); + const int64_t rejected_path = Path(chain_last_node); for (int i = 1; i < rejected_nodes_.size(); ++i) { SetNext(rejected_nodes_[i - 1], rejected_nodes_[i], rejected_path); } - const int64 insertion_path = Path(insertion_node); + const int64_t insertion_path = Path(insertion_node); for (int i = 1; i < subtrip_nodes_.size(); ++i) { SetNext(subtrip_nodes_[i - 1], subtrip_nodes_[i], insertion_path); } @@ -1451,7 +1476,7 @@ bool RelocateSubtrip::MakeNeighbor() { ExchangeSubtrip::ExchangeSubtrip( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs) : PathOperator(vars, secondary_vars, 2, true, false, std::move(start_empty_path_class)) { @@ -1471,14 +1496,14 @@ ExchangeSubtrip::ExchangeSubtrip( opened_pairs_set_.resize(pairs.size(), false); } -void ExchangeSubtrip::SetPath(const std::vector& path, int path_id) { +void ExchangeSubtrip::SetPath(const std::vector& path, int path_id) { for (int i = 1; i < path.size(); ++i) { SetNext(path[i - 1], path[i], path_id); } } namespace { -bool VectorContains(const std::vector& values, int64 target) { +bool VectorContains(const std::vector& values, int64_t target) { return std::find(values.begin(), values.end(), target) != values.end(); } } // namespace @@ -1511,8 +1536,8 @@ bool ExchangeSubtrip::MakeNeighbor() { // Assemble the new paths. path0_ = {Prev(subtrip0_.front())}; path1_ = {Prev(subtrip1_.front())}; - const int64 last0 = Next(subtrip0_.back()); - const int64 last1 = Next(subtrip1_.back()); + const int64_t last0 = Next(subtrip0_.back()); + const int64_t last1 = Next(subtrip1_.back()); const bool concatenated01 = last0 == subtrip1_.front(); const bool concatenated10 = last1 == subtrip0_.front(); @@ -1537,15 +1562,16 @@ bool ExchangeSubtrip::MakeNeighbor() { // Change the paths. Since SetNext() modifies Path() values, // record path_id0 and path_id11 before calling SetPath(); - const int64 path0_id = Path(BaseNode(0)); - const int64 path1_id = Path(BaseNode(1)); + const int64_t path0_id = Path(BaseNode(0)); + const int64_t path1_id = Path(BaseNode(1)); SetPath(path0_, path0_id); SetPath(path1_, path1_id); return true; } bool ExchangeSubtrip::ExtractChainsAndCheckCanonical( - int64 base_node, std::vector* rejects, std::vector* subtrip) { + int64_t base_node, std::vector* rejects, + std::vector* subtrip) { const bool extracted = is_pickup_node_[base_node] ? ExtractChainsFromPickup(base_node, rejects, subtrip) @@ -1557,9 +1583,9 @@ bool ExchangeSubtrip::ExtractChainsAndCheckCanonical( !rejects->empty(); } -bool ExchangeSubtrip::ExtractChainsFromPickup(int64 base_node, - std::vector* rejects, - std::vector* subtrip) { +bool ExchangeSubtrip::ExtractChainsFromPickup(int64_t base_node, + std::vector* rejects, + std::vector* subtrip) { DCHECK(is_pickup_node_[base_node]); DCHECK(rejects->empty()); DCHECK(subtrip->empty()); @@ -1587,9 +1613,9 @@ bool ExchangeSubtrip::ExtractChainsFromPickup(int64 base_node, return num_opened_pairs == 0; } -bool ExchangeSubtrip::ExtractChainsFromDelivery(int64 base_node, - std::vector* rejects, - std::vector* subtrip) { +bool ExchangeSubtrip::ExtractChainsFromDelivery(int64_t base_node, + std::vector* rejects, + std::vector* subtrip) { DCHECK(is_delivery_node_[base_node]); DCHECK(rejects->empty()); DCHECK(subtrip->empty()); diff --git a/ortools/constraint_solver/routing_neighborhoods.h b/ortools/constraint_solver/routing_neighborhoods.h index 74bcb25317..34fa3c4838 100644 --- a/ortools/constraint_solver/routing_neighborhoods.h +++ b/ortools/constraint_solver/routing_neighborhoods.h @@ -14,10 +14,19 @@ #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_ #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_ -#include "absl/container/flat_hash_set.h" +#include +#include +#include +#include +#include +#include + +#include "absl/strings/str_cat.h" +#include "ortools/base/logging.h" #include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_search.h" #include "ortools/constraint_solver/routing_types.h" #include "ortools/util/bitset.h" @@ -49,7 +58,7 @@ class MakeRelocateNeighborsOperator : public PathOperator { MakeRelocateNeighborsOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, RoutingTransitCallback2 arc_evaluator); ~MakeRelocateNeighborsOperator() override {} @@ -63,8 +72,8 @@ class MakeRelocateNeighborsOperator : public PathOperator { /// NextVar domains, and moves the 'destination' down the path if the solution /// is inconsistent. Iterates the process on the new arcs created before /// the node 'destination' (if destination was moved). - bool MoveChainAndRepair(int64 before_chain, int64 chain_end, - int64 destination); + bool MoveChainAndRepair(int64_t before_chain, int64_t chain_end, + int64_t destination); /// Moves node after 'before_to_move' down the path until a position is found /// where NextVar domains are not violated, if it exists. Stops when reaching @@ -73,7 +82,7 @@ class MakeRelocateNeighborsOperator : public PathOperator { /// violate any domains or because not such position could be found), returns /// -1. If the node was moved to a new position before up_to, returns up_to; /// if it was moved just after up_to returns the node which was after up_to. - int64 Reposition(int64 before_to_move, int64 up_to); + int64_t Reposition(int64_t before_to_move, int64_t up_to); RoutingTransitCallback2 arc_evaluator_; }; @@ -105,7 +114,7 @@ class MakePairActiveOperator : public PathOperator { public: MakePairActiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs); ~MakePairActiveOperator() override {} bool MakeNeighbor() override; @@ -113,13 +122,13 @@ class MakePairActiveOperator : public PathOperator { protected: bool MakeOneNeighbor() override; - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { /// Both base nodes have to be on the same path since they represent the /// nodes after which unactive node pairs will be moved. return true; } - int64 GetBaseNodeRestartPosition(int base_index) override; + int64_t GetBaseNodeRestartPosition(int base_index) override; /// Required to ensure that after synchronization the operator is in a state /// compatible with GetBaseNodeRestartPosition. @@ -128,7 +137,7 @@ class MakePairActiveOperator : public PathOperator { private: void OnNodeInitialization() override; int FindNextInactivePair(int pair_index) const; - bool ContainsActiveNodes(const std::vector& nodes) const; + bool ContainsActiveNodes(const std::vector& nodes) const; int inactive_pair_; int inactive_pair_first_index_; @@ -141,7 +150,7 @@ class MakePairInactiveOperator : public PathOperator { public: MakePairInactiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); bool MakeNeighbor() override; @@ -160,7 +169,7 @@ class PairRelocateOperator : public PathOperator { public: PairRelocateOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); ~PairRelocateOperator() override {} @@ -168,13 +177,13 @@ class PairRelocateOperator : public PathOperator { std::string DebugString() const override { return "PairRelocateOperator"; } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { /// Both destination nodes must be on the same path. return base_index == kPairSecondNodeDestination; } - int64 GetBaseNodeRestartPosition(int base_index) override; + int64_t GetBaseNodeRestartPosition(int base_index) override; - bool ConsiderAlternatives(int64 base_index) const override { + bool ConsiderAlternatives(int64_t base_index) const override { return base_index == kPairFirstNode; } @@ -190,7 +199,7 @@ class LightPairRelocateOperator : public PathOperator { public: LightPairRelocateOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); ~LightPairRelocateOperator() override {} @@ -210,7 +219,7 @@ class PairExchangeOperator : public PathOperator { public: PairExchangeOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); ~PairExchangeOperator() override {} @@ -219,9 +228,9 @@ class PairExchangeOperator : public PathOperator { private: bool RestartAtPathStartOnSynchronize() override { return true; } - bool ConsiderAlternatives(int64 base_index) const override { return true; } - bool GetPreviousAndSibling(int64 node, int64* previous, int64* sibling, - int64* sibling_previous) const; + bool ConsiderAlternatives(int64_t base_index) const override { return true; } + bool GetPreviousAndSibling(int64_t node, int64_t* previous, int64_t* sibling, + int64_t* sibling_previous) const; }; /// Operator which exchanges the paths of two pairs (path have to be different). @@ -239,10 +248,11 @@ class PairExchangeOperator : public PathOperator { /// 1 -> 2 -> C -> D -> 3 4 -> 5 -> A -> B -> 6 class PairExchangeRelocateOperator : public PathOperator { public: - PairExchangeRelocateOperator(const std::vector& vars, - const std::vector& secondary_vars, - std::function start_empty_path_class, - const RoutingIndexPairs& index_pairs); + PairExchangeRelocateOperator( + const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingIndexPairs& index_pairs); ~PairExchangeRelocateOperator() override {} bool MakeNeighbor() override; @@ -251,17 +261,17 @@ class PairExchangeRelocateOperator : public PathOperator { } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override; - int64 GetBaseNodeRestartPosition(int base_index) override; + bool OnSamePathAsPreviousBase(int64_t base_index) override; + int64_t GetBaseNodeRestartPosition(int base_index) override; private: bool RestartAtPathStartOnSynchronize() override { return true; } - bool GetPreviousAndSibling(int64 node, int64* previous, int64* sibling, - int64* sibling_previous) const; - bool MoveNode(int pair, int node, int64 nodes[2][2], int64 dest[2][2], - int64 prev[2][2]); - bool LoadAndCheckDest(int pair, int node, int64 base_node, int64 nodes[2][2], - int64 dest[2][2]) const; + bool GetPreviousAndSibling(int64_t node, int64_t* previous, int64_t* sibling, + int64_t* sibling_previous) const; + bool MoveNode(int pair, int node, int64_t nodes[2][2], int64_t dest[2][2], + int64_t prev[2][2]); + bool LoadAndCheckDest(int pair, int node, int64_t base_node, + int64_t nodes[2][2], int64_t dest[2][2]) const; static constexpr int kFirstPairFirstNode = 0; static constexpr int kSecondPairFirstNode = 1; @@ -285,7 +295,7 @@ class SwapIndexPairOperator : public IntVarLocalSearchOperator { public: SwapIndexPairOperator(const std::vector& vars, const std::vector& path_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); ~SwapIndexPairOperator() override {} @@ -298,7 +308,7 @@ class SwapIndexPairOperator : public IntVarLocalSearchOperator { /// active nodes of the node pair of index pair_index_. bool UpdateActiveNodes(); /// Sets the to to be the node after from - void SetNext(int64 from, int64 to, int64 path) { + void SetNext(int64_t from, int64_t to, int64_t path) { DCHECK_LT(from, number_of_nexts_); SetValue(from, to); if (!ignore_path_vars_) { @@ -311,9 +321,9 @@ class SwapIndexPairOperator : public IntVarLocalSearchOperator { int pair_index_; int first_index_; int second_index_; - int64 first_active_; - int64 second_active_; - std::vector prevs_; + int64_t first_active_; + int64_t second_active_; + std::vector prevs_; const int number_of_nexts_; const bool ignore_path_vars_; }; @@ -322,10 +332,11 @@ class SwapIndexPairOperator : public IntVarLocalSearchOperator { /// active nodes inactive. class IndexPairSwapActiveOperator : public PathOperator { public: - IndexPairSwapActiveOperator(const std::vector& vars, - const std::vector& secondary_vars, - std::function start_empty_path_class, - const RoutingIndexPairs& index_pairs); + IndexPairSwapActiveOperator( + const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingIndexPairs& index_pairs); ~IndexPairSwapActiveOperator() override {} bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override; @@ -356,7 +367,7 @@ class FilteredHeuristicLocalSearchOperator : public IntVarLocalSearchOperator { /// Virtual method to return the next_accessor to be passed to the heuristic /// to build a new solution. This method should also correctly set the /// nodes being removed (if any) in removed_nodes_. - virtual std::function SetupNextAccessorForNeighbor() = 0; + virtual std::function SetupNextAccessorForNeighbor() = 0; std::string HeuristicName() const { std::string heuristic_name = heuristic_->DebugString(); @@ -382,7 +393,7 @@ class FilteredHeuristicLocalSearchOperator : public IntVarLocalSearchOperator { bool MakeOneNeighbor() override; bool MakeChangesAndInsertNodes(); - int64 VehicleVarIndex(int64 node) const { return model_.Size() + node; } + int64_t VehicleVarIndex(int64_t node) const { return model_.Size() + node; } const std::unique_ptr heuristic_; const bool consider_vehicle_vars_; @@ -408,7 +419,7 @@ class FilteredHeuristicPathLNSOperator bool CurrentRouteIsEmpty() const; void IncrementCurrentRouteToNextNonEmpty(); - std::function SetupNextAccessorForNeighbor() override; + std::function SetupNextAccessorForNeighbor() override; int current_route_; int last_route_; @@ -436,7 +447,7 @@ class RelocatePathAndHeuristicInsertUnperformedOperator bool IncrementPosition() override; bool IncrementRoutes(); - std::function SetupNextAccessorForNeighbor() override; + std::function SetupNextAccessorForNeighbor() override; int route_to_relocate_index_; int last_route_to_relocate_index_; @@ -444,7 +455,7 @@ class RelocatePathAndHeuristicInsertUnperformedOperator int last_empty_route_index_; std::vector routes_to_relocate_; std::vector empty_routes_; - std::vector last_node_on_route_; + std::vector last_node_on_route_; bool has_unperformed_nodes_; bool just_started_; }; @@ -458,7 +469,8 @@ class FilteredHeuristicExpensiveChainLNSOperator FilteredHeuristicExpensiveChainLNSOperator( std::unique_ptr heuristic, int num_arcs_to_consider, - std::function arc_cost_for_route_start); + std::function + arc_cost_for_route_start); ~FilteredHeuristicExpensiveChainLNSOperator() override {} std::string DebugString() const override { @@ -473,19 +485,19 @@ class FilteredHeuristicExpensiveChainLNSOperator bool IncrementCurrentArcIndices(); bool FindMostExpensiveChainsOnRemainingRoutes(); - std::function SetupNextAccessorForNeighbor() override; + std::function SetupNextAccessorForNeighbor() override; int current_route_; int last_route_; const int num_arcs_to_consider_; - std::vector> most_expensive_arc_starts_and_ranks_; + std::vector> most_expensive_arc_starts_and_ranks_; /// Indices in most_expensive_arc_starts_and_ranks_ corresponding to the first /// and second arcs currently being considered for removal. std::pair current_expensive_arc_indices_; - std::function + std::function arc_cost_for_route_start_; bool just_started_; @@ -510,40 +522,40 @@ class FilteredHeuristicCloseNodesLNSOperator bool IncrementPosition() override; - std::function SetupNextAccessorForNeighbor() override; + std::function SetupNextAccessorForNeighbor() override; - void RemoveNode(int64 node); - void RemoveNodeAndActiveSibling(int64 node); + void RemoveNode(int64_t node); + void RemoveNodeAndActiveSibling(int64_t node); - bool IsActive(int64 node) const { + bool IsActive(int64_t node) const { DCHECK_LT(node, model_.Size()); return Value(node) != node && !removed_nodes_[node]; } - int64 Prev(int64 node) const { + int64_t Prev(int64_t node) const { DCHECK_EQ(Value(InverseValue(node)), node); DCHECK_LT(node, new_prevs_.size()); return changed_prevs_[node] ? new_prevs_[node] : InverseValue(node); } - int64 Next(int64 node) const { + int64_t Next(int64_t node) const { DCHECK(!model_.IsEnd(node)); return changed_nexts_[node] ? new_nexts_[node] : Value(node); } - std::vector GetActiveSiblings(int64 node) const; + std::vector GetActiveSiblings(int64_t node) const; - const std::vector, std::vector>>& + const std::vector, std::vector>>& pickup_delivery_pairs_; int current_node_; int last_node_; bool just_started_; - std::vector> close_nodes_; + std::vector> close_nodes_; /// Keep track of changes when making a neighbor. - std::vector new_nexts_; + std::vector new_nexts_; SparseBitset<> changed_nexts_; - std::vector new_prevs_; + std::vector new_prevs_; SparseBitset<> changed_prevs_; }; @@ -556,12 +568,12 @@ class FilteredHeuristicCloseNodesLNSOperator /// most expensive arcs on this path. class RelocateExpensiveChain : public PathOperator { public: - RelocateExpensiveChain( - const std::vector& vars, - const std::vector& secondary_vars, - std::function start_empty_path_class, - int num_arcs_to_consider, - std::function arc_cost_for_path_start); + RelocateExpensiveChain(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + int num_arcs_to_consider, + std::function + arc_cost_for_path_start); ~RelocateExpensiveChain() override {} bool MakeNeighbor() override; bool MakeOneNeighbor() override; @@ -579,13 +591,13 @@ class RelocateExpensiveChain : public PathOperator { int num_arcs_to_consider_; int current_path_; - std::vector> most_expensive_arc_starts_and_ranks_; + std::vector> most_expensive_arc_starts_and_ranks_; /// Indices in most_expensive_arc_starts_and_ranks_ corresponding to the first /// and second arcs currently being considered for removal. std::pair current_expensive_arc_indices_; - std::function + std::function arc_cost_for_path_start_; int end_path_; /// The following boolean indicates if there are any non-empty paths left to @@ -605,7 +617,7 @@ class PairNodeSwapActiveOperator : public PathOperator { public: PairNodeSwapActiveOperator(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs); ~PairNodeSwapActiveOperator() override {} @@ -616,13 +628,13 @@ class PairNodeSwapActiveOperator : public PathOperator { } protected: - bool OnSamePathAsPreviousBase(int64 base_index) override { + bool OnSamePathAsPreviousBase(int64_t base_index) override { /// Both base nodes have to be on the same path since they represent the /// nodes after which unactive node pairs will be moved. return true; } - int64 GetBaseNodeRestartPosition(int base_index) override; + int64_t GetBaseNodeRestartPosition(int base_index) override; /// Required to ensure that after synchronization the operator is in a state /// compatible with GetBaseNodeRestartPosition. @@ -642,7 +654,7 @@ template PairNodeSwapActiveOperator::PairNodeSwapActiveOperator( const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& index_pairs) : PathOperator(vars, secondary_vars, 2, false, false, std::move(start_empty_path_class)), @@ -650,7 +662,7 @@ PairNodeSwapActiveOperator::PairNodeSwapActiveOperator( pairs_(index_pairs) {} template -int64 PairNodeSwapActiveOperator::GetBaseNodeRestartPosition( +int64_t PairNodeSwapActiveOperator::GetBaseNodeRestartPosition( int base_index) { // Base node 1 must be after base node 0 if they are both on the same path. if (base_index == 0 || StartNode(base_index) != StartNode(base_index - 1)) { @@ -689,12 +701,12 @@ bool PairNodeSwapActiveOperator::MakeNextNeighbor( template bool PairNodeSwapActiveOperator::MakeNeighbor() { - const int64 base = BaseNode(0); + const int64_t base = BaseNode(0); if (IsPathEnd(base)) { return false; } - const int64 pair_first = pairs_[inactive_pair_].first[0]; - const int64 pair_second = pairs_[inactive_pair_].second[0]; + const int64_t pair_first = pairs_[inactive_pair_].first[0]; + const int64_t pair_second = pairs_[inactive_pair_].second[0]; if (swap_first) { return MakeActive(pair_second, BaseNode(1)) && MakeActive(pair_first, base) && @@ -721,7 +733,7 @@ class RelocateSubtrip : public PathOperator { public: RelocateSubtrip(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs); std::string DebugString() const override { return "RelocateSubtrip"; } @@ -729,9 +741,11 @@ class RelocateSubtrip : public PathOperator { private: // Relocates the subtrip starting at chain_first_node. It must be a pickup. - bool RelocateSubTripFromPickup(int64 chain_first_node, int64 insertion_node); + bool RelocateSubTripFromPickup(int64_t chain_first_node, + int64_t insertion_node); /// Relocates the subtrip ending at chain_first_node. It must be a delivery. - bool RelocateSubTripFromDelivery(int64 chain_last_node, int64 insertion_node); + bool RelocateSubTripFromDelivery(int64_t chain_last_node, + int64_t insertion_node); std::vector is_pickup_node_; std::vector is_delivery_node_; std::vector pair_of_node_; @@ -740,15 +754,15 @@ class RelocateSubtrip : public PathOperator { // RelocateSubTripFromPickup() and RelocateSubTripFromDelivery(). std::vector opened_pairs_bitset_; - std::vector rejected_nodes_; - std::vector subtrip_nodes_; + std::vector rejected_nodes_; + std::vector subtrip_nodes_; }; class ExchangeSubtrip : public PathOperator { public: ExchangeSubtrip(const std::vector& vars, const std::vector& secondary_vars, - std::function start_empty_path_class, + std::function start_empty_path_class, const RoutingIndexPairs& pairs); std::string DebugString() const override { return "ExchangeSubtrip"; } @@ -763,24 +777,25 @@ class ExchangeSubtrip : public PathOperator { // remain in the original path, i.e. when rejects is empty after // chain extraction. In that case, we keep only a canonical move out of the // two possibilities, the move where base_node is a pickup. - bool ExtractChainsAndCheckCanonical(int64 base_node, - std::vector* rejects, - std::vector* subtrip); + bool ExtractChainsAndCheckCanonical(int64_t base_node, + std::vector* rejects, + std::vector* subtrip); // Reads the path from base_node forward, collecting subtrip nodes in // subtrip and non-subtrip nodes in rejects. // Non-subtrip nodes will be unmatched delivery nodes. // base_node must be a pickup, and remaining/extracted_nodes must be empty. // Returns true if such chains could be extracted. - bool ExtractChainsFromPickup(int64 base_node, std::vector* rejects, - std::vector* subtrip); + bool ExtractChainsFromPickup(int64_t base_node, std::vector* rejects, + std::vector* subtrip); // Reads the path from base_node backward, collecting subtrip nodes in // subtrip and non-subtrip nodes in rejects. // Non-subtrip nodes will be unmatched pickup nodes. // base_node must be a delivery, and remaining/extracted_nodes must be empty. // Returns true if such chains could be extracted. - bool ExtractChainsFromDelivery(int64 base_node, std::vector* rejects, - std::vector* subtrip); - void SetPath(const std::vector& path, int path_id); + bool ExtractChainsFromDelivery(int64_t base_node, + std::vector* rejects, + std::vector* subtrip); + void SetPath(const std::vector& path, int path_id); // Precompute some information about nodes. std::vector is_pickup_node_; @@ -789,12 +804,12 @@ class ExchangeSubtrip : public PathOperator { // Represents the set of opened pairs during ExtractChainsFromXXX(). std::vector opened_pairs_set_; // Keep internal structures under hand to avoid reallocation. - std::vector rejects0_; - std::vector subtrip0_; - std::vector rejects1_; - std::vector subtrip1_; - std::vector path0_; - std::vector path1_; + std::vector rejects0_; + std::vector subtrip0_; + std::vector rejects1_; + std::vector subtrip1_; + std::vector path0_; + std::vector path1_; }; } // namespace operations_research diff --git a/ortools/constraint_solver/routing_parameters.cc b/ortools/constraint_solver/routing_parameters.cc index 7ae145ed08..73bd3291e7 100644 --- a/ortools/constraint_solver/routing_parameters.cc +++ b/ortools/constraint_solver/routing_parameters.cc @@ -13,6 +13,8 @@ #include "ortools/constraint_solver/routing_parameters.h" +#include + #include "absl/strings/str_cat.h" #include "absl/time/time.h" #include "google/protobuf/descriptor.h" @@ -55,6 +57,8 @@ RoutingSearchParameters DefaultRoutingSearchParameters() { "cheapest_insertion_first_solution_min_neighbors: 1 " "cheapest_insertion_ls_operator_neighbors_ratio: 1 " "cheapest_insertion_ls_operator_min_neighbors: 1 " + "cheapest_insertion_first_solution_use_neighbors_ratio_for_" + "initialization: false " "cheapest_insertion_add_unperformed_entries: false " "local_search_operators {" " use_relocate: BOOL_TRUE" @@ -202,7 +206,7 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 min_neighbors = + const int32_t min_neighbors = search_parameters.cheapest_insertion_first_solution_min_neighbors(); if (min_neighbors < 1) { return StrCat("Invalid cheapest_insertion_first_solution_min_neighbors: ", @@ -218,7 +222,7 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 min_neighbors = + const int32_t min_neighbors = search_parameters.cheapest_insertion_ls_operator_min_neighbors(); if (min_neighbors < 1) { return StrCat("Invalid cheapest_insertion_ls_operator_min_neighbors: ", @@ -226,7 +230,7 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 num_arcs = + const int32_t num_arcs = search_parameters.relocate_expensive_chain_num_arcs_to_consider(); if (num_arcs < 2 || num_arcs > 1e6) { return StrCat("Invalid relocate_expensive_chain_num_arcs_to_consider: ", @@ -234,7 +238,7 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 num_arcs = + const int32_t num_arcs = search_parameters.heuristic_expensive_chain_lns_num_arcs_to_consider(); if (num_arcs < 2 || num_arcs > 1e6) { return StrCat( @@ -243,7 +247,7 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 num_nodes = + const int32_t num_nodes = search_parameters.heuristic_close_nodes_lns_num_nodes(); if (num_nodes < 0 || num_nodes > 1e4) { return StrCat("Invalid heuristic_close_nodes_lns_num_nodes: ", num_nodes, @@ -266,11 +270,11 @@ std::string FindErrorInRoutingSearchParameters( } } { - const int32 num = search_parameters.number_of_solutions_to_collect(); + const int32_t num = search_parameters.number_of_solutions_to_collect(); if (num < 1) return StrCat("Invalid number_of_solutions_to_collect:", num); } { - const int64 lim = search_parameters.solution_limit(); + const int64_t lim = search_parameters.solution_limit(); if (lim < 1) return StrCat("Invalid solution_limit:", lim); } if (!IsValidNonNegativeDuration(search_parameters.time_limit())) { @@ -331,7 +335,7 @@ std::string FindErrorInRoutingSearchParameters( improvement_rate_coefficient); } - const int32 improvement_rate_solutions_distance = + const int32_t improvement_rate_solutions_distance = search_parameters.improvement_limit_parameters() .improvement_rate_solutions_distance(); if (improvement_rate_solutions_distance <= 0) { diff --git a/ortools/constraint_solver/routing_parameters.proto b/ortools/constraint_solver/routing_parameters.proto index 08a310eff7..51d83c94ec 100644 --- a/ortools/constraint_solver/routing_parameters.proto +++ b/ortools/constraint_solver/routing_parameters.proto @@ -34,7 +34,7 @@ package operations_research; // then the routing library will pick its preferred value for that parameter // automatically: this should be the case for most parameters. // To see those "default" parameters, call GetDefaultRoutingSearchParameters(). -// Next ID: 46 +// Next ID: 47 message RoutingSearchParameters { // First solution strategies, used as starting point of local search. FirstSolutionStrategy.Value first_solution_strategy = 1; @@ -96,6 +96,11 @@ message RoutingSearchParameters { double cheapest_insertion_ls_operator_neighbors_ratio = 31; int32 cheapest_insertion_ls_operator_min_neighbors = 45; + // Whether or not to only consider closest neighbors when initializing the + // assignment for the first solution. + bool + cheapest_insertion_first_solution_use_neighbors_ratio_for_initialization = + 46; // Whether or not to consider entries making the nodes/pairs unperformed in // the GlobalCheapestInsertion heuristic. bool cheapest_insertion_add_unperformed_entries = 40; diff --git a/ortools/constraint_solver/routing_sat.cc b/ortools/constraint_solver/routing_sat.cc index 53371a36d3..7c9511f5b5 100644 --- a/ortools/constraint_solver/routing_sat.cc +++ b/ortools/constraint_solver/routing_sat.cc @@ -11,8 +11,28 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/time/time.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/map_util.h" +#include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/routing.h" -#include "ortools/sat/cp_model.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/sat/cp_model.pb.h" +#include "ortools/sat/cp_model_solver.h" +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/util/saturated_arithmetic.h" namespace operations_research { namespace sat { @@ -27,7 +47,7 @@ bool RoutingModelCanBeSolvedBySat(const RoutingModel& model) { } // Adds an integer variable to a CpModelProto, returning its index in the proto. -int AddVariable(CpModelProto* cp_model, int64 lb, int64 ub) { +int AddVariable(CpModelProto* cp_model, int64_t lb, int64_t ub) { const int index = cp_model->variables_size(); IntegerVariableProto* const var = cp_model->add_variables(); var->add_domain(lb); @@ -36,7 +56,7 @@ int AddVariable(CpModelProto* cp_model, int64 lb, int64 ub) { } // Returns the unique depot node used in the CP-SAT models (as of 01/2020). -int64 GetDepotFromModel(const RoutingModel& model) { return model.Start(0); } +int64_t GetDepotFromModel(const RoutingModel& model) { return model.Start(0); } // Structure to keep track of arcs created. struct Arc { @@ -70,17 +90,17 @@ void AddDimensions(const RoutingModel& model, const ArcVarMap& arc_vars, const RoutingModel::TransitCallback2& transit = dimension->transit_evaluator(0); std::vector cumuls(dimension->cumuls().size(), -1); - const int64 min_start = dimension->cumuls()[model.Start(0)]->Min(); - const int64 max_end = std::min(dimension->cumuls()[model.End(0)]->Max(), - dimension->vehicle_capacities()[0]); + const int64_t min_start = dimension->cumuls()[model.Start(0)]->Min(); + const int64_t max_end = std::min(dimension->cumuls()[model.End(0)]->Max(), + dimension->vehicle_capacities()[0]); for (int i = 0; i < cumuls.size(); ++i) { if (model.IsStart(i) || model.IsEnd(i)) continue; // Reducing bounds supposing the triangular inequality. - const int64 cumul_min = + const int64_t cumul_min = std::max(sat::kMinIntegerValue.value(), std::max(dimension->cumuls()[i]->Min(), CapAdd(transit(model.Start(0), i), min_start))); - const int64 cumul_max = + const int64_t cumul_max = std::min(sat::kMaxIntegerValue.value(), std::min(dimension->cumuls()[i]->Max(), CapSub(max_end, transit(i, model.End(0))))); @@ -96,7 +116,7 @@ void AddDimensions(const RoutingModel& model, const ArcVarMap& arc_vars, ct->add_enforcement_literal(arc_var.second); LinearConstraintProto* arg = ct->mutable_linear(); arg->add_domain(transit(tail, head)); - arg->add_domain(kint64max); + arg->add_domain(std::numeric_limits::max()); arg->add_vars(cumuls[tail]); arg->add_coeffs(-1); arg->add_vars(cumuls[head]); @@ -186,14 +206,14 @@ void AddPickupDeliveryConstraints(const RoutingModel& model, const std::vector vehicles = CreateVehicleVars(model, arc_vars, cp_model); for (const auto& pairs : model.GetPickupAndDeliveryPairs()) { - const int64 pickup = pairs.first[0]; - const int64 delivery = pairs.second[0]; + const int64_t pickup = pairs.first[0]; + const int64_t delivery = pairs.second[0]; { // ranks[pickup] + 1 <= ranks[delivery]. ConstraintProto* ct = cp_model->add_constraints(); LinearConstraintProto* arg = ct->mutable_linear(); arg->add_domain(1); - arg->add_domain(kint64max); + arg->add_domain(std::numeric_limits::max()); arg->add_vars(ranks[delivery]); arg->add_coeffs(1); arg->add_vars(ranks[pickup]); @@ -238,9 +258,9 @@ ArcVarMap PopulateMultiRouteModelFromRoutingModel(const RoutingModel& model, if (model.IsStart(head)) continue; const int head_index = model.IsEnd(head) ? depot : head; if (head_index == tail_index) continue; - const int64 cost = tail != head ? model.GetHomogeneousCost(tail, head) - : model.UnperformedPenalty(tail); - if (cost == kint64max) continue; + const int64_t cost = tail != head ? model.GetHomogeneousCost(tail, head) + : model.UnperformedPenalty(tail); + if (cost == std::numeric_limits::max()) continue; const Arc arc = {tail_index, head_index}; if (gtl::ContainsKey(arc_vars, arc)) continue; const int index = AddVariable(cp_model, 0, 1); @@ -390,9 +410,9 @@ ArcVarMap PopulateSingleRouteModelFromRoutingModel(const RoutingModel& model, // those. if (model.IsStart(head)) continue; if (model.IsEnd(head)) head = model.Start(0); - const int64 cost = tail != head ? model.GetHomogeneousCost(tail, head) - : model.UnperformedPenalty(tail); - if (cost == kint64max) continue; + const int64_t cost = tail != head ? model.GetHomogeneousCost(tail, head) + : model.UnperformedPenalty(tail); + if (cost == std::numeric_limits::max()) continue; const int index = AddVariable(cp_model, 0, 1); circuit->add_literals(index); circuit->add_tails(tail); diff --git a/ortools/constraint_solver/routing_search.cc b/ortools/constraint_solver/routing_search.cc index 5b2df19b5a..fa9e0c0323 100644 --- a/ortools/constraint_solver/routing_search.cc +++ b/ortools/constraint_solver/routing_search.cc @@ -16,2742 +16,61 @@ // and local search filters. // TODO(user): Move all existing routing search code here. +#include "ortools/constraint_solver/routing_search.h" + #include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include #include +#include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" +#include "absl/flags/flag.h" +#include "absl/memory/memory.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "ortools/base/adjustable_priority_queue-inl.h" +#include "ortools/base/adjustable_priority_queue.h" #include "ortools/base/integral_types.h" -#include "ortools/base/iterator_adaptors.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" #include "ortools/base/map_util.h" -#include "ortools/base/small_map.h" -#include "ortools/base/small_ordered_set.h" #include "ortools/base/stl_util.h" -#include "ortools/base/strong_vector.h" +#include "ortools/constraint_solver/constraint_solver.h" #include "ortools/constraint_solver/constraint_solveri.h" #include "ortools/constraint_solver/routing.h" -#include "ortools/constraint_solver/routing_lp_scheduling.h" +#include "ortools/constraint_solver/routing_index_manager.h" #include "ortools/constraint_solver/routing_types.h" #include "ortools/graph/christofides.h" #include "ortools/util/bitset.h" +#include "ortools/util/range_query_function.h" #include "ortools/util/saturated_arithmetic.h" -ABSL_FLAG(bool, routing_strong_debug_checks, false, - "Run stronger checks in debug; these stronger tests might change " - "the complexity of the code in particular."); +namespace operations_research { +class LocalSearchPhaseParameters; +} // namespace operations_research + ABSL_FLAG(bool, routing_shift_insertion_cost_by_penalty, true, "Shift insertion costs by the penalty of the inserted node(s)."); +ABSL_FLAG(int64_t, sweep_sectors, 1, + "The number of sectors the space is divided into before it is sweeped" + " by the ray."); + namespace operations_research { -namespace { - -// Max active vehicles filter. - -class MaxActiveVehiclesFilter : public IntVarLocalSearchFilter { - public: - explicit MaxActiveVehiclesFilter(const RoutingModel& routing_model) - : IntVarLocalSearchFilter(routing_model.Nexts()), - routing_model_(routing_model), - is_active_(routing_model.vehicles(), false), - active_vehicles_(0) {} - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override { - const int64 kUnassigned = -1; - const Assignment::IntContainer& container = delta->IntVarContainer(); - const int delta_size = container.Size(); - int current_active_vehicles = active_vehicles_; - for (int i = 0; i < delta_size; ++i) { - const IntVarElement& new_element = container.Element(i); - IntVar* const var = new_element.Var(); - int64 index = kUnassigned; - if (FindIndex(var, &index) && routing_model_.IsStart(index)) { - if (new_element.Min() != new_element.Max()) { - // LNS detected. - return true; - } - const int vehicle = routing_model_.VehicleIndex(index); - const bool is_active = - (new_element.Min() != routing_model_.End(vehicle)); - if (is_active && !is_active_[vehicle]) { - ++current_active_vehicles; - } else if (!is_active && is_active_[vehicle]) { - --current_active_vehicles; - } - } - } - return current_active_vehicles <= - routing_model_.GetMaximumNumberOfActiveVehicles(); - } - - private: - void OnSynchronize(const Assignment* delta) override { - active_vehicles_ = 0; - for (int i = 0; i < routing_model_.vehicles(); ++i) { - const int index = routing_model_.Start(i); - if (IsVarSynced(index) && Value(index) != routing_model_.End(i)) { - is_active_[i] = true; - ++active_vehicles_; - } else { - is_active_[i] = false; - } - } - } - - const RoutingModel& routing_model_; - std::vector is_active_; - int active_vehicles_; -}; -} // namespace - -IntVarLocalSearchFilter* MakeMaxActiveVehiclesFilter( - const RoutingModel& routing_model) { - return routing_model.solver()->RevAlloc( - new MaxActiveVehiclesFilter(routing_model)); -} - -namespace { - -// Node disjunction filter class. - -class NodeDisjunctionFilter : public IntVarLocalSearchFilter { - public: - explicit NodeDisjunctionFilter(const RoutingModel& routing_model) - : IntVarLocalSearchFilter(routing_model.Nexts()), - routing_model_(routing_model), - active_per_disjunction_(routing_model.GetNumberOfDisjunctions(), 0), - inactive_per_disjunction_(routing_model.GetNumberOfDisjunctions(), 0), - synchronized_objective_value_(kint64min), - accepted_objective_value_(kint64min) {} - - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override { - const int64 kUnassigned = -1; - const Assignment::IntContainer& container = delta->IntVarContainer(); - const int delta_size = container.Size(); - gtl::small_map> - disjunction_active_deltas; - gtl::small_map> - disjunction_inactive_deltas; - bool lns_detected = false; - // Update active/inactive count per disjunction for each element of delta. - for (int i = 0; i < delta_size; ++i) { - const IntVarElement& new_element = container.Element(i); - IntVar* const var = new_element.Var(); - int64 index = kUnassigned; - if (FindIndex(var, &index)) { - const bool is_inactive = - (new_element.Min() <= index && new_element.Max() >= index); - if (new_element.Min() != new_element.Max()) { - lns_detected = true; - } - for (const RoutingModel::DisjunctionIndex disjunction_index : - routing_model_.GetDisjunctionIndices(index)) { - const bool active_state_changed = - !IsVarSynced(index) || (Value(index) == index) != is_inactive; - if (active_state_changed) { - if (!is_inactive) { - ++gtl::LookupOrInsert(&disjunction_active_deltas, - disjunction_index, 0); - if (IsVarSynced(index)) { - --gtl::LookupOrInsert(&disjunction_inactive_deltas, - disjunction_index, 0); - } - } else { - ++gtl::LookupOrInsert(&disjunction_inactive_deltas, - disjunction_index, 0); - if (IsVarSynced(index)) { - --gtl::LookupOrInsert(&disjunction_active_deltas, - disjunction_index, 0); - } - } - } - } - } - } - // Check if any disjunction has too many active nodes. - for (const std::pair - disjunction_active_delta : disjunction_active_deltas) { - const int current_active_nodes = - active_per_disjunction_[disjunction_active_delta.first]; - const int active_nodes = - current_active_nodes + disjunction_active_delta.second; - const int max_cardinality = routing_model_.GetDisjunctionMaxCardinality( - disjunction_active_delta.first); - // Too many active nodes. - if (active_nodes > max_cardinality) { - return false; - } - } - // Update penalty costs for disjunctions. - accepted_objective_value_ = synchronized_objective_value_; - for (const std::pair - disjunction_inactive_delta : disjunction_inactive_deltas) { - const int64 penalty = routing_model_.GetDisjunctionPenalty( - disjunction_inactive_delta.first); - if (penalty != 0 && !lns_detected) { - const RoutingModel::DisjunctionIndex disjunction_index = - disjunction_inactive_delta.first; - const int current_inactive_nodes = - inactive_per_disjunction_[disjunction_index]; - const int inactive_nodes = - current_inactive_nodes + disjunction_inactive_delta.second; - const int max_inactive_cardinality = - routing_model_.GetDisjunctionIndices(disjunction_index).size() - - routing_model_.GetDisjunctionMaxCardinality(disjunction_index); - // Too many inactive nodes. - if (inactive_nodes > max_inactive_cardinality) { - if (penalty < 0) { - // Nodes are mandatory, i.e. exactly max_cardinality nodes must be - // performed, so the move is not acceptable. - return false; - } else if (current_inactive_nodes <= max_inactive_cardinality) { - // Add penalty if there were not too many inactive nodes before the - // move. - accepted_objective_value_ = - CapAdd(accepted_objective_value_, penalty); - } - } else if (current_inactive_nodes > max_inactive_cardinality) { - // Remove penalty if there were too many inactive nodes before the - // move and there are not too many after the move. - accepted_objective_value_ = - CapSub(accepted_objective_value_, penalty); - } - } - } - if (lns_detected) { - accepted_objective_value_ = 0; - return true; - } else { - // Only compare to max as a cost lower bound is computed. - return accepted_objective_value_ <= objective_max; - } - } - std::string DebugString() const override { return "NodeDisjunctionFilter"; } - int64 GetSynchronizedObjectiveValue() const override { - return synchronized_objective_value_; - } - int64 GetAcceptedObjectiveValue() const override { - return accepted_objective_value_; - } - - private: - void OnSynchronize(const Assignment* delta) override { - synchronized_objective_value_ = 0; - for (RoutingModel::DisjunctionIndex i(0); - i < active_per_disjunction_.size(); ++i) { - active_per_disjunction_[i] = 0; - inactive_per_disjunction_[i] = 0; - const std::vector& disjunction_indices = - routing_model_.GetDisjunctionIndices(i); - for (const int64 index : disjunction_indices) { - const bool index_synced = IsVarSynced(index); - if (index_synced) { - if (Value(index) != index) { - ++active_per_disjunction_[i]; - } else { - ++inactive_per_disjunction_[i]; - } - } - } - const int64 penalty = routing_model_.GetDisjunctionPenalty(i); - const int max_cardinality = - routing_model_.GetDisjunctionMaxCardinality(i); - if (inactive_per_disjunction_[i] > - disjunction_indices.size() - max_cardinality && - penalty > 0) { - synchronized_objective_value_ = - CapAdd(synchronized_objective_value_, penalty); - } - } - } - - const RoutingModel& routing_model_; - - absl::StrongVector - active_per_disjunction_; - absl::StrongVector - inactive_per_disjunction_; - int64 synchronized_objective_value_; - int64 accepted_objective_value_; -}; -} // namespace - -IntVarLocalSearchFilter* MakeNodeDisjunctionFilter( - const RoutingModel& routing_model) { - return routing_model.solver()->RevAlloc( - new NodeDisjunctionFilter(routing_model)); -} - -const int64 BasePathFilter::kUnassigned = -1; - -BasePathFilter::BasePathFilter(const std::vector& nexts, - int next_domain_size) - : IntVarLocalSearchFilter(nexts), - node_path_starts_(next_domain_size, kUnassigned), - paths_(nexts.size(), -1), - new_synchronized_unperformed_nodes_(nexts.size()), - new_nexts_(nexts.size(), kUnassigned), - touched_paths_(nexts.size()), - touched_path_chain_start_ends_(nexts.size(), {kUnassigned, kUnassigned}), - ranks_(next_domain_size, -1), - status_(BasePathFilter::UNKNOWN) {} - -bool BasePathFilter::Accept(const Assignment* delta, - const Assignment* deltadelta, int64 objective_min, - int64 objective_max) { - if (IsDisabled()) return true; - for (const int touched : delta_touched_) { - new_nexts_[touched] = kUnassigned; - } - delta_touched_.clear(); - const Assignment::IntContainer& container = delta->IntVarContainer(); - const int delta_size = container.Size(); - delta_touched_.reserve(delta_size); - // Determining touched paths and their touched chain start and ends (a node is - // touched if it corresponds to an element of delta or that an element of - // delta points to it). - // The start and end of a touched path subchain will have remained on the same - // path and will correspond to the min and max ranks of touched nodes in the - // current assignment. - for (int64 touched_path : touched_paths_.PositionsSetAtLeastOnce()) { - touched_path_chain_start_ends_[touched_path] = {kUnassigned, kUnassigned}; - } - touched_paths_.SparseClearAll(); - - const auto update_touched_path_chain_start_end = [this](int64 index) { - const int64 start = node_path_starts_[index]; - if (start == kUnassigned) return; - touched_paths_.Set(start); - - int64& chain_start = touched_path_chain_start_ends_[start].first; - if (chain_start == kUnassigned || ranks_[index] < ranks_[chain_start]) { - chain_start = index; - } - - int64& chain_end = touched_path_chain_start_ends_[start].second; - if (chain_end == kUnassigned || ranks_[index] > ranks_[chain_end]) { - chain_end = index; - } - }; - - for (int i = 0; i < delta_size; ++i) { - const IntVarElement& new_element = container.Element(i); - IntVar* const var = new_element.Var(); - int64 index = kUnassigned; - if (FindIndex(var, &index)) { - if (!new_element.Bound()) { - // LNS detected - return true; - } - new_nexts_[index] = new_element.Value(); - delta_touched_.push_back(index); - update_touched_path_chain_start_end(index); - update_touched_path_chain_start_end(new_nexts_[index]); - } - } - // Checking feasibility of touched paths. - InitializeAcceptPath(); - bool accept = true; - for (const int64 touched_start : touched_paths_.PositionsSetAtLeastOnce()) { - const std::pair start_end = - touched_path_chain_start_ends_[touched_start]; - if (!AcceptPath(touched_start, start_end.first, start_end.second)) { - accept = false; - break; - } - } - // NOTE: FinalizeAcceptPath() is only called if all paths are accepted. - return accept && FinalizeAcceptPath(delta, objective_min, objective_max); -} - -void BasePathFilter::ComputePathStarts(std::vector* path_starts, - std::vector* index_to_path) { - path_starts->clear(); - const int nexts_size = Size(); - index_to_path->assign(nexts_size, kUnassigned); - Bitset64<> has_prevs(nexts_size); - for (int i = 0; i < nexts_size; ++i) { - if (!IsVarSynced(i)) { - has_prevs.Set(i); - } else { - const int next = Value(i); - if (next < nexts_size) { - has_prevs.Set(next); - } - } - } - for (int i = 0; i < nexts_size; ++i) { - if (!has_prevs[i]) { - (*index_to_path)[i] = path_starts->size(); - path_starts->push_back(i); - } - } -} - -bool BasePathFilter::HavePathsChanged() { - std::vector path_starts; - std::vector index_to_path(Size(), kUnassigned); - ComputePathStarts(&path_starts, &index_to_path); - if (path_starts.size() != starts_.size()) { - return true; - } - for (int i = 0; i < path_starts.size(); ++i) { - if (path_starts[i] != starts_[i]) { - return true; - } - } - for (int i = 0; i < Size(); ++i) { - if (index_to_path[i] != paths_[i]) { - return true; - } - } - return false; -} - -void BasePathFilter::SynchronizeFullAssignment() { - // Subclasses of BasePathFilter might not propagate injected objective values - // so making sure it is done here (can be done again by the subclass if - // needed). - ComputePathStarts(&starts_, &paths_); - for (int64 index = 0; index < Size(); index++) { - if (IsVarSynced(index) && Value(index) == index && - node_path_starts_[index] != kUnassigned) { - // index was performed before and is now unperformed. - new_synchronized_unperformed_nodes_.Set(index); - } - } - // Marking unactive nodes (which are not on a path). - node_path_starts_.assign(node_path_starts_.size(), kUnassigned); - // Marking nodes on a path and storing next values. - const int nexts_size = Size(); - for (const int64 start : starts_) { - int node = start; - node_path_starts_[node] = start; - DCHECK(IsVarSynced(node)); - int next = Value(node); - while (next < nexts_size) { - node = next; - node_path_starts_[node] = start; - DCHECK(IsVarSynced(node)); - next = Value(node); - } - node_path_starts_[next] = start; - } - OnBeforeSynchronizePaths(); - UpdateAllRanks(); - OnAfterSynchronizePaths(); -} - -void BasePathFilter::OnSynchronize(const Assignment* delta) { - if (status_ == BasePathFilter::UNKNOWN) { - status_ = - DisableFiltering() ? BasePathFilter::DISABLED : BasePathFilter::ENABLED; - } - if (IsDisabled()) return; - new_synchronized_unperformed_nodes_.ClearAll(); - if (delta == nullptr || delta->Empty() || starts_.empty()) { - SynchronizeFullAssignment(); - return; - } - // Subclasses of BasePathFilter might not propagate injected objective values - // so making sure it is done here (can be done again by the subclass if - // needed). - // This code supposes that path starts didn't change. - DCHECK(!absl::GetFlag(FLAGS_routing_strong_debug_checks) || - !HavePathsChanged()); - const Assignment::IntContainer& container = delta->IntVarContainer(); - touched_paths_.SparseClearAll(); - for (int i = 0; i < container.Size(); ++i) { - const IntVarElement& new_element = container.Element(i); - int64 index = kUnassigned; - if (FindIndex(new_element.Var(), &index)) { - const int64 start = node_path_starts_[index]; - if (start != kUnassigned) { - touched_paths_.Set(start); - if (Value(index) == index) { - // New unperformed node (its previous start isn't unassigned). - DCHECK_LT(index, new_nexts_.size()); - new_synchronized_unperformed_nodes_.Set(index); - node_path_starts_[index] = kUnassigned; - } - } - } - } - OnBeforeSynchronizePaths(); - for (const int64 touched_start : touched_paths_.PositionsSetAtLeastOnce()) { - int64 node = touched_start; - while (node < Size()) { - node_path_starts_[node] = touched_start; - node = Value(node); - } - node_path_starts_[node] = touched_start; - UpdatePathRanksFromStart(touched_start); - OnSynchronizePathFromStart(touched_start); - } - OnAfterSynchronizePaths(); -} - -void BasePathFilter::UpdateAllRanks() { - for (int i = 0; i < ranks_.size(); ++i) { - ranks_[i] = kUnassigned; - } - for (int r = 0; r < NumPaths(); ++r) { - UpdatePathRanksFromStart(Start(r)); - OnSynchronizePathFromStart(Start(r)); - } -} - -void BasePathFilter::UpdatePathRanksFromStart(int start) { - int rank = 0; - int64 node = start; - while (node < Size()) { - ranks_[node] = rank; - rank++; - node = Value(node); - } - ranks_[node] = rank; -} - -namespace { - -class VehicleAmortizedCostFilter : public BasePathFilter { - public: - explicit VehicleAmortizedCostFilter(const RoutingModel& routing_model); - ~VehicleAmortizedCostFilter() override {} - std::string DebugString() const override { - return "VehicleAmortizedCostFilter"; - } - int64 GetSynchronizedObjectiveValue() const override { - return current_vehicle_cost_; - } - int64 GetAcceptedObjectiveValue() const override { - return delta_vehicle_cost_; - } - - private: - void OnSynchronizePathFromStart(int64 start) override; - void OnAfterSynchronizePaths() override; - void InitializeAcceptPath() override; - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min, - int64 objective_max) override; - - int64 current_vehicle_cost_; - int64 delta_vehicle_cost_; - std::vector current_route_lengths_; - std::vector start_to_end_; - std::vector start_to_vehicle_; - std::vector vehicle_to_start_; - const std::vector& linear_cost_factor_of_vehicle_; - const std::vector& quadratic_cost_factor_of_vehicle_; -}; - -VehicleAmortizedCostFilter::VehicleAmortizedCostFilter( - const RoutingModel& routing_model) - : BasePathFilter(routing_model.Nexts(), - routing_model.Size() + routing_model.vehicles()), - current_vehicle_cost_(0), - delta_vehicle_cost_(0), - current_route_lengths_(Size(), -1), - linear_cost_factor_of_vehicle_( - routing_model.GetAmortizedLinearCostFactorOfVehicles()), - quadratic_cost_factor_of_vehicle_( - routing_model.GetAmortizedQuadraticCostFactorOfVehicles()) { - start_to_end_.resize(Size(), -1); - start_to_vehicle_.resize(Size(), -1); - vehicle_to_start_.resize(routing_model.vehicles()); - for (int v = 0; v < routing_model.vehicles(); v++) { - const int64 start = routing_model.Start(v); - start_to_vehicle_[start] = v; - start_to_end_[start] = routing_model.End(v); - vehicle_to_start_[v] = start; - } -} - -void VehicleAmortizedCostFilter::OnSynchronizePathFromStart(int64 start) { - const int64 end = start_to_end_[start]; - CHECK_GE(end, 0); - const int route_length = Rank(end) - 1; - CHECK_GE(route_length, 0); - current_route_lengths_[start] = route_length; -} - -void VehicleAmortizedCostFilter::OnAfterSynchronizePaths() { - current_vehicle_cost_ = 0; - for (int vehicle = 0; vehicle < vehicle_to_start_.size(); vehicle++) { - const int64 start = vehicle_to_start_[vehicle]; - DCHECK_EQ(vehicle, start_to_vehicle_[start]); - - const int route_length = current_route_lengths_[start]; - DCHECK_GE(route_length, 0); - - if (route_length == 0) { - // The path is empty. - continue; - } - - const int64 linear_cost_factor = linear_cost_factor_of_vehicle_[vehicle]; - const int64 route_length_cost = - CapProd(quadratic_cost_factor_of_vehicle_[vehicle], - route_length * route_length); - - current_vehicle_cost_ = CapAdd( - current_vehicle_cost_, CapSub(linear_cost_factor, route_length_cost)); - } -} - -void VehicleAmortizedCostFilter::InitializeAcceptPath() { - delta_vehicle_cost_ = current_vehicle_cost_; -} - -bool VehicleAmortizedCostFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - // Number of nodes previously between chain_start and chain_end - const int previous_chain_nodes = Rank(chain_end) - 1 - Rank(chain_start); - CHECK_GE(previous_chain_nodes, 0); - int new_chain_nodes = 0; - int64 node = GetNext(chain_start); - while (node != chain_end) { - new_chain_nodes++; - node = GetNext(node); - } - - const int previous_route_length = current_route_lengths_[path_start]; - CHECK_GE(previous_route_length, 0); - const int new_route_length = - previous_route_length - previous_chain_nodes + new_chain_nodes; - - const int vehicle = start_to_vehicle_[path_start]; - CHECK_GE(vehicle, 0); - DCHECK_EQ(path_start, vehicle_to_start_[vehicle]); - - // Update the cost related to used vehicles. - // TODO(user): Handle possible overflows. - if (previous_route_length == 0) { - // The route was empty before, it is no longer the case (changed path). - CHECK_GT(new_route_length, 0); - delta_vehicle_cost_ = - CapAdd(delta_vehicle_cost_, linear_cost_factor_of_vehicle_[vehicle]); - } else if (new_route_length == 0) { - // The route is now empty. - delta_vehicle_cost_ = - CapSub(delta_vehicle_cost_, linear_cost_factor_of_vehicle_[vehicle]); - } - - // Update the cost related to the sum of the squares of the route lengths. - const int64 quadratic_cost_factor = - quadratic_cost_factor_of_vehicle_[vehicle]; - delta_vehicle_cost_ = - CapAdd(delta_vehicle_cost_, - CapProd(quadratic_cost_factor, - previous_route_length * previous_route_length)); - delta_vehicle_cost_ = CapSub( - delta_vehicle_cost_, - CapProd(quadratic_cost_factor, new_route_length * new_route_length)); - - return true; -} - -bool VehicleAmortizedCostFilter::FinalizeAcceptPath(const Assignment* delta, - int64 objective_min, - int64 objective_max) { - return delta_vehicle_cost_ <= objective_max; -} - -} // namespace - -IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter( - const RoutingModel& routing_model) { - return routing_model.solver()->RevAlloc( - new VehicleAmortizedCostFilter(routing_model)); -} - -namespace { - -class TypeRegulationsFilter : public BasePathFilter { - public: - explicit TypeRegulationsFilter(const RoutingModel& model); - ~TypeRegulationsFilter() override {} - std::string DebugString() const override { return "TypeRegulationsFilter"; } - - private: - void OnSynchronizePathFromStart(int64 start) override; - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - - bool HardIncompatibilitiesRespected(int vehicle, int64 chain_start, - int64 chain_end); - - const RoutingModel& routing_model_; - std::vector start_to_vehicle_; - // The following vector is used to keep track of the type counts for hard - // incompatibilities. - std::vector> hard_incompatibility_type_counts_per_vehicle_; - // Used to verify the temporal incompatibilities and requirements. - TypeIncompatibilityChecker temporal_incompatibility_checker_; - TypeRequirementChecker requirement_checker_; -}; - -TypeRegulationsFilter::TypeRegulationsFilter(const RoutingModel& model) - : BasePathFilter(model.Nexts(), model.Size() + model.vehicles()), - routing_model_(model), - start_to_vehicle_(model.Size(), -1), - temporal_incompatibility_checker_(model, - /*check_hard_incompatibilities*/ false), - requirement_checker_(model) { - const int num_vehicles = model.vehicles(); - const bool has_hard_type_incompatibilities = - model.HasHardTypeIncompatibilities(); - if (has_hard_type_incompatibilities) { - hard_incompatibility_type_counts_per_vehicle_.resize(num_vehicles); - } - const int num_visit_types = model.GetNumberOfVisitTypes(); - for (int vehicle = 0; vehicle < num_vehicles; vehicle++) { - const int64 start = model.Start(vehicle); - start_to_vehicle_[start] = vehicle; - if (has_hard_type_incompatibilities) { - hard_incompatibility_type_counts_per_vehicle_[vehicle].resize( - num_visit_types, 0); - } - } -} - -void TypeRegulationsFilter::OnSynchronizePathFromStart(int64 start) { - if (!routing_model_.HasHardTypeIncompatibilities()) return; - - const int vehicle = start_to_vehicle_[start]; - CHECK_GE(vehicle, 0); - std::vector& type_counts = - hard_incompatibility_type_counts_per_vehicle_[vehicle]; - std::fill(type_counts.begin(), type_counts.end(), 0); - const int num_types = type_counts.size(); - - int64 node = start; - while (node < Size()) { - DCHECK(IsVarSynced(node)); - const int type = routing_model_.GetVisitType(node); - if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != - RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { - CHECK_LT(type, num_types); - type_counts[type]++; - } - node = Value(node); - } -} - -bool TypeRegulationsFilter::HardIncompatibilitiesRespected(int vehicle, - int64 chain_start, - int64 chain_end) { - if (!routing_model_.HasHardTypeIncompatibilities()) return true; - - const std::vector& previous_type_counts = - hard_incompatibility_type_counts_per_vehicle_[vehicle]; - - absl::flat_hash_map new_type_counts; - absl::flat_hash_set types_to_check; - - // Go through the new nodes on the path and increment their type counts. - int64 node = GetNext(chain_start); - while (node != chain_end) { - const int type = routing_model_.GetVisitType(node); - if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != - RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { - DCHECK_LT(type, previous_type_counts.size()); - int& type_count = gtl::LookupOrInsert(&new_type_counts, type, - previous_type_counts[type]); - if (type_count++ == 0) { - // New type on the route, mark to check its incompatibilities. - types_to_check.insert(type); - } - } - node = GetNext(node); - } - - // Update new_type_counts by decrementing the occurrence of the types of the - // nodes no longer on the route. - node = Value(chain_start); - while (node != chain_end) { - const int type = routing_model_.GetVisitType(node); - if (type >= 0 && routing_model_.GetVisitTypePolicy(node) != - RoutingModel::ADDED_TYPE_REMOVED_FROM_VEHICLE) { - DCHECK_LT(type, previous_type_counts.size()); - int& type_count = gtl::LookupOrInsert(&new_type_counts, type, - previous_type_counts[type]); - CHECK_GE(type_count, 1); - type_count--; - } - node = Value(node); - } - - // Check the incompatibilities for types in types_to_check. - for (int type : types_to_check) { - for (int incompatible_type : - routing_model_.GetHardTypeIncompatibilitiesOfType(type)) { - if (gtl::FindWithDefault(new_type_counts, incompatible_type, - previous_type_counts[incompatible_type]) > 0) { - return false; - } - } - } - return true; -} - -bool TypeRegulationsFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - const int vehicle = start_to_vehicle_[path_start]; - CHECK_GE(vehicle, 0); - const auto next_accessor = [this](int64 node) { return GetNext(node); }; - return HardIncompatibilitiesRespected(vehicle, chain_start, chain_end) && - temporal_incompatibility_checker_.CheckVehicle(vehicle, - next_accessor) && - requirement_checker_.CheckVehicle(vehicle, next_accessor); -} - -} // namespace - -IntVarLocalSearchFilter* MakeTypeRegulationsFilter( - const RoutingModel& routing_model) { - return routing_model.solver()->RevAlloc( - new TypeRegulationsFilter(routing_model)); -} - -namespace { - -// ChainCumul filter. Version of dimension path filter which is O(delta) rather -// than O(length of touched paths). Currently only supports dimensions without -// costs (global and local span cost, soft bounds) and with unconstrained -// cumul variables except overall capacity and cumul variables of path ends. - -class ChainCumulFilter : public BasePathFilter { - public: - ChainCumulFilter(const RoutingModel& routing_model, - const RoutingDimension& dimension); - ~ChainCumulFilter() override {} - std::string DebugString() const override { - return "ChainCumulFilter(" + name_ + ")"; - } - - private: - void OnSynchronizePathFromStart(int64 start) override; - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - - const std::vector cumuls_; - std::vector start_to_vehicle_; - std::vector start_to_end_; - std::vector evaluators_; - const std::vector vehicle_capacities_; - std::vector current_path_cumul_mins_; - std::vector current_max_of_path_end_cumul_mins_; - std::vector old_nexts_; - std::vector old_vehicles_; - std::vector current_transits_; - const std::string name_; -}; - -ChainCumulFilter::ChainCumulFilter(const RoutingModel& routing_model, - const RoutingDimension& dimension) - : BasePathFilter(routing_model.Nexts(), dimension.cumuls().size()), - cumuls_(dimension.cumuls()), - evaluators_(routing_model.vehicles(), nullptr), - vehicle_capacities_(dimension.vehicle_capacities()), - current_path_cumul_mins_(dimension.cumuls().size(), 0), - current_max_of_path_end_cumul_mins_(dimension.cumuls().size(), 0), - old_nexts_(routing_model.Size(), kUnassigned), - old_vehicles_(routing_model.Size(), kUnassigned), - current_transits_(routing_model.Size(), 0), - name_(dimension.name()) { - start_to_vehicle_.resize(Size(), -1); - start_to_end_.resize(Size(), -1); - for (int i = 0; i < routing_model.vehicles(); ++i) { - start_to_vehicle_[routing_model.Start(i)] = i; - start_to_end_[routing_model.Start(i)] = routing_model.End(i); - evaluators_[i] = &dimension.transit_evaluator(i); - } -} - -// On synchronization, maintain "propagated" cumul mins and max level of cumul -// from each node to the end of the path; to be used by AcceptPath to -// incrementally check feasibility. -void ChainCumulFilter::OnSynchronizePathFromStart(int64 start) { - const int vehicle = start_to_vehicle_[start]; - std::vector path_nodes; - int64 node = start; - int64 cumul = cumuls_[node]->Min(); - while (node < Size()) { - path_nodes.push_back(node); - current_path_cumul_mins_[node] = cumul; - const int64 next = Value(node); - if (next != old_nexts_[node] || vehicle != old_vehicles_[node]) { - old_nexts_[node] = next; - old_vehicles_[node] = vehicle; - current_transits_[node] = (*evaluators_[vehicle])(node, next); - } - cumul = CapAdd(cumul, current_transits_[node]); - cumul = std::max(cumuls_[next]->Min(), cumul); - node = next; - } - path_nodes.push_back(node); - current_path_cumul_mins_[node] = cumul; - int64 max_cumuls = cumul; - for (int i = path_nodes.size() - 1; i >= 0; --i) { - const int64 node = path_nodes[i]; - max_cumuls = std::max(max_cumuls, current_path_cumul_mins_[node]); - current_max_of_path_end_cumul_mins_[node] = max_cumuls; - } -} - -// The complexity of the method is O(size of chain (chain_start...chain_end). -bool ChainCumulFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - const int vehicle = start_to_vehicle_[path_start]; - const int64 capacity = vehicle_capacities_[vehicle]; - int64 node = chain_start; - int64 cumul = current_path_cumul_mins_[node]; - while (node != chain_end) { - const int64 next = GetNext(node); - if (IsVarSynced(node) && next == Value(node) && - vehicle == old_vehicles_[node]) { - cumul = CapAdd(cumul, current_transits_[node]); - } else { - cumul = CapAdd(cumul, (*evaluators_[vehicle])(node, next)); - } - cumul = std::max(cumuls_[next]->Min(), cumul); - if (cumul > capacity) return false; - node = next; - } - const int64 end = start_to_end_[path_start]; - const int64 end_cumul_delta = - CapSub(current_path_cumul_mins_[end], current_path_cumul_mins_[node]); - const int64 after_chain_cumul_delta = - CapSub(current_max_of_path_end_cumul_mins_[node], - current_path_cumul_mins_[node]); - return CapAdd(cumul, after_chain_cumul_delta) <= capacity && - CapAdd(cumul, end_cumul_delta) <= cumuls_[end]->Max(); -} - -// PathCumul filter. - -class PathCumulFilter : public BasePathFilter { - public: - PathCumulFilter(const RoutingModel& routing_model, - const RoutingDimension& dimension, - const RoutingSearchParameters& parameters, - bool propagate_own_objective_value, - bool filter_objective_cost, bool can_use_lp); - ~PathCumulFilter() override {} - std::string DebugString() const override { - return "PathCumulFilter(" + name_ + ")"; - } - int64 GetSynchronizedObjectiveValue() const override { - return propagate_own_objective_value_ ? synchronized_objective_value_ : 0; - } - int64 GetAcceptedObjectiveValue() const override { - return propagate_own_objective_value_ ? accepted_objective_value_ : 0; - } - - private: - // This structure stores the "best" path cumul value for a solution, the path - // supporting this value, and the corresponding path cumul values for all - // paths. - struct SupportedPathCumul { - SupportedPathCumul() : cumul_value(0), cumul_value_support(0) {} - int64 cumul_value; - int cumul_value_support; - std::vector path_values; - }; - - struct SoftBound { - SoftBound() : bound(-1), coefficient(0) {} - int64 bound; - int64 coefficient; - }; - - // This class caches transit values between nodes of paths. Transit and path - // nodes are to be added in the order in which they appear on a path. - class PathTransits { - public: - void Clear() { - paths_.clear(); - transits_.clear(); - } - void ClearPath(int path) { - paths_[path].clear(); - transits_[path].clear(); - } - int AddPaths(int num_paths) { - const int first_path = paths_.size(); - paths_.resize(first_path + num_paths); - transits_.resize(first_path + num_paths); - return first_path; - } - void ReserveTransits(int path, int number_of_route_arcs) { - transits_[path].reserve(number_of_route_arcs); - paths_[path].reserve(number_of_route_arcs + 1); - } - // Stores the transit between node and next on path. For a given non-empty - // path, node must correspond to next in the previous call to PushTransit. - void PushTransit(int path, int node, int next, int64 transit) { - transits_[path].push_back(transit); - if (paths_[path].empty()) { - paths_[path].push_back(node); - } - DCHECK_EQ(paths_[path].back(), node); - paths_[path].push_back(next); - } - int NumPaths() const { return paths_.size(); } - int PathSize(int path) const { return paths_[path].size(); } - int Node(int path, int position) const { return paths_[path][position]; } - int64 Transit(int path, int position) const { - return transits_[path][position]; - } - - private: - // paths_[r][i] is the ith node on path r. - std::vector> paths_; - // transits_[r][i] is the transit value between nodes path_[i] and - // path_[i+1] on path r. - std::vector> transits_; - }; - - void InitializeAcceptPath() override { - cumul_cost_delta_ = total_current_cumul_cost_value_; - node_with_precedence_to_delta_min_max_cumuls_.clear(); - // Cleaning up for the new delta. - delta_max_end_cumul_ = kint64min; - delta_paths_.clear(); - delta_path_transits_.Clear(); - lns_detected_ = false; - delta_nodes_with_precedences_and_changed_cumul_.ClearAll(); - } - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min, - int64 objective_max) override; - void OnBeforeSynchronizePaths() override; - - bool FilterSpanCost() const { return global_span_cost_coefficient_ != 0; } - - bool FilterSlackCost() const { - return has_nonzero_vehicle_span_cost_coefficients_ || - has_vehicle_span_upper_bounds_; - } - - bool FilterBreakCost(int vehicle) const { - return dimension_.HasBreakConstraints() && - !dimension_.GetBreakIntervalsOfVehicle(vehicle).empty(); - } - - bool FilterCumulSoftBounds() const { return !cumul_soft_bounds_.empty(); } - - int64 GetCumulSoftCost(int64 node, int64 cumul_value) const; - - bool FilterCumulPiecewiseLinearCosts() const { - return !cumul_piecewise_linear_costs_.empty(); - } - - bool FilterWithDimensionCumulOptimizerForVehicle(int vehicle) const { - if (!can_use_lp_ || FilterCumulPiecewiseLinearCosts()) { - return false; - } - - int num_linear_constraints = 0; - if (dimension_.GetSpanCostCoefficientForVehicle(vehicle) > 0) - ++num_linear_constraints; - if (FilterSoftSpanCost(vehicle)) ++num_linear_constraints; - if (FilterCumulSoftLowerBounds()) ++num_linear_constraints; - if (FilterCumulSoftBounds()) ++num_linear_constraints; - if (vehicle_span_upper_bounds_[vehicle] < kint64max) - ++num_linear_constraints; - const bool has_breaks = FilterBreakCost(vehicle); - if (has_breaks) ++num_linear_constraints; - - // The DimensionCumulOptimizer is used to compute a more precise value of - // the cost related to the cumul values (soft bounds and span costs). - // It is also used to garantee feasibility with complex mixes of constraints - // and in particular in the presence of break requests along other - // constraints. - // Therefore, without breaks, we only use the optimizer when the costs are - // actually used to filter the solutions, i.e. when filter_objective_cost_ - // is true. - return num_linear_constraints >= 2 && - (has_breaks || filter_objective_cost_); - } - - bool FilterDimensionForbiddenIntervals() const { - for (const SortedDisjointIntervalList& intervals : - dimension_.forbidden_intervals()) { - // TODO(user): Change the following test to check intervals within - // the domain of the corresponding variables. - if (intervals.NumIntervals() > 0) { - return true; - } - } - return false; - } - - int64 GetCumulPiecewiseLinearCost(int64 node, int64 cumul_value) const; - - bool FilterCumulSoftLowerBounds() const { - return !cumul_soft_lower_bounds_.empty(); - } - - bool FilterPrecedences() const { return !node_index_to_precedences_.empty(); } - - bool FilterSoftSpanCost() const { - return dimension_.HasSoftSpanUpperBounds(); - } - bool FilterSoftSpanCost(int vehicle) const { - return dimension_.HasSoftSpanUpperBounds() && - dimension_.GetSoftSpanUpperBoundForVehicle(vehicle).cost > 0; - } - bool FilterSoftSpanQuadraticCost() const { - return dimension_.HasQuadraticCostSoftSpanUpperBounds(); - } - bool FilterSoftSpanQuadraticCost(int vehicle) const { - return dimension_.HasQuadraticCostSoftSpanUpperBounds() && - dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle) - .cost > 0; - } - - int64 GetCumulSoftLowerBoundCost(int64 node, int64 cumul_value) const; - - int64 GetPathCumulSoftLowerBoundCost(const PathTransits& path_transits, - int path) const; - - void InitializeSupportedPathCumul(SupportedPathCumul* supported_cumul, - int64 default_value); - - // Given the vector of minimum cumuls on the path, determines if the pickup to - // delivery limits for this dimension (if there are any) can be respected by - // this path. - // Returns true if for every pickup/delivery nodes visited on this path, - // min_cumul_value(delivery) - max_cumul_value(pickup) is less than the limit - // set for this pickup to delivery. - // TODO(user): Verify if we should filter the pickup/delivery limits using - // the LP, for a perfect filtering. - bool PickupToDeliveryLimitsRespected( - const PathTransits& path_transits, int path, - const std::vector& min_path_cumuls) const; - - // Computes the maximum cumul value of nodes along the path using - // [current|delta]_path_transits_, and stores the min/max cumul - // related to each node in the corresponding vector - // [current|delta]_[min|max]_node_cumuls_. - // The boolean is_delta indicates if the computations should take place on the - // "delta" or "current" members. When true, the nodes for which the min/max - // cumul has changed from the current value are marked in - // delta_nodes_with_precedences_and_changed_cumul_. - void StoreMinMaxCumulOfNodesOnPath(int path, - const std::vector& min_path_cumuls, - bool is_delta); - - // Compute the max start cumul value for a given path and a given minimal end - // cumul value. - // NOTE: Since this function is used to compute a lower bound on the span of - // the routes, we don't "jump" over the forbidden intervals with this min end - // cumul value. We do however concurrently compute the max possible start - // given the max end cumul, for which we can "jump" over forbidden intervals, - // and return the minimum of the two. - int64 ComputePathMaxStartFromEndCumul(const PathTransits& path_transits, - int path, int64 path_start, - int64 min_end_cumul) const; - - const RoutingModel& routing_model_; - const RoutingDimension& dimension_; - const std::vector cumuls_; - const std::vector slacks_; - std::vector start_to_vehicle_; - std::vector evaluators_; - std::vector vehicle_span_upper_bounds_; - bool has_vehicle_span_upper_bounds_; - int64 total_current_cumul_cost_value_; - int64 synchronized_objective_value_; - int64 accepted_objective_value_; - // Map between paths and path soft cumul bound costs. The paths are indexed - // by the index of the start node of the path. - absl::flat_hash_map current_cumul_cost_values_; - int64 cumul_cost_delta_; - // Cumul cost values for paths in delta, indexed by vehicle. - std::vector delta_path_cumul_cost_values_; - const int64 global_span_cost_coefficient_; - std::vector cumul_soft_bounds_; - std::vector cumul_soft_lower_bounds_; - std::vector cumul_piecewise_linear_costs_; - std::vector vehicle_span_cost_coefficients_; - bool has_nonzero_vehicle_span_cost_coefficients_; - const std::vector vehicle_capacities_; - // node_index_to_precedences_[node_index] contains all NodePrecedence elements - // with node_index as either "first_node" or "second_node". - // This vector is empty if there are no precedences on the dimension_. - std::vector> - node_index_to_precedences_; - // Data reflecting information on paths and cumul variables for the solution - // to which the filter was synchronized. - SupportedPathCumul current_min_start_; - SupportedPathCumul current_max_end_; - PathTransits current_path_transits_; - // Current min/max cumul values, indexed by node. - std::vector> current_min_max_node_cumuls_; - // Data reflecting information on paths and cumul variables for the "delta" - // solution (aka neighbor solution) being examined. - PathTransits delta_path_transits_; - int64 delta_max_end_cumul_; - SparseBitset delta_nodes_with_precedences_and_changed_cumul_; - absl::flat_hash_map> - node_with_precedence_to_delta_min_max_cumuls_; - // Note: small_ordered_set only support non-hash sets. - gtl::small_ordered_set> delta_paths_; - const std::string name_; - - LocalDimensionCumulOptimizer* optimizer_; - std::unique_ptr internal_optimizer_; - LocalDimensionCumulOptimizer* mp_optimizer_; - std::unique_ptr internal_mp_optimizer_; - const bool filter_objective_cost_; - // This boolean indicates if the LP optimizer can be used if necessary to - // optimize the dimension cumuls, and is only used for testing purposes. - const bool can_use_lp_; - const bool propagate_own_objective_value_; - - // Used to do span lower bounding in presence of vehicle breaks. - DisjunctivePropagator disjunctive_propagator_; - DisjunctivePropagator::Tasks tasks_; - TravelBounds travel_bounds_; - std::vector current_path_; - - bool lns_detected_; -}; - -PathCumulFilter::PathCumulFilter(const RoutingModel& routing_model, - const RoutingDimension& dimension, - const RoutingSearchParameters& parameters, - bool propagate_own_objective_value, - bool filter_objective_cost, bool can_use_lp) - : BasePathFilter(routing_model.Nexts(), dimension.cumuls().size()), - routing_model_(routing_model), - dimension_(dimension), - cumuls_(dimension.cumuls()), - slacks_(dimension.slacks()), - evaluators_(routing_model.vehicles(), nullptr), - vehicle_span_upper_bounds_(dimension.vehicle_span_upper_bounds()), - has_vehicle_span_upper_bounds_(false), - total_current_cumul_cost_value_(0), - synchronized_objective_value_(0), - accepted_objective_value_(0), - current_cumul_cost_values_(), - cumul_cost_delta_(0), - delta_path_cumul_cost_values_(routing_model.vehicles(), kint64min), - global_span_cost_coefficient_(dimension.global_span_cost_coefficient()), - vehicle_span_cost_coefficients_( - dimension.vehicle_span_cost_coefficients()), - has_nonzero_vehicle_span_cost_coefficients_(false), - vehicle_capacities_(dimension.vehicle_capacities()), - delta_max_end_cumul_(0), - delta_nodes_with_precedences_and_changed_cumul_(routing_model.Size()), - name_(dimension.name()), - optimizer_(routing_model.GetMutableLocalCumulOptimizer(dimension)), - mp_optimizer_(routing_model.GetMutableLocalCumulMPOptimizer(dimension)), - filter_objective_cost_(filter_objective_cost), - can_use_lp_(can_use_lp), - propagate_own_objective_value_(propagate_own_objective_value), - lns_detected_(false) { - for (const int64 upper_bound : vehicle_span_upper_bounds_) { - if (upper_bound != kint64max) { - has_vehicle_span_upper_bounds_ = true; - break; - } - } - for (const int64 coefficient : vehicle_span_cost_coefficients_) { - if (coefficient != 0) { - has_nonzero_vehicle_span_cost_coefficients_ = true; - break; - } - } - cumul_soft_bounds_.resize(cumuls_.size()); - cumul_soft_lower_bounds_.resize(cumuls_.size()); - cumul_piecewise_linear_costs_.resize(cumuls_.size()); - bool has_cumul_soft_bounds = false; - bool has_cumul_soft_lower_bounds = false; - bool has_cumul_piecewise_linear_costs = false; - bool has_cumul_hard_bounds = false; - for (const IntVar* const slack : slacks_) { - if (slack->Min() > 0) { - has_cumul_hard_bounds = true; - break; - } - } - for (int i = 0; i < cumuls_.size(); ++i) { - if (dimension.HasCumulVarSoftUpperBound(i)) { - has_cumul_soft_bounds = true; - cumul_soft_bounds_[i].bound = dimension.GetCumulVarSoftUpperBound(i); - cumul_soft_bounds_[i].coefficient = - dimension.GetCumulVarSoftUpperBoundCoefficient(i); - } - if (dimension.HasCumulVarSoftLowerBound(i)) { - has_cumul_soft_lower_bounds = true; - cumul_soft_lower_bounds_[i].bound = - dimension.GetCumulVarSoftLowerBound(i); - cumul_soft_lower_bounds_[i].coefficient = - dimension.GetCumulVarSoftLowerBoundCoefficient(i); - } - if (dimension.HasCumulVarPiecewiseLinearCost(i)) { - has_cumul_piecewise_linear_costs = true; - cumul_piecewise_linear_costs_[i] = - dimension.GetCumulVarPiecewiseLinearCost(i); - } - IntVar* const cumul_var = cumuls_[i]; - if (cumul_var->Min() > 0 || cumul_var->Max() < kint64max) { - has_cumul_hard_bounds = true; - } - } - if (!has_cumul_soft_bounds) { - cumul_soft_bounds_.clear(); - } - if (!has_cumul_soft_lower_bounds) { - cumul_soft_lower_bounds_.clear(); - } - if (!has_cumul_piecewise_linear_costs) { - cumul_piecewise_linear_costs_.clear(); - } - if (!has_cumul_hard_bounds) { - // Slacks don't need to be constrained if the cumuls don't have hard bounds; - // therefore we can ignore the vehicle span cost coefficient (note that the - // transit part is already handled by the arc cost filters). - // This doesn't concern the global span filter though. - vehicle_span_cost_coefficients_.assign(routing_model.vehicles(), 0); - has_nonzero_vehicle_span_cost_coefficients_ = false; - } - start_to_vehicle_.resize(Size(), -1); - for (int i = 0; i < routing_model.vehicles(); ++i) { - start_to_vehicle_[routing_model.Start(i)] = i; - evaluators_[i] = &dimension.transit_evaluator(i); - } - - const std::vector& node_precedences = - dimension.GetNodePrecedences(); - if (!node_precedences.empty()) { - current_min_max_node_cumuls_.resize(cumuls_.size(), {-1, -1}); - node_index_to_precedences_.resize(cumuls_.size()); - for (const auto& node_precedence : node_precedences) { - node_index_to_precedences_[node_precedence.first_node].push_back( - node_precedence); - node_index_to_precedences_[node_precedence.second_node].push_back( - node_precedence); - } - } - // NOTE(user): The model's local optimizer for this dimension could be - // null because the finalizer is using a global optimizer, so we create a - // separate optimizer for the PathCumulFilter if we need it. - if (can_use_lp_ && optimizer_ == nullptr) { - DCHECK(mp_optimizer_ == nullptr); - for (int vehicle = 0; vehicle < routing_model.vehicles(); vehicle++) { - if (!FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { - continue; - } - if (optimizer_ == nullptr) { - // NOTE: The optimizer_ might have already been set in the for loop, - // since we continue scanning vehicles in case one of them needs the - // the mp_optimizer_ for break constraints. - internal_optimizer_ = absl::make_unique( - &dimension, parameters.continuous_scheduling_solver()); - optimizer_ = internal_optimizer_.get(); - } - if (FilterBreakCost(vehicle) || FilterDimensionForbiddenIntervals()) { - internal_mp_optimizer_ = - absl::make_unique( - &dimension, parameters.mixed_integer_scheduling_solver()); - mp_optimizer_ = internal_mp_optimizer_.get(); - break; - } - } - } -} - -int64 PathCumulFilter::GetCumulSoftCost(int64 node, int64 cumul_value) const { - if (node < cumul_soft_bounds_.size()) { - const int64 bound = cumul_soft_bounds_[node].bound; - const int64 coefficient = cumul_soft_bounds_[node].coefficient; - if (coefficient > 0 && bound < cumul_value) { - return CapProd(CapSub(cumul_value, bound), coefficient); - } - } - return 0; -} - -int64 PathCumulFilter::GetCumulPiecewiseLinearCost(int64 node, - int64 cumul_value) const { - if (node < cumul_piecewise_linear_costs_.size()) { - const PiecewiseLinearFunction* cost = cumul_piecewise_linear_costs_[node]; - if (cost != nullptr) { - return cost->Value(cumul_value); - } - } - return 0; -} - -int64 PathCumulFilter::GetCumulSoftLowerBoundCost(int64 node, - int64 cumul_value) const { - if (node < cumul_soft_lower_bounds_.size()) { - const int64 bound = cumul_soft_lower_bounds_[node].bound; - const int64 coefficient = cumul_soft_lower_bounds_[node].coefficient; - if (coefficient > 0 && bound > cumul_value) { - return CapProd(CapSub(bound, cumul_value), coefficient); - } - } - return 0; -} - -int64 PathCumulFilter::GetPathCumulSoftLowerBoundCost( - const PathTransits& path_transits, int path) const { - int64 node = path_transits.Node(path, path_transits.PathSize(path) - 1); - int64 cumul = cumuls_[node]->Max(); - int64 current_cumul_cost_value = GetCumulSoftLowerBoundCost(node, cumul); - for (int i = path_transits.PathSize(path) - 2; i >= 0; --i) { - node = path_transits.Node(path, i); - cumul = CapSub(cumul, path_transits.Transit(path, i)); - cumul = std::min(cumuls_[node]->Max(), cumul); - current_cumul_cost_value = CapAdd(current_cumul_cost_value, - GetCumulSoftLowerBoundCost(node, cumul)); - } - return current_cumul_cost_value; -} - -void PathCumulFilter::OnBeforeSynchronizePaths() { - total_current_cumul_cost_value_ = 0; - cumul_cost_delta_ = 0; - current_cumul_cost_values_.clear(); - if (NumPaths() > 0 && - (FilterSpanCost() || FilterCumulSoftBounds() || FilterSlackCost() || - FilterCumulSoftLowerBounds() || FilterCumulPiecewiseLinearCosts() || - FilterPrecedences() || FilterSoftSpanCost() || - FilterSoftSpanQuadraticCost())) { - InitializeSupportedPathCumul(¤t_min_start_, kint64max); - InitializeSupportedPathCumul(¤t_max_end_, kint64min); - current_path_transits_.Clear(); - current_path_transits_.AddPaths(NumPaths()); - // For each path, compute the minimum end cumul and store the max of these. - for (int r = 0; r < NumPaths(); ++r) { - int64 node = Start(r); - const int vehicle = start_to_vehicle_[Start(r)]; - // First pass: evaluating route length to reserve memory to store route - // information. - int number_of_route_arcs = 0; - while (node < Size()) { - ++number_of_route_arcs; - node = Value(node); - } - current_path_transits_.ReserveTransits(r, number_of_route_arcs); - // Second pass: update cumul, transit and cost values. - node = Start(r); - int64 cumul = cumuls_[node]->Min(); - std::vector min_path_cumuls; - min_path_cumuls.reserve(number_of_route_arcs + 1); - min_path_cumuls.push_back(cumul); - - int64 current_cumul_cost_value = GetCumulSoftCost(node, cumul); - current_cumul_cost_value = CapAdd( - current_cumul_cost_value, GetCumulPiecewiseLinearCost(node, cumul)); - - int64 total_transit = 0; - while (node < Size()) { - const int64 next = Value(node); - const int64 transit = (*evaluators_[vehicle])(node, next); - total_transit = CapAdd(total_transit, transit); - const int64 transit_slack = CapAdd(transit, slacks_[node]->Min()); - current_path_transits_.PushTransit(r, node, next, transit_slack); - cumul = CapAdd(cumul, transit_slack); - cumul = - dimension_.GetFirstPossibleGreaterOrEqualValueForNode(next, cumul); - cumul = std::max(cumuls_[next]->Min(), cumul); - min_path_cumuls.push_back(cumul); - node = next; - current_cumul_cost_value = - CapAdd(current_cumul_cost_value, GetCumulSoftCost(node, cumul)); - current_cumul_cost_value = CapAdd( - current_cumul_cost_value, GetCumulPiecewiseLinearCost(node, cumul)); - } - if (FilterPrecedences()) { - StoreMinMaxCumulOfNodesOnPath(/*path=*/r, min_path_cumuls, - /*is_delta=*/false); - } - if (number_of_route_arcs == 1 && - !routing_model_.AreEmptyRouteCostsConsideredForVehicle(vehicle)) { - // This is an empty route (single start->end arc) which we don't take - // into account for costs. - current_cumul_cost_values_[Start(r)] = 0; - current_path_transits_.ClearPath(r); - continue; - } - if (FilterSlackCost() || FilterSoftSpanCost() || - FilterSoftSpanQuadraticCost()) { - const int64 start = ComputePathMaxStartFromEndCumul( - current_path_transits_, r, Start(r), cumul); - const int64 span_lower_bound = CapSub(cumul, start); - if (FilterSlackCost()) { - current_cumul_cost_value = - CapAdd(current_cumul_cost_value, - CapProd(vehicle_span_cost_coefficients_[vehicle], - CapSub(span_lower_bound, total_transit))); - } - if (FilterSoftSpanCost()) { - const SimpleBoundCosts::BoundCost bound_cost = - dimension_.GetSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.bound < span_lower_bound) { - const int64 violation = CapSub(span_lower_bound, bound_cost.bound); - current_cumul_cost_value = CapAdd( - current_cumul_cost_value, CapProd(bound_cost.cost, violation)); - } - } - if (FilterSoftSpanQuadraticCost()) { - const SimpleBoundCosts::BoundCost bound_cost = - dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.bound < span_lower_bound) { - const int64 violation = CapSub(span_lower_bound, bound_cost.bound); - current_cumul_cost_value = - CapAdd(current_cumul_cost_value, - CapProd(bound_cost.cost, CapProd(violation, violation))); - } - } - } - if (FilterCumulSoftLowerBounds()) { - current_cumul_cost_value = - CapAdd(current_cumul_cost_value, - GetPathCumulSoftLowerBoundCost(current_path_transits_, r)); - } - if (FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { - // TODO(user): Return a status from the optimizer to detect failures - // The only admissible failures here are because of LP timeout. - int64 lp_cumul_cost_value = 0; - LocalDimensionCumulOptimizer* const optimizer = - FilterBreakCost(vehicle) ? mp_optimizer_ : optimizer_; - DCHECK(optimizer != nullptr); - const DimensionSchedulingStatus status = - optimizer->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64 node) { return Value(node); }, - &lp_cumul_cost_value); - switch (status) { - case DimensionSchedulingStatus::INFEASIBLE: - lp_cumul_cost_value = 0; - break; - case DimensionSchedulingStatus::RELAXED_OPTIMAL_ONLY: - DCHECK(mp_optimizer_ != nullptr); - if (mp_optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64 node) { return Value(node); }, - &lp_cumul_cost_value) == - DimensionSchedulingStatus::INFEASIBLE) { - lp_cumul_cost_value = 0; - } - break; - default: - DCHECK(status == DimensionSchedulingStatus::OPTIMAL); - } - current_cumul_cost_value = - std::max(current_cumul_cost_value, lp_cumul_cost_value); - } - current_cumul_cost_values_[Start(r)] = current_cumul_cost_value; - current_max_end_.path_values[r] = cumul; - if (current_max_end_.cumul_value < cumul) { - current_max_end_.cumul_value = cumul; - current_max_end_.cumul_value_support = r; - } - total_current_cumul_cost_value_ = - CapAdd(total_current_cumul_cost_value_, current_cumul_cost_value); - } - if (FilterPrecedences()) { - // Update the min/max node cumuls of new unperformed nodes. - for (int64 node : GetNewSynchronizedUnperformedNodes()) { - current_min_max_node_cumuls_[node] = {-1, -1}; - } - } - // Use the max of the path end cumul mins to compute the corresponding - // maximum start cumul of each path; store the minimum of these. - for (int r = 0; r < NumPaths(); ++r) { - const int64 start = ComputePathMaxStartFromEndCumul( - current_path_transits_, r, Start(r), current_max_end_.cumul_value); - current_min_start_.path_values[r] = start; - if (current_min_start_.cumul_value > start) { - current_min_start_.cumul_value = start; - current_min_start_.cumul_value_support = r; - } - } - } - // Initialize this before considering any deltas (neighbor). - delta_max_end_cumul_ = kint64min; - lns_detected_ = false; - - DCHECK_GE(current_max_end_.cumul_value, current_min_start_.cumul_value); - synchronized_objective_value_ = - CapAdd(total_current_cumul_cost_value_, - CapProd(global_span_cost_coefficient_, - CapSub(current_max_end_.cumul_value, - current_min_start_.cumul_value))); -} - -bool PathCumulFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - int64 node = path_start; - int64 cumul = cumuls_[node]->Min(); - int64 cumul_cost_delta = 0; - int64 total_transit = 0; - const int path = delta_path_transits_.AddPaths(1); - const int vehicle = start_to_vehicle_[path_start]; - const int64 capacity = vehicle_capacities_[vehicle]; - const bool filter_vehicle_costs = - !routing_model_.IsEnd(GetNext(node)) || - routing_model_.AreEmptyRouteCostsConsideredForVehicle(vehicle); - if (filter_vehicle_costs) { - cumul_cost_delta = CapAdd(GetCumulSoftCost(node, cumul), - GetCumulPiecewiseLinearCost(node, cumul)); - } - // Evaluating route length to reserve memory to store transit information. - int number_of_route_arcs = 0; - while (node < Size()) { - const int64 next = GetNext(node); - // TODO(user): This shouldn't be needed anymore as such deltas should - // have been filtered already. - if (next == kUnassigned) { - // LNS detected, return true since other paths were ok up to now. - lns_detected_ = true; - return true; - } - ++number_of_route_arcs; - node = next; - } - delta_path_transits_.ReserveTransits(path, number_of_route_arcs); - std::vector min_path_cumuls; - min_path_cumuls.reserve(number_of_route_arcs + 1); - min_path_cumuls.push_back(cumul); - // Check that the path is feasible with regards to cumul bounds, scanning - // the paths from start to end (caching path node sequences and transits - // for further span cost filtering). - node = path_start; - while (node < Size()) { - const int64 next = GetNext(node); - const int64 transit = (*evaluators_[vehicle])(node, next); - total_transit = CapAdd(total_transit, transit); - const int64 transit_slack = CapAdd(transit, slacks_[node]->Min()); - delta_path_transits_.PushTransit(path, node, next, transit_slack); - cumul = CapAdd(cumul, transit_slack); - cumul = dimension_.GetFirstPossibleGreaterOrEqualValueForNode(next, cumul); - if (cumul > std::min(capacity, cumuls_[next]->Max())) { - return false; - } - cumul = std::max(cumuls_[next]->Min(), cumul); - min_path_cumuls.push_back(cumul); - node = next; - if (filter_vehicle_costs) { - cumul_cost_delta = - CapAdd(cumul_cost_delta, GetCumulSoftCost(node, cumul)); - cumul_cost_delta = - CapAdd(cumul_cost_delta, GetCumulPiecewiseLinearCost(node, cumul)); - } - } - const int64 min_end = cumul; - - if (!PickupToDeliveryLimitsRespected(delta_path_transits_, path, - min_path_cumuls)) { - return false; - } - if (FilterSlackCost() || FilterBreakCost(vehicle) || - FilterSoftSpanCost(vehicle) || FilterSoftSpanQuadraticCost(vehicle)) { - int64 slack_max = kint64max; - if (vehicle_span_upper_bounds_[vehicle] < kint64max) { - const int64 span_max = vehicle_span_upper_bounds_[vehicle]; - slack_max = std::min(slack_max, CapSub(span_max, total_transit)); - } - const int64 max_start_from_min_end = ComputePathMaxStartFromEndCumul( - delta_path_transits_, path, path_start, min_end); - const int64 span_lb = CapSub(min_end, max_start_from_min_end); - int64 min_total_slack = CapSub(span_lb, total_transit); - if (min_total_slack > slack_max) return false; - - if (dimension_.HasBreakConstraints()) { - for (const auto [limit, min_break_duration] : - dimension_.GetBreakDistanceDurationOfVehicle(vehicle)) { - // Minimal number of breaks depends on total transit: - // 0 breaks for 0 <= total transit <= limit, - // 1 break for limit + 1 <= total transit <= 2 * limit, - // i breaks for i * limit + 1 <= total transit <= (i+1) * limit, ... - if (limit == 0 || total_transit == 0) continue; - const int num_breaks_lb = (total_transit - 1) / limit; - const int64 slack_lb = CapProd(num_breaks_lb, min_break_duration); - if (slack_lb > slack_max) return false; - min_total_slack = std::max(min_total_slack, slack_lb); - } - // Compute a lower bound of the amount of break that must be made inside - // the route. We compute a mandatory interval (might be empty) - // [max_start, min_end[ during which the route will have to happen, - // then the duration of break that must happen during this interval. - int64 min_total_break = 0; - int64 max_path_end = cumuls_[routing_model_.End(vehicle)]->Max(); - const int64 max_start = ComputePathMaxStartFromEndCumul( - delta_path_transits_, path, path_start, max_path_end); - for (const IntervalVar* br : - dimension_.GetBreakIntervalsOfVehicle(vehicle)) { - if (!br->MustBePerformed()) continue; - if (max_start < br->EndMin() && br->StartMax() < min_end) { - min_total_break = CapAdd(min_total_break, br->DurationMin()); - } - } - if (min_total_break > slack_max) return false; - min_total_slack = std::max(min_total_slack, min_total_break); - } - if (filter_vehicle_costs) { - cumul_cost_delta = CapAdd( - cumul_cost_delta, - CapProd(vehicle_span_cost_coefficients_[vehicle], min_total_slack)); - const int64 span_lower_bound = CapAdd(total_transit, min_total_slack); - if (FilterSoftSpanCost()) { - const SimpleBoundCosts::BoundCost bound_cost = - dimension_.GetSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.bound < span_lower_bound) { - const int64 violation = CapSub(span_lower_bound, bound_cost.bound); - cumul_cost_delta = - CapAdd(cumul_cost_delta, CapProd(bound_cost.cost, violation)); - } - } - if (FilterSoftSpanQuadraticCost()) { - const SimpleBoundCosts::BoundCost bound_cost = - dimension_.GetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle); - if (bound_cost.bound < span_lower_bound) { - const int64 violation = CapSub(span_lower_bound, bound_cost.bound); - cumul_cost_delta = - CapAdd(cumul_cost_delta, - CapProd(bound_cost.cost, CapProd(violation, violation))); - } - } - } - if (CapAdd(total_transit, min_total_slack) > - vehicle_span_upper_bounds_[vehicle]) { - return false; - } - } - if (FilterCumulSoftLowerBounds() && filter_vehicle_costs) { - cumul_cost_delta = - CapAdd(cumul_cost_delta, - GetPathCumulSoftLowerBoundCost(delta_path_transits_, path)); - } - if (FilterPrecedences()) { - StoreMinMaxCumulOfNodesOnPath(path, min_path_cumuls, /*is_delta=*/true); - } - if (!filter_vehicle_costs) { - // If this route's costs should't be taken into account, reset the - // cumul_cost_delta and delta_path_transits_ for this path. - cumul_cost_delta = 0; - delta_path_transits_.ClearPath(path); - } - if (FilterSpanCost() || FilterCumulSoftBounds() || FilterSlackCost() || - FilterCumulSoftLowerBounds() || FilterCumulPiecewiseLinearCosts() || - FilterSoftSpanCost(vehicle) || FilterSoftSpanQuadraticCost(vehicle)) { - delta_paths_.insert(GetPath(path_start)); - delta_path_cumul_cost_values_[vehicle] = cumul_cost_delta; - cumul_cost_delta = - CapSub(cumul_cost_delta, current_cumul_cost_values_[path_start]); - if (filter_vehicle_costs) { - delta_max_end_cumul_ = std::max(delta_max_end_cumul_, min_end); - } - } - cumul_cost_delta_ = CapAdd(cumul_cost_delta_, cumul_cost_delta); - return true; -} - -bool PathCumulFilter::FinalizeAcceptPath(const Assignment* delta, - int64 objective_min, - int64 objective_max) { - if ((!FilterSpanCost() && !FilterCumulSoftBounds() && !FilterSlackCost() && - !FilterCumulSoftLowerBounds() && !FilterCumulPiecewiseLinearCosts() && - !FilterPrecedences() && !FilterSoftSpanCost() && - !FilterSoftSpanQuadraticCost()) || - lns_detected_) { - return true; - } - if (FilterPrecedences()) { - for (int64 node : delta_nodes_with_precedences_and_changed_cumul_ - .PositionsSetAtLeastOnce()) { - const std::pair node_min_max_cumul_in_delta = - gtl::FindWithDefault(node_with_precedence_to_delta_min_max_cumuls_, - node, {-1, -1}); - // NOTE: This node was seen in delta, so its delta min/max cumul should be - // stored in the map. - DCHECK(node_min_max_cumul_in_delta.first >= 0 && - node_min_max_cumul_in_delta.second >= 0); - for (const RoutingDimension::NodePrecedence& precedence : - node_index_to_precedences_[node]) { - const bool node_is_first = (precedence.first_node == node); - const int64 other_node = - node_is_first ? precedence.second_node : precedence.first_node; - if (GetNext(other_node) == kUnassigned || - GetNext(other_node) == other_node) { - // The other node is unperformed, so the precedence constraint is - // inactive. - continue; - } - // max_cumul[second_node] should be greater or equal than - // min_cumul[first_node] + offset. - const std::pair& other_min_max_cumul_in_delta = - gtl::FindWithDefault(node_with_precedence_to_delta_min_max_cumuls_, - other_node, - current_min_max_node_cumuls_[other_node]); - - const int64 first_min_cumul = node_is_first - ? node_min_max_cumul_in_delta.first - : other_min_max_cumul_in_delta.first; - const int64 second_max_cumul = node_is_first - ? other_min_max_cumul_in_delta.second - : node_min_max_cumul_in_delta.second; - - if (second_max_cumul < first_min_cumul + precedence.offset) { - return false; - } - } - } - } - int64 new_max_end = delta_max_end_cumul_; - int64 new_min_start = kint64max; - if (FilterSpanCost()) { - if (new_max_end < current_max_end_.cumul_value) { - // Delta max end is lower than the current solution one. - // If the path supporting the current max end has been modified, we need - // to check all paths to find the largest max end. - if (!gtl::ContainsKey(delta_paths_, - current_max_end_.cumul_value_support)) { - new_max_end = current_max_end_.cumul_value; - } else { - for (int i = 0; i < current_max_end_.path_values.size(); ++i) { - if (current_max_end_.path_values[i] > new_max_end && - !gtl::ContainsKey(delta_paths_, i)) { - new_max_end = current_max_end_.path_values[i]; - } - } - } - } - // Now that the max end cumul has been found, compute the corresponding - // min start cumul, first from the delta, then if the max end cumul has - // changed, from the unchanged paths as well. - for (int r = 0; r < delta_path_transits_.NumPaths(); ++r) { - new_min_start = - std::min(ComputePathMaxStartFromEndCumul(delta_path_transits_, r, - Start(r), new_max_end), - new_min_start); - } - if (new_max_end != current_max_end_.cumul_value) { - for (int r = 0; r < NumPaths(); ++r) { - if (gtl::ContainsKey(delta_paths_, r)) { - continue; - } - new_min_start = std::min(new_min_start, ComputePathMaxStartFromEndCumul( - current_path_transits_, r, - Start(r), new_max_end)); - } - } else if (new_min_start > current_min_start_.cumul_value) { - // Delta min start is greater than the current solution one. - // If the path supporting the current min start has been modified, we need - // to check all paths to find the smallest min start. - if (!gtl::ContainsKey(delta_paths_, - current_min_start_.cumul_value_support)) { - new_min_start = current_min_start_.cumul_value; - } else { - for (int i = 0; i < current_min_start_.path_values.size(); ++i) { - if (current_min_start_.path_values[i] < new_min_start && - !gtl::ContainsKey(delta_paths_, i)) { - new_min_start = current_min_start_.path_values[i]; - } - } - } - } - } - - // Filtering on objective value, calling LPs and MIPs if needed.. - accepted_objective_value_ = - CapAdd(cumul_cost_delta_, CapProd(global_span_cost_coefficient_, - CapSub(new_max_end, new_min_start))); - - if (can_use_lp_ && optimizer_ != nullptr && - accepted_objective_value_ <= objective_max) { - const size_t num_touched_paths = GetTouchedPathStarts().size(); - std::vector path_delta_cost_values(num_touched_paths, 0); - std::vector requires_mp(num_touched_paths, false); - for (int i = 0; i < num_touched_paths; ++i) { - const int64 start = GetTouchedPathStarts()[i]; - const int vehicle = start_to_vehicle_[start]; - if (!FilterWithDimensionCumulOptimizerForVehicle(vehicle)) { - continue; - } - int64 path_delta_cost_with_lp = 0; - const DimensionSchedulingStatus status = - optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64 node) { return GetNext(node); }, - &path_delta_cost_with_lp); - if (status == DimensionSchedulingStatus::INFEASIBLE) { - return false; - } - DCHECK(gtl::ContainsKey(delta_paths_, GetPath(start))); - const int64 path_cost_diff_with_lp = CapSub( - path_delta_cost_with_lp, delta_path_cumul_cost_values_[vehicle]); - if (path_cost_diff_with_lp > 0) { - path_delta_cost_values[i] = path_delta_cost_with_lp; - accepted_objective_value_ = - CapAdd(accepted_objective_value_, path_cost_diff_with_lp); - if (accepted_objective_value_ > objective_max) { - return false; - } - } else { - path_delta_cost_values[i] = delta_path_cumul_cost_values_[vehicle]; - } - if (mp_optimizer_ != nullptr) { - requires_mp[i] = - FilterBreakCost(vehicle) || - (status == DimensionSchedulingStatus::RELAXED_OPTIMAL_ONLY); - } - } - if (mp_optimizer_ == nullptr) { - return accepted_objective_value_ <= objective_max; - } - for (int i = 0; i < num_touched_paths; ++i) { - if (!requires_mp[i]) { - continue; - } - const int64 start = GetTouchedPathStarts()[i]; - const int vehicle = start_to_vehicle_[start]; - int64 path_delta_cost_with_mp = 0; - if (mp_optimizer_->ComputeRouteCumulCostWithoutFixedTransits( - vehicle, [this](int64 node) { return GetNext(node); }, - &path_delta_cost_with_mp) == - DimensionSchedulingStatus::INFEASIBLE) { - return false; - } - DCHECK(gtl::ContainsKey(delta_paths_, GetPath(start))); - const int64 path_cost_diff_with_mp = - CapSub(path_delta_cost_with_mp, path_delta_cost_values[i]); - if (path_cost_diff_with_mp > 0) { - accepted_objective_value_ = - CapAdd(accepted_objective_value_, path_cost_diff_with_mp); - if (accepted_objective_value_ > objective_max) { - return false; - } - } - } - } - - return accepted_objective_value_ <= objective_max; -} - -void PathCumulFilter::InitializeSupportedPathCumul( - SupportedPathCumul* supported_cumul, int64 default_value) { - supported_cumul->cumul_value = default_value; - supported_cumul->cumul_value_support = -1; - supported_cumul->path_values.resize(NumPaths(), default_value); -} - -bool PathCumulFilter::PickupToDeliveryLimitsRespected( - const PathTransits& path_transits, int path, - const std::vector& min_path_cumuls) const { - if (!dimension_.HasPickupToDeliveryLimits()) { - return true; - } - const int num_pairs = routing_model_.GetPickupAndDeliveryPairs().size(); - DCHECK_GT(num_pairs, 0); - std::vector> visited_delivery_and_min_cumul_per_pair( - num_pairs, {-1, -1}); - - const int path_size = path_transits.PathSize(path); - CHECK_EQ(min_path_cumuls.size(), path_size); - - int64 max_cumul = min_path_cumuls.back(); - for (int i = path_transits.PathSize(path) - 2; i >= 0; i--) { - const int node_index = path_transits.Node(path, i); - max_cumul = CapSub(max_cumul, path_transits.Transit(path, i)); - max_cumul = std::min(cumuls_[node_index]->Max(), max_cumul); - - const std::vector>& pickup_index_pairs = - routing_model_.GetPickupIndexPairs(node_index); - const std::vector>& delivery_index_pairs = - routing_model_.GetDeliveryIndexPairs(node_index); - if (!pickup_index_pairs.empty()) { - // The node is a pickup. Check that it is not a delivery and that it - // appears in a single pickup/delivery pair (as required when limits are - // set on dimension cumuls for pickup and deliveries). - DCHECK(delivery_index_pairs.empty()); - DCHECK_EQ(pickup_index_pairs.size(), 1); - const int pair_index = pickup_index_pairs[0].first; - // Get the delivery visited for this pair. - const int delivery_index = - visited_delivery_and_min_cumul_per_pair[pair_index].first; - if (delivery_index < 0) { - // No delivery visited after this pickup for this pickup/delivery pair. - continue; - } - const int64 cumul_diff_limit = dimension_.GetPickupToDeliveryLimitForPair( - pair_index, pickup_index_pairs[0].second, delivery_index); - if (CapSub(visited_delivery_and_min_cumul_per_pair[pair_index].second, - max_cumul) > cumul_diff_limit) { - return false; - } - } - if (!delivery_index_pairs.empty()) { - // The node is a delivery. Check that it's not a pickup and it belongs to - // a single pair. - DCHECK(pickup_index_pairs.empty()); - DCHECK_EQ(delivery_index_pairs.size(), 1); - const int pair_index = delivery_index_pairs[0].first; - std::pair& delivery_index_and_cumul = - visited_delivery_and_min_cumul_per_pair[pair_index]; - int& delivery_index = delivery_index_and_cumul.first; - DCHECK_EQ(delivery_index, -1); - delivery_index = delivery_index_pairs[0].second; - delivery_index_and_cumul.second = min_path_cumuls[i]; - } - } - return true; -} - -void PathCumulFilter::StoreMinMaxCumulOfNodesOnPath( - int path, const std::vector& min_path_cumuls, bool is_delta) { - const PathTransits& path_transits = - is_delta ? delta_path_transits_ : current_path_transits_; - - const int path_size = path_transits.PathSize(path); - DCHECK_EQ(min_path_cumuls.size(), path_size); - - int64 max_cumul = cumuls_[path_transits.Node(path, path_size - 1)]->Max(); - for (int i = path_size - 1; i >= 0; i--) { - const int node_index = path_transits.Node(path, i); - - if (i < path_size - 1) { - max_cumul = CapSub(max_cumul, path_transits.Transit(path, i)); - max_cumul = std::min(cumuls_[node_index]->Max(), max_cumul); - } - - if (is_delta && node_index_to_precedences_[node_index].empty()) { - // No need to update the delta cumul map for nodes without precedences. - continue; - } - - std::pair& min_max_cumuls = - is_delta ? node_with_precedence_to_delta_min_max_cumuls_[node_index] - : current_min_max_node_cumuls_[node_index]; - min_max_cumuls.first = min_path_cumuls[i]; - min_max_cumuls.second = max_cumul; - - if (is_delta && !routing_model_.IsEnd(node_index) && - (min_max_cumuls.first != - current_min_max_node_cumuls_[node_index].first || - max_cumul != current_min_max_node_cumuls_[node_index].second)) { - delta_nodes_with_precedences_and_changed_cumul_.Set(node_index); - } - } -} - -int64 PathCumulFilter::ComputePathMaxStartFromEndCumul( - const PathTransits& path_transits, int path, int64 path_start, - int64 min_end_cumul) const { - int64 cumul_from_min_end = min_end_cumul; - int64 cumul_from_max_end = - cumuls_[routing_model_.End(start_to_vehicle_[path_start])]->Max(); - for (int i = path_transits.PathSize(path) - 2; i >= 0; --i) { - const int64 transit = path_transits.Transit(path, i); - const int64 node = path_transits.Node(path, i); - cumul_from_min_end = - std::min(cumuls_[node]->Max(), CapSub(cumul_from_min_end, transit)); - cumul_from_max_end = dimension_.GetLastPossibleLessOrEqualValueForNode( - node, CapSub(cumul_from_max_end, transit)); - } - return std::min(cumul_from_min_end, cumul_from_max_end); -} - -} // namespace - -IntVarLocalSearchFilter* MakePathCumulFilter( - const RoutingDimension& dimension, - const RoutingSearchParameters& parameters, - bool propagate_own_objective_value, bool filter_objective_cost, - bool can_use_lp) { - RoutingModel& model = *dimension.model(); - return model.solver()->RevAlloc(new PathCumulFilter( - model, dimension, parameters, propagate_own_objective_value, - filter_objective_cost, can_use_lp)); -} - -namespace { - -bool DimensionHasCumulCost(const RoutingDimension& dimension) { - if (dimension.global_span_cost_coefficient() != 0) return true; - if (dimension.HasSoftSpanUpperBounds()) return true; - if (dimension.HasQuadraticCostSoftSpanUpperBounds()) return true; - for (const int64 coefficient : dimension.vehicle_span_cost_coefficients()) { - if (coefficient != 0) return true; - } - for (int i = 0; i < dimension.cumuls().size(); ++i) { - if (dimension.HasCumulVarSoftUpperBound(i)) return true; - if (dimension.HasCumulVarSoftLowerBound(i)) return true; - if (dimension.HasCumulVarPiecewiseLinearCost(i)) return true; - } - return false; -} - -bool DimensionHasCumulConstraint(const RoutingDimension& dimension) { - if (dimension.HasBreakConstraints()) return true; - if (dimension.HasPickupToDeliveryLimits()) return true; - if (!dimension.GetNodePrecedences().empty()) return true; - for (const int64 upper_bound : dimension.vehicle_span_upper_bounds()) { - if (upper_bound != kint64max) return true; - } - for (const IntVar* const slack : dimension.slacks()) { - if (slack->Min() > 0) return true; - } - const std::vector& cumuls = dimension.cumuls(); - for (int i = 0; i < cumuls.size(); ++i) { - IntVar* const cumul_var = cumuls[i]; - if (cumul_var->Min() > 0 && cumul_var->Max() < kint64max && - !dimension.model()->IsEnd(i)) { - return true; - } - if (dimension.forbidden_intervals()[i].NumIntervals() > 0) return true; - } - return false; -} - -} // namespace - -void AppendLightWeightDimensionFilters( - const PathState* path_state, - const std::vector& dimensions, - std::vector* filters) { - // For every dimension that fits, add a UnaryDimensionChecker. - for (const RoutingDimension* dimension : dimensions) { - // Skip dimension if not unary. - if (dimension->GetUnaryTransitEvaluator(0) == nullptr) continue; - - using Intervals = std::vector; - // Fill path capacities and classes. - const int num_vehicles = dimension->model()->vehicles(); - Intervals path_capacity(num_vehicles); - std::vector path_class(num_vehicles); - for (int v = 0; v < num_vehicles; ++v) { - const auto& vehicle_capacities = dimension->vehicle_capacities(); - path_capacity[v] = {0, vehicle_capacities[v]}; - path_class[v] = dimension->vehicle_to_class(v); - } - // For each class, retrieve the demands of each node. - // Dimension store evaluators with a double indirection for compacity: - // vehicle -> vehicle_class -> evaluator_index. - // We replicate this in UnaryDimensionChecker, - // except we expand evaluator_index to an array of values for all nodes. - const int num_vehicle_classes = - 1 + *std::max_element(path_class.begin(), path_class.end()); - std::vector demands(num_vehicle_classes); - const int num_cumuls = dimension->cumuls().size(); - const int num_slacks = dimension->slacks().size(); - for (int vehicle = 0; vehicle < num_vehicles; ++vehicle) { - const int vehicle_class = path_class[vehicle]; - if (!demands[vehicle_class].empty()) continue; - const auto& evaluator = dimension->GetUnaryTransitEvaluator(vehicle); - Intervals class_demands(num_cumuls); - for (int node = 0; node < num_cumuls; ++node) { - if (node < num_slacks) { - const int64 demand_min = evaluator(node); - const int64 slack_max = dimension->SlackVar(node)->Max(); - class_demands[node] = {demand_min, CapAdd(demand_min, slack_max)}; - } else { - class_demands[node] = {0, 0}; - } - } - demands[vehicle_class] = std::move(class_demands); - } - // Fill node capacities. - Intervals node_capacity(num_cumuls); - for (int node = 0; node < num_cumuls; ++node) { - const IntVar* cumul = dimension->CumulVar(node); - node_capacity[node] = {cumul->Min(), cumul->Max()}; - } - // Make the dimension checker and pass ownership to the filter. - auto checker = absl::make_unique( - path_state, std::move(path_capacity), std::move(path_class), - std::move(demands), std::move(node_capacity)); - const auto kAccept = LocalSearchFilterManager::FilterEventType::kAccept; - LocalSearchFilter* filter = MakeUnaryDimensionFilter( - dimension->model()->solver(), std::move(checker)); - filters->push_back({filter, kAccept}); - } -} - -void AppendDimensionCumulFilters( - const std::vector& dimensions, - const RoutingSearchParameters& parameters, bool filter_objective_cost, - std::vector* filters) { - const auto kAccept = LocalSearchFilterManager::FilterEventType::kAccept; - // NOTE: We first sort the dimensions by increasing complexity of filtering: - // - Dimensions without any cumul-related costs or constraints will have a - // ChainCumulFilter. - // - Dimensions with cumul costs or constraints, but no global span cost - // and/or precedences will have a PathCumulFilter. - // - Dimensions with a global span cost coefficient and/or precedences will - // have a global LP filter. - const int num_dimensions = dimensions.size(); - - std::vector use_path_cumul_filter(num_dimensions); - std::vector use_cumul_bounds_propagator_filter(num_dimensions); - std::vector use_global_lp_filter(num_dimensions); - std::vector filtering_difficulty(num_dimensions); - for (int d = 0; d < num_dimensions; d++) { - const RoutingDimension& dimension = *dimensions[d]; - const bool has_cumul_cost = DimensionHasCumulCost(dimension); - use_path_cumul_filter[d] = - has_cumul_cost || DimensionHasCumulConstraint(dimension); - - const bool can_use_cumul_bounds_propagator_filter = - !dimension.HasBreakConstraints() && - (!filter_objective_cost || !has_cumul_cost); - const bool has_precedences = !dimension.GetNodePrecedences().empty(); - use_global_lp_filter[d] = - (has_precedences && !can_use_cumul_bounds_propagator_filter) || - (filter_objective_cost && dimension.global_span_cost_coefficient() > 0); - - use_cumul_bounds_propagator_filter[d] = - has_precedences && !use_global_lp_filter[d]; - - filtering_difficulty[d] = 4 * use_global_lp_filter[d] + - 2 * use_cumul_bounds_propagator_filter[d] + - use_path_cumul_filter[d]; - } - - std::vector sorted_dimension_indices(num_dimensions); - std::iota(sorted_dimension_indices.begin(), sorted_dimension_indices.end(), - 0); - std::sort(sorted_dimension_indices.begin(), sorted_dimension_indices.end(), - [&filtering_difficulty](int d1, int d2) { - return filtering_difficulty[d1] < filtering_difficulty[d2]; - }); - - for (const int d : sorted_dimension_indices) { - const RoutingDimension& dimension = *dimensions[d]; - const RoutingModel& model = *dimension.model(); - // NOTE: We always add the [Chain|Path]CumulFilter to filter each route's - // feasibility separately to try and cut bad decisions earlier in the - // search, but we don't propagate the computed cost if the LPCumulFilter is - // already doing it. - const bool use_global_lp = use_global_lp_filter[d]; - if (use_path_cumul_filter[d]) { - filters->push_back( - {MakePathCumulFilter(dimension, parameters, !use_global_lp, - filter_objective_cost), - kAccept}); - } else { - filters->push_back( - {model.solver()->RevAlloc(new ChainCumulFilter(model, dimension)), - kAccept}); - } - - if (use_global_lp) { - DCHECK(model.GetMutableGlobalCumulOptimizer(dimension) != nullptr); - filters->push_back({MakeGlobalLPCumulFilter( - model.GetMutableGlobalCumulOptimizer(dimension), - filter_objective_cost), - kAccept}); - } else if (use_cumul_bounds_propagator_filter[d]) { - filters->push_back({MakeCumulBoundsPropagatorFilter(dimension), kAccept}); - } - } -} - -namespace { - -// Filter for pickup/delivery precedences. -class PickupDeliveryFilter : public BasePathFilter { - public: - PickupDeliveryFilter(const std::vector& nexts, int next_domain_size, - const RoutingModel::IndexPairs& pairs, - const std::vector& - vehicle_policies); - ~PickupDeliveryFilter() override {} - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - std::string DebugString() const override { return "PickupDeliveryFilter"; } - - private: - bool AcceptPathDefault(int64 path_start); - template - bool AcceptPathOrdered(int64 path_start); - - std::vector pair_firsts_; - std::vector pair_seconds_; - const RoutingModel::IndexPairs pairs_; - SparseBitset<> visited_; - std::deque visited_deque_; - const std::vector vehicle_policies_; -}; - -PickupDeliveryFilter::PickupDeliveryFilter( - const std::vector& nexts, int next_domain_size, - const RoutingModel::IndexPairs& pairs, - const std::vector& vehicle_policies) - : BasePathFilter(nexts, next_domain_size), - pair_firsts_(next_domain_size, kUnassigned), - pair_seconds_(next_domain_size, kUnassigned), - pairs_(pairs), - visited_(Size()), - vehicle_policies_(vehicle_policies) { - for (int i = 0; i < pairs.size(); ++i) { - const auto& index_pair = pairs[i]; - for (int first : index_pair.first) { - pair_firsts_[first] = i; - } - for (int second : index_pair.second) { - pair_seconds_[second] = i; - } - } -} - -bool PickupDeliveryFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - switch (vehicle_policies_[GetPath(path_start)]) { - case RoutingModel::PICKUP_AND_DELIVERY_NO_ORDER: - return AcceptPathDefault(path_start); - case RoutingModel::PICKUP_AND_DELIVERY_LIFO: - return AcceptPathOrdered(path_start); - case RoutingModel::PICKUP_AND_DELIVERY_FIFO: - return AcceptPathOrdered(path_start); - default: - return true; - } -} - -bool PickupDeliveryFilter::AcceptPathDefault(int64 path_start) { - visited_.ClearAll(); - int64 node = path_start; - int64 path_length = 1; - while (node < Size()) { - // Detect sub-cycles (path is longer than longest possible path). - if (path_length > Size()) { - return false; - } - if (pair_firsts_[node] != kUnassigned) { - // Checking on pair firsts is not actually necessary (inconsistencies - // will get caught when checking pair seconds); doing it anyway to - // cut checks early. - for (int second : pairs_[pair_firsts_[node]].second) { - if (visited_[second]) { - return false; - } - } - } - if (pair_seconds_[node] != kUnassigned) { - bool found_first = false; - bool some_synced = false; - for (int first : pairs_[pair_seconds_[node]].first) { - if (visited_[first]) { - found_first = true; - break; - } - if (IsVarSynced(first)) { - some_synced = true; - } - } - if (!found_first && some_synced) { - return false; - } - } - visited_.Set(node); - const int64 next = GetNext(node); - if (next == kUnassigned) { - // LNS detected, return true since path was ok up to now. - return true; - } - node = next; - ++path_length; - } - for (const int64 node : visited_.PositionsSetAtLeastOnce()) { - if (pair_firsts_[node] != kUnassigned) { - bool found_second = false; - bool some_synced = false; - for (int second : pairs_[pair_firsts_[node]].second) { - if (visited_[second]) { - found_second = true; - break; - } - if (IsVarSynced(second)) { - some_synced = true; - } - } - if (!found_second && some_synced) { - return false; - } - } - } - return true; -} - -template -bool PickupDeliveryFilter::AcceptPathOrdered(int64 path_start) { - visited_deque_.clear(); - int64 node = path_start; - int64 path_length = 1; - while (node < Size()) { - // Detect sub-cycles (path is longer than longest possible path). - if (path_length > Size()) { - return false; - } - if (pair_firsts_[node] != kUnassigned) { - if (lifo) { - visited_deque_.push_back(node); - } else { - visited_deque_.push_front(node); - } - } - if (pair_seconds_[node] != kUnassigned) { - bool found_first = false; - bool some_synced = false; - for (int first : pairs_[pair_seconds_[node]].first) { - if (!visited_deque_.empty() && visited_deque_.back() == first) { - found_first = true; - break; - } - if (IsVarSynced(first)) { - some_synced = true; - } - } - if (!found_first && some_synced) { - return false; - } else if (!visited_deque_.empty()) { - visited_deque_.pop_back(); - } - } - const int64 next = GetNext(node); - if (next == kUnassigned) { - // LNS detected, return true since path was ok up to now. - return true; - } - node = next; - ++path_length; - } - while (!visited_deque_.empty()) { - for (int second : pairs_[pair_firsts_[visited_deque_.back()]].second) { - if (IsVarSynced(second)) { - return false; - } - } - visited_deque_.pop_back(); - } - return true; -} - -} // namespace - -IntVarLocalSearchFilter* MakePickupDeliveryFilter( - const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs, - const std::vector& - vehicle_policies) { - return routing_model.solver()->RevAlloc(new PickupDeliveryFilter( - routing_model.Nexts(), routing_model.Size() + routing_model.vehicles(), - pairs, vehicle_policies)); -} - -namespace { - -// Vehicle variable filter -class VehicleVarFilter : public BasePathFilter { - public: - explicit VehicleVarFilter(const RoutingModel& routing_model); - ~VehicleVarFilter() override {} - bool AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) override; - std::string DebugString() const override { return "VehicleVariableFilter"; } - - private: - bool DisableFiltering() const override; - bool IsVehicleVariableConstrained(int index) const; - - std::vector start_to_vehicle_; - std::vector vehicle_vars_; - const int64 unconstrained_vehicle_var_domain_size_; -}; - -VehicleVarFilter::VehicleVarFilter(const RoutingModel& routing_model) - : BasePathFilter(routing_model.Nexts(), - routing_model.Size() + routing_model.vehicles()), - vehicle_vars_(routing_model.VehicleVars()), - unconstrained_vehicle_var_domain_size_(routing_model.vehicles()) { - start_to_vehicle_.resize(Size(), -1); - for (int i = 0; i < routing_model.vehicles(); ++i) { - start_to_vehicle_[routing_model.Start(i)] = i; - } -} - -bool VehicleVarFilter::AcceptPath(int64 path_start, int64 chain_start, - int64 chain_end) { - const int64 vehicle = start_to_vehicle_[path_start]; - int64 node = chain_start; - while (node != chain_end) { - if (!vehicle_vars_[node]->Contains(vehicle)) { - return false; - } - node = GetNext(node); - } - return vehicle_vars_[node]->Contains(vehicle); -} - -bool VehicleVarFilter::DisableFiltering() const { - for (int i = 0; i < vehicle_vars_.size(); ++i) { - if (IsVehicleVariableConstrained(i)) return false; - } - return true; -} - -bool VehicleVarFilter::IsVehicleVariableConstrained(int index) const { - const IntVar* const vehicle_var = vehicle_vars_[index]; - // If vehicle variable contains -1 (optional node), then we need to - // add it to the "unconstrained" domain. Impact we don't filter mandatory - // nodes made inactive here, but it is covered by other filters. - const int adjusted_unconstrained_vehicle_var_domain_size = - vehicle_var->Min() >= 0 ? unconstrained_vehicle_var_domain_size_ - : unconstrained_vehicle_var_domain_size_ + 1; - return vehicle_var->Size() != adjusted_unconstrained_vehicle_var_domain_size; -} - -} // namespace - -IntVarLocalSearchFilter* MakeVehicleVarFilter( - const RoutingModel& routing_model) { - return routing_model.solver()->RevAlloc(new VehicleVarFilter(routing_model)); -} - -namespace { - -class CumulBoundsPropagatorFilter : public IntVarLocalSearchFilter { - public: - explicit CumulBoundsPropagatorFilter(const RoutingDimension& dimension); - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override; - std::string DebugString() const override { - return "CumulBoundsPropagatorFilter(" + propagator_.dimension().name() + - ")"; - } - - private: - CumulBoundsPropagator propagator_; - const int64 cumul_offset_; - SparseBitset delta_touched_; - std::vector delta_nexts_; -}; - -CumulBoundsPropagatorFilter::CumulBoundsPropagatorFilter( - const RoutingDimension& dimension) - : IntVarLocalSearchFilter(dimension.model()->Nexts()), - propagator_(&dimension), - cumul_offset_(dimension.GetGlobalOptimizerOffset()), - delta_touched_(Size()), - delta_nexts_(Size()) {} - -bool CumulBoundsPropagatorFilter::Accept(const Assignment* delta, - const Assignment* deltadelta, - int64 objective_min, - int64 objective_max) { - delta_touched_.ClearAll(); - for (const IntVarElement& delta_element : - delta->IntVarContainer().elements()) { - int64 index = -1; - if (FindIndex(delta_element.Var(), &index)) { - if (!delta_element.Bound()) { - // LNS detected - return true; - } - delta_touched_.Set(index); - delta_nexts_[index] = delta_element.Value(); - } - } - const auto& next_accessor = [this](int64 index) { - return delta_touched_[index] ? delta_nexts_[index] : Value(index); - }; - - return propagator_.PropagateCumulBounds(next_accessor, cumul_offset_); -} - -} // namespace - -IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter( - const RoutingDimension& dimension) { - return dimension.model()->solver()->RevAlloc( - new CumulBoundsPropagatorFilter(dimension)); -} - -namespace { - -class LPCumulFilter : public IntVarLocalSearchFilter { - public: - LPCumulFilter(const std::vector& nexts, - GlobalDimensionCumulOptimizer* optimizer, - bool filter_objective_cost); - bool Accept(const Assignment* delta, const Assignment* deltadelta, - int64 objective_min, int64 objective_max) override; - int64 GetAcceptedObjectiveValue() const override; - void OnSynchronize(const Assignment* delta) override; - int64 GetSynchronizedObjectiveValue() const override; - std::string DebugString() const override { - return "LPCumulFilter(" + optimizer_.dimension()->name() + ")"; - } - - private: - GlobalDimensionCumulOptimizer& optimizer_; - const bool filter_objective_cost_; - int64 synchronized_cost_without_transit_; - int64 delta_cost_without_transit_; - SparseBitset delta_touched_; - std::vector delta_nexts_; -}; - -LPCumulFilter::LPCumulFilter(const std::vector& nexts, - GlobalDimensionCumulOptimizer* optimizer, - bool filter_objective_cost) - : IntVarLocalSearchFilter(nexts), - optimizer_(*optimizer), - filter_objective_cost_(filter_objective_cost), - synchronized_cost_without_transit_(-1), - delta_cost_without_transit_(-1), - delta_touched_(Size()), - delta_nexts_(Size()) {} - -bool LPCumulFilter::Accept(const Assignment* delta, - const Assignment* deltadelta, int64 objective_min, - int64 objective_max) { - delta_touched_.ClearAll(); - for (const IntVarElement& delta_element : - delta->IntVarContainer().elements()) { - int64 index = -1; - if (FindIndex(delta_element.Var(), &index)) { - if (!delta_element.Bound()) { - // LNS detected - return true; - } - delta_touched_.Set(index); - delta_nexts_[index] = delta_element.Value(); - } - } - const auto& next_accessor = [this](int64 index) { - return delta_touched_[index] ? delta_nexts_[index] : Value(index); - }; - - if (!filter_objective_cost_) { - // No need to compute the cost of the LP, only verify its feasibility. - delta_cost_without_transit_ = 0; - return optimizer_.IsFeasible(next_accessor); - } - - if (!optimizer_.ComputeCumulCostWithoutFixedTransits( - next_accessor, &delta_cost_without_transit_)) { - // Infeasible. - delta_cost_without_transit_ = kint64max; - return false; - } - return delta_cost_without_transit_ <= objective_max; -} - -int64 LPCumulFilter::GetAcceptedObjectiveValue() const { - return delta_cost_without_transit_; -} - -void LPCumulFilter::OnSynchronize(const Assignment* delta) { - // TODO(user): Try to optimize this so the LP is not called when the last - // computed delta cost corresponds to the solution being synchronized. - const RoutingModel& model = *optimizer_.dimension()->model(); - if (!optimizer_.ComputeCumulCostWithoutFixedTransits( - [this, &model](int64 index) { - return IsVarSynced(index) ? Value(index) - : model.IsStart(index) ? model.End(model.VehicleIndex(index)) - : index; - }, - &synchronized_cost_without_transit_)) { - // TODO(user): This should only happen if the LP solver times out. - // DCHECK the fail wasn't due to an infeasible model. - synchronized_cost_without_transit_ = 0; - } -} - -int64 LPCumulFilter::GetSynchronizedObjectiveValue() const { - return synchronized_cost_without_transit_; -} - -} // namespace - -IntVarLocalSearchFilter* MakeGlobalLPCumulFilter( - GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost) { - const RoutingModel& model = *optimizer->dimension()->model(); - return model.solver()->RevAlloc( - new LPCumulFilter(model.Nexts(), optimizer, filter_objective_cost)); -} - -const int64 CPFeasibilityFilter::kUnassigned = -1; - -CPFeasibilityFilter::CPFeasibilityFilter(RoutingModel* routing_model) - : IntVarLocalSearchFilter(routing_model->Nexts()), - model_(routing_model), - solver_(routing_model->solver()), - assignment_(solver_->MakeAssignment()), - temp_assignment_(solver_->MakeAssignment()), - restore_(solver_->MakeRestoreAssignment(temp_assignment_)), - limit_(solver_->MakeCustomLimit( - [routing_model]() { return routing_model->CheckLimit(); })) { - assignment_->Add(routing_model->Nexts()); -} - -bool CPFeasibilityFilter::Accept(const Assignment* delta, - const Assignment* deltadelta, - int64 objective_min, int64 objective_max) { - temp_assignment_->Copy(assignment_); - AddDeltaToAssignment(delta, temp_assignment_); - - return solver_->Solve(restore_, limit_); -} - -void CPFeasibilityFilter::OnSynchronize(const Assignment* delta) { - AddDeltaToAssignment(delta, assignment_); -} - -void CPFeasibilityFilter::AddDeltaToAssignment(const Assignment* delta, - Assignment* assignment) { - if (delta == nullptr) { - return; - } - Assignment::IntContainer* const container = - assignment->MutableIntVarContainer(); - const Assignment::IntContainer& delta_container = delta->IntVarContainer(); - const int delta_size = delta_container.Size(); - - for (int i = 0; i < delta_size; i++) { - const IntVarElement& delta_element = delta_container.Element(i); - IntVar* const var = delta_element.Var(); - int64 index = kUnassigned; - CHECK(FindIndex(var, &index)); - DCHECK_EQ(var, Var(index)); - const int64 value = delta_element.Value(); - - container->AddAtPosition(var, index)->SetValue(value); - if (model_->IsStart(index)) { - if (model_->IsEnd(value)) { - // Do not restore unused routes. - container->MutableElement(index)->Deactivate(); - } else { - // Re-activate the route's start in case it was deactivated before. - container->MutableElement(index)->Activate(); - } - } - } -} - -IntVarLocalSearchFilter* MakeCPFeasibilityFilter(RoutingModel* routing_model) { - return routing_model->solver()->RevAlloc( - new CPFeasibilityFilter(routing_model)); -} - -// TODO(user): Implement same-vehicle filter. Could be merged with node -// precedence filter. - // --- VehicleTypeCurator --- void VehicleTypeCurator::Reset(const std::function& store_vehicle) { @@ -2861,11 +180,11 @@ Decision* IntVarFilteredDecisionBuilder::Next(Solver* solver) { return nullptr; } -int64 IntVarFilteredDecisionBuilder::number_of_decisions() const { +int64_t IntVarFilteredDecisionBuilder::number_of_decisions() const { return heuristic_->number_of_decisions(); } -int64 IntVarFilteredDecisionBuilder::number_of_rejects() const { +int64_t IntVarFilteredDecisionBuilder::number_of_rejects() const { return heuristic_->number_of_rejects(); } @@ -2917,7 +236,7 @@ Assignment* const IntVarFilteredHeuristic::BuildSolution() { } const Assignment* RoutingFilteredHeuristic::BuildSolutionFromRoutes( - const std::function& next_accessor) { + const std::function& next_accessor) { ResetSolution(); ResetVehicleIndices(); // NOTE: We don't need to clear or pre-set the two following vectors as the @@ -2926,9 +245,9 @@ const Assignment* RoutingFilteredHeuristic::BuildSolutionFromRoutes( end_chain_starts_.resize(model()->vehicles()); for (int v = 0; v < model_->vehicles(); v++) { - int64 node = model_->Start(v); + int64_t node = model_->Start(v); while (!model_->IsEnd(node)) { - const int64 next = next_accessor(node); + const int64_t next = next_accessor(node); DCHECK_NE(next, node); SetValue(node, next); SetVehicleIndex(node, v); @@ -2984,7 +303,9 @@ void IntVarFilteredHeuristic::SynchronizeFilters() { bool IntVarFilteredHeuristic::FilterAccept() { if (!filter_manager_) return true; LocalSearchMonitor* const monitor = solver_->GetLocalSearchMonitor(); - return filter_manager_->Accept(monitor, delta_, empty_, kint64min, kint64max); + return filter_manager_->Accept(monitor, delta_, empty_, + std::numeric_limits::min(), + std::numeric_limits::max()); } // RoutingFilteredHeuristic @@ -3011,9 +332,9 @@ bool RoutingFilteredHeuristic::InitializeSolution() { ResetVehicleIndices(); for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { - int64 node = model()->Start(vehicle); + int64_t node = model()->Start(vehicle); while (!model()->IsEnd(node) && Var(node)->Bound()) { - const int64 next = Var(node)->Min(); + const int64_t next = Var(node)->Min(); SetValue(node, next); SetVehicleIndex(node, vehicle); node = next; @@ -3021,8 +342,8 @@ bool RoutingFilteredHeuristic::InitializeSolution() { start_chain_ends_[vehicle] = node; } - std::vector starts(Size() + model()->vehicles(), -1); - std::vector ends(Size() + model()->vehicles(), -1); + std::vector starts(Size() + model()->vehicles(), -1); + std::vector ends(Size() + model()->vehicles(), -1); for (int node = 0; node < Size() + model()->vehicles(); ++node) { // Each node starts as a singleton chain. starts[node] = node; @@ -3048,9 +369,9 @@ bool RoutingFilteredHeuristic::InitializeSolution() { // chain at its end, without nodes in between. for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { end_chain_starts_[vehicle] = starts[model()->End(vehicle)]; - int64 node = start_chain_ends_[vehicle]; + int64_t node = start_chain_ends_[vehicle]; if (!model()->IsEnd(node)) { - int64 next = starts[model()->End(vehicle)]; + int64_t next = starts[model()->End(vehicle)]; SetValue(node, next); SetVehicleIndex(node, vehicle); node = next; @@ -3070,7 +391,7 @@ bool RoutingFilteredHeuristic::InitializeSolution() { return true; } -void RoutingFilteredHeuristic::MakeDisjunctionNodesUnperformed(int64 node) { +void RoutingFilteredHeuristic::MakeDisjunctionNodesUnperformed(int64_t node) { model()->ForEachNodeInDisjunctionWithMaxCardinalityFromIndex( node, 1, [this, node](int alternate) { if (node != alternate && !Contains(alternate)) { @@ -3091,15 +412,15 @@ 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) { + int64_t performed_pickup = -1; + for (int64_t pickup : pickups) { if (Contains(pickup) && Value(pickup) != pickup) { performed_pickup = pickup; break; } } - int64 performed_delivery = -1; - for (int64 delivery : deliveries) { + int64_t performed_delivery = -1; + for (int64_t delivery : deliveries) { if (Contains(delivery) && Value(delivery) != delivery) { performed_delivery = delivery; break; @@ -3116,9 +437,9 @@ void RoutingFilteredHeuristic::MakePartiallyPerformedPairsUnperformed() { } for (int index = 0; index < Size(); ++index) { if (to_make_unperformed[index] || !Contains(index)) continue; - int64 next = Value(index); + int64_t next = Value(index); while (next < Size() && to_make_unperformed[next]) { - const int64 next_of_next = Value(next); + const int64_t next_of_next = Value(next); SetValue(index, next_of_next); SetValue(next, next); next = next_of_next; @@ -3129,8 +450,9 @@ void RoutingFilteredHeuristic::MakePartiallyPerformedPairsUnperformed() { // CheapestInsertionFilteredHeuristic CheapestInsertionFilteredHeuristic::CheapestInsertionFilteredHeuristic( - RoutingModel* model, std::function evaluator, - std::function penalty_evaluator, + RoutingModel* model, + std::function evaluator, + std::function penalty_evaluator, LocalSearchFilterManager* filter_manager) : RoutingFilteredHeuristic(model, filter_manager), evaluator_(std::move(evaluator)), @@ -3148,11 +470,11 @@ CheapestInsertionFilteredHeuristic::ComputeStartEndDistanceForVehicles( start_end_distances_per_node[node]; for (const int vehicle : vehicles) { - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); // We compute the distance of node to the start/end nodes of the route. - const int64 distance = + const int64_t distance = CapAdd(model()->GetArcCostForVehicle(start, node, vehicle), model()->GetArcCostForVehicle(node, end, vehicle)); start_end_distances.push_back({distance, vehicle}); @@ -3188,21 +510,21 @@ void CheapestInsertionFilteredHeuristic::InitializePriorityQueue( } } -void CheapestInsertionFilteredHeuristic::InsertBetween(int64 node, - int64 predecessor, - int64 successor) { +void CheapestInsertionFilteredHeuristic::InsertBetween(int64_t node, + int64_t predecessor, + int64_t successor) { SetValue(predecessor, node); SetValue(node, successor); MakeDisjunctionNodesUnperformed(node); } void CheapestInsertionFilteredHeuristic::AppendEvaluatedPositionsAfter( - int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, - std::vector* valued_positions) { + int64_t node_to_insert, int64_t start, int64_t next_after_start, + int64_t vehicle, std::vector* valued_positions) { CHECK(valued_positions != nullptr); - int64 insert_after = start; + int64_t insert_after = start; while (!model()->IsEnd(insert_after)) { - const int64 insert_before = + const int64_t insert_before = (insert_after == start) ? next_after_start : Value(insert_after); valued_positions->push_back(std::make_pair( GetInsertionCostForNodeAtPosition(node_to_insert, insert_after, @@ -3212,31 +534,31 @@ void CheapestInsertionFilteredHeuristic::AppendEvaluatedPositionsAfter( } } -int64 CheapestInsertionFilteredHeuristic::GetInsertionCostForNodeAtPosition( - int64 node_to_insert, int64 insert_after, int64 insert_before, +int64_t CheapestInsertionFilteredHeuristic::GetInsertionCostForNodeAtPosition( + int64_t node_to_insert, int64_t insert_after, int64_t insert_before, int vehicle) const { return CapSub(CapAdd(evaluator_(insert_after, node_to_insert, vehicle), evaluator_(node_to_insert, insert_before, vehicle)), evaluator_(insert_after, insert_before, vehicle)); } -int64 CheapestInsertionFilteredHeuristic::GetUnperformedValue( - int64 node_to_insert) const { +int64_t CheapestInsertionFilteredHeuristic::GetUnperformedValue( + int64_t node_to_insert) const { if (penalty_evaluator_ != nullptr) { return penalty_evaluator_(node_to_insert); } - return kint64max; + return std::numeric_limits::max(); } namespace { template -void SortAndExtractPairSeconds(std::vector>* pairs, +void SortAndExtractPairSeconds(std::vector>* pairs, std::vector* sorted_seconds) { CHECK(pairs != nullptr); CHECK(sorted_seconds != nullptr); std::sort(pairs->begin(), pairs->end()); sorted_seconds->reserve(pairs->size()); - for (const std::pair& p : *pairs) { + for (const std::pair& p : *pairs) { sorted_seconds->push_back(p.second); } } @@ -3250,7 +572,7 @@ class GlobalCheapestInsertionFilteredHeuristic::PairEntry { PairEntry(int pickup_to_insert, int pickup_insert_after, int delivery_to_insert, int delivery_insert_after, int vehicle) : heap_index_(-1), - value_(kint64max), + value_(std::numeric_limits::max()), pickup_to_insert_(pickup_to_insert), pickup_insert_after_(pickup_insert_after), delivery_to_insert_(delivery_to_insert), @@ -3275,8 +597,8 @@ class GlobalCheapestInsertionFilteredHeuristic::PairEntry { } void SetHeapIndex(int h) { heap_index_ = h; } int GetHeapIndex() const { return heap_index_; } - int64 value() const { return value_; } - void set_value(int64 value) { value_ = value; } + int64_t value() const { return value_; } + void set_value(int64_t value) { value_ = value; } int pickup_to_insert() const { return pickup_to_insert_; } int pickup_insert_after() const { return pickup_insert_after_; } void set_pickup_insert_after(int pickup_insert_after) { @@ -3289,7 +611,7 @@ class GlobalCheapestInsertionFilteredHeuristic::PairEntry { private: int heap_index_; - int64 value_; + int64_t value_; const int pickup_to_insert_; int pickup_insert_after_; const int delivery_to_insert_; @@ -3302,7 +624,7 @@ class GlobalCheapestInsertionFilteredHeuristic::NodeEntry { public: NodeEntry(int node_to_insert, int insert_after, int vehicle) : heap_index_(-1), - value_(kint64max), + value_(std::numeric_limits::max()), node_to_insert_(node_to_insert), insert_after_(insert_after), vehicle_(vehicle) {} @@ -3319,8 +641,8 @@ class GlobalCheapestInsertionFilteredHeuristic::NodeEntry { } void SetHeapIndex(int h) { heap_index_ = h; } int GetHeapIndex() const { return heap_index_; } - int64 value() const { return value_; } - void set_value(int64 value) { value_ = value; } + int64_t value() const { return value_; } + void set_value(int64_t value) { value_ = value; } int node_to_insert() const { return node_to_insert_; } int insert_after() const { return insert_after_; } void set_insert_after(int insert_after) { insert_after_ = insert_after; } @@ -3329,7 +651,7 @@ class GlobalCheapestInsertionFilteredHeuristic::NodeEntry { private: int heap_index_; - int64 value_; + int64_t value_; const int node_to_insert_; int insert_after_; int vehicle_; @@ -3340,8 +662,8 @@ class GlobalCheapestInsertionFilteredHeuristic::NodeEntry { GlobalCheapestInsertionFilteredHeuristic:: GlobalCheapestInsertionFilteredHeuristic( RoutingModel* model, - std::function evaluator, - std::function penalty_evaluator, + std::function evaluator, + std::function penalty_evaluator, LocalSearchFilterManager* filter_manager, GlobalCheapestInsertionParameters parameters) : CheapestInsertionFilteredHeuristic(model, std::move(evaluator), @@ -3375,24 +697,24 @@ void GlobalCheapestInsertionFilteredHeuristic::ComputeNeighborhoods() { } // TODO(user): Refactor the neighborhood computations in RoutingModel. - const int64 num_neighbors = NumNeighbors(); + const int64_t num_neighbors = NumNeighbors(); // If num_neighbors was greater or equal num_non_start_end_nodes - 1, // gci_params_.neighbors_ratio should have been set to 1. DCHECK_LT(num_neighbors, NumNonStartEndNodes() - 1); const RoutingModel& routing_model = *model(); - const int64 size = routing_model.Size(); + const int64_t size = routing_model.Size(); node_index_to_neighbors_by_cost_class_.resize(size); const int num_cost_classes = routing_model.GetCostClassesCount(); - for (int64 node_index = 0; node_index < size; node_index++) { + for (int64_t node_index = 0; node_index < size; node_index++) { node_index_to_neighbors_by_cost_class_[node_index].resize(num_cost_classes); for (int cc = 0; cc < num_cost_classes; cc++) { node_index_to_neighbors_by_cost_class_[node_index][cc] = - absl::make_unique>(size); + absl::make_unique>(size); } } - for (int64 node_index = 0; node_index < size; ++node_index) { + for (int64_t node_index = 0; node_index < size; ++node_index) { DCHECK(!routing_model.IsEnd(node_index)); if (routing_model.IsStart(node_index)) { // We don't compute neighbors for vehicle starts: all nodes are considered @@ -3407,7 +729,8 @@ void GlobalCheapestInsertionFilteredHeuristic::ComputeNeighborhoods() { // No vehicle with this cost class, avoid unnecessary computations. continue; } - std::vector> costed_after_nodes; + std::vector> + costed_after_nodes; costed_after_nodes.reserve(size); for (int after_node = 0; after_node < size; ++after_node) { if (after_node != node_index && !routing_model.IsStart(after_node)) { @@ -3434,7 +757,7 @@ void GlobalCheapestInsertionFilteredHeuristic::ComputeNeighborhoods() { } // Add all vehicle starts as neighbors to this node and vice-versa. for (int vehicle = 0; vehicle < routing_model.vehicles(); vehicle++) { - const int64 vehicle_start = routing_model.Start(vehicle); + const int64_t vehicle_start = routing_model.Start(vehicle); node_index_to_neighbors_by_cost_class_[node_index][cost_class]->Set( vehicle_start); node_index_to_neighbors_by_cost_class_[vehicle_start][cost_class]->Set( @@ -3445,7 +768,7 @@ void GlobalCheapestInsertionFilteredHeuristic::ComputeNeighborhoods() { } bool GlobalCheapestInsertionFilteredHeuristic::IsNeighborForCostClass( - int cost_class, int64 node_index, int64 neighbor_index) const { + int cost_class, int64_t node_index, int64_t neighbor_index) const { return gci_params_.neighbors_ratio == 1 || (*node_index_to_neighbors_by_cost_class_[node_index] [cost_class])[neighbor_index]; @@ -3489,14 +812,14 @@ bool GlobalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { for (int index = 0; index < pickup_delivery_pairs.size(); index++) { const RoutingModel::IndexPair& index_pair = pickup_delivery_pairs[index]; int pickup_vehicle = -1; - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { if (Contains(pickup)) { pickup_vehicle = node_index_to_vehicle_[pickup]; break; } } int delivery_vehicle = -1; - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { if (Contains(delivery)) { delivery_vehicle = node_index_to_vehicle_[delivery]; break; @@ -3507,13 +830,13 @@ bool GlobalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { } if (pickup_vehicle >= 0 && delivery_vehicle < 0) { std::vector& pair_nodes = vehicle_to_pair_nodes[pickup_vehicle]; - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { pair_nodes.push_back(delivery); } } if (pickup_vehicle < 0 && delivery_vehicle >= 0) { std::vector& pair_nodes = vehicle_to_pair_nodes[delivery_vehicle]; - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { pair_nodes.push_back(pickup); } } @@ -3571,8 +894,8 @@ void GlobalCheapestInsertionFilteredHeuristic::InsertPairs( return; } PairEntry* const entry = priority_queue.Top(); - const int64 pickup = entry->pickup_to_insert(); - const int64 delivery = entry->delivery_to_insert(); + const int64_t pickup = entry->pickup_to_insert(); + const int64_t delivery = entry->delivery_to_insert(); if (Contains(pickup) || Contains(delivery)) { DeletePairEntry(entry, &priority_queue, &pickup_to_entries, &delivery_to_entries); @@ -3600,14 +923,14 @@ void GlobalCheapestInsertionFilteredHeuristic::InsertPairs( continue; } - const int64 pickup_insert_after = entry->pickup_insert_after(); - const int64 pickup_insert_before = Value(pickup_insert_after); + const int64_t pickup_insert_after = entry->pickup_insert_after(); + const int64_t pickup_insert_before = Value(pickup_insert_after); InsertBetween(pickup, pickup_insert_after, pickup_insert_before); - const int64 delivery_insert_after = entry->delivery_insert_after(); - const int64 delivery_insert_before = (delivery_insert_after == pickup) - ? pickup_insert_before - : Value(delivery_insert_after); + const int64_t delivery_insert_after = entry->delivery_insert_after(); + const int64_t delivery_insert_before = (delivery_insert_after == pickup) + ? pickup_insert_before + : Value(delivery_insert_after); InsertBetween(delivery, delivery_insert_after, delivery_insert_before); if (Commit()) { UpdateAfterPairInsertion(pair_indices, entry_vehicle, pickup, @@ -3641,9 +964,10 @@ bool GlobalCheapestInsertionFilteredHeuristic:: // As we only have one pair_entry per empty vehicle type, we try inserting on // all vehicles of this type with the same fixed cost, as they all have the // same insertion value. - const int64 pickup = pair_entry->pickup_to_insert(); - const int64 delivery = pair_entry->delivery_to_insert(); - const int64 entry_fixed_cost = model()->GetFixedCostOfVehicle(entry_vehicle); + const int64_t pickup = pair_entry->pickup_to_insert(); + const int64_t delivery = pair_entry->delivery_to_insert(); + const int64_t entry_fixed_cost = + model()->GetFixedCostOfVehicle(entry_vehicle); auto vehicle_is_compatible = [this, entry_fixed_cost, pickup, delivery](int vehicle) { if (model()->GetFixedCostOfVehicle(vehicle) != entry_fixed_cost) { @@ -3651,7 +975,7 @@ bool GlobalCheapestInsertionFilteredHeuristic:: } // NOTE: Only empty vehicles should be in the vehicle_curator_. DCHECK(VehicleIsEmpty(vehicle)); - const int64 end = model()->End(vehicle); + const int64_t end = model()->End(vehicle); InsertBetween(pickup, model()->Start(vehicle), end); InsertBetween(delivery, pickup, end); return Commit(); @@ -3669,7 +993,7 @@ bool GlobalCheapestInsertionFilteredHeuristic:: vehicle_is_compatible, stop_and_return_vehicle); if (compatible_vehicle >= 0) { // The pair was inserted on this vehicle. - const int64 vehicle_start = model()->Start(compatible_vehicle); + const int64_t vehicle_start = model()->Start(compatible_vehicle); const int num_previous_vehicle_entries = pickup_to_entries->at(vehicle_start).size() + delivery_to_entries->at(vehicle_start).size(); @@ -3744,7 +1068,7 @@ void GlobalCheapestInsertionFilteredHeuristic::InsertNodesOnRoutes( } return; } - const int64 node_to_insert = node_entry->node_to_insert(); + const int64_t node_to_insert = node_entry->node_to_insert(); if (Contains(node_to_insert)) { DeleteNodeEntry(node_entry, &priority_queue, &position_to_node_entries); continue; @@ -3769,7 +1093,7 @@ void GlobalCheapestInsertionFilteredHeuristic::InsertNodesOnRoutes( continue; } - const int64 insert_after = node_entry->insert_after(); + const int64_t insert_after = node_entry->insert_after(); InsertBetween(node_to_insert, insert_after, Value(insert_after)); if (Commit()) { UpdatePositions(nodes, entry_vehicle, node_to_insert, all_vehicles, @@ -3802,8 +1126,9 @@ bool GlobalCheapestInsertionFilteredHeuristic:: // As we only have one node_entry per type, we try inserting on all vehicles // of this type with the same fixed cost as they all have the same insertion // value. - const int64 node_to_insert = node_entry->node_to_insert(); - const int64 entry_fixed_cost = model()->GetFixedCostOfVehicle(entry_vehicle); + const int64_t node_to_insert = node_entry->node_to_insert(); + const int64_t entry_fixed_cost = + model()->GetFixedCostOfVehicle(entry_vehicle); auto vehicle_is_compatible = [this, entry_fixed_cost, node_to_insert](int vehicle) { if (model()->GetFixedCostOfVehicle(vehicle) != entry_fixed_cost) { @@ -3830,7 +1155,7 @@ bool GlobalCheapestInsertionFilteredHeuristic:: // The node was inserted on this vehicle. UpdatePositions(nodes, compatible_vehicle, node_to_insert, all_vehicles, priority_queue, position_to_node_entries); - const int64 compatible_start = model()->Start(compatible_vehicle); + const int64_t compatible_start = model()->Start(compatible_vehicle); const bool no_prior_entries_for_this_vehicle = position_to_node_entries->at(compatible_start).empty(); UpdatePositions(nodes, compatible_vehicle, compatible_start, all_vehicles, @@ -3986,8 +1311,8 @@ int GlobalCheapestInsertionFilteredHeuristic::InsertSeedNode( } if (!(*is_vehicle_used)[seed_vehicle]) { // Try to insert this seed_node on this vehicle's route. - const int64 start = model()->Start(seed_vehicle); - const int64 end = model()->End(seed_vehicle); + const int64_t start = model()->Start(seed_vehicle); + const int64_t end = model()->End(seed_vehicle); DCHECK_EQ(Value(start), end); InsertBetween(seed_node, start, end); if (Commit()) { @@ -4030,9 +1355,9 @@ void GlobalCheapestInsertionFilteredHeuristic::InitializePairPositions( model()->GetPickupAndDeliveryPairs(); for (int index : pair_indices) { const RoutingModel::IndexPair& index_pair = pickup_delivery_pairs[index]; - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { if (Contains(pickup)) continue; - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { if (Contains(delivery)) continue; // Add insertion entry making pair unperformed. When the pair is part // of a disjunction we do not try to make any of its pairs unperformed @@ -4040,8 +1365,10 @@ void GlobalCheapestInsertionFilteredHeuristic::InitializePairPositions( // TODO(user): Adapt the code to make pair disjunctions unperformed. if (gci_params_.add_unperformed_entries && index_pair.first.size() == 1 && index_pair.second.size() == 1 && - GetUnperformedValue(pickup) != kint64max && - GetUnperformedValue(delivery) != kint64max) { + GetUnperformedValue(pickup) != + std::numeric_limits::max() && + GetUnperformedValue(delivery) != + std::numeric_limits::max()) { AddPairEntry(pickup, -1, delivery, -1, -1, priority_queue, nullptr, nullptr); } @@ -4056,7 +1383,7 @@ void GlobalCheapestInsertionFilteredHeuristic::InitializePairPositions( void GlobalCheapestInsertionFilteredHeuristic:: InitializeInsertionEntriesPerformingPair( - int64 pickup, int64 delivery, + int64_t pickup, int64_t delivery, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::PairEntry>* priority_queue, @@ -4065,7 +1392,7 @@ void GlobalCheapestInsertionFilteredHeuristic:: std::vector* delivery_to_entries) { if (!gci_params_.use_neighbors_ratio_for_initialization) { - std::vector, std::pair>> + std::vector, std::pair>> valued_positions; for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { if (VehicleIsEmpty(vehicle) && @@ -4075,13 +1402,13 @@ void GlobalCheapestInsertionFilteredHeuristic:: // entries. continue; } - const int64 start = model()->Start(vehicle); + const int64_t start = model()->Start(vehicle); std::vector valued_pickup_positions; AppendEvaluatedPositionsAfter(pickup, start, Value(start), vehicle, &valued_pickup_positions); for (const ValuedPosition& valued_pickup_position : valued_pickup_positions) { - const int64 pickup_position = valued_pickup_position.second; + const int64_t pickup_position = valued_pickup_position.second; CHECK(!model()->IsEnd(pickup_position)); std::vector valued_delivery_positions; AppendEvaluatedPositionsAfter(delivery, pickup, Value(pickup_position), @@ -4110,15 +1437,17 @@ void GlobalCheapestInsertionFilteredHeuristic:: // the pickup/delivery pair. for (int cost_class = 0; cost_class < model()->GetCostClassesCount(); cost_class++) { - absl::flat_hash_set> existing_insertion_positions; + absl::flat_hash_set> + existing_insertion_positions; // Explore the neighborhood of the pickup. - for (const int64 pickup_insert_after : + for (const int64_t pickup_insert_after : GetNeighborsOfNodeForCostClass(cost_class, pickup)) { if (!Contains(pickup_insert_after)) { continue; } const int vehicle = node_index_to_vehicle_[pickup_insert_after]; - if (model()->GetCostClassIndexOfVehicle(vehicle).value() != cost_class) { + if (vehicle < 0 || + model()->GetCostClassIndexOfVehicle(vehicle).value() != cost_class) { continue; } @@ -4130,9 +1459,9 @@ void GlobalCheapestInsertionFilteredHeuristic:: continue; } - int64 delivery_insert_after = pickup; + int64_t delivery_insert_after = pickup; while (!model()->IsEnd(delivery_insert_after)) { - const std::pair insertion_position = { + const std::pair insertion_position = { pickup_insert_after, delivery_insert_after}; DCHECK(!gtl::ContainsKey(existing_insertion_positions, insertion_position)); @@ -4148,13 +1477,14 @@ void GlobalCheapestInsertionFilteredHeuristic:: } // Explore the neighborhood of the delivery. - for (const int64 delivery_insert_after : + for (const int64_t delivery_insert_after : GetNeighborsOfNodeForCostClass(cost_class, delivery)) { if (!Contains(delivery_insert_after)) { continue; } const int vehicle = node_index_to_vehicle_[delivery_insert_after]; - if (model()->GetCostClassIndexOfVehicle(vehicle).value() != cost_class) { + if (vehicle < 0 || + model()->GetCostClassIndexOfVehicle(vehicle).value() != cost_class) { continue; } @@ -4163,7 +1493,7 @@ void GlobalCheapestInsertionFilteredHeuristic:: DCHECK_EQ(delivery_insert_after, model()->Start(vehicle)); } - int64 pickup_insert_after = model()->Start(vehicle); + int64_t pickup_insert_after = model()->Start(vehicle); while (pickup_insert_after != delivery_insert_after) { if (!gtl::ContainsKey( existing_insertion_positions, @@ -4179,8 +1509,8 @@ void GlobalCheapestInsertionFilteredHeuristic:: } void GlobalCheapestInsertionFilteredHeuristic::UpdateAfterPairInsertion( - const std::vector& pair_indices, int vehicle, int64 pickup, - int64 pickup_position, int64 delivery, int64 delivery_position, + const std::vector& pair_indices, int vehicle, int64_t pickup, + int64_t pickup_position, int64_t delivery, int64_t delivery_position, AdjustablePriorityQueue* priority_queue, std::vector* pickup_to_entries, std::vector* delivery_to_entries) { @@ -4200,7 +1530,7 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdateAfterPairInsertion( void GlobalCheapestInsertionFilteredHeuristic::UpdatePickupPositions( const std::vector& pair_indices, int vehicle, - int64 pickup_insert_after, + int64_t pickup_insert_after, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::PairEntry>* priority_queue, std::vector* @@ -4209,8 +1539,8 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdatePickupPositions( delivery_to_entries) { // First, remove entries which have already been inserted and keep track of // the entries which are being kept and must be updated. - using Pair = std::pair; - using Insertion = std::pair; + using Pair = std::pair; + using Insertion = std::pair; absl::flat_hash_set existing_insertions; std::vector to_remove; for (PairEntry* const pair_entry : @@ -4236,22 +1566,22 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdatePickupPositions( // Create new entries for which the pickup is to be inserted after // pickup_insert_after. const int cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value(); - const int64 pickup_insert_before = Value(pickup_insert_after); + const int64_t pickup_insert_before = Value(pickup_insert_after); const RoutingModel::IndexPairs& pickup_delivery_pairs = model()->GetPickupAndDeliveryPairs(); for (int pair_index : pair_indices) { const RoutingModel::IndexPair& index_pair = pickup_delivery_pairs[pair_index]; - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { if (Contains(pickup) || !IsNeighborForCostClass(cost_class, pickup_insert_after, pickup)) { continue; } - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { if (Contains(delivery)) { continue; } - int64 delivery_insert_after = pickup; + int64_t delivery_insert_after = pickup; while (!model()->IsEnd(delivery_insert_after)) { const Insertion insertion = {{pickup, delivery}, delivery_insert_after}; @@ -4273,7 +1603,7 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdatePickupPositions( void GlobalCheapestInsertionFilteredHeuristic::UpdateDeliveryPositions( const std::vector& pair_indices, int vehicle, - int64 delivery_insert_after, + int64_t delivery_insert_after, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::PairEntry>* priority_queue, std::vector* @@ -4282,8 +1612,8 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdateDeliveryPositions( delivery_to_entries) { // First, remove entries which have already been inserted and keep track of // the entries which are being kept and must be updated. - using Pair = std::pair; - using Insertion = std::pair; + using Pair = std::pair; + using Insertion = std::pair; absl::flat_hash_set existing_insertions; std::vector to_remove; for (PairEntry* const pair_entry : @@ -4314,17 +1644,17 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdateDeliveryPositions( for (int pair_index : pair_indices) { const RoutingModel::IndexPair& index_pair = pickup_delivery_pairs[pair_index]; - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { if (Contains(delivery) || !IsNeighborForCostClass(cost_class, delivery_insert_after, delivery)) { continue; } - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { if (Contains(pickup)) { continue; } - int64 pickup_insert_after = model()->Start(vehicle); + int64_t pickup_insert_after = model()->Start(vehicle); while (pickup_insert_after != delivery_insert_after) { const Insertion insertion = {{pickup, delivery}, pickup_insert_after}; if (!gtl::ContainsKey(existing_insertions, insertion)) { @@ -4356,8 +1686,8 @@ void GlobalCheapestInsertionFilteredHeuristic::DeletePairEntry( } void GlobalCheapestInsertionFilteredHeuristic::AddPairEntry( - int64 pickup, int64 pickup_insert_after, int64 delivery, - int64 delivery_insert_after, int vehicle, + int64_t pickup, int64_t pickup_insert_after, int64_t delivery, + int64_t delivery_insert_after, int vehicle, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::PairEntry>* priority_queue, std::vector* @@ -4404,24 +1734,23 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdatePairEntry( priority_queue->NoteChangedPriority(pair_entry); } -int64 GlobalCheapestInsertionFilteredHeuristic:: - GetInsertionValueForPairAtPositions(int64 pickup, int64 pickup_insert_after, - int64 delivery, - int64 delivery_insert_after, - int vehicle) const { +int64_t +GlobalCheapestInsertionFilteredHeuristic::GetInsertionValueForPairAtPositions( + int64_t pickup, int64_t pickup_insert_after, int64_t delivery, + int64_t delivery_insert_after, int vehicle) const { DCHECK_GE(pickup_insert_after, 0); - const int64 pickup_insert_before = Value(pickup_insert_after); - const int64 pickup_value = GetInsertionCostForNodeAtPosition( + const int64_t pickup_insert_before = Value(pickup_insert_after); + const int64_t pickup_value = GetInsertionCostForNodeAtPosition( pickup, pickup_insert_after, pickup_insert_before, vehicle); DCHECK_GE(delivery_insert_after, 0); - const int64 delivery_insert_before = (delivery_insert_after == pickup) - ? pickup_insert_before - : Value(delivery_insert_after); - const int64 delivery_value = GetInsertionCostForNodeAtPosition( + const int64_t delivery_insert_before = (delivery_insert_after == pickup) + ? pickup_insert_before + : Value(delivery_insert_after); + const int64_t delivery_value = GetInsertionCostForNodeAtPosition( delivery, delivery_insert_after, delivery_insert_before, vehicle); - const int64 penalty_shift = + const int64_t penalty_shift = absl::GetFlag(FLAGS_routing_shift_insertion_cost_by_penalty) ? CapAdd(GetUnperformedValue(pickup), GetUnperformedValue(delivery)) : 0; @@ -4448,7 +1777,7 @@ void GlobalCheapestInsertionFilteredHeuristic::InitializePositions( } // Add insertion entry making node unperformed. if (gci_params_.add_unperformed_entries && - GetUnperformedValue(node) != kint64max) { + GetUnperformedValue(node) != std::numeric_limits::max()) { AddNodeEntry(node, -1, -1, all_vehicles, priority_queue, nullptr); } // Add all insertion entries making node performed. @@ -4459,7 +1788,7 @@ void GlobalCheapestInsertionFilteredHeuristic::InitializePositions( void GlobalCheapestInsertionFilteredHeuristic:: InitializeInsertionEntriesPerformingNode( - int64 node, const absl::flat_hash_set& vehicles, + int64_t node, const absl::flat_hash_set& vehicles, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::NodeEntry>* priority_queue, @@ -4474,7 +1803,7 @@ void GlobalCheapestInsertionFilteredHeuristic:: for (int v = 0; v < num_vehicles; v++) { const int vehicle = vehicles.empty() ? v : *vehicles_it++; - const int64 start = model()->Start(vehicle); + const int64_t start = model()->Start(vehicle); if (all_vehicles && VehicleIsEmpty(vehicle) && empty_vehicle_type_curator_->GetLowestFixedCostVehicleOfType( empty_vehicle_type_curator_->Type(vehicle)) != vehicle) { @@ -4485,7 +1814,8 @@ void GlobalCheapestInsertionFilteredHeuristic:: std::vector valued_positions; AppendEvaluatedPositionsAfter(node, start, Value(start), vehicle, &valued_positions); - for (const std::pair& valued_position : valued_positions) { + for (const std::pair& valued_position : + valued_positions) { AddNodeEntry(node, valued_position.second, vehicle, all_vehicles, priority_queue, position_to_node_entries); } @@ -4502,7 +1832,7 @@ void GlobalCheapestInsertionFilteredHeuristic:: }; for (int cost_class = 0; cost_class < model()->GetCostClassesCount(); cost_class++) { - for (const int64 insert_after : + for (const int64_t insert_after : GetNeighborsOfNodeForCostClass(cost_class, node)) { if (!Contains(insert_after)) { continue; @@ -4526,7 +1856,7 @@ void GlobalCheapestInsertionFilteredHeuristic:: } void GlobalCheapestInsertionFilteredHeuristic::UpdatePositions( - const std::vector& nodes, int vehicle, int64 insert_after, + const std::vector& nodes, int vehicle, int64_t insert_after, bool all_vehicles, AdjustablePriorityQueue< GlobalCheapestInsertionFilteredHeuristic::NodeEntry>* priority_queue, @@ -4538,7 +1868,7 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdatePositions( absl::flat_hash_set existing_insertions; for (NodeEntry* const node_entry : node_entries->at(insert_after)) { DCHECK_EQ(node_entry->insert_after(), insert_after); - const int64 node_to_insert = node_entry->node_to_insert(); + const int64_t node_to_insert = node_entry->node_to_insert(); if (Contains(node_to_insert)) { to_remove.push_back(node_entry); } else { @@ -4573,11 +1903,11 @@ void GlobalCheapestInsertionFilteredHeuristic::DeleteNodeEntry( } void GlobalCheapestInsertionFilteredHeuristic::AddNodeEntry( - int64 node, int64 insert_after, int vehicle, bool all_vehicles, + int64_t node, int64_t insert_after, int vehicle, bool all_vehicles, AdjustablePriorityQueue* priority_queue, std::vector* node_entries) const { - const int64 node_penalty = GetUnperformedValue(node); - const int64 penalty_shift = + const int64_t node_penalty = GetUnperformedValue(node); + const int64_t penalty_shift = absl::GetFlag(FLAGS_routing_shift_insertion_cost_by_penalty) ? node_penalty : 0; @@ -4595,7 +1925,7 @@ void GlobalCheapestInsertionFilteredHeuristic::AddNodeEntry( return; } - const int64 insertion_cost = GetInsertionCostForNodeAtPosition( + const int64_t insertion_cost = GetInsertionCostForNodeAtPosition( node, insert_after, Value(insert_after), vehicle); if (!all_vehicles && insertion_cost > node_penalty) { // NOTE: When all vehicles aren't considered for insertion, we don't @@ -4615,12 +1945,12 @@ void GlobalCheapestInsertionFilteredHeuristic::AddNodeEntry( void GlobalCheapestInsertionFilteredHeuristic::UpdateNodeEntry( NodeEntry* const node_entry, AdjustablePriorityQueue* priority_queue) const { - const int64 node = node_entry->node_to_insert(); - const int64 insert_after = node_entry->insert_after(); + const int64_t node = node_entry->node_to_insert(); + const int64_t insert_after = node_entry->insert_after(); DCHECK_GE(insert_after, 0); - const int64 insertion_cost = GetInsertionCostForNodeAtPosition( + const int64_t insertion_cost = GetInsertionCostForNodeAtPosition( node, insert_after, Value(insert_after), node_entry->vehicle()); - const int64 penalty_shift = + const int64_t penalty_shift = absl::GetFlag(FLAGS_routing_shift_insertion_cost_by_penalty) ? GetUnperformedValue(node) : 0; @@ -4636,7 +1966,7 @@ void GlobalCheapestInsertionFilteredHeuristic::UpdateNodeEntry( LocalCheapestInsertionFilteredHeuristic:: LocalCheapestInsertionFilteredHeuristic( RoutingModel* model, - std::function evaluator, + std::function evaluator, LocalSearchFilterManager* filter_manager) : CheapestInsertionFilteredHeuristic(model, std::move(evaluator), nullptr, filter_manager) { @@ -4651,19 +1981,19 @@ bool LocalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { // Marking if we've tried inserting a node. std::vector visited(model()->Size(), false); // Possible positions where the current node can inserted. - std::vector insertion_positions; + std::vector insertion_positions; // Possible positions where its associated delivery node can inserted (if the // current node has one). - std::vector delivery_insertion_positions; + std::vector delivery_insertion_positions; // Iterating on pickup and delivery pairs const RoutingModel::IndexPairs& index_pairs = model()->GetPickupAndDeliveryPairs(); for (const auto& index_pair : index_pairs) { - for (int64 pickup : index_pair.first) { + for (int64_t pickup : index_pair.first) { if (Contains(pickup)) { continue; } - for (int64 delivery : index_pair.second) { + for (int64_t delivery : index_pair.second) { // If either is already in the solution, let it be inserted in the // standard node insertion loop. if (Contains(delivery)) { @@ -4673,15 +2003,16 @@ bool LocalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { visited[pickup] = true; visited[delivery] = true; ComputeEvaluatorSortedPositions(pickup, &insertion_positions); - for (const int64 pickup_insertion : insertion_positions) { + for (const int64_t pickup_insertion : insertion_positions) { const int pickup_insertion_next = Value(pickup_insertion); ComputeEvaluatorSortedPositionsOnRouteAfter( delivery, pickup, pickup_insertion_next, &delivery_insertion_positions); bool found = false; - for (const int64 delivery_insertion : delivery_insertion_positions) { + for (const int64_t delivery_insertion : + delivery_insertion_positions) { InsertBetween(pickup, pickup_insertion, pickup_insertion_next); - const int64 delivery_insertion_next = + const int64_t delivery_insertion_next = (delivery_insertion == pickup_insertion) ? pickup : (delivery_insertion == pickup) ? pickup_insertion_next : Value(delivery_insertion); @@ -4708,7 +2039,7 @@ bool LocalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { node_queue.pop(); if (Contains(node) || visited[node]) continue; ComputeEvaluatorSortedPositions(node, &insertion_positions); - for (const int64 insertion : insertion_positions) { + for (const int64_t insertion : insertion_positions) { if (StopSearch()) return false; InsertBetween(node, insertion, Value(insertion)); if (Commit()) { @@ -4721,15 +2052,15 @@ bool LocalCheapestInsertionFilteredHeuristic::BuildSolutionInternal() { } void LocalCheapestInsertionFilteredHeuristic::ComputeEvaluatorSortedPositions( - int64 node, std::vector* sorted_positions) { + int64_t node, std::vector* sorted_positions) { CHECK(sorted_positions != nullptr); CHECK(!Contains(node)); sorted_positions->clear(); const int size = model()->Size(); if (node < size) { - std::vector> valued_positions; + std::vector> valued_positions; for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { - const int64 start = model()->Start(vehicle); + const int64_t start = model()->Start(vehicle); AppendEvaluatedPositionsAfter(node, start, Value(start), vehicle, &valued_positions); } @@ -4739,15 +2070,15 @@ void LocalCheapestInsertionFilteredHeuristic::ComputeEvaluatorSortedPositions( void LocalCheapestInsertionFilteredHeuristic:: ComputeEvaluatorSortedPositionsOnRouteAfter( - int64 node, int64 start, int64 next_after_start, - std::vector* sorted_positions) { + int64_t node, int64_t start, int64_t next_after_start, + std::vector* sorted_positions) { CHECK(sorted_positions != nullptr); CHECK(!Contains(node)); sorted_positions->clear(); const int size = model()->Size(); if (node < size) { // TODO(user): Take vehicle into account. - std::vector> valued_positions; + std::vector> valued_positions; AppendEvaluatedPositionsAfter(node, start, next_after_start, 0, &valued_positions); SortAndExtractPairSeconds(&valued_positions, sorted_positions); @@ -4763,8 +2094,8 @@ CheapestAdditionFilteredHeuristic::CheapestAdditionFilteredHeuristic( bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { const int kUnassigned = -1; const RoutingModel::IndexPairs& pairs = model()->GetPickupAndDeliveryPairs(); - std::vector> deliveries(Size()); - std::vector> pickups(Size()); + std::vector> deliveries(Size()); + std::vector> pickups(Size()); for (const RoutingModel::IndexPair& pair : pairs) { for (int first : pair.first) { for (int second : pair.second) { @@ -4784,7 +2115,7 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { PartialRoutesAndLargeVehicleIndicesFirst(*this)); // Neighbors of the node currently being extended. for (const int vehicle : sorted_vehicles) { - int64 last_node = GetStartChainEnd(vehicle); + int64_t last_node = GetStartChainEnd(vehicle); bool extend_route = true; // Extend the route of the current vehicle while it's possible. We can // iterate more than once if pickup and delivery pairs have been inserted @@ -4793,8 +2124,8 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { while (extend_route) { extend_route = false; bool found = true; - int64 index = last_node; - int64 end = GetEndChainStart(vehicle); + int64_t index = last_node; + int64_t end = GetEndChainStart(vehicle); // Extend the route until either the end node of the vehicle is reached // or no node or node pair can be added. Deliveries in pickup and // delivery pairs are added at the same time as pickups, at the end of the @@ -4802,7 +2133,7 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { // alone. while (found && !model()->IsEnd(index)) { found = false; - std::vector neighbors; + std::vector neighbors; if (index < model()->Nexts().size()) { std::unique_ptr it( model()->Nexts()[index]->MakeDomainIterator(false)); @@ -4811,7 +2142,7 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { next_values.end()); } for (int i = 0; !found && i < neighbors.size(); ++i) { - int64 next = -1; + int64_t next = -1; switch (i) { case 0: next = FindTopSuccessor(index, neighbors); @@ -4828,7 +2159,7 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { // Only add a delivery if one of its pickups has been added already. if (!model()->IsEnd(next) && !pickups[next].empty()) { bool contains_pickups = false; - for (int64 pickup : pickups[next]) { + for (int64_t pickup : pickups[next]) { if (Contains(pickup)) { contains_pickups = true; break; @@ -4838,7 +2169,7 @@ bool CheapestAdditionFilteredHeuristic::BuildSolutionInternal() { continue; } } - std::vector next_deliveries; + std::vector next_deliveries; if (next < deliveries.size()) { next_deliveries = GetPossibleNextsFromIterator( next, deliveries[next].begin(), deliveries[next].end()); @@ -4908,18 +2239,19 @@ bool CheapestAdditionFilteredHeuristic:: EvaluatorCheapestAdditionFilteredHeuristic:: EvaluatorCheapestAdditionFilteredHeuristic( - RoutingModel* model, std::function evaluator, + RoutingModel* model, std::function evaluator, LocalSearchFilterManager* filter_manager) : CheapestAdditionFilteredHeuristic(model, filter_manager), evaluator_(std::move(evaluator)) {} -int64 EvaluatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( - int64 node, const std::vector& successors) { - int64 best_evaluation = kint64max; - int64 best_successor = -1; - for (int64 successor : successors) { - const int64 evaluation = - (successor >= 0) ? evaluator_(node, successor) : kint64max; +int64_t EvaluatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( + int64_t node, const std::vector& successors) { + int64_t best_evaluation = std::numeric_limits::max(); + int64_t best_successor = -1; + for (int64_t successor : successors) { + const int64_t evaluation = (successor >= 0) + ? evaluator_(node, successor) + : std::numeric_limits::max(); if (evaluation < best_evaluation || (evaluation == best_evaluation && successor > best_successor)) { best_evaluation = evaluation; @@ -4930,10 +2262,10 @@ int64 EvaluatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( } void EvaluatorCheapestAdditionFilteredHeuristic::SortSuccessors( - int64 node, std::vector* successors) { - std::vector> values; + int64_t node, std::vector* successors) { + std::vector> values; values.reserve(successors->size()); - for (int64 successor : *successors) { + for (int64_t successor : *successors) { // Tie-breaking on largest node index to mimic the behavior of // CheapestValueSelector (search.cc). values.push_back({evaluator_(node, successor), -successor}); @@ -4954,8 +2286,8 @@ ComparatorCheapestAdditionFilteredHeuristic:: : CheapestAdditionFilteredHeuristic(model, filter_manager), comparator_(std::move(comparator)) {} -int64 ComparatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( - int64 node, const std::vector& successors) { +int64_t ComparatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( + int64_t node, const std::vector& successors) { return *std::min_element(successors.begin(), successors.end(), [this, node](int successor1, int successor2) { return comparator_(node, successor1, successor2); @@ -4963,7 +2295,7 @@ int64 ComparatorCheapestAdditionFilteredHeuristic::FindTopSuccessor( } void ComparatorCheapestAdditionFilteredHeuristic::SortSuccessors( - int64 node, std::vector* successors) { + int64_t node, std::vector* successors) { std::sort(successors->begin(), successors->end(), [this, node](int successor1, int successor2) { return comparator_(node, successor1, successor2); @@ -5031,7 +2363,7 @@ class SavingsFilteredHeuristic::SavingsContainer { sorted_(false), to_update_(true) {} - void InitializeContainer(int64 size, int64 saving_neighbors) { + void InitializeContainer(int64_t size, int64_t saving_neighbors) { sorted_savings_per_vehicle_type_.clear(); sorted_savings_per_vehicle_type_.resize(vehicle_types_); for (std::vector& savings : sorted_savings_per_vehicle_type_) { @@ -5059,8 +2391,8 @@ class SavingsFilteredHeuristic::SavingsContainer { outgoing_new_reinjected_savings_ = nullptr; } - void AddNewSaving(const Saving& saving, int64 total_cost, int64 before_node, - int64 after_node, int vehicle_type) { + void AddNewSaving(const Saving& saving, int64_t total_cost, + int64_t before_node, int64_t after_node, int vehicle_type) { CHECK(!sorted_savings_per_vehicle_type_.empty()) << "Container not initialized!"; sorted_savings_per_vehicle_type_[vehicle_type].push_back(saving); @@ -5091,19 +2423,19 @@ class SavingsFilteredHeuristic::SavingsContainer { for (int arc_index = 0; arc_index < costs_and_savings_per_arc_.size(); arc_index++) { - std::vector>& costs_and_savings = + std::vector>& costs_and_savings = costs_and_savings_per_arc_[arc_index]; DCHECK(!costs_and_savings.empty()); std::sort( costs_and_savings.begin(), costs_and_savings.end(), - [](const std::pair& cs1, - const std::pair& cs2) { return cs1 > cs2; }); + [](const std::pair& cs1, + const std::pair& cs2) { return cs1 > cs2; }); // Insert all Savings for this arc with the lowest cost into // sorted_savings_. // TODO(user): Also do this when reiterating on next_savings_. - const int64 cost = costs_and_savings.back().first; + const int64_t cost = costs_and_savings.back().first; while (!costs_and_savings.empty() && costs_and_savings.back().first == cost) { sorted_savings_.push_back( @@ -5165,7 +2497,7 @@ class SavingsFilteredHeuristic::SavingsContainer { void Update(bool update_best_saving, int type = -1) { CHECK(to_update_) << "Container already up to date!"; if (update_best_saving) { - const int64 arc_index = current_saving_.arc_index; + const int64_t arc_index = current_saving_.arc_index; UpdateNextAndSkippedSavingsForArcWithType(arc_index, type); } if (!HasReinjectedSavings()) { @@ -5197,12 +2529,12 @@ class SavingsFilteredHeuristic::SavingsContainer { return sorted_savings_per_vehicle_type_[type]; } - void ReinjectSkippedSavingsStartingAt(int64 node) { + void ReinjectSkippedSavingsStartingAt(int64_t node) { CHECK(outgoing_new_reinjected_savings_ == nullptr); outgoing_new_reinjected_savings_ = &(skipped_savings_starting_at_[node]); } - void ReinjectSkippedSavingsEndingAt(int64 node) { + void ReinjectSkippedSavingsEndingAt(int64_t node) { CHECK(incoming_new_reinjected_savings_ == nullptr); incoming_new_reinjected_savings_ = &(skipped_savings_ending_at_[node]); } @@ -5210,7 +2542,7 @@ class SavingsFilteredHeuristic::SavingsContainer { private: struct SavingAndArc { Saving saving; - int64 arc_index; + int64_t arc_index; bool operator<(const SavingAndArc& other) const { return std::tie(saving, arc_index) < @@ -5222,8 +2554,8 @@ class SavingsFilteredHeuristic::SavingsContainer { // skipped_savings_ vector of the nodes, if they're uncontained. void SkipSavingForArc(const SavingAndArc& saving_and_arc) { const Saving& saving = saving_and_arc.saving; - const int64 before_node = savings_db_->GetBeforeNodeFromSaving(saving); - const int64 after_node = savings_db_->GetAfterNodeFromSaving(saving); + const int64_t before_node = savings_db_->GetBeforeNodeFromSaving(saving); + const int64_t after_node = savings_db_->GetAfterNodeFromSaving(saving); if (!savings_db_->Contains(before_node)) { skipped_savings_starting_at_[before_node].push_back(saving_and_arc); } @@ -5242,7 +2574,7 @@ class SavingsFilteredHeuristic::SavingsContainer { // Finally, the right Saving is skipped for this arc: if looking for a // specific type (i.e. type != -1), next_saving (which has the correct type) // is skipped, otherwise the current_saving_ is. - void UpdateNextAndSkippedSavingsForArcWithType(int64 arc_index, int type) { + void UpdateNextAndSkippedSavingsForArcWithType(int64_t arc_index, int type) { if (single_vehicle_type_) { // No next Saving, skip the current Saving. CHECK_EQ(type, -1); @@ -5339,8 +2671,8 @@ class SavingsFilteredHeuristic::SavingsContainer { } void UpdateArcIndicesCostsAndSavings( - int64 before_node, int64 after_node, - const std::pair& cost_and_saving) { + int64_t before_node, int64_t after_node, + const std::pair& cost_and_saving) { if (single_vehicle_type_) { return; } @@ -5357,9 +2689,9 @@ class SavingsFilteredHeuristic::SavingsContainer { } } - bool GetNextSavingForArcWithType(int64 arc_index, int type, + bool GetNextSavingForArcWithType(int64_t arc_index, int type, Saving* next_saving) { - std::vector>& costs_and_savings = + std::vector>& costs_and_savings = costs_and_savings_per_arc_[arc_index]; bool found_saving = false; @@ -5376,7 +2708,7 @@ class SavingsFilteredHeuristic::SavingsContainer { const SavingsFilteredHeuristic* const savings_db_; const int vehicle_types_; - int64 index_in_sorted_savings_; + int64_t index_in_sorted_savings_; std::vector> sorted_savings_per_vehicle_type_; std::vector sorted_savings_; std::vector next_savings_; @@ -5384,7 +2716,7 @@ class SavingsFilteredHeuristic::SavingsContainer { next_saving_type_and_index_for_arc_; SavingAndArc current_saving_; const bool single_vehicle_type_; - std::vector>> + std::vector>> costs_and_savings_per_arc_; std::vector> arc_indices_per_before_node_; @@ -5426,7 +2758,7 @@ bool SavingsFilteredHeuristic::BuildSolutionInternal() { // Only store empty vehicles in the vehicle_type_curator_. vehicle_type_curator_->Reset( [this](int vehicle) { return VehicleIsEmpty(vehicle); }); - ComputeSavings(); + if (!ComputeSavings()) return false; BuildRoutesFromSavings(); // Free all the space used to store the Savings in the container. savings_container_.reset(); @@ -5437,7 +2769,7 @@ bool SavingsFilteredHeuristic::BuildSolutionInternal() { } int SavingsFilteredHeuristic::StartNewRouteWithBestVehicleOfType( - int type, int64 before_node, int64 after_node) { + int type, int64_t before_node, int64_t after_node) { auto vehicle_is_compatible = [this, before_node, after_node](int vehicle) { if (!model()->VehicleVar(before_node)->Contains(vehicle) || !model()->VehicleVar(after_node)->Contains(vehicle)) { @@ -5445,8 +2777,8 @@ int SavingsFilteredHeuristic::StartNewRouteWithBestVehicleOfType( } // Try to commit the arc on this vehicle. DCHECK(VehicleIsEmpty(vehicle)); - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); SetValue(start, before_node); SetValue(before_node, after_node); SetValue(after_node, end); @@ -5461,9 +2793,9 @@ int SavingsFilteredHeuristic::StartNewRouteWithBestVehicleOfType( } void SavingsFilteredHeuristic::AddSymmetricArcsToAdjacencyLists( - std::vector>* adjacency_lists) { - for (int64 node = 0; node < adjacency_lists->size(); node++) { - for (int64 neighbor : (*adjacency_lists)[node]) { + std::vector>* adjacency_lists) { + for (int64_t node = 0; node < adjacency_lists->size(); node++) { + for (int64_t neighbor : (*adjacency_lists)[node]) { if (model()->IsStart(neighbor) || model()->IsEnd(neighbor)) { continue; } @@ -5471,7 +2803,7 @@ void SavingsFilteredHeuristic::AddSymmetricArcsToAdjacencyLists( } } std::transform(adjacency_lists->begin(), adjacency_lists->end(), - adjacency_lists->begin(), [](std::vector vec) { + adjacency_lists->begin(), [](std::vector vec) { std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); return vec; @@ -5489,11 +2821,11 @@ void SavingsFilteredHeuristic::AddSymmetricArcsToAdjacencyLists( // The higher this saving value, the better the arc. // Here, the value stored for the savings is -saving, which are therefore // considered in decreasing order. -void SavingsFilteredHeuristic::ComputeSavings() { +bool SavingsFilteredHeuristic::ComputeSavings() { const int num_vehicle_types = vehicle_type_curator_->NumTypes(); const int size = model()->Size(); - std::vector uncontained_non_start_end_nodes; + std::vector uncontained_non_start_end_nodes; uncontained_non_start_end_nodes.reserve(size); for (int node = 0; node < size; node++) { if (!model()->IsStart(node) && !model()->IsEnd(node) && !Contains(node)) { @@ -5501,15 +2833,15 @@ void SavingsFilteredHeuristic::ComputeSavings() { } } - const int64 saving_neighbors = + const int64_t saving_neighbors = std::min(MaxNumNeighborsPerNode(num_vehicle_types), - static_cast(uncontained_non_start_end_nodes.size())); + static_cast(uncontained_non_start_end_nodes.size())); savings_container_ = absl::make_unique>(this, num_vehicle_types); savings_container_->InitializeContainer(size, saving_neighbors); - - std::vector> adjacency_lists(size); + if (StopSearch()) return false; + std::vector> adjacency_lists(size); for (int type = 0; type < num_vehicle_types; ++type) { const int vehicle = @@ -5518,17 +2850,19 @@ void SavingsFilteredHeuristic::ComputeSavings() { continue; } - const int64 cost_class = + const int64_t cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value(); - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); - const int64 fixed_cost = model()->GetFixedCostOfVehicle(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); + const int64_t fixed_cost = model()->GetFixedCostOfVehicle(vehicle); // Compute the neighbors for each non-start/end node not already inserted in // the model. for (int before_node : uncontained_non_start_end_nodes) { - std::vector> costed_after_nodes; + std::vector> + costed_after_nodes; costed_after_nodes.reserve(uncontained_non_start_end_nodes.size()); + if (StopSearch()) return false; for (int after_node : uncontained_non_start_end_nodes) { if (after_node != before_node) { costed_after_nodes.push_back(std::make_pair( @@ -5545,47 +2879,49 @@ void SavingsFilteredHeuristic::ComputeSavings() { adjacency_lists[before_node].resize(costed_after_nodes.size()); std::transform(costed_after_nodes.begin(), costed_after_nodes.end(), adjacency_lists[before_node].begin(), - [](std::pair cost_and_node) { + [](std::pair cost_and_node) { return cost_and_node.second; }); } if (savings_params_.add_reverse_arcs) { AddSymmetricArcsToAdjacencyLists(&adjacency_lists); } + if (StopSearch()) return false; // Build the savings for this vehicle type given the adjacency_lists. for (int before_node : uncontained_non_start_end_nodes) { - const int64 before_to_end_cost = + const int64_t before_to_end_cost = model()->GetArcCostForClass(before_node, end, cost_class); - const int64 start_to_before_cost = + const int64_t start_to_before_cost = CapSub(model()->GetArcCostForClass(start, before_node, cost_class), fixed_cost); - for (int64 after_node : adjacency_lists[before_node]) { + if (StopSearch()) return false; + for (int64_t after_node : adjacency_lists[before_node]) { if (model()->IsStart(after_node) || model()->IsEnd(after_node) || before_node == after_node || Contains(after_node)) { continue; } - const int64 arc_cost = + const int64_t arc_cost = model()->GetArcCostForClass(before_node, after_node, cost_class); - const int64 start_to_after_cost = + const int64_t start_to_after_cost = CapSub(model()->GetArcCostForClass(start, after_node, cost_class), fixed_cost); - const int64 after_to_end_cost = + const int64_t after_to_end_cost = model()->GetArcCostForClass(after_node, end, cost_class); const double weighted_arc_cost_fp = savings_params_.arc_coefficient * arc_cost; - const int64 weighted_arc_cost = - weighted_arc_cost_fp < kint64max - ? static_cast(weighted_arc_cost_fp) - : kint64max; - const int64 saving_value = CapSub( + const int64_t weighted_arc_cost = + weighted_arc_cost_fp < std::numeric_limits::max() + ? static_cast(weighted_arc_cost_fp) + : std::numeric_limits::max(); + const int64_t saving_value = CapSub( CapAdd(before_to_end_cost, start_to_after_cost), weighted_arc_cost); const Saving saving = BuildSaving(-saving_value, type, before_node, after_node); - const int64 total_cost = + const int64_t total_cost = CapAdd(CapAdd(start_to_before_cost, arc_cost), after_to_end_cost); savings_container_->AddNewSaving(saving, total_cost, before_node, @@ -5594,13 +2930,14 @@ void SavingsFilteredHeuristic::ComputeSavings() { } } savings_container_->Sort(); + return !StopSearch(); } -int64 SavingsFilteredHeuristic::MaxNumNeighborsPerNode( +int64_t SavingsFilteredHeuristic::MaxNumNeighborsPerNode( int num_vehicle_types) const { - const int64 size = model()->Size(); + const int64_t size = model()->Size(); - const int64 num_neighbors_with_ratio = + const int64_t num_neighbors_with_ratio = std::max(1.0, size * savings_params_.neighbors_ratio); // A single Saving takes 2*8 bytes of memory. @@ -5614,7 +2951,7 @@ int64 SavingsFilteredHeuristic::MaxNumNeighborsPerNode( // - Once in "sorted_savings_per_vehicle_type", and (at most) once in // "sorted_savings_" --> factor 2 // - If num_vehicle_types > 1, they're also stored by arc_index in - // "costs_and_savings_per_arc", along with their int64 cost --> factor 1.5 + // "costs_and_savings_per_arc", along with their int64_t cost --> factor 1.5 // // On top of that, // - In the sequential version, the Saving* are also stored by in-coming and @@ -5630,7 +2967,7 @@ int64 SavingsFilteredHeuristic::MaxNumNeighborsPerNode( } const double num_savings = max_memory_usage_in_savings_unit / multiplicative_factor; - const int64 num_neighbors_with_memory_restriction = + const int64_t num_neighbors_with_memory_restriction = std::max(1.0, num_savings / (num_vehicle_types * size)); return std::min(num_neighbors_with_ratio, @@ -5662,6 +2999,7 @@ void SequentialSavingsFilteredHeuristic::BuildRoutesFromSavings() { // Build routes from savings. while (savings_container_->HasSaving()) { + if (StopSearch()) return; // First find the best saving to start a new route. const Saving saving = savings_container_->GetSaving(); int before_node = GetBeforeNodeFromSaving(saving); @@ -5679,8 +3017,8 @@ void SequentialSavingsFilteredHeuristic::BuildRoutesFromSavings() { if (vehicle >= 0) { committed = true; - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); // Then extend the route from both ends of the partial route. int in_index = 0; int out_index = 0; @@ -5760,7 +3098,7 @@ void SequentialSavingsFilteredHeuristic::BuildRoutesFromSavings() { void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { // Initialize the vehicles of the first/last non start/end nodes served by // each route. - const int64 size = model()->Size(); + const int64_t size = model()->Size(); const int vehicles = model()->vehicles(); first_node_on_route_.resize(vehicles, -1); @@ -5768,17 +3106,17 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { vehicle_of_first_or_last_node_.resize(size, -1); for (int vehicle = 0; vehicle < vehicles; vehicle++) { - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); if (!Contains(start)) { continue; } - int64 node = Value(start); + int64_t node = Value(start); if (node != end) { vehicle_of_first_or_last_node_[node] = vehicle; first_node_on_route_[vehicle] = node; - int64 next = Value(node); + int64_t next = Value(node); while (next != end) { node = next; next = Value(node); @@ -5791,8 +3129,8 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { while (savings_container_->HasSaving()) { if (StopSearch()) return; const Saving saving = savings_container_->GetSaving(); - const int64 before_node = GetBeforeNodeFromSaving(saving); - const int64 after_node = GetAfterNodeFromSaving(saving); + const int64_t before_node = GetBeforeNodeFromSaving(saving); + const int64_t after_node = GetAfterNodeFromSaving(saving); const int type = GetVehicleTypeFromSaving(saving); if (!Contains(before_node) && !Contains(after_node)) { @@ -5821,10 +3159,10 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { // route, the two nodes aren't already on the same route, and the vehicle // types are compatible. const int v1 = vehicle_of_first_or_last_node_[before_node]; - const int64 last_node = v1 == -1 ? -1 : last_node_on_route_[v1]; + const int64_t last_node = v1 == -1 ? -1 : last_node_on_route_[v1]; const int v2 = vehicle_of_first_or_last_node_[after_node]; - const int64 first_node = v2 == -1 ? -1 : first_node_on_route_[v2]; + const int64_t first_node = v2 == -1 ? -1 : first_node_on_route_[v2]; if (before_node == last_node && after_node == first_node && v1 != v2 && vehicle_type_curator_->Type(v1) == vehicle_type_curator_->Type(v2)) { @@ -5841,10 +3179,11 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { if (Contains(before_node) && !Contains(after_node)) { const int vehicle = vehicle_of_first_or_last_node_[before_node]; - const int64 last_node = vehicle == -1 ? -1 : last_node_on_route_[vehicle]; + const int64_t last_node = + vehicle == -1 ? -1 : last_node_on_route_[vehicle]; if (before_node == last_node) { - const int64 end = model()->End(vehicle); + const int64_t end = model()->End(vehicle); CHECK_EQ(Value(before_node), end); const int route_type = vehicle_type_curator_->Type(vehicle); @@ -5873,11 +3212,11 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { if (!Contains(before_node) && Contains(after_node)) { const int vehicle = vehicle_of_first_or_last_node_[after_node]; - const int64 first_node = + const int64_t first_node = vehicle == -1 ? -1 : first_node_on_route_[vehicle]; if (after_node == first_node) { - const int64 start = model()->Start(vehicle); + const int64_t start = model()->Start(vehicle); CHECK_EQ(Value(start), after_node); const int route_type = vehicle_type_curator_->Type(vehicle); @@ -5909,13 +3248,13 @@ void ParallelSavingsFilteredHeuristic::BuildRoutesFromSavings() { void ParallelSavingsFilteredHeuristic::MergeRoutes(int first_vehicle, int second_vehicle, - int64 before_node, - int64 after_node) { + int64_t before_node, + int64_t after_node) { if (StopSearch()) return; - const int64 new_first_node = first_node_on_route_[first_vehicle]; + const int64_t new_first_node = first_node_on_route_[first_vehicle]; DCHECK_EQ(vehicle_of_first_or_last_node_[new_first_node], first_vehicle); CHECK_EQ(Value(model()->Start(first_vehicle)), new_first_node); - const int64 new_last_node = last_node_on_route_[second_vehicle]; + const int64_t new_last_node = last_node_on_route_[second_vehicle]; DCHECK_EQ(vehicle_of_first_or_last_node_[new_last_node], second_vehicle); CHECK_EQ(Value(new_last_node), model()->End(second_vehicle)); @@ -5970,6 +3309,7 @@ void ParallelSavingsFilteredHeuristic::MergeRoutes(int first_vehicle, } // ChristofidesFilteredHeuristic + ChristofidesFilteredHeuristic::ChristofidesFilteredHeuristic( RoutingModel* model, LocalSearchFilterManager* filter_manager, bool use_minimum_matching) @@ -5994,32 +3334,32 @@ bool ChristofidesFilteredHeuristic::BuildSolutionInternal() { std::vector> path_per_cost_class(num_cost_classes); std::vector class_covered(num_cost_classes, false); for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { - const int64 cost_class = + const int64_t cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value(); if (!class_covered[cost_class]) { class_covered[cost_class] = true; - const int64 start = model()->Start(vehicle); - const int64 end = model()->End(vehicle); + const int64_t start = model()->Start(vehicle); + const int64_t end = model()->End(vehicle); auto cost = [this, &indices, start, end, cost_class](int from, int to) { DCHECK_LT(from, indices.size()); DCHECK_LT(to, indices.size()); const int from_index = (from == 0) ? start : indices[from]; const int to_index = (to == 0) ? end : indices[to]; - const int64 cost = + const int64_t cost = model()->GetArcCostForClass(from_index, to_index, cost_class); // To avoid overflow issues, capping costs at kint64max/2, the maximum // value supported by MinCostPerfectMatching. // TODO(user): Investigate if ChristofidesPathSolver should not // return a status to bail out fast in case of problem. - return std::min(cost, kint64max / 2); + return std::min(cost, std::numeric_limits::max() / 2); }; using Cost = decltype(cost); - ChristofidesPathSolver christofides_solver( + ChristofidesPathSolver christofides_solver( indices.size(), cost); if (use_minimum_matching_) { christofides_solver.SetMatchingAlgorithm( - ChristofidesPathSolver::MatchingAlgorithm:: - MINIMUM_WEIGHT_MATCHING); + ChristofidesPathSolver:: + MatchingAlgorithm::MINIMUM_WEIGHT_MATCHING); } if (christofides_solver.Solve()) { path_per_cost_class[cost_class] = @@ -6029,7 +3369,7 @@ bool ChristofidesFilteredHeuristic::BuildSolutionInternal() { } // TODO(user): Investigate if sorting paths per cost improves solutions. for (int vehicle = 0; vehicle < model()->vehicles(); ++vehicle) { - const int64 cost_class = + const int64_t cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value(); const std::vector& path = path_per_cost_class[cost_class]; if (path.empty()) continue; @@ -6054,38 +3394,697 @@ bool ChristofidesFilteredHeuristic::BuildSolutionInternal() { return Commit(); } +// Sweep heuristic +// TODO(user): Clean up to match other first solution strategies. + +namespace { +struct SweepIndex { + SweepIndex(const int64_t index, const double angle, const double distance) + : index(index), angle(angle), distance(distance) {} + ~SweepIndex() {} + + int64_t index; + double angle; + double distance; +}; + +struct SweepIndexSortAngle { + bool operator()(const SweepIndex& node1, const SweepIndex& node2) const { + return (node1.angle < node2.angle); + } +} SweepIndexAngleComparator; + +struct SweepIndexSortDistance { + bool operator()(const SweepIndex& node1, const SweepIndex& node2) const { + return (node1.distance < node2.distance); + } +} SweepIndexDistanceComparator; +} // namespace + +SweepArranger::SweepArranger( + const std::vector>& points) + : coordinates_(2 * points.size(), 0), sectors_(1) { + for (int64_t i = 0; i < points.size(); ++i) { + coordinates_[2 * i] = points[i].first; + coordinates_[2 * i + 1] = points[i].second; + } +} + +// Splits the space of the indices into sectors and sorts the indices of each +// sector with ascending angle from the depot. +void SweepArranger::ArrangeIndices(std::vector* indices) { + const double pi_rad = 3.14159265; + // Suppose that the center is at x0, y0. + const int x0 = coordinates_[0]; + const int y0 = coordinates_[1]; + + std::vector sweep_indices; + for (int64_t index = 0; index < static_cast(coordinates_.size()) / 2; + ++index) { + const int x = coordinates_[2 * index]; + const int y = coordinates_[2 * index + 1]; + const double x_delta = x - x0; + const double y_delta = y - y0; + double square_distance = x_delta * x_delta + y_delta * y_delta; + double angle = square_distance == 0 ? 0 : std::atan2(y_delta, x_delta); + angle = angle >= 0 ? angle : 2 * pi_rad + angle; + SweepIndex sweep_index(index, angle, square_distance); + sweep_indices.push_back(sweep_index); + } + std::sort(sweep_indices.begin(), sweep_indices.end(), + SweepIndexDistanceComparator); + + const int size = static_cast(sweep_indices.size()) / sectors_; + for (int sector = 0; sector < sectors_; ++sector) { + std::vector cluster; + std::vector::iterator begin = + sweep_indices.begin() + sector * size; + std::vector::iterator end = + sector == sectors_ - 1 ? sweep_indices.end() + : sweep_indices.begin() + (sector + 1) * size; + std::sort(begin, end, SweepIndexAngleComparator); + } + for (const SweepIndex& sweep_index : sweep_indices) { + indices->push_back(sweep_index.index); + } +} + +namespace { + +struct Link { + Link(std::pair link, double value, int vehicle_class, + int64_t start_depot, int64_t end_depot) + : link(link), + value(value), + vehicle_class(vehicle_class), + start_depot(start_depot), + end_depot(end_depot) {} + ~Link() {} + + std::pair link; + int64_t value; + int vehicle_class; + int64_t start_depot; + int64_t end_depot; +}; + +// The RouteConstructor creates the routes of a VRP instance subject to its +// constraints by iterating on a list of arcs appearing in descending order +// of priority. +// TODO(user): Use the dimension class in this class. +// TODO(user): Add support for vehicle-dependent dimension transits. +class RouteConstructor { + public: + RouteConstructor(Assignment* const assignment, RoutingModel* const model, + bool check_assignment, int64_t num_indices, + const std::vector& links_list) + : assignment_(assignment), + model_(model), + check_assignment_(check_assignment), + solver_(model_->solver()), + num_indices_(num_indices), + links_list_(links_list), + nexts_(model_->Nexts()), + in_route_(num_indices_, -1), + final_routes_(), + index_to_chain_index_(num_indices, -1), + index_to_vehicle_class_index_(num_indices, -1) { + { + const std::vector dimension_names = + model_->GetAllDimensionNames(); + dimensions_.assign(dimension_names.size(), nullptr); + for (int i = 0; i < dimension_names.size(); ++i) { + dimensions_[i] = &model_->GetDimensionOrDie(dimension_names[i]); + } + } + cumuls_.resize(dimensions_.size()); + for (std::vector& cumuls : cumuls_) { + cumuls.resize(num_indices_); + } + new_possible_cumuls_.resize(dimensions_.size()); + } + + ~RouteConstructor() {} + + void Construct() { + model_->solver()->TopPeriodicCheck(); + // Initial State: Each order is served by its own vehicle. + for (int index = 0; index < num_indices_; ++index) { + if (!model_->IsStart(index) && !model_->IsEnd(index)) { + std::vector route(1, index); + routes_.push_back(route); + in_route_[index] = routes_.size() - 1; + } + } + + for (const Link& link : links_list_) { + model_->solver()->TopPeriodicCheck(); + const int index1 = link.link.first; + const int index2 = link.link.second; + const int vehicle_class = link.vehicle_class; + const int64_t start_depot = link.start_depot; + const int64_t end_depot = link.end_depot; + + // Initialisation of cumuls_ if the indices are encountered for first time + if (index_to_vehicle_class_index_[index1] < 0) { + for (int dimension_index = 0; dimension_index < dimensions_.size(); + ++dimension_index) { + cumuls_[dimension_index][index1] = + std::max(dimensions_[dimension_index]->GetTransitValue( + start_depot, index1, 0), + dimensions_[dimension_index]->CumulVar(index1)->Min()); + } + } + if (index_to_vehicle_class_index_[index2] < 0) { + for (int dimension_index = 0; dimension_index < dimensions_.size(); + ++dimension_index) { + cumuls_[dimension_index][index2] = + std::max(dimensions_[dimension_index]->GetTransitValue( + start_depot, index2, 0), + dimensions_[dimension_index]->CumulVar(index2)->Min()); + } + } + + const int route_index1 = in_route_[index1]; + const int route_index2 = in_route_[index2]; + const bool merge = + route_index1 >= 0 && route_index2 >= 0 && + FeasibleMerge(routes_[route_index1], routes_[route_index2], index1, + index2, route_index1, route_index2, vehicle_class, + start_depot, end_depot); + if (Merge(merge, route_index1, route_index2)) { + index_to_vehicle_class_index_[index1] = vehicle_class; + index_to_vehicle_class_index_[index2] = vehicle_class; + } + } + + model_->solver()->TopPeriodicCheck(); + // Beyond this point not checking limits anymore as the rest of the code is + // linear and that given we managed to build a solution would be stupid to + // drop it now. + for (int chain_index = 0; chain_index < chains_.size(); ++chain_index) { + if (!gtl::ContainsKey(deleted_chains_, chain_index)) { + final_chains_.push_back(chains_[chain_index]); + } + } + std::sort(final_chains_.begin(), final_chains_.end(), ChainComparator); + for (int route_index = 0; route_index < routes_.size(); ++route_index) { + if (!gtl::ContainsKey(deleted_routes_, route_index)) { + final_routes_.push_back(routes_[route_index]); + } + } + std::sort(final_routes_.begin(), final_routes_.end(), RouteComparator); + + const int extra_vehicles = std::max( + 0, static_cast(final_chains_.size()) - model_->vehicles()); + // Bind the Start and End of each chain + int chain_index = 0; + for (chain_index = extra_vehicles; chain_index < final_chains_.size(); + ++chain_index) { + if (chain_index - extra_vehicles >= model_->vehicles()) { + break; + } + const int start = final_chains_[chain_index].head; + const int end = final_chains_[chain_index].tail; + assignment_->Add( + model_->NextVar(model_->Start(chain_index - extra_vehicles))); + assignment_->SetValue( + model_->NextVar(model_->Start(chain_index - extra_vehicles)), start); + assignment_->Add(nexts_[end]); + assignment_->SetValue(nexts_[end], + model_->End(chain_index - extra_vehicles)); + } + + // Create the single order routes + for (int route_index = 0; route_index < final_routes_.size(); + ++route_index) { + if (chain_index - extra_vehicles >= model_->vehicles()) { + break; + } + DCHECK_LT(route_index, final_routes_.size()); + const int head = final_routes_[route_index].front(); + const int tail = final_routes_[route_index].back(); + if (head == tail && head < model_->Size()) { + assignment_->Add( + model_->NextVar(model_->Start(chain_index - extra_vehicles))); + assignment_->SetValue( + model_->NextVar(model_->Start(chain_index - extra_vehicles)), head); + assignment_->Add(nexts_[tail]); + assignment_->SetValue(nexts_[tail], + model_->End(chain_index - extra_vehicles)); + ++chain_index; + } + } + + // Unperformed + for (int index = 0; index < model_->Size(); ++index) { + IntVar* const next = nexts_[index]; + if (!assignment_->Contains(next)) { + assignment_->Add(next); + if (next->Contains(index)) { + assignment_->SetValue(next, index); + } + } + } + } + + const std::vector>& final_routes() const { + return final_routes_; + } + + private: + enum MergeStatus { FIRST_SECOND, SECOND_FIRST, NO_MERGE }; + + struct RouteSort { + bool operator()(const std::vector& route1, + const std::vector& route2) const { + return (route1.size() < route2.size()); + } + } RouteComparator; + + struct Chain { + int head; + int tail; + int nodes; + }; + + struct ChainSort { + bool operator()(const Chain& chain1, const Chain& chain2) const { + return (chain1.nodes < chain2.nodes); + } + } ChainComparator; + + bool Head(int node) const { + return (node == routes_[in_route_[node]].front()); + } + + bool Tail(int node) const { + return (node == routes_[in_route_[node]].back()); + } + + bool FeasibleRoute(const std::vector& route, int64_t route_cumul, + int dimension_index) { + const RoutingDimension& dimension = *dimensions_[dimension_index]; + std::vector::const_iterator it = route.begin(); + int64_t cumul = route_cumul; + while (it != route.end()) { + const int previous = *it; + const int64_t cumul_previous = cumul; + gtl::InsertOrDie(&(new_possible_cumuls_[dimension_index]), previous, + cumul_previous); + ++it; + if (it == route.end()) { + return true; + } + const int next = *it; + int64_t available_from_previous = + cumul_previous + dimension.GetTransitValue(previous, next, 0); + int64_t available_cumul_next = + std::max(cumuls_[dimension_index][next], available_from_previous); + + const int64_t slack = available_cumul_next - available_from_previous; + if (slack > dimension.SlackVar(previous)->Max()) { + available_cumul_next = + available_from_previous + dimension.SlackVar(previous)->Max(); + } + + if (available_cumul_next > dimension.CumulVar(next)->Max()) { + return false; + } + if (available_cumul_next <= cumuls_[dimension_index][next]) { + return true; + } + cumul = available_cumul_next; + } + return true; + } + + bool CheckRouteConnection(const std::vector& route1, + const std::vector& route2, int dimension_index, + int64_t start_depot, int64_t end_depot) { + const int tail1 = route1.back(); + const int head2 = route2.front(); + const int tail2 = route2.back(); + const RoutingDimension& dimension = *dimensions_[dimension_index]; + int non_depot_node = -1; + for (int node = 0; node < num_indices_; ++node) { + if (!model_->IsStart(node) && !model_->IsEnd(node)) { + non_depot_node = node; + break; + } + } + CHECK_GE(non_depot_node, 0); + const int64_t depot_threshold = + std::max(dimension.SlackVar(non_depot_node)->Max(), + dimension.CumulVar(non_depot_node)->Max()); + + int64_t available_from_tail1 = cumuls_[dimension_index][tail1] + + dimension.GetTransitValue(tail1, head2, 0); + int64_t new_available_cumul_head2 = + std::max(cumuls_[dimension_index][head2], available_from_tail1); + + const int64_t slack = new_available_cumul_head2 - available_from_tail1; + if (slack > dimension.SlackVar(tail1)->Max()) { + new_available_cumul_head2 = + available_from_tail1 + dimension.SlackVar(tail1)->Max(); + } + + bool feasible_route = true; + if (new_available_cumul_head2 > dimension.CumulVar(head2)->Max()) { + return false; + } + if (new_available_cumul_head2 <= cumuls_[dimension_index][head2]) { + return true; + } + + feasible_route = + FeasibleRoute(route2, new_available_cumul_head2, dimension_index); + const int64_t new_possible_cumul_tail2 = + gtl::ContainsKey(new_possible_cumuls_[dimension_index], tail2) + ? new_possible_cumuls_[dimension_index][tail2] + : cumuls_[dimension_index][tail2]; + + if (!feasible_route || (new_possible_cumul_tail2 + + dimension.GetTransitValue(tail2, end_depot, 0) > + depot_threshold)) { + return false; + } + return true; + } + + bool FeasibleMerge(const std::vector& route1, + const std::vector& route2, int node1, int node2, + int route_index1, int route_index2, int vehicle_class, + int64_t start_depot, int64_t end_depot) { + if ((route_index1 == route_index2) || !(Tail(node1) && Head(node2))) { + return false; + } + + // Vehicle Class Check + if (!((index_to_vehicle_class_index_[node1] == -1 && + index_to_vehicle_class_index_[node2] == -1) || + (index_to_vehicle_class_index_[node1] == vehicle_class && + index_to_vehicle_class_index_[node2] == -1) || + (index_to_vehicle_class_index_[node1] == -1 && + index_to_vehicle_class_index_[node2] == vehicle_class) || + (index_to_vehicle_class_index_[node1] == vehicle_class && + index_to_vehicle_class_index_[node2] == vehicle_class))) { + return false; + } + + // Check Route1 -> Route2 connection for every dimension + bool merge = true; + for (int dimension_index = 0; dimension_index < dimensions_.size(); + ++dimension_index) { + new_possible_cumuls_[dimension_index].clear(); + merge = merge && CheckRouteConnection(route1, route2, dimension_index, + start_depot, end_depot); + if (!merge) { + return false; + } + } + return true; + } + + bool CheckTempAssignment(Assignment* const temp_assignment, + int new_chain_index, int old_chain_index, int head1, + int tail1, int head2, int tail2) { + // TODO(user): If the chain index is greater than the number of vehicles, + // use another vehicle instead. + if (new_chain_index >= model_->vehicles()) return false; + const int start = head1; + temp_assignment->Add(model_->NextVar(model_->Start(new_chain_index))); + temp_assignment->SetValue(model_->NextVar(model_->Start(new_chain_index)), + start); + temp_assignment->Add(nexts_[tail1]); + temp_assignment->SetValue(nexts_[tail1], head2); + temp_assignment->Add(nexts_[tail2]); + temp_assignment->SetValue(nexts_[tail2], model_->End(new_chain_index)); + for (int chain_index = 0; chain_index < chains_.size(); ++chain_index) { + if ((chain_index != new_chain_index) && + (chain_index != old_chain_index) && + (!gtl::ContainsKey(deleted_chains_, chain_index))) { + const int start = chains_[chain_index].head; + const int end = chains_[chain_index].tail; + temp_assignment->Add(model_->NextVar(model_->Start(chain_index))); + temp_assignment->SetValue(model_->NextVar(model_->Start(chain_index)), + start); + temp_assignment->Add(nexts_[end]); + temp_assignment->SetValue(nexts_[end], model_->End(chain_index)); + } + } + return solver_->Solve(solver_->MakeRestoreAssignment(temp_assignment)); + } + + bool UpdateAssignment(const std::vector& route1, + const std::vector& route2) { + bool feasible = true; + const int head1 = route1.front(); + const int tail1 = route1.back(); + const int head2 = route2.front(); + const int tail2 = route2.back(); + const int chain_index1 = index_to_chain_index_[head1]; + const int chain_index2 = index_to_chain_index_[head2]; + if (chain_index1 < 0 && chain_index2 < 0) { + const int chain_index = chains_.size(); + if (check_assignment_) { + Assignment* const temp_assignment = + solver_->MakeAssignment(assignment_); + feasible = CheckTempAssignment(temp_assignment, chain_index, -1, head1, + tail1, head2, tail2); + } + if (feasible) { + Chain chain; + chain.head = head1; + chain.tail = tail2; + chain.nodes = 2; + index_to_chain_index_[head1] = chain_index; + index_to_chain_index_[tail2] = chain_index; + chains_.push_back(chain); + } + } else if (chain_index1 >= 0 && chain_index2 < 0) { + if (check_assignment_) { + Assignment* const temp_assignment = + solver_->MakeAssignment(assignment_); + feasible = + CheckTempAssignment(temp_assignment, chain_index1, chain_index2, + head1, tail1, head2, tail2); + } + if (feasible) { + index_to_chain_index_[tail2] = chain_index1; + chains_[chain_index1].head = head1; + chains_[chain_index1].tail = tail2; + ++chains_[chain_index1].nodes; + } + } else if (chain_index1 < 0 && chain_index2 >= 0) { + if (check_assignment_) { + Assignment* const temp_assignment = + solver_->MakeAssignment(assignment_); + feasible = + CheckTempAssignment(temp_assignment, chain_index2, chain_index1, + head1, tail1, head2, tail2); + } + if (feasible) { + index_to_chain_index_[head1] = chain_index2; + chains_[chain_index2].head = head1; + chains_[chain_index2].tail = tail2; + ++chains_[chain_index2].nodes; + } + } else { + if (check_assignment_) { + Assignment* const temp_assignment = + solver_->MakeAssignment(assignment_); + feasible = + CheckTempAssignment(temp_assignment, chain_index1, chain_index2, + head1, tail1, head2, tail2); + } + if (feasible) { + index_to_chain_index_[tail2] = chain_index1; + chains_[chain_index1].head = head1; + chains_[chain_index1].tail = tail2; + chains_[chain_index1].nodes += chains_[chain_index2].nodes; + deleted_chains_.insert(chain_index2); + } + } + if (feasible) { + assignment_->Add(nexts_[tail1]); + assignment_->SetValue(nexts_[tail1], head2); + } + return feasible; + } + + bool Merge(bool merge, int index1, int index2) { + if (merge) { + if (UpdateAssignment(routes_[index1], routes_[index2])) { + // Connection Route1 -> Route2 + for (const int node : routes_[index2]) { + in_route_[node] = index1; + routes_[index1].push_back(node); + } + for (int dimension_index = 0; dimension_index < dimensions_.size(); + ++dimension_index) { + for (const std::pair new_possible_cumul : + new_possible_cumuls_[dimension_index]) { + cumuls_[dimension_index][new_possible_cumul.first] = + new_possible_cumul.second; + } + } + deleted_routes_.insert(index2); + return true; + } + } + return false; + } + + Assignment* const assignment_; + RoutingModel* const model_; + const bool check_assignment_; + Solver* const solver_; + const int64_t num_indices_; + const std::vector links_list_; + std::vector nexts_; + std::vector dimensions_; // Not owned. + std::vector> cumuls_; + std::vector> new_possible_cumuls_; + std::vector> routes_; + std::vector in_route_; + absl::flat_hash_set deleted_routes_; + std::vector> final_routes_; + std::vector chains_; + absl::flat_hash_set deleted_chains_; + std::vector final_chains_; + std::vector index_to_chain_index_; + std::vector index_to_vehicle_class_index_; +}; + +// Decision Builder building a first solution based on Sweep heuristic for +// Vehicle Routing Problem. +// Suitable only when distance is considered as the cost. +class SweepBuilder : public DecisionBuilder { + public: + SweepBuilder(RoutingModel* const model, bool check_assignment) + : model_(model), check_assignment_(check_assignment) {} + ~SweepBuilder() override {} + + Decision* Next(Solver* const solver) override { + // Setup the model of the instance for the Sweep Algorithm + ModelSetup(); + + // Build the assignment routes for the model + Assignment* const assignment = solver->MakeAssignment(); + route_constructor_ = absl::make_unique( + assignment, model_, check_assignment_, num_indices_, links_); + // This call might cause backtracking if the search limit is reached. + route_constructor_->Construct(); + route_constructor_.reset(nullptr); + // This call might cause backtracking if the solution is not feasible. + assignment->Restore(); + + return nullptr; + } + + private: + void ModelSetup() { + const int depot = model_->GetDepot(); + num_indices_ = model_->Size() + model_->vehicles(); + if (absl::GetFlag(FLAGS_sweep_sectors) > 0 && + absl::GetFlag(FLAGS_sweep_sectors) < num_indices_) { + model_->sweep_arranger()->SetSectors(absl::GetFlag(FLAGS_sweep_sectors)); + } + std::vector indices; + model_->sweep_arranger()->ArrangeIndices(&indices); + for (int i = 0; i < indices.size() - 1; ++i) { + const int64_t first = indices[i]; + const int64_t second = indices[i + 1]; + if ((model_->IsStart(first) || !model_->IsEnd(first)) && + (model_->IsStart(second) || !model_->IsEnd(second))) { + if (first != depot && second != depot) { + Link link(std::make_pair(first, second), 0, 0, depot, depot); + links_.push_back(link); + } + } + } + } + + RoutingModel* const model_; + std::unique_ptr route_constructor_; + const bool check_assignment_; + int64_t num_indices_; + std::vector links_; +}; +} // namespace + +DecisionBuilder* MakeSweepDecisionBuilder(RoutingModel* model, + bool check_assignment) { + return model->solver()->RevAlloc(new SweepBuilder(model, check_assignment)); +} + +// AllUnperformed + +namespace { +// Decision builder to build a solution with all nodes inactive. It does no +// branching and may fail if some nodes cannot be made inactive. + +class AllUnperformed : public DecisionBuilder { + public: + // Does not take ownership of model. + explicit AllUnperformed(RoutingModel* const model) : model_(model) {} + ~AllUnperformed() override {} + Decision* Next(Solver* const solver) override { + // Solver::(Un)FreezeQueue is private, passing through the public API + // on PropagationBaseObject. + model_->CostVar()->FreezeQueue(); + for (int i = 0; i < model_->Size(); ++i) { + if (!model_->IsStart(i)) { + model_->ActiveVar(i)->SetValue(0); + } + } + model_->CostVar()->UnfreezeQueue(); + return nullptr; + } + + private: + RoutingModel* const model_; +}; +} // namespace + +DecisionBuilder* MakeAllUnperformed(RoutingModel* model) { + return model->solver()->RevAlloc(new AllUnperformed(model)); +} + namespace { // The description is in routing.h:MakeGuidedSlackFinalizer class GuidedSlackFinalizer : public DecisionBuilder { public: GuidedSlackFinalizer(const RoutingDimension* dimension, RoutingModel* model, - std::function initializer); + std::function initializer); Decision* Next(Solver* solver) override; private: - int64 SelectValue(int64 index); - int64 ChooseVariable(); + int64_t SelectValue(int64_t index); + int64_t ChooseVariable(); const RoutingDimension* const dimension_; RoutingModel* const model_; - const std::function initializer_; + const std::function initializer_; RevArray is_initialized_; - std::vector initial_values_; - Rev current_index_; - Rev current_route_; - RevArray last_delta_used_; + std::vector initial_values_; + Rev current_index_; + Rev current_route_; + RevArray last_delta_used_; DISALLOW_COPY_AND_ASSIGN(GuidedSlackFinalizer); }; GuidedSlackFinalizer::GuidedSlackFinalizer( const RoutingDimension* dimension, RoutingModel* model, - std::function initializer) + std::function initializer) : dimension_(ABSL_DIE_IF_NULL(dimension)), model_(ABSL_DIE_IF_NULL(model)), initializer_(std::move(initializer)), is_initialized_(dimension->slacks().size(), false), - initial_values_(dimension->slacks().size(), kint64min), + initial_values_(dimension->slacks().size(), + std::numeric_limits::min()), current_index_(model_->Start(0)), current_route_(0), last_delta_used_(dimension->slacks().size(), 0) {} @@ -6100,20 +4099,20 @@ Decision* GuidedSlackFinalizer::Next(Solver* solver) { initial_values_[node_idx] = initializer_(node_idx); is_initialized_.SetValue(solver, node_idx, true); } - const int64 value = SelectValue(node_idx); + const int64_t value = SelectValue(node_idx); IntVar* const slack_variable = dimension_->SlackVar(node_idx); return solver->MakeAssignVariableValue(slack_variable, value); } return nullptr; } -int64 GuidedSlackFinalizer::SelectValue(int64 index) { +int64_t GuidedSlackFinalizer::SelectValue(int64_t index) { const IntVar* const slack_variable = dimension_->SlackVar(index); - const int64 center = initial_values_[index]; - const int64 max_delta = + const int64_t center = initial_values_[index]; + const int64_t max_delta = std::max(center - slack_variable->Min(), slack_variable->Max() - center) + 1; - int64 delta = last_delta_used_[index]; + int64_t delta = last_delta_used_[index]; // The sequence of deltas is 0, 1, -1, 2, -2 ... // Only the values inside the domain of variable are returned. @@ -6129,9 +4128,9 @@ int64 GuidedSlackFinalizer::SelectValue(int64 index) { return center + delta; } -int64 GuidedSlackFinalizer::ChooseVariable() { - int64 int_current_node = current_index_.Value(); - int64 int_current_route = current_route_.Value(); +int64_t GuidedSlackFinalizer::ChooseVariable() { + int64_t int_current_node = current_index_.Value(); + int64_t int_current_route = current_route_.Value(); while (int_current_route < model_->vehicles()) { while (!model_->IsEnd(int_current_node) && @@ -6161,23 +4160,23 @@ int64 GuidedSlackFinalizer::ChooseVariable() { DecisionBuilder* RoutingModel::MakeGuidedSlackFinalizer( const RoutingDimension* dimension, - std::function initializer) { + std::function initializer) { return solver_->RevAlloc( new GuidedSlackFinalizer(dimension, this, std::move(initializer))); } -int64 RoutingDimension::ShortestTransitionSlack(int64 node) const { +int64_t RoutingDimension::ShortestTransitionSlack(int64_t node) const { CHECK_EQ(base_dimension_, this); CHECK(!model_->IsEnd(node)); // Recall that the model is cumul[i+1] = cumul[i] + transit[i] + slack[i]. Our // aim is to find a value for slack[i] such that cumul[i+1] + transit[i+1] is // minimized. - const int64 next = model_->NextVar(node)->Value(); + const int64_t next = model_->NextVar(node)->Value(); if (model_->IsEnd(next)) { return SlackVar(node)->Min(); } - const int64 next_next = model_->NextVar(next)->Value(); - const int64 serving_vehicle = model_->VehicleVar(node)->Value(); + const int64_t next_next = model_->NextVar(next)->Value(); + const int64_t serving_vehicle = model_->VehicleVar(node)->Value(); CHECK_EQ(serving_vehicle, model_->VehicleVar(next)->Value()); const RoutingModel::StateDependentTransit transit_from_next = model_->StateDependentTransitCallback( @@ -6185,9 +4184,9 @@ int64 RoutingDimension::ShortestTransitionSlack(int64 node) const { [state_dependent_vehicle_to_class_[serving_vehicle]])(next, next_next); // We have that transit[i+1] is a function of cumul[i+1]. - const int64 next_cumul_min = CumulVar(next)->Min(); - const int64 next_cumul_max = CumulVar(next)->Max(); - const int64 optimal_next_cumul = + const int64_t next_cumul_min = CumulVar(next)->Min(); + const int64_t next_cumul_max = CumulVar(next)->Max(); + const int64_t optimal_next_cumul = transit_from_next.transit_plus_identity->RangeMinArgument( next_cumul_min, next_cumul_max + 1); // A few checks to make sure we're on the same page. @@ -6197,19 +4196,19 @@ int64 RoutingDimension::ShortestTransitionSlack(int64 node) const { // optimal_slack = optimal_next_cumul - cumul - transit. // In the current implementation TransitVar(i) = transit[i] + slack[i], so we // have to find the transit from the evaluators. - const int64 current_cumul = CumulVar(node)->Value(); - const int64 current_state_independent_transit = model_->TransitCallback( + const int64_t current_cumul = CumulVar(node)->Value(); + const int64_t current_state_independent_transit = model_->TransitCallback( class_evaluators_[vehicle_to_class_[serving_vehicle]])(node, next); - const int64 current_state_dependent_transit = + const int64_t current_state_dependent_transit = model_ ->StateDependentTransitCallback( state_dependent_class_evaluators_ [state_dependent_vehicle_to_class_[serving_vehicle]])(node, next) .transit->Query(current_cumul); - const int64 optimal_slack = optimal_next_cumul - current_cumul - - current_state_independent_transit - - current_state_dependent_transit; + const int64_t optimal_slack = optimal_next_cumul - current_cumul - + current_state_independent_transit - + current_state_dependent_transit; CHECK_LE(SlackVar(node)->Min(), optimal_slack); CHECK_LE(optimal_slack, SlackVar(node)->Max()); return optimal_slack; @@ -6224,18 +4223,18 @@ class GreedyDescentLSOperator : public LocalSearchOperator { void Start(const Assignment* assignment) override; private: - int64 FindMaxDistanceToDomain(const Assignment* assignment); + int64_t FindMaxDistanceToDomain(const Assignment* assignment); const std::vector variables_; const Assignment* center_; - int64 current_step_; + int64_t current_step_; // The deltas are returned in this order: // (current_step_, 0, ... 0), (-current_step_, 0, ... 0), // (0, current_step_, ... 0), (0, -current_step_, ... 0), // ... // (0, ... 0, current_step_), (0, ... 0, -current_step_). // current_direction_ keeps track what was the last returned delta. - int64 current_direction_; + int64_t current_direction_; DISALLOW_COPY_AND_ASSIGN(GreedyDescentLSOperator); }; @@ -6248,15 +4247,15 @@ GreedyDescentLSOperator::GreedyDescentLSOperator(std::vector variables) bool GreedyDescentLSOperator::MakeNextNeighbor(Assignment* delta, Assignment* /*deltadelta*/) { - static const int64 sings[] = {1, -1}; + static const int64_t sings[] = {1, -1}; for (; 1 <= current_step_; current_step_ /= 2) { for (; current_direction_ < 2 * variables_.size();) { - const int64 variable_idx = current_direction_ / 2; + const int64_t variable_idx = current_direction_ / 2; IntVar* const variable = variables_[variable_idx]; - const int64 sign_index = current_direction_ % 2; - const int64 sign = sings[sign_index]; - const int64 offset = sign * current_step_; - const int64 new_value = center_->Value(variable) + offset; + const int64_t sign_index = current_direction_ % 2; + const int64_t sign = sings[sign_index]; + const int64_t offset = sign * current_step_; + const int64_t new_value = center_->Value(variable) + offset; ++current_direction_; if (variable->Contains(new_value)) { delta->Add(variable); @@ -6275,9 +4274,9 @@ void GreedyDescentLSOperator::Start(const Assignment* assignment) { center_ = assignment; } -int64 GreedyDescentLSOperator::FindMaxDistanceToDomain( +int64_t GreedyDescentLSOperator::FindMaxDistanceToDomain( const Assignment* assignment) { - int64 result = kint64min; + int64_t result = std::numeric_limits::min(); for (const IntVar* const var : variables_) { result = std::max(result, std::abs(var->Max() - assignment->Value(var))); result = std::max(result, std::abs(var->Min() - assignment->Value(var))); @@ -6296,7 +4295,7 @@ DecisionBuilder* RoutingModel::MakeSelfDependentDimensionFinalizer( const RoutingDimension* dimension) { CHECK(dimension != nullptr); CHECK(dimension->base_dimension() == dimension); - std::function slack_guide = [dimension](int64 index) { + std::function slack_guide = [dimension](int64_t index) { return dimension->ShortestTransitionSlack(index); }; DecisionBuilder* const guided_finalizer = @@ -6304,7 +4303,7 @@ DecisionBuilder* RoutingModel::MakeSelfDependentDimensionFinalizer( DecisionBuilder* const slacks_finalizer = solver_->MakeSolveOnce(guided_finalizer); std::vector start_cumuls(vehicles_, nullptr); - for (int64 vehicle_idx = 0; vehicle_idx < vehicles_; ++vehicle_idx) { + for (int64_t vehicle_idx = 0; vehicle_idx < vehicles_; ++vehicle_idx) { start_cumuls[vehicle_idx] = dimension->CumulVar(starts_[vehicle_idx]); } LocalSearchOperator* const hill_climber = diff --git a/ortools/constraint_solver/routing_search.h b/ortools/constraint_solver/routing_search.h new file mode 100644 index 0000000000..48a6da2789 --- /dev/null +++ b/ortools/constraint_solver/routing_search.h @@ -0,0 +1,1002 @@ +// Copyright 2010-2018 Google LLC +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/container/flat_hash_set.h" +#include "ortools/base/adjustable_priority_queue.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/mathutil.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_index_manager.h" +#include "ortools/util/bitset.h" + +namespace operations_research { + +class IntVarFilteredHeuristic; +#ifndef SWIG +/// Helper class that manages vehicles. This class is based on the +/// RoutingModel::VehicleTypeContainer that sorts and stores vehicles based on +/// their "type". +class VehicleTypeCurator { + public: + explicit VehicleTypeCurator( + const RoutingModel::VehicleTypeContainer& vehicle_type_container) + : vehicle_type_container_(&vehicle_type_container) {} + + int NumTypes() const { return vehicle_type_container_->NumTypes(); } + + int Type(int vehicle) const { return vehicle_type_container_->Type(vehicle); } + + /// Resets the vehicles stored, storing only vehicles from the + /// vehicle_type_container_ for which store_vehicle() returns true. + void Reset(const std::function& store_vehicle); + + /// Goes through all the currently stored vehicles and removes vehicles for + /// which remove_vehicle() returns true. + void Update(const std::function& remove_vehicle); + + int GetLowestFixedCostVehicleOfType(int type) const { + DCHECK_LT(type, NumTypes()); + const std::set& vehicle_classes = + sorted_vehicle_classes_per_type_[type]; + if (vehicle_classes.empty()) { + return -1; + } + const int vehicle_class = (vehicle_classes.begin())->vehicle_class; + DCHECK(!vehicles_per_vehicle_class_[vehicle_class].empty()); + return vehicles_per_vehicle_class_[vehicle_class][0]; + } + + void ReinjectVehicleOfClass(int vehicle, int vehicle_class, + int64_t fixed_cost) { + std::vector& vehicles = vehicles_per_vehicle_class_[vehicle_class]; + if (vehicles.empty()) { + /// Add the vehicle class entry to the set (it was removed when + /// vehicles_per_vehicle_class_[vehicle_class] got empty). + std::set& vehicle_classes = + sorted_vehicle_classes_per_type_[Type(vehicle)]; + const auto& insertion = + vehicle_classes.insert({vehicle_class, fixed_cost}); + DCHECK(insertion.second); + } + vehicles.push_back(vehicle); + } + + /// Searches for the best compatible vehicle of the given type, i.e. the first + /// vehicle v of type 'type' for which vehicle_is_compatible(v) returns true. + /// If a compatible *vehicle* is found, its index is removed from + /// vehicles_per_vehicle_class_ and the function returns {vehicle, -1}. + /// If for some *vehicle* 'stop_and_return_vehicle' returns true before a + /// compatible vehicle is found, the function simply returns {-1, vehicle}. + /// Returns {-1, -1} if no compatible vehicle is found and the stopping + /// condition is never met. + std::pair GetCompatibleVehicleOfType( + int type, std::function vehicle_is_compatible, + std::function stop_and_return_vehicle); + + private: + using VehicleClassEntry = + RoutingModel::VehicleTypeContainer::VehicleClassEntry; + const RoutingModel::VehicleTypeContainer* const vehicle_type_container_; + // clang-format off + std::vector > sorted_vehicle_classes_per_type_; + std::vector > vehicles_per_vehicle_class_; + // clang-format on +}; + +/// Decision builder building a solution using heuristics with local search +/// filters to evaluate its feasibility. This is very fast but can eventually +/// fail when the solution is restored if filters did not detect all +/// infeasiblities. +/// More details: +/// Using local search filters to build a solution. The approach is pretty +/// straight-forward: have a general assignment storing the current solution, +/// build delta assigment representing possible extensions to the current +/// solution and validate them with filters. +/// The tricky bit comes from using the assignment and filter APIs in a way +/// which avoids the lazy creation of internal hash_maps between variables +/// and indices. + +/// Generic filter-based decision builder using an IntVarFilteredHeuristic. +// TODO(user): Eventually move this to the core CP solver library +/// when the code is mature enough. +class IntVarFilteredDecisionBuilder : public DecisionBuilder { + public: + explicit IntVarFilteredDecisionBuilder( + std::unique_ptr heuristic); + + ~IntVarFilteredDecisionBuilder() override {} + + Decision* Next(Solver* solver) override; + + std::string DebugString() const override; + + /// Returns statistics from its underlying heuristic. + int64_t number_of_decisions() const; + int64_t number_of_rejects() const; + + private: + const std::unique_ptr heuristic_; +}; + +/// Generic filter-based heuristic applied to IntVars. +class IntVarFilteredHeuristic { + public: + IntVarFilteredHeuristic(Solver* solver, const std::vector& vars, + LocalSearchFilterManager* filter_manager); + + virtual ~IntVarFilteredHeuristic() {} + + /// Builds a solution. Returns the resulting assignment if a solution was + /// found, and nullptr otherwise. + Assignment* const BuildSolution(); + + /// Returns statistics on search, number of decisions sent to filters, number + /// of decisions rejected by filters. + int64_t number_of_decisions() const { return number_of_decisions_; } + int64_t number_of_rejects() const { return number_of_rejects_; } + + virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; } + + protected: + /// Resets the data members for a new solution. + void ResetSolution(); + /// Virtual method to initialize the solution. + virtual bool InitializeSolution() { return true; } + /// Virtual method to redefine how to build a solution. + virtual bool BuildSolutionInternal() = 0; + /// Commits the modifications to the current solution if these modifications + /// are "filter-feasible", returns false otherwise; in any case discards + /// all modifications. + bool Commit(); + /// Returns true if the search must be stopped. + virtual bool StopSearch() { return false; } + /// Modifies the current solution by setting the variable of index 'index' to + /// value 'value'. + void SetValue(int64_t index, int64_t value) { + if (!is_in_delta_[index]) { + delta_->FastAdd(vars_[index])->SetValue(value); + delta_indices_.push_back(index); + is_in_delta_[index] = true; + } else { + delta_->SetValue(vars_[index], value); + } + } + /// Returns the value of the variable of index 'index' in the last committed + /// solution. + int64_t Value(int64_t index) const { + return assignment_->IntVarContainer().Element(index).Value(); + } + /// Returns true if the variable of index 'index' is in the current solution. + bool Contains(int64_t index) const { + return assignment_->IntVarContainer().Element(index).Var() != nullptr; + } + /// Returns the number of variables the decision builder is trying to + /// instantiate. + int Size() const { return vars_.size(); } + /// Returns the variable of index 'index'. + IntVar* Var(int64_t index) const { return vars_[index]; } + /// Synchronizes filters with an assignment (the current solution). + void SynchronizeFilters(); + + Assignment* const assignment_; + + private: + /// Checks if filters accept a given modification to the current solution + /// (represented by delta). + bool FilterAccept(); + + Solver* solver_; + const std::vector vars_; + Assignment* const delta_; + std::vector delta_indices_; + std::vector is_in_delta_; + Assignment* const empty_; + LocalSearchFilterManager* filter_manager_; + /// Stats on search + int64_t number_of_decisions_; + int64_t number_of_rejects_; +}; + +/// Filter-based heuristic dedicated to routing. +class RoutingFilteredHeuristic : public IntVarFilteredHeuristic { + public: + RoutingFilteredHeuristic(RoutingModel* model, + LocalSearchFilterManager* filter_manager); + ~RoutingFilteredHeuristic() override {} + /// Builds a solution starting from the routes formed by the next accessor. + const Assignment* BuildSolutionFromRoutes( + const std::function& next_accessor); + RoutingModel* model() const { return model_; } + /// Returns the end of the start chain of vehicle, + int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; } + /// Returns the start of the end chain of vehicle, + int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; } + /// Make nodes in the same disjunction as 'node' unperformed. 'node' is a + /// variable index corresponding to a node. + void MakeDisjunctionNodesUnperformed(int64_t 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(); } + virtual void SetVehicleIndex(int64_t node, int vehicle) {} + virtual void ResetVehicleIndices() {} + bool VehicleIsEmpty(int vehicle) const { + return Value(model()->Start(vehicle)) == model()->End(vehicle); + } + + private: + /// Initializes the current solution with empty or partial vehicle routes. + bool InitializeSolution() override; + + RoutingModel* const model_; + std::vector start_chain_ends_; + std::vector end_chain_starts_; +}; + +class CheapestInsertionFilteredHeuristic : public RoutingFilteredHeuristic { + public: + /// Takes ownership of evaluator. + CheapestInsertionFilteredHeuristic( + RoutingModel* model, std::function evaluator, + std::function penalty_evaluator, + LocalSearchFilterManager* filter_manager); + ~CheapestInsertionFilteredHeuristic() override {} + + protected: + typedef std::pair ValuedPosition; + struct StartEndValue { + int64_t distance; + int vehicle; + + bool operator<(const StartEndValue& other) const { + return std::tie(distance, vehicle) < + std::tie(other.distance, other.vehicle); + } + }; + typedef std::pair Seed; + + /// Computes and returns the distance of each uninserted node to every vehicle + /// in "vehicles" as a std::vector>, + /// start_end_distances_per_node. + /// For each node, start_end_distances_per_node[node] is sorted in decreasing + /// order. + // clang-format off + std::vector > + ComputeStartEndDistanceForVehicles(const std::vector& vehicles); + + /// Initializes the priority_queue by inserting the best entry corresponding + /// to each node, i.e. the last element of start_end_distances_per_node[node], + /// which is supposed to be sorted in decreasing order. + /// Queue is a priority queue containing Seeds. + template + void InitializePriorityQueue( + std::vector >* start_end_distances_per_node, + Queue* priority_queue); + // clang-format on + + /// Inserts 'node' just after 'predecessor', and just before 'successor', + /// resulting in the following subsequence: predecessor -> node -> successor. + /// If 'node' is part of a disjunction, other nodes of the disjunction are + /// made unperformed. + void InsertBetween(int64_t node, int64_t predecessor, int64_t successor); + /// Helper method to the ComputeEvaluatorSortedPositions* methods. Finds all + /// possible insertion positions of node 'node_to_insert' in the partial route + /// starting at node 'start' and adds them to 'valued_position', a list of + /// unsorted pairs of (cost, position to insert the node). + void AppendEvaluatedPositionsAfter( + int64_t node_to_insert, int64_t start, int64_t next_after_start, int64_t vehicle, + std::vector* valued_positions); + /// Returns the cost of inserting 'node_to_insert' between 'insert_after' and + /// 'insert_before' on the 'vehicle', i.e. + /// Cost(insert_after-->node) + Cost(node-->insert_before) + /// - Cost (insert_after-->insert_before). + // TODO(user): Replace 'insert_before' and 'insert_after' by 'predecessor' + // and 'successor' in the code. + int64_t GetInsertionCostForNodeAtPosition(int64_t node_to_insert, + int64_t insert_after, + int64_t insert_before, + int vehicle) const; + /// Returns the cost of unperforming node 'node_to_insert'. Returns kint64max + /// if penalty callback is null or if the node cannot be unperformed. + int64_t GetUnperformedValue(int64_t node_to_insert) const; + + std::function evaluator_; + std::function penalty_evaluator_; +}; + +/// Filter-based decision builder which builds a solution by inserting +/// nodes at their cheapest position on any route; potentially several routes +/// can be built in parallel. The cost of a position is computed from an +/// arc-based cost callback. The node selected for insertion is the one which +/// minimizes insertion cost. If a non null penalty evaluator is passed, making +/// nodes unperformed is also taken into account with the corresponding penalty +/// cost. +class GlobalCheapestInsertionFilteredHeuristic + : public CheapestInsertionFilteredHeuristic { + public: + struct GlobalCheapestInsertionParameters { + /// Whether the routes are constructed sequentially or in parallel. + bool is_sequential; + /// The ratio of routes on which to insert farthest nodes as seeds before + /// starting the cheapest insertion. + double farthest_seeds_ratio; + /// If neighbors_ratio < 1 then for each node only this ratio of its + /// neighbors leading to the smallest arc costs are considered for + /// insertions, with a minimum of 'min_neighbors': + /// num_closest_neighbors = max(min_neighbors, neighbors_ratio*N), + /// where N is the number of non-start/end nodes in the model. + double neighbors_ratio; + int64_t min_neighbors; + /// If true, only closest neighbors (see neighbors_ratio and min_neighbors) + /// are considered as insertion positions during initialization. Otherwise, + /// all possible insertion positions are considered. + bool use_neighbors_ratio_for_initialization; + /// If true, entries are created for making the nodes/pairs unperformed, and + /// when the cost of making a node unperformed is lower than all insertions, + /// the node/pair will be made unperformed. If false, only entries making + /// a node/pair performed are considered. + bool add_unperformed_entries; + }; + + /// Takes ownership of evaluators. + GlobalCheapestInsertionFilteredHeuristic( + RoutingModel* model, std::function evaluator, + std::function penalty_evaluator, + LocalSearchFilterManager* filter_manager, + GlobalCheapestInsertionParameters parameters); + ~GlobalCheapestInsertionFilteredHeuristic() override {} + bool BuildSolutionInternal() override; + std::string DebugString() const override { + return "GlobalCheapestInsertionFilteredHeuristic"; + } + + private: + class NodeEntry; + class PairEntry; + + typedef absl::flat_hash_set PairEntries; + typedef absl::flat_hash_set NodeEntries; + + /// Inserts non-inserted single nodes or pickup/delivery pairs which have a + /// visit type in the type requirement graph, i.e. required for or requiring + /// another type for insertions. + /// These nodes are inserted iff the requirement graph is acyclic, in which + /// case nodes are inserted based on the topological order of their type, + /// given by the routing model's GetTopologicallySortedVisitTypes() method. + void InsertPairsAndNodesByRequirementTopologicalOrder(); + + /// Inserts non-inserted pickup and delivery pairs. Maintains a priority + /// queue of possible pair insertions, which is incrementally updated when a + /// pair insertion is committed. Incrementality is obtained by updating pair + /// insertion positions on the four newly modified route arcs: after the + /// pickup insertion position, after the pickup position, after the delivery + /// insertion position and after the delivery position. + void InsertPairs(const std::vector& pair_indices); + + /// If the vehicle of the given 'pair_entry' is empty, tries to insert the + /// pickup/delivery pair on a vehicle of the same type and same fixed cost as + /// the pair_entry.vehicle() using the empty_vehicle_type_curator_, or update + /// the pair_entry accordingly if the insertion was not possible. + /// Returns true iff the empty_vehicle_type_curator_ is used for the + /// insertion, i.e. iff the pair_entry.vehicle() was empty. + bool InsertPairEntryUsingEmptyVehicleTypeCurator( + const std::vector& pair_indices, PairEntry* const pair_entry, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + + /// Inserts non-inserted individual nodes on the given routes (or all routes + /// if "vehicles" is an empty vector), by constructing routes in parallel. + /// Maintains a priority queue of possible insertions, which is incrementally + /// updated when an insertion is committed. + /// Incrementality is obtained by updating insertion positions on the two + /// newly modified route arcs: after the node insertion position and after the + /// node position. + void InsertNodesOnRoutes(const std::vector& nodes, + const absl::flat_hash_set& vehicles); + + /// If the vehicle of the given 'node_entry' is empty, tries to insert the + /// node on a vehicle of the same type and same fixed cost as the + /// node_entry.vehicle() using the empty_vehicle_type_curator_, or update the + /// node_entry accordingly if the insertion was not possible. + /// Returns true iff the empty_vehicle_type_curator_ is used for the + /// insertion, i.e. iff 'all_vehicles' is true and the node_entry.vehicle() + /// was empty. + bool InsertNodeEntryUsingEmptyVehicleTypeCurator( + const std::vector& nodes, bool all_vehicles, + NodeEntry* const node_entry, + AdjustablePriorityQueue* priority_queue, + std::vector* position_to_node_entries); + + /// Inserts non-inserted individual nodes on routes by constructing routes + /// sequentially. + /// For each new route, the vehicle to use and the first node to insert on it + /// are given by calling InsertSeedNode(). The route is then completed with + /// other nodes by calling InsertNodesOnRoutes({vehicle}). + void SequentialInsertNodes(const std::vector& nodes); + + /// Goes through all vehicles in the model to check if they are already used + /// (i.e. Value(start) != end) or not. + /// Updates the three passed vectors accordingly. + void DetectUsedVehicles(std::vector* is_vehicle_used, + std::vector* unused_vehicles, + absl::flat_hash_set* used_vehicles); + + /// Inserts the (farthest_seeds_ratio_ * model()->vehicles()) nodes farthest + /// from the start/ends of the available vehicle routes as seeds on their + /// closest route. + void InsertFarthestNodesAsSeeds(); + + /// Inserts a "seed node" based on the given priority_queue of Seeds. + /// A "seed" is the node used in order to start a new route. + /// If the Seed at the top of the priority queue cannot be inserted, + /// (node already inserted in the model, corresponding vehicle already used, + /// or unsuccessful Commit()), start_end_distances_per_node is updated and + /// used to insert a new entry for that node if necessary (next best vehicle). + /// If a seed node is successfully inserted, updates is_vehicle_used and + /// returns the vehice of the corresponding route. Returns -1 otherwise. + template + int InsertSeedNode( + std::vector>* start_end_distances_per_node, + Queue* priority_queue, std::vector* is_vehicle_used); + // clang-format on + + /// Initializes the priority queue and the pair entries for the given pair + /// indices with the current state of the solution. + void InitializePairPositions( + const std::vector& pair_indices, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Adds insertion entries performing the 'pickup' and 'delivery', and updates + /// 'priority_queue', pickup_to_entries and delivery_to_entries accordingly. + /// Based on gci_params_.use_neighbors_ratio_for_initialization, either all + /// contained nodes are considered as insertion positions, or only the + /// closest neighbors of 'pickup' and/or 'delivery'. + void InitializeInsertionEntriesPerformingPair( + int64_t pickup, int64_t delivery, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Performs all the necessary updates after a pickup/delivery pair was + /// successfully inserted on the 'vehicle', respectively after + /// 'pickup_position' and 'delivery_position'. + void UpdateAfterPairInsertion( + const std::vector& pair_indices, int vehicle, int64_t pickup, + int64_t pickup_position, int64_t delivery, int64_t delivery_position, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Updates all pair entries inserting a node after node "insert_after" and + /// updates the priority queue accordingly. + void UpdatePairPositions(const std::vector& pair_indices, int vehicle, + int64_t insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries) { + UpdatePickupPositions(pair_indices, vehicle, insert_after, priority_queue, + pickup_to_entries, delivery_to_entries); + UpdateDeliveryPositions(pair_indices, vehicle, insert_after, priority_queue, + pickup_to_entries, delivery_to_entries); + } + /// Updates all pair entries inserting their pickup node after node + /// "insert_after" and updates the priority queue accordingly. + void UpdatePickupPositions(const std::vector& pair_indices, int vehicle, + int64_t pickup_insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Updates all pair entries inserting their delivery node after node + /// "insert_after" and updates the priority queue accordingly. + void UpdateDeliveryPositions( + const std::vector& pair_indices, int vehicle, + int64_t delivery_insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Deletes an entry, removing it from the priority queue and the appropriate + /// pickup and delivery entry sets. + void DeletePairEntry(PairEntry* entry, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + /// Creates a PairEntry corresponding to the insertion of 'pickup' and + /// 'delivery' respectively after 'pickup_insert_after' and + /// 'delivery_insert_after', and adds it to the 'priority_queue', + /// 'pickup_entries' and 'delivery_entries'. + void AddPairEntry(int64_t pickup, int64_t pickup_insert_after, int64_t delivery, + int64_t delivery_insert_after, int vehicle, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_entries, + std::vector* delivery_entries) const; + /// Updates the pair entry's value and rearranges the priority queue + /// accordingly. + void UpdatePairEntry( + PairEntry* const pair_entry, + AdjustablePriorityQueue* priority_queue) const; + /// Computes and returns the insertion value of inserting 'pickup' and + /// 'delivery' respectively after 'pickup_insert_after' and + /// 'delivery_insert_after' on 'vehicle'. + int64_t GetInsertionValueForPairAtPositions(int64_t pickup, + int64_t pickup_insert_after, + int64_t delivery, + int64_t delivery_insert_after, + int vehicle) const; + + /// Initializes the priority queue and the node entries with the current state + /// of the solution on the given vehicle routes. + void InitializePositions(const std::vector& nodes, + const absl::flat_hash_set& vehicles, + AdjustablePriorityQueue* priority_queue, + std::vector* position_to_node_entries); + /// Adds insertion entries performing 'node', and updates 'priority_queue' and + /// position_to_node_entries accordingly. + /// Based on gci_params_.use_neighbors_ratio_for_initialization, either all + /// contained nodes are considered as insertion positions, or only the + /// closest neighbors of 'node'. + void InitializeInsertionEntriesPerformingNode( + int64_t node, const absl::flat_hash_set& vehicles, + AdjustablePriorityQueue* priority_queue, + std::vector* position_to_node_entries); + /// Updates all node entries inserting a node after node "insert_after" and + /// updates the priority queue accordingly. + void UpdatePositions(const std::vector& nodes, int vehicle, + int64_t insert_after, bool all_vehicles, + AdjustablePriorityQueue* priority_queue, + std::vector* node_entries); + /// Deletes an entry, removing it from the priority queue and the appropriate + /// node entry sets. + void DeleteNodeEntry(NodeEntry* entry, + AdjustablePriorityQueue* priority_queue, + std::vector* node_entries); + + /// Creates a NodeEntry corresponding to the insertion of 'node' after + /// 'insert_after' on 'vehicle' and adds it to the 'priority_queue' and + /// 'node_entries'. + void AddNodeEntry(int64_t node, int64_t insert_after, int vehicle, + bool all_vehicles, + AdjustablePriorityQueue* priority_queue, + std::vector* node_entries) const; + /// Updates the given node_entry's value and rearranges the priority queue + /// accordingly. + void UpdateNodeEntry( + NodeEntry* const node_entry, + AdjustablePriorityQueue* priority_queue) const; + + /// Computes the neighborhood of all nodes for every cost class, if needed and + /// not done already. + void ComputeNeighborhoods(); + + /// Returns true iff neighbor_index is in node_index's neighbors list + /// corresponding to neighbor_is_pickup and neighbor_is_delivery. + bool IsNeighborForCostClass(int cost_class, int64_t node_index, + int64_t neighbor_index) const; + + /// Returns the neighbors of the given node for the given cost_class. + const std::vector& GetNeighborsOfNodeForCostClass( + int cost_class, int64_t node_index) const { + return gci_params_.neighbors_ratio == 1 + ? all_nodes_ + : node_index_to_neighbors_by_cost_class_[node_index][cost_class] + ->PositionsSetAtLeastOnce(); + } + + int64_t NumNonStartEndNodes() const { + return model()->Size() - model()->vehicles(); + } + + int64_t NumNeighbors() const { + return std::max(gci_params_.min_neighbors, + MathUtil::FastInt64Round(gci_params_.neighbors_ratio * + NumNonStartEndNodes())); + } + + void ResetVehicleIndices() override { + node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1); + } + + void SetVehicleIndex(int64_t node, int vehicle) override { + DCHECK_LT(node, node_index_to_vehicle_.size()); + node_index_to_vehicle_[node] = vehicle; + } + + /// Function that verifies node_index_to_vehicle_ is correctly filled for all + /// nodes given the current routes. + bool CheckVehicleIndices() const; + + GlobalCheapestInsertionParameters gci_params_; + /// Stores the vehicle index of each node in the current assignment. + std::vector node_index_to_vehicle_; + + // clang-format off + std::vector > > > + node_index_to_neighbors_by_cost_class_; + // clang-format on + + std::unique_ptr empty_vehicle_type_curator_; + + /// When neighbors_ratio is 1, we don't compute the neighborhood matrix + /// above, and use the following vector in the code to avoid unnecessary + /// computations and decrease the time and space complexities. + std::vector all_nodes_; +}; + +/// Filter-base decision builder which builds a solution by inserting +/// nodes at their cheapest position. The cost of a position is computed +/// an arc-based cost callback. Node selected for insertion are considered in +/// decreasing order of distance to the start/ends of the routes, i.e. farthest +/// nodes are inserted first. +class LocalCheapestInsertionFilteredHeuristic + : public CheapestInsertionFilteredHeuristic { + public: + /// Takes ownership of evaluator. + LocalCheapestInsertionFilteredHeuristic( + RoutingModel* model, std::function evaluator, + LocalSearchFilterManager* filter_manager); + ~LocalCheapestInsertionFilteredHeuristic() override {} + bool BuildSolutionInternal() override; + std::string DebugString() const override { + return "LocalCheapestInsertionFilteredHeuristic"; + } + + private: + /// Computes the possible insertion positions of 'node' and sorts them + /// according to the current cost evaluator. + /// 'node' is a variable index corresponding to a node, 'sorted_positions' is + /// a vector of variable indices corresponding to nodes after which 'node' can + /// be inserted. + void ComputeEvaluatorSortedPositions(int64_t node, + std::vector* sorted_positions); + /// Like ComputeEvaluatorSortedPositions, subject to the additional + /// restrictions that the node may only be inserted after node 'start' on the + /// route. For convenience, this method also needs the node that is right + /// after 'start' on the route. + void ComputeEvaluatorSortedPositionsOnRouteAfter( + int64_t node, int64_t start, int64_t next_after_start, + std::vector* sorted_positions); + + std::vector> start_end_distances_per_node_; +}; + +/// Filtered-base decision builder based on the addition heuristic, extending +/// a path from its start node with the cheapest arc. +class CheapestAdditionFilteredHeuristic : public RoutingFilteredHeuristic { + public: + CheapestAdditionFilteredHeuristic(RoutingModel* model, + LocalSearchFilterManager* filter_manager); + ~CheapestAdditionFilteredHeuristic() override {} + bool BuildSolutionInternal() override; + + private: + class PartialRoutesAndLargeVehicleIndicesFirst { + public: + explicit PartialRoutesAndLargeVehicleIndicesFirst( + const CheapestAdditionFilteredHeuristic& builder) + : builder_(builder) {} + bool operator()(int vehicle1, int vehicle2) const; + + private: + const CheapestAdditionFilteredHeuristic& builder_; + }; + /// Returns a vector of possible next indices of node from an iterator. + template + std::vector GetPossibleNextsFromIterator(int64_t node, Iterator start, + Iterator end) const { + const int size = model()->Size(); + std::vector nexts; + for (Iterator it = start; it != end; ++it) { + const int64_t next = *it; + if (next != node && (next >= size || !Contains(next))) { + nexts.push_back(next); + } + } + return nexts; + } + /// Sorts a vector of successors of node. + virtual void SortSuccessors(int64_t node, std::vector* successors) = 0; + virtual int64_t FindTopSuccessor(int64_t node, + const std::vector& successors) = 0; +}; + +/// A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' +/// comes from an arc evaluator. +class EvaluatorCheapestAdditionFilteredHeuristic + : public CheapestAdditionFilteredHeuristic { + public: + /// Takes ownership of evaluator. + EvaluatorCheapestAdditionFilteredHeuristic( + RoutingModel* model, std::function evaluator, + LocalSearchFilterManager* filter_manager); + ~EvaluatorCheapestAdditionFilteredHeuristic() override {} + std::string DebugString() const override { + return "EvaluatorCheapestAdditionFilteredHeuristic"; + } + + private: + /// Next nodes are sorted according to the current evaluator. + void SortSuccessors(int64_t node, std::vector* successors) override; + int64_t FindTopSuccessor(int64_t node, + const std::vector& successors) override; + + std::function evaluator_; +}; + +/// A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' +/// comes from an arc comparator. +class ComparatorCheapestAdditionFilteredHeuristic + : public CheapestAdditionFilteredHeuristic { + public: + /// Takes ownership of evaluator. + ComparatorCheapestAdditionFilteredHeuristic( + RoutingModel* model, Solver::VariableValueComparator comparator, + LocalSearchFilterManager* filter_manager); + ~ComparatorCheapestAdditionFilteredHeuristic() override {} + std::string DebugString() const override { + return "ComparatorCheapestAdditionFilteredHeuristic"; + } + + private: + /// Next nodes are sorted according to the current comparator. + void SortSuccessors(int64_t node, std::vector* successors) override; + int64_t FindTopSuccessor(int64_t node, + const std::vector& successors) override; + + Solver::VariableValueComparator comparator_; +}; + +/// Filter-based decision builder which builds a solution by using +/// Clarke & Wright's Savings heuristic. For each pair of nodes, the savings +/// value is the difference between the cost of two routes visiting one node +/// each and one route visiting both nodes. Routes are built sequentially, each +/// route being initialized from the pair with the best avalaible savings value +/// then extended by selecting the nodes with best savings on both ends of the +/// partial route. Cost is based on the arc cost function of the routing model +/// and cost classes are taken into account. +class SavingsFilteredHeuristic : public RoutingFilteredHeuristic { + public: + struct SavingsParameters { + /// If neighbors_ratio < 1 then for each node only this ratio of its + /// neighbors leading to the smallest arc costs are considered. + double neighbors_ratio = 1.0; + /// The number of neighbors considered for each node is also adapted so that + /// the stored Savings don't use up more than max_memory_usage_bytes bytes. + double max_memory_usage_bytes = 6e9; + /// If add_reverse_arcs is true, the neighborhood relationships are + /// considered symmetrically. + bool add_reverse_arcs = false; + /// arc_coefficient is a strictly positive parameter indicating the + /// coefficient of the arc being considered in the Saving formula. + double arc_coefficient = 1.0; + }; + + SavingsFilteredHeuristic(RoutingModel* model, + const RoutingIndexManager* manager, + SavingsParameters parameters, + LocalSearchFilterManager* filter_manager); + ~SavingsFilteredHeuristic() override; + bool BuildSolutionInternal() override; + + protected: + typedef std::pair Saving; + + template + class SavingsContainer; + + virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0; + + virtual void BuildRoutesFromSavings() = 0; + + /// Returns the cost class from a saving. + int64_t GetVehicleTypeFromSaving(const Saving& saving) const { + return saving.second / size_squared_; + } + /// Returns the "before node" from a saving. + int64_t GetBeforeNodeFromSaving(const Saving& saving) const { + return (saving.second % size_squared_) / Size(); + } + /// Returns the "after node" from a saving. + int64_t GetAfterNodeFromSaving(const Saving& saving) const { + return (saving.second % size_squared_) % Size(); + } + /// Returns the saving value from a saving. + int64_t GetSavingValue(const Saving& saving) const { return saving.first; } + + /// Finds the best available vehicle of type "type" to start a new route to + /// serve the arc before_node-->after_node. + /// Since there are different vehicle classes for each vehicle type, each + /// vehicle class having its own capacity constraints, we go through all + /// vehicle types (in each case only studying the first available vehicle) to + /// make sure this Saving is inserted if possible. + /// If possible, the arc is committed to the best vehicle, and the vehicle + /// index is returned. If this arc can't be served by any vehicle of this + /// type, the function returns -1. + int StartNewRouteWithBestVehicleOfType(int type, int64_t before_node, + int64_t after_node); + + // clang-format off + std::unique_ptr > savings_container_; + // clang-format on + std::unique_ptr vehicle_type_curator_; + + private: + /// Used when add_reverse_arcs_ is true. + /// Given the vector of adjacency lists of a graph, adds symmetric arcs not + /// already in the graph to the adjacencies (i.e. if n1-->n2 is present and + /// not n2-->n1, then n1 is added to adjacency_matrix[n2]. + // clang-format off + void AddSymmetricArcsToAdjacencyLists( + std::vector >* adjacency_lists); + // clang-format on + + /// Computes saving values for node pairs (see MaxNumNeighborsPerNode()) and + /// all vehicle types (see ComputeVehicleTypes()). + /// The saving index attached to each saving value is an index used to + /// store and recover the node pair to which the value is linked (cf. the + /// index conversion methods below). + /// The computed savings are stored and sorted using the savings_container_. + /// Returns false if the computation could not be done within the model's + /// time limit. + bool ComputeSavings(); + /// Builds a saving from a saving value, a vehicle type and two nodes. + Saving BuildSaving(int64_t saving, int vehicle_type, int before_node, + int after_node) const { + return std::make_pair(saving, vehicle_type * size_squared_ + + before_node * Size() + after_node); + } + + /// Computes and returns the maximum number of (closest) neighbors to consider + /// for each node when computing Savings, based on the neighbors ratio and max + /// memory usage specified by the savings_params_. + int64_t MaxNumNeighborsPerNode(int num_vehicle_types) const; + + const RoutingIndexManager* const manager_; + const SavingsParameters savings_params_; + int64_t size_squared_; + + friend class SavingsFilteredHeuristicTestPeer; +}; + +class SequentialSavingsFilteredHeuristic : public SavingsFilteredHeuristic { + public: + SequentialSavingsFilteredHeuristic(RoutingModel* model, + const RoutingIndexManager* manager, + SavingsParameters parameters, + LocalSearchFilterManager* filter_manager) + : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {} + ~SequentialSavingsFilteredHeuristic() override{}; + std::string DebugString() const override { + return "SequentialSavingsFilteredHeuristic"; + } + + private: + /// Builds routes sequentially. + /// Once a Saving is used to start a new route, we extend this route as much + /// as possible from both ends by gradually inserting the best Saving at + /// either end of the route. + void BuildRoutesFromSavings() override; + double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; } +}; + +class ParallelSavingsFilteredHeuristic : public SavingsFilteredHeuristic { + public: + ParallelSavingsFilteredHeuristic(RoutingModel* model, + const RoutingIndexManager* manager, + SavingsParameters parameters, + LocalSearchFilterManager* filter_manager) + : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {} + ~ParallelSavingsFilteredHeuristic() override{}; + std::string DebugString() const override { + return "ParallelSavingsFilteredHeuristic"; + } + + private: + /// Goes through the ordered computed Savings to build routes in parallel. + /// Given a Saving for a before-->after arc : + /// -- If both before and after are uncontained, we start a new route. + /// -- If only before is served and is the last node on its route, we try + /// adding after at the end of the route. + /// -- If only after is served and is first on its route, we try adding before + /// as first node on this route. + /// -- If both nodes are contained and are respectively the last and first + /// nodes on their (different) routes, we merge the routes of the two nodes + /// into one if possible. + void BuildRoutesFromSavings() override; + + double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; } + + /// Merges the routes of first_vehicle and second_vehicle onto the vehicle + /// with lower fixed cost. The routes respectively end at before_node and + /// start at after_node, and are merged into one by adding the arc + /// before_node-->after_node. + void MergeRoutes(int first_vehicle, int second_vehicle, int64_t before_node, + int64_t after_node); + + /// First and last non start/end nodes served by each vehicle. + std::vector first_node_on_route_; + std::vector last_node_on_route_; + /// For each first/last node served by a vehicle (besides start/end nodes of + /// vehicle), this vector contains the index of the vehicle serving them. + /// For other (intermediary) nodes, contains -1. + std::vector vehicle_of_first_or_last_node_; +}; + +/// Christofides addition heuristic. Initially created to solve TSPs, extended +/// to support any model by extending routes as much as possible following the +/// path found by the heuristic, before starting a new route. + +class ChristofidesFilteredHeuristic : public RoutingFilteredHeuristic { + public: + ChristofidesFilteredHeuristic(RoutingModel* model, + LocalSearchFilterManager* filter_manager, + bool use_minimum_matching); + ~ChristofidesFilteredHeuristic() override {} + bool BuildSolutionInternal() override; + std::string DebugString() const override { + return "ChristofidesFilteredHeuristic"; + } + + private: + const bool use_minimum_matching_; +}; + +/// Class to arrange indices by by their distance and their angles from the +/// depot. Used in the Sweep first solution heuristic. +class SweepArranger { + public: + explicit SweepArranger(const std::vector>& points); + virtual ~SweepArranger() {} + void ArrangeIndices(std::vector* indices); + void SetSectors(int sectors) { sectors_ = sectors; } + + private: + std::vector coordinates_; + int sectors_; + + DISALLOW_COPY_AND_ASSIGN(SweepArranger); +}; +#endif // SWIG + +// Returns a DecisionBuilder building a first solution based on the Sweep +// heuristic. Mostly suitable when cost is proportional to distance. +DecisionBuilder* MakeSweepDecisionBuilder(RoutingModel* model, + bool check_assignment); + +// Returns a DecisionBuilder making all nodes unperformed. +DecisionBuilder* MakeAllUnperformed(RoutingModel* model); + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ diff --git a/ortools/constraint_solver/routing_types.h b/ortools/constraint_solver/routing_types.h index a7a96feabe..48d72ae416 100644 --- a/ortools/constraint_solver/routing_types.h +++ b/ortools/constraint_solver/routing_types.h @@ -18,6 +18,7 @@ #include #include +#include "absl/strings/string_view.h" #include "ortools/base/int_type.h" #include "ortools/base/integral_types.h" @@ -38,10 +39,10 @@ DEFINE_INT_TYPE(RoutingDimensionIndex, int); DEFINE_INT_TYPE(RoutingDisjunctionIndex, int); DEFINE_INT_TYPE(RoutingVehicleClassIndex, int); -typedef std::function RoutingTransitCallback1; -typedef std::function RoutingTransitCallback2; +typedef std::function RoutingTransitCallback1; +typedef std::function RoutingTransitCallback2; // NOTE(user): keep the "> >" for SWIG. -typedef std::pair, std::vector > RoutingIndexPair; +typedef std::pair, std::vector > RoutingIndexPair; typedef std::vector RoutingIndexPairs; } // namespace operations_research diff --git a/ortools/constraint_solver/samples/simple_cp_program.cc b/ortools/constraint_solver/samples/simple_cp_program.cc index 371be0a6c0..1f48b8e153 100644 --- a/ortools/constraint_solver/samples/simple_cp_program.cc +++ b/ortools/constraint_solver/samples/simple_cp_program.cc @@ -26,7 +26,7 @@ void SimpleCpProgram() { // Create the variables. // [START variables] - const int64 num_vals = 3; + const int64_t num_vals = 3; IntVar* const x = solver.MakeIntVar(0, num_vals - 1, "x"); IntVar* const y = solver.MakeIntVar(0, num_vals - 1, "y"); IntVar* const z = solver.MakeIntVar(0, num_vals - 1, "z"); diff --git a/ortools/constraint_solver/samples/simple_ls_program.cc b/ortools/constraint_solver/samples/simple_ls_program.cc index 24f29e2614..34e444696e 100644 --- a/ortools/constraint_solver/samples/simple_ls_program.cc +++ b/ortools/constraint_solver/samples/simple_ls_program.cc @@ -61,7 +61,7 @@ class MoveOneVar : public IntVarLocalSearchOperator { protected: // Make a neighbor assigning one variable to its target value. bool MakeOneNeighbor() override { - const int64 current_value = OldValue(variable_index_); + const int64_t current_value = OldValue(variable_index_); if (move_up_) { SetValue(variable_index_, current_value + 1); variable_index_ = (variable_index_ + 1) % Size(); @@ -79,7 +79,7 @@ class MoveOneVar : public IntVarLocalSearchOperator { } // Index of the next variable to try to restore - int64 variable_index_; + int64_t variable_index_; // Direction of the modification. bool move_up_; }; @@ -99,7 +99,7 @@ class SumFilter : public IntVarLocalSearchFilter { } bool Accept(const Assignment* delta, const Assignment* unused_deltadelta, - int64 objective_min, int64 objective_max) override { + int64_t objective_min, int64_t objective_max) override { const Assignment::IntContainer& solution_delta = delta->IntVarContainer(); const int solution_delta_size = solution_delta.Size(); @@ -130,13 +130,13 @@ class SumFilter : public IntVarLocalSearchFilter { return true; } } - int64 new_sum = sum_; + int64_t new_sum = sum_; VLOG(1) << "No LNS, size = " << solution_delta_size; for (int index = 0; index < solution_delta_size; ++index) { - int64 touched_var = -1; + int64_t touched_var = -1; FindIndex(solution_delta.Element(index).Var(), &touched_var); - const int64 old_value = Value(touched_var); - const int64 new_value = solution_delta.Element(index).Value(); + const int64_t old_value = Value(touched_var); + const int64_t new_value = solution_delta.Element(index).Value(); new_sum += new_value - old_value; } VLOG(1) << "new sum = " << new_sum << ", old sum = " << sum_; @@ -144,7 +144,7 @@ class SumFilter : public IntVarLocalSearchFilter { } private: - int64 sum_; + int64_t sum_; }; enum SolveType { LNS, LS, LS_WITH_FILTER }; diff --git a/ortools/constraint_solver/samples/simple_routing_program.cc b/ortools/constraint_solver/samples/simple_routing_program.cc index 3abe017167..64cab88a86 100644 --- a/ortools/constraint_solver/samples/simple_routing_program.cc +++ b/ortools/constraint_solver/samples/simple_routing_program.cc @@ -45,7 +45,7 @@ void SimpleRoutingProgram() { // Define cost of each arc. // [START arc_cost] int distance_call_index = routing.RegisterTransitCallback( - [&manager](int64 from_index, int64 to_index) -> int64 { + [&manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to user NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/tsp.cc b/ortools/constraint_solver/samples/tsp.cc index 4a5f11b18a..c3c6c28ab5 100644 --- a/ortools/constraint_solver/samples/tsp.cc +++ b/ortools/constraint_solver/samples/tsp.cc @@ -111,7 +111,7 @@ void Tsp() { // [START transit_callback] const auto distance_matrix = GenerateManhattanDistanceMatrix(data.locations); const int transit_callback_index = routing.RegisterTransitCallback( - [&distance_matrix, &manager](int64 from_index, int64 to_index) -> int64 { + [&distance_matrix, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/tsp_circuit_board.cc b/ortools/constraint_solver/samples/tsp_circuit_board.cc index 0567b38ea9..9f7cc1b1dd 100644 --- a/ortools/constraint_solver/samples/tsp_circuit_board.cc +++ b/ortools/constraint_solver/samples/tsp_circuit_board.cc @@ -146,7 +146,7 @@ void Tsp() { // [START transit_callback] const auto distance_matrix = ComputeEuclideanDistanceMatrix(data.locations); const int transit_callback_index = routing.RegisterTransitCallback( - [&distance_matrix, &manager](int64 from_index, int64 to_index) -> int64 { + [&distance_matrix, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/tsp_cities.cc b/ortools/constraint_solver/samples/tsp_cities.cc index 7a2e235de4..819962a3a2 100644 --- a/ortools/constraint_solver/samples/tsp_cities.cc +++ b/ortools/constraint_solver/samples/tsp_cities.cc @@ -92,7 +92,7 @@ void Tsp() { // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/tsp_cities_routes.cc b/ortools/constraint_solver/samples/tsp_cities_routes.cc index 9c9fa8363a..79232c510a 100644 --- a/ortools/constraint_solver/samples/tsp_cities_routes.cc +++ b/ortools/constraint_solver/samples/tsp_cities_routes.cc @@ -91,7 +91,7 @@ void Tsp() { // Define cost of each arc. // [START arc_cost] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/tsp_distance_matrix.cc b/ortools/constraint_solver/samples/tsp_distance_matrix.cc index a11aab9603..06af46a57f 100644 --- a/ortools/constraint_solver/samples/tsp_distance_matrix.cc +++ b/ortools/constraint_solver/samples/tsp_distance_matrix.cc @@ -113,7 +113,7 @@ void Tsp() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp.cc b/ortools/constraint_solver/samples/vrp.cc index 0781a3b519..a79b4c9bf3 100644 --- a/ortools/constraint_solver/samples/vrp.cc +++ b/ortools/constraint_solver/samples/vrp.cc @@ -119,7 +119,7 @@ void Vrp() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_breaks.cc b/ortools/constraint_solver/samples/vrp_breaks.cc index 81384adb22..21c0f92195 100644 --- a/ortools/constraint_solver/samples/vrp_breaks.cc +++ b/ortools/constraint_solver/samples/vrp_breaks.cc @@ -152,7 +152,7 @@ void VrpBreaks() { // [END time_constraint] // Add Breaks - std::vector service_times(routing.Size()); + std::vector service_times(routing.Size()); for (int index = 0; index < routing.Size(); index++) { const RoutingIndexManager::NodeIndex node = manager.IndexToNode(index); service_times[index] = data.service_time[node.value()]; diff --git a/ortools/constraint_solver/samples/vrp_capacity.cc b/ortools/constraint_solver/samples/vrp_capacity.cc index 038ab61c9a..73b84f954a 100644 --- a/ortools/constraint_solver/samples/vrp_capacity.cc +++ b/ortools/constraint_solver/samples/vrp_capacity.cc @@ -132,7 +132,7 @@ void VrpCapacity() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. int from_node = manager.IndexToNode(from_index).value(); int to_node = manager.IndexToNode(to_index).value(); @@ -148,7 +148,7 @@ void VrpCapacity() { // Add Capacity constraint. // [START capacity_constraint] const int demand_callback_index = routing.RegisterUnaryTransitCallback( - [&data, &manager](int64 from_index) -> int64 { + [&data, &manager](int64_t from_index) -> int64_t { // Convert from routing variable Index to demand NodeIndex. int from_node = manager.IndexToNode(from_index).value(); return data.demands[from_node]; diff --git a/ortools/constraint_solver/samples/vrp_drop_nodes.cc b/ortools/constraint_solver/samples/vrp_drop_nodes.cc index d04647deb2..8279e3ea9a 100644 --- a/ortools/constraint_solver/samples/vrp_drop_nodes.cc +++ b/ortools/constraint_solver/samples/vrp_drop_nodes.cc @@ -142,7 +142,7 @@ void VrpDropNodes() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); @@ -158,7 +158,7 @@ void VrpDropNodes() { // Add Capacity constraint. // [START capacity_constraint] const int demand_callback_index = routing.RegisterUnaryTransitCallback( - [&data, &manager](int64 from_index) -> int64 { + [&data, &manager](int64_t from_index) -> int64_t { // Convert from routing variable Index to demand NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); return data.demands[from_node]; diff --git a/ortools/constraint_solver/samples/vrp_global_span.cc b/ortools/constraint_solver/samples/vrp_global_span.cc index d988beeb23..d121bc3480 100644 --- a/ortools/constraint_solver/samples/vrp_global_span.cc +++ b/ortools/constraint_solver/samples/vrp_global_span.cc @@ -117,7 +117,7 @@ void VrpGlobalSpan() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_initial_routes.cc b/ortools/constraint_solver/samples/vrp_initial_routes.cc index 726088c9e3..8f61ed5a28 100644 --- a/ortools/constraint_solver/samples/vrp_initial_routes.cc +++ b/ortools/constraint_solver/samples/vrp_initial_routes.cc @@ -124,7 +124,7 @@ void VrpInitialRoutes() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery.cc b/ortools/constraint_solver/samples/vrp_pickup_delivery.cc index ac690401af..abf5b60511 100644 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery.cc +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery.cc @@ -139,7 +139,7 @@ void VrpGlobalSpan() { // Define cost of each arc. // [START arc_cost] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.cc b/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.cc index a1c28aebde..40791f3eb9 100644 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.cc +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.cc @@ -139,7 +139,7 @@ void VrpGlobalSpan() { // Define cost of each arc. // [START arc_cost] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.cc b/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.cc index c88ec4592a..aaa788e7e1 100644 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.cc +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.cc @@ -139,7 +139,7 @@ void VrpGlobalSpan() { // Define cost of each arc. // [START arc_cost] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_resources.cc b/ortools/constraint_solver/samples/vrp_resources.cc index 5ca8384875..0e4cd3e9f4 100644 --- a/ortools/constraint_solver/samples/vrp_resources.cc +++ b/ortools/constraint_solver/samples/vrp_resources.cc @@ -129,7 +129,7 @@ void VrpTimeWindows() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to time matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_routes.cc b/ortools/constraint_solver/samples/vrp_routes.cc index c61f223e3d..8a13701dae 100644 --- a/ortools/constraint_solver/samples/vrp_routes.cc +++ b/ortools/constraint_solver/samples/vrp_routes.cc @@ -111,7 +111,7 @@ void Vrp() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_starts_ends.cc b/ortools/constraint_solver/samples/vrp_starts_ends.cc index 4ca69db7f0..9a1c257c04 100644 --- a/ortools/constraint_solver/samples/vrp_starts_ends.cc +++ b/ortools/constraint_solver/samples/vrp_starts_ends.cc @@ -130,7 +130,7 @@ void VrpStartsEnds() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to distance matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_time_windows.cc b/ortools/constraint_solver/samples/vrp_time_windows.cc index 8a12352e40..78f175b808 100644 --- a/ortools/constraint_solver/samples/vrp_time_windows.cc +++ b/ortools/constraint_solver/samples/vrp_time_windows.cc @@ -125,7 +125,7 @@ void VrpTimeWindows() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to time matrix NodeIndex. auto from_node = manager.IndexToNode(from_index).value(); auto to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/samples/vrp_with_time_limit.cc b/ortools/constraint_solver/samples/vrp_with_time_limit.cc index d7c4d8ab9e..e30047c55f 100644 --- a/ortools/constraint_solver/samples/vrp_with_time_limit.cc +++ b/ortools/constraint_solver/samples/vrp_with_time_limit.cc @@ -75,7 +75,7 @@ void VrpGlobalSpan() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [](int64 from_index, int64 to_index) -> int64 { return 1; }); + [](int64_t from_index, int64_t to_index) -> int64_t { return 1; }); // [END transit_callback] // Define cost of each arc. diff --git a/ortools/constraint_solver/samples/vrptw_store_solution_data.cc b/ortools/constraint_solver/samples/vrptw_store_solution_data.cc index 1a79df3fc2..b9cddaf56e 100644 --- a/ortools/constraint_solver/samples/vrptw_store_solution_data.cc +++ b/ortools/constraint_solver/samples/vrptw_store_solution_data.cc @@ -165,7 +165,7 @@ void VrpTimeWindows() { // Create and register a transit callback. // [START transit_callback] const int transit_callback_index = routing.RegisterTransitCallback( - [&data, &manager](int64 from_index, int64 to_index) -> int64 { + [&data, &manager](int64_t from_index, int64_t to_index) -> int64_t { // Convert from routing variable Index to time matrix NodeIndex. int from_node = manager.IndexToNode(from_index).value(); int to_node = manager.IndexToNode(to_index).value(); diff --git a/ortools/constraint_solver/sched_constraints.cc b/ortools/constraint_solver/sched_constraints.cc index 5627c345ce..f0078115ec 100644 --- a/ortools/constraint_solver/sched_constraints.cc +++ b/ortools/constraint_solver/sched_constraints.cc @@ -21,6 +21,8 @@ // var unperformed implies all intervals unperformed, cover var // performed implis at least one interval performed). +#include +#include #include #include @@ -75,9 +77,9 @@ class TreeArrayConstraint : public Constraint { } // Reduce the range of a given node (interval, state). - void ReduceDomain(int depth, int position, int64 new_start_min, - int64 new_start_max, int64 new_end_min, int64 new_end_max, - PerformedStatus performed) { + void ReduceDomain(int depth, int position, int64_t new_start_min, + int64_t new_start_max, int64_t new_end_min, + int64_t new_end_max, PerformedStatus performed) { NodeInfo* const info = &tree_[depth][position]; if (new_start_min > info->start_min.Value()) { info->start_min.SetValue(solver(), new_start_min); @@ -98,14 +100,14 @@ class TreeArrayConstraint : public Constraint { } } - void InitLeaf(int position, int64 start_min, int64 start_max, int64 end_min, - int64 end_max, PerformedStatus performed) { + void InitLeaf(int position, int64_t start_min, int64_t start_max, + int64_t end_min, int64_t end_max, PerformedStatus performed) { InitNode(MaxDepth(), position, start_min, start_max, end_min, end_max, performed); } - void InitNode(int depth, int position, int64 start_min, int64 start_max, - int64 end_min, int64 end_max, PerformedStatus performed) { + void InitNode(int depth, int position, int64_t start_min, int64_t start_max, + int64_t end_min, int64_t end_max, PerformedStatus performed) { tree_[depth][position].start_min.SetValue(solver(), start_min); tree_[depth][position].start_max.SetValue(solver(), start_max); tree_[depth][position].end_min.SetValue(solver(), end_min); @@ -114,19 +116,19 @@ class TreeArrayConstraint : public Constraint { static_cast(performed)); } - int64 StartMin(int depth, int position) const { + int64_t StartMin(int depth, int position) const { return tree_[depth][position].start_min.Value(); } - int64 StartMax(int depth, int position) const { + int64_t StartMax(int depth, int position) const { return tree_[depth][position].start_max.Value(); } - int64 EndMax(int depth, int position) const { + int64_t EndMax(int depth, int position) const { return tree_[depth][position].end_max.Value(); } - int64 EndMin(int depth, int position) const { + int64_t EndMin(int depth, int position) const { return tree_[depth][position].end_min.Value(); } @@ -137,47 +139,47 @@ class TreeArrayConstraint : public Constraint { return static_cast(p); } - int64 RootStartMin() const { return root_node_->start_min.Value(); } + int64_t RootStartMin() const { return root_node_->start_min.Value(); } - int64 RootStartMax() const { return root_node_->start_max.Value(); } + int64_t RootStartMax() const { return root_node_->start_max.Value(); } - int64 RootEndMin() const { return root_node_->end_min.Value(); } + int64_t RootEndMin() const { return root_node_->end_min.Value(); } - int64 RootEndMax() const { return root_node_->end_max.Value(); } + int64_t RootEndMax() const { return root_node_->end_max.Value(); } PerformedStatus RootPerformed() const { return Performed(0, 0); } // This getters query first if the var can be performed, and will // return a default value if not. - int64 VarStartMin(int position) const { + int64_t VarStartMin(int position) const { return vars_[position]->MayBePerformed() ? vars_[position]->StartMin() : 0; } - int64 VarStartMax(int position) const { + int64_t VarStartMax(int position) const { return vars_[position]->MayBePerformed() ? vars_[position]->StartMax() : 0; } - int64 VarEndMin(int position) const { + int64_t VarEndMin(int position) const { return vars_[position]->MayBePerformed() ? vars_[position]->EndMin() : 0; } - int64 VarEndMax(int position) const { + int64_t VarEndMax(int position) const { return vars_[position]->MayBePerformed() ? vars_[position]->EndMax() : 0; } - int64 TargetVarStartMin() const { + int64_t TargetVarStartMin() const { return target_var_->MayBePerformed() ? target_var_->StartMin() : 0; } - int64 TargetVarStartMax() const { + int64_t TargetVarStartMax() const { return target_var_->MayBePerformed() ? target_var_->StartMax() : 0; } - int64 TargetVarEndMin() const { + int64_t TargetVarEndMin() const { return target_var_->MayBePerformed() ? target_var_->EndMin() : 0; } - int64 TargetVarEndMax() const { + int64_t TargetVarEndMax() const { return target_var_->MayBePerformed() ? target_var_->EndMax() : 0; } @@ -238,10 +240,10 @@ class TreeArrayConstraint : public Constraint { end_max(0), performed(UNDECIDED) {} - Rev start_min; - Rev start_max; - Rev end_min; - Rev end_max; + Rev start_min; + Rev start_max; + Rev end_min; + Rev end_max; Rev performed; }; @@ -284,10 +286,10 @@ class CoverConstraint : public TreeArrayConstraint { // Compute up. for (int i = MaxDepth() - 1; i >= 0; --i) { for (int j = 0; j < Width(i); ++j) { - int64 bucket_start_min = kint64max; - int64 bucket_start_max = kint64max; - int64 bucket_end_min = kint64min; - int64 bucket_end_max = kint64min; + int64_t bucket_start_min = std::numeric_limits::max(); + int64_t bucket_start_max = std::numeric_limits::max(); + int64_t bucket_end_min = std::numeric_limits::min(); + int64_t bucket_end_max = std::numeric_limits::min(); bool one_undecided = false; const PerformedStatus up_performed = ComputePropagationUp( i, j, &bucket_start_min, &bucket_start_max, &bucket_end_min, @@ -326,8 +328,8 @@ class CoverConstraint : public TreeArrayConstraint { TargetVarEndMax(), TargetVarPerformed()); } - void PushDown(int depth, int position, int64 new_start_min, - int64 new_start_max, int64 new_end_min, int64 new_end_max, + void PushDown(int depth, int position, int64_t new_start_min, + int64_t new_start_max, int64_t new_end_min, int64_t new_end_max, PerformedStatus performed) { // TODO(user): Propagate start_max and end_min going down. // Nothing to do? @@ -418,10 +420,10 @@ class CoverConstraint : public TreeArrayConstraint { // Do we need to propagate up? const int parent = Parent(term_index); const int parent_depth = MaxDepth() - 1; - const int64 parent_start_min = StartMin(parent_depth, parent); - const int64 parent_start_max = StartMax(parent_depth, parent); - const int64 parent_end_min = EndMin(parent_depth, parent); - const int64 parent_end_max = EndMax(parent_depth, parent); + const int64_t parent_start_min = StartMin(parent_depth, parent); + const int64_t parent_start_max = StartMax(parent_depth, parent); + const int64_t parent_end_min = EndMin(parent_depth, parent); + const int64_t parent_end_max = EndMax(parent_depth, parent); IntervalVar* const var = vars_[term_index]; const bool performed_bound = var->IsPerformedBound(); const bool was_performed_bound = var->WasPerformedBound(); @@ -442,10 +444,10 @@ class CoverConstraint : public TreeArrayConstraint { while (depth > 0) { const int parent = Parent(position); const int parent_depth = depth - 1; - int64 bucket_start_min = kint64max; - int64 bucket_start_max = kint64max; - int64 bucket_end_min = kint64min; - int64 bucket_end_max = kint64min; + int64_t bucket_start_min = std::numeric_limits::max(); + int64_t bucket_start_max = std::numeric_limits::max(); + int64_t bucket_end_min = std::numeric_limits::min(); + int64_t bucket_end_max = std::numeric_limits::min(); bool one_undecided = false; const PerformedStatus status_up = ComputePropagationUp( parent_depth, parent, &bucket_start_min, &bucket_start_max, @@ -483,15 +485,15 @@ class CoverConstraint : public TreeArrayConstraint { private: PerformedStatus ComputePropagationUp(int parent_depth, int parent_position, - int64* const bucket_start_min, - int64* const bucket_start_max, - int64* const bucket_end_min, - int64* const bucket_end_max, + int64_t* const bucket_start_min, + int64_t* const bucket_start_max, + int64_t* const bucket_end_min, + int64_t* const bucket_end_max, bool* one_undecided) { - *bucket_start_min = kint64max; - *bucket_start_max = kint64max; - *bucket_end_min = kint64min; - *bucket_end_max = kint64min; + *bucket_start_min = std::numeric_limits::max(); + *bucket_start_max = std::numeric_limits::max(); + *bucket_end_min = std::numeric_limits::min(); + *bucket_end_max = std::numeric_limits::min(); int may_be_performed_count = 0; int must_be_performed_count = 0; diff --git a/ortools/constraint_solver/sched_expr.cc b/ortools/constraint_solver/sched_expr.cc index 5001d82abb..15158ab0df 100644 --- a/ortools/constraint_solver/sched_expr.cc +++ b/ortools/constraint_solver/sched_expr.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -33,17 +34,19 @@ class IntervalVarStartExpr : public BaseIntExpr { : BaseIntExpr(i->solver()), interval_(i) {} ~IntervalVarStartExpr() override {} - int64 Min() const override { return interval_->StartMin(); } + int64_t Min() const override { return interval_->StartMin(); } - void SetMin(int64 m) override { interval_->SetStartMin(m); } + void SetMin(int64_t m) override { interval_->SetStartMin(m); } - int64 Max() const override { return interval_->StartMax(); } + int64_t Max() const override { return interval_->StartMax(); } - void SetMax(int64 m) override { interval_->SetStartMax(m); } + void SetMax(int64_t m) override { interval_->SetStartMax(m); } - void SetRange(int64 l, int64 u) override { interval_->SetStartRange(l, u); } + void SetRange(int64_t l, int64_t u) override { + interval_->SetStartRange(l, u); + } - void SetValue(int64 v) override { interval_->SetStartRange(v, v); } + void SetValue(int64_t v) override { interval_->SetStartRange(v, v); } bool Bound() const override { return interval_->StartMin() == interval_->StartMax(); @@ -72,17 +75,17 @@ class IntervalVarEndExpr : public BaseIntExpr { : BaseIntExpr(i->solver()), interval_(i) {} ~IntervalVarEndExpr() override {} - int64 Min() const override { return interval_->EndMin(); } + int64_t Min() const override { return interval_->EndMin(); } - void SetMin(int64 m) override { interval_->SetEndMin(m); } + void SetMin(int64_t m) override { interval_->SetEndMin(m); } - int64 Max() const override { return interval_->EndMax(); } + int64_t Max() const override { return interval_->EndMax(); } - void SetMax(int64 m) override { interval_->SetEndMax(m); } + void SetMax(int64_t m) override { interval_->SetEndMax(m); } - void SetRange(int64 l, int64 u) override { interval_->SetEndRange(l, u); } + void SetRange(int64_t l, int64_t u) override { interval_->SetEndRange(l, u); } - void SetValue(int64 v) override { interval_->SetEndRange(v, v); } + void SetValue(int64_t v) override { interval_->SetEndRange(v, v); } bool Bound() const override { return interval_->EndMin() == interval_->EndMax(); @@ -111,19 +114,19 @@ class IntervalVarDurationExpr : public BaseIntExpr { : BaseIntExpr(i->solver()), interval_(i) {} ~IntervalVarDurationExpr() override {} - int64 Min() const override { return interval_->DurationMin(); } + int64_t Min() const override { return interval_->DurationMin(); } - void SetMin(int64 m) override { interval_->SetDurationMin(m); } + void SetMin(int64_t m) override { interval_->SetDurationMin(m); } - int64 Max() const override { return interval_->DurationMax(); } + int64_t Max() const override { return interval_->DurationMax(); } - void SetMax(int64 m) override { interval_->SetDurationMax(m); } + void SetMax(int64_t m) override { interval_->SetDurationMax(m); } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { interval_->SetDurationRange(l, u); } - void SetValue(int64 v) override { interval_->SetDurationRange(v, v); } + void SetValue(int64_t v) override { interval_->SetDurationRange(v, v); } bool Bound() const override { return interval_->DurationMin() == interval_->DurationMax(); @@ -179,17 +182,17 @@ IntExpr* BuildEndExpr(IntervalVar* var) { return expr; } -IntExpr* BuildSafeStartExpr(IntervalVar* var, int64 unperformed_value) { +IntExpr* BuildSafeStartExpr(IntervalVar* var, int64_t unperformed_value) { return var->solver()->MakeConditionalExpression( var->PerformedExpr()->Var(), var->StartExpr(), unperformed_value); } -IntExpr* BuildSafeDurationExpr(IntervalVar* var, int64 unperformed_value) { +IntExpr* BuildSafeDurationExpr(IntervalVar* var, int64_t unperformed_value) { return var->solver()->MakeConditionalExpression( var->PerformedExpr()->Var(), var->DurationExpr(), unperformed_value); } -IntExpr* BuildSafeEndExpr(IntervalVar* var, int64 unperformed_value) { +IntExpr* BuildSafeEndExpr(IntervalVar* var, int64_t unperformed_value) { return var->solver()->MakeConditionalExpression( var->PerformedExpr()->Var(), var->EndExpr(), unperformed_value); } diff --git a/ortools/constraint_solver/sched_search.cc b/ortools/constraint_solver/sched_search.cc index 5472bbcff7..5efa917384 100644 --- a/ortools/constraint_solver/sched_search.cc +++ b/ortools/constraint_solver/sched_search.cc @@ -11,7 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include #include #include @@ -24,9 +26,9 @@ namespace operations_research { namespace { -int64 ValueToIndex(int64 value) { return value - 1; } +int64_t ValueToIndex(int64_t value) { return value - 1; } -int64 IndexToValue(int64 index) { return index + 1; } +int64_t IndexToValue(int64_t index) { return index + 1; } } // namespace // ----- SequenceVar ----- @@ -54,7 +56,7 @@ IntervalVar* SequenceVar::Interval(int index) const { IntVar* SequenceVar::Next(int index) const { return nexts_[index]; } std::string SequenceVar::DebugString() const { - int64 hmin, hmax, dmin, dmax; + int64_t hmin, hmax, dmin, dmax; HorizonRange(&hmin, &hmax); DurationRange(&dmin, &dmax); int unperformed = 0; @@ -72,9 +74,10 @@ void SequenceVar::Accept(ModelVisitor* const visitor) const { visitor->VisitSequenceVariable(this); } -void SequenceVar::DurationRange(int64* const dmin, int64* const dmax) const { - int64 dur_min = 0; - int64 dur_max = 0; +void SequenceVar::DurationRange(int64_t* const dmin, + int64_t* const dmax) const { + int64_t dur_min = 0; + int64_t dur_max = 0; for (int i = 0; i < intervals_.size(); ++i) { IntervalVar* const t = intervals_[i]; if (t->MayBePerformed()) { @@ -88,9 +91,9 @@ void SequenceVar::DurationRange(int64* const dmin, int64* const dmax) const { *dmax = dur_max; } -void SequenceVar::HorizonRange(int64* const hmin, int64* const hmax) const { - int64 hor_min = kint64max; - int64 hor_max = kint64min; +void SequenceVar::HorizonRange(int64_t* const hmin, int64_t* const hmax) const { + int64_t hor_min = std::numeric_limits::max(); + int64_t hor_max = std::numeric_limits::min(); for (int i = 0; i < intervals_.size(); ++i) { IntervalVar* const t = intervals_[i]; if (t->MayBePerformed()) { @@ -103,8 +106,8 @@ void SequenceVar::HorizonRange(int64* const hmin, int64* const hmax) const { *hmax = hor_max; } -void SequenceVar::ActiveHorizonRange(int64* const hmin, - int64* const hmax) const { +void SequenceVar::ActiveHorizonRange(int64_t* const hmin, + int64_t* const hmax) const { absl::flat_hash_set decided; for (int i = 0; i < intervals_.size(); ++i) { if (intervals_[i]->CannotBePerformed()) { @@ -128,8 +131,8 @@ void SequenceVar::ActiveHorizonRange(int64* const hmin, decided.insert(ValueToIndex(last)); } } - int64 hor_min = kint64max; - int64 hor_max = kint64min; + int64_t hor_min = std::numeric_limits::max(); + int64_t hor_max = std::numeric_limits::min(); for (int i = 0; i < intervals_.size(); ++i) { if (!gtl::ContainsKey(decided, i)) { IntervalVar* const t = intervals_[i]; @@ -207,9 +210,9 @@ void SequenceVar::ComputePossibleFirstsAndLasts( IntVar* const forward_var = nexts_[first]; std::vector candidates; - int64 smallest_start_max = kint64max; + int64_t smallest_start_max = std::numeric_limits::max(); int ssm_support = -1; - for (int64 i = forward_var->Min(); i <= forward_var->Max(); ++i) { + for (int64_t i = forward_var->Min(); i <= forward_var->Max(); ++i) { // TODO(user): use domain iterator. if (i != 0 && i < IndexToValue(intervals_.size()) && intervals_[ValueToIndex(i)]->MayBePerformed() && @@ -240,7 +243,7 @@ void SequenceVar::ComputePossibleFirstsAndLasts( } candidates.clear(); - int64 biggest_end_min = kint64min; + int64_t biggest_end_min = std::numeric_limits::min(); int bem_support = -1; for (const int candidate : to_check) { if (nexts_[IndexToValue(candidate)]->Contains(last)) { @@ -386,7 +389,7 @@ namespace { // class ScheduleOrPostpone : public Decision { public: - ScheduleOrPostpone(IntervalVar* const var, int64 est, int64* const marker) + ScheduleOrPostpone(IntervalVar* const var, int64_t est, int64_t* const marker) : var_(var), est_(est), marker_(marker) {} ~ScheduleOrPostpone() override {} @@ -414,20 +417,21 @@ class ScheduleOrPostpone : public Decision { private: IntervalVar* const var_; - NumericalRev est_; - int64* const marker_; + NumericalRev est_; + int64_t* const marker_; }; class SetTimesForward : public DecisionBuilder { public: explicit SetTimesForward(const std::vector& vars) - : vars_(vars), markers_(vars.size(), kint64min) {} + : vars_(vars), + markers_(vars.size(), std::numeric_limits::min()) {} ~SetTimesForward() override {} Decision* Next(Solver* const s) override { - int64 best_est = kint64max; - int64 best_lct = kint64max; + int64_t best_est = std::numeric_limits::max(); + int64_t best_lct = std::numeric_limits::max(); int support = -1; // We are looking for the interval that has the smallest start min // (tie break with smallest end max) and is not postponed. And @@ -446,7 +450,7 @@ class SetTimesForward : public DecisionBuilder { // TODO(user) : remove this crude quadratic loop with // reversibles range reduction. if (support == -1) { // All intervals are either fixed or postponed. - UnperformPostponedTaskBefore(kint64max); + UnperformPostponedTaskBefore(std::numeric_limits::max()); return nullptr; } UnperformPostponedTaskBefore(best_est); @@ -469,7 +473,7 @@ class SetTimesForward : public DecisionBuilder { return vars_[index]->StartMin() <= markers_[index]; } - void UnperformPostponedTaskBefore(int64 date) { + void UnperformPostponedTaskBefore(int64_t date) { for (int i = 0; i < vars_.size(); ++i) { IntervalVar* const v = vars_[i]; if (v->MayBePerformed() && v->StartMin() != v->StartMax() && @@ -488,7 +492,7 @@ class SetTimesForward : public DecisionBuilder { } const std::vector vars_; - std::vector markers_; + std::vector markers_; }; // @@ -496,7 +500,7 @@ class SetTimesForward : public DecisionBuilder { // class ScheduleOrExpedite : public Decision { public: - ScheduleOrExpedite(IntervalVar* const var, int64 est, int64* const marker) + ScheduleOrExpedite(IntervalVar* const var, int64_t est, int64_t* const marker) : var_(var), est_(est), marker_(marker) {} ~ScheduleOrExpedite() override {} @@ -524,20 +528,21 @@ class ScheduleOrExpedite : public Decision { private: IntervalVar* const var_; - NumericalRev est_; - int64* const marker_; + NumericalRev est_; + int64_t* const marker_; }; class SetTimesBackward : public DecisionBuilder { public: explicit SetTimesBackward(const std::vector& vars) - : vars_(vars), markers_(vars.size(), kint64max) {} + : vars_(vars), + markers_(vars.size(), std::numeric_limits::max()) {} ~SetTimesBackward() override {} Decision* Next(Solver* const s) override { - int64 best_end = kint64min; - int64 best_start = kint64min; + int64_t best_end = std::numeric_limits::min(); + int64_t best_start = std::numeric_limits::min(); int support = -1; int refuted = 0; for (int i = 0; i < vars_.size(); ++i) { @@ -578,7 +583,7 @@ class SetTimesBackward : public DecisionBuilder { private: const std::vector vars_; - std::vector markers_; + std::vector markers_; }; // ----- Decisions and DecisionBuilders on sequences ----- @@ -678,7 +683,7 @@ class RankFirstIntervalVars : public DecisionBuilder { SequenceVar* const best_sequence, int* const best_interval_index) { int best_interval = -1; - int64 best_start_min = kint64max; + int64_t best_start_min = std::numeric_limits::max(); for (int index = 0; index < best_possible_firsts_.size(); ++index) { const int candidate = best_possible_firsts_[index]; IntervalVar* const interval = best_sequence->Interval(candidate); @@ -722,8 +727,8 @@ class RankFirstIntervalVars : public DecisionBuilder { // Selects the sequence var to start ranking. bool FindSequenceVarOnSlack(Solver* const s, SequenceVar** const best_sequence) { - int64 best_slack = kint64max; - int64 best_ahmin = kint64max; + int64_t best_slack = std::numeric_limits::max(); + int64_t best_ahmin = std::numeric_limits::max(); *best_sequence = nullptr; best_possible_firsts_.clear(); for (int i = 0; i < sequences_.size(); ++i) { @@ -751,12 +756,12 @@ class RankFirstIntervalVars : public DecisionBuilder { } // Evaluating the sequence. - int64 hmin, hmax, dmin, dmax; + int64_t hmin, hmax, dmin, dmax; candidate_sequence->HorizonRange(&hmin, &hmax); candidate_sequence->DurationRange(&dmin, &dmax); - int64 ahmin, ahmax; + int64_t ahmin, ahmax; candidate_sequence->ActiveHorizonRange(&ahmin, &ahmax); - const int64 current_slack = (hmax - hmin - dmax); + const int64_t current_slack = (hmax - hmin - dmax); if (current_slack < best_slack || (current_slack == best_slack && ahmin < best_ahmin)) { best_slack = current_slack; @@ -831,15 +836,15 @@ class RankFirstIntervalVars : public DecisionBuilder { }; } // namespace -Decision* Solver::MakeScheduleOrPostpone(IntervalVar* const var, int64 est, - int64* const marker) { +Decision* Solver::MakeScheduleOrPostpone(IntervalVar* const var, int64_t est, + int64_t* const marker) { CHECK(var != nullptr); CHECK(marker != nullptr); return RevAlloc(new ScheduleOrPostpone(var, est, marker)); } -Decision* Solver::MakeScheduleOrExpedite(IntervalVar* const var, int64 est, - int64* const marker) { +Decision* Solver::MakeScheduleOrExpedite(IntervalVar* const var, int64_t est, + int64_t* const marker) { CHECK(var != nullptr); CHECK(marker != nullptr); return RevAlloc(new ScheduleOrExpedite(var, est, marker)); diff --git a/ortools/constraint_solver/search.cc b/ortools/constraint_solver/search.cc index 2a33245b1a..86da756b60 100644 --- a/ortools/constraint_solver/search.cc +++ b/ortools/constraint_solver/search.cc @@ -12,7 +12,9 @@ // limitations under the License. #include +#include #include +#include #include #include #include @@ -47,7 +49,7 @@ ABSL_FLAG(bool, cp_use_sparse_gls_penalties, false, ABSL_FLAG(bool, cp_log_to_vlog, false, "Whether search related logging should be " "vlog or info."); -ABSL_FLAG(int64, cp_large_domain_no_splitting_limit, 0xFFFFF, +ABSL_FLAG(int64_t, cp_large_domain_no_splitting_limit, 0xFFFFF, "Size limit to allow holes in variables from the strategy."); namespace operations_research { @@ -68,9 +70,9 @@ SearchLog::SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var, display_on_new_solutions_only_(display_on_new_solutions_only), nsol_(0), tick_(0), - objective_min_(kint64max), - objective_max_(kint64min), - min_right_depth_(kint32max), + objective_min_(std::numeric_limits::max()), + objective_max_(std::numeric_limits::min()), + min_right_depth_(std::numeric_limits::max()), max_depth_(0), sliding_min_depth_(0), sliding_max_depth_(0) { @@ -87,12 +89,12 @@ void SearchLog::EnterSearch() { absl::StrFormat("Start search (%s)", MemoryUsage()); OutputLine(buffer); timer_->Restart(); - min_right_depth_ = kint32max; + min_right_depth_ = std::numeric_limits::max(); } void SearchLog::ExitSearch() { - const int64 branches = solver()->branches(); - int64 ms = timer_->GetInMs(); + const int64_t branches = solver()->branches(); + int64_t ms = timer_->GetInMs(); if (ms == 0) { ms = 1; } @@ -107,9 +109,9 @@ bool SearchLog::AtSolution() { Maintain(); const int depth = solver()->SearchDepth(); std::string obj_str = ""; - int64 current = 0; + int64_t current = 0; bool objective_updated = false; - const auto scaled_str = [this](int64 value) { + const auto scaled_str = [this](int64_t value) { if (scaling_factor_ != 1.0 || offset_ != 0.0) { return absl::StrFormat("%d (%.8lf)", value, scaling_factor_ * (value + offset_)); @@ -199,7 +201,7 @@ void SearchLog::NoMoreSolutions() { void SearchLog::ApplyDecision(Decision* const decision) { Maintain(); - const int64 b = solver()->branches(); + const int64_t b = solver()->branches(); if (b % period_ == 0 && b > 0) { OutputDecision(); } @@ -214,7 +216,8 @@ void SearchLog::OutputDecision() { std::string buffer = absl::StrFormat("%d branches, %d ms, %d failures", solver()->branches(), timer_->GetInMs(), solver()->failures()); - if (min_right_depth_ != kint32max && max_depth_ != 0) { + if (min_right_depth_ != std::numeric_limits::max() && + max_depth_ != 0) { const int depth = solver()->SearchDepth(); absl::StrAppendFormat(&buffer, ", tree pos=%d/%d/%d minref=%d max=%d", sliding_min_depth_, depth, sliding_max_depth_, @@ -222,8 +225,9 @@ void SearchLog::OutputDecision() { sliding_min_depth_ = depth; sliding_max_depth_ = depth; } - if (obj_ != nullptr && objective_min_ != kint64max && - objective_max_ != kint64min) { + if (obj_ != nullptr && + objective_min_ != std::numeric_limits::max() && + objective_max_ != std::numeric_limits::min()) { absl::StrAppendFormat(&buffer, ", objective minimum = %d" ", objective maximum = %d", @@ -246,7 +250,7 @@ void SearchLog::Maintain() { void SearchLog::BeginInitialPropagation() { tick_ = timer_->GetInMs(); } void SearchLog::EndInitialPropagation() { - const int64 delta = std::max(timer_->GetInMs() - tick_, 0); + const int64_t delta = std::max(timer_->GetInMs() - tick_, 0); const std::string buffer = absl::StrFormat( "Root node processed (time = %d ms, constraints = %d, %s)", delta, solver()->constraints(), MemoryUsage()); @@ -262,11 +266,11 @@ void SearchLog::OutputLine(const std::string& line) { } std::string SearchLog::MemoryUsage() { - static const int64 kDisplayThreshold = 2; - static const int64 kKiloByte = 1024; - static const int64 kMegaByte = kKiloByte * kKiloByte; - static const int64 kGigaByte = kMegaByte * kKiloByte; - const int64 memory_usage = Solver::MemoryUsage(); + static const int64_t kDisplayThreshold = 2; + static const int64_t kKiloByte = 1024; + static const int64_t kMegaByte = kKiloByte * kKiloByte; + static const int64_t kGigaByte = kMegaByte * kKiloByte; + const int64_t memory_usage = Solver::MemoryUsage(); if (memory_usage > kDisplayThreshold * kGigaByte) { return absl::StrFormat("memory used = %.2lf GB", memory_usage * 1.0 / kGigaByte); @@ -747,13 +751,13 @@ class BaseVariableAssignmentSelector : public BaseObject { ~BaseVariableAssignmentSelector() override {} - virtual int64 SelectValue(const IntVar* v, int64 id) = 0; + virtual int64_t SelectValue(const IntVar* v, int64_t id) = 0; // Returns -1 if no variable are suitable. - virtual int64 ChooseVariable() = 0; + virtual int64_t ChooseVariable() = 0; - int64 ChooseVariableWrapper() { - int64 i; + int64_t ChooseVariableWrapper() { + int64_t i; for (i = first_unbound_.Value(); i <= last_unbound_.Value(); ++i) { if (!vars_[i]->Bound()) { break; @@ -784,15 +788,15 @@ class BaseVariableAssignmentSelector : public BaseObject { protected: Solver* const solver_; std::vector vars_; - Rev first_unbound_; - Rev last_unbound_; + Rev first_unbound_; + Rev last_unbound_; }; // ----- Choose first unbound -- -int64 ChooseFirstUnbound(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseFirstUnbound(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + for (int64_t i = first_unbound; i <= last_unbound; ++i) { if (!vars[i]->Bound()) { return i; } @@ -802,12 +806,12 @@ int64 ChooseFirstUnbound(Solver* solver, const std::vector& vars, // ----- Choose Min Size Lowest Min ----- -int64 ChooseMinSizeLowestMin(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = kuint64max; - int64 best_min = kint64max; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMinSizeLowestMin(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = std::numeric_limits::max(); + int64_t best_min = std::numeric_limits::max(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() < best_size || @@ -823,12 +827,13 @@ int64 ChooseMinSizeLowestMin(Solver* solver, const std::vector& vars, // ----- Choose Min Size Highest Min ----- -int64 ChooseMinSizeHighestMin(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = kuint64max; - int64 best_min = kint64min; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMinSizeHighestMin(Solver* solver, + const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = std::numeric_limits::max(); + int64_t best_min = std::numeric_limits::min(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() < best_size || @@ -844,12 +849,12 @@ int64 ChooseMinSizeHighestMin(Solver* solver, const std::vector& vars, // ----- Choose Min Size Lowest Max ----- -int64 ChooseMinSizeLowestMax(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = kuint64max; - int64 best_max = kint64max; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMinSizeLowestMax(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = std::numeric_limits::max(); + int64_t best_max = std::numeric_limits::max(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() < best_size || @@ -865,12 +870,13 @@ int64 ChooseMinSizeLowestMax(Solver* solver, const std::vector& vars, // ----- Choose Min Size Highest Max ----- -int64 ChooseMinSizeHighestMax(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = kuint64max; - int64 best_max = kint64min; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMinSizeHighestMax(Solver* solver, + const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = std::numeric_limits::max(); + int64_t best_max = std::numeric_limits::min(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() < best_size || @@ -886,11 +892,11 @@ int64 ChooseMinSizeHighestMax(Solver* solver, const std::vector& vars, // ----- Choose Lowest Min -- -int64 ChooseLowestMin(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - int64 best_min = kint64max; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseLowestMin(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + int64_t best_min = std::numeric_limits::max(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Min() < best_min) { @@ -904,11 +910,11 @@ int64 ChooseLowestMin(Solver* solver, const std::vector& vars, // ----- Choose Highest Max ----- -int64 ChooseHighestMax(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - int64 best_max = kint64min; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseHighestMax(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + int64_t best_max = std::numeric_limits::min(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Max() > best_max) { @@ -922,11 +928,11 @@ int64 ChooseHighestMax(Solver* solver, const std::vector& vars, // ----- Choose Lowest Size -- -int64 ChooseMinSize(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = kuint64max; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMinSize(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = std::numeric_limits::max(); + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() < best_size) { @@ -940,11 +946,11 @@ int64 ChooseMinSize(Solver* solver, const std::vector& vars, // ----- Choose Highest Size ----- -int64 ChooseMaxSize(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - uint64 best_size = 0; - int64 best_index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t ChooseMaxSize(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + uint64_t best_size = 0; + int64_t best_index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { if (var->Size() > best_size) { @@ -962,18 +968,18 @@ class HighestRegretSelectorOnMin : public BaseObject { public: explicit HighestRegretSelectorOnMin(const std::vector& vars) : iterators_(vars.size()) { - for (int64 i = 0; i < vars.size(); ++i) { + for (int64_t i = 0; i < vars.size(); ++i) { iterators_[i] = vars[i]->MakeDomainIterator(true); } } ~HighestRegretSelectorOnMin() override {} - int64 Choose(Solver* const s, const std::vector& vars, - int64 first_unbound, int64 last_unbound); + int64_t Choose(Solver* const s, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound); std::string DebugString() const override { return "MaxRegretSelector"; } - int64 ComputeRegret(IntVar* var, int64 index) const { + int64_t ComputeRegret(IntVar* var, int64_t index) const { DCHECK(!var->Bound()); - const int64 vmin = var->Min(); + const int64_t vmin = var->Min(); IntVarIterator* const iterator = iterators_[index]; iterator->Init(); iterator->Next(); @@ -984,16 +990,16 @@ class HighestRegretSelectorOnMin : public BaseObject { std::vector iterators_; }; -int64 HighestRegretSelectorOnMin::Choose(Solver* const s, - const std::vector& vars, - int64 first_unbound, - int64 last_unbound) { - int64 best_regret = 0; - int64 index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t HighestRegretSelectorOnMin::Choose(Solver* const s, + const std::vector& vars, + int64_t first_unbound, + int64_t last_unbound) { + int64_t best_regret = 0; + int64_t index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { IntVar* const var = vars[i]; if (!var->Bound()) { - const int64 regret = ComputeRegret(var, i); + const int64_t regret = ComputeRegret(var, i); if (regret > best_regret) { best_regret = regret; index = i; @@ -1005,12 +1011,12 @@ int64 HighestRegretSelectorOnMin::Choose(Solver* const s, // ----- Choose random unbound -- -int64 ChooseRandom(Solver* solver, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - const int64 span = last_unbound - first_unbound + 1; - const int64 shift = solver->Rand32(span); - for (int64 i = 0; i < span; ++i) { - const int64 index = (i + shift) % span + first_unbound; +int64_t ChooseRandom(Solver* solver, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + const int64_t span = last_unbound - first_unbound + 1; + const int64_t shift = solver->Rand32(span); + for (int64_t i = 0; i < span; ++i) { + const int64_t index = (i + shift) % span + first_unbound; if (!vars[index]->Bound()) { return index; } @@ -1022,25 +1028,26 @@ int64 ChooseRandom(Solver* solver, const std::vector& vars, class CheapestVarSelector : public BaseObject { public: - explicit CheapestVarSelector(std::function var_evaluator) + explicit CheapestVarSelector(std::function var_evaluator) : var_evaluator_(std::move(var_evaluator)) {} ~CheapestVarSelector() override {} - int64 Choose(Solver* const s, const std::vector& vars, - int64 first_unbound, int64 last_unbound); + int64_t Choose(Solver* const s, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound); std::string DebugString() const override { return "CheapestVarSelector"; } private: - std::function var_evaluator_; + std::function var_evaluator_; }; -int64 CheapestVarSelector::Choose(Solver* const s, - const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - int64 best_eval = kint64max; - int64 index = -1; - for (int64 i = first_unbound; i <= last_unbound; ++i) { +int64_t CheapestVarSelector::Choose(Solver* const s, + const std::vector& vars, + int64_t first_unbound, + int64_t last_unbound) { + int64_t best_eval = std::numeric_limits::max(); + int64_t index = -1; + for (int64_t i = first_unbound; i <= last_unbound; ++i) { if (!vars[i]->Bound()) { - const int64 eval = var_evaluator_(i); + const int64_t eval = var_evaluator_(i); if (eval < best_eval) { best_eval = eval; index = i; @@ -1055,26 +1062,26 @@ int64 CheapestVarSelector::Choose(Solver* const s, class PathSelector : public BaseObject { public: - PathSelector() : first_(kint64max) {} + PathSelector() : first_(std::numeric_limits::max()) {} ~PathSelector() override {} - int64 Choose(Solver* const s, const std::vector& vars, - int64 first_unbound, int64 last_unbound); + int64_t Choose(Solver* const s, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound); std::string DebugString() const override { return "ChooseNextOnPath"; } private: - bool UpdateIndex(const std::vector& vars, int64* index) const; - bool FindPathStart(const std::vector& vars, int64* index) const; + bool UpdateIndex(const std::vector& vars, int64_t* index) const; + bool FindPathStart(const std::vector& vars, int64_t* index) const; - Rev first_; + Rev first_; }; -int64 PathSelector::Choose(Solver* const s, const std::vector& vars, - int64 first_unbound, int64 last_unbound) { - int64 index = first_.Value(); +int64_t PathSelector::Choose(Solver* const s, const std::vector& vars, + int64_t first_unbound, int64_t last_unbound) { + int64_t index = first_.Value(); if (!UpdateIndex(vars, &index)) { return -1; } - int64 count = 0; + int64_t count = 0; while (vars[index]->Bound()) { index = vars[index]->Value(); if (!UpdateIndex(vars, &index)) { @@ -1091,7 +1098,7 @@ int64 PathSelector::Choose(Solver* const s, const std::vector& vars, } bool PathSelector::UpdateIndex(const std::vector& vars, - int64* index) const { + int64_t* index) const { if (*index >= vars.size()) { if (!FindPathStart(vars, index)) { return false; @@ -1107,11 +1114,11 @@ bool PathSelector::UpdateIndex(const std::vector& vars, // an unbound variable, to which no other variable can point. // 3. If everything else fails, pick the first unbound variable. bool PathSelector::FindPathStart(const std::vector& vars, - int64* index) const { + int64_t* index) const { // Try to extend an existing path - for (int64 i = vars.size() - 1; i >= 0; --i) { + for (int64_t i = vars.size() - 1; i >= 0; --i) { if (vars[i]->Bound()) { - const int64 next = vars[i]->Value(); + const int64_t next = vars[i]->Value(); if (next < vars.size() && !vars[next]->Bound()) { *index = next; return true; @@ -1119,10 +1126,10 @@ bool PathSelector::FindPathStart(const std::vector& vars, } } // Pick path start - for (int64 i = vars.size() - 1; i >= 0; --i) { + for (int64_t i = vars.size() - 1; i >= 0; --i) { if (!vars[i]->Bound()) { bool has_possible_prev = false; - for (int64 j = 0; j < vars.size(); ++j) { + for (int64_t j = 0; j < vars.size(); ++j) { if (vars[j]->Contains(i)) { has_possible_prev = true; break; @@ -1135,7 +1142,7 @@ bool PathSelector::FindPathStart(const std::vector& vars, } } // Pick first unbound - for (int64 i = 0; i < vars.size(); ++i) { + for (int64_t i = 0; i < vars.size(); ++i) { if (!vars[i]->Bound()) { *index = i; return true; @@ -1146,34 +1153,34 @@ bool PathSelector::FindPathStart(const std::vector& vars, // ----- Select min ----- -int64 SelectMinValue(const IntVar* v, int64 id) { return v->Min(); } +int64_t SelectMinValue(const IntVar* v, int64_t id) { return v->Min(); } // ----- Select max ----- -int64 SelectMaxValue(const IntVar* v, int64 id) { return v->Max(); } +int64_t SelectMaxValue(const IntVar* v, int64_t id) { return v->Max(); } // ----- Select random ----- -int64 SelectRandomValue(const IntVar* v, int64 id) { - const uint64 span = v->Max() - v->Min() + 1; +int64_t SelectRandomValue(const IntVar* v, int64_t id) { + const uint64_t span = v->Max() - v->Min() + 1; if (span > absl::GetFlag(FLAGS_cp_large_domain_no_splitting_limit)) { // Do not create holes in large domains. return v->Min(); } - const uint64 size = v->Size(); + const uint64_t size = v->Size(); Solver* const s = v->solver(); if (size > span / 4) { // Dense enough, we can try to find the // value randomly. for (;;) { - const int64 value = v->Min() + s->Rand64(span); + const int64_t value = v->Min() + s->Rand64(span); if (v->Contains(value)) { return value; } } } else { // Not dense enough, we will count. - int64 index = s->Rand64(size); + int64_t index = s->Rand64(size); if (index <= size / 2) { - for (int64 i = v->Min(); i <= v->Max(); ++i) { + for (int64_t i = v->Min(); i <= v->Max(); ++i) { if (v->Contains(i)) { if (--index == 0) { return i; @@ -1182,7 +1189,7 @@ int64 SelectRandomValue(const IntVar* v, int64 id) { } CHECK_LE(index, 0); } else { - for (int64 i = v->Max(); i > v->Min(); --i) { + for (int64_t i = v->Max(); i > v->Min(); --i) { if (v->Contains(i)) { if (--index == 0) { return i; @@ -1197,19 +1204,19 @@ int64 SelectRandomValue(const IntVar* v, int64 id) { // ----- Select center ----- -int64 SelectCenterValue(const IntVar* v, int64 id) { - const int64 vmin = v->Min(); - const int64 vmax = v->Max(); +int64_t SelectCenterValue(const IntVar* v, int64_t id) { + const int64_t vmin = v->Min(); + const int64_t vmax = v->Max(); if (vmax - vmin > absl::GetFlag(FLAGS_cp_large_domain_no_splitting_limit)) { // Do not create holes in large domains. return vmin; } - const int64 mid = (vmin + vmax) / 2; + const int64_t mid = (vmin + vmax) / 2; if (v->Contains(mid)) { return mid; } - const int64 diameter = vmax - mid; // always greater than mid - vmix. - for (int64 i = 1; i <= diameter; ++i) { + const int64_t diameter = vmax - mid; // always greater than mid - vmix. + for (int64_t i = 1; i <= diameter; ++i) { if (v->Contains(mid - i)) { return mid - i; } @@ -1222,11 +1229,11 @@ int64 SelectCenterValue(const IntVar* v, int64 id) { // ----- Select center ----- -int64 SelectSplitValue(const IntVar* v, int64 id) { - const int64 vmin = v->Min(); - const int64 vmax = v->Max(); - const uint64 delta = vmax - vmin; - const int64 mid = vmin + delta / 2; +int64_t SelectSplitValue(const IntVar* v, int64_t id) { + const int64_t vmin = v->Min(); + const int64_t vmax = v->Max(); + const uint64_t delta = vmax - vmin; + const int64_t mid = vmin + delta / 2; return mid; } @@ -1234,25 +1241,25 @@ int64 SelectSplitValue(const IntVar* v, int64 id) { class CheapestValueSelector : public BaseObject { public: - CheapestValueSelector(std::function eval, - std::function tie_breaker) + CheapestValueSelector(std::function eval, + std::function tie_breaker) : eval_(std::move(eval)), tie_breaker_(std::move(tie_breaker)) {} ~CheapestValueSelector() override {} - int64 Select(const IntVar* v, int64 id); + int64_t Select(const IntVar* v, int64_t id); std::string DebugString() const override { return "CheapestValue"; } private: - std::function eval_; - std::function tie_breaker_; - std::vector cache_; + std::function eval_; + std::function tie_breaker_; + std::vector cache_; }; -int64 CheapestValueSelector::Select(const IntVar* v, int64 id) { +int64_t CheapestValueSelector::Select(const IntVar* v, int64_t id) { cache_.clear(); - int64 best = kint64max; + int64_t best = std::numeric_limits::max(); std::unique_ptr it(v->MakeDomainIterator(false)); - for (const int64 i : InitAndGetValues(it.get())) { - int64 eval = eval_(id, i); + for (const int64_t i : InitAndGetValues(it.get())) { + int64_t eval = eval_(id, i); if (eval < best) { best = eval; cache_.clear(); @@ -1283,7 +1290,7 @@ class BestValueByComparisonSelector : public BaseObject { Solver::VariableValueComparator comparator) : comparator_(std::move(comparator)) {} ~BestValueByComparisonSelector() override {} - int64 Select(const IntVar* v, int64 id); + int64_t Select(const IntVar* v, int64_t id); std::string DebugString() const override { return "BestValueByComparisonSelector"; } @@ -1292,13 +1299,13 @@ class BestValueByComparisonSelector : public BaseObject { Solver::VariableValueComparator comparator_; }; -int64 BestValueByComparisonSelector::Select(const IntVar* v, int64 id) { +int64_t BestValueByComparisonSelector::Select(const IntVar* v, int64_t id) { std::unique_ptr it(v->MakeDomainIterator(false)); it->Init(); DCHECK(it->Ok()); // At least one value. - int64 best_value = it->Value(); + int64_t best_value = it->Value(); for (it->Next(); it->Ok(); it->Next()) { - const int64 candidate_value = it->Value(); + const int64_t candidate_value = it->Value(); if (comparator_(id, candidate_value, best_value)) { best_value = candidate_value; } @@ -1319,10 +1326,10 @@ class VariableAssignmentSelector : public BaseVariableAssignmentSelector { value_selector_(std::move(value_selector)), name_(name) {} ~VariableAssignmentSelector() override {} - int64 SelectValue(const IntVar* var, int64 id) override { + int64_t SelectValue(const IntVar* var, int64_t id) override { return value_selector_(var, id); } - int64 ChooseVariable() override { + int64_t ChooseVariable() override { return var_selector_(solver_, vars_, first_unbound_.Value(), last_unbound_.Value()); } @@ -1343,27 +1350,27 @@ std::string VariableAssignmentSelector::DebugString() const { class BaseEvaluatorSelector : public BaseVariableAssignmentSelector { public: BaseEvaluatorSelector(Solver* solver, const std::vector& vars, - std::function evaluator); + std::function evaluator); ~BaseEvaluatorSelector() override {} protected: struct Element { Element() : var(0), value(0) {} - Element(int64 i, int64 j) : var(i), value(j) {} - int64 var; - int64 value; + Element(int64_t i, int64_t j) : var(i), value(j) {} + int64_t var; + int64_t value; }; std::string DebugStringInternal(const std::string& name) const { return absl::StrFormat("%s(%s)", name, JoinDebugStringPtr(vars_, ", ")); } - std::function evaluator_; + std::function evaluator_; }; BaseEvaluatorSelector::BaseEvaluatorSelector( Solver* solver, const std::vector& vars, - std::function evaluator) + std::function evaluator) : BaseVariableAssignmentSelector(solver, vars), evaluator_(std::move(evaluator)) {} @@ -1372,40 +1379,40 @@ BaseEvaluatorSelector::BaseEvaluatorSelector( class DynamicEvaluatorSelector : public BaseEvaluatorSelector { public: DynamicEvaluatorSelector(Solver* solver, const std::vector& vars, - std::function evaluator, - std::function tie_breaker); + std::function evaluator, + std::function tie_breaker); ~DynamicEvaluatorSelector() override {} - int64 SelectValue(const IntVar* var, int64 id) override; - int64 ChooseVariable() override; + int64_t SelectValue(const IntVar* var, int64_t id) override; + int64_t ChooseVariable() override; std::string DebugString() const override; private: - int64 first_; - std::function tie_breaker_; + int64_t first_; + std::function tie_breaker_; std::vector cache_; }; DynamicEvaluatorSelector::DynamicEvaluatorSelector( Solver* solver, const std::vector& vars, - std::function evaluator, - std::function tie_breaker) + std::function evaluator, + std::function tie_breaker) : BaseEvaluatorSelector(solver, vars, std::move(evaluator)), first_(-1), tie_breaker_(std::move(tie_breaker)) {} -int64 DynamicEvaluatorSelector::SelectValue(const IntVar* var, int64 id) { +int64_t DynamicEvaluatorSelector::SelectValue(const IntVar* var, int64_t id) { return cache_[first_].value; } -int64 DynamicEvaluatorSelector::ChooseVariable() { - int64 best_evaluation = kint64max; +int64_t DynamicEvaluatorSelector::ChooseVariable() { + int64_t best_evaluation = std::numeric_limits::max(); cache_.clear(); - for (int64 i = 0; i < vars_.size(); ++i) { + for (int64_t i = 0; i < vars_.size(); ++i) { const IntVar* const var = vars_[i]; if (!var->Bound()) { std::unique_ptr it(var->MakeDomainIterator(false)); - for (const int64 j : InitAndGetValues(it.get())) { - const int64 value = evaluator_(i, j); + for (const int64_t j : InitAndGetValues(it.get())) { + const int64_t value = evaluator_(i, j); if (value < best_evaluation) { best_evaluation = value; cache_.clear(); @@ -1438,55 +1445,56 @@ std::string DynamicEvaluatorSelector::DebugString() const { class StaticEvaluatorSelector : public BaseEvaluatorSelector { public: - StaticEvaluatorSelector(Solver* solver, const std::vector& vars, - const std::function& evaluator); + StaticEvaluatorSelector( + Solver* solver, const std::vector& vars, + const std::function& evaluator); ~StaticEvaluatorSelector() override {} - int64 SelectValue(const IntVar* var, int64 id) override; - int64 ChooseVariable() override; + int64_t SelectValue(const IntVar* var, int64_t id) override; + int64_t ChooseVariable() override; std::string DebugString() const override; private: class Compare { public: - explicit Compare(std::function evaluator) + explicit Compare(std::function evaluator) : evaluator_(std::move(evaluator)) {} bool operator()(const Element& lhs, const Element& rhs) const { - const int64 value_lhs = Value(lhs); - const int64 value_rhs = Value(rhs); + const int64_t value_lhs = Value(lhs); + const int64_t value_rhs = Value(rhs); return value_lhs < value_rhs || (value_lhs == value_rhs && (lhs.var < rhs.var || (lhs.var == rhs.var && lhs.value < rhs.value))); } - int64 Value(const Element& element) const { + int64_t Value(const Element& element) const { return evaluator_(element.var, element.value); } private: - std::function evaluator_; + std::function evaluator_; }; Compare comp_; std::vector elements_; - int64 first_; + int64_t first_; }; StaticEvaluatorSelector::StaticEvaluatorSelector( Solver* solver, const std::vector& vars, - const std::function& evaluator) + const std::function& evaluator) : BaseEvaluatorSelector(solver, vars, evaluator), comp_(evaluator), first_(-1) {} -int64 StaticEvaluatorSelector::SelectValue(const IntVar* var, int64 id) { +int64_t StaticEvaluatorSelector::SelectValue(const IntVar* var, int64_t id) { return elements_[first_].value; } -int64 StaticEvaluatorSelector::ChooseVariable() { +int64_t StaticEvaluatorSelector::ChooseVariable() { if (first_ == -1) { // first call to select. update assignment costs // Two phases: compute size then filland sort - int64 element_size = 0; - for (int64 i = 0; i < vars_.size(); ++i) { + int64_t element_size = 0; + for (int64_t i = 0; i < vars_.size(); ++i) { if (!vars_[i]->Bound()) { element_size += vars_[i]->Size(); } @@ -1497,16 +1505,16 @@ int64 StaticEvaluatorSelector::ChooseVariable() { const IntVar* const var = vars_[i]; if (!var->Bound()) { std::unique_ptr it(var->MakeDomainIterator(false)); - for (const int64 value : InitAndGetValues(it.get())) { + for (const int64_t value : InitAndGetValues(it.get())) { elements_[count++] = Element(i, value); } } } // Sort is stable here given the tie-breaking rules in comp_. std::sort(elements_.begin(), elements_.end(), comp_); - solver_->SaveAndSetValue(&first_, 0); + solver_->SaveAndSetValue(&first_, 0); } - for (int64 i = first_; i < elements_.size(); ++i) { + for (int64_t i = first_; i < elements_.size(); ++i) { const Element& element = elements_[i]; IntVar* const var = vars_[element.var]; if (!var->Bound() && var->Contains(element.value)) { @@ -1514,7 +1522,7 @@ int64 StaticEvaluatorSelector::ChooseVariable() { return element.var; } } - solver_->SaveAndSetValue(&first_, static_cast(elements_.size())); + solver_->SaveAndSetValue(&first_, static_cast(elements_.size())); return -1; } @@ -1526,7 +1534,7 @@ std::string StaticEvaluatorSelector::DebugString() const { class AssignOneVariableValue : public Decision { public: - AssignOneVariableValue(IntVar* const v, int64 val); + AssignOneVariableValue(IntVar* const v, int64_t val); ~AssignOneVariableValue() override {} void Apply(Solver* const s) override; void Refute(Solver* const s) override; @@ -1537,10 +1545,10 @@ class AssignOneVariableValue : public Decision { private: IntVar* const var_; - int64 value_; + int64_t value_; }; -AssignOneVariableValue::AssignOneVariableValue(IntVar* const v, int64 val) +AssignOneVariableValue::AssignOneVariableValue(IntVar* const v, int64_t val) : var_(v), value_(val) {} std::string AssignOneVariableValue::DebugString() const { @@ -1555,7 +1563,7 @@ void AssignOneVariableValue::Refute(Solver* const s) { } } // namespace -Decision* Solver::MakeAssignVariableValue(IntVar* const var, int64 val) { +Decision* Solver::MakeAssignVariableValue(IntVar* const var, int64_t val) { return RevAlloc(new AssignOneVariableValue(var, val)); } @@ -1564,7 +1572,7 @@ Decision* Solver::MakeAssignVariableValue(IntVar* const var, int64 val) { namespace { class AssignOneVariableValueOrFail : public Decision { public: - AssignOneVariableValueOrFail(IntVar* const v, int64 value); + AssignOneVariableValueOrFail(IntVar* const v, int64_t value); ~AssignOneVariableValueOrFail() override {} void Apply(Solver* const s) override; void Refute(Solver* const s) override; @@ -1575,11 +1583,11 @@ class AssignOneVariableValueOrFail : public Decision { private: IntVar* const var_; - const int64 value_; + const int64_t value_; }; AssignOneVariableValueOrFail::AssignOneVariableValueOrFail(IntVar* const v, - int64 value) + int64_t value) : var_(v), value_(value) {} std::string AssignOneVariableValueOrFail::DebugString() const { @@ -1594,7 +1602,7 @@ void AssignOneVariableValueOrFail::Refute(Solver* const s) { s->Fail(); } } // namespace Decision* Solver::MakeAssignVariableValueOrFail(IntVar* const var, - int64 value) { + int64_t value) { return RevAlloc(new AssignOneVariableValueOrFail(var, value)); } @@ -1603,7 +1611,7 @@ Decision* Solver::MakeAssignVariableValueOrFail(IntVar* const var, namespace { class AssignOneVariableValueDoNothing : public Decision { public: - AssignOneVariableValueDoNothing(IntVar* const v, int64 value) + AssignOneVariableValueDoNothing(IntVar* const v, int64_t value) : var_(v), value_(value) {} ~AssignOneVariableValueDoNothing() override {} void Apply(Solver* const s) override { var_->SetValue(value_); } @@ -1617,13 +1625,13 @@ class AssignOneVariableValueDoNothing : public Decision { private: IntVar* const var_; - const int64 value_; + const int64_t value_; }; } // namespace Decision* Solver::MakeAssignVariableValueOrDoNothing(IntVar* const var, - int64 value) { + int64_t value) { return RevAlloc(new AssignOneVariableValueDoNothing(var, value)); } @@ -1632,7 +1640,7 @@ Decision* Solver::MakeAssignVariableValueOrDoNothing(IntVar* const var, namespace { class SplitOneVariable : public Decision { public: - SplitOneVariable(IntVar* const v, int64 val, bool start_with_lower_half); + SplitOneVariable(IntVar* const v, int64_t val, bool start_with_lower_half); ~SplitOneVariable() override {} void Apply(Solver* const s) override; void Refute(Solver* const s) override; @@ -1643,11 +1651,11 @@ class SplitOneVariable : public Decision { private: IntVar* const var_; - const int64 value_; + const int64_t value_; const bool start_with_lower_half_; }; -SplitOneVariable::SplitOneVariable(IntVar* const v, int64 val, +SplitOneVariable::SplitOneVariable(IntVar* const v, int64_t val, bool start_with_lower_half) : var_(v), value_(val), start_with_lower_half_(start_with_lower_half) {} @@ -1676,17 +1684,18 @@ void SplitOneVariable::Refute(Solver* const s) { } } // namespace -Decision* Solver::MakeSplitVariableDomain(IntVar* const var, int64 val, +Decision* Solver::MakeSplitVariableDomain(IntVar* const var, int64_t val, bool start_with_lower_half) { return RevAlloc(new SplitOneVariable(var, val, start_with_lower_half)); } -Decision* Solver::MakeVariableLessOrEqualValue(IntVar* const var, int64 value) { +Decision* Solver::MakeVariableLessOrEqualValue(IntVar* const var, + int64_t value) { return MakeSplitVariableDomain(var, value, true); } Decision* Solver::MakeVariableGreaterOrEqualValue(IntVar* const var, - int64 value) { + int64_t value) { return MakeSplitVariableDomain(var, value, false); } @@ -1696,7 +1705,7 @@ namespace { class AssignVariablesValues : public Decision { public: AssignVariablesValues(const std::vector& vars, - const std::vector& values); + const std::vector& values); ~AssignVariablesValues() override {} void Apply(Solver* const s) override; void Refute(Solver* const s) override; @@ -1716,11 +1725,11 @@ class AssignVariablesValues : public Decision { private: const std::vector vars_; - const std::vector values_; + const std::vector values_; }; AssignVariablesValues::AssignVariablesValues(const std::vector& vars, - const std::vector& values) + const std::vector& values) : vars_(vars), values_(values) {} std::string AssignVariablesValues::DebugString() const { @@ -1749,8 +1758,8 @@ void AssignVariablesValues::Refute(Solver* const s) { } } // namespace -Decision* Solver::MakeAssignVariablesValues(const std::vector& vars, - const std::vector& values) { +Decision* Solver::MakeAssignVariablesValues( + const std::vector& vars, const std::vector& values) { CHECK_EQ(vars.size(), values.size()); return RevAlloc(new AssignVariablesValues(vars, values)); } @@ -1864,7 +1873,7 @@ Decision* BaseAssignVariables::Next(Solver* const s) { int id = selector_->ChooseVariableWrapper(); if (id >= 0 && id < vars.size()) { IntVar* const var = vars[id]; - const int64 value = selector_->SelectValue(var, id); + const int64_t value = selector_->SelectValue(var, id); switch (mode_) { case ASSIGN: return s->RevAlloc(new AssignOneVariableValue(var, value)); @@ -2043,7 +2052,7 @@ DecisionBuilder* Solver::MakePhase(const std::vector& vars, CheapestValueSelector* const value_selector = RevAlloc(new CheapestValueSelector(std::move(value_evaluator), nullptr)); Solver::VariableValueSelector select_value = - [value_selector](const IntVar* var, int64 id) { + [value_selector](const IntVar* var, int64_t id) { return value_selector->Select(var, id); }; const std::string name = ChooseVariableName(var_str) + "_SelectCheapestValue"; @@ -2060,7 +2069,7 @@ DecisionBuilder* Solver::MakePhase( BestValueByComparisonSelector* const value_selector = RevAlloc( new BestValueByComparisonSelector(std::move(var_val1_val2_comparator))); Solver::VariableValueSelector select_value = - [value_selector](const IntVar* var, int64 id) { + [value_selector](const IntVar* var, int64_t id) { return value_selector->Select(var, id); }; return BaseAssignVariables::MakePhase(this, vars, choose_variable, @@ -2081,7 +2090,7 @@ DecisionBuilder* Solver::MakePhase(const std::vector& vars, CheapestValueSelector* value_selector = RevAlloc(new CheapestValueSelector(std::move(value_evaluator), nullptr)); Solver::VariableValueSelector select_value = - [value_selector](const IntVar* var, int64 id) { + [value_selector](const IntVar* var, int64_t id) { return value_selector->Select(var, id); }; return BaseAssignVariables::MakePhase(this, vars, choose_variable, @@ -2098,7 +2107,7 @@ DecisionBuilder* Solver::MakePhase(const std::vector& vars, CheapestValueSelector* value_selector = RevAlloc(new CheapestValueSelector( std::move(value_evaluator), std::move(tie_breaker))); Solver::VariableValueSelector select_value = - [value_selector](const IntVar* var, int64 id) { + [value_selector](const IntVar* var, int64_t id) { return value_selector->Select(var, id); }; return BaseAssignVariables::MakePhase(this, vars, choose_variable, @@ -2120,7 +2129,7 @@ DecisionBuilder* Solver::MakePhase(const std::vector& vars, CheapestValueSelector* value_selector = RevAlloc(new CheapestValueSelector( std::move(value_evaluator), std::move(tie_breaker))); Solver::VariableValueSelector select_value = - [value_selector](const IntVar* var, int64 id) { + [value_selector](const IntVar* var, int64_t id) { return value_selector->Select(var, id); }; return BaseAssignVariables::MakePhase(this, vars, choose_variable, @@ -2324,43 +2333,43 @@ Assignment* SolutionCollector::solution(int n) const { int SolutionCollector::solution_count() const { return solution_data_.size(); } -int64 SolutionCollector::wall_time(int n) const { +int64_t SolutionCollector::wall_time(int n) const { check_index(n); return solution_data_[n].time; } -int64 SolutionCollector::branches(int n) const { +int64_t SolutionCollector::branches(int n) const { check_index(n); return solution_data_[n].branches; } -int64 SolutionCollector::failures(int n) const { +int64_t SolutionCollector::failures(int n) const { check_index(n); return solution_data_[n].failures; } -int64 SolutionCollector::objective_value(int n) const { +int64_t SolutionCollector::objective_value(int n) const { check_index(n); return solution_data_[n].objective_value; } -int64 SolutionCollector::Value(int n, IntVar* const var) const { +int64_t SolutionCollector::Value(int n, IntVar* const var) const { return solution(n)->Value(var); } -int64 SolutionCollector::StartValue(int n, IntervalVar* const var) const { +int64_t SolutionCollector::StartValue(int n, IntervalVar* const var) const { return solution(n)->StartValue(var); } -int64 SolutionCollector::DurationValue(int n, IntervalVar* const var) const { +int64_t SolutionCollector::DurationValue(int n, IntervalVar* const var) const { return solution(n)->DurationValue(var); } -int64 SolutionCollector::EndValue(int n, IntervalVar* const var) const { +int64_t SolutionCollector::EndValue(int n, IntervalVar* const var) const { return solution(n)->EndValue(var); } -int64 SolutionCollector::PerformedValue(int n, IntervalVar* const var) const { +int64_t SolutionCollector::PerformedValue(int n, IntervalVar* const var) const { return solution(n)->PerformedValue(var); } @@ -2497,24 +2506,27 @@ class BestValueSolutionCollector : public SolutionCollector { public: const bool maximize_; - int64 best_; + int64_t best_; }; BestValueSolutionCollector::BestValueSolutionCollector( Solver* const s, const Assignment* const a, bool maximize) : SolutionCollector(s, a), maximize_(maximize), - best_(maximize ? kint64min : kint64max) {} + best_(maximize ? std::numeric_limits::min() + : std::numeric_limits::max()) {} BestValueSolutionCollector::BestValueSolutionCollector(Solver* const s, bool maximize) : SolutionCollector(s), maximize_(maximize), - best_(maximize ? kint64min : kint64max) {} + best_(maximize ? std::numeric_limits::min() + : std::numeric_limits::max()) {} void BestValueSolutionCollector::EnterSearch() { SolutionCollector::EnterSearch(); - best_ = maximize_ ? kint64min : kint64max; + best_ = maximize_ ? std::numeric_limits::min() + : std::numeric_limits::max(); } bool BestValueSolutionCollector::AtSolution() { @@ -2574,7 +2586,7 @@ class NBestValueSolutionCollector : public SolutionCollector { void Clear(); const bool maximize_; - std::priority_queue> solutions_pq_; + std::priority_queue> solutions_pq_; const int solution_count_; }; @@ -2613,7 +2625,7 @@ bool NBestValueSolutionCollector::AtSolution() { if (prototype_ != nullptr) { const IntVar* objective = prototype_->Objective(); if (objective != nullptr) { - const int64 objective_value = + const int64_t objective_value = maximize_ ? CapSub(0, objective->Max()) : objective->Min(); if (solutions_pq_.size() < solution_count_) { solutions_pq_.push( @@ -2715,11 +2727,11 @@ SolutionCollector* Solver::MakeAllSolutionCollector() { // ---------- Objective Management ---------- OptimizeVar::OptimizeVar(Solver* const s, bool maximize, IntVar* const a, - int64 step) + int64_t step) : SearchMonitor(s), var_(a), step_(step), - best_(kint64max), + best_(std::numeric_limits::max()), maximize_(maximize), found_initial_solution_(false) { CHECK_GT(step_, 0); @@ -2738,9 +2750,9 @@ OptimizeVar::~OptimizeVar() {} void OptimizeVar::EnterSearch() { found_initial_solution_ = false; if (maximize_) { - best_ = kint64min; + best_ = std::numeric_limits::min(); } else { - best_ = kint64max; + best_ = std::numeric_limits::max(); } } @@ -2763,7 +2775,7 @@ void OptimizeVar::ApplyBound() { void OptimizeVar::RefuteDecision(Decision* const d) { ApplyBound(); } bool OptimizeVar::AcceptSolution() { - const int64 val = var_->Value(); + const int64_t val = var_->Value(); if (!found_initial_solution_) { return true; } else { @@ -2775,7 +2787,7 @@ bool OptimizeVar::AcceptSolution() { } bool OptimizeVar::AtSolution() { - int64 val = var_->Value(); + int64_t val = var_->Value(); if (maximize_) { CHECK(!found_initial_solution_ || val > best_); best_ = val; @@ -2797,22 +2809,24 @@ bool OptimizeVar::AcceptDelta(Assignment* delta, Assignment* deltadelta) { const Assignment* const local_search_state = solver()->GetOrCreateLocalSearchState(); if (maximize_) { - const int64 delta_min_objective = - delta_has_objective ? delta->ObjectiveMin() : kint64min; - const int64 min_objective = + const int64_t delta_min_objective = + delta_has_objective ? delta->ObjectiveMin() + : std::numeric_limits::min(); + const int64_t min_objective = local_search_state->HasObjective() ? CapAdd(local_search_state->ObjectiveMin(), step_) - : kint64min; + : std::numeric_limits::min(); delta->SetObjectiveMin( std::max({var_->Min(), min_objective, delta_min_objective})); } else { - const int64 delta_max_objective = - delta_has_objective ? delta->ObjectiveMax() : kint64max; - const int64 max_objective = + const int64_t delta_max_objective = + delta_has_objective ? delta->ObjectiveMax() + : std::numeric_limits::max(); + const int64_t max_objective = local_search_state->HasObjective() ? CapSub(local_search_state->ObjectiveMax(), step_) - : kint64max; + : std::numeric_limits::max(); delta->SetObjectiveMax( std::min({var_->Max(), max_objective, delta_max_objective})); } @@ -2846,15 +2860,16 @@ void OptimizeVar::Accept(ModelVisitor* const visitor) const { visitor->EndVisitExtension(ModelVisitor::kObjectiveExtension); } -OptimizeVar* Solver::MakeMinimize(IntVar* const v, int64 step) { +OptimizeVar* Solver::MakeMinimize(IntVar* const v, int64_t step) { return RevAlloc(new OptimizeVar(this, false, v, step)); } -OptimizeVar* Solver::MakeMaximize(IntVar* const v, int64 step) { +OptimizeVar* Solver::MakeMaximize(IntVar* const v, int64_t step) { return RevAlloc(new OptimizeVar(this, true, v, step)); } -OptimizeVar* Solver::MakeOptimize(bool maximize, IntVar* const v, int64 step) { +OptimizeVar* Solver::MakeOptimize(bool maximize, IntVar* const v, + int64_t step) { return RevAlloc(new OptimizeVar(this, maximize, v, step)); } @@ -2863,7 +2878,7 @@ class WeightedOptimizeVar : public OptimizeVar { public: WeightedOptimizeVar(Solver* solver, bool maximize, const std::vector& sub_objectives, - const std::vector& weights, int64 step) + const std::vector& weights, int64_t step) : OptimizeVar(solver, maximize, solver->MakeScalProd(sub_objectives, weights)->Var(), step), sub_objectives_(sub_objectives), @@ -2876,7 +2891,7 @@ class WeightedOptimizeVar : public OptimizeVar { private: const std::vector sub_objectives_; - const std::vector weights_; + const std::vector weights_; DISALLOW_COPY_AND_ASSIGN(WeightedOptimizeVar); }; @@ -2895,41 +2910,41 @@ std::string WeightedOptimizeVar::Print() const { OptimizeVar* Solver::MakeWeightedOptimize( bool maximize, const std::vector& sub_objectives, - const std::vector& weights, int64 step) { + const std::vector& weights, int64_t step) { return RevAlloc( new WeightedOptimizeVar(this, maximize, sub_objectives, weights, step)); } OptimizeVar* Solver::MakeWeightedMinimize( const std::vector& sub_objectives, - const std::vector& weights, int64 step) { + const std::vector& weights, int64_t step) { return RevAlloc( new WeightedOptimizeVar(this, false, sub_objectives, weights, step)); } OptimizeVar* Solver::MakeWeightedMaximize( const std::vector& sub_objectives, - const std::vector& weights, int64 step) { + const std::vector& weights, int64_t step) { return RevAlloc( new WeightedOptimizeVar(this, true, sub_objectives, weights, step)); } OptimizeVar* Solver::MakeWeightedOptimize( bool maximize, const std::vector& sub_objectives, - const std::vector& weights, int64 step) { + const std::vector& weights, int64_t step) { return MakeWeightedOptimize(maximize, sub_objectives, ToInt64Vector(weights), step); } OptimizeVar* Solver::MakeWeightedMinimize( const std::vector& sub_objectives, const std::vector& weights, - int64 step) { + int64_t step) { return MakeWeightedMinimize(sub_objectives, ToInt64Vector(weights), step); } OptimizeVar* Solver::MakeWeightedMaximize( const std::vector& sub_objectives, const std::vector& weights, - int64 step) { + int64_t step) { return MakeWeightedMaximize(sub_objectives, ToInt64Vector(weights), step); } @@ -2939,7 +2954,7 @@ namespace { class Metaheuristic : public SearchMonitor { public: Metaheuristic(Solver* const solver, bool maximize, IntVar* objective, - int64 step); + int64_t step); ~Metaheuristic() override {} bool AtSolution() override; @@ -2949,19 +2964,19 @@ class Metaheuristic : public SearchMonitor { protected: IntVar* const objective_; - int64 step_; - int64 current_; - int64 best_; + int64_t step_; + int64_t current_; + int64_t best_; bool maximize_; }; Metaheuristic::Metaheuristic(Solver* const solver, bool maximize, - IntVar* objective, int64 step) + IntVar* objective, int64_t step) : SearchMonitor(solver), objective_(objective), step_(step), - current_(kint64max), - best_(kint64max), + current_(std::numeric_limits::max()), + best_(std::numeric_limits::max()), maximize_(maximize) {} bool Metaheuristic::AtSolution() { @@ -2980,10 +2995,10 @@ void Metaheuristic::EnterSearch() { solver()->SetUseFastLocalSearch(false); if (maximize_) { best_ = objective_->Min(); - current_ = kint64min; + current_ = std::numeric_limits::min(); } else { best_ = objective_->Max(); - current_ = kint64max; + current_ = std::numeric_limits::max(); } } @@ -3019,9 +3034,9 @@ bool Metaheuristic::AcceptDelta(Assignment* delta, Assignment* deltadelta) { class TabuSearch : public Metaheuristic { public: - TabuSearch(Solver* const s, bool maximize, IntVar* objective, int64 step, - const std::vector& vars, int64 keep_tenure, - int64 forbid_tenure, double tabu_factor); + TabuSearch(Solver* const s, bool maximize, IntVar* objective, int64_t step, + const std::vector& vars, int64_t keep_tenure, + int64_t forbid_tenure, double tabu_factor); ~TabuSearch() override {} void EnterSearch() override; void ApplyDecision(Decision* d) override; @@ -3032,11 +3047,11 @@ class TabuSearch : public Metaheuristic { protected: struct VarValue { - VarValue(IntVar* const var, int64 value, int64 stamp) + VarValue(IntVar* const var, int64_t value, int64_t stamp) : var_(var), value_(value), stamp_(stamp) {} IntVar* const var_; - const int64 value_; - const int64 stamp_; + const int64_t value_; + const int64_t stamp_; }; typedef std::list TabuList; @@ -3044,31 +3059,31 @@ class TabuSearch : public Metaheuristic { const TabuList& forbid_tabu_list() { return forbid_tabu_list_; } private: - void AgeList(int64 tenure, TabuList* list); + void AgeList(int64_t tenure, TabuList* list); void AgeLists(); const std::vector vars_; Assignment assignment_; - int64 last_; + int64_t last_; TabuList keep_tabu_list_; - int64 keep_tenure_; + int64_t keep_tenure_; TabuList forbid_tabu_list_; - int64 forbid_tenure_; + int64_t forbid_tenure_; double tabu_factor_; - int64 stamp_; + int64_t stamp_; bool found_initial_solution_; DISALLOW_COPY_AND_ASSIGN(TabuSearch); }; TabuSearch::TabuSearch(Solver* const s, bool maximize, IntVar* objective, - int64 step, const std::vector& vars, - int64 keep_tenure, int64 forbid_tenure, + int64_t step, const std::vector& vars, + int64_t keep_tenure, int64_t forbid_tenure, double tabu_factor) : Metaheuristic(s, maximize, objective, step), vars_(vars), assignment_(s), - last_(kint64max), + last_(std::numeric_limits::max()), keep_tenure_(keep_tenure), forbid_tenure_(forbid_tenure), tabu_factor_(tabu_factor), @@ -3111,15 +3126,19 @@ void TabuSearch::ApplyDecision(Decision* const d) { if (tabu_var != nullptr) { s->AddConstraint( - s->MakeGreaterOrEqual(s->MakeSum(aspiration, tabu_var), int64{1})); + s->MakeGreaterOrEqual(s->MakeSum(aspiration, tabu_var), int64_t{1})); } // Go downhill to the next local optimum if (maximize_) { - const int64 bound = (current_ > kint64min) ? current_ + step_ : current_; + const int64_t bound = (current_ > std::numeric_limits::min()) + ? current_ + step_ + : current_; s->AddConstraint(s->MakeGreaterOrEqual(objective_, bound)); } else { - const int64 bound = (current_ < kint64max) ? current_ - step_ : current_; + const int64_t bound = (current_ < std::numeric_limits::max()) + ? current_ - step_ + : current_; s->AddConstraint(s->MakeLessOrEqual(objective_, bound)); } @@ -3160,8 +3179,8 @@ bool TabuSearch::AtSolution() { if (0 != stamp_) { for (int i = 0; i < vars_.size(); ++i) { IntVar* const var = vars_[i]; - const int64 old_value = assignment_.Value(var); - const int64 new_value = var->Value(); + const int64_t old_value = assignment_.Value(var); + const int64_t new_value = var->Value(); if (old_value != new_value) { if (keep_tenure_ > 0) { VarValue keep_value(var, new_value, stamp_); @@ -3182,9 +3201,9 @@ bool TabuSearch::AtSolution() { bool TabuSearch::LocalOptimum() { AgeLists(); if (maximize_) { - current_ = kint64min; + current_ = std::numeric_limits::min(); } else { - current_ = kint64max; + current_ = std::numeric_limits::max(); } return found_initial_solution_; } @@ -3195,7 +3214,7 @@ void TabuSearch::AcceptNeighbor() { } } -void TabuSearch::AgeList(int64 tenure, TabuList* list) { +void TabuSearch::AgeList(int64_t tenure, TabuList* list) { while (!list->empty() && list->back().stamp_ < stamp_ - tenure) { list->pop_back(); } @@ -3210,8 +3229,8 @@ void TabuSearch::AgeLists() { class GenericTabuSearch : public TabuSearch { public: GenericTabuSearch(Solver* const s, bool maximize, IntVar* objective, - int64 step, const std::vector& vars, - int64 forbid_tenure) + int64_t step, const std::vector& vars, + int64_t forbid_tenure) : TabuSearch(s, maximize, objective, step, vars, 0, forbid_tenure, 1) {} std::string DebugString() const override { return "Generic Tabu Search"; } @@ -3238,17 +3257,18 @@ std::vector GenericTabuSearch::CreateTabuVars() { } // namespace SearchMonitor* Solver::MakeTabuSearch(bool maximize, IntVar* const v, - int64 step, + int64_t step, const std::vector& vars, - int64 keep_tenure, int64 forbid_tenure, + int64_t keep_tenure, + int64_t forbid_tenure, double tabu_factor) { return RevAlloc(new TabuSearch(this, maximize, v, step, vars, keep_tenure, forbid_tenure, tabu_factor)); } SearchMonitor* Solver::MakeGenericTabuSearch( - bool maximize, IntVar* const v, int64 step, - const std::vector& tabu_vars, int64 forbid_tenure) { + bool maximize, IntVar* const v, int64_t step, + const std::vector& tabu_vars, int64_t forbid_tenure) { return RevAlloc( new GenericTabuSearch(this, maximize, v, step, tabu_vars, forbid_tenure)); } @@ -3259,7 +3279,7 @@ namespace { class SimulatedAnnealing : public Metaheuristic { public: SimulatedAnnealing(Solver* const s, bool maximize, IntVar* objective, - int64 step, int64 initial_temperature); + int64_t step, int64_t initial_temperature); ~SimulatedAnnealing() override {} void EnterSearch() override; void ApplyDecision(Decision* d) override; @@ -3271,8 +3291,8 @@ class SimulatedAnnealing : public Metaheuristic { private: double Temperature() const; - const int64 temperature0_; - int64 iteration_; + const int64_t temperature0_; + int64_t iteration_; std::mt19937 rand_; bool found_initial_solution_; @@ -3280,8 +3300,8 @@ class SimulatedAnnealing : public Metaheuristic { }; SimulatedAnnealing::SimulatedAnnealing(Solver* const s, bool maximize, - IntVar* objective, int64 step, - int64 initial_temperature) + IntVar* objective, int64_t step, + int64_t initial_temperature) : Metaheuristic(s, maximize, objective, step), temperature0_(initial_temperature), iteration_(0), @@ -3304,14 +3324,16 @@ void SimulatedAnnealing::ApplyDecision(Decision* const d) { #else const double rand_log2_double = log2(rand_double); #endif - const int64 energy_bound = Temperature() * rand_log2_double; + const int64_t energy_bound = Temperature() * rand_log2_double; if (maximize_) { - const int64 bound = - (current_ > kint64min) ? current_ + step_ + energy_bound : current_; + const int64_t bound = (current_ > std::numeric_limits::min()) + ? current_ + step_ + energy_bound + : current_; s->AddConstraint(s->MakeGreaterOrEqual(objective_, bound)); } else { - const int64 bound = - (current_ < kint64max) ? current_ - step_ - energy_bound : current_; + const int64_t bound = (current_ < std::numeric_limits::max()) + ? current_ - step_ - energy_bound + : current_; s->AddConstraint(s->MakeLessOrEqual(objective_, bound)); } } @@ -3326,9 +3348,9 @@ bool SimulatedAnnealing::AtSolution() { bool SimulatedAnnealing::LocalOptimum() { if (maximize_) { - current_ = kint64min; + current_ = std::numeric_limits::min(); } else { - current_ = kint64max; + current_ = std::numeric_limits::max(); } ++iteration_; return found_initial_solution_ && Temperature() > 0; @@ -3350,15 +3372,15 @@ double SimulatedAnnealing::Temperature() const { } // namespace SearchMonitor* Solver::MakeSimulatedAnnealing(bool maximize, IntVar* const v, - int64 step, - int64 initial_temperature) { + int64_t step, + int64_t initial_temperature) { return RevAlloc( new SimulatedAnnealing(this, maximize, v, step, initial_temperature)); } // ---------- Guided Local Search ---------- -typedef std::pair Arc; +typedef std::pair Arc; namespace { // Base GLS penalties abstract class. Maintains the penalty frequency for each @@ -3368,7 +3390,7 @@ class GuidedLocalSearchPenalties { virtual ~GuidedLocalSearchPenalties() {} virtual bool HasValues() const = 0; virtual void Increment(const Arc& arc) = 0; - virtual int64 Value(const Arc& arc) const = 0; + virtual int64_t Value(const Arc& arc) const = 0; virtual void Reset() = 0; }; @@ -3379,11 +3401,11 @@ class GuidedLocalSearchPenaltiesTable : public GuidedLocalSearchPenalties { ~GuidedLocalSearchPenaltiesTable() override {} bool HasValues() const override { return has_values_; } void Increment(const Arc& arc) override; - int64 Value(const Arc& arc) const override; + int64_t Value(const Arc& arc) const override; void Reset() override; private: - std::vector> penalties_; + std::vector> penalties_; bool has_values_; }; @@ -3391,8 +3413,8 @@ GuidedLocalSearchPenaltiesTable::GuidedLocalSearchPenaltiesTable(int size) : penalties_(size), has_values_(false) {} void GuidedLocalSearchPenaltiesTable::Increment(const Arc& arc) { - std::vector& first_penalties = penalties_[arc.first]; - const int64 second = arc.second; + std::vector& first_penalties = penalties_[arc.first]; + const int64_t second = arc.second; if (second >= first_penalties.size()) { first_penalties.resize(second + 1, 0); } @@ -3407,9 +3429,9 @@ void GuidedLocalSearchPenaltiesTable::Reset() { } } -int64 GuidedLocalSearchPenaltiesTable::Value(const Arc& arc) const { - const std::vector& first_penalties = penalties_[arc.first]; - const int64 second = arc.second; +int64_t GuidedLocalSearchPenaltiesTable::Value(const Arc& arc) const { + const std::vector& first_penalties = penalties_[arc.first]; + const int64_t second = arc.second; if (second >= first_penalties.size()) { return 0; } else { @@ -3424,12 +3446,12 @@ class GuidedLocalSearchPenaltiesMap : public GuidedLocalSearchPenalties { ~GuidedLocalSearchPenaltiesMap() override {} bool HasValues() const override { return (!penalties_.empty()); } void Increment(const Arc& arc) override; - int64 Value(const Arc& arc) const override; + int64_t Value(const Arc& arc) const override; void Reset() override; private: Bitmap penalized_; - absl::flat_hash_map penalties_; + absl::flat_hash_map penalties_; }; GuidedLocalSearchPenaltiesMap::GuidedLocalSearchPenaltiesMap(int size) @@ -3445,7 +3467,7 @@ void GuidedLocalSearchPenaltiesMap::Reset() { penalized_.Clear(); } -int64 GuidedLocalSearchPenaltiesMap::Value(const Arc& arc) const { +int64_t GuidedLocalSearchPenaltiesMap::Value(const Arc& arc) const { if (penalized_.Get(arc.first)) { return gtl::FindWithDefault(penalties_, arc, 0); } @@ -3455,7 +3477,7 @@ int64 GuidedLocalSearchPenaltiesMap::Value(const Arc& arc) const { class GuidedLocalSearch : public Metaheuristic { public: GuidedLocalSearch(Solver* const s, IntVar* objective, bool maximize, - int64 step, const std::vector& vars, + int64_t step, const std::vector& vars, double penalty_factor); ~GuidedLocalSearch() override {} bool AcceptDelta(Assignment* delta, Assignment* deltadelta) override; @@ -3463,13 +3485,13 @@ class GuidedLocalSearch : public Metaheuristic { bool AtSolution() override; void EnterSearch() override; bool LocalOptimum() override; - virtual int64 AssignmentElementPenalty(const Assignment& assignment, - int index) = 0; - virtual int64 AssignmentPenalty(const Assignment& assignment, int index, - int64 next) = 0; + virtual int64_t AssignmentElementPenalty(const Assignment& assignment, + int index) = 0; + virtual int64_t AssignmentPenalty(const Assignment& assignment, int index, + int64_t next) = 0; virtual bool EvaluateElementValue(const Assignment::IntContainer& container, - int64 index, int* container_index, - int64* penalty) = 0; + int64_t index, int* container_index, + int64_t* penalty) = 0; virtual IntExpr* MakeElementPenalty(int index) = 0; std::string DebugString() const override { return "Guided Local Search"; } @@ -3481,24 +3503,24 @@ class GuidedLocalSearch : public Metaheuristic { } }; - int64 Evaluate(const Assignment* delta, int64 current_penalty, - const int64* const out_values, bool cache_delta_values); + int64_t Evaluate(const Assignment* delta, int64_t current_penalty, + const int64_t* const out_values, bool cache_delta_values); IntVar* penalized_objective_; Assignment assignment_; - int64 assignment_penalized_value_; - int64 old_penalized_value_; + int64_t assignment_penalized_value_; + int64_t old_penalized_value_; const std::vector vars_; - absl::flat_hash_map indices_; + absl::flat_hash_map indices_; const double penalty_factor_; std::unique_ptr penalties_; - std::unique_ptr current_penalized_values_; - std::unique_ptr delta_cache_; + std::unique_ptr current_penalized_values_; + std::unique_ptr delta_cache_; bool incremental_; }; GuidedLocalSearch::GuidedLocalSearch(Solver* const s, IntVar* objective, - bool maximize, int64 step, + bool maximize, int64_t step, const std::vector& vars, double penalty_factor) : Metaheuristic(s, maximize, objective, step), @@ -3512,8 +3534,8 @@ GuidedLocalSearch::GuidedLocalSearch(Solver* const s, IntVar* objective, if (!vars.empty()) { // TODO(user): Remove scoped_array. assignment_.Add(vars_); - current_penalized_values_ = absl::make_unique(vars_.size()); - delta_cache_ = absl::make_unique(vars_.size()); + current_penalized_values_ = absl::make_unique(vars_.size()); + delta_cache_ = absl::make_unique(vars_.size()); memset(current_penalized_values_.get(), 0, vars_.size() * sizeof(*current_penalized_values_.get())); } @@ -3547,7 +3569,7 @@ void GuidedLocalSearch::ApplyDecision(Decision* const d) { std::vector elements; for (int i = 0; i < vars_.size(); ++i) { elements.push_back(MakeElementPenalty(i)->Var()); - const int64 penalty = AssignmentElementPenalty(assignment_, i); + const int64_t penalty = AssignmentElementPenalty(assignment_, i); current_penalized_values_[i] = penalty; delta_cache_[i] = penalty; assignment_penalized_value_ = @@ -3572,10 +3594,14 @@ void GuidedLocalSearch::ApplyDecision(Decision* const d) { } else { penalized_objective_ = nullptr; if (maximize_) { - const int64 bound = (current_ > kint64min) ? current_ + step_ : current_; + const int64_t bound = (current_ > std::numeric_limits::min()) + ? current_ + step_ + : current_; objective_->SetMin(bound); } else { - const int64 bound = (current_ < kint64max) ? current_ - step_ : current_; + const int64_t bound = (current_ < std::numeric_limits::max()) + ? current_ - step_ + : current_; objective_->SetMax(bound); } } @@ -3609,7 +3635,7 @@ bool GuidedLocalSearch::AcceptDelta(Assignment* delta, Assignment* deltadelta) { if (!penalties_->HasValues()) { return Metaheuristic::AcceptDelta(delta, deltadelta); } - int64 penalty = 0; + int64_t penalty = 0; if (!deltadelta->Empty()) { if (!incremental_) { penalty = Evaluate(delta, assignment_penalized_value_, @@ -3651,20 +3677,20 @@ bool GuidedLocalSearch::AcceptDelta(Assignment* delta, Assignment* deltadelta) { return true; } -int64 GuidedLocalSearch::Evaluate(const Assignment* delta, - int64 current_penalty, - const int64* const out_values, - bool cache_delta_values) { - int64 penalty = current_penalty; +int64_t GuidedLocalSearch::Evaluate(const Assignment* delta, + int64_t current_penalty, + const int64_t* const out_values, + bool cache_delta_values) { + int64_t penalty = current_penalty; const Assignment::IntContainer& container = delta->IntVarContainer(); const int size = container.Size(); for (int i = 0; i < size; ++i) { const IntVarElement& new_element = container.Element(i); IntVar* var = new_element.Var(); - int64 index = -1; + int64_t index = -1; if (gtl::FindCopy(indices_, var, &index)) { penalty = CapSub(penalty, out_values[index]); - int64 new_penalty = 0; + int64_t new_penalty = 0; if (EvaluateElementValue(container, index, &i, &new_penalty)) { penalty = CapAdd(penalty, new_penalty); if (cache_delta_values) { @@ -3685,78 +3711,78 @@ bool GuidedLocalSearch::LocalOptimum() { // Never synced with a solution, problem infeasible. return false; } - const int64 var_value = assignment_.Value(vars_[i]); - const int64 value = + const int64_t var_value = assignment_.Value(vars_[i]); + const int64_t value = (var_value != i) ? AssignmentPenalty(assignment_, i, var_value) : 0; const Arc arc(i, var_value); - const int64 penalty = penalties_->Value(arc); + const int64_t penalty = penalties_->Value(arc); utility[i] = std::pair(arc, value / (penalty + 1.0)); } Comparator comparator; std::sort(utility.begin(), utility.end(), comparator); - int64 utility_value = utility[0].second; + int64_t utility_value = utility[0].second; penalties_->Increment(utility[0].first); for (int i = 1; i < utility.size() && utility_value == utility[i].second; ++i) { penalties_->Increment(utility[i].first); } if (maximize_) { - current_ = kint64min; + current_ = std::numeric_limits::min(); } else { - current_ = kint64max; + current_ = std::numeric_limits::max(); } return true; } class BinaryGuidedLocalSearch : public GuidedLocalSearch { public: - BinaryGuidedLocalSearch(Solver* const solver, IntVar* const objective, - std::function objective_function, - bool maximize, int64 step, - const std::vector& vars, - double penalty_factor); + BinaryGuidedLocalSearch( + Solver* const solver, IntVar* const objective, + std::function objective_function, + bool maximize, int64_t step, const std::vector& vars, + double penalty_factor); ~BinaryGuidedLocalSearch() override {} IntExpr* MakeElementPenalty(int index) override; - int64 AssignmentElementPenalty(const Assignment& assignment, - int index) override; - int64 AssignmentPenalty(const Assignment& assignment, int index, - int64 next) override; + int64_t AssignmentElementPenalty(const Assignment& assignment, + int index) override; + int64_t AssignmentPenalty(const Assignment& assignment, int index, + int64_t next) override; bool EvaluateElementValue(const Assignment::IntContainer& container, - int64 index, int* container_index, - int64* penalty) override; + int64_t index, int* container_index, + int64_t* penalty) override; private: - int64 PenalizedValue(int64 i, int64 j); - std::function objective_function_; + int64_t PenalizedValue(int64_t i, int64_t j); + std::function objective_function_; }; BinaryGuidedLocalSearch::BinaryGuidedLocalSearch( Solver* const solver, IntVar* const objective, - std::function objective_function, bool maximize, - int64 step, const std::vector& vars, double penalty_factor) + std::function objective_function, bool maximize, + int64_t step, const std::vector& vars, double penalty_factor) : GuidedLocalSearch(solver, objective, maximize, step, vars, penalty_factor), objective_function_(std::move(objective_function)) {} IntExpr* BinaryGuidedLocalSearch::MakeElementPenalty(int index) { return solver()->MakeElement( - [this, index](int64 i) { return PenalizedValue(index, i); }, + [this, index](int64_t i) { return PenalizedValue(index, i); }, vars_[index]); } -int64 BinaryGuidedLocalSearch::AssignmentElementPenalty( +int64_t BinaryGuidedLocalSearch::AssignmentElementPenalty( const Assignment& assignment, int index) { return PenalizedValue(index, assignment.Value(vars_[index])); } -int64 BinaryGuidedLocalSearch::AssignmentPenalty(const Assignment& assignment, - int index, int64 next) { +int64_t BinaryGuidedLocalSearch::AssignmentPenalty(const Assignment& assignment, + int index, int64_t next) { return objective_function_(index, next); } bool BinaryGuidedLocalSearch::EvaluateElementValue( - const Assignment::IntContainer& container, int64 index, - int* container_index, int64* penalty) { + const Assignment::IntContainer& container, int64_t index, + int* container_index, int64_t* penalty) { const IntVarElement& element = container.Element(*container_index); if (element.Activated()) { *penalty = PenalizedValue(index, element.Value()); @@ -3766,15 +3792,16 @@ bool BinaryGuidedLocalSearch::EvaluateElementValue( } // Penalized value for (i, j) = penalty_factor_ * penalty(i, j) * cost (i, j) -int64 BinaryGuidedLocalSearch::PenalizedValue(int64 i, int64 j) { +int64_t BinaryGuidedLocalSearch::PenalizedValue(int64_t i, int64_t j) { const Arc arc(i, j); - const int64 penalty = penalties_->Value(arc); + const int64_t penalty = penalties_->Value(arc); if (penalty != 0) { // objective_function_->Run(i, j) can be costly const double penalized_value_fp = penalty_factor_ * penalty * objective_function_(i, j); - const int64 penalized_value = (penalized_value_fp <= kint64max) - ? static_cast(penalized_value_fp) - : kint64max; + const int64_t penalized_value = + (penalized_value_fp <= std::numeric_limits::max()) + ? static_cast(penalized_value_fp) + : std::numeric_limits::max(); if (maximize_) { return -penalized_value; } else { @@ -3789,32 +3816,32 @@ class TernaryGuidedLocalSearch : public GuidedLocalSearch { public: TernaryGuidedLocalSearch( Solver* const solver, IntVar* const objective, - std::function objective_function, - bool maximize, int64 step, const std::vector& vars, + std::function objective_function, + bool maximize, int64_t step, const std::vector& vars, const std::vector& secondary_vars, double penalty_factor); ~TernaryGuidedLocalSearch() override {} IntExpr* MakeElementPenalty(int index) override; - int64 AssignmentElementPenalty(const Assignment& assignment, - int index) override; - int64 AssignmentPenalty(const Assignment& assignment, int index, - int64 next) override; + int64_t AssignmentElementPenalty(const Assignment& assignment, + int index) override; + int64_t AssignmentPenalty(const Assignment& assignment, int index, + int64_t next) override; bool EvaluateElementValue(const Assignment::IntContainer& container, - int64 index, int* container_index, - int64* penalty) override; + int64_t index, int* container_index, + int64_t* penalty) override; private: - int64 PenalizedValue(int64 i, int64 j, int64 k); - int64 GetAssignmentSecondaryValue(const Assignment::IntContainer& container, - int index, int* container_index) const; + int64_t PenalizedValue(int64_t i, int64_t j, int64_t k); + int64_t GetAssignmentSecondaryValue(const Assignment::IntContainer& container, + int index, int* container_index) const; const std::vector secondary_vars_; - std::function objective_function_; + std::function objective_function_; }; TernaryGuidedLocalSearch::TernaryGuidedLocalSearch( Solver* const solver, IntVar* const objective, - std::function objective_function, bool maximize, - int64 step, const std::vector& vars, + std::function objective_function, + bool maximize, int64_t step, const std::vector& vars, const std::vector& secondary_vars, double penalty_factor) : GuidedLocalSearch(solver, objective, maximize, step, vars, penalty_factor), @@ -3827,25 +3854,25 @@ TernaryGuidedLocalSearch::TernaryGuidedLocalSearch( IntExpr* TernaryGuidedLocalSearch::MakeElementPenalty(int index) { return solver()->MakeElement( - [this, index](int64 i, int64 j) { return PenalizedValue(index, i, j); }, + [this, index](int64_t i, int64_t j) { return PenalizedValue(index, i, j); }, vars_[index], secondary_vars_[index]); } -int64 TernaryGuidedLocalSearch::AssignmentElementPenalty( +int64_t TernaryGuidedLocalSearch::AssignmentElementPenalty( const Assignment& assignment, int index) { return PenalizedValue(index, assignment.Value(vars_[index]), assignment.Value(secondary_vars_[index])); } -int64 TernaryGuidedLocalSearch::AssignmentPenalty(const Assignment& assignment, - int index, int64 next) { +int64_t TernaryGuidedLocalSearch::AssignmentPenalty( + const Assignment& assignment, int index, int64_t next) { return objective_function_(index, next, assignment.Value(secondary_vars_[index])); } bool TernaryGuidedLocalSearch::EvaluateElementValue( - const Assignment::IntContainer& container, int64 index, - int* container_index, int64* penalty) { + const Assignment::IntContainer& container, int64_t index, + int* container_index, int64_t* penalty) { const IntVarElement& element = container.Element(*container_index); if (element.Activated()) { *penalty = PenalizedValue( @@ -3857,15 +3884,17 @@ bool TernaryGuidedLocalSearch::EvaluateElementValue( } // Penalized value for (i, j) = penalty_factor_ * penalty(i, j) * cost (i, j) -int64 TernaryGuidedLocalSearch::PenalizedValue(int64 i, int64 j, int64 k) { +int64_t TernaryGuidedLocalSearch::PenalizedValue(int64_t i, int64_t j, + int64_t k) { const Arc arc(i, j); - const int64 penalty = penalties_->Value(arc); + const int64_t penalty = penalties_->Value(arc); if (penalty != 0) { // objective_function_(i, j, k) can be costly const double penalized_value_fp = penalty_factor_ * penalty * objective_function_(i, j, k); - const int64 penalized_value = (penalized_value_fp <= kint64max) - ? static_cast(penalized_value_fp) - : kint64max; + const int64_t penalized_value = + (penalized_value_fp <= std::numeric_limits::max()) + ? static_cast(penalized_value_fp) + : std::numeric_limits::max(); if (maximize_) { return -penalized_value; } else { @@ -3876,7 +3905,7 @@ int64 TernaryGuidedLocalSearch::PenalizedValue(int64 i, int64 j, int64 k) { } } -int64 TernaryGuidedLocalSearch::GetAssignmentSecondaryValue( +int64_t TernaryGuidedLocalSearch::GetAssignmentSecondaryValue( const Assignment::IntContainer& container, int index, int* container_index) const { const IntVar* secondary_var = secondary_vars_[index]; @@ -3893,7 +3922,7 @@ int64 TernaryGuidedLocalSearch::GetAssignmentSecondaryValue( SearchMonitor* Solver::MakeGuidedLocalSearch( bool maximize, IntVar* const objective, - Solver::IndexEvaluator2 objective_function, int64 step, + Solver::IndexEvaluator2 objective_function, int64_t step, const std::vector& vars, double penalty_factor) { return RevAlloc(new BinaryGuidedLocalSearch( this, objective, std::move(objective_function), maximize, step, vars, @@ -3902,7 +3931,7 @@ SearchMonitor* Solver::MakeGuidedLocalSearch( SearchMonitor* Solver::MakeGuidedLocalSearch( bool maximize, IntVar* const objective, - Solver::IndexEvaluator3 objective_function, int64 step, + Solver::IndexEvaluator3 objective_function, int64_t step, const std::vector& vars, const std::vector& secondary_vars, double penalty_factor) { return RevAlloc(new TernaryGuidedLocalSearch( @@ -3946,9 +3975,10 @@ void SearchLimit::TopPeriodicCheck() { // ----- Regular Limit ----- -RegularLimit::RegularLimit(Solver* const s, absl::Duration time, int64 branches, - int64 failures, int64 solutions, - bool smart_time_check, bool cumulative) +RegularLimit::RegularLimit(Solver* const s, absl::Duration time, + int64_t branches, int64_t failures, + int64_t solutions, bool smart_time_check, + bool cumulative) : SearchLimit(s), duration_limit_(time), solver_time_at_limit_start_(s->Now()), @@ -3995,7 +4025,7 @@ bool RegularLimit::Check() { int RegularLimit::ProgressPercent() { Solver* const s = solver(); - int64 progress = GetPercent(s->branches(), branches_offset_, branches_); + int64_t progress = GetPercent(s->branches(), branches_offset_, branches_); progress = std::max(progress, GetPercent(s->failures(), failures_offset_, failures_)); progress = std::max( @@ -4028,8 +4058,8 @@ void RegularLimit::ExitSearch() { } } -void RegularLimit::UpdateLimits(absl::Duration time, int64 branches, - int64 failures, int64 solutions) { +void RegularLimit::UpdateLimits(absl::Duration time, int64_t branches, + int64_t failures, int64_t solutions) { duration_limit_ = time; branches_ = branches; failures_ = failures; @@ -4068,8 +4098,8 @@ void RegularLimit::Accept(ModelVisitor* const visitor) const { bool RegularLimit::CheckTime() { return TimeElapsed() >= duration_limit(); } absl::Duration RegularLimit::TimeElapsed() { - const int64 kMaxSkip = 100; - const int64 kCheckWarmupIterations = 100; + const int64_t kMaxSkip = 100; + const int64_t kCheckWarmupIterations = 100; ++check_count_; if (duration_limit() != absl::InfiniteDuration() && next_check_ <= check_count_) { @@ -4077,7 +4107,7 @@ absl::Duration RegularLimit::TimeElapsed() { absl::Duration elapsed = s->Now() - solver_time_at_limit_start_; if (smart_time_check_ && check_count_ > kCheckWarmupIterations && elapsed > absl::ZeroDuration()) { - const int64 estimated_check_count_at_limit = MathUtil::FastInt64Round( + const int64_t estimated_check_count_at_limit = MathUtil::FastInt64Round( check_count_ * absl::FDivDuration(duration_limit_, elapsed)); next_check_ = std::min(check_count_ + kMaxSkip, estimated_check_count_at_limit); @@ -4088,52 +4118,61 @@ absl::Duration RegularLimit::TimeElapsed() { } RegularLimit* Solver::MakeTimeLimit(absl::Duration time) { - return MakeLimit(time, kint64max, kint64max, kint64max, + return MakeLimit(time, std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), /*smart_time_check=*/false, /*cumulative=*/false); } -RegularLimit* Solver::MakeBranchesLimit(int64 branches) { - return MakeLimit(absl::InfiniteDuration(), branches, kint64max, kint64max, +RegularLimit* Solver::MakeBranchesLimit(int64_t branches) { + return MakeLimit(absl::InfiniteDuration(), branches, + std::numeric_limits::max(), + std::numeric_limits::max(), /*smart_time_check=*/false, /*cumulative=*/false); } -RegularLimit* Solver::MakeFailuresLimit(int64 failures) { - return MakeLimit(absl::InfiniteDuration(), kint64max, failures, kint64max, +RegularLimit* Solver::MakeFailuresLimit(int64_t failures) { + return MakeLimit(absl::InfiniteDuration(), + std::numeric_limits::max(), failures, + std::numeric_limits::max(), /*smart_time_check=*/false, /*cumulative=*/false); } -RegularLimit* Solver::MakeSolutionsLimit(int64 solutions) { - return MakeLimit(absl::InfiniteDuration(), kint64max, kint64max, solutions, +RegularLimit* Solver::MakeSolutionsLimit(int64_t solutions) { + return MakeLimit(absl::InfiniteDuration(), + std::numeric_limits::max(), + std::numeric_limits::max(), solutions, /*smart_time_check=*/false, /*cumulative=*/false); } -RegularLimit* Solver::MakeLimit(int64 time, int64 branches, int64 failures, - int64 solutions, bool smart_time_check, - bool cumulative) { +RegularLimit* Solver::MakeLimit(int64_t time, int64_t branches, + int64_t failures, int64_t solutions, + bool smart_time_check, bool cumulative) { return MakeLimit(absl::Milliseconds(time), branches, failures, solutions, smart_time_check, cumulative); } -RegularLimit* Solver::MakeLimit(absl::Duration time, int64 branches, - int64 failures, int64 solutions, +RegularLimit* Solver::MakeLimit(absl::Duration time, int64_t branches, + int64_t failures, int64_t solutions, bool smart_time_check, bool cumulative) { return RevAlloc(new RegularLimit(this, time, branches, failures, solutions, smart_time_check, cumulative)); } RegularLimit* Solver::MakeLimit(const RegularLimitParameters& proto) { - return MakeLimit(proto.time() == kint64max ? absl::InfiniteDuration() - : absl::Milliseconds(proto.time()), + return MakeLimit(proto.time() == std::numeric_limits::max() + ? absl::InfiniteDuration() + : absl::Milliseconds(proto.time()), proto.branches(), proto.failures(), proto.solutions(), proto.smart_time_check(), proto.cumulative()); } RegularLimitParameters Solver::MakeDefaultRegularLimitParameters() const { RegularLimitParameters proto; - proto.set_time(kint64max); - proto.set_branches(kint64max); - proto.set_failures(kint64max); - proto.set_solutions(kint64max); + proto.set_time(std::numeric_limits::max()); + proto.set_branches(std::numeric_limits::max()); + proto.set_failures(std::numeric_limits::max()); + proto.set_solutions(std::numeric_limits::max()); proto.set_smart_time_check(false); proto.set_cumulative(false); return proto; @@ -4201,8 +4240,8 @@ bool ImprovementSearchLimit::Check() { return false; } - const std::pair cur = improvements_.back(); - const std::pair prev = improvements_.front(); + const std::pair cur = improvements_.back(); + const std::pair prev = improvements_.front(); DCHECK_GT(cur.second, prev.second); double improvement_rate = std::abs(prev.first - cur.first) / (cur.second - prev.second); @@ -4216,7 +4255,7 @@ bool ImprovementSearchLimit::Check() { } bool ImprovementSearchLimit::AtSolution() { - const int64 new_objective = + const int64_t new_objective = objective_var_ != nullptr && objective_var_->Bound() ? objective_var_->Value() : (maximize_ @@ -4465,7 +4504,7 @@ namespace { class NestedOptimize : public DecisionBuilder { public: NestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step) + bool maximize, int64_t step) : db_(db), solution_(solution), maximize_(maximize), @@ -4478,7 +4517,7 @@ class NestedOptimize : public DecisionBuilder { } NestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step, + bool maximize, int64_t step, const std::vector& monitors) : db_(db), solution_(solution), @@ -4523,7 +4562,7 @@ class NestedOptimize : public DecisionBuilder { DecisionBuilder* const db_; Assignment* const solution_; const bool maximize_; - const int64 step_; + const int64_t step_; std::vector monitors_; SolutionCollector* collector_; }; @@ -4531,13 +4570,13 @@ class NestedOptimize : public DecisionBuilder { DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step) { + bool maximize, int64_t step) { return RevAlloc(new NestedOptimize(db, solution, maximize, step)); } DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step, + bool maximize, int64_t step, SearchMonitor* const monitor1) { std::vector monitors; monitors.push_back(monitor1); @@ -4546,7 +4585,7 @@ DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step, + bool maximize, int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2) { std::vector monitors; @@ -4557,7 +4596,7 @@ DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, Assignment* const solution, - bool maximize, int64 step, + bool maximize, int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2, SearchMonitor* const monitor3) { @@ -4570,7 +4609,7 @@ DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db, DecisionBuilder* Solver::MakeNestedOptimize( DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, SearchMonitor* const monitor1, SearchMonitor* const monitor2, + int64_t step, SearchMonitor* const monitor1, SearchMonitor* const monitor2, SearchMonitor* const monitor3, SearchMonitor* const monitor4) { std::vector monitors; monitors.push_back(monitor1); @@ -4582,7 +4621,7 @@ DecisionBuilder* Solver::MakeNestedOptimize( DecisionBuilder* Solver::MakeNestedOptimize( DecisionBuilder* const db, Assignment* const solution, bool maximize, - int64 step, const std::vector& monitors) { + int64_t step, const std::vector& monitors) { return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors)); } @@ -4590,10 +4629,10 @@ DecisionBuilder* Solver::MakeNestedOptimize( namespace { // Luby Strategy -int64 NextLuby(int i) { +int64_t NextLuby(int i) { DCHECK_GT(i, 0); - DCHECK_LT(i, kint32max); - int64 power; + DCHECK_LT(i, std::numeric_limits::max()); + int64_t power; // let's find the least power of 2 >= (i+1). power = 2; @@ -4635,8 +4674,8 @@ class LubyRestart : public SearchMonitor { private: const int scale_factor_; int iteration_; - int64 current_fails_; - int64 next_step_; + int64_t current_fails_; + int64_t next_step_; }; } // namespace @@ -4669,7 +4708,7 @@ class ConstantRestart : public SearchMonitor { private: const int frequency_; - int64 current_fails_; + int64_t current_fails_; }; } // namespace @@ -4787,7 +4826,7 @@ class SymmetryManager : public SearchMonitor { // ----- Symmetry Breaker ----- void SymmetryBreaker::AddIntegerVariableEqualValueClause(IntVar* const var, - int64 value) { + int64_t value) { CHECK(var != nullptr); Solver* const solver = var->solver(); IntVar* const term = solver->MakeIsEqualCstVar(var, value); @@ -4795,7 +4834,7 @@ void SymmetryBreaker::AddIntegerVariableEqualValueClause(IntVar* const var, } void SymmetryBreaker::AddIntegerVariableGreaterOrEqualValueClause( - IntVar* const var, int64 value) { + IntVar* const var, int64_t value) { CHECK(var != nullptr); Solver* const solver = var->solver(); IntVar* const term = solver->MakeIsGreaterOrEqualCstVar(var, value); @@ -4803,7 +4842,7 @@ void SymmetryBreaker::AddIntegerVariableGreaterOrEqualValueClause( } void SymmetryBreaker::AddIntegerVariableLessOrEqualValueClause( - IntVar* const var, int64 value) { + IntVar* const var, int64_t value) { CHECK(var != nullptr); Solver* const solver = var->solver(); IntVar* const term = solver->MakeIsLessOrEqualCstVar(var, value); diff --git a/ortools/constraint_solver/table.cc b/ortools/constraint_solver/table.cc index 3fca3c7807..e3a0b3949f 100644 --- a/ortools/constraint_solver/table.cc +++ b/ortools/constraint_solver/table.cc @@ -15,6 +15,8 @@ // This file implements the table constraints. #include +#include +#include #include #include #include @@ -38,12 +40,14 @@ namespace { // TODO(user): Move this out of this file. struct AffineTransformation { // y == a*x + b. AffineTransformation() : a(1), b(0) {} - AffineTransformation(int64 aa, int64 bb) : a(aa), b(bb) { CHECK_NE(a, 0); } - int64 a; - int64 b; + AffineTransformation(int64_t aa, int64_t bb) : a(aa), b(bb) { + CHECK_NE(a, 0); + } + int64_t a; + int64_t b; - bool Reverse(int64 value, int64* const reverse) const { - const int64 temp = value - b; + bool Reverse(int64_t value, int64_t* const reverse) const { + const int64_t temp = value - b; if (temp % a == 0) { *reverse = temp / a; DCHECK_EQ(Forward(*reverse), value); @@ -53,9 +57,9 @@ struct AffineTransformation { // y == a*x + b. } } - int64 Forward(int64 value) const { return value * a + b; } + int64_t Forward(int64_t value) const { return value * a + b; } - int64 UnsafeReverse(int64 value) const { return (value - b) / a; } + int64_t UnsafeReverse(int64_t value) const { return (value - b) / a; } void Clear() { a = 1; @@ -74,7 +78,7 @@ class VarLinearizer : public ModelParser { ~VarLinearizer() override {} void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override { if (operation == ModelVisitor::kSumOperation) { AddConstant(value); @@ -114,11 +118,11 @@ class VarLinearizer : public ModelParser { std::string DebugString() const override { return "VarLinearizer"; } private: - void AddConstant(int64 constant) { + void AddConstant(int64_t constant) { transformation_->b += constant * multipliers_.back(); } - void PushMultiplier(int64 multiplier) { + void PushMultiplier(int64_t multiplier) { if (multipliers_.empty()) { multipliers_.push_back(multiplier); } else { @@ -128,7 +132,7 @@ class VarLinearizer : public ModelParser { void PopMultiplier() { multipliers_.pop_back(); } - std::vector multipliers_; + std::vector multipliers_; IntVar** target_var_; AffineTransformation* transformation_; }; @@ -197,19 +201,19 @@ class BasePositiveTableConstraint : public Constraint { } protected: - bool TupleValue(int tuple_index, int var_index, int64* const value) const { + bool TupleValue(int tuple_index, int var_index, int64_t* const value) const { return transformations_[var_index].Reverse( tuples_.Value(tuple_index, var_index), value); } - int64 UnsafeTupleValue(int tuple_index, int var_index) const { + int64_t UnsafeTupleValue(int tuple_index, int var_index) const { return transformations_[var_index].UnsafeReverse( tuples_.Value(tuple_index, var_index)); } bool IsTupleSupported(int tuple_index) { for (int var_index = 0; var_index < arity_; ++var_index) { - int64 value = 0; + int64_t value = 0; if (!TupleValue(tuple_index, var_index, &value) || !vars_[var_index]->Contains(value)) { return false; @@ -223,7 +227,7 @@ class BasePositiveTableConstraint : public Constraint { std::vector vars_; std::vector holes_; std::vector iterators_; - std::vector to_remove_; + std::vector to_remove_; private: // All allowed tuples. @@ -235,7 +239,7 @@ class BasePositiveTableConstraint : public Constraint { class PositiveTableConstraint : public BasePositiveTableConstraint { public: - typedef absl::flat_hash_map> ValueBitset; + typedef absl::flat_hash_map> ValueBitset; PositiveTableConstraint(Solver* const s, const std::vector& vars, const IntTupleSet& tuples) @@ -261,7 +265,7 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { InitializeMask(i); } // Initialize the active tuple bitset. - std::vector actives(word_length_, 0); + std::vector actives(word_length_, 0); for (int tuple_index = 0; tuple_index < tuple_count_; ++tuple_index) { if (IsTupleSupported(tuple_index)) { SetBit64(actives.data(), tuple_index); @@ -287,7 +291,7 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { const ValueBitset& mask = masks_[var_index]; IntVar* const var = vars_[var_index]; to_remove_.clear(); - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : InitAndGetValues(iterators_[var_index])) { if (!gtl::ContainsKey(mask, value)) { to_remove_.push_back(value); } @@ -302,7 +306,7 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { for (int var_index = 0; var_index < arity_; ++var_index) { IntVar* const var = vars_[var_index]; to_remove_.clear(); - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : InitAndGetValues(iterators_[var_index])) { if (!Supported(var_index, value)) { to_remove_.push_back(value); } @@ -316,22 +320,22 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { void Update(int index) { const ValueBitset& var_masks = masks_[index]; IntVar* const var = vars_[index]; - const int64 old_max = var->OldMax(); - const int64 vmin = var->Min(); - const int64 vmax = var->Max(); - for (int64 value = var->OldMin(); value < vmin; ++value) { + const int64_t old_max = var->OldMax(); + const int64_t vmin = var->Min(); + const int64_t vmax = var->Max(); + for (int64_t value = var->OldMin(); value < vmin; ++value) { const auto& it = var_masks.find(value); if (it != var_masks.end()) { BlankActives(it->second); } } - for (const int64 value : InitAndGetValues(holes_[index])) { + for (const int64_t value : InitAndGetValues(holes_[index])) { const auto& it = var_masks.find(value); if (it != var_masks.end()) { BlankActives(it->second); } } - for (int64 value = vmax + 1; value <= old_max; ++value) { + for (int64_t value = vmax + 1; value <= old_max; ++value) { const auto& it = var_masks.find(value); if (it != var_masks.end()) { BlankActives(it->second); @@ -339,7 +343,7 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { } } - void BlankActives(const std::vector& mask) { + void BlankActives(const std::vector& mask) { if (!mask.empty()) { active_tuples_.RevSubtract(solver(), mask); if (active_tuples_.Empty()) { @@ -348,11 +352,11 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { } } - bool Supported(int var_index, int64 value) { + bool Supported(int var_index, int64_t value) { DCHECK_GE(var_index, 0); DCHECK_LT(var_index, arity_); DCHECK(gtl::ContainsKey(masks_[var_index], value)); - const std::vector& mask = masks_[var_index][value]; + const std::vector& mask = masks_[var_index][value]; int tmp = 0; return active_tuples_.Intersects(mask, &tmp); } @@ -364,15 +368,15 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { protected: void InitializeMask(int tuple_index) { - std::vector cache(arity_); + std::vector cache(arity_); for (int var_index = 0; var_index < arity_; ++var_index) { if (!TupleValue(tuple_index, var_index, &cache[var_index])) { return; } } for (int var_index = 0; var_index < arity_; ++var_index) { - const int64 value = cache[var_index]; - std::vector& mask = masks_[var_index][value]; + const int64_t value = cache[var_index]; + std::vector& mask = masks_[var_index][value]; if (mask.empty()) { mask.assign(word_length_, 0); } @@ -383,7 +387,7 @@ class PositiveTableConstraint : public BasePositiveTableConstraint { const int word_length_; UnsortedNullableRevBitset active_tuples_; std::vector masks_; - std::vector temp_mask_; + std::vector temp_mask_; }; // ----- Compact Tables ----- @@ -451,8 +455,8 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { continue; } IntVar* const var = vars_[var_index]; - const int64 original_min = original_min_[var_index]; - const int64 var_size = var->Size(); + const int64_t original_min = original_min_[var_index]; + const int64_t var_size = var->Size(); // The domain iterator is very slow, let's try to see if we can // work our way around. switch (var_size) { @@ -463,8 +467,8 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { break; } case 2: { - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); const bool min_support = Supported(var_index, var_min - original_min); const bool max_support = Supported(var_index, var_max - original_min); if (!min_support) { @@ -482,10 +486,10 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { } default: { to_remove_.clear(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); - int64 new_min = var_min; - int64 new_max = var_max; + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); + int64_t new_min = var_min; + int64_t new_max = var_max; // If the domain of a variable is an interval, it is much // faster to iterate on that interval instead of using the // iterator. @@ -501,7 +505,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { } } var->SetRange(new_min, new_max); - for (int64 value = new_min + 1; value < new_max; ++value) { + for (int64_t value = new_min + 1; value < new_max; ++value) { if (!Supported(var_index, value - original_min)) { to_remove_.push_back(value); } @@ -510,12 +514,13 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { // Let's not collect all values below the first supported // value as this can easily and more rapidly be taken care // of by a SetRange() call. - new_min = kint64max; // escape value. - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + new_min = std::numeric_limits::max(); // escape value. + for (const int64_t value : + InitAndGetValues(iterators_[var_index])) { if (!Supported(var_index, value - original_min)) { to_remove_.push_back(value); } else { - if (new_min == kint64max) { + if (new_min == std::numeric_limits::max()) { new_min = value; // This will be covered by the SetRange. to_remove_.clear(); @@ -548,10 +553,10 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { // We first collect the complete set of tuples to blank out in temp_mask_. IntVar* const var = vars_[var_index]; bool changed = false; - const int64 omin = original_min_[var_index]; - const int64 var_size = var->Size(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t omin = original_min_[var_index]; + const int64_t var_size = var->Size(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); switch (var_size) { case 1: { @@ -565,23 +570,23 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { break; } default: { - const int64 estimated_hole_size = + const int64_t estimated_hole_size = var_sizes_.Value(var_index) - var_size; - const int64 old_min = var->OldMin(); - const int64 old_max = var->OldMax(); + const int64_t old_min = var->OldMin(); + const int64_t old_max = var->OldMax(); // Rough estimation of the number of operation if we scan // deltas in the domain of the variable. - const int64 number_of_operations = + const int64_t number_of_operations = estimated_hole_size + var_min - old_min + old_max - var_max; if (number_of_operations < var_size) { // Let's scan the removed values since last run. - for (int64 value = old_min; value < var_min; ++value) { + for (int64_t value = old_min; value < var_min; ++value) { changed |= SubtractMaskFromActive(masks_[var_index][value - omin]); } - for (const int64 value : InitAndGetValues(holes_[var_index])) { + for (const int64_t value : InitAndGetValues(holes_[var_index])) { changed |= SubtractMaskFromActive(masks_[var_index][value - omin]); } - for (int64 value = var_max + 1; value <= old_max; ++value) { + for (int64_t value = var_max + 1; value <= old_max; ++value) { changed |= SubtractMaskFromActive(masks_[var_index][value - omin]); } } else { @@ -589,11 +594,12 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { // Let's build the mask of supported tuples from the current // domain. if (var_max - var_min + 1 == var_size) { // Contiguous. - for (int64 value = var_min; value <= var_max; ++value) { + for (int64_t value = var_min; value <= var_max; ++value) { OrTempMask(var_index, value - omin); } } else { - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : + InitAndGetValues(iterators_[var_index])) { OrTempMask(var_index, value - omin); } } @@ -628,20 +634,20 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { // Build masks. for (int i = 0; i < arity_; ++i) { original_min_[i] = vars_[i]->Min(); - const int64 span = vars_[i]->Max() - original_min_[i] + 1; + const int64_t span = vars_[i]->Max() - original_min_[i] + 1; masks_[i].resize(span); } } void FillMasksAndActiveTuples() { - std::vector actives(word_length_, 0); + std::vector actives(word_length_, 0); for (int tuple_index = 0; tuple_index < tuple_count_; ++tuple_index) { if (IsTupleSupported(tuple_index)) { SetBit64(actives.data(), tuple_index); // Fill in all masks. for (int var_index = 0; var_index < arity_; ++var_index) { - const int64 value = UnsafeTupleValue(tuple_index, var_index); - const int64 value_index = value - original_min_[var_index]; + const int64_t value = UnsafeTupleValue(tuple_index, var_index); + const int64_t value_index = value - original_min_[var_index]; DCHECK_GE(value_index, 0); DCHECK_LT(value_index, masks_[var_index].size()); if (masks_[var_index][value_index].empty()) { @@ -659,7 +665,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { for (int var_index = 0; var_index < arity_; ++var_index) { IntVar* const var = vars_[var_index]; to_remove_.clear(); - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : InitAndGetValues(iterators_[var_index])) { if (masks_[var_index][value - original_min_[var_index]].empty()) { to_remove_.push_back(value); } @@ -676,7 +682,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { mask_ends_[var_index].resize(masks_[var_index].size()); for (int value_index = 0; value_index < masks_[var_index].size(); ++value_index) { - const std::vector& mask = masks_[var_index][value_index]; + const std::vector& mask = masks_[var_index][value_index]; if (mask.empty()) { continue; } @@ -706,7 +712,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { // ----- Helpers during propagation ----- - bool AndMaskWithActive(const std::vector& mask) { + bool AndMaskWithActive(const std::vector& mask) { const bool result = active_tuples_.RevAnd(solver(), mask); if (active_tuples_.Empty()) { solver()->Fail(); @@ -714,7 +720,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { return result; } - bool SubtractMaskFromActive(const std::vector& mask) { + bool SubtractMaskFromActive(const std::vector& mask) { const bool result = active_tuples_.RevSubtract(solver(), mask); if (active_tuples_.Empty()) { solver()->Fail(); @@ -722,18 +728,18 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { return result; } - bool Supported(int var_index, int64 value_index) { + bool Supported(int var_index, int64_t value_index) { DCHECK_GE(var_index, 0); DCHECK_LT(var_index, arity_); DCHECK_GE(value_index, 0); DCHECK_LT(value_index, masks_[var_index].size()); - const std::vector& mask = masks_[var_index][value_index]; + const std::vector& mask = masks_[var_index][value_index]; DCHECK(!mask.empty()); return active_tuples_.Intersects(mask, &supports_[var_index][value_index]); } - void OrTempMask(int var_index, int64 value_index) { - const std::vector& mask = masks_[var_index][value_index]; + void OrTempMask(int var_index, int64_t value_index) { + const std::vector& mask = masks_[var_index][value_index]; if (!mask.empty()) { const int mask_span = mask_ends_[var_index][value_index] - mask_starts_[var_index][value_index] + 1; @@ -750,7 +756,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { } } - void SetTempMask(int var_index, int64 value_index) { + void SetTempMask(int var_index, int64_t value_index) { // We assume memset is much faster that looping and assigning. // Still we do want to stay sparse if possible. // Thus we switch between dense and sparse initialization by @@ -777,24 +783,24 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint { } // The length in 64 bit words of the number of tuples. - int64 word_length_; + int64_t word_length_; // The active bitset. UnsortedNullableRevBitset active_tuples_; // The masks per value per variable. - std::vector>> masks_; + std::vector>> masks_; // The range of active indices in the masks. std::vector> mask_starts_; std::vector> mask_ends_; // The min on the vars at creation time. - std::vector original_min_; + std::vector original_min_; // A temporary mask use for computation. - std::vector temp_mask_; + std::vector temp_mask_; // The index of the word in the active bitset supporting each value per // variable. std::vector> supports_; Demon* demon_; int touched_var_; - RevArray var_sizes_; + RevArray var_sizes_; }; // ----- Small Compact Table. ----- @@ -839,14 +845,14 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { // Build masks. for (int i = 0; i < arity_; ++i) { original_min_[i] = vars_[i]->Min(); - const int64 span = vars_[i]->Max() - original_min_[i] + 1; + const int64_t span = vars_[i]->Max() - original_min_[i] + 1; masks_[i].assign(span, 0); } } bool IsTupleSupported(int tuple_index) { for (int var_index = 0; var_index < arity_; ++var_index) { - int64 value = 0; + int64_t value = 0; if (!TupleValue(tuple_index, var_index, &value) || !vars_[var_index]->Contains(value)) { return false; @@ -860,10 +866,10 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { // Compute active_tuples_ and update masks. for (int tuple_index = 0; tuple_index < tuple_count_; ++tuple_index) { if (IsTupleSupported(tuple_index)) { - const uint64 local_mask = OneBit64(tuple_index); + const uint64_t local_mask = OneBit64(tuple_index); active_tuples_ |= local_mask; for (int var_index = 0; var_index < arity_; ++var_index) { - const int64 value = UnsafeTupleValue(tuple_index, var_index); + const int64_t value = UnsafeTupleValue(tuple_index, var_index); masks_[var_index][value - original_min_[var_index]] |= local_mask; } } @@ -877,9 +883,9 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { // remove unreached values. for (int var_index = 0; var_index < arity_; ++var_index) { IntVar* const var = vars_[var_index]; - const int64 original_min = original_min_[var_index]; + const int64_t original_min = original_min_[var_index]; to_remove_.clear(); - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : InitAndGetValues(iterators_[var_index])) { if (masks_[var_index][value - original_min] == 0) { to_remove_.push_back(value); } @@ -908,7 +914,7 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } // We cache active_tuples_. - const uint64 actives = active_tuples_; + const uint64_t actives = active_tuples_; // We scan all variables and check their domains. for (int var_index = 0; var_index < arity_; ++var_index) { @@ -920,10 +926,10 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { touched_var_ = -1; // Clean it, it is a one time flag. continue; } - const std::vector& var_mask = masks_[var_index]; - const int64 original_min = original_min_[var_index]; + const std::vector& var_mask = masks_[var_index]; + const int64_t original_min = original_min_[var_index]; IntVar* const var = vars_[var_index]; - const int64 var_size = var->Size(); + const int64_t var_size = var->Size(); switch (var_size) { case 1: { if ((var_mask[var->Min() - original_min] & actives) == 0) { @@ -936,8 +942,8 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { break; } case 2: { - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); const bool min_support = (var_mask[var_min - original_min] & actives) != 0; const bool max_support = @@ -953,10 +959,10 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } default: { to_remove_.clear(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); - int64 new_min = var_min; - int64 new_max = var_max; + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); + int64_t new_min = var_min; + int64_t new_max = var_max; if (var_max - var_min + 1 == var_size) { // Contiguous case. for (; new_min <= var_max; ++new_min) { @@ -970,7 +976,7 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } } var->SetRange(new_min, new_max); - for (int64 value = new_min + 1; value < new_max; ++value) { + for (int64_t value = new_min + 1; value < new_max; ++value) { if ((var_mask[value - original_min] & actives) == 0) { to_remove_.push_back(value); } @@ -978,7 +984,8 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } else { bool min_set = false; int last_size = 0; - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : + InitAndGetValues(iterators_[var_index])) { // The iterator is not safe w.r.t. deletion. Thus we // postpone all value removals. if ((var_mask[value - original_min] & actives) == 0) { @@ -1012,8 +1019,8 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { // tuples attached to values of the variables that have been removed. IntVar* const var = vars_[var_index]; - const int64 original_min = original_min_[var_index]; - const int64 var_size = var->Size(); + const int64_t original_min = original_min_[var_index]; + const int64_t var_size = var->Size(); switch (var_size) { case 1: { ApplyMask(var_index, masks_[var_index][var->Min() - original_min]); @@ -1027,11 +1034,11 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { default: { // We first collect the complete set of tuples to blank out in // temp_mask. - const std::vector& var_mask = masks_[var_index]; - const int64 old_min = var->OldMin(); - const int64 old_max = var->OldMax(); - const int64 var_min = var->Min(); - const int64 var_max = var->Max(); + const std::vector& var_mask = masks_[var_index]; + const int64_t old_min = var->OldMin(); + const int64_t old_max = var->OldMax(); + const int64_t var_min = var->Min(); + const int64_t var_max = var->Max(); const bool contiguous = var_size == var_max - var_min + 1; const bool nearly_contiguous = var_size > (var_max - var_min + 1) * 7 / 10; @@ -1041,38 +1048,39 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { // TODO(user): Implement HolesSize() on IntVar* and use it // to remove this code and the var_sizes in the non_small // version. - uint64 hole_mask = 0; + uint64_t hole_mask = 0; if (!contiguous) { - for (const int64 value : InitAndGetValues(holes_[var_index])) { + for (const int64_t value : InitAndGetValues(holes_[var_index])) { hole_mask |= var_mask[value - original_min]; } } - const int64 hole_operations = var_min - old_min + old_max - var_max; + const int64_t hole_operations = var_min - old_min + old_max - var_max; // We estimate the domain iterator to be 4x slower. - const int64 domain_operations = contiguous ? var_size : 4 * var_size; + const int64_t domain_operations = contiguous ? var_size : 4 * var_size; if (hole_operations < domain_operations) { - for (int64 value = old_min; value < var_min; ++value) { + for (int64_t value = old_min; value < var_min; ++value) { hole_mask |= var_mask[value - original_min]; } - for (int64 value = var_max + 1; value <= old_max; ++value) { + for (int64_t value = var_max + 1; value <= old_max; ++value) { hole_mask |= var_mask[value - original_min]; } // We reverse the mask as this was negative information. ApplyMask(var_index, ~hole_mask); } else { - uint64 domain_mask = 0; + uint64_t domain_mask = 0; if (contiguous) { - for (int64 value = var_min; value <= var_max; ++value) { + for (int64_t value = var_min; value <= var_max; ++value) { domain_mask |= var_mask[value - original_min]; } } else if (nearly_contiguous) { - for (int64 value = var_min; value <= var_max; ++value) { + for (int64_t value = var_min; value <= var_max; ++value) { if (var->Contains(value)) { domain_mask |= var_mask[value - original_min]; } } } else { - for (const int64 value : InitAndGetValues(iterators_[var_index])) { + for (const int64_t value : + InitAndGetValues(iterators_[var_index])) { domain_mask |= var_mask[value - original_min]; } } @@ -1089,10 +1097,10 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } private: - void ApplyMask(int var_index, uint64 mask) { + void ApplyMask(int var_index, uint64_t mask) { if ((~mask & active_tuples_) != 0) { // Check if we need to save the active_tuples in this node. - const uint64 current_stamp = solver()->stamp(); + const uint64_t current_stamp = solver()->stamp(); if (stamp_ < current_stamp) { stamp_ = current_stamp; solver()->SaveValue(&active_tuples_); @@ -1115,13 +1123,13 @@ class SmallCompactPositiveTableConstraint : public BasePositiveTableConstraint { } // Bitset of active tuples. - uint64 active_tuples_; + uint64_t active_tuples_; // Stamp of the active_tuple bitset. - uint64 stamp_; + uint64_t stamp_; // The masks per value per variable. - std::vector> masks_; + std::vector> masks_; // The min on the vars at creation time. - std::vector original_min_; + std::vector original_min_; Demon* demon_; int touched_var_; }; @@ -1143,8 +1151,9 @@ class TransitionConstraint : public Constraint { static const int kNextStatePosition; static const int kTransitionTupleSize; TransitionConstraint(Solver* const s, const std::vector& vars, - const IntTupleSet& transition_table, int64 initial_state, - const std::vector& final_states) + const IntTupleSet& transition_table, + int64_t initial_state, + const std::vector& final_states) : Constraint(s), vars_(vars), transition_table_(transition_table), @@ -1152,7 +1161,8 @@ class TransitionConstraint : public Constraint { final_states_(final_states) {} TransitionConstraint(Solver* const s, const std::vector& vars, - const IntTupleSet& transition_table, int64 initial_state, + const IntTupleSet& transition_table, + int64_t initial_state, const std::vector& final_states) : Constraint(s), vars_(vars), @@ -1168,8 +1178,8 @@ class TransitionConstraint : public Constraint { void Post() override { Solver* const s = solver(); - int64 state_min = kint64max; - int64 state_max = kint64min; + int64_t state_min = std::numeric_limits::max(); + int64_t state_max = std::numeric_limits::min(); const int nb_vars = vars_.size(); for (int i = 0; i < transition_table_.NumTuples(); ++i) { state_max = @@ -1236,9 +1246,9 @@ class TransitionConstraint : public Constraint { // The transition as tuples (state, value, next_state). const IntTupleSet transition_table_; // The initial state before the first transition. - const int64 initial_state_; + const int64_t initial_state_; // Vector of final state after the last transision. - std::vector final_states_; + std::vector final_states_; }; const int TransitionConstraint::kStatePosition = 0; @@ -1263,14 +1273,14 @@ Constraint* Solver::MakeAllowedAssignments(const std::vector& vars, Constraint* Solver::MakeTransitionConstraint( const std::vector& vars, const IntTupleSet& transition_table, - int64 initial_state, const std::vector& final_states) { + int64_t initial_state, const std::vector& final_states) { return RevAlloc(new TransitionConstraint(this, vars, transition_table, initial_state, final_states)); } Constraint* Solver::MakeTransitionConstraint( const std::vector& vars, const IntTupleSet& transition_table, - int64 initial_state, const std::vector& final_states) { + int64_t initial_state, const std::vector& final_states) { return RevAlloc(new TransitionConstraint(this, vars, transition_table, initial_state, final_states)); } diff --git a/ortools/constraint_solver/timetabling.cc b/ortools/constraint_solver/timetabling.cc index 59efd68d9e..ec4c61e84e 100644 --- a/ortools/constraint_solver/timetabling.cc +++ b/ortools/constraint_solver/timetabling.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include "absl/strings/str_format.h" @@ -37,7 +38,7 @@ const char* kBinaryNames[] = { class IntervalUnaryRelation : public Constraint { public: - IntervalUnaryRelation(Solver* const s, IntervalVar* const t, int64 d, + IntervalUnaryRelation(Solver* const s, IntervalVar* const t, int64_t d, Solver::UnaryIntervalRelation rel) : Constraint(s), t_(t), d_(d), rel_(rel) {} ~IntervalUnaryRelation() override {} @@ -61,7 +62,7 @@ class IntervalUnaryRelation : public Constraint { private: IntervalVar* const t_; - const int64 d_; + const int64_t d_; const Solver::UnaryIntervalRelation rel_; }; @@ -112,7 +113,7 @@ void IntervalUnaryRelation::InitialPropagate() { Constraint* Solver::MakeIntervalVarRelation(IntervalVar* const t, Solver::UnaryIntervalRelation r, - int64 d) { + int64_t d) { return RevAlloc(new IntervalUnaryRelation(this, t, d, r)); } @@ -123,7 +124,7 @@ class IntervalBinaryRelation : public Constraint { public: IntervalBinaryRelation(Solver* const s, IntervalVar* const t1, IntervalVar* const t2, - Solver::BinaryIntervalRelation rel, int64 delay) + Solver::BinaryIntervalRelation rel, int64_t delay) : Constraint(s), t1_(t1), t2_(t2), rel_(rel), delay_(delay) {} ~IntervalBinaryRelation() override {} @@ -148,7 +149,7 @@ class IntervalBinaryRelation : public Constraint { IntervalVar* const t1_; IntervalVar* const t2_; const Solver::BinaryIntervalRelation rel_; - const int64 delay_; + const int64_t delay_; }; void IntervalBinaryRelation::Post() { @@ -237,7 +238,7 @@ Constraint* Solver::MakeIntervalVarRelation(IntervalVar* const t1, Constraint* Solver::MakeIntervalVarRelationWithDelay( IntervalVar* const t1, Solver::BinaryIntervalRelation r, - IntervalVar* const t2, int64 delay) { + IntervalVar* const t2, int64_t delay) { return RevAlloc(new IntervalBinaryRelation(this, t1, t2, r, delay)); } diff --git a/ortools/constraint_solver/trace.cc b/ortools/constraint_solver/trace.cc index 052441ec98..f19b9530fd 100644 --- a/ortools/constraint_solver/trace.cc +++ b/ortools/constraint_solver/trace.cc @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -45,27 +46,27 @@ class TraceIntVar : public IntVar { ~TraceIntVar() override {} - int64 Min() const override { return inner_->Min(); } + int64_t Min() const override { return inner_->Min(); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { if (m > inner_->Min()) { solver()->GetPropagationMonitor()->SetMin(inner_, m); inner_->SetMin(m); } } - int64 Max() const override { return inner_->Max(); } + int64_t Max() const override { return inner_->Max(); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { if (m < inner_->Max()) { solver()->GetPropagationMonitor()->SetMax(inner_, m); inner_->SetMax(m); } } - void Range(int64* l, int64* u) override { inner_->Range(l, u); } + void Range(int64_t* l, int64_t* u) override { inner_->Range(l, u); } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { if (l > inner_->Min() || u < inner_->Max()) { if (l == u) { solver()->GetPropagationMonitor()->SetValue(inner_, l); @@ -83,31 +84,31 @@ class TraceIntVar : public IntVar { IntVar* Var() override { return this; } - int64 Value() const override { return inner_->Value(); } + int64_t Value() const override { return inner_->Value(); } - void RemoveValue(int64 v) override { + void RemoveValue(int64_t v) override { if (inner_->Contains(v)) { solver()->GetPropagationMonitor()->RemoveValue(inner_, v); inner_->RemoveValue(v); } } - void SetValue(int64 v) override { + void SetValue(int64_t v) override { solver()->GetPropagationMonitor()->SetValue(inner_, v); inner_->SetValue(v); } - void RemoveInterval(int64 l, int64 u) override { + void RemoveInterval(int64_t l, int64_t u) override { solver()->GetPropagationMonitor()->RemoveInterval(inner_, l, u); inner_->RemoveInterval(l, u); } - void RemoveValues(const std::vector& values) override { + void RemoveValues(const std::vector& values) override { solver()->GetPropagationMonitor()->RemoveValues(inner_, values); inner_->RemoveValues(values); } - void SetValues(const std::vector& values) override { + void SetValues(const std::vector& values) override { solver()->GetPropagationMonitor()->SetValues(inner_, values); inner_->SetValues(values); } @@ -118,9 +119,9 @@ class TraceIntVar : public IntVar { void WhenDomain(Demon* d) override { inner_->WhenDomain(d); } - uint64 Size() const override { return inner_->Size(); } + uint64_t Size() const override { return inner_->Size(); } - bool Contains(int64 v) const override { return inner_->Contains(v); } + bool Contains(int64_t v) const override { return inner_->Contains(v); } IntVarIterator* MakeHoleIterator(bool reversible) const override { return inner_->MakeHoleIterator(reversible); @@ -130,9 +131,9 @@ class TraceIntVar : public IntVar { return inner_->MakeDomainIterator(reversible); } - int64 OldMin() const override { return inner_->OldMin(); } + int64_t OldMin() const override { return inner_->OldMin(); } - int64 OldMax() const override { return inner_->OldMax(); } + int64_t OldMax() const override { return inner_->OldMax(); } int VarType() const override { return TRACE_VAR; } @@ -149,17 +150,19 @@ class TraceIntVar : public IntVar { std::string DebugString() const override { return inner_->DebugString(); } - IntVar* IsEqual(int64 constant) override { return inner_->IsEqual(constant); } + IntVar* IsEqual(int64_t constant) override { + return inner_->IsEqual(constant); + } - IntVar* IsDifferent(int64 constant) override { + IntVar* IsDifferent(int64_t constant) override { return inner_->IsDifferent(constant); } - IntVar* IsGreaterOrEqual(int64 constant) override { + IntVar* IsGreaterOrEqual(int64_t constant) override { return inner_->IsGreaterOrEqual(constant); } - IntVar* IsLessOrEqual(int64 constant) override { + IntVar* IsLessOrEqual(int64_t constant) override { return inner_->IsLessOrEqual(constant); } @@ -179,23 +182,23 @@ class TraceIntExpr : public IntExpr { ~TraceIntExpr() override {} - int64 Min() const override { return inner_->Min(); } + int64_t Min() const override { return inner_->Min(); } - void SetMin(int64 m) override { + void SetMin(int64_t m) override { solver()->GetPropagationMonitor()->SetMin(inner_, m); inner_->SetMin(m); } - int64 Max() const override { return inner_->Max(); } + int64_t Max() const override { return inner_->Max(); } - void SetMax(int64 m) override { + void SetMax(int64_t m) override { solver()->GetPropagationMonitor()->SetMax(inner_, m); inner_->SetMax(m); } - void Range(int64* l, int64* u) override { inner_->Range(l, u); } + void Range(int64_t* l, int64_t* u) override { inner_->Range(l, u); } - void SetRange(int64 l, int64 u) override { + void SetRange(int64_t l, int64_t u) override { if (l > inner_->Min() || u < inner_->Max()) { solver()->GetPropagationMonitor()->SetRange(inner_, l, u); inner_->SetRange(l, u); @@ -236,25 +239,25 @@ class TraceIntervalVar : public IntervalVar { } ~TraceIntervalVar() override {} - int64 StartMin() const override { return inner_->StartMin(); } + int64_t StartMin() const override { return inner_->StartMin(); } - int64 StartMax() const override { return inner_->StartMax(); } + int64_t StartMax() const override { return inner_->StartMax(); } - void SetStartMin(int64 m) override { + void SetStartMin(int64_t m) override { if (inner_->MayBePerformed() && (m > inner_->StartMin())) { solver()->GetPropagationMonitor()->SetStartMin(inner_, m); inner_->SetStartMin(m); } } - void SetStartMax(int64 m) override { + void SetStartMax(int64_t m) override { if (inner_->MayBePerformed() && (m < inner_->StartMax())) { solver()->GetPropagationMonitor()->SetStartMax(inner_, m); inner_->SetStartMax(m); } } - void SetStartRange(int64 mi, int64 ma) override { + void SetStartRange(int64_t mi, int64_t ma) override { if (inner_->MayBePerformed() && (mi > inner_->StartMin() || ma < inner_->StartMax())) { solver()->GetPropagationMonitor()->SetStartRange(inner_, mi, ma); @@ -262,33 +265,33 @@ class TraceIntervalVar : public IntervalVar { } } - int64 OldStartMin() const override { return inner_->OldStartMin(); } + int64_t OldStartMin() const override { return inner_->OldStartMin(); } - int64 OldStartMax() const override { return inner_->OldStartMax(); } + int64_t OldStartMax() const override { return inner_->OldStartMax(); } void WhenStartRange(Demon* const d) override { inner_->WhenStartRange(d); } void WhenStartBound(Demon* const d) override { inner_->WhenStartBound(d); } - int64 EndMin() const override { return inner_->EndMin(); } + int64_t EndMin() const override { return inner_->EndMin(); } - int64 EndMax() const override { return inner_->EndMax(); } + int64_t EndMax() const override { return inner_->EndMax(); } - void SetEndMin(int64 m) override { + void SetEndMin(int64_t m) override { if (inner_->MayBePerformed() && (m > inner_->EndMin())) { solver()->GetPropagationMonitor()->SetEndMin(inner_, m); inner_->SetEndMin(m); } } - void SetEndMax(int64 m) override { + void SetEndMax(int64_t m) override { if (inner_->MayBePerformed() && (m < inner_->EndMax())) { solver()->GetPropagationMonitor()->SetEndMax(inner_, m); inner_->SetEndMax(m); } } - void SetEndRange(int64 mi, int64 ma) override { + void SetEndRange(int64_t mi, int64_t ma) override { if (inner_->MayBePerformed() && (mi > inner_->EndMin() || ma < inner_->EndMax())) { solver()->GetPropagationMonitor()->SetEndRange(inner_, mi, ma); @@ -296,33 +299,33 @@ class TraceIntervalVar : public IntervalVar { } } - int64 OldEndMin() const override { return inner_->OldEndMin(); } + int64_t OldEndMin() const override { return inner_->OldEndMin(); } - int64 OldEndMax() const override { return inner_->OldEndMax(); } + int64_t OldEndMax() const override { return inner_->OldEndMax(); } void WhenEndRange(Demon* const d) override { inner_->WhenEndRange(d); } void WhenEndBound(Demon* const d) override { inner_->WhenStartBound(d); } - int64 DurationMin() const override { return inner_->DurationMin(); } + int64_t DurationMin() const override { return inner_->DurationMin(); } - int64 DurationMax() const override { return inner_->DurationMax(); } + int64_t DurationMax() const override { return inner_->DurationMax(); } - void SetDurationMin(int64 m) override { + void SetDurationMin(int64_t m) override { if (inner_->MayBePerformed() && (m > inner_->DurationMin())) { solver()->GetPropagationMonitor()->SetDurationMin(inner_, m); inner_->SetDurationMin(m); } } - void SetDurationMax(int64 m) override { + void SetDurationMax(int64_t m) override { if (inner_->MayBePerformed() && (m < inner_->DurationMax())) { solver()->GetPropagationMonitor()->SetDurationMax(inner_, m); inner_->SetDurationMax(m); } } - void SetDurationRange(int64 mi, int64 ma) override { + void SetDurationRange(int64_t mi, int64_t ma) override { if (inner_->MayBePerformed() && (mi > inner_->DurationMin() || ma < inner_->DurationMax())) { solver()->GetPropagationMonitor()->SetDurationRange(inner_, mi, ma); @@ -330,9 +333,9 @@ class TraceIntervalVar : public IntervalVar { } } - int64 OldDurationMin() const override { return inner_->OldDurationMin(); } + int64_t OldDurationMin() const override { return inner_->OldDurationMin(); } - int64 OldDurationMax() const override { return inner_->OldDurationMax(); } + int64_t OldDurationMax() const override { return inner_->OldDurationMax(); } void WhenDurationRange(Demon* const d) override { inner_->WhenDurationRange(d); @@ -366,13 +369,13 @@ class TraceIntervalVar : public IntervalVar { IntExpr* DurationExpr() override { return inner_->DurationExpr(); } IntExpr* EndExpr() override { return inner_->EndExpr(); } IntExpr* PerformedExpr() override { return inner_->PerformedExpr(); } - IntExpr* SafeStartExpr(int64 unperformed_value) override { + IntExpr* SafeStartExpr(int64_t unperformed_value) override { return inner_->SafeStartExpr(unperformed_value); } - IntExpr* SafeDurationExpr(int64 unperformed_value) override { + IntExpr* SafeDurationExpr(int64_t unperformed_value) override { return inner_->SafeDurationExpr(unperformed_value); } - IntExpr* SafeEndExpr(int64 unperformed_value) override { + IntExpr* SafeEndExpr(int64_t unperformed_value) override { return inner_->SafeEndExpr(unperformed_value); } @@ -584,60 +587,62 @@ class PrintTrace : public PropagationMonitor { // ----- IntExpr modifiers ----- - void SetMin(IntExpr* const expr, int64 new_min) override { + void SetMin(IntExpr* const expr, int64_t new_min) override { DisplayModification( absl::StrFormat("SetMin(%s, %d)", expr->DebugString(), new_min)); } - void SetMax(IntExpr* const expr, int64 new_max) override { + void SetMax(IntExpr* const expr, int64_t new_max) override { DisplayModification( absl::StrFormat("SetMax(%s, %d)", expr->DebugString(), new_max)); } - void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) override { + void SetRange(IntExpr* const expr, int64_t new_min, + int64_t new_max) override { DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])", expr->DebugString(), new_min, new_max)); } // ----- IntVar modifiers ----- - void SetMin(IntVar* const var, int64 new_min) override { + void SetMin(IntVar* const var, int64_t new_min) override { DisplayModification( absl::StrFormat("SetMin(%s, %d)", var->DebugString(), new_min)); } - void SetMax(IntVar* const var, int64 new_max) override { + void SetMax(IntVar* const var, int64_t new_max) override { DisplayModification( absl::StrFormat("SetMax(%s, %d)", var->DebugString(), new_max)); } - void SetRange(IntVar* const var, int64 new_min, int64 new_max) override { + void SetRange(IntVar* const var, int64_t new_min, int64_t new_max) override { DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])", var->DebugString(), new_min, new_max)); } - void RemoveValue(IntVar* const var, int64 value) override { + void RemoveValue(IntVar* const var, int64_t value) override { DisplayModification( absl::StrFormat("RemoveValue(%s, %d)", var->DebugString(), value)); } - void SetValue(IntVar* const var, int64 value) override { + void SetValue(IntVar* const var, int64_t value) override { DisplayModification( absl::StrFormat("SetValue(%s, %d)", var->DebugString(), value)); } - void RemoveInterval(IntVar* const var, int64 imin, int64 imax) override { + void RemoveInterval(IntVar* const var, int64_t imin, int64_t imax) override { DisplayModification(absl::StrFormat("RemoveInterval(%s, [%d .. %d])", var->DebugString(), imin, imax)); } - void SetValues(IntVar* const var, const std::vector& values) override { + void SetValues(IntVar* const var, + const std::vector& values) override { DisplayModification(absl::StrFormat("SetValues(%s, %s)", var->DebugString(), absl::StrJoin(values, ", "))); } void RemoveValues(IntVar* const var, - const std::vector& values) override { + const std::vector& values) override { DisplayModification(absl::StrFormat("RemoveValues(%s, %s)", var->DebugString(), absl::StrJoin(values, ", "))); @@ -645,50 +650,50 @@ class PrintTrace : public PropagationMonitor { // ----- IntervalVar modifiers ----- - void SetStartMin(IntervalVar* const var, int64 new_min) override { + void SetStartMin(IntervalVar* const var, int64_t new_min) override { DisplayModification( absl::StrFormat("SetStartMin(%s, %d)", var->DebugString(), new_min)); } - void SetStartMax(IntervalVar* const var, int64 new_max) override { + void SetStartMax(IntervalVar* const var, int64_t new_max) override { DisplayModification( absl::StrFormat("SetStartMax(%s, %d)", var->DebugString(), new_max)); } - void SetStartRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetStartRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { DisplayModification(absl::StrFormat("SetStartRange(%s, [%d .. %d])", var->DebugString(), new_min, new_max)); } - void SetEndMin(IntervalVar* const var, int64 new_min) override { + void SetEndMin(IntervalVar* const var, int64_t new_min) override { DisplayModification( absl::StrFormat("SetEndMin(%s, %d)", var->DebugString(), new_min)); } - void SetEndMax(IntervalVar* const var, int64 new_max) override { + void SetEndMax(IntervalVar* const var, int64_t new_max) override { DisplayModification( absl::StrFormat("SetEndMax(%s, %d)", var->DebugString(), new_max)); } - void SetEndRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetEndRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { DisplayModification(absl::StrFormat("SetEndRange(%s, [%d .. %d])", var->DebugString(), new_min, new_max)); } - void SetDurationMin(IntervalVar* const var, int64 new_min) override { + void SetDurationMin(IntervalVar* const var, int64_t new_min) override { DisplayModification( absl::StrFormat("SetDurationMin(%s, %d)", var->DebugString(), new_min)); } - void SetDurationMax(IntervalVar* const var, int64 new_max) override { + void SetDurationMax(IntervalVar* const var, int64_t new_max) override { DisplayModification( absl::StrFormat("SetDurationMax(%s, %d)", var->DebugString(), new_max)); } - void SetDurationRange(IntervalVar* const var, int64 new_min, - int64 new_max) override { + void SetDurationRange(IntervalVar* const var, int64_t new_min, + int64_t new_max) override { DisplayModification(absl::StrFormat("SetDurationRange(%s, [%d .. %d])", var->DebugString(), new_min, new_max)); } diff --git a/ortools/constraint_solver/utilities.cc b/ortools/constraint_solver/utilities.cc index ded7df2296..d4ad21eb2f 100644 --- a/ortools/constraint_solver/utilities.cc +++ b/ortools/constraint_solver/utilities.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include "absl/container/flat_hash_map.h" @@ -29,24 +30,26 @@ namespace operations_research { // ---------- SmallRevBitSet ---------- -SmallRevBitSet::SmallRevBitSet(int64 size) : bits_(0LL) { +SmallRevBitSet::SmallRevBitSet(int64_t size) : bits_(0LL) { DCHECK_GT(size, 0); DCHECK_LE(size, 64); } -void SmallRevBitSet::SetToOne(Solver* const solver, int64 pos) { +void SmallRevBitSet::SetToOne(Solver* const solver, int64_t pos) { DCHECK_GE(pos, 0); bits_.SetValue(solver, bits_.Value() | OneBit64(pos)); } -void SmallRevBitSet::SetToZero(Solver* const solver, int64 pos) { +void SmallRevBitSet::SetToZero(Solver* const solver, int64_t pos) { DCHECK_GE(pos, 0); bits_.SetValue(solver, bits_.Value() & ~OneBit64(pos)); } -int64 SmallRevBitSet::Cardinality() const { return BitCount64(bits_.Value()); } +int64_t SmallRevBitSet::Cardinality() const { + return BitCount64(bits_.Value()); +} -int64 SmallRevBitSet::GetFirstOne() const { +int64_t SmallRevBitSet::GetFirstOne() const { if (bits_.Value() == 0) { return -1; } @@ -55,11 +58,11 @@ int64 SmallRevBitSet::GetFirstOne() const { // ---------- RevBitSet ---------- -RevBitSet::RevBitSet(int64 size) +RevBitSet::RevBitSet(int64_t size) : size_(size), length_(BitLength64(size)), - bits_(new uint64[length_]), - stamps_(new uint64[length_]) { + bits_(new uint64_t[length_]), + stamps_(new uint64_t[length_]) { DCHECK_GE(size, 1); memset(bits_, 0, sizeof(*bits_) * length_); memset(stamps_, 0, sizeof(*stamps_) * length_); @@ -71,43 +74,43 @@ RevBitSet::~RevBitSet() { } void RevBitSet::Save(Solver* const solver, int offset) { - const uint64 current_stamp = solver->stamp(); + const uint64_t current_stamp = solver->stamp(); if (current_stamp > stamps_[offset]) { stamps_[offset] = current_stamp; solver->SaveValue(&bits_[offset]); } } -void RevBitSet::SetToOne(Solver* const solver, int64 index) { +void RevBitSet::SetToOne(Solver* const solver, int64_t index) { DCHECK_GE(index, 0); DCHECK_LT(index, size_); - const int64 offset = BitOffset64(index); - const int64 pos = BitPos64(index); + const int64_t offset = BitOffset64(index); + const int64_t pos = BitPos64(index); if (!(bits_[offset] & OneBit64(pos))) { Save(solver, offset); bits_[offset] |= OneBit64(pos); } } -void RevBitSet::SetToZero(Solver* const solver, int64 index) { +void RevBitSet::SetToZero(Solver* const solver, int64_t index) { DCHECK_GE(index, 0); DCHECK_LT(index, size_); - const int64 offset = BitOffset64(index); - const int64 pos = BitPos64(index); + const int64_t offset = BitOffset64(index); + const int64_t pos = BitPos64(index); if (bits_[offset] & OneBit64(pos)) { Save(solver, offset); bits_[offset] &= ~OneBit64(pos); } } -bool RevBitSet::IsSet(int64 index) const { +bool RevBitSet::IsSet(int64_t index) const { DCHECK_GE(index, 0); DCHECK_LT(index, size_); return IsBitSet64(bits_, index); } -int64 RevBitSet::Cardinality() const { - int64 card = 0; +int64_t RevBitSet::Cardinality() const { + int64_t card = 0; for (int i = 0; i < length_; ++i) { card += BitCount64(bits_[i]); } @@ -126,7 +129,7 @@ bool RevBitSet::IsCardinalityZero() const { bool RevBitSet::IsCardinalityOne() const { bool found_one = false; for (int i = 0; i < length_; ++i) { - const uint64 partial = bits_[i]; + const uint64_t partial = bits_[i]; if (partial) { if (!(partial & (partial - 1))) { if (found_one) { @@ -141,7 +144,7 @@ bool RevBitSet::IsCardinalityOne() const { return found_one; } -int64 RevBitSet::GetFirstBit(int start) const { +int64_t RevBitSet::GetFirstBit(int start) const { return LeastSignificantBitPosition64(bits_, start, size_ - 1); } @@ -156,7 +159,7 @@ void RevBitSet::ClearAll(Solver* const solver) { // ----- RevBitMatrix ----- -RevBitMatrix::RevBitMatrix(int64 rows, int64 columns) +RevBitMatrix::RevBitMatrix(int64_t rows, int64_t columns) : RevBitSet(rows * columns), rows_(rows), columns_(columns) { DCHECK_GE(rows, 1); DCHECK_GE(columns, 1); @@ -164,7 +167,7 @@ RevBitMatrix::RevBitMatrix(int64 rows, int64 columns) RevBitMatrix::~RevBitMatrix() {} -void RevBitMatrix::SetToOne(Solver* const solver, int64 row, int64 column) { +void RevBitMatrix::SetToOne(Solver* const solver, int64_t row, int64_t column) { DCHECK_GE(row, 0); DCHECK_LT(row, rows_); DCHECK_GE(column, 0); @@ -172,7 +175,8 @@ void RevBitMatrix::SetToOne(Solver* const solver, int64 row, int64 column) { RevBitSet::SetToOne(solver, row * columns_ + column); } -void RevBitMatrix::SetToZero(Solver* const solver, int64 row, int64 column) { +void RevBitMatrix::SetToZero(Solver* const solver, int64_t row, + int64_t column) { DCHECK_GE(row, 0); DCHECK_LT(row, rows_); DCHECK_GE(column, 0); @@ -180,7 +184,7 @@ void RevBitMatrix::SetToZero(Solver* const solver, int64 row, int64 column) { RevBitSet::SetToZero(solver, row * columns_ + column); } -int64 RevBitMatrix::Cardinality(int row) const { +int64_t RevBitMatrix::Cardinality(int row) const { DCHECK_GE(row, 0); DCHECK_LT(row, rows_); const int start = row * columns_; @@ -197,14 +201,15 @@ bool RevBitMatrix::IsCardinalityZero(int row) const { return IsEmptyRange64(bits_, start, start + columns_ - 1); } -int64 RevBitMatrix::GetFirstBit(int row, int start) const { +int64_t RevBitMatrix::GetFirstBit(int row, int start) const { DCHECK_GE(start, 0); DCHECK_GE(row, 0); DCHECK_LT(row, rows_); DCHECK_LT(start, columns_); const int beginning = row * columns_; const int end = beginning + columns_ - 1; - int64 position = LeastSignificantBitPosition64(bits_, beginning + start, end); + int64_t position = + LeastSignificantBitPosition64(bits_, beginning + start, end); if (position == -1) { return -1; } else { @@ -225,7 +230,7 @@ UnsortedNullableRevBitset::UnsortedNullableRevBitset(int bit_size) active_words_(word_size_) {} void UnsortedNullableRevBitset::Init(Solver* const solver, - const std::vector& mask) { + const std::vector& mask) { CHECK_LE(mask.size(), word_size_); for (int i = 0; i < mask.size(); ++i) { if (mask[i]) { @@ -236,13 +241,13 @@ void UnsortedNullableRevBitset::Init(Solver* const solver, } bool UnsortedNullableRevBitset::RevSubtract(Solver* const solver, - const std::vector& mask) { + const std::vector& mask) { bool changed = false; to_remove_.clear(); for (int index : active_words_) { if (index < mask.size() && (bits_[index] & mask[index]) != 0) { changed = true; - const uint64 result = bits_[index] & ~mask[index]; + const uint64_t result = bits_[index] & ~mask[index]; bits_.SetValue(solver, index, result); if (result == 0) { to_remove_.push_back(index); @@ -263,14 +268,14 @@ void UnsortedNullableRevBitset::CleanUpActives(Solver* const solver) { } bool UnsortedNullableRevBitset::RevAnd(Solver* const solver, - const std::vector& mask) { + const std::vector& mask) { bool changed = false; to_remove_.clear(); for (int index : active_words_) { if (index < mask.size()) { if ((bits_[index] & ~mask[index]) != 0) { changed = true; - const uint64 result = bits_[index] & mask[index]; + const uint64_t result = bits_[index] & mask[index]; bits_.SetValue(solver, index, result); if (result == 0) { to_remove_.push_back(index); @@ -287,7 +292,7 @@ bool UnsortedNullableRevBitset::RevAnd(Solver* const solver, return changed; } -bool UnsortedNullableRevBitset::Intersects(const std::vector& mask, +bool UnsortedNullableRevBitset::Intersects(const std::vector& mask, int* support_index) { DCHECK_GE(*support_index, 0); DCHECK_LT(*support_index, word_size_); @@ -366,7 +371,7 @@ class PrintModelVisitor : public ModelVisitor { } void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override { LOG(INFO) << Spaces() << "IntVar"; Increase(); @@ -377,7 +382,7 @@ class PrintModelVisitor : public ModelVisitor { } void VisitIntervalVariable(const IntervalVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntervalVar* const delegate) override { if (delegate != nullptr) { LOG(INFO) << Spaces() << operation << " <" << value << ", "; @@ -395,12 +400,13 @@ class PrintModelVisitor : public ModelVisitor { } // Variables. - void VisitIntegerArgument(const std::string& arg_name, int64 value) override { + void VisitIntegerArgument(const std::string& arg_name, + int64_t value) override { LOG(INFO) << Spaces() << arg_name << ": " << value; } void VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) override { + const std::vector& values) override { LOG(INFO) << Spaces() << arg_name << ": [" << absl::StrJoin(values, ", ") << "]"; } @@ -592,7 +598,7 @@ class ModelStatisticsVisitor : public ModelVisitor { } void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override { num_variables_++; Register(variable); @@ -601,7 +607,7 @@ class ModelStatisticsVisitor : public ModelVisitor { } void VisitIntervalVariable(const IntervalVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntervalVar* const delegate) override { num_intervals_++; if (delegate) { @@ -726,7 +732,7 @@ class VariableDegreeVisitor : public ModelVisitor { } void VisitIntegerVariable(const IntVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntVar* const delegate) override { IntVar* const var = const_cast(variable); if (gtl::ContainsKey(*map_, var)) { @@ -736,7 +742,7 @@ class VariableDegreeVisitor : public ModelVisitor { } void VisitIntervalVariable(const IntervalVar* const variable, - const std::string& operation, int64 value, + const std::string& operation, int64_t value, IntervalVar* const delegate) override { if (delegate) { VisitSubArgument(delegate); @@ -819,8 +825,8 @@ ModelVisitor* Solver::MakeVariableDegreeVisitor( // ----- Vector manipulations ----- -std::vector ToInt64Vector(const std::vector& input) { - std::vector result(input.size()); +std::vector ToInt64Vector(const std::vector& input) { + std::vector result(input.size()); for (int i = 0; i < input.size(); ++i) { result[i] = input[i]; } diff --git a/ortools/constraint_solver/visitor.cc b/ortools/constraint_solver/visitor.cc index 157c732043..58d5dad347 100644 --- a/ortools/constraint_solver/visitor.cc +++ b/ortools/constraint_solver/visitor.cc @@ -12,6 +12,7 @@ // limitations under the License. #include +#include #include #include @@ -35,12 +36,12 @@ void ArgumentHolder::SetTypeName(const std::string& type_name) { } void ArgumentHolder::SetIntegerArgument(const std::string& arg_name, - int64 value) { + int64_t value) { integer_argument_[arg_name] = value; } -void ArgumentHolder::SetIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) { +void ArgumentHolder::SetIntegerArrayArgument( + const std::string& arg_name, const std::vector& values) { integer_array_argument_[arg_name] = values; } @@ -91,17 +92,17 @@ bool ArgumentHolder::HasIntegerVariableArrayArgument( return gtl::ContainsKey(integer_variable_array_argument_, arg_name); } -int64 ArgumentHolder::FindIntegerArgumentWithDefault( - const std::string& arg_name, int64 def) const { +int64_t ArgumentHolder::FindIntegerArgumentWithDefault( + const std::string& arg_name, int64_t def) const { return gtl::FindWithDefault(integer_argument_, arg_name, def); } -int64 ArgumentHolder::FindIntegerArgumentOrDie( +int64_t ArgumentHolder::FindIntegerArgumentOrDie( const std::string& arg_name) const { return gtl::FindOrDie(integer_argument_, arg_name); } -const std::vector& ArgumentHolder::FindIntegerArrayArgumentOrDie( +const std::vector& ArgumentHolder::FindIntegerArrayArgumentOrDie( const std::string& arg_name) const { return gtl::FindOrDie(integer_array_argument_, arg_name); } @@ -165,14 +166,14 @@ void ModelParser::VisitIntegerVariable(const IntVar* const variable, void ModelParser::VisitIntegerVariable(const IntVar* const variable, const std::string& operation, - int64 value, IntVar* const delegate) { + int64_t value, IntVar* const delegate) { delegate->Accept(this); // Usual place for parsing. } void ModelParser::VisitIntervalVariable(const IntervalVar* const variable, const std::string& operation, - int64 value, + int64_t value, IntervalVar* const delegate) { if (delegate != nullptr) { delegate->Accept(this); @@ -186,12 +187,12 @@ void ModelParser::VisitSequenceVariable(const SequenceVar* const variable) { // Integer arguments void ModelParser::VisitIntegerArgument(const std::string& arg_name, - int64 value) { + int64_t value) { Top()->SetIntegerArgument(arg_name, value); } -void ModelParser::VisitIntegerArrayArgument(const std::string& arg_name, - const std::vector& values) { +void ModelParser::VisitIntegerArrayArgument( + const std::string& arg_name, const std::vector& values) { Top()->SetIntegerArrayArgument(arg_name, values); } diff --git a/ortools/data/rcpsp_parser.h b/ortools/data/rcpsp_parser.h index 5d5d6b6e60..6358bdf2d0 100644 --- a/ortools/data/rcpsp_parser.h +++ b/ortools/data/rcpsp_parser.h @@ -64,10 +64,10 @@ class RcpspParser { // accordingly. void SetNumDeclaredTasks(int t); int strtoint32(const std::string& word); - int64 strtoint64(const std::string& word); + int64_t strtoint64(const std::string& word); std::string basedata_; - int64 seed_; + int64_t seed_; LoadStatus load_status_; int num_declared_tasks_; int current_task_; diff --git a/ortools/flatzinc/csharp/flatzinc.i b/ortools/flatzinc/csharp/flatzinc.i index f5b3007056..289d540168 100644 --- a/ortools/flatzinc/csharp/flatzinc.i +++ b/ortools/flatzinc/csharp/flatzinc.i @@ -27,7 +27,7 @@ DECLARE_bool(fz_logging); %} %include "std_vector.i" -%template(Int64Vector) std::vector; +%template(Int64Vector) std::vector; %template(AnnotationVector) std::vector; %template(ArgumentVector) std::vector; %template(ConstraintVector) std::vector; diff --git a/ortools/flatzinc/model.h b/ortools/flatzinc/model.h index 06a303336b..0a1e2721ec 100644 --- a/ortools/flatzinc/model.h +++ b/ortools/flatzinc/model.h @@ -42,7 +42,7 @@ class Model; // - all integers, in which case values is empty, and is_interval is true. // Note that semi-infinite intervals aren't supported. // - a Boolean domain({ 0, 1 } with Boolean display tag). -// TODO(user): Rework domains, all int64 should be kintmin..kint64max. +// TODO(user): Rework domains, all int64_t should be kintmin..kint64max. // It is a bit tricky though as we must take care of overflows. // If is_a_set is true, then this domain has a set semantics. For a set // variable, any subset of the initial set of values is a valid assignment, diff --git a/ortools/flatzinc/parser.tab.cc b/ortools/flatzinc/parser.tab.cc index f2d86c540d..731ce625f9 100644 --- a/ortools/flatzinc/parser.tab.cc +++ b/ortools/flatzinc/parser.tab.cc @@ -1461,7 +1461,7 @@ yyreduce: // TODO(lperron): Check that the assignment is included in the domain. context->domain_map[identifier] = assignment; } else { - const int64 value = assignment.values.front(); + const int64_t value = assignment.values.front(); CHECK(domain.Contains(value)); context->integer_map[identifier] = value; } @@ -1479,9 +1479,9 @@ yyreduce: // Declaration of a (named) constant array. See rule right above. CHECK_EQ((yyvsp[-12].integer_value), 1) << "Only [1..n] array are supported here."; - const int64 num_constants = (yyvsp[-10].integer_value); + const int64_t num_constants = (yyvsp[-10].integer_value); const std::string& identifier = (yyvsp[-5].string_value); - const std::vector* const assignments = (yyvsp[-1].integers); + const std::vector* const assignments = (yyvsp[-1].integers); CHECK(assignments != nullptr); CHECK_EQ(num_constants, assignments->size()); // TODO(lperron): CHECK all values within domain. @@ -1500,10 +1500,10 @@ yyreduce: // Declaration of a (named) constant array. See rule right above. CHECK_EQ((yyvsp[-11].integer_value), 1) << "Only [1..n] array are supported here."; - const int64 num_constants = (yyvsp[-9].integer_value); + const int64_t num_constants = (yyvsp[-9].integer_value); CHECK_EQ(num_constants, 0) << "Empty arrays should have a size of 0"; const std::string& identifier = (yyvsp[-4].string_value); - context->integer_array_map[identifier] = std::vector(); + context->integer_array_map[identifier] = std::vector(); delete annotations; } #line 1651 "./ortools/flatzinc/parser.tab.cc" @@ -1518,7 +1518,7 @@ yyreduce: // Declaration of a (named) constant array. See rule right above. CHECK_EQ((yyvsp[-12].integer_value), 1) << "Only [1..n] array are supported here."; - const int64 num_constants = (yyvsp[-10].integer_value); + const int64_t num_constants = (yyvsp[-10].integer_value); const std::string& identifier = (yyvsp[-5].string_value); const std::vector* const assignments = (yyvsp[-1].doubles); CHECK(assignments != nullptr); @@ -1539,7 +1539,7 @@ yyreduce: // Declaration of a (named) constant array. See rule right above. CHECK_EQ((yyvsp[-11].integer_value), 1) << "Only [1..n] array are supported here."; - const int64 num_constants = (yyvsp[-9].integer_value); + const int64_t num_constants = (yyvsp[-9].integer_value); CHECK_EQ(num_constants, 0) << "Empty arrays should have a size of 0"; const std::string& identifier = (yyvsp[-4].string_value); context->float_array_map[identifier] = std::vector(); @@ -1556,7 +1556,7 @@ yyreduce: // Declaration of a (named) constant array: See rule above. CHECK_EQ((yyvsp[-12].integer_value), 1) << "Only [1..n] array are supported here."; - const int64 num_constants = (yyvsp[-10].integer_value); + const int64_t num_constants = (yyvsp[-10].integer_value); const Domain& domain = (yyvsp[-7].domain); const std::string& identifier = (yyvsp[-5].string_value); const std::vector* const assignments = (yyvsp[-1].domains); @@ -1569,7 +1569,7 @@ yyreduce: context->domain_array_map[identifier] = *assignments; // TODO(lperron): check that all assignments are included in the domain. } else { - std::vector values(num_constants); + std::vector values(num_constants); for (int i = 0; i < num_constants; ++i) { values[i] = (*assignments)[i].values.front(); CHECK(domain.Contains(values[i])); @@ -1629,7 +1629,7 @@ yyreduce: // variable declarations, where the identifier for declaration #i is // IDENTIFIER[i] (1-based index). CHECK_EQ((yyvsp[-10].integer_value), 1); - const int64 num_vars = (yyvsp[-8].integer_value); + const int64_t num_vars = (yyvsp[-8].integer_value); const Domain& domain = (yyvsp[-4].domain); const std::string& identifier = (yyvsp[-2].string_value); std::vector* const annotations = (yyvsp[-1].annotations); @@ -1650,7 +1650,7 @@ yyreduce: vars[i] = model->AddVariable(var_name, domain, introduced); } else if (assignments->variables[i] == nullptr) { // Assigned to an integer constant. - const int64 value = assignments->values[i]; + const int64_t value = assignments->values[i]; CHECK(domain.Contains(value)); vars[i] = model->AddVariable(var_name, Domain::IntegerValue(value), introduced); @@ -1788,7 +1788,7 @@ yyreduce: { // A given element of an existing constant array or variable array. const std::string& id = (yyvsp[-3].string_value); - const int64 value = (yyvsp[-1].integer_value); + const int64_t value = (yyvsp[-1].integer_value); if (gtl::ContainsKey(context->integer_array_map, id)) { (yyval.var_or_value) = VariableRefOrValue::Value( Lookup(gtl::FindOrDie(context->integer_array_map, id), value)); @@ -1886,8 +1886,8 @@ yyreduce: case 46: /* float_domain: DVALUE DOTDOT DVALUE */ #line 421 "./ortools/flatzinc/parser.yy" { - const int64 lb = ConvertAsIntegerOrDie((yyvsp[-2].double_value)); - const int64 ub = ConvertAsIntegerOrDie((yyvsp[0].double_value)); + const int64_t lb = ConvertAsIntegerOrDie((yyvsp[-2].double_value)); + const int64_t ub = ConvertAsIntegerOrDie((yyvsp[0].double_value)); (yyval.domain) = Domain::Interval(lb, ub); } #line 1990 "./ortools/flatzinc/parser.tab.cc" @@ -1929,7 +1929,7 @@ yyreduce: case 51: /* integers: integer */ #line 434 "./ortools/flatzinc/parser.yy" { - (yyval.integers) = new std::vector(); + (yyval.integers) = new std::vector(); (yyval.integers)->emplace_back((yyvsp[0].integer_value)); } #line 2020 "./ortools/flatzinc/parser.tab.cc" @@ -2047,7 +2047,7 @@ yyreduce: { CHECK_EQ(std::round((yyvsp[0].double_value)), (yyvsp[0].double_value)); (yyval.domain) = - Domain::IntegerValue(static_cast((yyvsp[0].double_value))); + Domain::IntegerValue(static_cast((yyvsp[0].double_value))); } #line 2109 "./ortools/flatzinc/parser.tab.cc" break; @@ -2184,9 +2184,9 @@ yyreduce: } else if (gtl::ContainsKey(context->float_array_map, id)) { const auto& double_values = gtl::FindOrDie(context->float_array_map, id); - std::vector integer_values; + std::vector integer_values; for (const double d : double_values) { - const int64 i = ConvertAsIntegerOrDie(d); + const int64_t i = ConvertAsIntegerOrDie(d); integer_values.push_back(i); } (yyval.arg) = Argument::IntegerList(std::move(integer_values)); @@ -2214,7 +2214,7 @@ yyreduce: #line 544 "./ortools/flatzinc/parser.yy" { const std::string& id = (yyvsp[-3].string_value); - const int64 index = (yyvsp[-1].integer_value); + const int64_t index = (yyvsp[-1].integer_value); if (gtl::ContainsKey(context->integer_array_map, id)) { (yyval.arg) = Argument::IntegerValue( Lookup(gtl::FindOrDie(context->integer_array_map, id), index)); diff --git a/ortools/flatzinc/parser.yy b/ortools/flatzinc/parser.yy index 2ac283f9ec..9806afa5a6 100644 --- a/ortools/flatzinc/parser.yy +++ b/ortools/flatzinc/parser.yy @@ -159,7 +159,7 @@ variable_or_constant_declaration: // TODO(lperron): Check that the assignment is included in the domain. context->domain_map[identifier] = assignment; } else { - const int64 value = assignment.values.front(); + const int64_t value = assignment.values.front(); CHECK(domain.Contains(value)); context->integer_map[identifier] = value; } @@ -170,9 +170,9 @@ variable_or_constant_declaration: std::vector* const annotations = $11; // Declaration of a (named) constant array. See rule right above. CHECK_EQ($3, 1) << "Only [1..n] array are supported here."; - const int64 num_constants = $5; + const int64_t num_constants = $5; const std::string& identifier = $10; - const std::vector* const assignments = $14; + const std::vector* const assignments = $14; CHECK(assignments != nullptr); CHECK_EQ(num_constants, assignments->size()); // TODO(lperron): CHECK all values within domain. @@ -185,10 +185,10 @@ variable_or_constant_declaration: std::vector* const annotations = $11; // Declaration of a (named) constant array. See rule right above. CHECK_EQ($3, 1) << "Only [1..n] array are supported here."; - const int64 num_constants = $5; + const int64_t num_constants = $5; CHECK_EQ(num_constants, 0) << "Empty arrays should have a size of 0"; const std::string& identifier = $10; - context->integer_array_map[identifier] = std::vector(); + context->integer_array_map[identifier] = std::vector(); delete annotations; } | ARRAY '[' IVALUE DOTDOT IVALUE ']' OF float_domain ':' IDENTIFIER @@ -196,7 +196,7 @@ variable_or_constant_declaration: std::vector* const annotations = $11; // Declaration of a (named) constant array. See rule right above. CHECK_EQ($3, 1) << "Only [1..n] array are supported here."; - const int64 num_constants = $5; + const int64_t num_constants = $5; const std::string& identifier = $10; const std::vector* const assignments = $14; CHECK(assignments != nullptr); @@ -211,7 +211,7 @@ variable_or_constant_declaration: std::vector* const annotations = $11; // Declaration of a (named) constant array. See rule right above. CHECK_EQ($3, 1) << "Only [1..n] array are supported here."; - const int64 num_constants = $5; + const int64_t num_constants = $5; CHECK_EQ(num_constants, 0) << "Empty arrays should have a size of 0"; const std::string& identifier = $10; context->float_array_map[identifier] = std::vector(); @@ -221,7 +221,7 @@ variable_or_constant_declaration: annotations '=' '[' const_literals ']' { // Declaration of a (named) constant array: See rule above. CHECK_EQ($3, 1) << "Only [1..n] array are supported here."; - const int64 num_constants = $5; + const int64_t num_constants = $5; const Domain& domain = $8; const std::string& identifier = $10; const std::vector* const assignments = $14; @@ -233,7 +233,7 @@ variable_or_constant_declaration: context->domain_array_map[identifier] = *assignments; // TODO(lperron): check that all assignments are included in the domain. } else { - std::vector values(num_constants); + std::vector values(num_constants); for (int i = 0; i < num_constants; ++i) { values[i] = (*assignments)[i].values.front(); CHECK(domain.Contains(values[i])); @@ -282,7 +282,7 @@ variable_or_constant_declaration: // variable declarations, where the identifier for declaration #i is // IDENTIFIER[i] (1-based index). CHECK_EQ($3, 1); - const int64 num_vars = $5; + const int64_t num_vars = $5; const Domain& domain = $9; const std::string& identifier = $11; std::vector* const annotations = $12; @@ -300,7 +300,7 @@ variable_or_constant_declaration: vars[i] = model->AddVariable(var_name, domain, introduced); } else if (assignments->variables[i] == nullptr) { // Assigned to an integer constant. - const int64 value = assignments->values[i]; + const int64_t value = assignments->values[i]; CHECK(domain.Contains(value)); vars[i] = model->AddVariable(var_name, Domain::IntegerValue(value), introduced); @@ -382,7 +382,7 @@ var_or_value: | IDENTIFIER '[' IVALUE ']' { // A given element of an existing constant array or variable array. const std::string& id = $1; - const int64 value = $3; + const int64_t value = $3; if (gtl::ContainsKey(context->integer_array_map, id)) { $$ = VariableRefOrValue::Value( Lookup(gtl::FindOrDie(context->integer_array_map, id), value)); @@ -419,8 +419,8 @@ set_domain: float_domain: TOKEN_FLOAT { $$ = Domain::AllInt64(); } // TODO(lperron): implement floats. | DVALUE DOTDOT DVALUE { - const int64 lb = ConvertAsIntegerOrDie($1); - const int64 ub = ConvertAsIntegerOrDie($3); + const int64_t lb = ConvertAsIntegerOrDie($1); + const int64_t ub = ConvertAsIntegerOrDie($3); $$ = Domain::Interval(lb, ub); } // TODO(lperron): floats. @@ -431,7 +431,7 @@ domain: integers: integers ',' integer { $$ = $1; $$->emplace_back($3); } -| integer { $$ = new std::vector(); $$->emplace_back($1); } +| integer { $$ = new std::vector(); $$->emplace_back($1); } integer: IVALUE { $$ = $1; } @@ -462,7 +462,7 @@ const_literal: | '{' '}' { $$ = Domain::EmptyDomain(); } | DVALUE { CHECK_EQ(std::round($1), $1); - $$ = Domain::IntegerValue(static_cast($1)); + $$ = Domain::IntegerValue(static_cast($1)); } // TODO(lperron): floats. | IDENTIFIER { $$ = Domain::IntegerValue(gtl::FindOrDie(context->integer_map, $1)); } | IDENTIFIER '[' IVALUE ']' { @@ -521,9 +521,9 @@ argument: $$ = Argument::IntegerValue(ConvertAsIntegerOrDie(d)); } else if (gtl::ContainsKey(context->float_array_map, id)) { const auto& double_values = gtl::FindOrDie(context->float_array_map, id); - std::vector integer_values; + std::vector integer_values; for (const double d : double_values) { - const int64 i = ConvertAsIntegerOrDie(d); + const int64_t i = ConvertAsIntegerOrDie(d); integer_values.push_back(i); } $$ = Argument::IntegerList(std::move(integer_values)); @@ -543,7 +543,7 @@ argument: } | IDENTIFIER '[' IVALUE ']' { const std::string& id = $1; - const int64 index = $3; + const int64_t index = $3; if (gtl::ContainsKey(context->integer_array_map, id)) { $$ = Argument::IntegerValue( Lookup(gtl::FindOrDie(context->integer_array_map, id), index)); diff --git a/ortools/flatzinc/parser_util.cc b/ortools/flatzinc/parser_util.cc index 88b7261fd9..c5a0e19596 100644 --- a/ortools/flatzinc/parser_util.cc +++ b/ortools/flatzinc/parser_util.cc @@ -62,9 +62,9 @@ bool AllDomainsHaveOneValue(const std::vector& domains) { return true; } -int64 ConvertAsIntegerOrDie(double d) { +int64_t ConvertAsIntegerOrDie(double d) { const double rounded = std::round(d); - const int64 i = static_cast(rounded); + const int64_t i = static_cast(rounded); CHECK_LE(std::abs(static_cast(i) - rounded), 1e-9); return i; } diff --git a/ortools/flatzinc/parser_util.h b/ortools/flatzinc/parser_util.h index 3346c2bfbb..ad089add1a 100644 --- a/ortools/flatzinc/parser_util.h +++ b/ortools/flatzinc/parser_util.h @@ -101,7 +101,7 @@ struct LexerInfo { VariableRefOrValueArray* var_or_value_array; }; -// If the argument is an integer, return it as int64. Otherwise, die. +// If the argument is an integer, return it as int64_t. Otherwise, die. int64_t ConvertAsIntegerOrDie(double d); } // namespace fz } // namespace operations_research diff --git a/ortools/glop/entering_variable.h b/ortools/glop/entering_variable.h index 0295a70621..69b7df2c64 100644 --- a/ortools/glop/entering_variable.h +++ b/ortools/glop/entering_variable.h @@ -172,7 +172,7 @@ class EnteringVariable { std::vector breakpoints_; // Counter for the deterministic time. - int64 num_operations_ = 0; + int64_t num_operations_ = 0; DISALLOW_COPY_AND_ASSIGN(EnteringVariable); }; diff --git a/ortools/glop/markowitz.cc b/ortools/glop/markowitz.cc index c2b8dec24d..ceb73d9df6 100644 --- a/ortools/glop/markowitz.cc +++ b/ortools/glop/markowitz.cc @@ -390,7 +390,7 @@ int64_t Markowitz::FindPivot(const RowPermutation& row_perm, } } - // Note(user): we use int64 since this is a product of two ints, moreover + // Note(user): we use int64_t since this is a product of two ints, moreover // the ints should be relatively small, so that should be fine for a while. int64_t min_markowitz_number = std::numeric_limits::max(); examined_col_.clear(); diff --git a/ortools/glop/markowitz.h b/ortools/glop/markowitz.h index a310b86fc4..fa14797caf 100644 --- a/ortools/glop/markowitz.h +++ b/ortools/glop/markowitz.h @@ -445,7 +445,7 @@ class Markowitz { GlopParameters parameters_; // Number of floating point operations of the last factorization. - int64 num_fp_operations_; + int64_t num_fp_operations_; DISALLOW_COPY_AND_ASSIGN(Markowitz); }; diff --git a/ortools/glop/preprocessor.cc b/ortools/glop/preprocessor.cc index 13684a01c4..c137407e34 100644 --- a/ortools/glop/preprocessor.cc +++ b/ortools/glop/preprocessor.cc @@ -158,7 +158,7 @@ void MainLpPreprocessor::RunAndPushIfRelevant( (lp->num_constraints() - initial_num_rows_).value(), lp->num_variables().value(), (lp->num_variables() - initial_num_cols_).value(), - // static_cast is needed because the Android port uses int32. + // static_cast is needed because the Android port uses int32. static_cast(new_num_entries.value()), static_cast(new_num_entries.value() - initial_num_entries_.value())); diff --git a/ortools/glop/revised_simplex.h b/ortools/glop/revised_simplex.h index da7dafb4e7..9c22685d65 100644 --- a/ortools/glop/revised_simplex.h +++ b/ortools/glop/revised_simplex.h @@ -665,7 +665,7 @@ class RevisedSimplex { uint64_t num_optimization_iterations_; // Deterministic time for DualPhaseIUpdatePriceOnReducedCostChange(). - int64 num_update_price_operations_ = 0; + int64_t num_update_price_operations_ = 0; // Total time spent in Solve(). double total_time_; diff --git a/ortools/graph/astar.cc b/ortools/graph/astar.cc index 70beaf02d7..cda26ca66a 100644 --- a/ortools/graph/astar.cc +++ b/ortools/graph/astar.cc @@ -36,30 +36,30 @@ class Element { } void SetHeapIndex(int h) { heap_index_ = h; } int GetHeapIndex() const { return heap_index_; } - void set_distance(int64 distance) { distance_ = distance; } - void set_distance_with_heuristic(int64 distance_with_heuristic) { + void set_distance(int64_t distance) { distance_ = distance; } + void set_distance_with_heuristic(int64_t distance_with_heuristic) { distance_with_heuristic_ = distance_with_heuristic; } - int64 distance_with_heuristic() { return distance_with_heuristic_; } + int64_t distance_with_heuristic() { return distance_with_heuristic_; } - int64 distance() const { return distance_; } + int64_t distance() const { return distance_; } void set_node(int node) { node_ = node; } int node() const { return node_; } private: int heap_index_; - int64 distance_; - int64 distance_with_heuristic_; + int64_t distance_; + int64_t distance_with_heuristic_; int node_; }; } // namespace class AStarSP { public: - static const int64 kInfinity = kint64max / 2; + static const int64_t kInfinity = kint64max / 2; - AStarSP(int node_count, int start_node, std::function graph, - std::function heuristic, int64 disconnected_distance) + AStarSP(int node_count, int start_node, std::function graph, + std::function heuristic, int64_t disconnected_distance) : node_count_(node_count), start_node_(start_node), graph_(std::move(graph)), @@ -71,15 +71,15 @@ class AStarSP { private: void Initialize(); - int SelectClosestNode(int64* distance); + int SelectClosestNode(int64_t* distance); void Update(int label); void FindPath(int dest, std::vector* nodes); const int node_count_; const int start_node_; - std::function graph_; - std::function heuristic_; - const int64 disconnected_distance_; + std::function graph_; + std::function heuristic_; + const int64_t disconnected_distance_; std::unique_ptr predecessor_; AdjustablePriorityQueue frontier_; std::vector elements_; @@ -104,7 +104,7 @@ void AStarSP::Initialize() { } } -int AStarSP::SelectClosestNode(int64* distance) { +int AStarSP::SelectClosestNode(int64_t* distance) { const int node = frontier_.Top()->node(); *distance = frontier_.Top()->distance(); frontier_.Pop(); @@ -117,7 +117,7 @@ void AStarSP::Update(int node) { for (absl::flat_hash_set::const_iterator it = not_visited_.begin(); it != not_visited_.end(); ++it) { const int other_node = *it; - const int64 graph_node_i = graph_(node, other_node); + const int64_t graph_node_i = graph_(node, other_node); if (graph_node_i != disconnected_distance_) { if (added_to_the_frontier_.find(other_node) == added_to_the_frontier_.end()) { @@ -125,7 +125,7 @@ void AStarSP::Update(int node) { added_to_the_frontier_.insert(other_node); } - const int64 other_distance = elements_[node].distance() + graph_node_i; + const int64_t other_distance = elements_[node].distance() + graph_node_i; if (elements_[other_node].distance() > other_distance) { elements_[other_node].set_distance(other_distance); elements_[other_node].set_distance_with_heuristic( @@ -150,7 +150,7 @@ bool AStarSP::ShortestPath(int end_node, std::vector* nodes) { Initialize(); bool found = false; while (!frontier_.IsEmpty()) { - int64 distance; + int64_t distance; int node = SelectClosestNode(&distance); if (distance == kInfinity) { found = false; @@ -168,9 +168,9 @@ bool AStarSP::ShortestPath(int end_node, std::vector* nodes) { } bool AStarShortestPath(int node_count, int start_node, int end_node, - std::function graph, - std::function heuristic, - int64 disconnected_distance, std::vector* nodes) { + std::function graph, + std::function heuristic, + int64_t disconnected_distance, std::vector* nodes) { AStarSP bf(node_count, start_node, std::move(graph), std::move(heuristic), disconnected_distance); return bf.ShortestPath(end_node, nodes); diff --git a/ortools/graph/bellman_ford.cc b/ortools/graph/bellman_ford.cc index e6807a02cb..781f72eb51 100644 --- a/ortools/graph/bellman_ford.cc +++ b/ortools/graph/bellman_ford.cc @@ -22,15 +22,15 @@ namespace operations_research { class BellmanFord { public: - static constexpr int64 kInfinity = kint64max / 2; + static constexpr int64_t kInfinity = kint64max / 2; BellmanFord(int node_count, int start_node, - std::function graph, int64 disconnected_distance) + std::function graph, int64_t disconnected_distance) : node_count_(node_count), start_node_(start_node), graph_(std::move(graph)), disconnected_distance_(disconnected_distance), - distance_(new int64[node_count_]), + distance_(new int64_t[node_count_]), predecessor_(new int[node_count_]) {} bool ShortestPath(int end_node, std::vector* nodes); @@ -42,9 +42,9 @@ class BellmanFord { const int node_count_; const int start_node_; - std::function graph_; - const int64 disconnected_distance_; - std::unique_ptr distance_; + std::function graph_; + const int64_t disconnected_distance_; + std::unique_ptr distance_; std::unique_ptr predecessor_; }; @@ -60,9 +60,9 @@ void BellmanFord::Update() { for (int i = 0; i < node_count_ - 1; i++) { for (int u = 0; u < node_count_; u++) { for (int v = 0; v < node_count_; v++) { - const int64 graph_u_v = graph_(u, v); + const int64_t graph_u_v = graph_(u, v); if (graph_u_v != disconnected_distance_) { - const int64 other_distance = distance_[u] + graph_u_v; + const int64_t other_distance = distance_[u] + graph_u_v; if (distance_[v] > other_distance) { distance_[v] = other_distance; predecessor_[v] = u; @@ -110,8 +110,8 @@ bool BellmanFord::ShortestPath(int end_node, std::vector* nodes) { } bool BellmanFordShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, + std::function graph, + int64_t disconnected_distance, std::vector* nodes) { BellmanFord bf(node_count, start_node, std::move(graph), disconnected_distance); diff --git a/ortools/graph/christofides.h b/ortools/graph/christofides.h index f16712120b..e56be42de0 100644 --- a/ortools/graph/christofides.h +++ b/ortools/graph/christofides.h @@ -36,7 +36,7 @@ namespace operations_research { using ::util::CompleteGraph; -template > class ChristofidesPathSolver { @@ -79,7 +79,7 @@ class ChristofidesPathSolver { // return a + b; //} //template <> - int64 SafeAdd(int64 a, int64 b) { + int64_t SafeAdd(int64_t a, int64_t b) { return CapAdd(a, b); } diff --git a/ortools/graph/cliques.h b/ortools/graph/cliques.h index f1b204aae6..299b549bff 100644 --- a/ortools/graph/cliques.h +++ b/ortools/graph/cliques.h @@ -180,7 +180,7 @@ class BronKerboschAlgorithm { // can be called again and it will resume the work where the previous call had // stopped. When it returns COMPLETED any subsequent call to the method will // resume the search from the beginning. - BronKerboschAlgorithmStatus RunIterations(int64 max_num_iterations); + BronKerboschAlgorithmStatus RunIterations(int64_t max_num_iterations); // Runs at most 'max_num_iterations' iterations of the Bron-Kerbosch // algorithm, until the time limit is exceeded or until all cliques are @@ -189,7 +189,7 @@ class BronKerboschAlgorithm { // can be called again and it will resume the work where the previous call had // stopped. When it returns COMPLETED any subsequent call to the method will // resume the search from the beginning. - BronKerboschAlgorithmStatus RunWithTimeLimit(int64 max_num_iterations, + BronKerboschAlgorithmStatus RunWithTimeLimit(int64_t max_num_iterations, TimeLimit* time_limit); // Runs the Bron-Kerbosch algorithm for at most kint64max iterations, until @@ -347,7 +347,7 @@ class BronKerboschAlgorithm { // Set to true if the algorithm is active (it was not stopped by an the clique // callback). - int64 num_remaining_iterations_; + int64_t num_remaining_iterations_; // The current time limit used by the solver. The time limit is assigned by // the Run methods and it can be different for each call to run. @@ -507,7 +507,7 @@ void BronKerboschAlgorithm::PushState(NodeIndex selected) { template BronKerboschAlgorithmStatus BronKerboschAlgorithm::RunWithTimeLimit( - int64 max_num_iterations, TimeLimit* time_limit) { + int64_t max_num_iterations, TimeLimit* time_limit) { CHECK(time_limit != nullptr); time_limit_ = time_limit; if (states_.empty()) { @@ -545,7 +545,7 @@ BronKerboschAlgorithmStatus BronKerboschAlgorithm::RunWithTimeLimit( template BronKerboschAlgorithmStatus BronKerboschAlgorithm::RunIterations( - int64 max_num_iterations) { + int64_t max_num_iterations) { TimeLimit time_limit(std::numeric_limits::infinity()); return RunWithTimeLimit(max_num_iterations, &time_limit); } diff --git a/ortools/graph/dijkstra.cc b/ortools/graph/dijkstra.cc index 687d974b1e..2da9ffec23 100644 --- a/ortools/graph/dijkstra.cc +++ b/ortools/graph/dijkstra.cc @@ -33,13 +33,13 @@ class Element { } void SetHeapIndex(int h) { heap_index_ = h; } int GetHeapIndex() const { return heap_index_; } - void set_distance(int64 distance) { distance_ = distance; } - int64 distance() const { return distance_; } + void set_distance(int64_t distance) { distance_ = distance; } + int64_t distance() const { return distance_; } void set_node(int node) { node_ = node; } int node() const { return node_; } private: - int64 distance_ = 0; + int64_t distance_ = 0; int heap_index_ = -1; int node_ = -1; }; @@ -48,10 +48,10 @@ class Element { template class DijkstraSP { public: - static constexpr int64 kInfinity = kint64max / 2; + static constexpr int64_t kInfinity = kint64max / 2; DijkstraSP(int node_count, int start_node, - std::function graph, int64 disconnected_distance) + std::function graph, int64_t disconnected_distance) : node_count_(node_count), start_node_(start_node), graph_(std::move(graph)), @@ -63,7 +63,7 @@ class DijkstraSP { Initialize(); bool found = false; while (!frontier_.IsEmpty()) { - int64 distance; + int64_t distance; int node = SelectClosestNode(&distance); if (distance == kInfinity) { found = false; @@ -96,7 +96,7 @@ class DijkstraSP { } } - int SelectClosestNode(int64* distance) { + int SelectClosestNode(int64_t* distance) { const int node = frontier_.Top()->node(); *distance = frontier_.Top()->distance(); frontier_.Pop(); @@ -107,14 +107,14 @@ class DijkstraSP { void Update(int node) { for (const auto& other_node : not_visited_) { - const int64 graph_node_i = graph_(node, other_node); + const int64_t graph_node_i = graph_(node, other_node); if (graph_node_i != disconnected_distance_) { if (added_to_the_frontier_.find(other_node) == added_to_the_frontier_.end()) { frontier_.Add(&elements_[other_node]); added_to_the_frontier_.insert(other_node); } - const int64 other_distance = elements_[node].distance() + graph_node_i; + const int64_t other_distance = elements_[node].distance() + graph_node_i; if (elements_[other_node].distance() > other_distance) { elements_[other_node].set_distance(other_distance); frontier_.NoteChangedPriority(&elements_[other_node]); @@ -135,8 +135,8 @@ class DijkstraSP { const int node_count_; const int start_node_; - std::function graph_; - const int64 disconnected_distance_; + std::function graph_; + const int64_t disconnected_distance_; std::unique_ptr predecessor_; AdjustablePriorityQueue frontier_; std::vector elements_; @@ -145,8 +145,8 @@ class DijkstraSP { }; bool DijkstraShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, + std::function graph, + int64_t disconnected_distance, std::vector* nodes) { DijkstraSP> bf( node_count, start_node, std::move(graph), disconnected_distance); @@ -154,8 +154,8 @@ bool DijkstraShortestPath(int node_count, int start_node, int end_node, } bool StableDijkstraShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, + std::function graph, + int64_t disconnected_distance, std::vector* nodes) { DijkstraSP> bf(node_count, start_node, std::move(graph), disconnected_distance); diff --git a/ortools/graph/ebert_graph.h b/ortools/graph/ebert_graph.h index cf4c341b53..afdebdb906 100644 --- a/ortools/graph/ebert_graph.h +++ b/ortools/graph/ebert_graph.h @@ -199,8 +199,8 @@ class ForwardStaticGraph; // type shortcuts here will often come in handy. typedef int32 NodeIndex; typedef int32 ArcIndex; -typedef int64 FlowQuantity; -typedef int64 CostValue; +typedef int64_t FlowQuantity; +typedef int64_t CostValue; typedef EbertGraph StarGraph; typedef ForwardEbertGraph ForwardStarGraph; typedef ForwardStaticGraph ForwardStarStaticGraph; @@ -303,7 +303,7 @@ class StarGraphBase { if (node == kNilNode) { return "NilNode"; } else { - return absl::StrCat(static_cast(node)); + return absl::StrCat(static_cast(node)); } } @@ -311,7 +311,7 @@ class StarGraphBase { if (arc == kNilArc) { return "NilArc"; } else { - return absl::StrCat(static_cast(arc)); + return absl::StrCat(static_cast(arc)); } } @@ -1112,8 +1112,8 @@ class EbertGraphBase void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) { if (!Reserve(max_num_nodes, max_num_arcs)) { LOG(DFATAL) << "Could not reserve memory for " - << static_cast(max_num_nodes) << " nodes and " - << static_cast(max_num_arcs) << " arcs."; + << static_cast(max_num_nodes) << " nodes and " + << static_cast(max_num_arcs) << " arcs."; } first_incident_arc_.SetAll(kNilArc); ThisAsDerived()->InitializeInternal(max_num_nodes, max_num_arcs); diff --git a/ortools/graph/hamiltonian_path.h b/ortools/graph/hamiltonian_path.h index e07bfe34d7..0ac43d0197 100644 --- a/ortools/graph/hamiltonian_path.h +++ b/ortools/graph/hamiltonian_path.h @@ -167,11 +167,11 @@ class Set { } // Returns the number of elements in the set. Uses the 32-bit version for - // types that have 32-bits or less. Specialized for uint64. + // types that have 32-bits or less. Specialized for uint64_t. int Cardinality() const { return BitCount32(value_); } // Returns the index of the smallest element in the set. Uses the 32-bit - // version for types that have 32-bits or less. Specialized for uint64. + // version for types that have 32-bits or less. Specialized for uint64_t. int SmallestElement() const { return LeastSignificantBitPosition32(value_); } // Returns a set equal to the calling object, with its smallest @@ -207,12 +207,12 @@ class Set { }; template <> -inline int Set::SmallestElement() const { +inline int Set::SmallestElement() const { return LeastSignificantBitPosition64(value_); } template <> -inline int Set::Cardinality() const { +inline int Set::Cardinality() const { return BitCount64(value_); } @@ -296,18 +296,18 @@ class LatticeMemoryManager { void Init(int max_card); // Returns the offset in memory for f(s, node), with node contained in s. - uint64 Offset(Set s, int node) const; + uint64_t Offset(Set s, int node) const; // Returns the base offset in memory for f(s, node), with node contained in s. // This is useful in the Dynamic Programming iterations. // Note(user): inlining this function gains about 5%. // TODO(user): Investigate how to compute BaseOffset(card - 1, s \ { n }) // from BaseOffset(card, n) to speed up the DP iteration. - inline uint64 BaseOffset(int card, Set s) const; + inline uint64_t BaseOffset(int card, Set s) const; // Returns the offset delta for a set of cardinality 'card', to which // node 'removed_node' is replaced by 'added_node' at 'rank' - uint64 OffsetDelta(int card, int added_node, int removed_node, + uint64_t OffsetDelta(int card, int added_node, int removed_node, int rank) const { return card * (binomial_coefficients_[added_node][rank] - // delta for added_node @@ -320,7 +320,7 @@ class LatticeMemoryManager { // Memorizes 'value' at 'offset'. This is useful in the Dynamic Programming // iterations where we want to avoid compute the offset of a pair (set, node). - void SetValueAtOffset(uint64 offset, CostType value) { + void SetValueAtOffset(uint64_t offset, CostType value) { memory_[offset] = value; } @@ -330,7 +330,7 @@ class LatticeMemoryManager { // Returns the memorized value at 'offset'. // This is useful in the Dynamic Programming iterations. - CostType ValueAtOffset(uint64 offset) const { return memory_[offset]; } + CostType ValueAtOffset(uint64_t offset) const { return memory_[offset]; } private: // Returns true if the values used to manage memory are set correctly. @@ -342,11 +342,11 @@ class LatticeMemoryManager { int max_card_; // binomial_coefficients_[n][k] contains (n choose k). - std::vector> binomial_coefficients_; + std::vector> binomial_coefficients_; // base_offset_[card] contains the base offset for all f(set, node) with // card(set) == card. - std::vector base_offset_; + std::vector base_offset_; // memory_[Offset(set, node)] contains the costs of the partial path // f(set, node). @@ -391,7 +391,7 @@ void LatticeMemoryManager::Init(int max_card) { template bool LatticeMemoryManager::CheckConsistency() const { for (int n = 0; n <= max_card_; ++n) { - int64 sum = 0; + int64_t sum = 0; for (int k = 0; k <= n; ++k) { sum += binomial_coefficients_[n][k]; } @@ -404,11 +404,11 @@ bool LatticeMemoryManager::CheckConsistency() const { } template -uint64 LatticeMemoryManager::BaseOffset(int card, +uint64_t LatticeMemoryManager::BaseOffset(int card, Set set) const { DCHECK_LT(0, card); DCHECK_EQ(set.Cardinality(), card); - uint64 local_offset = 0; + uint64_t local_offset = 0; int node_rank = 0; for (int node : set) { // There are binomial_coefficients_[node][node_rank + 1] sets which have @@ -428,7 +428,7 @@ uint64 LatticeMemoryManager::BaseOffset(int card, } template -uint64 LatticeMemoryManager::Offset(Set set, int node) const { +uint64_t LatticeMemoryManager::Offset(Set set, int node) const { DCHECK(set.Contains(node)); return BaseOffset(set.Cardinality(), set) + set.ElementRank(node); } @@ -517,32 +517,32 @@ class HamiltonianPathSolver { template // Returns the saturated addition of a and b. It is specialized below for - // int32 and int64. + // int32 and int64_t. struct SaturatedArithmetic { static T Add(T a, T b) { return a + b; } static T Sub(T a, T b) { return a - b; } }; template - struct SaturatedArithmetic { - static int64 Add(int64 a, int64 b) { return CapAdd(a, b); } - static int64 Sub(int64 a, int64 b) { return CapSub(a, b); } + struct SaturatedArithmetic { + static int64_t Add(int64_t a, int64_t b) { return CapAdd(a, b); } + static int64_t Sub(int64_t a, int64_t b) { return CapSub(a, b); } }; // TODO(user): implement this natively in saturated_arithmetic.h template struct SaturatedArithmetic { static int32 Add(int32 a, int32 b) { - const int64 a64 = a; - const int64 b64 = b; - const int64 min_int32 = kint32min; - const int64 max_int32 = kint32max; + const int64_t a64 = a; + const int64_t b64 = b; + const int64_t min_int32 = kint32min; + const int64_t max_int32 = kint32max; return static_cast( std::max(min_int32, std::min(max_int32, a64 + b64))); } static int32 Sub(int32 a, int32 b) { - const int64 a64 = a; - const int64 b64 = b; - const int64 min_int32 = kint32min; - const int64 max_int32 = kint32max; + const int64_t a64 = a; + const int64_t b64 = b; + const int64_t min_int32 = kint32min; + const int64_t max_int32 = kint32max; return static_cast( std::max(min_int32, std::min(max_int32, a64 - b64))); } @@ -669,11 +669,11 @@ void HamiltonianPathSolver::Solve() { for (NodeSet set : SetRangeWithCardinality>(card, num_nodes_)) { // Using BaseOffset and maintaining the node ranks, to reduce the // computational effort for accessing the data. - const uint64 set_offset = mem_.BaseOffset(card, set); + const uint64_t set_offset = mem_.BaseOffset(card, set); // The first subset on which we'll iterate is set.RemoveSmallestElement(). // Compute its offset. It will be updated incrementaly. This saves about // 30-35% of computation time. - uint64 subset_offset = + uint64_t subset_offset = mem_.BaseOffset(card - 1, set.RemoveSmallestElement()); int prev_dest = set.SmallestElement(); int dest_rank = 0; diff --git a/ortools/graph/linear_assignment.cc b/ortools/graph/linear_assignment.cc index 31d24d50c8..9fbb939241 100644 --- a/ortools/graph/linear_assignment.cc +++ b/ortools/graph/linear_assignment.cc @@ -15,7 +15,7 @@ #include "ortools/base/commandlineflags.h" -ABSL_FLAG(int64, assignment_alpha, 5, +ABSL_FLAG(int64_t, assignment_alpha, 5, "Divisor for epsilon at each Refine " "step of LinearSumAssignment."); ABSL_FLAG(int, assignment_progress_logging_period, 5000, diff --git a/ortools/graph/linear_assignment.h b/ortools/graph/linear_assignment.h index b9d292628b..019bac1599 100644 --- a/ortools/graph/linear_assignment.h +++ b/ortools/graph/linear_assignment.h @@ -214,7 +214,7 @@ #include "ortools/util/zvector.h" #ifndef SWIG -ABSL_DECLARE_FLAG(int64, assignment_alpha); +ABSL_DECLARE_FLAG(int64_t, assignment_alpha); ABSL_DECLARE_FLAG(int, assignment_progress_logging_period); ABSL_DECLARE_FLAG(bool, assignment_stack_order); #endif @@ -396,10 +396,10 @@ class LinearSumAssignment { "%d double pushes; %d pushes", refinements_, relabelings_, double_pushes_, pushes_); } - int64 pushes_; - int64 double_pushes_; - int64 relabelings_; - int64 refinements_; + int64_t pushes_; + int64_t double_pushes_; + int64_t relabelings_; + int64_t refinements_; }; #ifndef SWIG diff --git a/ortools/graph/min_cost_flow.cc b/ortools/graph/min_cost_flow.cc index 54254c5bd9..7a7d6a8863 100644 --- a/ortools/graph/min_cost_flow.cc +++ b/ortools/graph/min_cost_flow.cc @@ -26,7 +26,7 @@ // TODO(user): Remove these flags and expose the parameters in the API. // New clients, please do not use these flags! -ABSL_FLAG(int64, min_cost_flow_alpha, 5, +ABSL_FLAG(int64_t, min_cost_flow_alpha, 5, "Divide factor for epsilon at each refine step."); ABSL_FLAG(bool, min_cost_flow_check_feasibility, true, "Check that the graph has enough capacity to send all supplies " @@ -161,13 +161,13 @@ template bool GenericMinCostFlow::CheckInputConsistency() const { FlowQuantity total_supply = 0; - uint64 max_capacity = 0; // uint64 because it is positive and will be used + uint64_t max_capacity = 0; // uint64_t because it is positive and will be used // to check against FlowQuantity overflows. for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) { - const uint64 capacity = static_cast(residual_arc_capacity_[arc]); + const uint64_t capacity = static_cast(residual_arc_capacity_[arc]); max_capacity = std::max(capacity, max_capacity); } - uint64 total_flow = 0; // uint64 for the same reason as max_capacity. + uint64_t total_flow = 0; // uint64_t for the same reason as max_capacity. for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) { const FlowQuantity excess = node_excess_[node]; total_supply += excess; @@ -415,7 +415,7 @@ template CostValue GenericMinCostFlow::UnitCost( ArcIndex arc) const { DCHECK(IsArcValid(arc)); - DCHECK_EQ(uint64{1}, cost_scaling_factor_); + DCHECK_EQ(uint64_t{1}, cost_scaling_factor_); return scaled_arc_unit_cost_[arc]; } diff --git a/ortools/graph/min_cost_flow.h b/ortools/graph/min_cost_flow.h index 60862465ae..86685bffbe 100644 --- a/ortools/graph/min_cost_flow.h +++ b/ortools/graph/min_cost_flow.h @@ -444,7 +444,7 @@ class GenericMinCostFlow : public MinCostFlowBase { // To be used in a DCHECK. bool CheckResult() const; - // Checks that the cost range fits in the range of int64's. + // Checks that the cost range fits in the range of int64_t's. // To be used in a DCHECK. bool CheckCostRange() const; @@ -564,7 +564,7 @@ class GenericMinCostFlow : public MinCostFlowBase { // alpha_ is the factor by which epsilon_ is divided at each iteration of // Refine(). - const int64 alpha_; + const int64_t alpha_; // cost_scaling_factor_ is the scaling factor for cost. CostValue cost_scaling_factor_; diff --git a/ortools/graph/minimum_spanning_tree.h b/ortools/graph/minimum_spanning_tree.h index b92a8415b4..e014634f7a 100644 --- a/ortools/graph/minimum_spanning_tree.h +++ b/ortools/graph/minimum_spanning_tree.h @@ -106,7 +106,7 @@ std::vector BuildKruskalMinimumSpanningTree( // taken by the graph. // Usage: // ListGraph graph(...); -// const auto arc_cost = [&graph](int arc) -> int64 { +// const auto arc_cost = [&graph](int arc) -> int64_t { // return f(graph.Tail(arc), graph.Head(arc)); // }; // std::vector mst = BuildPrimMinimumSpanningTree(graph, arc_cost); diff --git a/ortools/graph/one_tree_lower_bound.h b/ortools/graph/one_tree_lower_bound.h index 921c4eb3eb..f99b658f0b 100644 --- a/ortools/graph/one_tree_lower_bound.h +++ b/ortools/graph/one_tree_lower_bound.h @@ -112,7 +112,7 @@ // on a partial graph is an upper bound to the one on a complete graph). // // Usage: -// std::function cost_function =...; +// std::function cost_function =...; // const double lower_bound = // ComputeOneTreeLowerBound(number_of_nodes, cost_function); // where number_of_nodes is the number of nodes in the TSP and cost_function @@ -213,7 +213,7 @@ class HeldWolfeCrowderEvaluator { step_(0) { // TODO(user): Improve upper bound with some local search; tighter upper // bounds lead to faster convergence. - ChristofidesPathSolver solver( + ChristofidesPathSolver solver( number_of_nodes, cost); upper_bound_ = solver.TravelingSalesmanCost(); } diff --git a/ortools/graph/perfect_matching.cc b/ortools/graph/perfect_matching.cc index 345c417294..43ab367590 100644 --- a/ortools/graph/perfect_matching.cc +++ b/ortools/graph/perfect_matching.cc @@ -24,7 +24,7 @@ void MinCostPerfectMatching::Reset(int num_nodes) { matches_.assign(num_nodes, -1); } -void MinCostPerfectMatching::AddEdgeWithCost(int tail, int head, int64 cost) { +void MinCostPerfectMatching::AddEdgeWithCost(int tail, int head, int64_t cost) { CHECK_GE(cost, 0) << "Not supported for now, just shift your costs."; if (tail == head) { VLOG(1) << "Ignoring self-arc: " << tail << " <-> " << head @@ -50,7 +50,7 @@ MinCostPerfectMatching::Status MinCostPerfectMatching::Solve() { // // TODO(user): Improve the overflow detection if needed. The current one seems // ok though. - int64 overflow_detection = CapAdd(maximum_edge_cost_, maximum_edge_cost_); + int64_t overflow_detection = CapAdd(maximum_edge_cost_, maximum_edge_cost_); if (overflow_detection >= BlossomGraph::kMaxCostValue) { return Status::INTEGER_OVERFLOW; } diff --git a/ortools/graph/perfect_matching.h b/ortools/graph/perfect_matching.h index 78b0c0530f..86903b9ea7 100644 --- a/ortools/graph/perfect_matching.h +++ b/ortools/graph/perfect_matching.h @@ -69,7 +69,7 @@ class MinCostPerfectMatching { // is better to only add one edge with a minimum cost between two nodes. In // particular, do not add both AddEdge(a, b, cost) and AddEdge(b, a, cost). // TODO(user): We could just presolve them away. - void AddEdgeWithCost(int tail, int head, int64 cost); + void AddEdgeWithCost(int tail, int head, int64_t cost); // Solves the min-cost perfect matching problem on the given graph. // @@ -90,7 +90,7 @@ class MinCostPerfectMatching { INTEGER_OVERFLOW = 2, // Advanced usage: the matching is OPTIMAL and was computed without - // overflow, but its OptimalCost() does not fit on an int64. Note that + // overflow, but its OptimalCost() does not fit on an int64_t. Note that // Match() still work and you can re-compute the cost in double for // instance. COST_OVERFLOW = 3, @@ -99,7 +99,7 @@ class MinCostPerfectMatching { // Returns the cost of the perfect macthing. Only valid when the last solve // status was OPTIMAL. - int64 OptimalCost() const { + int64_t OptimalCost() const { DCHECK(optimal_solution_found_); return optimal_cost_; } @@ -123,8 +123,8 @@ class MinCostPerfectMatching { // reclaim the memory of graph_ early or allows to still query the last // solution if we later allow re-solve with incremental changes to the graph. bool optimal_solution_found_ = false; - int64 optimal_cost_ = 0; - int64 maximum_edge_cost_ = 0; + int64_t optimal_cost_ = 0; + int64_t maximum_edge_cost_ = 0; std::vector matches_; }; @@ -167,7 +167,7 @@ class BlossomGraph { // Typed index used by this class. DEFINE_INT_TYPE(NodeIndex, int); DEFINE_INT_TYPE(EdgeIndex, int); - DEFINE_INT_TYPE(CostValue, int64); + DEFINE_INT_TYPE(CostValue, int64_t); // Basic constants. // NOTE(user): Those can't be constexpr because of the or-tools export, @@ -485,11 +485,11 @@ class BlossomGraph { CostValue dual_objective_ = CostValue(0); // Statistics on the main operations. - int64 num_grows_ = 0; - int64 num_augments_ = 0; - int64 num_shrinks_ = 0; - int64 num_expands_ = 0; - int64 num_dual_updates_ = 0; + int64_t num_grows_ = 0; + int64_t num_augments_ = 0; + int64_t num_shrinks_ = 0; + int64_t num_expands_ = 0; + int64_t num_dual_updates_ = 0; }; } // namespace operations_research diff --git a/ortools/graph/shortestpaths.h b/ortools/graph/shortestpaths.h index 0ec6e458d6..7120061195 100644 --- a/ortools/graph/shortestpaths.h +++ b/ortools/graph/shortestpaths.h @@ -35,8 +35,8 @@ namespace operations_research { // will delete it in the end. This function returns true if // 'start_node' and 'end_node' are connected, false otherwise. bool DijkstraShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, std::vector* nodes); + std::function graph, + int64_t disconnected_distance, std::vector* nodes); // Stable version of the Dijsktra Shortest path with callback based description // of the graph. The callback returns the distance between two nodes, a @@ -45,8 +45,8 @@ bool DijkstraShortestPath(int node_count, int start_node, int end_node, // will delete it in the end. This function returns true if // 'start_node' and 'end_node' are connected, false otherwise. bool StableDijkstraShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, + std::function graph, + int64_t disconnected_distance, std::vector* nodes); // Bellman-Ford Shortest path with callback-based description of the @@ -58,8 +58,8 @@ bool StableDijkstraShortestPath(int node_count, int start_node, int end_node, // true, it will fill the 'nodes' vector with the sequence of nodes on // the shortest path between 'start_node' and 'end_node'. bool BellmanFordShortestPath(int node_count, int start_node, int end_node, - std::function graph, - int64 disconnected_distance, + std::function graph, + int64_t disconnected_distance, std::vector* nodes); // A* Shortest path with function based description of the @@ -72,9 +72,9 @@ bool BellmanFordShortestPath(int node_count, int start_node, int end_node, // This function returns true if 'start_node' and 'end_node' are // connected, false otherwise. bool AStarShortestPath(int node_count, int start_node, int end_node, - std::function graph, - std::function heuristic, - int64 disconnected_distance, std::vector* nodes); + std::function graph, + std::function heuristic, + int64_t disconnected_distance, std::vector* nodes); } // namespace operations_research diff --git a/ortools/linear_solver/cplex_interface.cc b/ortools/linear_solver/cplex_interface.cc index 2273485f8a..f0db8ea8d0 100644 --- a/ortools/linear_solver/cplex_interface.cc +++ b/ortools/linear_solver/cplex_interface.cc @@ -97,9 +97,9 @@ class CplexInterface : public MPSolverInterface { // ------ Query statistics on the solution and the solve ------ // Number of simplex iterations - virtual int64 iterations() const; + virtual int64_t iterations() const; // Number of branch-and-bound nodes. Only available for discrete problems. - virtual int64 nodes() const; + virtual int64_t nodes() const; // Returns the basis status of a row. virtual MPSolver::BasisStatus row_status(int constraint_index) const; @@ -592,19 +592,19 @@ void CplexInterface::ClearObjective() { // ------ Query statistics on the solution and the solve ------ -int64 CplexInterface::iterations() const { +int64_t CplexInterface::iterations() const { int iter; if (!CheckSolutionIsSynchronized()) return kUnknownNumberOfIterations; if (mMip) - return static_cast(CPXXgetmipitcnt(mEnv, mLp)); + return static_cast(CPXXgetmipitcnt(mEnv, mLp)); else - return static_cast(CPXXgetitcnt(mEnv, mLp)); + return static_cast(CPXXgetitcnt(mEnv, mLp)); } -int64 CplexInterface::nodes() const { +int64_t CplexInterface::nodes() const { if (mMip) { if (!CheckSolutionIsSynchronized()) return kUnknownNumberOfNodes; - return static_cast(CPXXgetnodecnt(mEnv, mLp)); + return static_cast(CPXXgetnodecnt(mEnv, mLp)); } else { LOG(DFATAL) << "Number of nodes only available for discrete problems"; return kUnknownNumberOfNodes; diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 6509587ef5..a83ab868a9 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -144,9 +144,9 @@ class XpressInterface : public MPSolverInterface { // ------ Query statistics on the solution and the solve ------ // Number of simplex iterations - virtual int64 iterations() const; + virtual int64_t iterations() const; // Number of branch-and-bound nodes. Only available for discrete problems. - virtual int64 nodes() const; + virtual int64_t nodes() const; // Returns the basis status of a row. virtual MPSolver::BasisStatus row_status(int constraint_index) const; @@ -728,15 +728,15 @@ void XpressInterface::ClearObjective() { // ------ Query statistics on the solution and the solve ------ -int64 XpressInterface::iterations() const { +int64_t XpressInterface::iterations() const { if (!CheckSolutionIsSynchronized()) return kUnknownNumberOfIterations; - return static_cast(XPRSgetitcnt(mLp)); + return static_cast(XPRSgetitcnt(mLp)); } -int64 XpressInterface::nodes() const { +int64_t XpressInterface::nodes() const { if (mMip) { if (!CheckSolutionIsSynchronized()) return kUnknownNumberOfNodes; - return static_cast(XPRSgetnodecnt(mLp)); + return static_cast(XPRSgetnodecnt(mLp)); } else { LOG(DFATAL) << "Number of nodes only available for discrete problems"; return kUnknownNumberOfNodes; diff --git a/ortools/lp_data/lp_data.cc b/ortools/lp_data/lp_data.cc index 7b370cbfd7..9b0405fff9 100644 --- a/ortools/lp_data/lp_data.cc +++ b/ortools/lp_data/lp_data.cc @@ -429,7 +429,7 @@ std::string LinearProgram::GetDimensionString() const { return absl::StrFormat( "%d rows, %d columns, %d entries with magnitude in [%e, %e]", num_constraints().value(), num_variables().value(), - // static_cast is needed because the Android port uses int32. + // static_cast is needed because the Android port uses int32. static_cast(num_entries().value()), min_magnitude, max_magnitude); } diff --git a/ortools/lp_data/sparse.h b/ortools/lp_data/sparse.h index 7f32bb55fe..0145005569 100644 --- a/ortools/lp_data/sparse.h +++ b/ortools/lp_data/sparse.h @@ -697,7 +697,7 @@ class TriangularMatrix : private CompactSparseMatrix { SparseColumn* lower, SparseColumn* upper); // This is used to compute the deterministic time of a matrix factorization. - int64 NumFpOperationsInLastPermutedLowerSparseSolve() const { + int64_t NumFpOperationsInLastPermutedLowerSparseSolve() const { return num_fp_operations_; } @@ -779,7 +779,7 @@ class TriangularMatrix : private CompactSparseMatrix { mutable std::vector nodes_to_explore_; // For PermutedLowerSparseSolve(). - int64 num_fp_operations_; + int64_t num_fp_operations_; mutable std::vector lower_column_rows_; mutable std::vector upper_column_rows_; mutable DenseColumn initially_all_zero_scratchpad_; diff --git a/ortools/port/file.cc b/ortools/port/file.cc index 80a36b636a..d2279ad944 100644 --- a/ortools/port/file.cc +++ b/ortools/port/file.cc @@ -64,7 +64,7 @@ bool PortableTemporaryFile(const char* directory_prefix, #else // _MSC_VER int32 pid = 456; #endif // _MSC_VER - int64 now = absl::GetCurrentTimeNanos(); + int64_t now = absl::GetCurrentTimeNanos(); std::string filename = absl::StrFormat("/tmp/parameters-tempfile-%x-%d-%llx", tid, pid, now); return true; diff --git a/ortools/port/sysinfo.cc b/ortools/port/sysinfo.cc index 3fdbe1e1fd..037752be48 100644 --- a/ortools/port/sysinfo.cc +++ b/ortools/port/sysinfo.cc @@ -20,7 +20,7 @@ namespace operations_research { namespace sysinfo { -int64 MemoryUsageProcess() { +int64_t MemoryUsageProcess() { #if defined(__PORTABLE_PLATFORM__) return -1; #else // defined(__PORTABLE_PLATFORM__) diff --git a/ortools/port/sysinfo.h b/ortools/port/sysinfo.h index 64b9ea5c18..7c66fc3bcc 100644 --- a/ortools/port/sysinfo.h +++ b/ortools/port/sysinfo.h @@ -27,7 +27,7 @@ namespace sysinfo { // the case where memory info is not available. // // See base/sysinfo.h MemoryUsage -int64 MemoryUsageProcess(); +int64_t MemoryUsageProcess(); } // namespace sysinfo } // namespace operations_research diff --git a/ortools/sat/cp_model_checker.cc b/ortools/sat/cp_model_checker.cc index 20f75df16f..8949679754 100644 --- a/ortools/sat/cp_model_checker.cc +++ b/ortools/sat/cp_model_checker.cc @@ -103,7 +103,7 @@ std::string ValidateIntegerVariable(const CpModelProto& model, int v) { if (lb < 0 && lb + std::numeric_limits::max() < ub) { return absl::StrCat( "var #", v, - " has a domain that is too large, i.e. |UB - LB| overflow an int64: ", + " has a domain that is too large, i.e. |UB - LB| overflow an int64_t: ", ProtobufShortDebugString(proto)); } diff --git a/ortools/sat/cp_model_expand.cc b/ortools/sat/cp_model_expand.cc index a0b7109ae2..a28fb6ac27 100644 --- a/ortools/sat/cp_model_expand.cc +++ b/ortools/sat/cp_model_expand.cc @@ -433,7 +433,7 @@ void ExpandInverse(ConstraintProto* ct, PresolveContext* context) { const Domain domain = context->DomainOf(direct[i]); bool removed_value = false; for (const ClosedInterval& interval : domain) { - for (int64 j = interval.start; j <= interval.end; ++j) { + for (int64_t j = interval.start; j <= interval.end; ++j) { if (context->DomainOf(inverse[j]).Contains(i)) { possible_values.push_back(j); } else { diff --git a/ortools/sat/cp_model_loader.cc b/ortools/sat/cp_model_loader.cc index 047d5f23fa..384ddfc2fa 100644 --- a/ortools/sat/cp_model_loader.cc +++ b/ortools/sat/cp_model_loader.cc @@ -60,7 +60,7 @@ namespace sat { namespace { template -std::vector ValuesFromProto(const Values& values) { +std::vector ValuesFromProto(const Values& values) { return std::vector(values.begin(), values.end()); } diff --git a/ortools/sat/cp_model_presolve.cc b/ortools/sat/cp_model_presolve.cc index 79cff85aa7..f4dadda855 100644 --- a/ortools/sat/cp_model_presolve.cc +++ b/ortools/sat/cp_model_presolve.cc @@ -3159,7 +3159,7 @@ bool CpModelPresolver::PresolveCumulative(ConstraintProto* ct) { context_->UpdateRuleStats("cumulative: propagate min capacity."); if (!context_->IntersectDomainWith( capacity_ref, Domain(max_of_performed_demand_mins, - std::numeric_limits::max()))) { + std::numeric_limits::max()))) { return true; } } @@ -4447,7 +4447,7 @@ void CpModelPresolver::TransformIntoMaxCliques() { } } - int64 num_literals_before = 0; + int64_t num_literals_before = 0; const int num_old_cliques = cliques.size(); // We reuse the max-clique code from sat. @@ -4482,7 +4482,7 @@ void CpModelPresolver::TransformIntoMaxCliques() { } int num_new_cliques = 0; - int64 num_literals_after = 0; + int64_t num_literals_after = 0; for (const std::vector& clique : cliques) { if (clique.empty()) continue; num_new_cliques++; diff --git a/ortools/sat/cp_model_search.cc b/ortools/sat/cp_model_search.cc index 7f7ac54f18..0d882675d9 100644 --- a/ortools/sat/cp_model_search.cc +++ b/ortools/sat/cp_model_search.cc @@ -268,7 +268,7 @@ std::function InstrumentSearchStrategy( IntegerTrail* integer_trail = model->GetOrCreate(); for (const int ref : ref_to_display) { const IntegerVariable var = variable_mapping[ref]; - const std::pair new_domain( + const std::pair new_domain( integer_trail->LowerBound(var).value(), integer_trail->UpperBound(var).value()); if (new_domain != old_domains[ref]) { diff --git a/ortools/sat/cp_model_solver.cc b/ortools/sat/cp_model_solver.cc index 24c1edd623..78b28124fb 100644 --- a/ortools/sat/cp_model_solver.cc +++ b/ortools/sat/cp_model_solver.cc @@ -968,8 +968,8 @@ void RegisterVariableBoundsLevelZeroExport( CpModelMapping* const mapping = model->GetOrCreate(); std::vector model_variables; - std::vector new_lower_bounds; - std::vector new_upper_bounds; + std::vector new_lower_bounds; + std::vector new_upper_bounds; absl::flat_hash_set visited_variables; // Inspect the modified IntegerVariables. @@ -986,11 +986,11 @@ void RegisterVariableBoundsLevelZeroExport( } visited_variables.insert(model_var); - const int64 new_lb = + const int64_t new_lb = integer_trail->LevelZeroLowerBound(positive_var).value(); - const int64 new_ub = + const int64_t new_ub = integer_trail->LevelZeroUpperBound(positive_var).value(); - // TODO(user): We could imagine an API based on atomic + // TODO(user): We could imagine an API based on atomic // that could preemptively check if this new bounds are improving. model_variables.push_back(model_var); new_lower_bounds.push_back(new_lb); @@ -1067,8 +1067,8 @@ void RegisterVariableBoundsLevelZeroImport( const auto& import_level_zero_bounds = [&model_proto, shared_bounds_manager, model, integer_trail, id, mapping]() { std::vector model_variables; - std::vector new_lower_bounds; - std::vector new_upper_bounds; + std::vector new_lower_bounds; + std::vector new_upper_bounds; shared_bounds_manager->GetChangedBounds( id, &model_variables, &new_lower_bounds, &new_upper_bounds); bool new_bounds_have_been_imported = false; @@ -2457,13 +2457,13 @@ class LnsSolver : public SubSolver { // Choose a base solution for this neighborhood. CpSolverResponse base_response; { - const SharedSolutionRepository& repo = + const SharedSolutionRepository& repo = shared_->response->SolutionsRepository(); if (repo.NumSolutions() > 0) { base_response.set_status(CpSolverStatus::FEASIBLE); - const SharedSolutionRepository::Solution solution = + const SharedSolutionRepository::Solution solution = repo.GetRandomBiasedSolution(random); - for (const int64 value : solution.variable_values) { + for (const int64_t value : solution.variable_values) { base_response.add_solution(value); } // Note: We assume that the solution rank is the solution internal @@ -2493,7 +2493,7 @@ class LnsSolver : public SubSolver { const double fully_solved_proportion = static_cast(generator_->num_fully_solved_calls()) / - std::max(int64{1}, generator_->num_calls()); + std::max(int64_t{1}, generator_->num_calls()); std::string source_info = name(); if (!neighborhood.source_info.empty()) { absl::StrAppend(&source_info, "_", neighborhood.source_info); @@ -2524,7 +2524,7 @@ class LnsSolver : public SubSolver { local_time_limit->ResetLimitFromParameters(local_params); shared_->time_limit->UpdateLocalLimit(local_time_limit); - const int64 num_neighborhood_model_vars = + const int64_t num_neighborhood_model_vars = neighborhood.cp_model.variables_size(); // Presolve and solve the LNS fragment. CpModelProto mapping_proto; @@ -2600,7 +2600,7 @@ class LnsSolver : public SubSolver { if (has_feasible_solution) { if (SolutionIsFeasible( *shared_->model_proto, - std::vector(local_response.solution().begin(), + std::vector(local_response.solution().begin(), local_response.solution().end()))) { shared_->response->NewSolution(local_response, /*model=*/nullptr); @@ -2618,7 +2618,7 @@ class LnsSolver : public SubSolver { if (!local_response.solution().empty()) { CHECK(SolutionIsFeasible( *shared_->model_proto, - std::vector(local_response.solution().begin(), + std::vector(local_response.solution().begin(), local_response.solution().end()))) << solution_info; } @@ -3127,7 +3127,7 @@ CpSolverResponse SolveCpModel(const CpModelProto& model_proto, Model* model) { if (!response->solution().empty()) { CHECK( SolutionIsFeasible(model_proto, - std::vector(response->solution().begin(), + std::vector(response->solution().begin(), response->solution().end()), &mapping_proto, &postsolve_mapping)) << "final postsolved solution"; @@ -3193,7 +3193,7 @@ CpSolverResponse SolveCpModel(const CpModelProto& model_proto, Model* model) { if (DEBUG_MODE || absl::GetFlag(FLAGS_cp_model_check_intermediate_solutions)) { CHECK(SolutionIsFeasible( - model_proto, std::vector(response.solution().begin(), + model_proto, std::vector(response.solution().begin(), response.solution().end()))); } } diff --git a/ortools/sat/cp_model_symmetries.cc b/ortools/sat/cp_model_symmetries.cc index 6b9b0fecc3..9caaab66c6 100644 --- a/ortools/sat/cp_model_symmetries.cc +++ b/ortools/sat/cp_model_symmetries.cc @@ -60,11 +60,11 @@ class IdGenerator { // Appends values in `repeated_field` to `vector`. // -// We use a template as proto int64 != C++ int64 in open source. +// We use a template as proto int64_t != C++ int64_t in open source. template void Append( const google::protobuf::RepeatedField& repeated_field, - std::vector* vector) { + std::vector* vector) { CHECK(vector != nullptr); for (const FieldInt64Type value : repeated_field) { vector->push_back(value); @@ -98,7 +98,7 @@ std::unique_ptr GenerateGraphForSymmetryDetection( // can never be send one into another by a symmetry. The first element of // the color vector will always be the NodeType. // - // TODO(user): Using a full int64 for storing 3 values is not great. We + // TODO(user): Using a full int64_t for storing 3 values is not great. We // can optimize this at the price of a bit more code. enum NodeType { VARIABLE_NODE, @@ -108,7 +108,7 @@ std::unique_ptr GenerateGraphForSymmetryDetection( IdGenerator color_id_generator; initial_equivalence_classes->clear(); auto new_node = [&initial_equivalence_classes, &graph, - &color_id_generator](const std::vector& color) { + &color_id_generator](const std::vector& color) { // Since we add nodes one by one, initial_equivalence_classes->size() gives // the number of nodes at any point, which we use as the next node index. const int node = initial_equivalence_classes->size(); @@ -145,9 +145,9 @@ std::unique_ptr GenerateGraphForSymmetryDetection( // We will lazily create "coefficient nodes" that correspond to a variable // with a given coefficient. - absl::flat_hash_map, int> coefficient_nodes; + absl::flat_hash_map, int> coefficient_nodes; auto get_coefficient_node = [&new_node, &graph, &coefficient_nodes, - &tmp_color](int var, int64 coeff) { + &tmp_color](int var, int64_t coeff) { const int var_node = var; DCHECK(RefIsPositive(var)); @@ -190,7 +190,7 @@ std::unique_ptr GenerateGraphForSymmetryDetection( auto get_implication_node = [&new_node, &graph, &coefficient_nodes, &tmp_color](int ref) { const int var = PositiveRef(ref); - const int64 coeff = RefIsPositive(ref) ? 1 : -1; + const int64_t coeff = RefIsPositive(ref) ? 1 : -1; const auto insert = coefficient_nodes.insert({std::make_pair(var, coeff), 0}); if (!insert.second) return insert.first->second; diff --git a/ortools/sat/cuts.cc b/ortools/sat/cuts.cc index 466bc69907..3c752c6b39 100644 --- a/ortools/sat/cuts.cc +++ b/ortools/sat/cuts.cc @@ -477,7 +477,7 @@ CutGenerator CreateKnapsackCoverCutGenerator( KnapsackSolverForCuts knapsack_solver( "Knapsack on demand cover cut generator"); - int64 skipped_constraints = 0; + int64_t skipped_constraints = 0; LinearConstraint mutable_constraint; // Iterate through all knapsack constraints. @@ -1341,13 +1341,13 @@ CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z, [z, x, y, integer_trail]( const absl::StrongVector& lp_values, LinearConstraintManager* manager) { - const int64 x_lb = integer_trail->LevelZeroLowerBound(x).value(); - const int64 x_ub = integer_trail->LevelZeroUpperBound(x).value(); - const int64 y_lb = integer_trail->LevelZeroLowerBound(y).value(); - const int64 y_ub = integer_trail->LevelZeroUpperBound(y).value(); + const int64_t x_lb = integer_trail->LevelZeroLowerBound(x).value(); + const int64_t x_ub = integer_trail->LevelZeroUpperBound(x).value(); + const int64_t y_lb = integer_trail->LevelZeroLowerBound(y).value(); + const int64_t y_ub = integer_trail->LevelZeroUpperBound(y).value(); // TODO(user): Compute a better bound (int_max / 4 ?). - const int64 kMaxSafeInteger = (int64{1} << 53) - 1; + const int64_t kMaxSafeInteger = (int64_t{1} << 53) - 1; if (CapProd(x_ub, y_ub) >= kMaxSafeInteger) { VLOG(3) << "Potential overflow in PositiveMultiplicationCutGenerator"; @@ -1366,7 +1366,7 @@ CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z, // Cut -z + x_coeff * x + y_coeff* y <= rhs auto try_add_above_cut = [manager, z_lp_value, x_lp_value, y_lp_value, x, y, z, &lp_values]( - int64 x_coeff, int64 y_coeff, int64 rhs) { + int64_t x_coeff, int64_t y_coeff, int64_t rhs) { if (-z_lp_value + x_lp_value * x_coeff + y_lp_value * y_coeff >= rhs + kMinCutViolation) { LinearConstraint cut; @@ -1389,7 +1389,7 @@ CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z, // Cut -z + x_coeff * x + y_coeff* y >= rhs auto try_add_below_cut = [manager, z_lp_value, x_lp_value, y_lp_value, x, y, z, &lp_values]( - int64 x_coeff, int64 y_coeff, int64 rhs) { + int64_t x_coeff, int64_t y_coeff, int64_t rhs) { if (-z_lp_value + x_lp_value * x_coeff + y_lp_value * y_coeff <= rhs - kMinCutViolation) { LinearConstraint cut; @@ -1435,13 +1435,13 @@ CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x, [y, x, integer_trail]( const absl::StrongVector& lp_values, LinearConstraintManager* manager) { - const int64 x_ub = integer_trail->LevelZeroUpperBound(x).value(); - const int64 x_lb = integer_trail->LevelZeroLowerBound(x).value(); + const int64_t x_ub = integer_trail->LevelZeroUpperBound(x).value(); + const int64_t x_lb = integer_trail->LevelZeroLowerBound(x).value(); if (x_lb == x_ub) return; // Check for potential overflows. - if (x_ub > (int64{1} << 31)) return; + if (x_ub > (int64_t{1} << 31)) return; DCHECK_GE(x_lb, 0); const double y_lp_value = lp_values[y]; @@ -1450,8 +1450,8 @@ CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x, // First cut: target should be below the line: // (x_lb, x_lb ^ 2) to (x_ub, x_ub ^ 2). // The slope of that line is (ub^2 - lb^2) / (ub - lb) = ub + lb. - const int64 y_lb = x_lb * x_lb; - const int64 above_slope = x_ub + x_lb; + const int64_t y_lb = x_lb * x_lb; + const int64_t above_slope = x_ub + x_lb; const double max_lp_y = y_lb + above_slope * (x_lp_value - x_lb); if (y_lp_value >= max_lp_y + kMinCutViolation) { // cut: y <= (x_lb + x_ub) * x - x_lb * x_ub @@ -1471,8 +1471,8 @@ CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x, // // Note that we only add one of these cuts. The one for x_lp_value in // [value, value + 1]. - const int64 x_floor = static_cast(std::floor(x_lp_value)); - const int64 below_slope = 2 * x_floor + 1; + const int64_t x_floor = static_cast(std::floor(x_lp_value)); + const int64_t below_slope = 2 * x_floor + 1; const double min_lp_y = below_slope * x_lp_value - x_floor - x_floor * x_floor; if (min_lp_y >= y_lp_value + kMinCutViolation) { diff --git a/ortools/sat/integer.h b/ortools/sat/integer.h index e49808e47f..182de15a18 100644 --- a/ortools/sat/integer.h +++ b/ortools/sat/integer.h @@ -579,7 +579,7 @@ class IntegerTrail : public SatPropagator { // the decision level is zero (checked). The given bounds are INCLUSIVE and // must not cross. // - // Note on integer overflow: 'upper_bound - lower_bound' must fit on an int64, + // Note on integer overflow: 'upper_bound - lower_bound' must fit on an int64_t, // this is DCHECKed. More generally, depending on the constraints that are // added, the bounds magnitude must be small enough to satisfy each constraint // overflow precondition. @@ -1409,7 +1409,7 @@ inline void GenericLiteralWatcher::WatchIntegerVariable(IntegerVariable i, // ============================================================================ // Model based functions. // -// Note that in the model API, we simply use int64 for the integer values, so +// Note that in the model API, we simply use int64_t for the integer values, so // that it is nicer for the client. Internally these are converted to // IntegerValue which is typechecked. // ============================================================================ diff --git a/ortools/sat/integer_expr.cc b/ortools/sat/integer_expr.cc index 7ad5193cbc..cae54b7fe8 100644 --- a/ortools/sat/integer_expr.cc +++ b/ortools/sat/integer_expr.cc @@ -882,8 +882,8 @@ std::function IsOneOf(IntegerVariable var, CHECK(!values.empty()); CHECK_EQ(values.size(), selectors.size()); - std::vector unique_values; - absl::flat_hash_map> value_to_selector; + std::vector unique_values; + absl::flat_hash_map> value_to_selector; for (int i = 0; i < values.size(); ++i) { unique_values.push_back(values[i].value()); value_to_selector[values[i].value()].push_back(selectors[i]); @@ -898,7 +898,7 @@ std::function IsOneOf(IntegerVariable var, // Note that it is more efficient to call AssociateToIntegerEqualValue() // with the values ordered, like we do here. - for (const int64 v : unique_values) { + for (const int64_t v : unique_values) { const std::vector& selectors = value_to_selector[v]; if (selectors.size() == 1) { encoder->AssociateToIntegerEqualValue(selectors[0], var, diff --git a/ortools/sat/integer_expr.h b/ortools/sat/integer_expr.h index 5fbc7eb597..d0b453b0bd 100644 --- a/ortools/sat/integer_expr.h +++ b/ortools/sat/integer_expr.h @@ -354,14 +354,14 @@ inline std::function WeightedSumLowerOrEqual( for (int b = 0; b < num_buckets; ++b) { local_vars.clear(); local_coeffs.clear(); - int64 bucket_lb = 0; - int64 bucket_ub = 0; + int64_t bucket_lb = 0; + int64_t bucket_ub = 0; const int limit = num_vars * (b + 1); for (; i * num_buckets < limit; ++i) { local_vars.push_back(vars[i]); local_coeffs.push_back(IntegerValue(coefficients[i])); - const int64 term1 = model->Get(LowerBound(vars[i])) * coefficients[i]; - const int64 term2 = model->Get(UpperBound(vars[i])) * coefficients[i]; + const int64_t term1 = model->Get(LowerBound(vars[i])) * coefficients[i]; + const int64_t term2 = model->Get(UpperBound(vars[i])) * coefficients[i]; bucket_lb += std::min(term1, term2); bucket_ub += std::max(term1, term2); } @@ -635,7 +635,7 @@ inline std::function WeightedSumNotEqual( // given weighted sum of other IntegerVariables. // // Note that this is templated so that it can seamlessly accept vector or -// vector. +// vector. // // TODO(user): invert the coefficients/vars arguments. template @@ -647,8 +647,8 @@ inline std::function NewWeightedSum( // compute the basic bounds on the sum. // // TODO(user): deal with overflow here too! - int64 sum_lb(0); - int64 sum_ub(0); + int64_t sum_lb(0); + int64_t sum_ub(0); for (int i = 0; i < new_vars.size(); ++i) { if (coefficients[i] > 0) { sum_lb += coefficients[i] * model->Get(LowerBound(new_vars[i])); @@ -661,7 +661,7 @@ inline std::function NewWeightedSum( const IntegerVariable sum = model->Add(NewIntegerVariable(sum_lb, sum_ub)); new_vars.push_back(sum); - std::vector new_coeffs(coefficients.begin(), coefficients.end()); + std::vector new_coeffs(coefficients.begin(), coefficients.end()); new_coeffs.push_back(-1); model->Add(FixedWeightedSum(new_vars, new_coeffs, 0)); return sum; @@ -709,7 +709,7 @@ inline std::function IsEqualToMinOf( // min_var = min_expr std::vector min_sum_vars = min_expr.vars; - std::vector min_sum_coeffs; + std::vector min_sum_coeffs; for (IntegerValue coeff : min_expr.coeffs) { min_sum_coeffs.push_back(coeff.value()); } @@ -722,7 +722,7 @@ inline std::function IsEqualToMinOf( for (const LinearExpression& expr : exprs) { // min_var <= expr std::vector vars = expr.vars; - std::vector coeffs; + std::vector coeffs; for (IntegerValue coeff : expr.coeffs) { coeffs.push_back(coeff.value()); } diff --git a/ortools/sat/linear_programming_constraint.cc b/ortools/sat/linear_programming_constraint.cc index 648a76e986..7534549444 100644 --- a/ortools/sat/linear_programming_constraint.cc +++ b/ortools/sat/linear_programming_constraint.cc @@ -1821,7 +1821,7 @@ LinearProgrammingConstraint::ScaleLpMultiplier( return integer_multipliers; } - // We want max_sum * scaling to be <= 2 ^ max_pow and fit on an int64. + // We want max_sum * scaling to be <= 2 ^ max_pow and fit on an int64_t. // We use a power of 2 as this seems to work better. const double threshold = std::ldexp(1, max_pow) / max_sum; if (threshold < 1.0) { diff --git a/ortools/sat/lp_utils.cc b/ortools/sat/lp_utils.cc index 05c1f9e625..497d331938 100644 --- a/ortools/sat/lp_utils.cc +++ b/ortools/sat/lp_utils.cc @@ -608,7 +608,7 @@ ConstraintProto* ConstraintScaler::AddConstraint( max_relative_rhs_error, scaled_sum_error / (scaling_factor * ct_norm)); // Add the constraint bounds. Because we are sure the scaled constraint fit - // on an int64, if the scaled bounds are too large, the constraint is either + // on an int64_t, if the scaled bounds are too large, the constraint is either // always true or always false. if (relax_bound) { lb -= std::max(std::abs(lb), 1.0) * wanted_precision; @@ -969,7 +969,7 @@ bool ConvertBinaryMPModelProtoToBooleanProblem(const MPModelProto& mp_model, } } - // Variables needed to scale the double coefficients into int64. + // Variables needed to scale the double coefficients into int64_t. const int64_t kInt64Max = std::numeric_limits::max(); double max_relative_error = 0.0; double max_bound_error = 0.0; @@ -1010,7 +1010,7 @@ bool ConvertBinaryMPModelProtoToBooleanProblem(const MPModelProto& mp_model, // Add the bounds. Note that we do not pass them to // GetBestScalingOfDoublesToInt64() because we know that the sum of absolute - // coefficients of the constraint fit on an int64. If one of the scaled + // coefficients of the constraint fit on an int64_t. If one of the scaled // bound overflows, we don't care by how much because in this case the // constraint is just trivial or unsatisfiable. const Fractional lb = mp_constraint.lower_bound(); @@ -1085,7 +1085,7 @@ bool ConvertBinaryMPModelProtoToBooleanProblem(const MPModelProto& mp_model, // Test the precision of the conversion. const double kRelativeTolerance = 1e-8; if (max_relative_error > kRelativeTolerance) { - LOG(WARNING) << "The relative error during double -> int64 conversion " + LOG(WARNING) << "The relative error during double -> int64_t conversion " << "is too high!"; return false; } diff --git a/ortools/sat/presolve_util.cc b/ortools/sat/presolve_util.cc index 5b5705fd96..772a8338f4 100644 --- a/ortools/sat/presolve_util.cc +++ b/ortools/sat/presolve_util.cc @@ -104,7 +104,7 @@ namespace { template int64_t GetVarCoeffAndCopyOtherTerms( const int var, const ProtoWithVarsAndCoeffs& proto, - std::vector>* terms) { + std::vector>* terms) { bool found = false; int64_t var_coeff = 0; const int size = proto.vars().size(); @@ -132,7 +132,7 @@ int64_t GetVarCoeffAndCopyOtherTerms( // Helper method for variable substituion. Sorts and merges the terms in 'terms' // and adds them to 'proto'. template -void SortAndMergeTerms(std::vector>* terms, +void SortAndMergeTerms(std::vector>* terms, ProtoWithVarsAndCoeffs* proto) { proto->clear_vars(); proto->clear_coeffs(); diff --git a/ortools/sat/python/cp_model_helper.py b/ortools/sat/python/cp_model_helper.py index 6e3a7cf6fa..59e7b6f6dd 100644 --- a/ortools/sat/python/cp_model_helper.py +++ b/ortools/sat/python/cp_model_helper.py @@ -29,7 +29,7 @@ def AssertIsInt64(x): if not isinstance(x, numbers.Integral): raise TypeError('Not an integer: %s' % x) if x < INT_MIN or x > INT_MAX: - raise OverflowError('Does not fit in an int64: %s' % x) + raise OverflowError('Does not fit in an int64_t: %s' % x) def AssertIsInt32(x): @@ -56,7 +56,7 @@ def CapInt64(v): def CapSub(x, y): - """Saturated arithmetics. Returns x - y truncated to the int64 range.""" + """Saturated arithmetics. Returns x - y truncated to the int64_t range.""" AssertIsInt64(x) AssertIsInt64(y) if y == 0: diff --git a/ortools/sat/swig_helper.h b/ortools/sat/swig_helper.h index d98ee25cd6..32046f0459 100644 --- a/ortools/sat/swig_helper.h +++ b/ortools/sat/swig_helper.h @@ -43,17 +43,17 @@ class SolutionCallback { OnSolutionCallback(); } - int64 NumBooleans() const { return response_.num_booleans(); } + int64_t NumBooleans() const { return response_.num_booleans(); } - int64 NumBranches() const { return response_.num_branches(); } + int64_t NumBranches() const { return response_.num_branches(); } - int64 NumConflicts() const { return response_.num_conflicts(); } + int64_t NumConflicts() const { return response_.num_conflicts(); } - int64 NumBinaryPropagations() const { + int64_t NumBinaryPropagations() const { return response_.num_binary_propagations(); } - int64 NumIntegerPropagations() const { + int64_t NumIntegerPropagations() const { return response_.num_integer_propagations(); } @@ -67,7 +67,7 @@ class SolutionCallback { double BestObjectiveBound() const { return response_.best_objective_bound(); } - int64 SolutionIntegerValue(int index) { + int64_t SolutionIntegerValue(int index) { return index >= 0 ? response_.solution(index) : -response_.solution(-index - 1); } diff --git a/ortools/sat/table.cc b/ortools/sat/table.cc index b685b84526..0d651d2f5f 100644 --- a/ortools/sat/table.cc +++ b/ortools/sat/table.cc @@ -602,10 +602,10 @@ std::function TransitionConstraint( // Test precondition. { - std::set> unique_transition_checker; - for (const std::vector& transition : automaton) { + std::set> unique_transition_checker; + for (const std::vector& transition : automaton) { CHECK_EQ(transition.size(), 3); - const std::pair p{transition[0], transition[1]}; + const std::pair p{transition[0], transition[1]}; CHECK(!gtl::ContainsKey(unique_transition_checker, p)) << "Duplicate outgoing transitions with value " << transition[1] << " from state " << transition[0] << "."; @@ -614,10 +614,10 @@ std::function TransitionConstraint( } // Construct a table with the possible values of each vars. - std::vector> possible_values(n); + std::vector> possible_values(n); for (int time = 0; time < n; ++time) { const auto domain = integer_trail->InitialVariableDomain(vars[time]); - for (const std::vector& transition : automaton) { + for (const std::vector& transition : automaton) { // TODO(user): quadratic algo, improve! if (domain.Contains(transition[1])) { possible_values[time].insert(transition[1]); @@ -626,7 +626,7 @@ std::function TransitionConstraint( } // Compute the set of reachable state at each time point. - std::vector> reachable_states(n + 1); + std::vector> reachable_states(n + 1); reachable_states[0].insert(initial_state); reachable_states[n] = {final_states.begin(), final_states.end()}; @@ -635,7 +635,7 @@ std::function TransitionConstraint( // TODO(user): filter using the domain of vars[time] that may not contain // all the possible transitions. for (int time = 0; time + 1 < n; ++time) { - for (const std::vector& transition : automaton) { + for (const std::vector& transition : automaton) { if (!gtl::ContainsKey(reachable_states[time], transition[0])) continue; if (!gtl::ContainsKey(possible_values[time], transition[1])) continue; reachable_states[time + 1].insert(transition[2]); @@ -644,8 +644,8 @@ std::function TransitionConstraint( // Backward. for (int time = n - 1; time > 0; --time) { - std::set new_set; - for (const std::vector& transition : automaton) { + std::set new_set; + for (const std::vector& transition : automaton) { if (!gtl::ContainsKey(reachable_states[time], transition[0])) continue; if (!gtl::ContainsKey(possible_values[time], transition[1])) continue; if (!gtl::ContainsKey(reachable_states[time + 1], transition[2])) @@ -671,7 +671,7 @@ std::function TransitionConstraint( std::vector in_states; std::vector transition_values; std::vector out_states; - for (const std::vector& transition : automaton) { + for (const std::vector& transition : automaton) { if (!gtl::ContainsKey(reachable_states[time], transition[0])) continue; if (!gtl::ContainsKey(possible_values[time], transition[1])) continue; if (!gtl::ContainsKey(reachable_states[time + 1], transition[2])) @@ -702,7 +702,7 @@ std::function TransitionConstraint( encoding.clear(); if (s.size() > 1) { - std::vector values; + std::vector values; values.reserve(s.size()); for (IntegerValue v : s) values.push_back(v.value()); integer_trail->UpdateInitialDomain(vars[time], @@ -712,7 +712,7 @@ std::function TransitionConstraint( } else { // Fix vars[time] to its unique possible value. CHECK_EQ(s.size(), 1); - const int64 unique_value = s.begin()->value(); + const int64_t unique_value = s.begin()->value(); model->Add(LowerOrEqual(vars[time], unique_value)); model->Add(GreaterOrEqual(vars[time], unique_value)); } diff --git a/ortools/sat/theta_tree.h b/ortools/sat/theta_tree.h index d792e39620..3e3f09ad5b 100644 --- a/ortools/sat/theta_tree.h +++ b/ortools/sat/theta_tree.h @@ -25,7 +25,7 @@ namespace sat { // The Theta-Lambda tree can be used to implement several scheduling algorithms. // -// This template class is instantiated only for IntegerValue and int64. +// This template class is instantiated only for IntegerValue and int64_t. // // The tree structure itself is a binary tree coded in a vector, where node 0 is // unused, node 1 is the root, node 2 is the left child of the root, node 3 its diff --git a/ortools/sat/var_domination.h b/ortools/sat/var_domination.h index 00b8c95c8a..9c0043a8d9 100644 --- a/ortools/sat/var_domination.h +++ b/ortools/sat/var_domination.h @@ -165,7 +165,7 @@ class VarDomination { // start of the first variable in tmp_ranks_ with this rank. // // Note that the rank should be int, but to reuse the same vector when we - // construct it, we need int64. See FillTempRanks(). + // construct it, we need int64_t. See FillTempRanks(). std::vector tmp_ranks_; // This do not change after EndFirstPhase(). diff --git a/ortools/util/affine_relation.h b/ortools/util/affine_relation.h index ff3f6d4f36..6b39da9322 100644 --- a/ortools/util/affine_relation.h +++ b/ortools/util/affine_relation.h @@ -64,20 +64,20 @@ class AffineRelation { // // IMPORTANT: we do not check for integer overflow, but that could be added // if it is needed. - bool TryAdd(int x, int y, int64 coeff, int64 offset); + bool TryAdd(int x, int y, int64_t coeff, int64_t offset); // Same as TryAdd() with the option to disallow the use of a given // representative. - bool TryAdd(int x, int y, int64 coeff, int64 offset, bool allow_rep_x, + bool TryAdd(int x, int y, int64_t coeff, int64_t offset, bool allow_rep_x, bool allow_rep_y); // Returns a valid relation of the form x = coeff * representative + offset. // Note that this can return x = x. Non-const because of path-compression. struct Relation { int representative; - int64 coeff; - int64 offset; - Relation(int r, int64 c, int64 o) + int64_t coeff; + int64_t offset; + Relation(int r, int64_t c, int64_t o) : representative(r), coeff(c), offset(o) {} const bool operator==(const Relation& other) const { return representative == other.representative && coeff == other.coeff && @@ -146,8 +146,8 @@ class AffineRelation { // The offset and coefficient such that // variable[index] = coeff * variable[representative_[index]] + offset; - mutable std::vector coeff_; - mutable std::vector offset_; + mutable std::vector coeff_; + mutable std::vector offset_; // The size of each representative "tree", used to get a good complexity when // we have the choice of which tree to merge into the other. @@ -161,11 +161,11 @@ class AffineRelation { mutable std::vector tmp_path_; }; -inline bool AffineRelation::TryAdd(int x, int y, int64 coeff, int64 offset) { +inline bool AffineRelation::TryAdd(int x, int y, int64_t coeff, int64_t offset) { return TryAdd(x, y, coeff, offset, true, true); } -inline bool AffineRelation::TryAdd(int x, int y, int64 coeff, int64 offset, +inline bool AffineRelation::TryAdd(int x, int y, int64_t coeff, int64_t offset, bool allow_rep_x, bool allow_rep_y) { CHECK_NE(coeff, 0); CHECK_NE(x, y); @@ -183,9 +183,9 @@ inline bool AffineRelation::TryAdd(int x, int y, int64 coeff, int64 offset, // TODO(user): It should be possible to optimize this code block a bit, for // instance depending on the magnitude of new_coeff vs coeff_x, we may already // know that one of the two merge is not possible. - const int64 coeff_x = coeff_[x]; - const int64 new_coeff = coeff * coeff_[y]; - const int64 new_offset = coeff * offset_[y] + offset - offset_[x]; + const int64_t coeff_x = coeff_[x]; + const int64_t new_coeff = coeff * coeff_[y]; + const int64_t new_offset = coeff * offset_[y] + offset - offset_[x]; const bool condition1 = allow_rep_y && (new_coeff % coeff_x == 0) && (new_offset % coeff_x == 0); const bool condition2 = allow_rep_x && (coeff_x % new_coeff == 0) && diff --git a/ortools/util/bitset.h b/ortools/util/bitset.h index e9b10c58ce..cadd692b20 100644 --- a/ortools/util/bitset.h +++ b/ortools/util/bitset.h @@ -30,20 +30,20 @@ namespace operations_research { // Basic bit operations // Useful constants: word and double word will all bits set. -static const uint64 kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF}; -static const uint64 kAllBitsButLsb64 = uint64_t{0xFFFFFFFFFFFFFFFE}; +static const uint64_t kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF}; +static const uint64_t kAllBitsButLsb64 = uint64_t{0xFFFFFFFFFFFFFFFE}; static const uint32 kAllBits32 = 0xFFFFFFFFU; // Returns a word with only bit pos set. -inline uint64 OneBit64(int pos) { return uint64_t{1} << pos; } +inline uint64_t OneBit64(int pos) { return uint64_t{1} << pos; } inline uint32 OneBit32(int pos) { return 1U << pos; } // Returns the number of bits set in n. -inline uint64 BitCount64(uint64 n) { - const uint64 m1 = uint64_t{0x5555555555555555}; - const uint64 m2 = uint64_t{0x3333333333333333}; - const uint64 m4 = uint64_t{0x0F0F0F0F0F0F0F0F}; - const uint64 h01 = uint64_t{0x0101010101010101}; +inline uint64_t BitCount64(uint64_t n) { + const uint64_t m1 = uint64_t{0x5555555555555555}; + const uint64_t m2 = uint64_t{0x3333333333333333}; + const uint64_t m4 = uint64_t{0x0F0F0F0F0F0F0F0F}; + const uint64_t h01 = uint64_t{0x0101010101010101}; n -= (n >> 1) & m1; n = (n & m2) + ((n >> 2) & m2); n = (n + (n >> 4)) & m4; @@ -60,7 +60,7 @@ inline uint32 BitCount32(uint32 n) { } // Returns a word with only the least significant bit of n set. -inline uint64 LeastSignificantBitWord64(uint64 n) { return n & ~(n - 1); } +inline uint64_t LeastSignificantBitWord64(uint64_t n) { return n & ~(n - 1); } inline uint32 LeastSignificantBitWord32(uint32 n) { return n & ~(n - 1); } // Returns the least significant bit position in n. @@ -73,13 +73,13 @@ inline uint32 LeastSignificantBitWord32(uint32 n) { return n & ~(n - 1); } #endif #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT) -inline int LeastSignificantBitPosition64Fast(uint64 n) { +inline int LeastSignificantBitPosition64Fast(uint64_t n) { return n == 0 ? 0 : __builtin_ctzll(n); } #endif -inline int LeastSignificantBitPosition64DeBruijn(uint64 n) { - static const uint64 kSeq = uint64_t{0x0218a392dd5fb34f}; +inline int LeastSignificantBitPosition64DeBruijn(uint64_t n) { + static const uint64_t kSeq = uint64_t{0x0218a392dd5fb34f}; static const int kTab[64] = { // initialized by 'kTab[(kSeq << i) >> 58] = i 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58, @@ -90,7 +90,7 @@ inline int LeastSignificantBitPosition64DeBruijn(uint64 n) { return kTab[((n & (~n + 1)) * kSeq) >> 58]; } -inline int LeastSignificantBitPosition64Default(uint64 n) { +inline int LeastSignificantBitPosition64Default(uint64_t n) { if (n == 0) return 0; int pos = 63; if (n & 0x00000000FFFFFFFFLL) { @@ -124,7 +124,7 @@ inline int LeastSignificantBitPosition64Default(uint64 n) { return pos; } -inline int LeastSignificantBitPosition64(uint64 n) { +inline int LeastSignificantBitPosition64(uint64_t n) { DCHECK_NE(n, 0); #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT return LeastSignificantBitPosition64Fast(n); @@ -192,7 +192,7 @@ inline int LeastSignificantBitPosition32(uint32 n) { // Returns the most significant bit position in n. #if USE_FAST_LEAST_SIGNIFICANT_BIT -inline int MostSignificantBitPosition64Fast(uint64 n) { +inline int MostSignificantBitPosition64Fast(uint64_t n) { // __builtin_clzll(1) should always return 63. There is no penalty in // using offset, and the code looks more like its uint32 counterpart. const int offset = __builtin_clzll(1); @@ -200,7 +200,7 @@ inline int MostSignificantBitPosition64Fast(uint64 n) { } #endif -inline int MostSignificantBitPosition64Default(uint64 n) { +inline int MostSignificantBitPosition64Default(uint64_t n) { int b = 0; if (0 != (n & (kAllBits64 << (1 << 5)))) { b |= (1 << 5); @@ -228,7 +228,7 @@ inline int MostSignificantBitPosition64Default(uint64 n) { return b; } -inline int MostSignificantBitPosition64(uint64 n) { +inline int MostSignificantBitPosition64(uint64_t n) { #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT return MostSignificantBitPosition64Fast(n); #else @@ -282,7 +282,7 @@ inline int MostSignificantBitPosition32(uint32 n) { #undef USE_FAST_LEAST_SIGNIFICANT_BIT // Returns a word with bits from s to e set. -inline uint64 OneRange64(uint64 s, uint64 e) { +inline uint64_t OneRange64(uint64_t s, uint64_t e) { DCHECK_LE(s, 63); DCHECK_LE(e, 63); DCHECK_LE(s, e); @@ -297,7 +297,7 @@ inline uint32 OneRange32(uint32 s, uint32 e) { } // Returns a word with s least significant bits unset. -inline uint64 IntervalUp64(uint64 s) { +inline uint64_t IntervalUp64(uint64_t s) { DCHECK_LE(s, 63); return kAllBits64 << s; } @@ -308,7 +308,7 @@ inline uint32 IntervalUp32(uint32 s) { } // Returns a word with the s most significant bits unset. -inline uint64 IntervalDown64(uint64 s) { +inline uint64_t IntervalDown64(uint64_t s) { DCHECK_LE(s, 63); return kAllBits64 >> (63 - s); } @@ -319,7 +319,7 @@ inline uint32 IntervalDown32(uint32 s) { } // ----- Bitset operators ----- -// Bitset: array of uint32/uint64 words +// Bitset: array of uint32/uint64_t words // Bit operators used to manipulates bitsets. @@ -327,23 +327,23 @@ inline uint32 IntervalDown32(uint32 s) { // corresponding to the bit at position pos in the bitset. // Note: '& 63' is faster than '% 64' // TODO(user): rename BitPos and BitOffset to something more understandable. -inline uint32 BitPos64(uint64 pos) { return (pos & 63); } +inline uint32 BitPos64(uint64_t pos) { return (pos & 63); } inline uint32 BitPos32(uint32 pos) { return (pos & 31); } // Returns the word number corresponding to bit number pos. -inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); } +inline uint64_t BitOffset64(uint64_t pos) { return (pos >> 6); } inline uint32 BitOffset32(uint32 pos) { return (pos >> 5); } // Returns the number of words needed to store size bits. -inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); } +inline uint64_t BitLength64(uint64_t size) { return ((size + 63) >> 6); } inline uint32 BitLength32(uint32 size) { return ((size + 31) >> 5); } // Returns the bit number in the bitset of the first bit of word number v. -inline uint64 BitShift64(uint64 v) { return v << 6; } +inline uint64_t BitShift64(uint64_t v) { return v << 6; } inline uint32 BitShift32(uint32 v) { return v << 5; } // Returns true if the bit pos is set in bitset. -inline bool IsBitSet64(const uint64* const bitset, uint64 pos) { +inline bool IsBitSet64(const uint64_t* const bitset, uint64_t pos) { return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos))); } inline bool IsBitSet32(const uint32* const bitset, uint32 pos) { @@ -351,7 +351,7 @@ inline bool IsBitSet32(const uint32* const bitset, uint32 pos) { } // Sets the bit pos to true in bitset. -inline void SetBit64(uint64* const bitset, uint64 pos) { +inline void SetBit64(uint64_t* const bitset, uint64_t pos) { bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos)); } inline void SetBit32(uint32* const bitset, uint32 pos) { @@ -359,7 +359,7 @@ inline void SetBit32(uint32* const bitset, uint32 pos) { } // Sets the bit pos to false in bitset. -inline void ClearBit64(uint64* const bitset, uint64 pos) { +inline void ClearBit64(uint64_t* const bitset, uint64_t pos) { bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos)); } inline void ClearBit32(uint32* const bitset, uint32 pos) { @@ -367,46 +367,46 @@ inline void ClearBit32(uint32* const bitset, uint32 pos) { } // Returns the number of bits set in bitset between positions start and end. -uint64 BitCountRange64(const uint64* const bitset, uint64 start, uint64 end); +uint64_t BitCountRange64(const uint64_t* const bitset, uint64_t start, uint64_t end); uint32 BitCountRange32(const uint32* const bitset, uint32 start, uint32 end); // Returns true if no bits are set in bitset between start and end. -bool IsEmptyRange64(const uint64* const bitset, uint64 start, uint64 end); +bool IsEmptyRange64(const uint64_t* const bitset, uint64_t start, uint64_t end); bool IsEmptyRange32(const uint32* const bitset, uint32 start, uint32 end); // Returns the first bit set in bitset between start and max_bit. -int64 LeastSignificantBitPosition64(const uint64* const bitset, uint64 start, - uint64 end); +int64_t LeastSignificantBitPosition64(const uint64_t* const bitset, uint64_t start, + uint64_t end); int LeastSignificantBitPosition32(const uint32* const bitset, uint32 start, uint32 end); // Returns the last bit set in bitset between min_bit and start. -int64 MostSignificantBitPosition64(const uint64* const bitset, uint64 start, - uint64 end); +int64_t MostSignificantBitPosition64(const uint64_t* const bitset, uint64_t start, + uint64_t end); int MostSignificantBitPosition32(const uint32* const bitset, uint32 start, uint32 end); // Unsafe versions of the functions above where respectively end and start // are supposed to be set. -int64 UnsafeLeastSignificantBitPosition64(const uint64* const bitset, - uint64 start, uint64 end); +int64_t UnsafeLeastSignificantBitPosition64(const uint64_t* const bitset, + uint64_t start, uint64_t end); int32 UnsafeLeastSignificantBitPosition32(const uint32* const bitset, uint32 start, uint32 end); -int64 UnsafeMostSignificantBitPosition64(const uint64* const bitset, - uint64 start, uint64 end); +int64_t UnsafeMostSignificantBitPosition64(const uint64_t* const bitset, + uint64_t start, uint64_t end); int32 UnsafeMostSignificantBitPosition32(const uint32* const bitset, uint32 start, uint32 end); // Returns a mask with the bits pos % 64 and (pos ^ 1) % 64 sets. -inline uint64 TwoBitsFromPos64(uint64 pos) { return uint64_t{3} << (pos & 62); } +inline uint64_t TwoBitsFromPos64(uint64_t pos) { return uint64_t{3} << (pos & 62); } // This class is like an ITIVector except that it provides a // more efficient way to iterate over the positions set to true. It achieves -// this by caching the current uint64 bucket in the Iterator and using +// this by caching the current uint64_t bucket in the Iterator and using // LeastSignificantBitPosition64() to iterate over the positions at 1 in this // bucket. -template +template class Bitset64 { public: Bitset64() : size_(), data_(), end_(*this, /*at_end=*/true) {} @@ -443,11 +443,11 @@ class Bitset64 { const size_t bit_length = static_cast(BitLength64(Value(size_))); const size_t to_clear = std::min(data_.size(), bit_length); data_.resize(bit_length, 0); - memset(data_.data(), 0, to_clear * sizeof(int64)); + memset(data_.data(), 0, to_clear * sizeof(int64_t)); } // Sets all bits to 0. - void ClearAll() { memset(data_.data(), 0, data_.size() * sizeof(int64)); } + void ClearAll() { memset(data_.data(), 0, data_.size() * sizeof(int64_t)); } // Sets the bit at position i to 0. void Clear(IndexType i) { @@ -505,7 +505,7 @@ class Bitset64 { // Copies bucket containing bit i from "other" to "this". void CopyBucket(const Bitset64& other, IndexType i) { - const uint64 offset = BitOffset64(Value(i)); + const uint64_t offset = BitOffset64(Value(i)); data_[offset] = other.data_[offset]; } @@ -514,12 +514,12 @@ class Bitset64 { // larger, its high order bits are ignored. In any case "this" is not resized. template void SetContentFromBitset(const Bitset64& other) { - const int64 min_size = std::min(data_.size(), other.data_.size()); + const int64_t min_size = std::min(data_.size(), other.data_.size()); if (min_size == 0) return; - const uint64 last_common_bucket = data_[min_size - 1]; - memcpy(data_.data(), other.data_.data(), min_size * sizeof(uint64)); + const uint64_t last_common_bucket = data_[min_size - 1]; + memcpy(data_.data(), other.data_.data(), min_size * sizeof(uint64_t)); if (data_.size() >= other.data_.size()) { - const uint64 bitmask = kAllBitsButLsb64 + const uint64_t bitmask = kAllBitsButLsb64 << BitPos64(other.Value(other.size() - 1)); data_[min_size - 1] &= ~bitmask; data_[min_size - 1] |= (bitmask & last_common_bucket); @@ -530,7 +530,7 @@ class Bitset64 { template void SetContentFromBitsetOfSameSize(const Bitset64& other) { DCHECK_EQ(Value(size()), other.Value(other.size())); - memcpy(data_.data(), other.data_.data(), data_.size() * sizeof(uint64)); + memcpy(data_.data(), other.data_.data(), data_.size() * sizeof(uint64_t)); } // Sets "this" to be the intersection of "this" and "other". The @@ -558,7 +558,7 @@ class Bitset64 { // Class to iterate over the bit positions at 1 of a Bitset64. // - // IMPORTANT: Because the iterator "caches" the current uint64 bucket, this + // IMPORTANT: Because the iterator "caches" the current uint64_t bucket, this // will probably not do what you want if Bitset64 is modified while iterating. class Iterator { public: @@ -623,7 +623,7 @@ class Bitset64 { const Bitset64& bitset_; int index_; int base_index_; - uint64 current_; + uint64_t current_; }; // Allows range-based "for" loop on the non-zero positions: @@ -639,8 +639,8 @@ class Bitset64 { // little general use. Sets the bit at position i to the result of // (other1[i] && use1) XOR (other2[i] && use2). void SetBitFromOtherBitSets(IndexType i, const Bitset64& other1, - uint64 use1, const Bitset64& other2, - uint64 use2) { + uint64_t use1, const Bitset64& other2, + uint64_t use2) { DCHECK_EQ(data_.size(), other1.data_.size()); DCHECK_EQ(data_.size(), other2.data_.size()); DCHECK(use1 == 0 || use1 == 1); @@ -663,11 +663,11 @@ class Bitset64 { private: // Returns the value of the index type. - // This function is specialized below to work with IntType and int64. - int64 Value(IndexType input) const; + // This function is specialized below to work with IntType and int64_t. + int64_t Value(IndexType input) const; IndexType size_; - std::vector data_; + std::vector data_; // It is faster to store the end() Iterator than to recompute it every time. // Note that we cannot do the same for begin(). @@ -724,7 +724,7 @@ class BitQueue64 { void ClearTop() { DCHECK_NE(top_, -1); int bucket_index = static_cast(BitOffset64(top_)); - uint64 bucket = data_[bucket_index] &= ~OneBit64(BitPos64(top_)); + uint64_t bucket = data_[bucket_index] &= ~OneBit64(BitPos64(top_)); while (!bucket) { if (bucket_index == 0) { top_ = -1; @@ -743,25 +743,25 @@ class BitQueue64 { private: int size_; int top_; - std::vector data_; + std::vector data_; DISALLOW_COPY_AND_ASSIGN(BitQueue64); }; -// The specialization of Value() for IntType and int64. +// The specialization of Value() for IntType and int64_t. template -inline int64 Bitset64::Value(IntType input) const { +inline int64_t Bitset64::Value(IntType input) const { DCHECK_GE(input.value(), 0); return input.value(); } template <> -inline int64 Bitset64::Value(int64 input) const { +inline int64_t Bitset64::Value(int64_t input) const { DCHECK_GE(input, 0); return input; } // A simple utility class to set/unset integer in a range [0, size). // This is optimized for sparsity. -template +template class SparseBitset { public: SparseBitset() {} diff --git a/ortools/util/cached_log.cc b/ortools/util/cached_log.cc index 9286f8e7af..5c62fef2a5 100644 --- a/ortools/util/cached_log.cc +++ b/ortools/util/cached_log.cc @@ -22,7 +22,7 @@ CachedLog::CachedLog() {} CachedLog::~CachedLog() {} namespace { -double FastLog2(int64 input) { +double FastLog2(int64_t input) { #if defined(_MSC_VER) || defined(__ANDROID__) return log(static_cast(input)) / log(2.0L); #else @@ -40,7 +40,7 @@ void CachedLog::Init(int size) { } } -double CachedLog::Log2(int64 input) const { +double CachedLog::Log2(int64_t input) const { CHECK_GE(input, 1); if (input <= cache_.size()) { return cache_[input - 1]; diff --git a/ortools/util/cached_log.h b/ortools/util/cached_log.h index d0dbe2014a..24a1e8c969 100644 --- a/ortools/util/cached_log.h +++ b/ortools/util/cached_log.h @@ -39,7 +39,7 @@ class CachedLog { void Init(int cache_size); // Returns the log2 of 'input'. - double Log2(int64 input) const; + double Log2(int64_t input) const; private: std::vector cache_; diff --git a/ortools/util/csharp/vector.i b/ortools/util/csharp/vector.i index 764f1ca26e..2c7b8966e2 100644 --- a/ortools/util/csharp/vector.i +++ b/ortools/util/csharp/vector.i @@ -257,8 +257,8 @@ VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector); JAGGED_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector); //REGULAR_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector); -%template(Int64Vector) std::vector; -%template(Int64VectorVector) std::vector >; -VECTOR_AS_CSHARP_ARRAY(int64, int64, long, Int64Vector); -JAGGED_MATRIX_AS_CSHARP_ARRAY(int64, int64, long, Int64VectorVector); -//REGULAR_MATRIX_AS_CSHARP_ARRAY(int64, int64, long, Int64VectorVector); +%template(Int64Vector) std::vector; +%template(Int64VectorVector) std::vector >; +VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector); +JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector); +//REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector); diff --git a/ortools/util/fp_utils.cc b/ortools/util/fp_utils.cc index e6876e52e2..bbe4e63511 100644 --- a/ortools/util/fp_utils.cc +++ b/ortools/util/fp_utils.cc @@ -62,7 +62,7 @@ template void GetBestScalingOfDoublesToInt64(const std::vector& input, const std::vector& lb, const std::vector& ub, - int64 max_absolute_sum, + int64_t max_absolute_sum, double* scaling_factor) { const double kInfinity = std::numeric_limits::infinity(); @@ -76,11 +76,11 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, // // TODO(user): Consider using a non-power of two factor if the error can't be // zero? Note however that using power of two has the extra advantage that - // subsequent int64 -> double -> scaled back to int64 will loose no extra + // subsequent int64_t -> double -> scaled back to int64_t will loose no extra // information. int factor_exponent = 0; - uint64 sum_min = 0; // negated. - uint64 sum_max = 0; + uint64_t sum_min = 0; // negated. + uint64_t sum_max = 0; bool recompute_sum = false; bool is_first_value = true; const int msb = MostSignificantBitPosition64(max_absolute_sum); @@ -105,7 +105,7 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, if (std::round(ldexp(std::abs(c), candidate)) > max_absolute_sum) { --candidate; } - DCHECK_LE(std::abs(static_cast(round(ldexp(c, candidate)))), + DCHECK_LE(std::abs(static_cast(round(ldexp(c, candidate)))), max_absolute_sum); // Update factor_exponent which is the min of all the candidates. @@ -116,9 +116,9 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, } else { // Update the sum of absolute values of the numbers seen so far. sum_min -= - static_cast(std::round(ldexp(min_term, factor_exponent))); + static_cast(std::round(ldexp(min_term, factor_exponent))); sum_max += - static_cast(std::round(ldexp(max_term, factor_exponent))); + static_cast(std::round(ldexp(max_term, factor_exponent))); if (sum_min > max_absolute_sum || sum_max > max_absolute_sum) { factor_exponent--; recompute_sum = true; @@ -140,9 +140,9 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, double max_term = use_bounds ? x * ub[j] : x; ReorderAndCapTerms(&min_term, &max_term); sum_min -= - static_cast(std::round(ldexp(min_term, factor_exponent))); + static_cast(std::round(ldexp(min_term, factor_exponent))); sum_max += - static_cast(std::round(ldexp(max_term, factor_exponent))); + static_cast(std::round(ldexp(max_term, factor_exponent))); } if (sum_min > max_absolute_sum || sum_max > max_absolute_sum) { factor_exponent--; @@ -168,7 +168,7 @@ void ComputeScalingErrors(const std::vector& input, double GetBestScalingOfDoublesToInt64(const std::vector& input, const std::vector& lb, const std::vector& ub, - int64 max_absolute_sum) { + int64_t max_absolute_sum) { double scaling_factor; GetBestScalingOfDoublesToInt64(input, lb, ub, max_absolute_sum, &scaling_factor); @@ -176,7 +176,7 @@ double GetBestScalingOfDoublesToInt64(const std::vector& input, } void GetBestScalingOfDoublesToInt64(const std::vector& input, - int64 max_absolute_sum, + int64_t max_absolute_sum, double* scaling_factor, double* max_relative_coeff_error) { double max_scaled_sum_error; @@ -186,11 +186,11 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, max_relative_coeff_error, &max_scaled_sum_error); } -int64 ComputeGcdOfRoundedDoubles(const std::vector& x, +int64_t ComputeGcdOfRoundedDoubles(const std::vector& x, double scaling_factor) { - int64 gcd = 0; + int64_t gcd = 0; for (int i = 0; i < x.size() && gcd != 1; ++i) { - int64 value = std::abs(std::round(x[i] * scaling_factor)); + int64_t value = std::abs(std::round(x[i] * scaling_factor)); DCHECK_GE(value, 0); if (value == 0) continue; if (gcd == 0) { @@ -199,7 +199,7 @@ int64 ComputeGcdOfRoundedDoubles(const std::vector& x, } // GCD(gcd, value) = GCD(value, gcd % value); while (value != 0) { - const int64 r = gcd % value; + const int64_t r = gcd % value; gcd = value; value = r; } diff --git a/ortools/util/fp_utils.h b/ortools/util/fp_utils.h index 12d4f777cd..1b3f21912e 100644 --- a/ortools/util/fp_utils.h +++ b/ortools/util/fp_utils.h @@ -203,7 +203,7 @@ inline bool IsIntegerWithinTolerance(FloatType x, FloatType tolerance) { // TODO(user): incorporate the gcd computation here? The issue is that I am // not sure if I just do factor /= gcd that round(x * factor) will be the same. void GetBestScalingOfDoublesToInt64(const std::vector& input, - int64 max_absolute_sum, + int64_t max_absolute_sum, double* scaling_factor, double* max_relative_coeff_error); @@ -214,7 +214,7 @@ void GetBestScalingOfDoublesToInt64(const std::vector& input, double GetBestScalingOfDoublesToInt64(const std::vector& input, const std::vector& lb, const std::vector& ub, - int64 max_absolute_sum); + int64_t max_absolute_sum); // This computes: // // The max_relative_coeff_error, which is the maximum over all coeff of @@ -234,7 +234,7 @@ void ComputeScalingErrors(const std::vector& input, // round(fabs(x[i] * scaling_factor)). The numbers 0 are ignored and if they are // all zero then the result is 1. Note that round(fabs()) is the same as // fabs(round()) since the numbers are rounded away from zero. -int64 ComputeGcdOfRoundedDoubles(const std::vector& x, +int64_t ComputeGcdOfRoundedDoubles(const std::vector& x, double scaling_factor); // Returns alpha * x + (1 - alpha) * y. diff --git a/ortools/util/functions_swig_helpers.h b/ortools/util/functions_swig_helpers.h index a387e8e612..6deb149c62 100644 --- a/ortools/util/functions_swig_helpers.h +++ b/ortools/util/functions_swig_helpers.h @@ -27,37 +27,37 @@ namespace swig_util { class LongToLong { public: virtual ~LongToLong() {} - virtual int64 Run(int64) = 0; + virtual int64_t Run(int64_t) = 0; }; class LongLongToLong { public: virtual ~LongLongToLong() {} - virtual int64 Run(int64, int64) = 0; + virtual int64_t Run(int64_t, int64_t) = 0; }; class IntToLong { public: virtual ~IntToLong() {} - virtual int64 Run(int) = 0; + virtual int64_t Run(int) = 0; }; class IntIntToLong { public: virtual ~IntIntToLong() {} - virtual int64 Run(int, int) = 0; + virtual int64_t Run(int, int) = 0; }; class LongLongLongToLong { public: virtual ~LongLongLongToLong() {} - virtual int64 Run(int64, int64, int64) = 0; + virtual int64_t Run(int64_t, int64_t, int64_t) = 0; }; class LongToBoolean { public: virtual ~LongToBoolean() {} - virtual bool Run(int64) = 0; + virtual bool Run(int64_t) = 0; }; class VoidToString { @@ -75,13 +75,13 @@ class VoidToBoolean { class LongLongLongToBoolean { public: virtual ~LongLongLongToBoolean() {} - virtual bool Run(int64 i, int64 j, int64 k) = 0; + virtual bool Run(int64_t i, int64_t j, int64_t k) = 0; }; class LongToVoid { public: virtual ~LongToVoid() {} - virtual void Run(int64 i) = 0; + virtual void Run(int64_t i) = 0; }; class VoidToVoid { diff --git a/ortools/util/functions_swig_test_helpers.h b/ortools/util/functions_swig_test_helpers.h index 4b49dc0a53..0ca16adf27 100644 --- a/ortools/util/functions_swig_test_helpers.h +++ b/ortools/util/functions_swig_test_helpers.h @@ -34,42 +34,42 @@ class FunctionSwigTestHelpers { return fun(); } - static int64 NoOpInt64ToInt64(std::function fun, int64 x) { + static int64_t NoOpInt64ToInt64(std::function fun, int64_t x) { return fun(x); } - static int64 NoOpInt64PairToInt64(std::function fun, - int64 x, int64 y) { + static int64_t NoOpInt64PairToInt64(std::function fun, + int64_t x, int64_t y) { return fun(x, y); } - static int64 NoOpIntToInt64(std::function fun, int x) { + static int64_t NoOpIntToInt64(std::function fun, int x) { return fun(x); } - static int64 NoOpIntPairToInt64(std::function fun, int x, + static int64_t NoOpIntPairToInt64(std::function fun, int x, int y) { return fun(x, y); } - static int64 NoOpInt64TripleToInt64( - std::function fun, int64 x, int64 y, - int64 z) { + static int64_t NoOpInt64TripleToInt64( + std::function fun, int64_t x, int64_t y, + int64_t z) { return fun(x, y, z); } static bool NoOpInt64TripleToBool( - std::function fun, int64 x, int64 y, int64 z) { + std::function fun, int64_t x, int64_t y, int64_t z) { return fun(x, y, z); } - static bool NoOpInt64ToBool(std::function fun, int64 x) { + static bool NoOpInt64ToBool(std::function fun, int64_t x) { return fun(x); } static bool NoOpVoidToBool(std::function fun) { return fun(); } - static void NoOpInt64ToVoid(std::function fun, int64 x) { + static void NoOpInt64ToVoid(std::function fun, int64_t x) { fun(x); } @@ -84,13 +84,13 @@ class FunctionSwigTestHelpers { class DelayedFunctionSwigTestHelpers { public: explicit DelayedFunctionSwigTestHelpers( - std::function fun) + std::function fun) : fun_(fun) {} - int64 NoOpInt64PairToInt64(int64 x, int64 y) { return fun_(x, y); } + int64_t NoOpInt64PairToInt64(int64_t x, int64_t y) { return fun_(x, y); } private: - const std::function fun_; + const std::function fun_; }; } // namespace operations_research diff --git a/ortools/util/java/functions.i b/ortools/util/java/functions.i index 743ccd3dcb..4c4409b391 100644 --- a/ortools/util/java/functions.i +++ b/ortools/util/java/functions.i @@ -39,14 +39,14 @@ // The C preprocessor macros below use some tricks that make them work only if // the actual C preprocessor expands them (not the SWIG preprocessor). %{ -// NAMES(int64, bool, int) expands to: , i0, i1, i2 +// NAMES(int64_t, bool, int) expands to: , i0, i1, i2 #define NAMES_0 #define NAMES_1 i0 #define NAMES_2 i0, i1 #define NAMES_3 i0, i1, i2 #define NAMES(num) NAMES_ ## num -// INSERT_NAMES(int64, bool, int) expands to: int64 i0, bool i1, int i2 +// INSERT_NAMES(int64_t, bool, int) expands to: int64_t i0, bool i1, int i2 #define INSERT_NAMES_0() #define INSERT_NAMES_1(arg0) arg0 i0 #define INSERT_NAMES_2(arg0, arg1) arg0 i0, arg1 i1 @@ -54,13 +54,13 @@ #define INSERT_NAMES(num) INSERT_NAMES_ ## num // Abbreviation of the java type corresponding to the given CType. -// Eg. JAVA_ABBREV(int64) expands to "J". +// Eg. JAVA_ABBREV(int64_t) expands to "J". #define JAVA_ABBREV_int64 "J" #define JAVA_ABBREV_int "I" #define JAVA_ABBREV_bool "Z" #define JAVA_ABBREV(x) JAVA_ABBREV_ ## x -// ABBREV(int64, bool, int64) expands to: JZJ +// ABBREV(int64_t, bool, int64_t) expands to: JZJ #define ABBREV_0() #define ABBREV_1(arg1) JAVA_ABBREV(arg1) #define ABBREV_2(arg1, arg2) JAVA_ABBREV(arg1) JAVA_ABBREV(arg2) @@ -74,8 +74,8 @@ ReturnType, JavaReturnType, NumArgs, __Unused__, Args...) // The macro expansions can be hard to follow, so we show an example of the -// expected macro expansion with: ReturnType=int64, Args=int64, bool. -// EXPANSION EXAMPLE: "int64(int64, bool)". +// expected macro expansion with: ReturnType=int64_t, Args=int64_t, bool. +// EXPANSION EXAMPLE: "int64_t(int64_t, bool)". %typemap(in) std::function { jclass object_class = jenv->FindClass(ClassPath ClassName); if (nullptr == object_class) return $null; @@ -85,7 +85,7 @@ operations_research::swig_util::CppClass* const fun = reinterpret_cast( jenv->CallStaticLongMethod(object_class, method_id, $input)); - // EXPANSION EXAMPLE: "int64 i0, bool i1". + // EXPANSION EXAMPLE: "int64_t i0, bool i1". $1 = [fun](INSERT_NAMES(NumArgs)(Args)) { // EXPANSION EXAMPLE: "i0, i1". return fun->Run(NAMES(NumArgs)); @@ -178,7 +178,7 @@ WRAP_STD_FUNCTION_JAVA_AUX(Package, "CppClass", CppClass, ReturnType, // --------- LongToVoid --------- -%typemap(in) std::function { +%typemap(in) std::function { jclass object_class = jenv->FindClass(ClassPath "LongToVoid"); if (nullptr == object_class) return $null; @@ -189,16 +189,16 @@ WRAP_STD_FUNCTION_JAVA_AUX(Package, "CppClass", CppClass, ReturnType, operations_research::swig_util::LongToVoid* const fun = reinterpret_cast( jenv->CallStaticLongMethod(object_class, method_id, $input)); - $1 = [fun](int64 i) { fun->Run(i); }; + $1 = [fun](int64_t i) { fun->Run(i); }; } // These 3 typemaps tell SWIG what JNI and Java types to use -%typemap(jni) std::function "jobject" -%typemap(jtype) std::function "LongToVoid" -%typemap(jstype) std::function "LongToVoid" +%typemap(jni) std::function "jobject" +%typemap(jtype) std::function "LongToVoid" +%typemap(jstype) std::function "LongToVoid" // This typemap handles the conversion of the jstype to jtype typemap types -%typemap(javain) std::function "$javainput" +%typemap(javain) std::function "$javainput" %enddef // WRAP_STD_FUNCTIONS_WITH_VOID_JAVA %define WRAP_STD_FUNCTION_JAVA_CLASS_TO_VOID(CppClass, ClassPath, Parameter) diff --git a/ortools/util/java/vector.i b/ortools/util/java/vector.i index 2d115dc9e7..8677e55218 100644 --- a/ortools/util/java/vector.i +++ b/ortools/util/java/vector.i @@ -98,7 +98,7 @@ %enddef // VECTOR_AS_JAVA_ARRAY VECTOR_AS_JAVA_ARRAY(int, int, Int); -VECTOR_AS_JAVA_ARRAY(int64, long, Long); +VECTOR_AS_JAVA_ARRAY(int64_t, long, Long); VECTOR_AS_JAVA_ARRAY(double, double, Double); @@ -285,7 +285,7 @@ VECTOR_AS_JAVA_ARRAY(double, double, Double); %enddef // MATRIX_AS_JAVA_ARRAY MATRIX_AS_JAVA_ARRAY(int, int, Int); -MATRIX_AS_JAVA_ARRAY(int64, long, Long); +MATRIX_AS_JAVA_ARRAY(int64_t, long, Long); MATRIX_AS_JAVA_ARRAY(double, double, Double); %define REINTERPRET_CAST(CType, ptr) diff --git a/ortools/util/piecewise_linear_function.cc b/ortools/util/piecewise_linear_function.cc index d30ffc115e..ac55fd3924 100644 --- a/ortools/util/piecewise_linear_function.cc +++ b/ortools/util/piecewise_linear_function.cc @@ -29,7 +29,7 @@ namespace { // the index of the right segment. If the x value is not in the function's // domain, it returns the index of the previous segment or kNotFound if x // is before the first segment's start. -int FindSegmentIndex(const std::vector& segments, int64 x) { +int FindSegmentIndex(const std::vector& segments, int64_t x) { if (segments.empty() || segments.front().start_x() > x) { return PiecewiseLinearFunction::kNotFound; } @@ -46,11 +46,11 @@ int FindSegmentIndex(const std::vector& segments, int64 x) { return position - segments.begin(); } -inline bool IsAtBounds(int64 value) { +inline bool IsAtBounds(int64_t value) { return value == kint64min || value == kint64max; } -inline bool PointInsideRange(int64 point, int64 range_start, int64 range_end) { +inline bool PointInsideRange(int64_t point, int64_t range_start, int64_t range_end) { return range_start <= point && range_end >= point; } @@ -62,19 +62,19 @@ inline bool FormConvexPair(const PiecewiseSegment& left, right.start_y() == left.end_y(); } -uint64 UnsignedCapAdd(uint64 left, uint64 right) { +uint64_t UnsignedCapAdd(uint64_t left, uint64_t right) { return left > kuint64max - right ? kuint64max : left + right; } -uint64 UnsignedCapProd(uint64 left, uint64 right) { +uint64_t UnsignedCapProd(uint64_t left, uint64_t right) { if (right == 0) return 0; if (left > kuint64max / right) return kuint64max; return left * right; } } // namespace -PiecewiseSegment::PiecewiseSegment(int64 point_x, int64 point_y, int64 slope, - int64 other_point_x) +PiecewiseSegment::PiecewiseSegment(int64_t point_x, int64_t point_y, int64_t slope, + int64_t other_point_x) : slope_(slope), reference_x_(point_x), reference_y_(point_y) { start_x_ = std::min(point_x, other_point_x); end_x_ = std::max(point_x, other_point_x); @@ -82,11 +82,11 @@ PiecewiseSegment::PiecewiseSegment(int64 point_x, int64 point_y, int64 slope, reference_x_ < 0 ? SafeValuePostReference(0) : SafeValuePreReference(0); } -int64 PiecewiseSegment::Value(int64 x) const { +int64_t PiecewiseSegment::Value(int64_t x) const { CHECK_GE(x, start_x_); CHECK_LE(x, end_x_); - const int64 span_x = CapSub(x, reference_x_); + const int64_t span_x = CapSub(x, reference_x_); if (span_x == kint64max) { return SafeValuePostReference(x); @@ -95,7 +95,7 @@ int64 PiecewiseSegment::Value(int64 x) const { return SafeValuePreReference(x); } - const int64 span_y = CapProd(slope_, span_x); + const int64_t span_y = CapProd(slope_, span_x); if (IsAtBounds(span_y)) { if (span_x >= 0) { return SafeValuePostReference(x); @@ -104,7 +104,7 @@ int64 PiecewiseSegment::Value(int64 x) const { } } - const int64 value = CapAdd(reference_y_, span_y); + const int64_t value = CapAdd(reference_y_, span_y); if (IsAtBounds(value)) { if (span_x >= 0) { return SafeValuePostReference(x); @@ -116,9 +116,9 @@ int64 PiecewiseSegment::Value(int64 x) const { } } -int64 PiecewiseSegment::SafeValuePostReference(int64 x) const { +int64_t PiecewiseSegment::SafeValuePostReference(int64_t x) const { DCHECK_GE(x, reference_x_); - const uint64 span_x = static_cast(x) - reference_x_; + const uint64_t span_x = static_cast(x) - reference_x_; if (span_x == 0) { return reference_y_; } @@ -127,98 +127,98 @@ int64 PiecewiseSegment::SafeValuePostReference(int64 x) const { return reference_y_; } else if (slope_ > 0) { // Positive slope segment. - const uint64 span_y = UnsignedCapProd(span_x, slope_); + const uint64_t span_y = UnsignedCapProd(span_x, slope_); if (reference_y_ == 0) { return span_y > kint64max ? kint64max : span_y; } else if (reference_y_ > 0) { - const uint64 unsigned_sum = UnsignedCapAdd(reference_y_, span_y); + const uint64_t unsigned_sum = UnsignedCapAdd(reference_y_, span_y); return unsigned_sum > kint64max ? kint64max - : static_cast(unsigned_sum); + : static_cast(unsigned_sum); } else { - const uint64 opp_reference_y = -static_cast(reference_y_); + const uint64_t opp_reference_y = -static_cast(reference_y_); if (span_y >= opp_reference_y) { return span_y - opp_reference_y > kint64max ? kint64max - : static_cast(span_y - opp_reference_y); + : static_cast(span_y - opp_reference_y); } else { - return opp_reference_y - span_y > static_cast(kint64max) + 1 + return opp_reference_y - span_y > static_cast(kint64max) + 1 ? kint64min - : -static_cast(opp_reference_y - span_y); + : -static_cast(opp_reference_y - span_y); } } } else { // Negative slope segment. - const uint64 span_y = UnsignedCapProd(span_x, -slope_); + const uint64_t span_y = UnsignedCapProd(span_x, -slope_); if (reference_y_ == 0) { - return span_y > kint64max ? kint64min : -static_cast(span_y); + return span_y > kint64max ? kint64min : -static_cast(span_y); } else if (reference_y_ < 0) { - const uint64 opp_reference_y = -static_cast(reference_y_); - const uint64 opp_unsigned_sum = UnsignedCapAdd(opp_reference_y, span_y); + const uint64_t opp_reference_y = -static_cast(reference_y_); + const uint64_t opp_unsigned_sum = UnsignedCapAdd(opp_reference_y, span_y); return opp_unsigned_sum > kint64max ? kint64min - : -static_cast(opp_unsigned_sum); + : -static_cast(opp_unsigned_sum); } else { if (reference_y_ >= span_y) { return reference_y_ - span_y > kint64max ? kint64max - : static_cast(reference_y_ - span_y); + : static_cast(reference_y_ - span_y); } else { - return span_y - reference_y_ > static_cast(kint64max) + 1 + return span_y - reference_y_ > static_cast(kint64max) + 1 ? kint64min - : -static_cast(span_y - reference_y_); + : -static_cast(span_y - reference_y_); } } } } -int64 PiecewiseSegment::SafeValuePreReference(int64 x) const { +int64_t PiecewiseSegment::SafeValuePreReference(int64_t x) const { DCHECK_LE(x, reference_x_); - const uint64 span_x = static_cast(reference_x_) - x; + const uint64_t span_x = static_cast(reference_x_) - x; if (slope_ == 0) { // Zero slope segment. return reference_y_; } else if (slope_ > 0) { // Positive slope segment. - const uint64 span_y = UnsignedCapProd(span_x, slope_); + const uint64_t span_y = UnsignedCapProd(span_x, slope_); if (reference_y_ == 0) { - return span_y > kint64max ? kint64min : -static_cast(span_y); + return span_y > kint64max ? kint64min : -static_cast(span_y); } else if (reference_y_ > 0) { if (reference_y_ >= span_y) { return reference_y_ - span_y > kint64max ? kint64max - : static_cast(reference_y_ - span_y); + : static_cast(reference_y_ - span_y); } else { - return span_y - reference_y_ > static_cast(kint64max) + 1 + return span_y - reference_y_ > static_cast(kint64max) + 1 ? kint64min - : -static_cast(span_y - reference_y_); + : -static_cast(span_y - reference_y_); } } else { - const uint64 opp_reference_y = -static_cast(reference_y_); - const uint64 opp_unsigned_sum = UnsignedCapAdd(opp_reference_y, span_y); + const uint64_t opp_reference_y = -static_cast(reference_y_); + const uint64_t opp_unsigned_sum = UnsignedCapAdd(opp_reference_y, span_y); return opp_unsigned_sum > kint64max ? kint64min - : -static_cast(opp_unsigned_sum); + : -static_cast(opp_unsigned_sum); } } else { // Negative slope segment. - const uint64 span_y = UnsignedCapProd(span_x, -slope_); + const uint64_t span_y = UnsignedCapProd(span_x, -slope_); if (reference_y_ == 0) { return span_y > kint64max ? kint64max : span_y; } else if (reference_y_ < 0) { - const uint64 opp_reference_y = -static_cast(reference_y_); + const uint64_t opp_reference_y = -static_cast(reference_y_); if (span_y >= opp_reference_y) { return span_y - opp_reference_y > kint64max ? kint64max - : static_cast(span_y - opp_reference_y); + : static_cast(span_y - opp_reference_y); } else { - return opp_reference_y - span_y > static_cast(kint64max) + 1 + return opp_reference_y - span_y > static_cast(kint64max) + 1 ? kint64min - : -static_cast(opp_reference_y - span_y); + : -static_cast(opp_reference_y - span_y); } } else { - const uint64 unsigned_sum = UnsignedCapAdd(reference_y_, span_y); + const uint64_t unsigned_sum = UnsignedCapAdd(reference_y_, span_y); return unsigned_sum > kint64max ? kint64max - : static_cast(unsigned_sum); + : static_cast(unsigned_sum); } } } @@ -228,16 +228,16 @@ bool PiecewiseSegment::SortComparator(const PiecewiseSegment& segment1, return segment1.start_x_ < segment2.start_x_; } -bool PiecewiseSegment::FindComparator(int64 point, +bool PiecewiseSegment::FindComparator(int64_t point, const PiecewiseSegment& segment) { return point == kint64min || point < segment.start_x(); } -void PiecewiseSegment::ExpandEnd(int64 end_x) { +void PiecewiseSegment::ExpandEnd(int64_t end_x) { end_x_ = std::max(end_x_, end_x); } -void PiecewiseSegment::AddConstantToX(int64 constant) { +void PiecewiseSegment::AddConstantToX(int64_t constant) { if (IsAtBounds(CapAdd(reference_x_, constant))) { LOG(ERROR) << "Segment Overflow: " << DebugString(); return; @@ -247,7 +247,7 @@ void PiecewiseSegment::AddConstantToX(int64 constant) { reference_x_ = CapAdd(reference_x_, constant); } -void PiecewiseSegment::AddConstantToY(int64 constant) { +void PiecewiseSegment::AddConstantToY(int64_t constant) { if (IsAtBounds(CapAdd(reference_y_, constant))) { LOG(ERROR) << "Segment Overflow: " << DebugString(); return; @@ -288,8 +288,8 @@ PiecewiseLinearFunction::PiecewiseLinearFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreatePiecewiseLinearFunction( - std::vector points_x, std::vector points_y, - std::vector slopes, std::vector other_points_x) { + std::vector points_x, std::vector points_y, + std::vector slopes, std::vector other_points_x) { CHECK_EQ(points_x.size(), points_y.size()); CHECK_EQ(points_x.size(), other_points_x.size()); CHECK_EQ(points_x.size(), slopes.size()); @@ -305,8 +305,8 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreatePiecewiseLinearFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateStepFunction( - std::vector points_x, std::vector points_y, - std::vector other_points_x) { + std::vector points_x, std::vector points_y, + std::vector other_points_x) { CHECK_EQ(points_x.size(), points_y.size()); CHECK_EQ(points_x.size(), other_points_x.size()); CHECK_GT(points_x.size(), 0); @@ -321,12 +321,12 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreateStepFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateFullDomainFunction( - int64 initial_level, std::vector points_x, - std::vector slopes) { + int64_t initial_level, std::vector points_x, + std::vector slopes) { CHECK_EQ(points_x.size(), slopes.size() - 1); CHECK_GT(points_x.size(), 0); - int64 level = initial_level; + int64_t level = initial_level; std::vector segments; PiecewiseSegment segment = PiecewiseSegment(points_x[0], level, slopes[0], kint64min); @@ -345,7 +345,7 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreateFullDomainFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateOneSegmentFunction( - int64 point_x, int64 point_y, int64 slope, int64 other_point_x) { + int64_t point_x, int64_t point_y, int64_t slope, int64_t other_point_x) { // Visual studio 2013: We cannot inline the vector in the // PiecewiseLinearFunction ctor. std::vector segments = { @@ -354,21 +354,21 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreateOneSegmentFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateRightRayFunction( - int64 point_x, int64 point_y, int64 slope) { + int64_t point_x, int64_t point_y, int64_t slope) { std::vector segments = { PiecewiseSegment(point_x, point_y, slope, kint64max)}; return new PiecewiseLinearFunction(std::move(segments)); } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateLeftRayFunction( - int64 point_x, int64 point_y, int64 slope) { + int64_t point_x, int64_t point_y, int64_t slope) { std::vector segments = { PiecewiseSegment(point_x, point_y, slope, kint64min)}; return new PiecewiseLinearFunction(std::move(segments)); } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateFixedChargeFunction( - int64 slope, int64 value) { + int64_t slope, int64_t value) { std::vector segments = { PiecewiseSegment(0, 0, 0, kint64min), PiecewiseSegment(0, value, slope, kint64max)}; @@ -378,7 +378,7 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreateFixedChargeFunction( } PiecewiseLinearFunction* PiecewiseLinearFunction::CreateEarlyTardyFunction( - int64 reference, int64 earliness_slope, int64 tardiness_slope) { + int64_t reference, int64_t earliness_slope, int64_t tardiness_slope) { std::vector segments = { PiecewiseSegment(reference, 0, -earliness_slope, kint64min), PiecewiseSegment(reference, 0, tardiness_slope, kint64max)}; @@ -389,8 +389,8 @@ PiecewiseLinearFunction* PiecewiseLinearFunction::CreateEarlyTardyFunction( PiecewiseLinearFunction* PiecewiseLinearFunction::CreateEarlyTardyFunctionWithSlack( - int64 early_slack, int64 late_slack, int64 earliness_slope, - int64 tardiness_slope) { + int64_t early_slack, int64_t late_slack, int64_t earliness_slope, + int64_t tardiness_slope) { std::vector segments = { PiecewiseSegment(early_slack, 0, -earliness_slope, kint64min), PiecewiseSegment(early_slack, 0, 0, late_slack), @@ -401,7 +401,7 @@ PiecewiseLinearFunction::CreateEarlyTardyFunctionWithSlack( return new PiecewiseLinearFunction(std::move(segments)); } -bool PiecewiseLinearFunction::InDomain(int64 x) const { +bool PiecewiseLinearFunction::InDomain(int64_t x) const { int index = FindSegmentIndex(segments_, x); if (index == kNotFound) { return false; @@ -427,7 +427,7 @@ bool PiecewiseLinearFunction::IsNonIncreasing() const { return is_non_increasing_; } -int64 PiecewiseLinearFunction::Value(int64 x) const { +int64_t PiecewiseLinearFunction::Value(int64_t x) const { if (!InDomain(x)) { // TODO(user): Allow the user to specify the // undefined value and use kint64max as the default. @@ -437,8 +437,8 @@ int64 PiecewiseLinearFunction::Value(int64 x) const { return segments_[index].Value(x); } -int64 PiecewiseLinearFunction::GetMaximum(int64 range_start, - int64 range_end) const { +int64_t PiecewiseLinearFunction::GetMaximum(int64_t range_start, + int64_t range_end) const { if (IsNonDecreasing() && InDomain(range_end)) { return Value(range_end); } else if (IsNonIncreasing() && InDomain(range_start)) { @@ -452,7 +452,7 @@ int64 PiecewiseLinearFunction::GetMaximum(int64 range_start, } CHECK_GE(end_segment, start_segment); - int64 range_maximum = kint64min; + int64_t range_maximum = kint64min; if (InDomain(range_start)) { range_maximum = std::max(Value(range_start), range_maximum); } @@ -471,8 +471,8 @@ int64 PiecewiseLinearFunction::GetMaximum(int64 range_start, return range_maximum; } -int64 PiecewiseLinearFunction::GetMinimum(int64 range_start, - int64 range_end) const { +int64_t PiecewiseLinearFunction::GetMinimum(int64_t range_start, + int64_t range_end) const { if (IsNonDecreasing() && InDomain(range_start)) { return Value(range_start); } else if (IsNonIncreasing() && InDomain(range_end)) { @@ -486,7 +486,7 @@ int64 PiecewiseLinearFunction::GetMinimum(int64 range_start, } CHECK_GE(end_segment, start_segment); - int64 range_minimum = kint64max; + int64_t range_minimum = kint64max; if (InDomain(range_start)) { range_minimum = std::min(Value(range_start), range_minimum); } @@ -505,52 +505,52 @@ int64 PiecewiseLinearFunction::GetMinimum(int64 range_start, return range_minimum; } -int64 PiecewiseLinearFunction::GetMaximum() const { +int64_t PiecewiseLinearFunction::GetMaximum() const { return GetMaximum(segments_.front().start_x(), segments_.back().end_x()); } -int64 PiecewiseLinearFunction::GetMinimum() const { +int64_t PiecewiseLinearFunction::GetMinimum() const { return GetMinimum(segments_.front().start_x(), segments_.back().end_x()); } -std::pair -PiecewiseLinearFunction::GetSmallestRangeGreaterThanValue(int64 range_start, - int64 range_end, - int64 value) const { +std::pair +PiecewiseLinearFunction::GetSmallestRangeGreaterThanValue(int64_t range_start, + int64_t range_end, + int64_t value) const { return GetSmallestRangeInValueRange(range_start, range_end, value, kint64max); } -std::pair PiecewiseLinearFunction::GetSmallestRangeLessThanValue( - int64 range_start, int64 range_end, int64 value) const { +std::pair PiecewiseLinearFunction::GetSmallestRangeLessThanValue( + int64_t range_start, int64_t range_end, int64_t value) const { return GetSmallestRangeInValueRange(range_start, range_end, kint64min, value); } namespace { -std::pair ComputeXFromY(int64 start_x, int64 start_y, int64 slope, - int64 y) { +std::pair ComputeXFromY(int64_t start_x, int64_t start_y, int64_t slope, + int64_t y) { DCHECK_NE(slope, 0); - const int64 delta_y = CapSub(y, start_y); - const int64 delta_x = delta_y / slope; + const int64_t delta_y = CapSub(y, start_y); + const int64_t delta_x = delta_y / slope; if ((delta_y >= 0 && slope >= 0) || (delta_y <= 0 && slope <= 0)) { - const int64 delta_x_down = delta_x; - const int64 delta_x_up = delta_y % slope == 0 ? delta_x : delta_x + 1; + const int64_t delta_x_down = delta_x; + const int64_t delta_x_up = delta_y % slope == 0 ? delta_x : delta_x + 1; return {delta_x_down + start_x, delta_x_up + start_x}; } else { - const int64 delta_x_down = delta_y % slope == 0 ? delta_x : delta_x - 1; - const int64 delta_x_up = -(-delta_y / slope); + const int64_t delta_x_down = delta_y % slope == 0 ? delta_x : delta_x - 1; + const int64_t delta_x_up = -(-delta_y / slope); return {delta_x_down + start_x, delta_x_up + start_x}; } } -std::pair GetRangeInValueRange(int64 start_x, int64 end_x, - int64 start_y, int64 end_y, - int64 slope, int64 value_min, - int64 value_max) { +std::pair GetRangeInValueRange(int64_t start_x, int64_t end_x, + int64_t start_y, int64_t end_y, + int64_t slope, int64_t value_min, + int64_t value_max) { if ((start_y > value_max && end_y > value_max) || (start_y < value_min && end_y < value_min)) { return {kint64max, kint64min}; } - std::pair x_range_max = {kint64max, kint64min}; + std::pair x_range_max = {kint64max, kint64min}; if (start_y <= value_max && end_y <= value_max) { x_range_max = {start_x, end_x}; } else if (start_y <= value_max || end_y <= value_max) { @@ -563,7 +563,7 @@ std::pair GetRangeInValueRange(int64 start_x, int64 end_x, x_range_max = {start_x, x.first}; } } - std::pair x_range_min = {kint64max, kint64min}; + std::pair x_range_min = {kint64max, kint64min}; if (start_y >= value_min && end_y >= value_min) { x_range_min = {start_x, end_x}; } else if (start_y >= value_min || end_y >= value_min) { @@ -585,11 +585,11 @@ std::pair GetRangeInValueRange(int64 start_x, int64 end_x, } } // namespace -std::pair PiecewiseLinearFunction::GetSmallestRangeInValueRange( - int64 range_start, int64 range_end, int64 value_min, - int64 value_max) const { - int64 reduced_range_start = kint64max; - int64 reduced_range_end = kint64min; +std::pair PiecewiseLinearFunction::GetSmallestRangeInValueRange( + int64_t range_start, int64_t range_end, int64_t value_min, + int64_t value_max) const { + int64_t reduced_range_start = kint64max; + int64_t reduced_range_end = kint64min; int start_segment = -1; int end_segment = -1; if (!FindSegmentIndicesFromRange(range_start, range_end, &start_segment, @@ -598,11 +598,11 @@ std::pair PiecewiseLinearFunction::GetSmallestRangeInValueRange( } for (int i = std::max(0, start_segment); i <= end_segment; ++i) { const auto& segment = segments_[i]; - const int64 start_x = std::max(range_start, segment.start_x()); - const int64 end_x = std::min(range_end, segment.end_x()); - const int64 start_y = segment.Value(start_x); - const int64 end_y = segment.Value(end_x); - const std::pair range = GetRangeInValueRange( + const int64_t start_x = std::max(range_start, segment.start_x()); + const int64_t end_x = std::min(range_end, segment.end_x()); + const int64_t start_y = segment.Value(start_x); + const int64_t end_y = segment.Value(end_x); + const std::pair range = GetRangeInValueRange( start_x, end_x, start_y, end_y, segment.slope(), value_min, value_max); reduced_range_start = std::min(reduced_range_start, range.first); reduced_range_end = std::max(reduced_range_end, range.second); @@ -610,14 +610,14 @@ std::pair PiecewiseLinearFunction::GetSmallestRangeInValueRange( return {reduced_range_start, reduced_range_end}; } -void PiecewiseLinearFunction::AddConstantToX(int64 constant) { +void PiecewiseLinearFunction::AddConstantToX(int64_t constant) { is_modified_ = true; for (int i = 0; i < segments_.size(); ++i) { segments_[i].AddConstantToX(constant); } } -void PiecewiseLinearFunction::AddConstantToY(int64 constant) { +void PiecewiseLinearFunction::AddConstantToY(int64_t constant) { is_modified_ = true; for (int i = 0; i < segments_.size(); ++i) { segments_[i].AddConstantToY(constant); @@ -625,11 +625,11 @@ void PiecewiseLinearFunction::AddConstantToY(int64 constant) { } void PiecewiseLinearFunction::Add(const PiecewiseLinearFunction& other) { - Operation(other, [](int64 a, int64 b) { return CapAdd(a, b); }); + Operation(other, [](int64_t a, int64_t b) { return CapAdd(a, b); }); } void PiecewiseLinearFunction::Subtract(const PiecewiseLinearFunction& other) { - Operation(other, [](int64 a, int64 b) { return CapSub(a, b); }); + Operation(other, [](int64_t a, int64_t b) { return CapSub(a, b); }); } std::vector @@ -696,13 +696,13 @@ void PiecewiseLinearFunction::InsertSegment(const PiecewiseSegment& segment) { void PiecewiseLinearFunction::Operation( const PiecewiseLinearFunction& other, - const std::function& operation) { + const std::function& operation) { is_modified_ = true; std::vector own_segments; const std::vector& other_segments = other.segments(); own_segments.swap(segments_); - std::set start_x_points; + std::set start_x_points; for (int i = 0; i < own_segments.size(); ++i) { start_x_points.insert(own_segments[i].start_x()); } @@ -710,21 +710,21 @@ void PiecewiseLinearFunction::Operation( start_x_points.insert(other_segments[i].start_x()); } - for (int64 start_x : start_x_points) { + for (int64_t start_x : start_x_points) { const int own_index = FindSegmentIndex(own_segments, start_x); const int other_index = FindSegmentIndex(other_segments, start_x); if (own_index >= 0 && other_index >= 0) { const PiecewiseSegment& own_segment = own_segments[own_index]; const PiecewiseSegment& other_segment = other_segments[other_index]; - const int64 end_x = std::min(own_segment.end_x(), other_segment.end_x()); - const int64 start_y = + const int64_t end_x = std::min(own_segment.end_x(), other_segment.end_x()); + const int64_t start_y = operation(own_segment.Value(start_x), other_segment.Value(start_x)); - const int64 end_y = + const int64_t end_y = operation(own_segment.Value(end_x), other_segment.Value(end_x)); - const int64 slope = operation(own_segment.slope(), other_segment.slope()); + const int64_t slope = operation(own_segment.slope(), other_segment.slope()); - int64 point_x, point_y, other_point_x; + int64_t point_x, point_y, other_point_x; if (IsAtBounds(start_y)) { point_x = end_x; point_y = end_y; @@ -740,7 +740,7 @@ void PiecewiseLinearFunction::Operation( } bool PiecewiseLinearFunction::FindSegmentIndicesFromRange( - int64 range_start, int64 range_end, int* start_segment, + int64_t range_start, int64_t range_end, int* start_segment, int* end_segment) const { *start_segment = FindSegmentIndex(segments_, range_start); *end_segment = FindSegmentIndex(segments_, range_end); @@ -767,10 +767,10 @@ bool PiecewiseLinearFunction::IsConvexInternal() const { } bool PiecewiseLinearFunction::IsNonDecreasingInternal() const { - int64 value = kint64min; + int64_t value = kint64min; for (const auto& segment : segments_) { - const int64 start_y = segment.start_y(); - const int64 end_y = segment.end_y(); + const int64_t start_y = segment.start_y(); + const int64_t end_y = segment.end_y(); if (end_y < start_y || start_y < value) return false; value = end_y; } @@ -778,10 +778,10 @@ bool PiecewiseLinearFunction::IsNonDecreasingInternal() const { } bool PiecewiseLinearFunction::IsNonIncreasingInternal() const { - int64 value = kint64max; + int64_t value = kint64max; for (const auto& segment : segments_) { - const int64 start_y = segment.start_y(); - const int64 end_y = segment.end_y(); + const int64_t start_y = segment.start_y(); + const int64_t end_y = segment.end_y(); if (end_y > start_y || start_y > value) return false; value = end_y; } diff --git a/ortools/util/piecewise_linear_function.h b/ortools/util/piecewise_linear_function.h index a9eea9d567..50c9cb3e83 100644 --- a/ortools/util/piecewise_linear_function.h +++ b/ortools/util/piecewise_linear_function.h @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file implements piecewise linear functions over int64. It is built +// This file implements piecewise linear functions over int64_t. It is built // by inserting segments. // // This class maintains a minimal internal representation and checks for @@ -37,38 +37,38 @@ namespace operations_research { // It is defined for x values between start_x and end_x. class PiecewiseSegment { public: - PiecewiseSegment(int64 point_x, int64 point_y, int64 slope, - int64 other_point_x); + PiecewiseSegment(int64_t point_x, int64_t point_y, int64_t slope, + int64_t other_point_x); // Returns the value of the segment at point x. - int64 Value(int64 x) const; + int64_t Value(int64_t x) const; // Returns the start of the segment's domain. - int64 start_x() const { return start_x_; } + int64_t start_x() const { return start_x_; } // Returns the end of the segment's domain. - int64 end_x() const { return end_x_; } + int64_t end_x() const { return end_x_; } // Returns the value at the start of the segment's domain. - int64 start_y() const { return Value(start_x_); } + int64_t start_y() const { return Value(start_x_); } // Returns the value at the end of the segment's domain. - int64 end_y() const { return Value(end_x_); } + int64_t end_y() const { return Value(end_x_); } // Returns the segment's slope. - int64 slope() const { return slope_; } + int64_t slope() const { return slope_; } // Returns the intersection of the segment's extension with the y axis. - int64 intersection_y() const { return intersection_y_; } + int64_t intersection_y() const { return intersection_y_; } // Comparison method useful for sorting a sequence of segments. static bool SortComparator(const PiecewiseSegment& segment1, const PiecewiseSegment& segment2); // Comparison method useful for finding in which segment a point belongs. - static bool FindComparator(int64 point, const PiecewiseSegment& segment); + static bool FindComparator(int64_t point, const PiecewiseSegment& segment); // Expands segment to the specified endpoint, if it is further // than the current endpoint. The reference point of the segment // doesn't change for overflow reasons. - void ExpandEnd(int64 end_x); + void ExpandEnd(int64_t end_x); // Adds 'constant' to the 'x' the segments. - void AddConstantToX(int64 constant); + void AddConstantToX(int64_t constant); // Adds 'constant' to the 'y' the segments. - void AddConstantToY(int64 constant); + void AddConstantToY(int64_t constant); std::string DebugString() const; @@ -76,24 +76,24 @@ class PiecewiseSegment { // Computes the value of the segment at point x, taking care of possible // overflows when the value x follow the x coordinate of the segment's // reference point. - int64 SafeValuePostReference(int64 x) const; + int64_t SafeValuePostReference(int64_t x) const; // Computes the value of the segment at point x, taking care of possible // overflows when the value x follow the x coordinate of the segment's // reference point. - int64 SafeValuePreReference(int64 x) const; + int64_t SafeValuePreReference(int64_t x) const; // The x coordinate of the segment's left endpoint. - int64 start_x_; + int64_t start_x_; // The x coordinate of the segment's right endpoint. - int64 end_x_; + int64_t end_x_; // The segment's slope. - int64 slope_; + int64_t slope_; // The x coordinate of the segment's finite reference point. - int64 reference_x_; + int64_t reference_x_; // The y coordinate of the segment's finite reference point. - int64 reference_y_; + int64_t reference_y_; // The intersection of the segment's extension with the y axis. - int64 intersection_y_; + int64_t intersection_y_; }; // In mathematics, a piecewise linear function is a function composed @@ -118,15 +118,15 @@ class PiecewiseLinearFunction { // The segments represented by these vectors should not be overlapping. // Common endpoints are allowed. static PiecewiseLinearFunction* CreatePiecewiseLinearFunction( - std::vector points_x, std::vector points_y, - std::vector slopes, std::vector other_points_x); + std::vector points_x, std::vector points_y, + std::vector slopes, std::vector other_points_x); // Builds a multiple-segment step function with continuous or non continuous // domain. The arguments have the same semantics with the generic builder of // the piecewise linear function. In the step function all the slopes are 0. static PiecewiseLinearFunction* CreateStepFunction( - std::vector points_x, std::vector points_y, - std::vector other_points_x); + std::vector points_x, std::vector points_y, + std::vector other_points_x); // Builds a multiple-segment piecewise linear function with domain from // from kint64min to kint64max with n points and n+1 slopes. Each slope @@ -134,33 +134,33 @@ class PiecewiseLinearFunction { // which stops at kint64max. The first slope stops at the first point at // the level specified. static PiecewiseLinearFunction* CreateFullDomainFunction( - int64 initial_level, std::vector points_x, - std::vector slopes); + int64_t initial_level, std::vector points_x, + std::vector slopes); // Builds a function consisting of one segment. - static PiecewiseLinearFunction* CreateOneSegmentFunction(int64 point_x, - int64 point_y, - int64 slope, - int64 other_point_x); + static PiecewiseLinearFunction* CreateOneSegmentFunction(int64_t point_x, + int64_t point_y, + int64_t slope, + int64_t other_point_x); // Builds a function consisting of one ray starting at the specified // x and y coordinates with the specified slope. - static PiecewiseLinearFunction* CreateRightRayFunction(int64 point_x, - int64 point_y, - int64 slope); + static PiecewiseLinearFunction* CreateRightRayFunction(int64_t point_x, + int64_t point_y, + int64_t slope); // Builds a function consisting of one ray starting at the specified // x and y coordinates with the specified slope. - static PiecewiseLinearFunction* CreateLeftRayFunction(int64 point_x, - int64 point_y, - int64 slope); + static PiecewiseLinearFunction* CreateLeftRayFunction(int64_t point_x, + int64_t point_y, + int64_t slope); // Builds a two-segment fixed charge piecewise linear cost function. For // values less than zero, the cost is zero. For values greater than zero, // cost follows the line specified by the slope and the value given as // arguments. The slope and value are positive. - static PiecewiseLinearFunction* CreateFixedChargeFunction(int64 slope, - int64 value); + static PiecewiseLinearFunction* CreateFixedChargeFunction(int64_t slope, + int64_t value); // Builds an earliness-tardiness two-segment piecewise linear cost function. // The reference specifies the point where the cost is zero. Before the @@ -168,7 +168,7 @@ class PiecewiseLinearFunction { // referece, it increases with the tardiness slope. The absolute values of // the slopes are given. static PiecewiseLinearFunction* CreateEarlyTardyFunction( - int64 reference, int64 earliness_slope, int64 tardiness_slope); + int64_t reference, int64_t earliness_slope, int64_t tardiness_slope); // Builds an earliness-tardiness three-segment piecewise linear cost function // with a slack period around the due date. The early slack is the point @@ -177,11 +177,11 @@ class PiecewiseLinearFunction { // specified. Between the early and the late slack point, the cost is zero. // The absolute values of the slopes are given. static PiecewiseLinearFunction* CreateEarlyTardyFunctionWithSlack( - int64 early_slack, int64 late_slack, int64 earliness_slope, - int64 tardiness_slope); + int64_t early_slack, int64_t late_slack, int64_t earliness_slope, + int64_t tardiness_slope); // Returns if x is in the domain of the function. - bool InDomain(int64 x) const; + bool InDomain(int64_t x) const; // Determines whether the piecewise linear function is convex or non-convex // and returns true when the function is convex. bool IsConvex() const; @@ -190,44 +190,44 @@ class PiecewiseLinearFunction { // Returns true if the piecewise linear function is non-increasing. bool IsNonIncreasing() const; // Returns the value of the piecewise linear function for x. - int64 Value(int64 x) const; + int64_t Value(int64_t x) const; // Returns the maximum value of all the segments in the function. - int64 GetMaximum() const; + int64_t GetMaximum() const; // Returns the minimum value of all the segments in the function. - int64 GetMinimum() const; + int64_t GetMinimum() const; // Returns the maximum endpoint value of the segments in the specified // range. If the range is disjoint from the segments in the function, it // returns kint64max. - int64 GetMaximum(int64 range_start, int64 range_end) const; + int64_t GetMaximum(int64_t range_start, int64_t range_end) const; // Returns the minimum endpoint value of the segments in the specified // range. If the range is disjoint from the segments in the function, it // returns kint64max. - int64 GetMinimum(int64 range_start, int64 range_end) const; + int64_t GetMinimum(int64_t range_start, int64_t range_end) const; // Returns the smallest range within a given range containing all values // greater than a given value. - std::pair GetSmallestRangeGreaterThanValue(int64 range_start, - int64 range_end, - int64 value) const; + std::pair GetSmallestRangeGreaterThanValue(int64_t range_start, + int64_t range_end, + int64_t value) const; // Returns the smallest range within a given range containing all values // less than a given value. - std::pair GetSmallestRangeLessThanValue(int64 range_start, - int64 range_end, - int64 value) const; + std::pair GetSmallestRangeLessThanValue(int64_t range_start, + int64_t range_end, + int64_t value) const; // Returns the smallest range within a given range containing all values // greater than value_min and less than value_max. - std::pair GetSmallestRangeInValueRange(int64 range_start, - int64 range_end, - int64 value_min, - int64 value_max) const; + std::pair GetSmallestRangeInValueRange(int64_t range_start, + int64_t range_end, + int64_t value_min, + int64_t value_max) const; // Adds 'constant' to the 'x' of all segments. If the argument is positive, // the translation is to the right and when it's negative, to the left. The // overflows and the underflows are sticky. - void AddConstantToX(int64 constant); + void AddConstantToX(int64_t constant); // Adds 'constant' to the 'y' of all segments. If the argument is positive, // the translation is up and when it's negative, down. The overflows and the // underflows are sticky. - void AddConstantToY(int64 constant); + void AddConstantToY(int64_t constant); // Adds the function to the existing one. The domain of the resulting // function is the intersection of the two domains. The overflows and // the underflows are sticky. @@ -253,10 +253,10 @@ class PiecewiseLinearFunction { // Operation between two functions. In any operation between two functions the // final domain is the intersection between the two domains. void Operation(const PiecewiseLinearFunction& other, - const std::function& operation); + const std::function& operation); // Finds start and end segment indices from a range; returns false if the // range is outside the domain of the function. - bool FindSegmentIndicesFromRange(int64 range_start, int64 range_end, + bool FindSegmentIndicesFromRange(int64_t range_start, int64_t range_end, int* start_segment, int* end_segment) const; void UpdateStatus() { if (is_modified_) { diff --git a/ortools/util/python/functions.i b/ortools/util/python/functions.i index 1864ffaea2..39eeb00c5c 100644 --- a/ortools/util/python/functions.i +++ b/ortools/util/python/functions.i @@ -106,80 +106,80 @@ static ReturnT InvokePythonCallableReturning(PyObject* pyfunc) { $1 = [input]() { return InvokePythonCallableReturning(input.get()); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); - $1 = [input](int64 index) { - return InvokePythonCallableReturning(input.get(), "(L)", index); + $1 = [input](int64_t index) { + return InvokePythonCallableReturning(input.get(), "(L)", index); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); - $1 = [input](int64 i, int64 j) { - return InvokePythonCallableReturning(input.get(), "LL", i, j); + $1 = [input](int64_t i, int64_t j) { + return InvokePythonCallableReturning(input.get(), "LL", i, j); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); - $1 = [input](int64 i, int64 j, int64 k) { - return InvokePythonCallableReturning(input.get(), "LLL", i, j, k); + $1 = [input](int64_t i, int64_t j, int64_t k) { + return InvokePythonCallableReturning(input.get(), "LLL", i, j, k); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); $1 = [input](int index) { - return InvokePythonCallableReturning(input.get(), "(i)", index); + return InvokePythonCallableReturning(input.get(), "(i)", index); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); $1 = [input](int i, int j) { - return InvokePythonCallableReturning(input.get(), "ii", i, j); + return InvokePythonCallableReturning(input.get(), "ii", i, j); }; } -// Wrap std::function +// Wrap std::function -%typecheck(SWIG_TYPECHECK_POINTER) std::function { +%typecheck(SWIG_TYPECHECK_POINTER) std::function { $1 = PyCallable_Check($input); } -%typemap(in) std::function { +%typemap(in) std::function { SharedPyPtr input($input); - $1 = [input](int64 index) { + $1 = [input](int64_t index) { return InvokePythonCallableReturning(input.get(), "(L)", index); }; } diff --git a/ortools/util/python/vector.i b/ortools/util/python/vector.i index 5120b7ff01..b5d7c83e29 100644 --- a/ortools/util/python/vector.i +++ b/ortools/util/python/vector.i @@ -84,7 +84,7 @@ %enddef // PY_LIST_OUTPUT_TYPEMAP PY_LIST_INPUT_OUTPUT_TYPEMAP(int, PyInt_Check, PyInt_FromLong); -PY_LIST_INPUT_OUTPUT_TYPEMAP(int64, SwigPyIntOrLong_Check, PyLong_FromLongLong); +PY_LIST_INPUT_OUTPUT_TYPEMAP(int64_t, SwigPyIntOrLong_Check, PyLong_FromLongLong); PY_LIST_INPUT_OUTPUT_TYPEMAP(double, PyFloat_Check, PyFloat_FromDouble); PY_LIST_INPUT_OUTPUT_TYPEMAP(std::string, SwigString_Check, SwigString_FromString); @@ -190,7 +190,7 @@ PY_LIST_INPUT_OUTPUT_TYPEMAP(std::string, SwigString_Check, SwigString_FromStrin %enddef // PY_LIST_LIST_INPUT_TYPEMAP PY_LIST_LIST_INPUT_TYPEMAP(int, PyInt_Check); -PY_LIST_LIST_INPUT_TYPEMAP(int64, SwigPyIntOrLong_Check); +PY_LIST_LIST_INPUT_TYPEMAP(int64_t, SwigPyIntOrLong_Check); PY_LIST_LIST_INPUT_TYPEMAP(double, PyFloat_Check); // Helpers to convert vectors of operations_research::Class* diff --git a/ortools/util/range_query_function.cc b/ortools/util/range_query_function.cc index 09d2f9c1c7..8498c22fde 100644 --- a/ortools/util/range_query_function.cc +++ b/ortools/util/range_query_function.cc @@ -27,71 +27,71 @@ namespace { class LinearRangeIntToIntFunction : public RangeIntToIntFunction { public: explicit LinearRangeIntToIntFunction( - std::function base_function) + std::function base_function) : base_function_(std::move(base_function)) {} - int64 Query(int64 argument) const override { + int64_t Query(int64_t argument) const override { return base_function_(argument); } - int64 RangeMin(int64 range_begin, int64 range_end) const override { + int64_t RangeMin(int64_t range_begin, int64_t range_end) const override { DCHECK_LT(range_begin, range_end); - int64 min_val = kint64max; - for (int64 i = range_begin; i < range_end; ++i) { + int64_t min_val = kint64max; + for (int64_t i = range_begin; i < range_end; ++i) { min_val = std::min(min_val, base_function_(i)); } return min_val; } - int64 RangeMax(int64 range_begin, int64 range_end) const override { + int64_t RangeMax(int64_t range_begin, int64_t range_end) const override { DCHECK_LT(range_begin, range_end); - int64 max_val = kint64min; - for (int64 i = range_begin; i < range_end; ++i) { + int64_t max_val = kint64min; + for (int64_t i = range_begin; i < range_end; ++i) { max_val = std::max(max_val, base_function_(i)); } return max_val; } - int64 RangeFirstInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const override { + int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const override { // domain_start_ <= range_begin < range_end <= domain_start_+array().size() DCHECK_LT(range_begin, range_end); DCHECK_LT(interval_begin, interval_end); - int64 i = range_begin; + int64_t i = range_begin; for (; i < range_end; ++i) { - const int64 value = base_function_(i); + const int64_t value = base_function_(i); if (interval_begin <= value && value < interval_end) break; } return i; } - int64 RangeLastInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const override { + int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const override { // domain_start_ <= range_begin < range_end <= domain_start_+array().size() DCHECK_NE(range_begin, kint64max); DCHECK_LT(range_begin, range_end); DCHECK_LT(interval_begin, interval_end); - int64 i = range_end - 1; + int64_t i = range_end - 1; for (; i >= range_begin; --i) { - const int64 value = base_function_(i); + const int64_t value = base_function_(i); if (interval_begin <= value && value < interval_end) break; } return i; } private: - std::function base_function_; + std::function base_function_; DISALLOW_COPY_AND_ASSIGN(LinearRangeIntToIntFunction); }; -std::vector FunctionToVector(const std::function& f, - int64 domain_start, int64 domain_end) { +std::vector FunctionToVector(const std::function& f, + int64_t domain_start, int64_t domain_end) { CHECK_LT(domain_start, domain_end); - std::vector output(domain_end - domain_start, 0); - for (int64 i = 0; i < domain_end - domain_start; ++i) { + std::vector output(domain_end - domain_start, 0); + for (int64_t i = 0; i < domain_end - domain_start; ++i) { output[i] = f(i + domain_start); } return output; @@ -103,78 +103,78 @@ std::vector FunctionToVector(const std::function& f, // 2. It creates a data structure for quick answer to range queries. class CachedRangeIntToIntFunction : public RangeIntToIntFunction { public: - CachedRangeIntToIntFunction(const std::function& base_function, - int64 domain_start, int64 domain_end) + CachedRangeIntToIntFunction(const std::function& base_function, + int64_t domain_start, int64_t domain_end) : domain_start_(domain_start), rmq_min_(FunctionToVector(base_function, domain_start, domain_end)), rmq_max_(rmq_min_.array()) { CHECK_LT(domain_start, domain_end); } - int64 Query(int64 argument) const override { + int64_t Query(int64_t argument) const override { DCHECK_LE(domain_start_, argument); - DCHECK_LE(argument, domain_start_ + static_cast(array().size())); + DCHECK_LE(argument, domain_start_ + static_cast(array().size())); return array()[argument - domain_start_]; } - int64 RangeMin(int64 from, int64 to) const override { + int64_t RangeMin(int64_t from, int64_t to) const override { DCHECK_LE(domain_start_, from); DCHECK_LT(from, to); - DCHECK_LE(to, domain_start_ + static_cast(array().size())); + DCHECK_LE(to, domain_start_ + static_cast(array().size())); return rmq_min_.GetMinimumFromRange(from - domain_start_, to - domain_start_); } - int64 RangeMax(int64 from, int64 to) const override { + int64_t RangeMax(int64_t from, int64_t to) const override { DCHECK_LE(domain_start_, from); DCHECK_LT(from, to); - DCHECK_LE(to, domain_start_ + static_cast(array().size())); + DCHECK_LE(to, domain_start_ + static_cast(array().size())); return rmq_max_.GetMinimumFromRange(from - domain_start_, to - domain_start_); } - int64 RangeFirstInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const override { + int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const override { // domain_start_ <= range_begin < range_end <= domain_start_+array().size() DCHECK_LE(domain_start_, range_begin); DCHECK_LT(range_begin, range_end); DCHECK_LE(range_end, domain_start_ + array().size()); DCHECK_LT(interval_begin, interval_end); - int64 i = range_begin; + int64_t i = range_begin; for (; i < range_end; ++i) { - const int64 value = array()[i - domain_start_]; + const int64_t value = array()[i - domain_start_]; if (interval_begin <= value && value < interval_end) break; } return i; } - int64 RangeLastInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const override { + int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const override { // domain_start_ <= range_begin < range_end <= domain_start_+array().size() DCHECK_LE(domain_start_, range_begin); DCHECK_LT(range_begin, range_end); DCHECK_LE(range_end, domain_start_ + array().size()); DCHECK_LT(interval_begin, interval_end); - int64 i = range_end - 1; + int64_t i = range_end - 1; for (; i >= range_begin; --i) { - const int64 value = array()[i - domain_start_]; + const int64_t value = array()[i - domain_start_]; if (interval_begin <= value && value < interval_end) break; } return i; } private: - const std::vector& array() const { return rmq_min_.array(); } + const std::vector& array() const { return rmq_min_.array(); } - const int64 domain_start_; - const RangeMinimumQuery> rmq_min_; - const RangeMinimumQuery> rmq_max_; + const int64_t domain_start_; + const RangeMinimumQuery> rmq_min_; + const RangeMinimumQuery> rmq_max_; DISALLOW_COPY_AND_ASSIGN(CachedRangeIntToIntFunction); }; class CachedRangeMinMaxIndexFunction : public RangeMinMaxIndexFunction { public: - CachedRangeMinMaxIndexFunction(const std::function& f, - int64 domain_start, int64 domain_end) + CachedRangeMinMaxIndexFunction(const std::function& f, + int64_t domain_start, int64_t domain_end) : domain_start_(domain_start), domain_end_(domain_end), index_rmq_min_(FunctionToVector(f, domain_start, domain_end)), @@ -182,7 +182,7 @@ class CachedRangeMinMaxIndexFunction : public RangeMinMaxIndexFunction { CHECK_LT(domain_start, domain_end); } - inline int64 RangeMinArgument(int64 from, int64 to) const override { + inline int64_t RangeMinArgument(int64_t from, int64_t to) const override { DCHECK_LE(domain_start_, from); DCHECK_LT(from, to); DCHECK_LE(to, domain_end_); @@ -190,7 +190,7 @@ class CachedRangeMinMaxIndexFunction : public RangeMinMaxIndexFunction { to - domain_start_) + domain_start_; } - inline int64 RangeMaxArgument(int64 from, int64 to) const override { + inline int64_t RangeMaxArgument(int64_t from, int64_t to) const override { DCHECK_LE(domain_start_, from); DCHECK_LT(from, to); DCHECK_LE(to, domain_end_); @@ -200,28 +200,28 @@ class CachedRangeMinMaxIndexFunction : public RangeMinMaxIndexFunction { } private: - const int64 domain_start_; - const int64 domain_end_; - const RangeMinimumIndexQuery> index_rmq_min_; - const RangeMinimumIndexQuery> index_rmq_max_; + const int64_t domain_start_; + const int64_t domain_end_; + const RangeMinimumIndexQuery> index_rmq_min_; + const RangeMinimumIndexQuery> index_rmq_max_; DISALLOW_COPY_AND_ASSIGN(CachedRangeMinMaxIndexFunction); }; } // namespace -RangeIntToIntFunction* MakeBareIntToIntFunction(std::function f) { +RangeIntToIntFunction* MakeBareIntToIntFunction(std::function f) { return new LinearRangeIntToIntFunction(std::move(f)); } RangeIntToIntFunction* MakeCachedIntToIntFunction( - const std::function& f, int64 domain_start, - int64 domain_end) { + const std::function& f, int64_t domain_start, + int64_t domain_end) { return new CachedRangeIntToIntFunction(f, domain_start, domain_end); } RangeMinMaxIndexFunction* MakeCachedRangeMinMaxIndexFunction( - const std::function& f, int64 domain_start, - int64 domain_end) { + const std::function& f, int64_t domain_start, + int64_t domain_end) { return new CachedRangeMinMaxIndexFunction(f, domain_start, domain_end); } } // namespace operations_research diff --git a/ortools/util/range_query_function.h b/ortools/util/range_query_function.h index 0bc9cc9c5c..1db4c0f976 100644 --- a/ortools/util/range_query_function.h +++ b/ortools/util/range_query_function.h @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The header defines an interface for functions taking and returning an int64 +// The header defines an interface for functions taking and returning an int64_t // and supporting range queries over their domain and codomain. #ifndef OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_ @@ -23,7 +23,7 @@ #include "ortools/base/integral_types.h" namespace operations_research { -// RangeIntToIntFunction is an interface to int64->int64 functions supporting +// RangeIntToIntFunction is an interface to int64_t->int64_t functions supporting // fast answer to range queries about their domain/codomain. class RangeIntToIntFunction { public: @@ -32,21 +32,21 @@ class RangeIntToIntFunction { // Suppose f is the abstract underlying function. // Returns f(argument). // TODO(user): Rename to Run - virtual int64 Query(int64 argument) const = 0; + virtual int64_t Query(int64_t argument) const = 0; // Returns min_x f(x), where x is in [from, to). - virtual int64 RangeMin(int64 from, int64 to) const = 0; + virtual int64_t RangeMin(int64_t from, int64_t to) const = 0; // Returns max_x f(x), where x is in [from, to). - virtual int64 RangeMax(int64 from, int64 to) const = 0; + virtual int64_t RangeMax(int64_t from, int64_t to) const = 0; // Returns the first x from [range_begin, range_end) for which f(x) is in // [interval_begin, interval_end), or range_end if there is no such x. - virtual int64 RangeFirstInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const = 0; + virtual int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const = 0; // Returns the last x from [range_begin, range_end) for which f(x) is in // [interval_begin, interval_end), or range_begin-1 if there is no such x. - virtual int64 RangeLastInsideInterval(int64 range_begin, int64 range_end, - int64 interval_begin, - int64 interval_end) const = 0; + virtual int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end, + int64_t interval_begin, + int64_t interval_end) const = 0; }; // RangeMinMaxIndexFunction is different from RangeIntToIntFunction in two ways: @@ -61,24 +61,24 @@ class RangeMinMaxIndexFunction { // Suppose f is the abstract underlying function. // Returns an x from [from, to), such that f(x) => f(y) for every y from // [from, to). - virtual int64 RangeMaxArgument(int64 from, int64 to) const = 0; + virtual int64_t RangeMaxArgument(int64_t from, int64_t to) const = 0; // Returns an x from [from, to), such that f(x) <= f(y) for every y from // [from, to). - virtual int64 RangeMinArgument(int64 from, int64 to) const = 0; + virtual int64_t RangeMinArgument(int64_t from, int64_t to) const = 0; }; // A copy of f is going to be stored in the returned object, so its closure // should remain intact as long as the returned object is being used. -RangeIntToIntFunction* MakeBareIntToIntFunction(std::function f); +RangeIntToIntFunction* MakeBareIntToIntFunction(std::function f); // It is assumed that f is defined over the interval [domain_start, domain_end). // The function scans f once and it is safe to destroy f and its closure after // MakeCachedIntToIntFunction returns. RangeIntToIntFunction* MakeCachedIntToIntFunction( - const std::function& f, int64 domain_start, int64 domain_end); + const std::function& f, int64_t domain_start, int64_t domain_end); // It is safe to destroy the first argument and its closure after // MakeCachedRangeMinMaxIndexFunction returns. RangeMinMaxIndexFunction* MakeCachedRangeMinMaxIndexFunction( - const std::function& f, int64 domain_start, int64 domain_end); + const std::function& f, int64_t domain_start, int64_t domain_end); } // namespace operations_research #endif // OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_ diff --git a/ortools/util/rational_approximation.cc b/ortools/util/rational_approximation.cc index a629985bc5..6230fd502e 100644 --- a/ortools/util/rational_approximation.cc +++ b/ortools/util/rational_approximation.cc @@ -31,14 +31,14 @@ Fraction RationalApproximation(const double x, const double precision) { // Fractional is float or double are as accurate as possible. long double abs_x = std::abs(x); long double y = abs_x; - int64 previous_numerator = 0; - int64 previous_denominator = 1; - int64 numerator = 1; - int64 denominator = 0; + int64_t previous_numerator = 0; + int64_t previous_denominator = 1; + int64_t numerator = 1; + int64_t denominator = 0; while (true) { - const int64 term = static_cast(std::floor(y)); - const int64 new_numerator = term * numerator + previous_numerator; - const int64 new_denominator = term * denominator + previous_denominator; + const int64_t term = static_cast(std::floor(y)); + const int64_t new_numerator = term * numerator + previous_numerator; + const int64_t new_denominator = term * denominator + previous_denominator; // If there was an overflow, we prefer returning a not-so-good approximation // rather than something that is completely wrong. if (new_numerator < 0 || new_denominator < 0) break; diff --git a/ortools/util/rational_approximation.h b/ortools/util/rational_approximation.h index 53c19342d7..ef294ec847 100644 --- a/ortools/util/rational_approximation.h +++ b/ortools/util/rational_approximation.h @@ -23,7 +23,7 @@ namespace operations_research { // The type Fraction represents a number in the form of two integers: numerator // and denominator. This type is used to display the rational approximation // of a Fractional number. -typedef std::pair Fraction; +typedef std::pair Fraction; // Computes a rational approximation numerator/denominator for value x // using a continued fraction algorithm. The absolute difference between the diff --git a/ortools/util/rev.h b/ortools/util/rev.h index 1408a0f548..e1f759eea4 100644 --- a/ortools/util/rev.h +++ b/ortools/util/rev.h @@ -68,14 +68,14 @@ class RevRepository : public ReversibleInterface { // maintained by this class and is updated on each level changes. The whole // process make sure that only one SaveValue() par level will ever be called, // so it is efficient to call this before each update to the object T. - void SaveStateWithStamp(T* object, int64* stamp) { + void SaveStateWithStamp(T* object, int64_t* stamp) { if (*stamp == stamp_) return; *stamp = stamp_; SaveState(object); } private: - int64 stamp_; + int64_t stamp_; std::vector end_of_level_; // In stack_. // TODO(user): If we ever see this in any cpu profile, consider using two diff --git a/ortools/util/saturated_arithmetic.h b/ortools/util/saturated_arithmetic.h index 7999ea4477..3ac2b524c1 100644 --- a/ortools/util/saturated_arithmetic.h +++ b/ortools/util/saturated_arithmetic.h @@ -35,21 +35,21 @@ namespace operations_research { // // Note that the static assert will break if the code is compiled on machines // which do not use two's complement. -inline int64 TwosComplementAddition(int64 x, int64 y) { - static_assert(static_cast(-1LL) == ~0ULL, +inline int64_t TwosComplementAddition(int64_t x, int64_t y) { + static_assert(static_cast(-1LL) == ~0ULL, "The target architecture does not use two's complement."); - return absl::bit_cast(static_cast(x) + static_cast(y)); + return absl::bit_cast(static_cast(x) + static_cast(y)); } -inline int64 TwosComplementSubtraction(int64 x, int64 y) { - static_assert(static_cast(-1LL) == ~0ULL, +inline int64_t TwosComplementSubtraction(int64_t x, int64_t y) { + static_assert(static_cast(-1LL) == ~0ULL, "The target architecture does not use two's complement."); - return absl::bit_cast(static_cast(x) - static_cast(y)); + return absl::bit_cast(static_cast(x) - static_cast(y)); } // Helper function that returns true if an overflow has occured in computing // sum = x + y. sum is expected to be computed elsewhere. -inline bool AddHadOverflow(int64 x, int64 y, int64 sum) { +inline bool AddHadOverflow(int64_t x, int64_t y, int64_t sum) { // Overflow cannot occur if operands have different signs. // It can only occur if sign(x) == sign(y) and sign(sum) != sign(x), // which is equivalent to: sign(x) != sign(sum) && sign(y) != sign(sum). @@ -58,7 +58,7 @@ inline bool AddHadOverflow(int64 x, int64 y, int64 sum) { return ((x ^ sum) & (y ^ sum)) < 0; } -inline bool SubHadOverflow(int64 x, int64 y, int64 diff) { +inline bool SubHadOverflow(int64_t x, int64_t y, int64_t diff) { // This is the same reasoning as for AddHadOverflow. We have x = diff + y. // The formula is the same, with 'x' and diff exchanged. DCHECK_EQ(diff, TwosComplementSubtraction(x, y)); @@ -73,11 +73,11 @@ inline bool SubHadOverflow(int64 x, int64 y, int64 diff) { // and B is finite, then A-B won't be kint64max: overflows aren't sticky. // TODO(user): consider making some operations overflow-sticky, some others // not, but make an explicit choice throughout. -inline bool AddOverflows(int64 x, int64 y) { +inline bool AddOverflows(int64_t x, int64_t y) { return AddHadOverflow(x, y, TwosComplementAddition(x, y)); } -inline int64 SubOverflows(int64 x, int64 y) { +inline int64_t SubOverflows(int64_t x, int64_t y) { return SubHadOverflow(x, y, TwosComplementSubtraction(x, y)); } @@ -85,30 +85,30 @@ inline int64 SubOverflows(int64 x, int64 y) { // This function only works for typed integer type (IntType<>). template bool SafeAddInto(IntegerType a, IntegerType* b) { - const int64 x = a.value(); - const int64 y = b->value(); - const int64 sum = TwosComplementAddition(x, y); + const int64_t x = a.value(); + const int64_t y = b->value(); + const int64_t sum = TwosComplementAddition(x, y); if (AddHadOverflow(x, y, sum)) return false; *b = sum; return true; } // Returns kint64max if x >= 0 and kint64min if x < 0. -inline int64 CapWithSignOf(int64 x) { +inline int64_t CapWithSignOf(int64_t x) { // return kint64max if x >= 0 or kint64max + 1 (== kint64min) if x < 0. - return TwosComplementAddition(kint64max, static_cast(x < 0)); + return TwosComplementAddition(kint64max, static_cast(x < 0)); } -inline int64 CapAddGeneric(int64 x, int64 y) { - const int64 result = TwosComplementAddition(x, y); +inline int64_t CapAddGeneric(int64_t x, int64_t y) { + const int64_t result = TwosComplementAddition(x, y); return AddHadOverflow(x, y, result) ? CapWithSignOf(x) : result; } #if defined(__GNUC__) && defined(__x86_64__) // TODO(user): port this to other architectures. -inline int64 CapAddFast(int64 x, int64 y) { - const int64 cap = CapWithSignOf(x); - int64 result = x; +inline int64_t CapAddFast(int64_t x, int64_t y) { + const int64_t cap = CapWithSignOf(x); + int64_t result = x; // clang-format off asm volatile( // 'volatile': ask compiler optimizer "keep as is". "\t" "addq %[y],%[result]" @@ -121,7 +121,7 @@ inline int64 CapAddFast(int64 x, int64 y) { } #endif -inline int64 CapAdd(int64 x, int64 y) { +inline int64_t CapAdd(int64_t x, int64_t y) { #if defined(__GNUC__) && defined(__x86_64__) return CapAddFast(x, y); #else @@ -129,16 +129,16 @@ inline int64 CapAdd(int64 x, int64 y) { #endif } -inline int64 CapSubGeneric(int64 x, int64 y) { - const int64 result = TwosComplementSubtraction(x, y); +inline int64_t CapSubGeneric(int64_t x, int64_t y) { + const int64_t result = TwosComplementSubtraction(x, y); return SubHadOverflow(x, y, result) ? CapWithSignOf(x) : result; } #if defined(__GNUC__) && defined(__x86_64__) // TODO(user): port this to other architectures. -inline int64 CapSubFast(int64 x, int64 y) { - const int64 cap = CapWithSignOf(x); - int64 result = x; +inline int64_t CapSubFast(int64_t x, int64_t y) { + const int64_t cap = CapWithSignOf(x); + int64_t result = x; // clang-format off asm volatile( // 'volatile': ask compiler optimizer "keep as is". "\t" "subq %[y],%[result]" @@ -151,7 +151,7 @@ inline int64 CapSubFast(int64 x, int64 y) { } #endif -inline int64 CapSub(int64 x, int64 y) { +inline int64_t CapSub(int64_t x, int64_t y) { #if defined(__GNUC__) && defined(__x86_64__) return CapSubFast(x, y); #else @@ -160,13 +160,13 @@ inline int64 CapSub(int64 x, int64 y) { } // Note(user): -kint64min != kint64max, but kint64max == ~kint64min. -inline int64 CapOpp(int64 v) { return v == kint64min ? ~v : -v; } +inline int64_t CapOpp(int64_t v) { return v == kint64min ? ~v : -v; } namespace cap_prod_util { // Returns an unsigned int equal to the absolute value of n, in a way that // will not produce overflows. -inline uint64 uint_abs(int64 n) { - return n < 0 ? ~static_cast(n) + 1 : static_cast(n); +inline uint64_t uint_abs(int64_t n) { + return n < 0 ? ~static_cast(n) + 1 : static_cast(n); } } // namespace cap_prod_util @@ -176,10 +176,10 @@ inline uint64 uint_abs(int64 n) { // If the result needs at least 64 bits, then return a capped value. // If the result needs at most 63 bits, then return the product. // Otherwise, the result may use 63 or 64 bits: compute the product -// as a uint64, and cap it if necessary. -inline int64 CapProdGeneric(int64 x, int64 y) { - const uint64 a = cap_prod_util::uint_abs(x); - const uint64 b = cap_prod_util::uint_abs(y); +// as a uint64_t, and cap it if necessary. +inline int64_t CapProdGeneric(int64_t x, int64_t y) { + const uint64_t a = cap_prod_util::uint_abs(x); + const uint64_t b = cap_prod_util::uint_abs(y); // Let MSB(x) denote the most significant bit of x. We have: // MSB(x) + MSB(y) <= MSB(x * y) <= MSB(x) + MSB(y) + 1 const int msb_sum = @@ -189,29 +189,29 @@ inline int64 CapProdGeneric(int64 x, int64 y) { // Catch a == 0 or b == 0 now, as MostSignificantBitPosition64(0) == 0. // TODO(user): avoid this by writing function Log2(a) with Log2(0) == -1. if (a == 0 || b == 0) return 0; - const int64 cap = CapWithSignOf(x ^ y); + const int64_t cap = CapWithSignOf(x ^ y); if (msb_sum >= kMaxBitIndexInInt64) return cap; // The corner case is when msb_sum == 62, i.e. at least 63 bits will be // needed to store the product. The following product will never overflow - // on uint64, since msb_sum == 62. - const uint64 u_prod = a * b; + // on uint64_t, since msb_sum == 62. + const uint64_t u_prod = a * b; // The overflow cases are captured by one of the following conditions: - // (cap >= 0 && u_prod >= static_cast(kint64max) or - // (cap < 0 && u_prod >= static_cast(kint64min)). + // (cap >= 0 && u_prod >= static_cast(kint64max) or + // (cap < 0 && u_prod >= static_cast(kint64min)). // These can be optimized as follows (and if the condition is false, it is // safe to compute x * y. - if (u_prod >= static_cast(cap)) return cap; - const int64 abs_result = absl::bit_cast(u_prod); + if (u_prod >= static_cast(cap)) return cap; + const int64_t abs_result = absl::bit_cast(u_prod); return cap < 0 ? -abs_result : abs_result; } #if defined(__GNUC__) && defined(__x86_64__) // TODO(user): port this to other architectures. -inline int64 CapProdFast(int64 x, int64 y) { +inline int64_t CapProdFast(int64_t x, int64_t y) { // cap = kint64max if x and y have the same sign, cap = kint64min // otherwise. - const int64 cap = CapWithSignOf(x ^ y); - int64 result = x; + const int64_t cap = CapWithSignOf(x ^ y); + int64_t result = x; // Here, we use the fact that imul of two signed 64-integers returns a 128-bit // result -- we care about the lower 64 bits. More importantly, imul also sets // the carry flag if 64 bits were not enough. @@ -228,7 +228,7 @@ inline int64 CapProdFast(int64 x, int64 y) { } #endif -inline int64 CapProd(int64 x, int64 y) { +inline int64_t CapProd(int64_t x, int64_t y) { #if defined(__GNUC__) && defined(__x86_64__) return CapProdFast(x, y); #else diff --git a/ortools/util/sorted_interval_list.cc b/ortools/util/sorted_interval_list.cc index ed2cbf487a..9e0f62f1cf 100644 --- a/ortools/util/sorted_interval_list.cc +++ b/ortools/util/sorted_interval_list.cc @@ -84,17 +84,17 @@ void UnionOfSortedIntervals(absl::InlinedVector* intervals) { } // namespace // TODO(user): Use MathUtil::CeilOfRatio / FloorOfRatio instead. -int64 CeilRatio(int64 value, int64 positive_coeff) { +int64_t CeilRatio(int64_t value, int64_t positive_coeff) { DCHECK_GT(positive_coeff, 0); - const int64 result = value / positive_coeff; - const int64 adjust = static_cast(result * positive_coeff < value); + const int64_t result = value / positive_coeff; + const int64_t adjust = static_cast(result * positive_coeff < value); return result + adjust; } -int64 FloorRatio(int64 value, int64 positive_coeff) { +int64_t FloorRatio(int64_t value, int64_t positive_coeff) { DCHECK_GT(positive_coeff, 0); - const int64 result = value / positive_coeff; - const int64 adjust = static_cast(result * positive_coeff > value); + const int64_t result = value / positive_coeff; + const int64_t adjust = static_cast(result * positive_coeff > value); return result - adjust; } @@ -111,7 +111,7 @@ std::ostream& operator<<(std::ostream& out, const Domain& domain) { return out << IntervalsAsString(domain); } -Domain::Domain(int64 value) : intervals_({{value, value}}) {} +Domain::Domain(int64_t value) : intervals_({{value, value}}) {} // HACK(user): We spare significant time if we use an initializer here, because // InlineVector<1> is able to recognize the fast path or "exactly one element". @@ -120,7 +120,7 @@ Domain::Domain(int64 value) : intervals_({{value, value}}) {} // Since the constructor takes very few cycles (most likely less than 10), // that's quite significant. namespace { -inline ClosedInterval UncheckedClosedInterval(int64 s, int64 e) { +inline ClosedInterval UncheckedClosedInterval(int64_t s, int64_t e) { ClosedInterval i; i.start = s; i.end = e; @@ -128,17 +128,17 @@ inline ClosedInterval UncheckedClosedInterval(int64 s, int64 e) { } } // namespace -Domain::Domain(int64 left, int64 right) +Domain::Domain(int64_t left, int64_t right) : intervals_({UncheckedClosedInterval(left, right)}) { if (left > right) intervals_.clear(); } Domain Domain::AllValues() { return Domain(kint64min, kint64max); } -Domain Domain::FromValues(std::vector values) { +Domain Domain::FromValues(std::vector values) { std::sort(values.begin(), values.end()); Domain result; - for (const int64 v : values) { + for (const int64_t v : values) { if (result.intervals_.empty() || v > result.intervals_.back().end + 1) { result.intervals_.push_back({v, v}); } else { @@ -156,7 +156,7 @@ Domain Domain::FromIntervals(absl::Span intervals) { return result; } -Domain Domain::FromFlatSpanOfIntervals(absl::Span flat_intervals) { +Domain Domain::FromFlatSpanOfIntervals(absl::Span flat_intervals) { DCHECK(flat_intervals.size() % 2 == 0) << flat_intervals.size(); Domain result; result.intervals_.reserve(flat_intervals.size() / 2); @@ -168,14 +168,14 @@ Domain Domain::FromFlatSpanOfIntervals(absl::Span flat_intervals) { return result; } -Domain Domain::FromFlatIntervals(const std::vector& flat_intervals) { +Domain Domain::FromFlatIntervals(const std::vector& flat_intervals) { return FromFlatSpanOfIntervals(absl::MakeSpan(flat_intervals)); } Domain Domain::FromVectorIntervals( - const std::vector>& intervals) { + const std::vector>& intervals) { Domain result; - for (const std::vector& interval : intervals) { + for (const std::vector& interval : intervals) { if (interval.size() == 1) { result.intervals_.push_back({interval[0], interval[0]}); } else { @@ -192,8 +192,8 @@ bool Domain::IsEmpty() const { return intervals_.empty(); } bool Domain::IsFixed() const { return Min() == Max(); } -int64 Domain::Size() const { - int64 size = 0; +int64_t Domain::Size() const { + int64_t size = 0; for (const ClosedInterval interval : intervals_) { size = operations_research::CapAdd( size, operations_research::CapSub(interval.end, interval.start)); @@ -204,22 +204,22 @@ int64 Domain::Size() const { return size; } -int64 Domain::Min() const { +int64_t Domain::Min() const { DCHECK(!IsEmpty()); return intervals_.front().start; } -int64 Domain::Max() const { +int64_t Domain::Max() const { DCHECK(!IsEmpty()); return intervals_.back().end; } -int64 Domain::FixedValue() const { +int64_t Domain::FixedValue() const { DCHECK(IsFixed()); return intervals_.front().start; } -bool Domain::Contains(int64 value) const { +bool Domain::Contains(int64_t value) const { // Because we only compare by start and there is no duplicate starts, this // should be the next interval after the one that has a chance to contains // value. @@ -245,7 +245,7 @@ bool Domain::IsIncludedIn(const Domain& domain) const { Domain Domain::Complement() const { Domain result; - int64 next_start = kint64min; + int64_t next_start = kint64min; result.intervals_.reserve(intervals_.size() + 1); for (const ClosedInterval& interval : intervals_) { if (interval.start != kint64min) { @@ -359,13 +359,13 @@ Domain Domain::RelaxIfTooComplex() const { } } -Domain Domain::MultiplicationBy(int64 coeff, bool* exact) const { +Domain Domain::MultiplicationBy(int64_t coeff, bool* exact) const { if (exact != nullptr) *exact = true; if (intervals_.empty()) return {}; if (coeff == 0) return Domain(0); - const int64 abs_coeff = std::abs(coeff); - const int64 size_if_non_trivial = abs_coeff > 1 ? Size() : 0; + const int64_t abs_coeff = std::abs(coeff); + const int64_t size_if_non_trivial = abs_coeff > 1 ? Size() : 0; if (size_if_non_trivial > kDomainComplexityLimit) { if (exact != nullptr) *exact = false; return ContinuousMultiplicationBy(coeff); @@ -373,15 +373,15 @@ Domain Domain::MultiplicationBy(int64 coeff, bool* exact) const { Domain result; if (abs_coeff > 1) { - const int64 max_value = kint64max / abs_coeff; - const int64 min_value = kint64min / abs_coeff; + const int64_t max_value = kint64max / abs_coeff; + const int64_t min_value = kint64min / abs_coeff; result.intervals_.reserve(size_if_non_trivial); for (const ClosedInterval& i : intervals_) { - for (int64 v = i.start;; ++v) { + for (int64_t v = i.start;; ++v) { // We ignore anything that overflow. if (v >= min_value && v <= max_value) { // Because abs_coeff > 1, all new values are disjoint. - const int64 new_value = v * abs_coeff; + const int64_t new_value = v * abs_coeff; result.intervals_.push_back({new_value, new_value}); } @@ -396,9 +396,9 @@ Domain Domain::MultiplicationBy(int64 coeff, bool* exact) const { return result; } -Domain Domain::ContinuousMultiplicationBy(int64 coeff) const { +Domain Domain::ContinuousMultiplicationBy(int64_t coeff) const { Domain result = *this; - const int64 abs_coeff = std::abs(coeff); + const int64_t abs_coeff = std::abs(coeff); for (ClosedInterval& i : result.intervals_) { i.start = CapProd(i.start, abs_coeff); i.end = CapProd(i.end, abs_coeff); @@ -413,10 +413,10 @@ Domain Domain::ContinuousMultiplicationBy(const Domain& domain) const { for (const ClosedInterval& i : this->intervals_) { for (const ClosedInterval& j : domain.intervals_) { ClosedInterval new_interval; - const int64 a = CapProd(i.start, j.start); - const int64 b = CapProd(i.end, j.end); - const int64 c = CapProd(i.start, j.end); - const int64 d = CapProd(i.end, j.start); + const int64_t a = CapProd(i.start, j.start); + const int64_t b = CapProd(i.end, j.end); + const int64_t c = CapProd(i.start, j.end); + const int64_t d = CapProd(i.end, j.start); new_interval.start = std::min({a, b, c, d}); new_interval.end = std::max({a, b, c, d}); result.intervals_.push_back(new_interval); @@ -427,10 +427,10 @@ Domain Domain::ContinuousMultiplicationBy(const Domain& domain) const { return result; } -Domain Domain::DivisionBy(int64 coeff) const { +Domain Domain::DivisionBy(int64_t coeff) const { CHECK_NE(coeff, 0); Domain result = *this; - const int64 abs_coeff = std::abs(coeff); + const int64_t abs_coeff = std::abs(coeff); for (ClosedInterval& i : result.intervals_) { i.start = i.start / abs_coeff; i.end = i.end / abs_coeff; @@ -440,16 +440,16 @@ Domain Domain::DivisionBy(int64 coeff) const { return result; } -Domain Domain::InverseMultiplicationBy(const int64 coeff) const { +Domain Domain::InverseMultiplicationBy(const int64_t coeff) const { if (coeff == 0) { return Contains(0) ? Domain::AllValues() : Domain(); } Domain result = *this; int new_size = 0; - const int64 abs_coeff = std::abs(coeff); + const int64_t abs_coeff = std::abs(coeff); for (const ClosedInterval& i : result.intervals_) { - const int64 start = CeilRatio(i.start, abs_coeff); - const int64 end = FloorRatio(i.end, abs_coeff); + const int64_t start = CeilRatio(i.start, abs_coeff); + const int64_t end = FloorRatio(i.end, abs_coeff); if (start > end) continue; if (new_size > 0 && start == result.intervals_[new_size - 1].end + 1) { result.intervals_[new_size - 1].end = end; @@ -473,8 +473,8 @@ Domain Domain::SimplifyUsingImpliedDomain(const Domain& implied_domain) const { if (implied_domain.IsEmpty()) return result; int i = 0; - int64 min_point; - int64 max_point; + int64_t min_point; + int64_t max_point; bool started = false; for (const ClosedInterval interval : intervals_) { // We only "close" the new result interval if it cannot be extended by @@ -493,7 +493,7 @@ Domain Domain::SimplifyUsingImpliedDomain(const Domain& implied_domain) const { const ClosedInterval current = implied_domain.intervals_[i]; if (current.end >= interval.start && current.start <= interval.end) { // Current and interval have a non-empty intersection. - const int64 inter_max = std::min(interval.end, current.end); + const int64_t inter_max = std::min(interval.end, current.end); if (!started) { started = true; min_point = std::max(interval.start, current.start); @@ -516,8 +516,8 @@ Domain Domain::SimplifyUsingImpliedDomain(const Domain& implied_domain) const { return result; } -std::vector Domain::FlattenedIntervals() const { - std::vector result; +std::vector Domain::FlattenedIntervals() const { + std::vector result; for (const ClosedInterval& interval : intervals_) { result.push_back(interval.start); result.push_back(interval.end); @@ -542,8 +542,8 @@ bool Domain::operator<(const Domain& other) const { std::string Domain::ToString() const { return IntervalsAsString(intervals_); } -int64 SumOfKMinValueInDomain(const Domain& domain, int k) { - int64 current_sum = 0.0; +int64_t SumOfKMinValueInDomain(const Domain& domain, int k) { + int64_t current_sum = 0.0; int current_index = 0; for (const ClosedInterval interval : domain) { if (current_index >= k) break; @@ -556,14 +556,14 @@ int64 SumOfKMinValueInDomain(const Domain& domain, int k) { return current_sum; } -int64 SumOfKMaxValueInDomain(const Domain& domain, int k) { +int64_t SumOfKMaxValueInDomain(const Domain& domain, int k) { return -SumOfKMinValueInDomain(domain.Negation(), k); } SortedDisjointIntervalList::SortedDisjointIntervalList() {} SortedDisjointIntervalList::SortedDisjointIntervalList( - const std::vector& starts, const std::vector& ends) { + const std::vector& starts, const std::vector& ends) { InsertIntervals(starts, ends); } @@ -580,12 +580,12 @@ SortedDisjointIntervalList::SortedDisjointIntervalList( } SortedDisjointIntervalList -SortedDisjointIntervalList::BuildComplementOnInterval(int64 start, int64 end) { +SortedDisjointIntervalList::BuildComplementOnInterval(int64_t start, int64_t end) { SortedDisjointIntervalList interval_list; - int64 next_start = start; + int64_t next_start = start; for (auto it = FirstIntervalGreaterOrEqual(start); it != this->end(); ++it) { const ClosedInterval& interval = *it; - const int64 next_end = CapSub(interval.start, 1); + const int64_t next_end = CapSub(interval.start, 1); if (next_end > end) break; if (next_start <= next_end) { interval_list.InsertInterval(next_start, next_end); @@ -599,7 +599,7 @@ SortedDisjointIntervalList::BuildComplementOnInterval(int64 start, int64 end) { } SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::InsertInterval( - int64 start, int64 end) { + int64_t start, int64_t end) { // start > end could mean an empty interval, but we prefer to LOG(DFATAL) // anyway. Really, the user should never give us that. if (start > end) { @@ -623,7 +623,7 @@ SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::InsertInterval( if (start == kint64min) { // Catch underflows it1 = intervals_.begin(); } else { - const int64 before_start = start - 1; + const int64_t before_start = start - 1; while (it1 != intervals_.begin()) { auto prev_it = it1; --prev_it; @@ -638,7 +638,7 @@ SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::InsertInterval( if (end == kint64max) { it2 = intervals_.end(); } else { - const int64 after_end = end + 1; + const int64_t after_end = end + 1; do { ++it2; } while (it2 != intervals_.end() && it2->start <= after_end); @@ -650,8 +650,8 @@ SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::InsertInterval( auto it3 = it2; it3--; if (it1 == it3) return it3; // Nothing was merged. - const int64 new_start = std::min(it1->start, start); - const int64 new_end = std::max(it3->end, end); + const int64_t new_start = std::min(it1->start, start); + const int64_t new_end = std::max(it3->end, end); auto it = intervals_.erase(it1, it3); // HACK(user): set iterators point to *const* values. Which is expected, // because if one alters a set element's value, then it collapses the set @@ -663,7 +663,7 @@ SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::InsertInterval( } SortedDisjointIntervalList::Iterator SortedDisjointIntervalList::GrowRightByOne( - int64 value, int64* newly_covered) { + int64_t value, int64_t* newly_covered) { auto it = intervals_.upper_bound({value, kint64max}); auto it_prev = it; @@ -712,7 +712,7 @@ void SortedDisjointIntervalList::InsertAll(const std::vector& starts, } void SortedDisjointIntervalList::InsertIntervals( - const std::vector& starts, const std::vector& ends) { + const std::vector& starts, const std::vector& ends) { InsertAll(starts, ends); } @@ -723,7 +723,7 @@ void SortedDisjointIntervalList::InsertIntervals(const std::vector& starts, } SortedDisjointIntervalList::Iterator -SortedDisjointIntervalList::FirstIntervalGreaterOrEqual(int64 value) const { +SortedDisjointIntervalList::FirstIntervalGreaterOrEqual(int64_t value) const { const auto it = intervals_.upper_bound({value, kint64max}); if (it == begin()) return it; auto it_prev = it; @@ -733,7 +733,7 @@ SortedDisjointIntervalList::FirstIntervalGreaterOrEqual(int64 value) const { } SortedDisjointIntervalList::Iterator -SortedDisjointIntervalList::LastIntervalLessOrEqual(int64 value) const { +SortedDisjointIntervalList::LastIntervalLessOrEqual(int64_t value) const { const auto it = intervals_.upper_bound({value, kint64max}); if (it == begin()) return end(); auto it_prev = it; diff --git a/ortools/util/sorted_interval_list.h b/ortools/util/sorted_interval_list.h index dd0038cac4..4d201db4a3 100644 --- a/ortools/util/sorted_interval_list.h +++ b/ortools/util/sorted_interval_list.h @@ -32,7 +32,7 @@ namespace operations_research { */ struct ClosedInterval { ClosedInterval() {} - ClosedInterval(int64 s, int64 e) : start(s), end(e) { + ClosedInterval(int64_t s, int64_t e) : start(s), end(e) { DLOG_IF(DFATAL, s > e) << "Invalid ClosedInterval(" << s << ", " << e << ")"; } @@ -49,8 +49,8 @@ struct ClosedInterval { return start < other.start; } - int64 start = 0; // Inclusive. - int64 end = 0; // Inclusive. + int64_t start = 0; // Inclusive. + int64_t end = 0; // Inclusive. }; std::ostream& operator<<(std::ostream& out, const ClosedInterval& interval); @@ -104,13 +104,13 @@ class Domain { #endif // !defined(SWIG) /// Constructor for the common case of a singleton domain. - explicit Domain(int64 value); + explicit Domain(int64_t value); /** * Constructor for the common case of a single interval [left, right]. * If left > right, this will result in the empty domain. */ - Domain(int64 left, int64 right); + Domain(int64_t left, int64_t right); /** * Returns the full domain Int64. @@ -121,7 +121,7 @@ class Domain { * Creates a domain from the union of an unsorted list of integer values. * Input values may be repeated, with no consequence on the output */ - static Domain FromValues(std::vector values); + static Domain FromValues(std::vector values); /** * Creates a domain from the union of an unsorted list of intervals. @@ -132,7 +132,7 @@ class Domain { * Same as FromIntervals() for a flattened representation (start, end, * start, end, ...). */ - static Domain FromFlatSpanOfIntervals(absl::Span flat_intervals); + static Domain FromFlatSpanOfIntervals(absl::Span flat_intervals); /** * This method is available in Python, Java and .NET. It allows @@ -140,23 +140,23 @@ class Domain { * .NET, [[0, 2], [5, 5], [8, 10]] in python). */ static Domain FromVectorIntervals( - const std::vector >& intervals); + const std::vector >& intervals); /** * This method is available in Python, Java and .NET. It allows * building a Domain object from a flattened list of intervals * (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python). */ - static Domain FromFlatIntervals(const std::vector& flat_intervals); + static Domain FromFlatIntervals(const std::vector& flat_intervals); /** * This method returns the flattened list of interval bounds of the domain. * * Thus the domain {0, 1, 2, 5, 8, 9, 10} will return [0, 2, 5, 5, - * 8, 10] (as a C++ std::vector, as a java or C# long[], as + * 8, 10] (as a C++ std::vector, as a java or C# long[], as * a python list of integers). */ - std::vector FlattenedIntervals() const; + std::vector FlattenedIntervals() const; /** * Returns true if this is the empty set. @@ -166,19 +166,19 @@ class Domain { /** * Returns the number of elements in the domain. It is capped at kint64max */ - int64 Size() const; + int64_t Size() const; /** * Returns the min value of the domain. * The domain must not be empty. */ - int64 Min() const; + int64_t Min() const; /** * Returns the max value of the domain. * The domain must not be empty. */ - int64 Max() const; + int64_t Max() const; /** * Returns true iff the domain is reduced to a single value. @@ -191,12 +191,12 @@ class Domain { * This is the same as Min() or Max() but allows for amore readable code and * also crash in debug mode if called on a non fixed domain. */ - int64 FixedValue() const; + int64_t FixedValue() const; /** * Returns true iff value is in Domain. */ - bool Contains(int64 value) const; + bool Contains(int64_t value) const; /** * Returns true iff D is included in the given domain. @@ -242,7 +242,7 @@ class Domain { * Note that if you multiply by a negative coeff, kint64min will be dropped * from the result even if it was here due to how this is implemented. */ - Domain MultiplicationBy(int64 coeff, bool* exact = nullptr) const; + Domain MultiplicationBy(int64_t coeff, bool* exact = nullptr) const; /** * If NumIntervals() is too large, this return a superset of the domain. @@ -261,7 +261,7 @@ class Domain { * look for {x ∈ Int64, ∃ e ∈ D, x / coeff = e}, then we will get [2, 201] in * the case above. */ - Domain ContinuousMultiplicationBy(int64 coeff) const; + Domain ContinuousMultiplicationBy(int64_t coeff) const; /** * Returns a superset of MultiplicationBy() to avoid the explosion in the @@ -282,14 +282,14 @@ class Domain { * * For instance Domain(1, 7).DivisionBy(2) == Domain(0, 3). */ - Domain DivisionBy(int64 coeff) const; + Domain DivisionBy(int64_t coeff) const; /** * Returns {x ∈ Int64, ∃ e ∈ D, x * coeff = e}. * * For instance Domain(1, 7).InverseMultiplicationBy(2) == Domain(1, 3). */ - Domain InverseMultiplicationBy(const int64 coeff) const; + Domain InverseMultiplicationBy(const int64_t coeff) const; /** * Advanced usage. Given some \e implied information on this domain that is @@ -374,10 +374,10 @@ class Domain { std::ostream& operator<<(std::ostream& out, const Domain& domain); // Returns the sum of smallest k values in the domain. -int64 SumOfKMinValueInDomain(const Domain& domain, int k); +int64_t SumOfKMinValueInDomain(const Domain& domain, int k); // Returns the sum of largest k values in the domain. -int64 SumOfKMaxValueInDomain(const Domain& domain, int k); +int64_t SumOfKMaxValueInDomain(const Domain& domain, int k); /** * This class represents a sorted list of disjoint, closed intervals. When an @@ -405,19 +405,19 @@ class SortedDisjointIntervalList { /** * Creates a SortedDisjointIntervalList and fills it with intervals * [starts[i]..ends[i]]. All intervals must be consistent (starts[i] <= - * ends[i]). There are two version, one for int64 and one for int. + * ends[i]). There are two version, one for int64_t and one for int. */ // TODO(user): Explain why we favored this API to the more natural // input std::vector or std::vector>. - SortedDisjointIntervalList(const std::vector& starts, - const std::vector& ends); + SortedDisjointIntervalList(const std::vector& starts, + const std::vector& ends); SortedDisjointIntervalList(const std::vector& starts, const std::vector& ends); /** * Builds the complement of the interval list on the interval [start, end]. */ - SortedDisjointIntervalList BuildComplementOnInterval(int64 start, int64 end); + SortedDisjointIntervalList BuildComplementOnInterval(int64_t start, int64_t end); /** * Adds the interval [start..end] to the list, and merges overlapping or @@ -428,7 +428,7 @@ class SortedDisjointIntervalList { * * If start > end, it does LOG(DFATAL) and returns end() (no interval added). */ - Iterator InsertInterval(int64 start, int64 end); + Iterator InsertInterval(int64_t start, int64_t end); /** * If value is in an interval, increase its end by one, otherwise insert the @@ -439,16 +439,16 @@ class SortedDisjointIntervalList { * If this causes an interval ending at kint64max to grow, it will die with a * CHECK fail. */ - Iterator GrowRightByOne(int64 value, int64* newly_covered); + Iterator GrowRightByOne(int64_t value, int64_t* newly_covered); /** * Adds all intervals [starts[i]..ends[i]]. * * Same behavior as InsertInterval() upon invalid intervals. There's a version - * with int64 and int32. + * with int64_t and int32. */ - void InsertIntervals(const std::vector& starts, - const std::vector& ends); + void InsertIntervals(const std::vector& starts, + const std::vector& ends); void InsertIntervals(const std::vector& starts, const std::vector& ends); @@ -465,8 +465,8 @@ class SortedDisjointIntervalList { * * If the value is within an interval, both functions will return it. */ - Iterator FirstIntervalGreaterOrEqual(int64 value) const; - Iterator LastIntervalLessOrEqual(int64 value) const; + Iterator FirstIntervalGreaterOrEqual(int64_t value) const; + Iterator LastIntervalLessOrEqual(int64_t value) const; std::string DebugString() const; diff --git a/ortools/util/stats.cc b/ortools/util/stats.cc index 66ca89fb79..f1aba538be 100644 --- a/ortools/util/stats.cc +++ b/ortools/util/stats.cc @@ -23,11 +23,11 @@ namespace operations_research { std::string MemoryUsage() { - const int64 mem = operations_research::sysinfo::MemoryUsageProcess(); - static const int64 kDisplayThreshold = 2; - static const int64 kKiloByte = 1024; - static const int64 kMegaByte = kKiloByte * kKiloByte; - static const int64 kGigaByte = kMegaByte * kKiloByte; + const int64_t mem = operations_research::sysinfo::MemoryUsageProcess(); + static const int64_t kDisplayThreshold = 2; + static const int64_t kKiloByte = 1024; + static const int64_t kMegaByte = kKiloByte * kKiloByte; + static const int64_t kGigaByte = kMegaByte * kKiloByte; if (mem > kDisplayThreshold * kGigaByte) { return absl::StrFormat("%.2lf GB", mem * 1.0 / kGigaByte); } else if (mem > kDisplayThreshold * kMegaByte) { @@ -226,7 +226,7 @@ std::string DoubleDistribution::ValueAsString() const { Average(), StdDeviation()); } -void IntegerDistribution::Add(int64 value) { +void IntegerDistribution::Add(int64_t value) { AddToDistribution(static_cast(value)); } diff --git a/ortools/util/stats.h b/ortools/util/stats.h index c58fc809bf..aa4bf0bfc0 100644 --- a/ortools/util/stats.h +++ b/ortools/util/stats.h @@ -188,7 +188,7 @@ class DistributionStat : public Stat { double Sum() const override { return sum_; } double Max() const { return max_; } double Min() const { return min_; } - int64 Num() const { return num_; } + int64_t Num() const { return num_; } // Get the average of the distribution or 0.0 if empty. double Average() const; @@ -208,14 +208,14 @@ class DistributionStat : public Stat { double sum_squares_from_average_; double min_; double max_; - int64 num_; + int64_t num_; }; // Statistic on the distribution of a sequence of running times. // Also provides some facility to measure such time with the CPU cycle counter. // // TODO(user): Since we inherit from DistributionStat, we currently store the -// sum of CPU cycles as a double internally. A better option is to use int64 +// sum of CPU cycles as a double internally. A better option is to use int64_t // because with the 53 bits of precision of a double, we will run into an issue // if the sum of times reaches 52 days for a 2GHz processor. class TimeDistribution : public DistributionStat { @@ -292,7 +292,7 @@ class IntegerDistribution : public DistributionStat { IntegerDistribution(const std::string& name, StatsGroup* group) : DistributionStat(name, group) {} std::string ValueAsString() const override; - void Add(int64 value); + void Add(int64_t value); }; // Helper classes to time a block of code and add the result to a diff --git a/ortools/util/time_limit.h b/ortools/util/time_limit.h index e683e06af5..7fae18a9de 100644 --- a/ortools/util/time_limit.h +++ b/ortools/util/time_limit.h @@ -302,12 +302,12 @@ class TimeLimit { return "inst_retired:any_p:u"; } - mutable int64 start_ns_; // Not const! this is initialized after instruction + mutable int64_t start_ns_; // Not const! this is initialized after instruction // counter initialization. - int64 last_ns_; - int64 limit_ns_; // Not const! See the code of LimitReached(). - const int64 safety_buffer_ns_; - RunningMax running_max_; + int64_t last_ns_; + int64_t limit_ns_; // Not const! See the code of LimitReached(). + const int64_t safety_buffer_ns_; + RunningMax running_max_; // Only used when FLAGS_time_limit_use_usertime is true. UserTimer user_timer_; @@ -470,7 +470,7 @@ class NestedTimeLimit { inline TimeLimit::TimeLimit(double limit_in_seconds, double deterministic_limit, double instruction_limit) - : safety_buffer_ns_(static_cast(kSafetyBufferSeconds * 1e9)), + : safety_buffer_ns_(static_cast(kSafetyBufferSeconds * 1e9)), running_max_(kHistorySize), external_boolean_as_limit_(nullptr) { ResetTimers(limit_in_seconds, deterministic_limit, instruction_limit); @@ -498,7 +498,7 @@ inline void TimeLimit::ResetTimers(double limit_in_seconds, last_ns_ = start_ns_; limit_ns_ = limit_in_seconds >= 1e-9 * (kint64max - start_ns_) ? kint64max - : static_cast(limit_in_seconds * 1e9) + start_ns_; + : static_cast(limit_in_seconds * 1e9) + start_ns_; } template @@ -545,7 +545,7 @@ inline bool TimeLimit::LimitReached() { } #endif // HAS_PERF_SUBSYSTEM - const int64 current_ns = absl::GetCurrentTimeNanos(); + const int64_t current_ns = absl::GetCurrentTimeNanos(); running_max_.Add(std::max(safety_buffer_ns_, current_ns - last_ns_)); last_ns_ = current_ns; if (current_ns + running_max_.GetCurrentMax() >= limit_ns_) { @@ -555,7 +555,7 @@ inline bool TimeLimit::LimitReached() { // should advance more slowly, so this is correct. const double time_left_s = limit_in_seconds_ - user_timer_.Get(); if (time_left_s > kSafetyBufferSeconds) { - limit_ns_ = static_cast(time_left_s * 1e9) + last_ns_; + limit_ns_ = static_cast(time_left_s * 1e9) + last_ns_; return false; } } @@ -569,7 +569,7 @@ inline bool TimeLimit::LimitReached() { inline double TimeLimit::GetTimeLeft() const { if (limit_ns_ == kint64max) return std::numeric_limits::infinity(); - const int64 delta_ns = limit_ns_ - absl::GetCurrentTimeNanos(); + const int64_t delta_ns = limit_ns_ - absl::GetCurrentTimeNanos(); if (delta_ns < 0) return 0.0; if (absl::GetFlag(FLAGS_time_limit_use_usertime)) { return std::max(limit_in_seconds_ - user_timer_.Get(), 0.0); diff --git a/ortools/util/tuple_set.h b/ortools/util/tuple_set.h index 39783ee46f..a97508804d 100644 --- a/ortools/util/tuple_set.h +++ b/ortools/util/tuple_set.h @@ -14,7 +14,7 @@ // Set of integer tuples (fixed-size arrays, all of the same size) with // a basic API. // It supports several types of integer arrays transparently, with an -// inherent storage based on int64 arrays. +// inherent storage based on int64_t arrays. // // The key feature is the "lazy" copy: // - Copying an IntTupleSet won't actually copy the data right away; we @@ -62,29 +62,29 @@ class IntTupleSet { // arity of the set. It returns the index at which the tuple was // inserted (-1 if it was already present). int Insert(const std::vector& tuple); - int Insert(const std::vector& tuple); + int Insert(const std::vector& tuple); // Arity fixed version of Insert removing the need for a vector for the user. - int Insert2(int64 v0, int64 v1); - int Insert3(int64 v0, int64 v1, int64 v2); - int Insert4(int64 v0, int64 v1, int64 v2, int64 v3); + int Insert2(int64_t v0, int64_t v1); + int Insert3(int64_t v0, int64_t v1, int64_t v2); + int Insert4(int64_t v0, int64_t v1, int64_t v2, int64_t v3); // Inserts the tuples. - void InsertAll(const std::vector >& tuples); + void InsertAll(const std::vector >& tuples); void InsertAll(const std::vector >& tuples); // Checks if the tuple is in the set. bool Contains(const std::vector& tuple) const; - bool Contains(const std::vector& tuple) const; + bool Contains(const std::vector& tuple) const; // Returns the number of tuples. int NumTuples() const; // Get the given tuple's value at the given position. The indices // of the tuples correspond to the order in which they were // inserted. - int64 Value(int tuple_index, int pos_in_tuple) const; + int64_t Value(int tuple_index, int pos_in_tuple) const; // Returns the arity of the set. int Arity() const; // Access the raw data, see IntTupleSet::Data::flat_tuples_. - const int64* RawData() const; + const int64_t* RawData() const; // Returns the number of different values in the given column. int NumDifferentValuesInColumn(int col) const; // Return a copy of the set, sorted by the "col"-th value of each @@ -109,22 +109,22 @@ class IntTupleSet { template bool Contains(const std::vector& candidate) const; template - int64 Fingerprint(const std::vector& tuple) const; + int64_t Fingerprint(const std::vector& tuple) const; int NumTuples() const; - int64 Value(int index, int pos) const; + int64_t Value(int index, int pos) const; int Arity() const; - const int64* RawData() const; + const int64_t* RawData() const; void Clear(); private: const int arity_; int num_owners_; // Concatenation of all tuples ever added. - std::vector flat_tuples_; + std::vector flat_tuples_; // Maps a tuple's fingerprint to the list of tuples with this // fingerprint, represented by their start index in the // flat_tuples_ vector. - absl::flat_hash_map > tuple_fprint_to_index_; + absl::flat_hash_map > tuple_fprint_to_index_; }; // Used to represent a light representation of a tuple. @@ -137,8 +137,8 @@ class IntTupleSet { struct IndexValue { int index; - int64 value; - IndexValue(int i, int64 v) : index(i), value(v) {} + int64_t value; + IndexValue(int i, int64_t v) : index(i), value(v) {} static bool Compare(const IndexValue& a, const IndexValue& b); }; @@ -185,7 +185,7 @@ int IntTupleSet::Data::Insert(const std::vector& tuple) { for (int i = 0; i < arity_; ++i) { flat_tuples_[offset + i] = tuple[i]; } - const int64 fingerprint = Fingerprint(tuple); + const int64_t fingerprint = Fingerprint(tuple); tuple_fprint_to_index_[fingerprint].push_back(index); return index; } else { @@ -198,7 +198,7 @@ bool IntTupleSet::Data::Contains(const std::vector& candidate) const { if (candidate.size() != arity_) { return false; } - const int64 fingerprint = Fingerprint(candidate); + const int64_t fingerprint = Fingerprint(candidate); if (gtl::ContainsKey(tuple_fprint_to_index_, fingerprint)) { const std::vector& indices = gtl::FindOrDie(tuple_fprint_to_index_, fingerprint); @@ -216,24 +216,24 @@ bool IntTupleSet::Data::Contains(const std::vector& candidate) const { } template -int64 IntTupleSet::Data::Fingerprint(const std::vector& tuple) const { +int64_t IntTupleSet::Data::Fingerprint(const std::vector& tuple) const { switch (arity_) { case 0: return 0; case 1: return tuple[0]; case 2: { - uint64 x = tuple[0]; - uint64 y = uint64_t{0xe08c1d668b756f82}; - uint64 z = tuple[1]; + uint64_t x = tuple[0]; + uint64_t y = uint64_t{0xe08c1d668b756f82}; + uint64_t z = tuple[1]; mix(x, y, z); return z; } default: { - uint64 x = tuple[0]; - uint64 y = uint64_t{0xe08c1d668b756f82}; + uint64_t x = tuple[0]; + uint64_t y = uint64_t{0xe08c1d668b756f82}; for (int i = 1; i < tuple.size(); ++i) { - uint64 z = tuple[i]; + uint64_t z = tuple[i]; mix(x, y, z); x = z; } @@ -246,7 +246,7 @@ inline int IntTupleSet::Data::NumTuples() const { return tuple_fprint_to_index_.size(); } -inline int64 IntTupleSet::Data::Value(int index, int pos) const { +inline int64_t IntTupleSet::Data::Value(int index, int pos) const { DCHECK_GE(index, 0); DCHECK_LT(index, flat_tuples_.size() / arity_); DCHECK_GE(pos, 0); @@ -256,7 +256,7 @@ inline int64 IntTupleSet::Data::Value(int index, int pos) const { inline int IntTupleSet::Data::Arity() const { return arity_; } -inline const int64* IntTupleSet::Data::RawData() const { +inline const int64_t* IntTupleSet::Data::RawData() const { return flat_tuples_.data(); } @@ -291,28 +291,28 @@ inline int IntTupleSet::Insert(const std::vector& tuple) { return data_->Insert(tuple); } -inline int IntTupleSet::Insert(const std::vector& tuple) { +inline int IntTupleSet::Insert(const std::vector& tuple) { data_ = data_->CopyIfShared(); return data_->Insert(tuple); } -inline int IntTupleSet::Insert2(int64 v0, int64 v1) { - std::vector tuple(2); +inline int IntTupleSet::Insert2(int64_t v0, int64_t v1) { + std::vector tuple(2); tuple[0] = v0; tuple[1] = v1; return Insert(tuple); } -inline int IntTupleSet::Insert3(int64 v0, int64 v1, int64 v2) { - std::vector tuple(3); +inline int IntTupleSet::Insert3(int64_t v0, int64_t v1, int64_t v2) { + std::vector tuple(3); tuple[0] = v0; tuple[1] = v1; tuple[2] = v2; return Insert(tuple); } -inline int IntTupleSet::Insert4(int64 v0, int64 v1, int64 v2, int64 v3) { - std::vector tuple(4); +inline int IntTupleSet::Insert4(int64_t v0, int64_t v1, int64_t v2, int64_t v3) { + std::vector tuple(4); tuple[0] = v0; tuple[1] = v1; tuple[2] = v2; @@ -324,7 +324,7 @@ inline bool IntTupleSet::Contains(const std::vector& tuple) const { return data_->Contains(tuple); } -inline bool IntTupleSet::Contains(const std::vector& tuple) const { +inline bool IntTupleSet::Contains(const std::vector& tuple) const { return data_->Contains(tuple); } @@ -337,7 +337,7 @@ inline void IntTupleSet::InsertAll( } inline void IntTupleSet::InsertAll( - const std::vector >& tuples) { + const std::vector >& tuples) { data_ = data_->CopyIfShared(); for (int i = 0; i < tuples.size(); ++i) { Insert(tuples[i]); @@ -346,19 +346,19 @@ inline void IntTupleSet::InsertAll( inline int IntTupleSet::NumTuples() const { return data_->NumTuples(); } -inline int64 IntTupleSet::Value(int index, int pos) const { +inline int64_t IntTupleSet::Value(int index, int pos) const { return data_->Value(index, pos); } inline int IntTupleSet::Arity() const { return data_->Arity(); } -inline const int64* IntTupleSet::RawData() const { return data_->RawData(); } +inline const int64_t* IntTupleSet::RawData() const { return data_->RawData(); } inline int IntTupleSet::NumDifferentValuesInColumn(int col) const { if (col < 0 || col >= data_->Arity()) { return 0; } - absl::flat_hash_set values; + absl::flat_hash_set values; for (int i = 0; i < data_->NumTuples(); ++i) { values.insert(data_->Value(i, col)); } @@ -380,8 +380,8 @@ inline IntTupleSet IntTupleSet::SortedByColumn(int col) const { const int arity = data_->Arity(); IntTupleSet sorted(arity); for (int i = 0; i < keys.size(); ++i) { - const int64* tuple_ptr = data_->RawData() + keys[i].index * arity; - sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); + const int64_t* tuple_ptr = data_->RawData() + keys[i].index * arity; + sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); } return sorted; } @@ -391,8 +391,8 @@ inline bool IntTupleSet::IndexData::Compare(const IndexData& a, const IntTupleSet::Data* const data = a.data; const int arity = data->Arity(); for (int i = 0; i < arity; ++i) { - const int64 value1 = data->Value(a.index, i); - const int64 value2 = data->Value(b.index, i); + const int64_t value1 = data->Value(a.index, i); + const int64_t value2 = data->Value(b.index, i); if (value1 < value2) { return true; } @@ -413,9 +413,9 @@ inline IntTupleSet IntTupleSet::SortedLexicographically() const { const int arity = data_->Arity(); IntTupleSet sorted(arity); for (int i = 0; i < keys.size(); ++i) { - std::vector tuple(arity); - const int64* tuple_ptr = data_->RawData() + keys[i].index * arity; - sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); + std::vector tuple(arity); + const int64_t* tuple_ptr = data_->RawData() + keys[i].index * arity; + sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); } return sorted; } diff --git a/ortools/util/zvector.h b/ortools/util/zvector.h index c9c6b6a12c..b9e8d0fabb 100644 --- a/ortools/util/zvector.h +++ b/ortools/util/zvector.h @@ -47,7 +47,7 @@ class ZVector { ZVector() : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() {} - ZVector(int64 min_index, int64 max_index) + ZVector(int64_t min_index, int64_t max_index) : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() { if (!Reserve(min_index, max_index)) { LOG(DFATAL) << "Could not reserve memory for indices ranging from " @@ -55,12 +55,12 @@ class ZVector { } } - int64 min_index() const { return min_index_; } + int64_t min_index() const { return min_index_; } - int64 max_index() const { return max_index_; } + int64_t max_index() const { return max_index_; } // Returns the value stored at index. - T Value(int64 index) const { + T Value(int64_t index) const { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); @@ -69,14 +69,14 @@ class ZVector { #if !defined(SWIG) // Shortcut for returning the value stored at index. - T& operator[](int64 index) { + T& operator[](int64_t index) { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); return base_[index]; } - const T operator[](int64 index) const { + const T operator[](int64_t index) const { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); @@ -85,7 +85,7 @@ class ZVector { #endif // Sets to value the content of the array at index. - void Set(int64 index, T value) { + void Set(int64_t index, T value) { DCHECK_LE(min_index_, index); DCHECK_GE(max_index_, index); DCHECK(base_ != nullptr); @@ -95,11 +95,11 @@ class ZVector { // Reserves memory for new minimum and new maximum indices. // Returns true if the memory could be reserved. // Never shrinks the memory allocated. - bool Reserve(int64 new_min_index, int64 new_max_index) { + bool Reserve(int64_t new_min_index, int64_t new_max_index) { if (new_min_index > new_max_index) { return false; } - const uint64 new_size = new_max_index - new_min_index + 1; + const uint64_t new_size = new_max_index - new_min_index + 1; if (base_ != nullptr) { if (new_min_index >= min_index_ && new_max_index <= max_index_) { min_index_ = new_min_index; @@ -133,7 +133,7 @@ class ZVector { void SetAll(T value) { DLOG_IF(WARNING, base_ == nullptr || size_ <= 0) << "Trying to set values to uninitialized vector."; - for (int64 i = 0; i < size_; ++i) { + for (int64_t i = 0; i < size_; ++i) { base_[min_index_ + i] = value; } } @@ -143,13 +143,13 @@ class ZVector { T* base_; // Minimum index for the array. - int64 min_index_; + int64_t min_index_; // Maximum index for the array. - int64 max_index_; + int64_t max_index_; // The number of elements in the array. - int64 size_; + int64_t size_; // Storage memory for the array. std::unique_ptr storage_; @@ -159,11 +159,11 @@ class ZVector { typedef ZVector Int8ZVector; typedef ZVector Int16ZVector; typedef ZVector Int32ZVector; -typedef ZVector Int64ZVector; +typedef ZVector Int64ZVector; typedef ZVector UInt8ZVector; typedef ZVector UInt16ZVector; typedef ZVector UInt32ZVector; -typedef ZVector UInt64ZVector; +typedef ZVector UInt64ZVector; } // namespace operations_research