30class LinearRangeIntToIntFunction :
public RangeIntToIntFunction {
32 explicit LinearRangeIntToIntFunction(
33 std::function<int64_t(int64_t)> base_function)
34 : base_function_(
std::move(base_function)) {}
36 int64_t Query(int64_t argument)
const override {
37 return base_function_(argument);
40 int64_t RangeMin(int64_t range_begin, int64_t range_end)
const override {
43 for (int64_t i = range_begin; i < range_end; ++i) {
44 min_val =
std::min(min_val, base_function_(i));
49 int64_t RangeMax(int64_t range_begin, int64_t range_end)
const override {
52 for (int64_t i = range_begin; i < range_end; ++i) {
53 max_val =
std::max(max_val, base_function_(i));
58 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
59 int64_t interval_begin,
60 int64_t interval_end)
const override {
64 int64_t i = range_begin;
65 for (; i < range_end; ++i) {
66 const int64_t
value = base_function_(i);
67 if (interval_begin <=
value &&
value < interval_end)
break;
72 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
73 int64_t interval_begin,
74 int64_t interval_end)
const override {
79 int64_t i = range_end - 1;
80 for (; i >= range_begin; --i) {
81 const int64_t
value = base_function_(i);
82 if (interval_begin <=
value &&
value < interval_end)
break;
88 std::function<int64_t(int64_t)> base_function_;
93std::vector<int64_t> FunctionToVector(
const std::function<int64_t(int64_t)>& f,
97 std::vector<int64_t> output(domain_end - domain_start, 0);
98 for (int64_t i = 0; i < domain_end - domain_start; ++i) {
99 output[i] = f(i + domain_start);
108class CachedRangeIntToIntFunction :
public RangeIntToIntFunction {
110 CachedRangeIntToIntFunction(
111 const std::function<int64_t(int64_t)>& base_function,
112 int64_t domain_start, int64_t domain_end)
113 : domain_start_(domain_start),
114 rmq_min_(FunctionToVector(base_function, domain_start, domain_end)),
115 rmq_max_(rmq_min_.array()) {
119 int64_t Query(int64_t argument)
const override {
121 DCHECK_LE(argument, domain_start_ +
static_cast<int64_t
>(array().size()));
122 return array()[argument - domain_start_];
124 int64_t RangeMin(int64_t from, int64_t to)
const override {
127 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
128 return rmq_min_.GetMinimumFromRange(from - domain_start_,
131 int64_t RangeMax(int64_t from, int64_t to)
const override {
134 DCHECK_LE(to, domain_start_ +
static_cast<int64_t
>(array().size()));
135 return rmq_max_.GetMinimumFromRange(from - domain_start_,
138 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
139 int64_t interval_begin,
140 int64_t interval_end)
const override {
144 DCHECK_LE(range_end, domain_start_ + array().size());
146 int64_t i = range_begin;
147 for (; i < range_end; ++i) {
148 const int64_t
value = array()[i - domain_start_];
149 if (interval_begin <=
value &&
value < interval_end)
break;
153 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
154 int64_t interval_begin,
155 int64_t interval_end)
const override {
159 DCHECK_LE(range_end, domain_start_ + array().size());
161 int64_t i = range_end - 1;
162 for (; i >= range_begin; --i) {
163 const int64_t
value = array()[i - domain_start_];
164 if (interval_begin <=
value &&
value < interval_end)
break;
170 const std::vector<int64_t>& array()
const {
return rmq_min_.array(); }
172 const int64_t domain_start_;
173 const RangeMinimumQuery<int64_t, std::less<int64_t>> rmq_min_;
174 const RangeMinimumQuery<int64_t, std::greater<int64_t>> rmq_max_;
179class CachedRangeMinMaxIndexFunction :
public RangeMinMaxIndexFunction {
181 CachedRangeMinMaxIndexFunction(
const std::function<int64_t(int64_t)>& f,
182 int64_t domain_start, int64_t domain_end)
183 : domain_start_(domain_start),
184 domain_end_(domain_end),
185 index_rmq_min_(FunctionToVector(f, domain_start, domain_end)),
186 index_rmq_max_(index_rmq_min_.array()) {
190 inline int64_t RangeMinArgument(int64_t from, int64_t to)
const override {
194 return index_rmq_min_.GetMinimumIndexFromRange(from - domain_start_,
195 to - domain_start_) +
198 inline int64_t RangeMaxArgument(int64_t from, int64_t to)
const override {
202 return index_rmq_max_.GetMinimumIndexFromRange(from - domain_start_,
203 to - domain_start_) +
208 const int64_t domain_start_;
209 const int64_t domain_end_;
210 const RangeMinimumIndexQuery<int64_t, std::less<int64_t>> index_rmq_min_;
211 const RangeMinimumIndexQuery<int64_t, std::greater<int64_t>> index_rmq_max_;
218 std::function<int64_t(int64_t)> f) {
219 return new LinearRangeIntToIntFunction(std::move(f));
223 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
224 int64_t domain_end) {
225 return new CachedRangeIntToIntFunction(f, domain_start, domain_end);
229 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
230 int64_t domain_end) {
231 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)