27 class LinearRangeIntToIntFunction :
public RangeIntToIntFunction {
29 explicit LinearRangeIntToIntFunction(
30 std::function<int64_t(int64_t)> base_function)
31 : base_function_(std::move(base_function)) {}
33 int64_t Query(int64_t argument)
const override {
34 return base_function_(argument);
37 int64_t RangeMin(int64_t range_begin, int64_t range_end)
const override {
40 for (int64_t i = range_begin; i < range_end; ++i) {
41 min_val =
std::min(min_val, base_function_(i));
46 int64_t RangeMax(int64_t range_begin, int64_t range_end)
const override {
49 for (int64_t i = range_begin; i < range_end; ++i) {
50 max_val =
std::max(max_val, base_function_(i));
55 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
56 int64_t interval_begin,
57 int64_t interval_end)
const override {
61 int64_t i = range_begin;
62 for (; i < range_end; ++i) {
63 const int64_t
value = base_function_(i);
64 if (interval_begin <=
value &&
value < interval_end)
break;
69 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
70 int64_t interval_begin,
71 int64_t interval_end)
const override {
76 int64_t i = range_end - 1;
77 for (; i >= range_begin; --i) {
78 const int64_t
value = base_function_(i);
79 if (interval_begin <=
value &&
value < interval_end)
break;
85 std::function<int64_t(int64_t)> base_function_;
90 std::vector<int64_t> FunctionToVector(
const std::function<int64_t(int64_t)>& f,
94 std::vector<int64_t> output(domain_end - domain_start, 0);
95 for (int64_t i = 0; i < domain_end - domain_start; ++i) {
96 output[i] = f(i + domain_start);
105 class CachedRangeIntToIntFunction :
public RangeIntToIntFunction {
107 CachedRangeIntToIntFunction(
108 const std::function<int64_t(int64_t)>& base_function,
109 int64_t domain_start, int64_t domain_end)
110 : domain_start_(domain_start),
111 rmq_min_(FunctionToVector(base_function, domain_start, domain_end)),
112 rmq_max_(rmq_min_.array()) {
116 int64_t Query(int64_t argument)
const override {
118 DCHECK_LE(argument, domain_start_ +
static_cast<int64_t
>(array().size()));
119 return array()[argument - domain_start_];
121 int64_t RangeMin(int64_t from, int64_t to)
const override {
124 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
125 return rmq_min_.GetMinimumFromRange(from - domain_start_,
128 int64_t RangeMax(int64_t from, int64_t to)
const override {
131 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
132 return rmq_max_.GetMinimumFromRange(from - domain_start_,
135 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
136 int64_t interval_begin,
137 int64_t interval_end)
const override {
141 DCHECK_LE(range_end, domain_start_ + array().size());
143 int64_t i = range_begin;
144 for (; i < range_end; ++i) {
145 const int64_t
value = array()[i - domain_start_];
146 if (interval_begin <=
value &&
value < interval_end)
break;
150 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
151 int64_t interval_begin,
152 int64_t interval_end)
const override {
156 DCHECK_LE(range_end, domain_start_ + array().size());
158 int64_t i = range_end - 1;
159 for (; i >= range_begin; --i) {
160 const int64_t
value = array()[i - domain_start_];
161 if (interval_begin <=
value &&
value < interval_end)
break;
167 const std::vector<int64_t>& array()
const {
return rmq_min_.array(); }
169 const int64_t domain_start_;
170 const RangeMinimumQuery<int64_t, std::less<int64_t>> rmq_min_;
171 const RangeMinimumQuery<int64_t, std::greater<int64_t>> rmq_max_;
176 class CachedRangeMinMaxIndexFunction :
public RangeMinMaxIndexFunction {
178 CachedRangeMinMaxIndexFunction(
const std::function<int64_t(int64_t)>& f,
179 int64_t domain_start, int64_t domain_end)
180 : domain_start_(domain_start),
181 domain_end_(domain_end),
182 index_rmq_min_(FunctionToVector(f, domain_start, domain_end)),
183 index_rmq_max_(index_rmq_min_.array()) {
187 inline int64_t RangeMinArgument(int64_t from, int64_t to)
const override {
191 return index_rmq_min_.GetMinimumIndexFromRange(from - domain_start_,
192 to - domain_start_) +
195 inline int64_t RangeMaxArgument(int64_t from, int64_t to)
const override {
199 return index_rmq_max_.GetMinimumIndexFromRange(from - domain_start_,
200 to - domain_start_) +
205 const int64_t domain_start_;
206 const int64_t domain_end_;
207 const RangeMinimumIndexQuery<int64_t, std::less<int64_t>> index_rmq_min_;
208 const RangeMinimumIndexQuery<int64_t, std::greater<int64_t>> index_rmq_max_;
215 std::function<int64_t(int64_t)> f) {
216 return new LinearRangeIntToIntFunction(std::move(f));
220 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
221 int64_t domain_end) {
222 return new CachedRangeIntToIntFunction(f, domain_start, domain_end);
226 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
227 int64_t domain_end) {
228 return new CachedRangeMinMaxIndexFunction(f, domain_start, domain_end);
#define DCHECK_LE(val1, val2)
#define DCHECK_NE(val1, val2)
#define CHECK_LT(val1, val2)
#define DCHECK_LT(val1, val2)
static const int64_t kint64max
static const int64_t kint64min
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Collection of objects used to extend the Constraint Solver library.
RangeIntToIntFunction * MakeCachedIntToIntFunction(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
RangeMinMaxIndexFunction * MakeCachedRangeMinMaxIndexFunction(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
RangeIntToIntFunction * MakeBareIntToIntFunction(std::function< int64_t(int64_t)> f)