31 class LinearRangeIntToIntFunction :
public RangeIntToIntFunction {
33 explicit LinearRangeIntToIntFunction(
34 std::function<int64_t(int64_t)> base_function)
35 : base_function_(std::move(base_function)) {}
37 int64_t Query(int64_t argument)
const override {
38 return base_function_(argument);
41 int64_t RangeMin(int64_t range_begin, int64_t range_end)
const override {
42 DCHECK_LT(range_begin, range_end);
44 for (int64_t i = range_begin; i < range_end; ++i) {
45 min_val =
std::min(min_val, base_function_(i));
50 int64_t RangeMax(int64_t range_begin, int64_t range_end)
const override {
51 DCHECK_LT(range_begin, range_end);
53 for (int64_t i = range_begin; i < range_end; ++i) {
54 max_val =
std::max(max_val, base_function_(i));
59 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
60 int64_t interval_begin,
61 int64_t interval_end)
const override {
63 DCHECK_LT(range_begin, range_end);
64 DCHECK_LT(interval_begin, interval_end);
65 int64_t i = range_begin;
66 for (; i < range_end; ++i) {
67 const int64_t
value = base_function_(i);
68 if (interval_begin <=
value &&
value < interval_end)
break;
73 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
74 int64_t interval_begin,
75 int64_t interval_end)
const override {
78 DCHECK_LT(range_begin, range_end);
79 DCHECK_LT(interval_begin, interval_end);
80 int64_t i = range_end - 1;
81 for (; i >= range_begin; --i) {
82 const int64_t
value = base_function_(i);
83 if (interval_begin <=
value &&
value < interval_end)
break;
89 std::function<int64_t(int64_t)> base_function_;
94 std::vector<int64_t> FunctionToVector(
const std::function<int64_t(int64_t)>& f,
97 CHECK_LT(domain_start, domain_end);
98 std::vector<int64_t> output(domain_end - domain_start, 0);
99 for (int64_t i = 0; i < domain_end - domain_start; ++i) {
100 output[i] = f(i + domain_start);
109 class CachedRangeIntToIntFunction :
public RangeIntToIntFunction {
111 CachedRangeIntToIntFunction(
112 const std::function<int64_t(int64_t)>& base_function,
113 int64_t domain_start, int64_t domain_end)
114 : domain_start_(domain_start),
115 rmq_min_(FunctionToVector(base_function, domain_start, domain_end)),
116 rmq_max_(rmq_min_.array()) {
117 CHECK_LT(domain_start, domain_end);
120 int64_t Query(int64_t argument)
const override {
121 DCHECK_LE(domain_start_, argument);
122 DCHECK_LE(argument, domain_start_ +
static_cast<int64_t
>(array().size()));
123 return array()[argument - domain_start_];
125 int64_t RangeMin(int64_t from, int64_t to)
const override {
126 DCHECK_LE(domain_start_, from);
128 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
129 return rmq_min_.GetMinimumFromRange(from - domain_start_,
132 int64_t RangeMax(int64_t from, int64_t to)
const override {
133 DCHECK_LE(domain_start_, from);
135 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
136 return rmq_max_.GetMinimumFromRange(from - domain_start_,
139 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
140 int64_t interval_begin,
141 int64_t interval_end)
const override {
143 DCHECK_LE(domain_start_, range_begin);
144 DCHECK_LT(range_begin, range_end);
145 DCHECK_LE(range_end, domain_start_ + array().size());
146 DCHECK_LT(interval_begin, interval_end);
147 int64_t i = range_begin;
148 for (; i < range_end; ++i) {
149 const int64_t
value = array()[i - domain_start_];
150 if (interval_begin <=
value &&
value < interval_end)
break;
154 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
155 int64_t interval_begin,
156 int64_t interval_end)
const override {
158 DCHECK_LE(domain_start_, range_begin);
159 DCHECK_LT(range_begin, range_end);
160 DCHECK_LE(range_end, domain_start_ + array().size());
161 DCHECK_LT(interval_begin, interval_end);
162 int64_t i = range_end - 1;
163 for (; i >= range_begin; --i) {
164 const int64_t
value = array()[i - domain_start_];
165 if (interval_begin <=
value &&
value < interval_end)
break;
171 const std::vector<int64_t>& array()
const {
return rmq_min_.array(); }
173 const int64_t domain_start_;
174 const RangeMinimumQuery<int64_t, std::less<int64_t>> rmq_min_;
175 const RangeMinimumQuery<int64_t, std::greater<int64_t>> rmq_max_;
180 class CachedRangeMinMaxIndexFunction :
public RangeMinMaxIndexFunction {
182 CachedRangeMinMaxIndexFunction(
const std::function<int64_t(int64_t)>& f,
183 int64_t domain_start, int64_t domain_end)
184 : domain_start_(domain_start),
185 domain_end_(domain_end),
186 index_rmq_min_(FunctionToVector(f, domain_start, domain_end)),
187 index_rmq_max_(index_rmq_min_.array()) {
188 CHECK_LT(domain_start, domain_end);
191 inline int64_t RangeMinArgument(int64_t from, int64_t to)
const override {
192 DCHECK_LE(domain_start_, from);
194 DCHECK_LE(to, domain_end_);
195 return index_rmq_min_.GetMinimumIndexFromRange(from - domain_start_,
196 to - domain_start_) +
199 inline int64_t RangeMaxArgument(int64_t from, int64_t to)
const override {
200 DCHECK_LE(domain_start_, from);
202 DCHECK_LE(to, domain_end_);
203 return index_rmq_max_.GetMinimumIndexFromRange(from - domain_start_,
204 to - domain_start_) +
209 const int64_t domain_start_;
210 const int64_t domain_end_;
211 const RangeMinimumIndexQuery<int64_t, std::less<int64_t>> index_rmq_min_;
212 const RangeMinimumIndexQuery<int64_t, std::greater<int64_t>> index_rmq_max_;
219 std::function<int64_t(int64_t)> f) {
220 return new LinearRangeIntToIntFunction(std::move(f));
224 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
225 int64_t domain_end) {
226 return new CachedRangeIntToIntFunction(f, domain_start, domain_end);
230 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
231 int64_t domain_end) {
232 return new CachedRangeMinMaxIndexFunction(f, domain_start, domain_end);
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)