21 #include "absl/container/flat_hash_set.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_format.h"
24 #include "absl/strings/str_join.h"
64 result.
values.push_back(included_min);
65 result.
values.push_back(included_max);
74 result.
values.push_back(0);
75 result.
values.push_back(1);
120 if (!domain.
values.empty()) {
130 const int64_t imin =
values[0];
131 const int64_t imax =
values[1];
146 if (interval_min > interval_max) {
152 values.push_back(interval_min);
153 values.push_back(interval_max);
156 if (
values[0] >= interval_min &&
values[1] <= interval_max)
return false;
171 std::vector<int64_t> new_values;
172 new_values.reserve(
values.size());
173 bool changed =
false;
174 for (
const int64_t val :
values) {
175 if (val > interval_max) {
179 if (val >= interval_min &&
180 (new_values.empty() || val != new_values.back())) {
181 new_values.push_back(val);
200 for (
const int64_t v : integers) {
201 if (v >= dmin && v <= dmax)
values.push_back(v);
209 const int64_t last =
values.back();
222 absl::flat_hash_set<int64_t> other_values(integers.begin(), integers.end());
223 std::vector<int64_t> new_values;
225 bool changed =
false;
226 for (
const int64_t val :
values) {
228 if (new_values.empty() || val != new_values.back()) {
229 new_values.push_back(val);
285 bool IntervalOverlapValues(int64_t lb, int64_t ub,
286 const std::vector<int64_t>& values) {
287 for (int64_t
value : values) {
302 return IntervalOverlapValues(
values[0],
values[1], vec);
305 const std::vector<int64_t>& to_scan =
307 const absl::flat_hash_set<int64_t> container =
308 values.size() <= vec.size()
309 ? absl::flat_hash_set<int64_t>(vec.begin(), vec.end())
310 : absl::flat_hash_set<int64_t>(
values.begin(),
values.end());
311 for (int64_t
value : to_scan) {
326 const int64_t dlb =
values[0];
327 const int64_t dub =
values[1];
328 return !(dub < lb || dlb > ub);
330 return IntervalOverlapValues(lb, ub,
values);
336 if (other.
values.empty()) {
358 const int64_t vmax =
values[1];
361 for (int64_t v =
values[0] + 1; v <= vmax; ++v) {
382 return absl::StrFormat(
"[%d..%d]",
values[0],
values[1]);
384 }
else if (
values.size() == 1) {
385 return absl::StrCat(
values.back());
387 return absl::StrFormat(
"[%s]", absl::StrJoin(
values,
", "));
403 result.
values.push_back(imin);
404 result.
values.push_back(imax);
444 if (domain.
values.empty()) {
458 return absl::StrFormat(
"% d",
values[0]);
460 return absl::StrFormat(
"[%d..%d]",
values[0],
values[1]);
462 return absl::StrFormat(
"[%s]", absl::StrJoin(
values,
", "));
468 std::string result =
"[";
469 for (
int i = 0; i <
variables.size(); ++i) {
471 result.append(i !=
variables.size() - 1 ?
", " :
"]");
476 return "VoidArgument";
478 LOG(
FATAL) <<
"Unhandled case in DebugString " <<
static_cast<int>(
type);
518 if (!domain.HasOneValue()) {
528 if (!
var->domain.HasOneValue()) {
592 IntegerVariable::IntegerVariable(
const std::string& name_,
593 const Domain& domain_,
bool temporary_)
594 :
name(name_), domain(domain_), temporary(temporary_), active(true) {
595 if (!domain.is_interval) {
601 const Domain& other_domain,
bool other_temporary) {
616 active ?
"" :
" [removed during presolve]");
624 const std::string presolve_status_str =
627 :
"[removed during presolve]");
629 strong, presolve_status_str);
642 type =
"false_constraint";
675 std::vector<Annotation> args) {
737 std::vector<IntegerVariable*>*
const vars)
const {
739 ann.AppendAllIntegerVariables(vars);
767 std::string result =
"[";
768 for (
int i = 0; i <
variables.size(); ++i) {
770 result.append(i !=
variables.size() - 1 ?
", " :
"]");
778 LOG(
FATAL) <<
"Unhandled case in DebugString " <<
static_cast<int>(
type);
799 const std::string&
name, std::vector<Bounds>
bounds,
819 return absl::StrFormat(
"output_var(%s)",
variable->
name);
821 return absl::StrFormat(
"output_array([%s] [%s])",
835 const Domain& domain,
bool defined) {
837 variables_.push_back(
var);
845 variables_.push_back(
var);
850 std::vector<Argument> arguments,
bool is_domain) {
852 new Constraint(
id, std::move(arguments), is_domain);
853 constraints_.push_back(constraint);
857 std::vector<Argument> arguments) {
858 AddConstraint(
id, std::move(arguments),
false);
862 output_.push_back(std::move(output));
867 search_annotations_ = std::move(search_annotations);
871 std::vector<Annotation> search_annotations) {
874 search_annotations_ = std::move(search_annotations);
878 std::vector<Annotation> search_annotations) {
881 search_annotations_ = std::move(search_annotations);
885 std::string output = absl::StrFormat(
"Model %s\nVariables\n", name_);
886 for (
int i = 0; i < variables_.size(); ++i) {
887 absl::StrAppendFormat(&output,
" %s\n", variables_[i]->
DebugString());
889 output.append(
"Constraints\n");
890 for (
int i = 0; i < constraints_.size(); ++i) {
891 if (constraints_[i] !=
nullptr) {
892 absl::StrAppendFormat(&output,
" %s\n", constraints_[i]->
DebugString());
896 absl::StrAppendFormat(&output,
"%s %s\n %s\n",
900 absl::StrAppendFormat(&output,
"Satisfy\n %s\n",
903 output.append(
"Output\n");
904 for (
int i = 0; i < output_.size(); ++i) {
905 absl::StrAppendFormat(&output,
" %s\n", output_[i].
DebugString());
913 if (
var->domain.empty()) {
918 if (
ct->type ==
"false_constraint") {
930 for (
const auto& it : constraints_per_type_) {
931 SOLVER_LOG(logger_,
" - ", it.first,
": ", it.second.size());
933 if (model_.objective() ==
nullptr) {
934 SOLVER_LOG(logger_,
" - Satisfaction problem");
937 (model_.maximize() ?
"Maximization" :
"Minimization"),
944 constraints_per_type_.clear();
945 constraints_per_variables_.clear();
947 if (
ct !=
nullptr &&
ct->active) {
948 constraints_per_type_[
ct->type].push_back(
ct);
949 absl::flat_hash_set<const IntegerVariable*> marked;
956 constraints_per_variables_[
var].push_back(
ct);
#define CHECK_LT(val1, val2)
#define CHECK_GE(val1, val2)
#define DCHECK(condition)
IntegerVariable * AddVariable(const std::string &name, const Domain &domain, bool defined)
IntegerVariable * AddConstant(int64_t value)
void Satisfy(std::vector< Annotation > search_annotations)
void Maximize(IntegerVariable *obj, std::vector< Annotation > search_annotations)
std::string DebugString() const
void AddOutput(SolutionOutputSpecs output)
void AddConstraint(const std::string &id, std::vector< Argument > arguments, bool is_domain)
void Minimize(IntegerVariable *obj, std::vector< Annotation > search_annotations)
bool IsInconsistent() const
void PrintStatistics() const
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
void STLDeleteElements(T *container)
bool ContainsKey(const Collection &collection, const Key &key)
void FlattenAnnotations(const Annotation &ann, std::vector< Annotation > *out)
Collection of objects used to extend the Constraint Solver library.
std::string JoinNameFieldPtr(const std::vector< T > &v, const std::string &separator)
std::string JoinDebugString(const std::vector< T > &v, const std::string &separator)
static Annotation IntegerValue(int64_t value)
std::vector< IntegerVariable * > variables
static Annotation Variable(IntegerVariable *const var)
std::string DebugString() const
static Annotation FunctionCall(const std::string &id)
static Annotation AnnotationList(std::vector< Annotation > list)
static Annotation String(const std::string &str)
static Annotation Identifier(const std::string &id)
bool IsFunctionCallWithIdentifier(const std::string &identifier) const
std::vector< Annotation > annotations
static Annotation Interval(int64_t interval_min, int64_t interval_max)
static Annotation Empty()
void AppendAllIntegerVariables(std::vector< IntegerVariable * > *vars) const
static Annotation FunctionCallWithArguments(const std::string &id, std::vector< Annotation > args)
static Annotation VariableList(std::vector< IntegerVariable * > variables)
IntegerVariable * Var() const
static Argument DomainList(std::vector< Domain > domains)
std::vector< IntegerVariable * > variables
bool Contains(int64_t value) const
static Argument IntegerList(std::vector< int64_t > values)
IntegerVariable * VarAt(int pos) const
static Argument VoidArgument()
static Argument IntVarRefArray(std::vector< IntegerVariable * > vars)
static Argument IntegerValue(int64_t value)
static Argument Interval(int64_t imin, int64_t imax)
std::string DebugString() const
std::vector< Domain > domains
std::vector< int64_t > values
int64_t ValueAt(int pos) const
static Argument IntVarRef(IntegerVariable *const var)
bool IsArrayOfValues() const
static Argument FromDomain(const Domain &domain)
bool presolve_propagation_done
void RemoveArg(int arg_pos)
std::string DebugString() const
std::vector< Argument > arguments
static Domain IntegerValue(int64_t value)
static Domain EmptyDomain()
bool Contains(int64_t value) const
bool OverlapsDomain(const Domain &other) const
static Domain SetOfAllInt64()
bool IntersectWithSingleton(int64_t value)
static Domain SetOfInterval(int64_t included_min, int64_t included_max)
static Domain IntegerList(std::vector< int64_t > values)
std::string DebugString() const
bool IntersectWithInterval(int64_t interval_min, int64_t interval_max)
bool IntersectWithDomain(const Domain &domain)
bool OverlapsIntInterval(int64_t lb, int64_t ub) const
static Domain SetOfIntegerValue(int64_t value)
bool OverlapsIntList(const std::vector< int64_t > &vec) const
static Domain Interval(int64_t included_min, int64_t included_max)
std::vector< int64_t > values
static Domain SetOfBoolean()
static Domain SetOfIntegerList(std::vector< int64_t > values)
bool IntersectWithListOfIntegers(const std::vector< int64_t > &integers)
bool RemoveValue(int64_t value)
std::string DebugString() const
bool Merge(const std::string &other_name, const Domain &other_domain, bool other_temporary)
std::string DebugString() const
static SolutionOutputSpecs MultiDimensionalArray(const std::string &name, std::vector< Bounds > bounds, std::vector< IntegerVariable * > flat_variables, bool display_as_boolean)
std::vector< IntegerVariable * > flat_variables
static SolutionOutputSpecs VoidOutput()
std::string DebugString() const
IntegerVariable * variable
std::vector< Bounds > bounds
static SolutionOutputSpecs SingleVariable(const std::string &name, IntegerVariable *variable, bool display_as_boolean)
#define SOLVER_LOG(logger,...)