util: Export from google3
This commit is contained in:
@@ -37,16 +37,20 @@ config_setting(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "adaptative_parameter_value",
|
||||
hdrs = ["adaptative_parameter_value.h"],
|
||||
deps = ["//ortools/base"],
|
||||
# OptionalBoolean
|
||||
proto_library(
|
||||
name = "optional_boolean_proto",
|
||||
srcs = ["optional_boolean.proto"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "lazy_mutable_copy",
|
||||
hdrs = ["lazy_mutable_copy.h"],
|
||||
deps = ["@com_google_absl//absl/memory"],
|
||||
cc_proto_library(
|
||||
name = "optional_boolean_cc_proto",
|
||||
deps = [":optional_boolean_proto"],
|
||||
)
|
||||
|
||||
py_proto_library(
|
||||
name = "optional_boolean_py_pb2",
|
||||
deps = [":optional_boolean_proto"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -59,19 +63,16 @@ cc_library(
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "flat_matrix",
|
||||
hdrs = ["flat_matrix.h"],
|
||||
name = "filelineiter",
|
||||
hdrs = ["filelineiter.h"],
|
||||
deps = [
|
||||
"@com_google_absl//absl/types:span",
|
||||
"//ortools/base",
|
||||
"//ortools/base:file",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "random_engine",
|
||||
hdrs = ["random_engine.h"],
|
||||
deps = [],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "bitset",
|
||||
srcs = ["bitset.cc"],
|
||||
@@ -111,17 +112,6 @@ cc_library(
|
||||
deps = ["//ortools/base"],
|
||||
)
|
||||
|
||||
#cc_library(
|
||||
# name = "step_function",
|
||||
# srcs = ["step_function.cc"],
|
||||
# hdrs = ["step_function.h"],
|
||||
# deps = [
|
||||
# "@com_google_absl//absl/strings",
|
||||
# ":iterators",
|
||||
# "//ortools/base",
|
||||
# ],
|
||||
#)
|
||||
|
||||
cc_library(
|
||||
name = "saturated_arithmetic",
|
||||
hdrs = ["saturated_arithmetic.h"],
|
||||
@@ -173,16 +163,8 @@ cc_library(
|
||||
cc_library(
|
||||
name = "string_array",
|
||||
hdrs = ["string_array.h"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "string_util",
|
||||
srcs = ["string_util.cc"],
|
||||
hdrs = ["string_util.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -192,6 +174,8 @@ cc_library(
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"//ortools/base:hash",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -228,6 +212,15 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sigint",
|
||||
srcs = ["sigint.cc"],
|
||||
hdrs = ["sigint.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fp_utils",
|
||||
srcs = ["fp_utils.cc"],
|
||||
@@ -266,26 +259,6 @@ cc_library(
|
||||
deps = ["//ortools/base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "file_util",
|
||||
srcs = ["file_util.cc"],
|
||||
hdrs = ["file_util.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"//ortools/base:dump_vars",
|
||||
"//ortools/base:file",
|
||||
"//ortools/base:gzipstring",
|
||||
"//ortools/base:hash",
|
||||
"//ortools/base:recordio",
|
||||
"//ortools/base:status_macros",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_protobuf//:protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "proto_tools",
|
||||
srcs = ["proto_tools.cc"],
|
||||
@@ -322,23 +295,8 @@ py_proto_library(
|
||||
deps = [":int128_proto"],
|
||||
)
|
||||
|
||||
# OptionalBoolean
|
||||
proto_library(
|
||||
name = "optional_boolean_proto",
|
||||
srcs = ["optional_boolean.proto"],
|
||||
)
|
||||
# helper library for the swig wrappers.
|
||||
|
||||
cc_proto_library(
|
||||
name = "optional_boolean_cc_proto",
|
||||
deps = [":optional_boolean_proto"],
|
||||
)
|
||||
|
||||
py_proto_library(
|
||||
name = "optional_boolean_py_pb2",
|
||||
deps = [":optional_boolean_proto"],
|
||||
)
|
||||
|
||||
# SWIG
|
||||
cc_library(
|
||||
name = "functions_swig_helpers",
|
||||
hdrs = [
|
||||
@@ -382,15 +340,6 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sigint",
|
||||
srcs = ["sigint.cc"],
|
||||
hdrs = ["sigint.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "vector_or_function",
|
||||
hdrs = ["vector_or_function.h"],
|
||||
@@ -399,28 +348,7 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "filelineiter",
|
||||
hdrs = ["filelineiter.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"//ortools/base:file",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
#cc_library(
|
||||
# name = "bp_parser",
|
||||
# srcs = ["bp_parser.cc"],
|
||||
# hdrs = ["bp_parser.h"],
|
||||
# deps = [
|
||||
# "@com_google_absl//absl/strings",
|
||||
# ":filelineiter",
|
||||
# "//ortools/base",
|
||||
# "//ortools/base:file",
|
||||
# ],
|
||||
#)
|
||||
# Parsers and readers.
|
||||
|
||||
cc_library(
|
||||
name = "qap_reader",
|
||||
@@ -440,6 +368,55 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "file_util",
|
||||
srcs = ["file_util.cc"],
|
||||
hdrs = ["file_util.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"//ortools/base:dump_vars",
|
||||
"//ortools/base:file",
|
||||
"//ortools/base:gzipstring",
|
||||
"//ortools/base:hash",
|
||||
"//ortools/base:recordio",
|
||||
"//ortools/base:status_macros",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_protobuf//:protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "random_engine",
|
||||
hdrs = ["random_engine.h"],
|
||||
deps = [],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "string_util",
|
||||
srcs = ["string_util.cc"],
|
||||
hdrs = ["string_util.h"],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "adaptative_parameter_value",
|
||||
hdrs = ["adaptative_parameter_value.h"],
|
||||
deps = ["//ortools/base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "lazy_mutable_copy",
|
||||
hdrs = ["lazy_mutable_copy.h"],
|
||||
deps = ["@com_google_absl//absl/memory"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "logging",
|
||||
srcs = ["logging.cc"],
|
||||
@@ -488,6 +465,14 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "flat_matrix",
|
||||
hdrs = ["flat_matrix.h"],
|
||||
deps = [
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fp_roundtrip_conv_testing",
|
||||
testonly = 1,
|
||||
@@ -497,6 +482,26 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "aligned_memory",
|
||||
srcs = ["aligned_memory_internal.h"],
|
||||
hdrs = ["aligned_memory.h"],
|
||||
deps = [
|
||||
"//ortools/base:mathutil",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "vector_sum",
|
||||
srcs = ["vector_sum_internal.h"],
|
||||
hdrs = ["vector_sum.h"],
|
||||
deps = [
|
||||
":aligned_memory",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "parse_proto",
|
||||
srcs = ["parse_proto.cc"],
|
||||
@@ -520,3 +525,12 @@ cc_library(
|
||||
"@com_google_absl//absl/synchronization",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "dense_set",
|
||||
hdrs = ["dense_set.h"],
|
||||
deps = [
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "ortools/util/file_util.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/status/status.h"
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "google/protobuf/message.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "google/protobuf/util/json_util.h"
|
||||
#include "ortools/base/file.h"
|
||||
#include "ortools/base/gzipstring.h"
|
||||
#include "ortools/base/helpers.h"
|
||||
#include "ortools/base/logging.h"
|
||||
|
||||
@@ -42,7 +42,7 @@ absl::Status ReadFileToProto(
|
||||
// boolean doesn't work for JSON inputs.
|
||||
bool allow_partial = false);
|
||||
|
||||
// Exaclty like ReadFileToProto(), but directly from the contents.
|
||||
// Exactly like ReadFileToProto(), but directly from the contents.
|
||||
absl::Status StringToProto(absl::string_view data,
|
||||
google::protobuf::Message* proto,
|
||||
bool allow_partial = false);
|
||||
|
||||
@@ -11,24 +11,64 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// We use the notation min(arr, i, j) for the minimum arr[x] such that i <= x
|
||||
// and x < j.
|
||||
// Range Minimum Query (RMQ) is a data structure preprocessing an array arr so
|
||||
// that querying min(arr, i, j) takes O(1) time. The preprocessing takes
|
||||
// O(n*log(n)) time and memory.
|
||||
|
||||
// Note: There exists an O(n) preprocessing algorithm, but it is considerably
|
||||
// more involved and the hidden constants behind it are much higher.
|
||||
// The range minimum query problem is a range query problem where queries ask
|
||||
// for the minimum of all elements in ranges of the array.
|
||||
// The problem is divided into two phases:
|
||||
// - precomputation: the data structure is given an array A of n elements.
|
||||
// - query: the data structure must answer queries min(A, begin, end),
|
||||
// where min(A, begin, end) = min_{i in [begin, end)} A[i].
|
||||
// This file has an implementation of the sparse table approach to solving the
|
||||
// problem, for which the precomputation takes O(n*log(n)) time and memory,
|
||||
// and further queries take O(1) time.
|
||||
// Reference: https://en.wikipedia.org/wiki/Range_minimum_query.
|
||||
//
|
||||
// The algorithms are well explained in Wikipedia:
|
||||
// https://en.wikipedia.org/wiki/Range_minimum_query.
|
||||
// The data structure allows to have multiple arrays at the same time, and
|
||||
// to reset the arrays.
|
||||
//
|
||||
// Usage, single range:
|
||||
// RangeMinimumQuery rmq({10, 100, 30, 300, 70});
|
||||
// rmq.GetMinimumFromRange(0, 5); // Returns 10.
|
||||
// rmq.GetMinimumFromRange(2, 4); // Returns 30.
|
||||
//
|
||||
// Implementation: The idea is to cache every min(arr, i, j) where j - i is a
|
||||
// power of two, i.e. j = i + 2^k for some k. Provided this information, we can
|
||||
// answer all queries in O(1): given a pair (i, j) find the maximum k such that
|
||||
// i + 2^k < j and note that
|
||||
// std::min(min(arr, i, i+2^k), min(arr, j-2^k, j)) = min(arr, i, j).
|
||||
// Usage, multiple ranges:
|
||||
// RangeMinimumQuery rmq({10, 100, 30, 300, 70});
|
||||
// rmq.GetMinimumFromRange(0, 5); // Returns 10.
|
||||
// rmq.GetMinimumFromRange(2, 4); // Returns 30.
|
||||
//
|
||||
// // We add another array {-3, 10, 5, 2, 15, 3}.
|
||||
// const int begin2 = rmq.TablesSize();
|
||||
// for (const int element : {-3, 10, 5, 2, 15, 3}) {
|
||||
// rmq.PushBack(element);
|
||||
// }
|
||||
// rmq.MakeSparseTableFromNewElements();
|
||||
// rmq.GetMinimumFromRange(begin2 + 0, begin2 + 5); // Returns -3.
|
||||
// rmq.GetMinimumFromRange(begin2 + 2, begin2 + 4); // Returns 2.
|
||||
// rmq.GetMinimumFromRange(begin2 + 4, begin2 + 6); // Returns 3.
|
||||
// // The previous array can still be queried.
|
||||
// rmq.GetMinimumFromRange(1, 3); // Returns 30.
|
||||
//
|
||||
// // Forbidden, query ranges can only be within the same array.
|
||||
// rmq.GetMinimumFromRange(3, 9); // Undefined.
|
||||
//
|
||||
// rmq.Clear();
|
||||
// // All arrays have been removed, so no range query can be made.
|
||||
// rmq.GetMinimumFromRange(0, 5); // Undefined.
|
||||
//
|
||||
// // Add a new range.
|
||||
// for (const int element : {0, 3, 2}) {
|
||||
// rmq.PushBack(element);
|
||||
// }
|
||||
// rmq.MakeSparseTableFromNewElements();
|
||||
// // Queries on the new array can be made.
|
||||
//
|
||||
// Note: There are other space/time tradeoffs for this problem, but they are
|
||||
// generally worse in terms of the constants in the O(1) query time, moreover
|
||||
// their implementation is generally more involved.
|
||||
//
|
||||
// Implementation: The idea is to cache every min(A, i, i+2^k).
|
||||
// Provided this information, we can answer all queries in O(1): given a pair
|
||||
// (i, j), first find the maximum k such that i + 2^k < j, then use
|
||||
// min(A, i, j) = std::min(min(A, i, i+2^k), min(A, j-2^k, j)).
|
||||
|
||||
#ifndef OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_
|
||||
#define OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_
|
||||
@@ -39,12 +79,18 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/log/check.h"
|
||||
#include "ortools/util/bitset.h"
|
||||
|
||||
namespace operations_research {
|
||||
template <typename T, typename Compare = std::less<T>>
|
||||
class RangeMinimumQuery {
|
||||
public:
|
||||
RangeMinimumQuery() {
|
||||
// This class uses the first two rows of cache_ to know the number of new
|
||||
// elements, which at any moment is cache_[1].size() - cache_[0].size().
|
||||
cache_.resize(2);
|
||||
};
|
||||
explicit RangeMinimumQuery(std::vector<T> array);
|
||||
RangeMinimumQuery(std::vector<T> array, Compare cmp);
|
||||
|
||||
@@ -53,13 +99,37 @@ class RangeMinimumQuery {
|
||||
RangeMinimumQuery& operator=(const RangeMinimumQuery&) = delete;
|
||||
|
||||
// Returns the minimum (w.r.t. Compare) arr[x], where x is contained in
|
||||
// [from, to).
|
||||
T GetMinimumFromRange(int from, int to) const;
|
||||
// [begin_index, end_index).
|
||||
// The range [begin_index, end_index) can only cover elements that were new
|
||||
// at the same call to MakeTableFromNewElements().
|
||||
// When calling this method, there must be no pending new elements, i.e. the
|
||||
// last method called apart from TableSize() must not have been PushBack().
|
||||
T RangeMinimum(int begin, int end) const;
|
||||
|
||||
void PushBack(T element) { cache_[0].push_back(element); }
|
||||
|
||||
// Generates the sparse table for all new elements, i.e. elements that were
|
||||
// added with PushBack() since the latest of these events: construction of
|
||||
// this object, a previous call to MakeTableFromNewElements(), or a call to
|
||||
// Clear().
|
||||
// The range of new elements [begin, end), with begin the Size() at the
|
||||
// latest event, and end the current Size().
|
||||
void MakeTableFromNewElements();
|
||||
|
||||
// Returns the number of elements in sparse tables, excluding new elements.
|
||||
int TableSize() const { return cache_[1].size(); }
|
||||
|
||||
// Clears all tables. This invalidates all further range queries on currently
|
||||
// existing tables. This does *not* release memory held by this object.
|
||||
void Clear() {
|
||||
for (auto& row : cache_) row.clear();
|
||||
}
|
||||
|
||||
// Returns the concatenated sequence of all elements in all arrays.
|
||||
const std::vector<T>& array() const;
|
||||
|
||||
private:
|
||||
// cache_[k][i] = min(arr, i, i+2^k).
|
||||
// cache_[k][i] = min_{j in [i, i+2^k)} arr[j].
|
||||
std::vector<std::vector<T>> cache_;
|
||||
Compare cmp_;
|
||||
};
|
||||
@@ -76,9 +146,9 @@ class RangeMinimumIndexQuery {
|
||||
RangeMinimumIndexQuery(const RangeMinimumIndexQuery&) = delete;
|
||||
RangeMinimumIndexQuery& operator=(const RangeMinimumIndexQuery&) = delete;
|
||||
|
||||
// Returns an index idx from [from, to) such that arr[idx] is the minimum
|
||||
// value of arr over the interval [from, to).
|
||||
int GetMinimumIndexFromRange(int from, int to) const;
|
||||
// Returns an index idx from [begin, end) such that arr[idx] is the minimum
|
||||
// value of arr over the interval [begin, end).
|
||||
int GetMinimumIndexFromRange(int begin, int end) const;
|
||||
|
||||
// Returns the original array.
|
||||
const std::vector<T>& array() const;
|
||||
@@ -99,41 +169,57 @@ template <typename T, typename Compare>
|
||||
inline RangeMinimumQuery<T, Compare>::RangeMinimumQuery(std::vector<T> array)
|
||||
: RangeMinimumQuery(std::move(array), Compare()) {}
|
||||
|
||||
// Reminder: The task is to fill cache_ so that
|
||||
template <typename T, typename Compare>
|
||||
RangeMinimumQuery<T, Compare>::RangeMinimumQuery(std::vector<T> array,
|
||||
Compare cmp)
|
||||
: cache_(2), cmp_(std::move(cmp)) {
|
||||
// This class uses the first two rows of cache_ to know the number of new
|
||||
// elements.
|
||||
cache_[0] = std::move(array);
|
||||
MakeTableFromNewElements();
|
||||
}
|
||||
|
||||
template <typename T, typename Compare>
|
||||
inline T RangeMinimumQuery<T, Compare>::RangeMinimum(int begin, int end) const {
|
||||
DCHECK_LE(0, begin);
|
||||
DCHECK_LT(begin, end);
|
||||
DCHECK_LE(end, cache_[1].size());
|
||||
DCHECK_EQ(cache_[0].size(), cache_[1].size());
|
||||
const int layer = MostSignificantBitPosition32(end - begin);
|
||||
DCHECK_LT(layer, cache_.size());
|
||||
const int window = 1 << layer;
|
||||
const T* row = cache_[layer].data();
|
||||
DCHECK_LE(end - window, cache_[layer].size());
|
||||
return std::min(row[begin], row[end - window], cmp_);
|
||||
}
|
||||
|
||||
// Reminder: The task is to fill cache_ so that for i in [begin, end),
|
||||
// cache_[k][i] = min(arr, i, i+2^k) for every k <= Log2(n) and i <= n-2^k.
|
||||
// Note that cache_[k+1][i] = min(cache_[k][i], cache_[k][i+2^k]), hence every
|
||||
// row can be efficiently computed from the previous.
|
||||
template <typename T, typename Compare>
|
||||
RangeMinimumQuery<T, Compare>::RangeMinimumQuery(std::vector<T> array,
|
||||
Compare cmp)
|
||||
: cache_(MostSignificantBitPosition32(array.size()) + 1),
|
||||
cmp_(std::move(cmp)) {
|
||||
const int array_size = array.size();
|
||||
cache_[0] = std::move(array);
|
||||
for (int row_idx = 1; row_idx < cache_.size(); ++row_idx) {
|
||||
const int row_length = array_size - (1 << row_idx) + 1;
|
||||
const int window = 1 << (row_idx - 1);
|
||||
cache_[row_idx].resize(row_length);
|
||||
for (int col_idx = 0; col_idx < row_length; ++col_idx) {
|
||||
cache_[row_idx][col_idx] =
|
||||
std::min(cache_[row_idx - 1][col_idx],
|
||||
cache_[row_idx - 1][col_idx + window], cmp_);
|
||||
void RangeMinimumQuery<T, Compare>::MakeTableFromNewElements() {
|
||||
const int new_size = cache_[0].size();
|
||||
const int old_size = cache_[1].size();
|
||||
if (old_size >= new_size) return;
|
||||
// This is the minimum number of rows needed to store the sequence of
|
||||
// new elements, there may be more rows in the cache.
|
||||
const int num_rows = 1 + MostSignificantBitPosition32(new_size - old_size);
|
||||
if (cache_.size() < num_rows) cache_.resize(num_rows);
|
||||
// Record the new number of elements, wastes just size(T) space.
|
||||
cache_[1].resize(new_size);
|
||||
|
||||
for (int row = 1; row < num_rows; ++row) {
|
||||
const int half_window = 1 << (row - 1);
|
||||
const int last_col = new_size - 2 * half_window;
|
||||
if (cache_[row].size() <= last_col) cache_[row].resize(last_col + 1);
|
||||
for (int col = old_size; col <= last_col; ++col) {
|
||||
cache_[row][col] = std::min(cache_[row - 1][col],
|
||||
cache_[row - 1][col + half_window], cmp_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Compare>
|
||||
inline T RangeMinimumQuery<T, Compare>::GetMinimumFromRange(int from,
|
||||
int to) const {
|
||||
DCHECK_LE(0, from);
|
||||
DCHECK_LT(from, to);
|
||||
DCHECK_LE(to, array().size());
|
||||
const int log_diff = MostSignificantBitPosition32(to - from);
|
||||
const int window = 1 << log_diff;
|
||||
const std::vector<T>& row = cache_[log_diff];
|
||||
return std::min(row[from], row[to - window], cmp_);
|
||||
}
|
||||
|
||||
template <typename T, typename Compare>
|
||||
inline const std::vector<T>& RangeMinimumQuery<T, Compare>::array() const {
|
||||
return cache_[0];
|
||||
@@ -153,8 +239,9 @@ RangeMinimumIndexQuery<T, Compare>::RangeMinimumIndexQuery(std::vector<T> array,
|
||||
|
||||
template <typename T, typename Compare>
|
||||
inline int RangeMinimumIndexQuery<T, Compare>::GetMinimumIndexFromRange(
|
||||
int from, int to) const {
|
||||
return rmq_.GetMinimumFromRange(from, to);
|
||||
int begin, int end) const {
|
||||
DCHECK_LT(begin, end);
|
||||
return rmq_.RangeMinimum(begin, end);
|
||||
}
|
||||
|
||||
template <typename T, typename Compare>
|
||||
|
||||
@@ -133,15 +133,13 @@ class CachedRangeIntToIntFunction : public RangeIntToIntFunction {
|
||||
DCHECK_LE(domain_start_, from);
|
||||
DCHECK_LT(from, to);
|
||||
DCHECK_LE(to, domain_start_ + static_cast<int64_t>(array().size()));
|
||||
return rmq_min_.GetMinimumFromRange(from - domain_start_,
|
||||
to - domain_start_);
|
||||
return rmq_min_.RangeMinimum(from - domain_start_, to - domain_start_);
|
||||
}
|
||||
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<int64_t>(array().size()));
|
||||
return rmq_max_.GetMinimumFromRange(from - domain_start_,
|
||||
to - domain_start_);
|
||||
return rmq_max_.RangeMinimum(from - domain_start_, to - domain_start_);
|
||||
}
|
||||
int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
|
||||
int64_t interval_begin,
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
#ifndef OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_
|
||||
#define OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "ortools/base/types.h"
|
||||
|
||||
namespace operations_research {
|
||||
// RangeIntToIntFunction is an interface to int64_t->int64_t functions
|
||||
|
||||
Reference in New Issue
Block a user