/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * Guido Tack * * Contributing authors: * Stefano Gualandi * Mikael Lagerkvist * David Rijsman * Samuel Gagnon * * Copyright: * Stefano Gualandi, 2013 * Mikael Lagerkvist, 2006 * David Rijsman, 2009 * Christian Schulte, 2002 * Guido Tack, 2004 * Samuel Gagnon, 2018 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef GECODE_INT_HH #define GECODE_INT_HH #include #include #include #include #include #include #include #include #include #include #include /* * Configure linking * */ #if !defined(GECODE_STATIC_LIBS) && \ (defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)) #ifdef GECODE_BUILD_INT #define GECODE_INT_EXPORT __declspec( dllexport ) #else #define GECODE_INT_EXPORT __declspec( dllimport ) #endif #else #ifdef GECODE_GCC_HAS_CLASS_VISIBILITY #define GECODE_INT_EXPORT __attribute__ ((visibility("default"))) #else #define GECODE_INT_EXPORT #endif #endif // Configure auto-linking #ifndef GECODE_BUILD_INT #define GECODE_LIBRARY_NAME "Int" #include #endif /** * \namespace Gecode::Int * \brief Finite domain integers * * The Gecode::Int namespace contains all functionality required * to program propagators and branchers for finite domain integers. * In addition, all propagators and branchers for finite domain * integers provided by %Gecode are contained as nested namespaces. * */ #include namespace Gecode { namespace Int { /** * \brief Numerical limits for integer variables * * The integer limits are chosen such changing the sign is always possible * without overflow. * \ingroup TaskModelIntVars */ namespace Limits { /// Largest allowed integer value const int max = INT_MAX - 1; /// Smallest allowed integer value const int min = -max; /// Infinity for integers const int infinity = max + 1; /// Largest allowed long long integer value const long long int llmax = LLONG_MAX - 1; /// Smallest allowed long long integer value const long long int llmin = -llmax; /// Infinity for long long integers const long long int llinfinity = llmax + 1; /// Return whether \a n is in range bool valid(int n); /// Return whether \a n is in range bool valid(long long int n); /// Check whether \a n is in range, otherwise throw out of limits with information \a l void check(int n, const char* l); /// Check whether \a n is in range, otherwise throw out of limits with information \a l void check(long long int n, const char* l); /// Check whether \a n is in range and strictly positive, otherwise throw out of limits with information \a l void positive(int n, const char* l); /// Check whether \a n is in range and strictly positive, otherwise throw out of limits with information \a l void positive(long long int n, const char* l); /// Check whether \a n is in range and nonnegative, otherwise throw out of limits with information \a l void nonnegative(int n, const char* l); /// Check whether \a n is in integer range and nonnegative, otherwise throw out of limits exception with information \a l void nonnegative(long long int n, const char* l); /// Check whether adding \a n and \a m would overflow bool overflow_add(int n, int m); /// Check whether adding \a n and \a m would overflow bool overflow_add(long long int n, long long int m); /// Check whether subtracting \a m from \a n would overflow bool overflow_sub(int n, int m); /// Check whether subtracting \a m from \a n would overflow bool overflow_sub(long long int n, long long int m); /// Check whether multiplying \a n and \a m would overflow bool overflow_mul(int n, int m); /// Check whether multiplying \a n and \a m would overflow bool overflow_mul(long long int n, long long int m); } }} #include namespace Gecode { class IntSetRanges; template class IntSetInit; /** * \brief Integer sets * * Integer sets are the means to specify arbitrary sets * of integers to be used as domains for integer variables. * \ingroup TaskModelIntVars TaskModelSetVars */ class IntSet : public SharedHandle { friend class IntSetRanges; template friend class IntSetInit; private: /// %Range (intervals) of integers class Range { public: int min, max; }; class IntSetObject : public SharedHandle::Object { public: /// Size of set unsigned int size; /// Number of ranges int n; /// Array of ranges Range* r; /// Allocate object with \a m elements GECODE_INT_EXPORT static IntSetObject* allocate(int m); /// Check whether \a n is included in the set GECODE_INT_EXPORT bool in(int n) const; /// Perform equality test on ranges GECODE_INT_EXPORT bool equal(const IntSetObject& so) const; /// Delete object GECODE_INT_EXPORT virtual ~IntSetObject(void); }; /// Sort ranges according to increasing minimum class MinInc; /// Normalize the first \a n elements of \a r GECODE_INT_EXPORT void normalize(Range* r, int n); /// Initialize as range with minimum \a n and maximum \a m GECODE_INT_EXPORT void init(int n, int m); /// Initialize with \a n integers from array \a r GECODE_INT_EXPORT void init(const int r[], int n); /// Initialize with \a n ranges from array \a r GECODE_INT_EXPORT void init(const int r[][2], int n); public: /// \name Constructors and initialization //@{ /// Initialize as empty set IntSet(void); /** \brief Initialize as range with minimum \a n and maximum \a m * * Note that the set is empty if \a n is larger than \a m */ explicit IntSet(int n, int m); /// Initialize with \a n integers from array \a r explicit IntSet(const int r[], int n); /** \brief Initialize with \a n ranges from array \a r * * For position \a i in the array \a r, the minimum is \a r[\a i][0] * and the maximum is \a r[\a i][1]. */ explicit IntSet(const int r[][2], int n); /// Initialize with range iterator \a i template explicit IntSet(I& i); /// Initialize with range iterator \a i template explicit IntSet(const I& i); /// Initialize with integers from list \a r GECODE_INT_EXPORT explicit IntSet(std::initializer_list r); /** \brief Initialize with ranges from vector \a r * * The minimum is the first element and the maximum is the * second element. */ GECODE_INT_EXPORT explicit IntSet(std::initializer_list> r); //@} /// \name Range access //@{ /// Return number of ranges of the specification int ranges(void) const; /// Return minimum of range at position \a i int min(int i) const; /// Return maximum of range at position \a i int max(int i) const; /// Return width of range at position \a i unsigned int width(int i) const; //@} /// \name Entire set access //@{ /// Return whether \a n is included in the set bool in(int n) const; /// Return size (cardinality) of set unsigned int size(void) const; /// Return width of set (distance between maximum and minimum) unsigned int width(void) const; /// Return minimum of entire set int min(void) const; /// Return maximum of entire set int max(void) const; //@} /// \name Equality tests //@{ /// Return whether \a s is equal bool operator ==(const IntSet& s) const; /// Return whether \a s is not equal bool operator !=(const IntSet& s) const; //@} /// \name Predefined value //@{ /// Empty set GECODE_INT_EXPORT static const IntSet empty; //@} }; /** * \brief Range iterator for integer sets * * \ingroup TaskModelIntVars TaskModelSetVars */ class IntSetRanges { private: /// Current range const IntSet::Range* i; /// End range const IntSet::Range* e; public: /// \name Constructors and initialization //@{ /// Default constructor IntSetRanges(void); /// Initialize with ranges for set \a s IntSetRanges(const IntSet& s); /// Initialize with ranges for set \a s void init(const IntSet& s); //@} /// \name Iteration control //@{ /// Test whether iterator is still at a range or done bool operator ()(void) const; /// Move iterator to next range (if possible) void operator ++(void); //@} /// \name Range access //@{ /// Return smallest value of range int min(void) const; /// Return largest value of range int max(void) const; /// Return width of range (distance between minimum and maximum) unsigned int width(void) const; //@} }; /** * \brief Value iterator for integer sets * * \ingroup TaskModelIntVars TaskModelSetVars */ class IntSetValues : public Iter::Ranges::ToValues { public: /// \name Constructors and initialization //@{ /// Default constructor IntSetValues(void); /// Initialize with values for \a s IntSetValues(const IntSet& s); /// Initialize with values for \a s void init(const IntSet& s); //@} }; /** * \brief Print integer set \a s * \relates Gecode::IntSet */ template std::basic_ostream& operator <<(std::basic_ostream& os, const IntSet& s); } #include #include namespace Gecode { namespace Int { class IntView; } /** * \brief Integer variables * * \ingroup TaskModelIntVars */ class IntVar : public VarImpVar { friend class IntVarArray; friend class IntVarArgs; private: using VarImpVar::x; /** * \brief Initialize variable with range domain * * The variable is created with a domain ranging from \a min * to \a max. No exceptions are thrown. */ void _init(Space& home, int min, int max); /** * \brief Initialize variable with arbitrary domain * * The variable is created with a domain described by \a d. * No exceptions are thrown. */ void _init(Space& home, const IntSet& d); public: /// \name Constructors and initialization //@{ /// Default constructor IntVar(void); /// Initialize from integer variable \a y IntVar(const IntVar& y); /// Initialize from integer view \a y IntVar(const Int::IntView& y); /** * \brief Initialize variable with range domain * * The variable is created with a domain ranging from \a min * to \a max. The following exceptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min or \a max exceed the limits for integers as defined * in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVar(Space& home, int min, int max); /** * \brief Initialize variable with arbitrary domain * * The variable is created with a domain described by \a d. * The following exceptions might be thrown: * - If \a d is empty, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a d contains values that exceed the limits for integers * as defined in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVar(Space& home, const IntSet& d); //@} /// \name Value access //@{ /// Return minimum of domain int min(void) const; /// Return maximum of domain int max(void) const; /// Return median of domain (greatest element not greater than the median) int med(void) const; /** * \brief Return assigned value * * Throws an exception of type Int::ValOfUnassignedVar if variable * is not yet assigned. * */ int val(void) const; /// Return size (cardinality) of domain unsigned int size(void) const; /// Return width of domain (distance between maximum and minimum) unsigned int width(void) const; /// Return regret of domain minimum (distance to next larger value) unsigned int regret_min(void) const; /// Return regret of domain maximum (distance to next smaller value) unsigned int regret_max(void) const; //@} /// \name Domain tests //@{ /// Test whether domain is a range bool range(void) const; /// Test whether \a n is contained in domain bool in(int n) const; //@} }; /** * \brief Print integer variable \a x * \relates Gecode::IntVar */ template std::basic_ostream& operator <<(std::basic_ostream& os, const IntVar& x); /** * \brief %Range iterator for integer variables * \ingroup TaskModelIntVars */ class IntVarRanges : public Int::IntVarImpFwd { public: /// \name Constructors and initialization //@{ /// Default constructor IntVarRanges(void); /// Initialize with ranges for integer variable \a x IntVarRanges(const IntVar& x); /// Initialize with ranges for integer variable \a x void init(const IntVar& x); //@} }; /** * \brief Value iterator for integer variables * \ingroup TaskModelIntVars */ class IntVarValues : public Iter::Ranges::ToValues { public: /// \name Constructors and initialization //@{ /// Default constructor IntVarValues(void); /// Initialize with values for \a x IntVarValues(const IntVar& x); /// Initialize with values \a x void init(const IntVar& x); //@} }; namespace Int { class BoolView; } /** * \brief Boolean integer variables * * \ingroup TaskModelIntVars */ class BoolVar : public VarImpVar { friend class BoolVarArray; friend class BoolVarArgs; private: using VarImpVar::x; /** * \brief Initialize Boolean variable with range domain * * The variable is created with a domain ranging from \a min * to \a max. No exceptions are thrown. */ void _init(Space& home, int min, int max); public: /// \name Constructors and initialization //@{ /// Default constructor BoolVar(void); /// Initialize from Boolean variable \a y BoolVar(const BoolVar& y); /// Initialize from Boolean view \a y BoolVar(const Int::BoolView& y); /** * \brief Initialize Boolean variable with range domain * * The variable is created with a domain ranging from \a min * to \a max. The following exceptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min is less than 0 or \a max is greater than 1, * an exception of type * Gecode::Int::NotZeroOne is thrown. */ GECODE_INT_EXPORT BoolVar(Space& home, int min, int max); //@} /// \name Value access //@{ /// Return minimum of domain int min(void) const; /// Return maximum of domain int max(void) const; /// Return median of domain (greatest element not greater than the median) int med(void) const; /** * \brief Return assigned value * * Throws an exception of type Int::ValOfUnassignedVar if variable * is not yet assigned. * */ int val(void) const; /// Return size (cardinality) of domain unsigned int size(void) const; /// Return width of domain (distance between maximum and minimum) unsigned int width(void) const; /// Return regret of domain minimum (distance to next larger value) unsigned int regret_min(void) const; /// Return regret of domain maximum (distance to next smaller value) unsigned int regret_max(void) const; //@} /// \name Domain tests //@{ /// Test whether domain is a range bool range(void) const; /// Test whether \a n is contained in domain bool in(int n) const; //@} /// \name Boolean domain tests //@{ /// Test whether domain is zero bool zero(void) const; /// Test whether domain is one bool one(void) const; /// Test whether domain is neither zero nor one bool none(void) const; //@} }; /** * \brief Print Boolean variable \a x * \relates Gecode::BoolVar */ template std::basic_ostream& operator <<(std::basic_ostream& os, const BoolVar& x); } #include #include namespace Gecode { /** * \defgroup TaskModelIntArgs Argument arrays * * Argument arrays are just good enough for passing arguments * with automatic memory management. * \ingroup TaskModelInt */ //@{ /// Passing set arguments typedef ArgArray IntSetArgs; } #include namespace Gecode { /// Passing integer arguments class IntArgs : public ArgArray { public: /// \name Constructors and initialization //@{ /// Allocate empty array IntArgs(void); /// Allocate array with \a n elements explicit IntArgs(int n); /// Allocate array and copy elements from \a x IntArgs(const SharedArray& x); /// Allocate array and copy elements from \a x IntArgs(const std::vector& x); /// Allocate array and copy elements from \a x IntArgs(std::initializer_list x); /// Allocate array and copy elements from \a first to \a last template IntArgs(InputIterator first, InputIterator last); /// Allocate array with \a n elements and initialize with elements from array \a e IntArgs(int n, const int* e); /// Initialize from primitive argument array \a a (copy elements) IntArgs(const ArgArray& a); /// Allocate array with \a n elements such that for all \f$0\leq i { public: /// \name Constructors and initialization //@{ /// Allocate empty array IntVarArgs(void); /// Allocate array with \a n elements explicit IntVarArgs(int n); /// Initialize from variable argument array \a a (copy elements) IntVarArgs(const IntVarArgs& a); /// Initialize from variable array \a a (copy elements) IntVarArgs(const VarArray& a); /// Initialize from \a a IntVarArgs(const std::vector& a); /// Initialize from \a a IntVarArgs(std::initializer_list a); /// Initialize from InputIterator \a first and \a last template IntVarArgs(InputIterator first, InputIterator last); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain ranging from \a min * to \a max. The following execptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min or \a max exceed the limits for integers as defined * in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVarArgs(Space& home, int n, int min, int max); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain described by \a s. * The following execptions might be thrown: * - If \a s is empty, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a s contains values that exceed the limits for integers * as defined in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVarArgs(Space& home, int n, const IntSet& s); //@} }; /** \brief Passing Boolean variables * * We could have used a simple typedef instead, but doxygen cannot * resolve some overloading then, leading to unusable documentation for * important parts of the library. As long as there is no fix for this, * we will keep this workaround. * */ class BoolVarArgs : public VarArgArray { public: /// \name Constructors and initialization //@{ /// Allocate empty array BoolVarArgs(void); /// Allocate array with \a n elements explicit BoolVarArgs(int n); /// Initialize from variable argument array \a a (copy elements) BoolVarArgs(const BoolVarArgs& a); /// Initialize from variable array \a a (copy elements) BoolVarArgs(const VarArray& a); /// Initialize from \a a BoolVarArgs(const std::vector& a); /// Initialize from \a a BoolVarArgs(std::initializer_list a); /// Initialize from InputIterator \a first and \a last template BoolVarArgs(InputIterator first, InputIterator last); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain ranging from \a min * to \a max. The following execptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min is less than 0 or \a max is greater than 1, * an exception of type * Gecode::Int::NotZeroOne is thrown. */ GECODE_INT_EXPORT BoolVarArgs(Space& home, int n, int min, int max); //@} }; //@} /** * \defgroup TaskModelIntVarArrays Variable arrays * * Variable arrays can store variables. They are typically used * for storing the variables being part of a solution (script). However, * they can also be used for temporary purposes (even though * memory is not reclaimed until the space it is created for * is deleted). * \ingroup TaskModelInt */ /** * \brief Integer variable array * \ingroup TaskModelIntVarArrays */ class IntVarArray : public VarArray { public: /// \name Creation and initialization //@{ /// Default constructor (array of size 0) IntVarArray(void); /// Allocate array for \a n integer variables (variables are uninitialized) IntVarArray(Space& home, int n); /// Initialize from integer variable array \a a (share elements) IntVarArray(const IntVarArray& a); /// Initialize from integer variable argument array \a a (copy elements) IntVarArray(Space& home, const IntVarArgs& a); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain ranging from \a min * to \a max. The following execptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min or \a max exceed the limits for integers as defined * in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVarArray(Space& home, int n, int min, int max); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain described by \a s. * The following execptions might be thrown: * - If \a s is empty, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a s contains values that exceed the limits for integers * as defined in Gecode::Int::Limits, an exception of type * Gecode::Int::OutOfLimits is thrown. */ GECODE_INT_EXPORT IntVarArray(Space& home, int n, const IntSet& s); //@} }; /** * \brief Boolean variable array * \ingroup TaskModelIntVarArrays */ class BoolVarArray : public VarArray { public: /// \name Creation and initialization //@{ /// Default constructor (array of size 0) BoolVarArray(void); /// Allocate array for \a n Boolean variables (variables are uninitialized) BoolVarArray(Space& home, int n); /// Initialize from Boolean variable array \a a (share elements) BoolVarArray(const BoolVarArray& a); /// Initialize from Boolean variable argument array \a a (copy elements) BoolVarArray(Space& home, const BoolVarArgs& a); /** * \brief Initialize array with \a n new variables * * The variables are created with a domain ranging from \a min * to \a max. The following execptions might be thrown: * - If \a min is greater than \a max, an exception of type * Gecode::Int::VariableEmptyDomain is thrown. * - If \a min is less than 0 or \a max is greater than 1, * an exception of type * Gecode::Int::NotZeroOne is thrown. */ GECODE_INT_EXPORT BoolVarArray(Space& home, int n, int min, int max); //@} }; } #include #include namespace Gecode { /** * \brief Mode for reification * \ingroup TaskModelInt */ enum ReifyMode { /** * \brief Equivalence for reification (default) * * For a constraint \f$c\f$ and a Boolean control variable \f$b\f$ * defines that \f$b=1\Leftrightarrow c\f$ is propagated. */ RM_EQV, /** * \brief Implication for reification * * For a constraint \f$c\f$ and a Boolean control variable \f$b\f$ * defines that \f$b=1\Leftarrow c\f$ is propagated. */ RM_IMP, /** * \brief Inverse implication for reification * * For a constraint \f$c\f$ and a Boolean control variable \f$b\f$ * defines that \f$b=1\Rightarrow c\f$ is propagated. */ RM_PMI }; /** * \brief Reification specification * \ingroup TaskModelInt */ class Reify { protected: /// The Boolean control variable BoolVar x; /// The reification mode ReifyMode rm; public: /// Default constructor without proper initialization Reify(void); /// Construct reification specification Reify(BoolVar x, ReifyMode rm=RM_EQV); /// Return Boolean control variable BoolVar var(void) const; /// Return reification mode ReifyMode mode(void) const; /// Set Boolean control variable void var(BoolVar x); /// Set reification mode void mode(ReifyMode rm); }; /** * \brief Use equivalence for reification * \ingroup TaskModelInt */ Reify eqv(BoolVar x); /** * \brief Use implication for reification * \ingroup TaskModelInt */ Reify imp(BoolVar x); /** * \brief Use reverse implication for reification * \ingroup TaskModelInt */ Reify pmi(BoolVar x); } #include namespace Gecode { /** * \brief Relation types for integers * \ingroup TaskModelInt */ enum IntRelType { IRT_EQ, ///< Equality (\f$=\f$) IRT_NQ, ///< Disequality (\f$\neq\f$) IRT_LQ, ///< Less or equal (\f$\leq\f$) IRT_LE, ///< Less (\f$<\f$) IRT_GQ, ///< Greater or equal (\f$\geq\f$) IRT_GR ///< Greater (\f$>\f$) }; /// Return swapped relation type of \a irt IntRelType swap(IntRelType irt); /// Return negated relation type of \a irt IntRelType neg(IntRelType irt); } #include namespace Gecode { /** * \brief Operation types for Booleans * \ingroup TaskModelInt */ enum BoolOpType { BOT_AND, ///< Conjunction BOT_OR, ///< Disjunction BOT_IMP, ///< Implication BOT_EQV, ///< Equivalence BOT_XOR ///< Exclusive or }; /** * \brief Propagation levels for integer propagators * * The descriptions are meant to be approximate. It is not * required that a propagator achieves full domain consistency or * full bounds consistency. It is more like: which level * of consistency comes closest to the level of propagation * the propagator implements. * * If in the description of a constraint below no propagation level * is mentioned, the propagation level for the constraint is domain * propagation and the implementation in fact enforces domain * consistency. * * \ingroup TaskModelInt */ enum IntPropLevel { /// Simple propagation levels IPL_DEF = 0, ///< Default level of propagation IPL_VAL = 1, ///< Value propagation IPL_BND = 2, ///< Bounds propagation IPL_DOM = 3, ///< Domain propagation /// Options: basic versus advanced propagation IPL_BASIC = 4, ///< Use basic propagation algorithm IPL_ADVANCED = 8, ///< Use advanced propagation algorithm IPL_BASIC_ADVANCED = IPL_BASIC | IPL_ADVANCED, ///< Use both IPL_BITS_ = 4 ///< Number of bits required (internal) }; /// Extract value, bounds, or domain propagation from propagation level IntPropLevel vbd(IntPropLevel ipl); /// Extract basic or advanced from propagation level IntPropLevel ba(IntPropLevel ipl); } #include namespace Gecode { /** * \brief Type of task for scheduling constraints * * \ingroup TaskModelInt */ enum TaskType { TT_FIXP, //< Task with fixed processing time TT_FIXS, //< Task with fixed start time TT_FIXE //< Task with fixed end time }; /** * \brief Argument arrays for passing task type arguments * * \ingroup TaskModelInt */ typedef ArgArray TaskTypeArgs; /// Traits of %TaskTypeArgs template<> class ArrayTraits > { public: typedef TaskTypeArgs StorageType; typedef TaskType ValueType; typedef TaskTypeArgs ArgsType; }; /** * \defgroup TaskModelIntDomain Domain constraints * \ingroup TaskModelInt * */ //@{ /// Propagates \f$x=n\f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, int n, IntPropLevel ipl=IPL_DEF); /// Propagates \f$ x_i=n\f$ for all \f$0\leq i<|x|\f$ GECODE_INT_EXPORT void dom(Home home, const IntVarArgs& x, int n, IntPropLevel ipl=IPL_DEF); /// Propagates \f$ l\leq x\leq m\f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, int l, int m, IntPropLevel ipl=IPL_DEF); /// Propagates \f$ l\leq x_i\leq m\f$ for all \f$0\leq i<|x|\f$ GECODE_INT_EXPORT void dom(Home home, const IntVarArgs& x, int l, int m, IntPropLevel ipl=IPL_DEF); /// Propagates \f$ x\in s \f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, const IntSet& s, IntPropLevel ipl=IPL_DEF); /// Propagates \f$ x_i\in s\f$ for all \f$0\leq i<|x|\f$ GECODE_INT_EXPORT void dom(Home home, const IntVarArgs& x, const IntSet& s, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ (x=n) \equiv r\f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, int n, Reify r, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ (l\leq x \leq m) \equiv r\f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, int l, int m, Reify r, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ (x \in s) \equiv r\f$ GECODE_INT_EXPORT void dom(Home home, IntVar x, const IntSet& s, Reify r, IntPropLevel ipl=IPL_DEF); /// Constrain domain of \a x according to domain of \a d GECODE_INT_EXPORT void dom(Home home, IntVar x, IntVar d, IntPropLevel ipl=IPL_DEF); /// Constrain domain of \a x according to domain of \a d GECODE_INT_EXPORT void dom(Home home, BoolVar x, BoolVar d, IntPropLevel ipl=IPL_DEF); /// Constrain domain of \f$ x_i \f$ according to domain of \f$ d_i \f$ for all \f$0\leq i<|x|\f$ GECODE_INT_EXPORT void dom(Home home, const IntVarArgs& x, const IntVarArgs& d, IntPropLevel ipl=IPL_DEF); /// Constrain domain of \f$ x_i \f$ according to domain of \f$ d_i \f$ for all \f$0\leq i<|x|\f$ GECODE_INT_EXPORT void dom(Home home, const BoolVarArgs& x, const BoolVarArgs& d, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntRelInt Simple relation constraints over integer variables * \ingroup TaskModelInt */ /** \brief Post propagator for \f$ x_0 \sim_{irt} x_1\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, IntVar x0, IntRelType irt, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_i \sim_{irt} y \f$ for all \f$0\leq i<|x|\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Propagates \f$ x \sim_{irt} c\f$ * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, IntVar x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Propagates \f$ x_i \sim_{irt} c \f$ for all \f$0\leq i<|x|\f$ * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntVarArgs& x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ (x_0 \sim_{irt} x_1)\equiv r\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, IntVar x0, IntRelType irt, IntVar x1, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$(x \sim_{irt} c)\equiv r\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, IntVar x, IntRelType irt, int c, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for relation among elements in \a x. * * States that the elements of \a x are in the following relation: * - if \a r = IRT_LE, \a r = IRT_LQ, \a r = IRT_GR, or \a r = IRT_GQ, * then the elements of \a x are ordered with respect to \a r. * Supports domain consistency (\a ipl = IPL_DOM, default). * - if \a r = IRT_EQ, then all elements of \a x must be equal. * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * - if \a r = IRT_NQ, then not all elements of \a x must be equal. * Supports domain consistency (\a ipl = IPL_DOM, default). * * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntVarArgs& x, IntRelType irt, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntVarArgs& x, IntRelType irt, const IntVarArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Supports domain consistency. * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntVarArgs& x, IntRelType irt, const IntArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Supports domain consistency. * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * \ingroup TaskModelIntRelInt */ GECODE_INT_EXPORT void rel(Home home, const IntArgs& x, IntRelType irt, const IntVarArgs& y, IntPropLevel ipl=IPL_DEF); /** * \defgroup TaskModelIntRelBool Simple relation constraints over Boolean variables * \ingroup TaskModelInt */ /** \brief Post domain consistent propagator for \f$ x_0 \sim_{irt} x_1\f$ * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x0, IntRelType irt, BoolVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$(x_0 \sim_{irt} x_1)\equiv r\f$ * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x0, IntRelType irt, BoolVar x1, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ x_i \sim_{irt} y \f$ for all \f$0\leq i<|x|\f$ * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const BoolVarArgs& x, IntRelType irt, BoolVar y, IntPropLevel ipl=IPL_DEF); /** * \brief Propagates \f$ x \sim_{irt} n\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x, IntRelType irt, int n, IntPropLevel ipl=IPL_DEF); /** * \brief Post domain consistent propagator for \f$(x \sim_{irt} n)\equiv r\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x, IntRelType irt, int n, Reify r, IntPropLevel ipl=IPL_DEF); /** * \brief Propagates \f$ x_i \sim_{irt} n \f$ for all \f$0\leq i<|x|\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const BoolVarArgs& x, IntRelType irt, int n, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const BoolVarArgs& x, IntRelType irt, const BoolVarArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const BoolVarArgs& x, IntRelType irt, const IntArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for relation between \a x and \a y. * * Note that for the inequality relations this corresponds to * the lexical order between \a x and \a y. * * Note that the constraint is also defined if \a x and \a y are of * different size. That means that if \a x and \a y are of different * size, then if \a r = IRT_EQ the constraint is false and if * \a r = IRT_NQ the constraint is subsumed. * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const IntArgs& x, IntRelType irt, const BoolVarArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for relation between elements in \a x. * * States that the elements of \a x are in the following relation: * - if \a r = IRT_LE, \a r = IRT_LQ, \a r = IRT_GR, or \a r = IRT_GQ, * then the elements of \a x are ordered with respect to \a r. * - if \a r = IRT_EQ, then all elements of \a x must be equal. * - if \a r = IRT_NQ, then not all elements of \a x must be equal. * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, const BoolVarArgs& x, IntRelType irt, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean operation on \a x0 and \a x1 * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} x_1 = x_2\f$ * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x0, BoolOpType o, BoolVar x1, BoolVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean operation on \a x0 and \a x1 * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} x_1 = n\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolVar x0, BoolOpType o, BoolVar x1, int n, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean operation on \a x * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} \cdots * \diamond_{\mathit{o}} x_{|x|-1}= y\f$ * * Throws an exception of type Int::TooFewArguments, if \f$|x|<2\f$ * and \a o is BOT_IMP, BOT_EQV, or BOT_XOR. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolOpType o, const BoolVarArgs& x, BoolVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean operation on \a x * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} \cdots * \diamond_{\mathit{o}} x_{|x|-1}= n\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * * Throws an exception of type Int::TooFewArguments, if \f$|x|<2\f$ * and \a o is BOT_IMP, BOT_EQV, or BOT_XOR. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void rel(Home home, BoolOpType o, const BoolVarArgs& x, int n, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean clause with positive variables \a x and negative variables \a y * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} \cdots * \diamond_{\mathit{o}} x_{|x|-1} \diamond_{\mathit{o}} \neg y_0 * \diamond_{\mathit{o}} \cdots \diamond_{\mathit{o}} \neg y_{|y|-1}= z\f$ * * Throws an exception of type Int::IllegalOperation, if \a o is different * from BOT_AND or BOT_OR. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void clause(Home home, BoolOpType o, const BoolVarArgs& x, const BoolVarArgs& y, BoolVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for Boolean clause with positive variables \a x and negative variables \a y * * Posts propagator for \f$ x_0 \diamond_{\mathit{o}} \cdots * \diamond_{\mathit{o}} x_{|x|-1} \diamond_{\mathit{o}} \neg y_0 * \diamond_{\mathit{o}} \cdots \diamond_{\mathit{o}} \neg y_{|y|-1}= n\f$ * * Throws an exception of type Int::NotZeroOne, if \a n is neither * 0 or 1. * * Throws an exception of type Int::IllegalOperation, if \a o is different * from BOT_AND or BOT_OR. * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void clause(Home home, BoolOpType o, const BoolVarArgs& x, const BoolVarArgs& y, int n, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for if-then-else constraint * * Posts propagator for \f$ z = b ? x : y \f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void ite(Home home, BoolVar b, IntVar x, IntVar y, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for if-then-else constraint * * Posts propagator for \f$ z = b ? x : y \f$ * * \ingroup TaskModelIntRelBool */ GECODE_INT_EXPORT void ite(Home home, BoolVar b, BoolVar x, BoolVar y, BoolVar z, IntPropLevel ipl=IPL_DEF); /** * \defgroup TaskModelIntPrecede Value precedence constraints over integer variables * \ingroup TaskModelInt */ /** \brief Post propagator that \a s precedes \a t in \a x * * This constraint enforces that \f$x_0\neq t\f$ and * \f$x_j=t \to \bigvee_{0\leq i IntSharedArray; /** \brief Post domain consistent propagator for \f$ n_{x_0}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ n_{x_0+offset}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, int offset, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ n_{x_0}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, BoolVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ n_{x_0+offset}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, int offset, BoolVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ n_{x_0}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, int x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ n_{x_0+offset}=x_1\f$ * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray n, IntVar x0, int offset, int x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_{y_0}=y_1\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& x, IntVar y0, IntVar y1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_{y_0+offset}=y_1\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& x, IntVar y0, int offset, IntVar y1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_{y_0}=y_1\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& x, IntVar y0, int y1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_{y_0+offset}=y_1\f$ * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& x, IntVar y0, int offset, int y1, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ x_{y_0}=y_1\f$ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& x, IntVar y0, BoolVar y1, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ x_{y_0+offset}=y_1\f$ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& x, IntVar y0, int offset, BoolVar y1, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ x_{y_0}=y_1\f$ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& x, IntVar y0, int y1, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for \f$ x_{y_0+offset}=y_1\f$ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& x, IntVar y0, int offset, int y1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+w\cdot y}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray a, IntVar x, int w, IntVar y, int h, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+xoff+w\cdot (y+yoff)}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y, offset by * xoff and yoff. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray a, IntVar x, int xoff, int w, IntVar y, int yoff, int h, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+w\cdot y}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray a, IntVar x, int w, IntVar y, int h, BoolVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+xoff+w\cdot (y+yoff)}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y, offset by * xoff and yoff. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, IntSharedArray a, IntVar x, int xoff, int w, IntVar y, int yoff, int h, BoolVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ a_{x+w\cdot y}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y. * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& a, IntVar x, int w, IntVar y, int h, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ a_{x+xoff+w\cdot (y+yoff)}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y, offset by * xoff and yoff. * * Supports both bounds (\a ipl = IPL_BND) and * domain consistency (\a ipl = IPL_DOM, default). * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, const IntVarArgs& a, IntVar x, int xoff, int w, IntVar y, int yoff, int h, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+w\cdot y}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& a, IntVar x, int w, IntVar y, int h, BoolVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for \f$ a_{x+xoff+w\cdot (y+yoff)}=z\f$ * * If \a a is regarded as a two-dimensional array in row-major * order of width \a w and height \a h, then \a z is constrained * to be the element in column \a x and row \a y, offset by * xoff and yoff. * * Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \f$ w\cdot h\neq|a|\f$. */ GECODE_INT_EXPORT void element(Home home, const BoolVarArgs& a, IntVar x, int xoff, int w, IntVar y, int yoff, int h, BoolVar z, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntDistinct Distinct constraints * \ingroup TaskModelInt */ //@{ /** \brief Post propagator for \f$ x_i\neq x_j\f$ for all \f$0\leq i\neq j<|x|\f$ * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. */ GECODE_INT_EXPORT void distinct(Home home, const IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_i+n_i\neq x_j+n_j\f$ for all \f$0\leq i\neq j<|x|\f$ * * \li Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * \li Throws an exception of type Int::OutOfLimits, if * the integers in \a n exceed the limits in Int::Limits * or if the sum of \a n and \a x exceed the limits. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a n are of different size. * \li Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. */ GECODE_INT_EXPORT void distinct(Home home, const IntArgs& n, const IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ b_i=1\wedge b_j=1\to x_i\neq x_j\f$ for all \f$0\leq i\neq j<|x|\f$ * * \li Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * \li Throws an exception of type Int::OutOfLimits, if * the variable domains in \a x are too large (it must hold that * one of the values \f$(\max_{i=0,\ldots,|x|-1} \max(x_i))+|x|\f$ * and \f$(\min_{i=0,\ldots,|x|-1} \min(x_i))-|x|\f$ * does not exceed the limits in Int::Limits. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a b and \a x are of different size. * \li Throws an exception of type Int::ArgumentSame, if \a x * contains the same unassigned variable multiply. */ GECODE_INT_EXPORT void distinct(Home home, const BoolVarArgs& b, const IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_i=c\vee x_j=c\vee x_i\neq x_j\f$ for all \f$0\leq i\neq j<|x|\f$ * * \li Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * \li Throws an exception of type Int::OutOfLimits, if * the variable domains in \a x are too large (it must hold that * one of the values \f$(\max_{i=0,\ldots,|x|-1} \max(x_i))+|x|\f$ * and \f$(\min_{i=0,\ldots,|x|-1} \min(x_i))-|x|\f$ * does not exceed the limits in Int::Limits. * \li Throws an exception of type Int::ArgumentSame, if \a x * contains the same unassigned variable multiply. */ GECODE_INT_EXPORT void distinct(Home home, const IntVarArgs& x, int c, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntChannel Channel constraints * \ingroup TaskModelInt */ //@{ /** \brief Post propagator for \f$ x_i = j\leftrightarrow y_j=i\f$ for all \f$0\leq i<|x|\f$ * * \li Supports domain consistency (\a ipl = IPL_DOM) and value * propagation (all other values for \a ipl, default). * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a y are of different size. * \li Throws an exception of type Int::ArgumentSame, if \a x or * \a y contain the same unassigned variable multiply. Note that a * variable can occur in both \a x and \a y, but not more than * once in either \a x or \a y. */ GECODE_INT_EXPORT void channel(Home home, const IntVarArgs& x, const IntVarArgs& y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ x_i - \mathit{xoff} = j\leftrightarrow y_j - \mathit{yoff} = i\f$ for all \f$0\leq i<|x|\f$ * * \li Supports domain consistency (\a ipl = IPL_DOM) and value * propagation (all other values for \a ipl, default). * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a y are of different size. * \li Throws an exception of type Int::ArgumentSame, if \a x or * \a y contain the same unassigned variable multiply. Note that a * variable can occur in both \a x and \a y, but not more than * once in either \a x or \a y. * \li Throws an exception of type Int::OutOfLimits, if \a xoff or * \a yoff are negative. */ GECODE_INT_EXPORT void channel(Home home, const IntVarArgs& x, int xoff, const IntVarArgs& y, int yoff, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for channeling a Boolean and an integer variable \f$ x_0 = x_1\f$ GECODE_INT_EXPORT void channel(Home home, BoolVar x0, IntVar x1, IntPropLevel ipl=IPL_DEF); /// Post domain consistent propagator for channeling an integer and a Boolean variable \f$ x_0 = x_1\f$ void channel(Home home, IntVar x0, BoolVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post domain consistent propagator for channeling Boolean and integer variables \f$ x_i = 1\leftrightarrow y=i+o\f$ * * Throws an exception of type Int::ArgumentSame, if \a x * contains the same unassigned variable multiply. */ GECODE_INT_EXPORT void channel(Home home, const BoolVarArgs& x, IntVar y, int o=0, IntPropLevel ipl=IPL_DEF); //@} } #include namespace Gecode { /** * \defgroup TaskModelIntSorted Sorted constraints * * All sorted constraints support bounds consistency only. * * \ingroup TaskModelInt */ //@{ /** * \brief Post propagator that \a y is \a x sorted in increasing order * * Might throw the following exceptions: * - Int::ArgumentSizeMismatch, if \a x and \a y differ in size. * - Int::ArgumentSame, if \a x or \a y contain * shared unassigned variables. */ GECODE_INT_EXPORT void sorted(Home home, const IntVarArgs& x, const IntVarArgs& y, IntPropLevel ipl=IPL_DEF); /** * \brief Post propagator that \a y is \a x sorted in increasing order * * The values in \a z describe the sorting permutation, that is * \f$\forall i\in\{0,\dots,|x|-1\}: x_i=y_{z_i} \f$. * * Might throw the following exceptions: * - Int::ArgumentSizeMismatch, if \a x and \a y differ in size. * - Int::ArgumentSame, if \a x or \a y contain * shared unassigned variables. */ GECODE_INT_EXPORT void sorted(Home home, const IntVarArgs& x, const IntVarArgs& y, const IntVarArgs& z, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntCount Counting constraints * \ingroup TaskModelInt * * \note * Domain consistency on the extended cardinality variables of * the Global Cardinality Propagator is only obtained if they are bounds * consistent, otherwise the problem of enforcing domain consistency * on the cardinality variables is NP-complete as proved by * Qumiper et. al. in * ''Improved Algorithms for the Global Cardinality Constraint''. */ //@{ /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=n\}\sim_{irt} m\f$ * * Performs domain propagation but is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, int n, IntRelType irt, int m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i\in y\}\sim_{irt} m\f$ * * Performs domain propagation but is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntSet& y, IntRelType irt, int m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=y\}\sim_{irt} m\f$ * * Performs domain propagation (\a ipl = IPL_DOM, default) * and slightly less domain propagation (all other values for \a ipl), * where \a y is not pruned. Note that in both cases propagation * is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, IntVar y, IntRelType irt, int m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=y_i\}\sim_{irt} m\f$ * * Performs domain propagation but is not domain consistent. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a y are of different size. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntArgs& y, IntRelType irt, int m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=n\}\sim_{irt} z\f$ * * Performs domain propagation but is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, int n, IntRelType irt, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i\in y\}\sim_{irt} z\f$ * * Performs domain propagation but is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntSet& y, IntRelType irt, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=y\}\sim_{irt} z\f$ * * Performs domain propagation (\a ipl = IPL_DOM, default) * and slightly less domain propagation (all other values for \a ipl), * where \a y is not pruned. Note that in both cases propagation * is not domain consistent. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, IntVar y, IntRelType irt, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=y_i\}\sim_{irt} z\f$ * * Performs domain propagation but is not domain consistent. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a y are of different size. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntArgs& y, IntRelType irt, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Posts a global count (cardinality) constraint * * Posts the constraint that * \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=j\}=c_j\f$ and * \f$ \bigcup_i \{x_i\} \subseteq \{0,\ldots,|c|-1\}\f$ * (no other value occurs). * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntVarArgs& c, IntPropLevel ipl=IPL_DEF); /** \brief Posts a global count (cardinality) constraint * * Posts the constraint that * \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=j\}\in c_j\f$ and * \f$ \bigcup_i \{x_i\} \subseteq \{0,\ldots,|c|-1\}\f$ * (no other value occurs). * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntSetArgs& c, IntPropLevel ipl=IPL_DEF); /** \brief Posts a global count (cardinality) constraint * * Posts the constraint that * \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=v_j\}=c_j\f$ and * \f$ \bigcup_i \{x_i\} \subseteq \bigcup_j \{v_j\}\f$ * (no other value occurs). * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a c and \a v are of different size. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntVarArgs& c, const IntArgs& v, IntPropLevel ipl=IPL_DEF); /** \brief Posts a global count (cardinality) constraint * * Posts the constraint that * \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=v_j\}\in c_j\f$ and * \f$ \bigcup_i \{x_i\} \subseteq \bigcup_j \{v_j\}\f$ * (no other value occurs). * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a c and \a v are of different size. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntSetArgs& c, const IntArgs& v, IntPropLevel ipl=IPL_DEF); /** \brief Posts a global count (cardinality) constraint * * Posts the constraint that * \f$\#\{i\in\{0,\ldots,|x|-1\}\;|\;x_i=v_j\}\in c\f$ and * \f$ \bigcup_i \{x_i\} \subseteq \bigcup_j \{v_j\}\f$ * (no other value occurs). * * Supports value (\a ipl = IPL_VAL, default), bounds (\a ipl = IPL_BND), * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a c and \a v are of different size. */ GECODE_INT_EXPORT void count(Home home, const IntVarArgs& x, const IntSet& c, const IntArgs& v, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntNValues Number of values constraints * \ingroup TaskModelInt * * The number of values constraints perform propagation * following: C. Bessiere, E. Hebrard, B. Hnich, Z. Kiziltan, * and T. Walsh, Filtering Algorithms for the NValue * Constraint, Constraints, 11(4), 271-293, 2006. */ //@{ /** \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\sim_{irt} y\f$ * */ GECODE_INT_EXPORT void nvalues(Home home, const IntVarArgs& x, IntRelType irt, int y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\sim_{irt} y\f$ * */ GECODE_INT_EXPORT void nvalues(Home home, const IntVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\sim_{irt} y\f$ * */ GECODE_INT_EXPORT void nvalues(Home home, const BoolVarArgs& x, IntRelType irt, int y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\sim_{irt} y\f$ * */ GECODE_INT_EXPORT void nvalues(Home home, const BoolVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntSequence Sequence constraints * \ingroup TaskModelInt */ //@{ /** \brief Post propagator for \f$\operatorname{sequence}(x,s,q,l,u)\f$ * * Posts a domain consistent propagator for the constraint * \f$\bigwedge_{i=0}^{|x|-q} * \operatorname{among}(\langle x_i,\ldots,x_{i+q-1}\rangle,s,l,u)\f$ * where the among constraint is defined as * \f$l\leq\#\{j\in\{i,\ldots,i+q-1\}\;|\;x_j\in s\} \leq u\f$. * * Throws the following exceptions: * - Of type Int::TooFewArguments, if \f$|x|=0\f$. * - Of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. * - Of type Int::OutOfRange, if \f$q < 1 \vee q > |x|\f$. */ GECODE_INT_EXPORT void sequence(Home home, const IntVarArgs& x, const IntSet& s, int q, int l, int u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\operatorname{sequence}(x,s,q,l,u)\f$ * * Posts a domain consistent propagator for the constraint * \f$\bigwedge_{i=0}^{|x|-q} * \operatorname{among}(\langle x_i,\ldots,x_{i+q-1}\rangle,s,l,u)\f$ * where the among constraint is defined as * \f$l\leq\#\{j\in\{i,\ldots,i+q-1\}\;|\;x_j\in s\} \leq u\f$. * * Throws the following exceptions: * - Of type Int::TooFewArguments, if \f$|x|=0\f$. * - Of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. * - Of type Int::OutOfRange, if \f$q < 1 \vee q > |x|\f$. */ GECODE_INT_EXPORT void sequence(Home home, const BoolVarArgs& x, const IntSet& s, int q, int l, int u, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntExt Extensional constraints * \ingroup TaskModelInt * * Extensional constraints support different ways of how the * extensionally defined relation between the variables is defined. * Examples include specification by a %DFA or a table. * * A %DFA can be defined by a regular expression, for regular expressions * see the module MiniModel. */ /** * \brief Deterministic finite automaton (%DFA) * * After initialization, the start state is always zero. * The final states are contiguous ranging from the first to the * last final state. * * \ingroup TaskModelIntExt */ class DFA : public SharedHandle { private: /// Implementation of DFA class DFAI; /// Test whether DFA is equal to \a d GECODE_INT_EXPORT bool equal(const DFA& d) const; public: /// Specification of a %DFA transition class Transition { public: int i_state; ///< input state int symbol; ///< symbol int o_state; ///< output state /// Default constructor Transition(void); /// Initialize members Transition(int i_state0, int symbol0, int o_state0); }; /// Iterator for %DFA transitions (sorted by symbols) class Transitions { private: /// Current transition const Transition* c_trans; /// End of transitions const Transition* e_trans; public: /// Initialize to all transitions of DFA \a d Transitions(const DFA& d); /// Initialize to transitions of DFA \a d for symbol \a n Transitions(const DFA& d, int n); /// Test whether iterator still at a transition bool operator ()(void) const; /// Move iterator to next transition void operator ++(void); /// Return in-state of current transition int i_state(void) const; /// Return symbol of current transition int symbol(void) const; /// Return out-state of current transition int o_state(void) const; }; /// Iterator for %DFA symbols class Symbols { private: /// Current transition const Transition* c_trans; /// End of transitions const Transition* e_trans; public: /// Initialize to symbols of DFA \a d Symbols(const DFA& d); /// Test whether iterator still at a symbol bool operator ()(void) const; /// Move iterator to next symbol void operator ++(void); /// Return current symbol int val(void) const; }; /** * \brief Initialize DFA * * - Start state is given by \a s. * - %Transitions are described by \a t, where the last element * must have -1 as value for \c i_state. * - Final states are given by \a f, where the last final element * must be -1. * - Minimizes the DFA, if \a minimize is true. * - Note that the transitions must be deterministic. */ GECODE_INT_EXPORT void init(int s, Transition t[], int f[], bool minimize=true); public: friend class Transitions; /// Initialize for DFA accepting the empty word DFA(void); /** * \brief Initialize DFA * * - Start state is given by \a s. * - %Transitions are described by \a t, where the last element * must have -1 as value for \c i_state. * - Final states are given by \a f, where the last final element * must be -1. * - Minimizes the DFA, if \a minimize is true. * - Note that the transitions must be deterministic. */ GECODE_INT_EXPORT DFA(int s, Transition t[], int f[], bool minimize=true); /** * \brief Initialize DFA * * - Start state is given by \a s. * - %Transitions are described by \a t. * - Final states are given by \a f. * - Minimizes the DFA, if \a minimize is true. * - Note that the transitions must be deterministic. */ GECODE_INT_EXPORT DFA(int s, std::initializer_list t, std::initializer_list f, bool minimize=true); /// Initialize by DFA \a d (DFA is shared) DFA(const DFA& d); /// Test whether DFA is equal to \a d GECODE_INT_EXPORT bool operator ==(const DFA& d) const; /// Test whether DFA is not equal to \a d bool operator !=(const DFA& d) const; /// Return the number of states int n_states(void) const; /// Return the number of transitions int n_transitions(void) const; /// Return the number of symbols unsigned int n_symbols(void) const; /// Return maximal degree (in-degree and out-degree) of any state unsigned int max_degree(void) const; /// Return the number of the first final state int final_fst(void) const; /// Return the number of the last final state int final_lst(void) const; /// Return smallest symbol in DFA int symbol_min(void) const; /// Return largest symbol in DFA int symbol_max(void) const; /// Return hash key std::size_t hash(void) const; }; } #include namespace Gecode { /** \brief Class represeting a set of tuples. * * A TupleSet is used for storing an extensional representation of a * constraint. After a TupleSet is finalized, no more tuples may be * added to it. * * \ingroup TaskModelIntExt */ class TupleSet : public SharedHandle { public: /** \brief Type of a tuple * * The arity of the tuple is left implicit. */ typedef int* Tuple; /// Import bit set data type typedef Gecode::Support::BitSetData BitSetData; /// Range information class Range { public: /// Minimum value int min; /// Maximum value int max; /// Begin of supports BitSetData* s; /// Return the width unsigned int width(void) const; /// Return the supports for value \a n const BitSetData* supports(unsigned int n_words, int n) const; }; protected: /// Data about values in the table class ValueData { public: /// Number of ranges unsigned int n; /// Ranges Range* r; /// Find start range for value \a n unsigned int start(int n) const; }; /** * \brief Data stored for a Table * */ class GECODE_VTABLE_EXPORT Data : public SharedHandle::Object { protected: /// Initial number of free tuples static const int n_initial_free = 1024; public: /// Arity int arity; /// Number of words for support unsigned int n_words; /// Number of Tuples int n_tuples; /// Number of free tuple entries of arity int n_free; /// Smallest value int min; /// Largest value int max; /// Hash key std::size_t key; /// Tuple data int* td; /// Value data ValueData* vd; /// Pointer to all ranges Range* range; /// Pointer to all support data BitSetData* support; /// Return newly added tuple Tuple add(void); /// Return tuple with number \a i Tuple get(int i) const; /// Set bit \a n in bitset data \a d static void set(BitSetData* d, unsigned int n); /// Get bit \a n in bitset data \a d static bool get(const BitSetData* d, unsigned int n); /// Map tuple address to index unsigned int tuple2idx(Tuple t) const; /// Return first range for position \a i const Range* fst(int i) const; /// Return last range for position \a i const Range* lst(int i) const; /// Finalize datastructure (disallows additions of more Tuples) GECODE_INT_EXPORT void finalize(void); /// Resize tuple data GECODE_INT_EXPORT void resize(void); /// Is datastructure finalized bool finalized(void) const; /// Initialize as empty tuple set with arity \a a Data(int a); /// Delete implementation GECODE_INT_EXPORT virtual ~Data(void); }; /// Get data (must be initialized and finalized) Data& data(void) const; /// Get raw data (must be initialized) Data& raw(void) const; /// Add tuple \a t to tuple set GECODE_INT_EXPORT void _add(const IntArgs& t); /// Test whether tuple set is equal to \a t GECODE_INT_EXPORT bool equal(const TupleSet& t) const; public: /// \name Initialization //@{ /// Construct an unitialized tuple set TupleSet(void); /// Initialize for a tuple set with arity \a a GECODE_INT_EXPORT TupleSet(int a); /// Initialize an uninitialized tuple set GECODE_INT_EXPORT void init(int a); /// Initialize by TupleSet \a t (tuple set is shared) GECODE_INT_EXPORT TupleSet(const TupleSet& t); /// Assignment operator GECODE_INT_EXPORT TupleSet& operator =(const TupleSet& t); /// Initialize with DFA \a dfa for arity \a a GECODE_INT_EXPORT TupleSet(int a, const DFA& dfa); /// Test whether tuple set has been initialized operator bool(void) const; /// Test whether tuple set is equal to \a t bool operator ==(const TupleSet& t) const; /// Test whether tuple set is different from \a t bool operator !=(const TupleSet& t) const; //@} /// \name Addition and finalization //@{ /// Add tuple \a t to tuple set TupleSet& add(const IntArgs& t); /// Is tuple set finalized bool finalized(void) const; /// Finalize tuple set void finalize(void); //@} /// \name Tuple access //@{ /// Arity of tuple set int arity(void) const; /// Number of tuples int tuples(void) const; /// Return number of required bit set words unsigned int words(void) const; /// Get tuple \a i Tuple operator [](int i) const; /// Return minimal value in all tuples int min(void) const; /// Return maximal value in all tuples int max(void) const; /// Return hash key std::size_t hash(void) const; //@} /// \name Range access and iteration //@{ /// Return first range for position \a i const Range* fst(int i) const; /// Return last range for position \a i const Range* lst(int i) const; /// Iterator over ranges class Ranges { protected: /// Current range const Range* c; /// Last range const Range* l; public: /// \name Constructors and initialization //@{ /// Initialize for column \a i Ranges(const TupleSet& ts, int i); //@} /// \name Iteration control //@{ /// Test whether iterator is still at a range bool operator ()(void) const; /// Move iterator to next range (if possible) void operator ++(void); //@} /// \name %Range access //@{ /// Return smallest value of range int min(void) const; /// Return largest value of range int max(void) const; /// Return width of range (distance between minimum and maximum) unsigned int width(void) const; //@} }; //@} }; } #include namespace Gecode { /** * \brief Post domain consistent propagator for extensional constraint described by a DFA * * The elements of \a x must be a word of the language described by * the DFA \a d. * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. If shared occurences of variables * are required, unshare should be used. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const IntVarArgs& x, DFA d, IntPropLevel ipl=IPL_DEF); /** * \brief Post domain consistent propagator for extensional constraint described by a DFA * * The elements of \a x must be a word of the language described by * the DFA \a d. * * Throws an exception of type Int::ArgumentSame, if \a x contains * the same unassigned variable multiply. If shared occurences of variables * are required, unshare should be used. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const BoolVarArgs& x, DFA d, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x\in t\f$. * * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ void extensional(Home home, const IntVarArgs& x, const TupleSet& t, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x\in t\f$ or \f$x\not\in t\f$. * * \li If \a pos is true, it posts a propagator for \f$x\in t\f$ * and otherwise for \f$x\not\in t\f$. * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const IntVarArgs& x, const TupleSet& t, bool pos, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$(x\in t)\equiv r\f$. * * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ void extensional(Home home, const IntVarArgs& x, const TupleSet& t, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$(x\in t)\equiv r\f$ or \f$(x\not\in t)\equiv r\f$. * * \li If \a pos is true, it posts a propagator for \f$(x\in t)\equiv r\f$ * and otherwise for \f$(x\not\in t)\equiv r\f$. * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const IntVarArgs& x, const TupleSet& t, bool pos, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x\in t\f$. * * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ void extensional(Home home, const BoolVarArgs& x, const TupleSet& t, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x\in t\f$ or \f$x\not\in t\f$. * * \li If \a pos is true, it posts a propagator for \f$x\in t\f$ * and otherwise for \f$x\not\in t\f$. * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const BoolVarArgs& x, const TupleSet& t, bool pos, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$(x\in t)\equiv r\f$. * * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ void extensional(Home home, const BoolVarArgs& x, const TupleSet& t, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$(x\in t)\equiv r\f$ or \f$(x\not\in t)\equiv r\f$. * * \li If \a pos is true, it posts a propagator for \f$(x\in t)\equiv r\f$ * and otherwise for \f$(x\not\in t)\equiv r\f$. * \li Supports domain consistency (\a ipl = IPL_DOM, default) only. * \li Throws an exception of type Int::ArgumentSizeMismatch, if * \a x and \a t are of different size. * \li Throws an exception of type Int::NotYetFinalized, if the tuple * set \a t has not been finalized. * * \ingroup TaskModelIntExt */ GECODE_INT_EXPORT void extensional(Home home, const BoolVarArgs& x, const TupleSet& t, bool pos, Reify r, IntPropLevel ipl=IPL_DEF); } #include namespace Gecode { /** * \defgroup TaskModelIntArith Arithmetic constraints * \ingroup TaskModelInt */ //@{ /** \brief Post propagator for \f$ \min\{x_0,x_1\}=x_2\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void min(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \min x=y\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. */ GECODE_INT_EXPORT void min(Home home, const IntVarArgs& x, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \max\{x_0,x_1\}=x_2\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void max(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \max x=y\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. */ GECODE_INT_EXPORT void max(Home home, const IntVarArgs& x, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmin}(x)=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmin}(x)+o=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmin(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmax}(x)=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmax}(x)+o=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmax(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmin}(x)=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmin(Home home, const BoolVarArgs& x, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmin}(x)-o=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmin(Home home, const BoolVarArgs& x, int o, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmax}(x)=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmax(Home home, const BoolVarArgs& x, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ \operatorname{argmax}(x)-o=y\f$ * * In case of ties, the smallest value for \a y is chosen * (provided \a tiebreak is true). * * If \a x is empty, an exception of type Int::TooFewArguments is thrown. * If \a y occurs in \a x, an exception of type Int::ArgumentSame * is thrown. */ GECODE_INT_EXPORT void argmax(Home home, const BoolVarArgs& x, int o, IntVar y, bool tiebreak=true, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$ |x_0|=x_1\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void abs(Home home, IntVar x0, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0\cdot x_1=x_2\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void mult(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0\ \mathrm{div}\ x_1=x_2 \land x_0\ \mathrm{mod}\ x_1 = x_3\f$ * * Supports bounds consistency (\a ipl = IPL_BND, default). */ GECODE_INT_EXPORT void divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0\ \mathrm{div}\ x_1=x_2\f$ * * Supports bounds consistency (\a ipl = IPL_BND, default). */ GECODE_INT_EXPORT void div(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0\ \mathrm{mod}\ x_1=x_2\f$ * * Supports bounds consistency (\a ipl = IPL_BND, default). */ GECODE_INT_EXPORT void mod(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0^2=x_1\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void sqr(Home home, IntVar x0, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\lfloor\sqrt{x_0}\rfloor=x_1\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). */ GECODE_INT_EXPORT void sqrt(Home home, IntVar x0, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$x_0^n=x_1\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::OutOfLimits, if \a n is * negative. */ GECODE_INT_EXPORT void pow(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\lfloor\sqrt[n]{x_0}\rfloor=x_1\f$ * * Supports both bounds consistency (\a ipl = IPL_BND, default) * and domain consistency (\a ipl = IPL_DOM). * * Throws an exception of type Int::OutOfLimits, if \a n is * not strictly positive. */ GECODE_INT_EXPORT void nroot(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntLI Linear constraints over integer variables * \ingroup TaskModelInt * * All variants for linear constraints over integer variables share * the following properties: * - Bounds consistency (over the real numbers) is supported for * all constraints (actually, for disequlities always domain consistency * is used as it is cheaper). Domain consistency is supported for all * non-reified constraint. As bounds consistency for inequalities * coincides with domain consistency, the only * real variation is for linear equations. Domain consistent * linear equations have exponential complexity, so use with care! * - If the integer propagation level IPL_DEF is used as argument * (hence, default propagation) and the linear constraint is sufficiently * simple (two variables with unit coefficients), the domain * consistent propagation is used. * - Variables occurring multiply in the argument arrays are replaced * by a single occurrence: for example, \f$ax+bx\f$ becomes * \f$(a+b)x\f$. * - If in the above simplification the value for \f$(a+b)\f$ (or for * \f$a\f$ and \f$b\f$) exceeds the limits for integers as * defined in Int::Limits, an exception of type * Int::OutOfLimits is thrown. * - Assume the constraint * \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\f$. * If \f$|c|+\sum_{i=0}^{|x|-1}a_i\cdot x_i\f$ exceeds the maximal * available precision (at least \f$2^{48}\f$), an exception of * type Int::OutOfLimits is thrown. * - In all other cases, the created propagators are accurate (that * is, they will not silently overflow during propagation). */ /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}x_i\sim_{irt} c\f$ * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntVarArgs& x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}x_i\sim_{irt} y\f$ * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}x_i\sim_{irt} c\right)\equiv r\f$ * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntVarArgs& x, IntRelType irt, int c, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}x_i\sim_{irt} y\right)\equiv r\f$ * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntVarArgs& x, IntRelType irt, IntVar y, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const IntVarArgs& x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} y\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const IntVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\right)\equiv r\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const IntVarArgs& x, IntRelType irt, int c, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} y\right)\equiv r\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLI */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const IntVarArgs& x, IntRelType irt, IntVar y, Reify r, IntPropLevel ipl=IPL_DEF); /** * \defgroup TaskModelIntLB Linear constraints over Boolean variables * \ingroup TaskModelInt * * All variants for linear constraints over Boolean variables share * the following properties: * - Bounds consistency (over the real numbers) is supported for * all constraints (actually, for disequlities always domain consistency * is used as it is cheaper). * - Variables occurring multiply in the argument arrays are replaced * by a single occurrence: for example, \f$ax+bx\f$ becomes * \f$(a+b)x\f$. * - If in the above simplification the value for \f$(a+b)\f$ (or for * \f$a\f$ and \f$b\f$) exceeds the limits for integers as * defined in Int::Limits, an exception of type * Int::OutOfLimits is thrown. * - Assume the constraint * \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\f$. * If \f$|c|+\sum_{i=0}^{|x|-1}a_i\cdot x_i\f$ exceeds the limits * for integers as defined in Int::Limits, an exception of * type Int::OutOfLimits is thrown. * - In all other cases, the created propagators are accurate (that * is, they will not silently overflow during propagation). */ /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}x_i\sim_{irt} c\f$ * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const BoolVarArgs& x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}x_i\sim_{irt} c\right)\equiv r\f$ * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const BoolVarArgs& x, IntRelType irt, int c, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}x_i\sim_{irt} y\f$ * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const BoolVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}x_i\sim_{irt} y\right)\equiv r\f$ * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const BoolVarArgs& x, IntRelType irt, IntVar y, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const BoolVarArgs& x, IntRelType irt, int c, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} c\right)\equiv r\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const BoolVarArgs& x, IntRelType irt, int c, Reify r, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} y\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator for \f$\left(\sum_{i=0}^{|x|-1}a_i\cdot x_i\sim_{irt} y\right)\equiv r\f$ * * Throws an exception of type Int::ArgumentSizeMismatch, if * \a a and \a x are of different size. * \ingroup TaskModelIntLB */ GECODE_INT_EXPORT void linear(Home home, const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y, Reify r, IntPropLevel ipl=IPL_DEF); /** * \defgroup TaskModelIntBinPacking Bin packing constraints * \ingroup TaskModelInt * */ /** \brief Post propagator for bin packing * * The variables in \a l are the loads for each bin, whereas the * variables in \a b define for each item into which bin it is packed. * The integer values \a s define the size of the items. * * It is propagated that for each \f$j\f$ with \f$0\leq j<|l|\f$ the * constraint \f$l_j=\sum_{0\leq i<|b|\wedge b_i=j}s_i\f$ holds and that * for each \f$i\f$ with \f$0\leq i<|b|\f$ the constraint * \f$0\leq b_i<|l|\f$ holds. * * The propagation follows: Paul Shaw. A Constraint for Bin Packing. CP 2004. * * Throws the following exceptions: * - Of type Int::ArgumentSizeMismatch if \a b and \a s are not of * the same size. * - Of type Int::ArgumentSame if \a l and \a b share unassigned variables. * - Of type Int::OutOfLimits if \a s contains a negative number. * * \ingroup TaskModelIntBinPacking */ GECODE_INT_EXPORT void binpacking(Home home, const IntVarArgs& l, const IntVarArgs& b, const IntArgs& s, IntPropLevel ipl=IPL_DEF); /* \brief Post propagator for multi-dimensional bin packing * * In the following \a n refers to the number of items and \a m * refers to the number of bins. * * The multi-dimensional bin-packing constraint enforces that * all items are packed into bins * \f$b_i\in\{0,\ldots,m-1\}\f$ for \f$0\leq i"A new multi-resource cumulatives constraint * with negative heights", Nicolas Beldiceanu and Mats * Carlsson, Principles and Practice of Constraint Programming 2002. * * The constraint models a set of machines and a set of tasks that * should be assigned to the machines. The machines have a positive * resource limit and the tasks each have a resource usage that can * be either positive, negative, or zero. The constraint is enforced * over each point in time for a machine where there is at least one * task assigned. * * The propagator does not enforce \f$s_i+p_i=e_i\f$, this constraint * has to be posted in addition to ensure consistency of the task bounds. * * The limit for a machine is either the maximum amount available at * any given time (\a at_most = true), or else the least amount to * be used (\a at_most = false). * * \param home current space * \param m \f$ m_i \f$ is the machine assigned to task \f$ i \f$ * \param s \f$ s_i \f$ is the start time assigned to task \f$ i \f$ * \param p \f$ p_i \f$ is the processing time of task \f$ i \f$ * \param e \f$ e_i \f$ is the end time assigned to task \f$ i \f$ * \param u \f$ u_i \f$ is the amount of * resources consumed by task \f$ i \f$ * \param c \f$ c_r \f$ is the capacity, the amount of resource available * for machine \f$ r \f$ * \param at_most \a at_most tells if the amount of resources used * for a machine should be less than the limit (\a at_most * = true) or greater than the limit (\a at_most = false) * \param ipl Supports value-consistency only (\a ipl = IPL_VAL, default). * * \exception Int::ArgumentSizeMismatch thrown if the sizes * of the arguments representing tasks does not match. * \exception Int::OutOfLimits thrown if any numerical argument is * larger than Int::Limits::max or less than * Int::Limits::min. */ GECODE_INT_EXPORT void cumulatives(Home home, const IntVarArgs& m, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntVarArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntArgs& m, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntVarArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntVarArgs& m, const IntVarArgs& s, const IntArgs& p, const IntVarArgs& e, const IntVarArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntArgs& m, const IntVarArgs& s, const IntArgs& p, const IntVarArgs& e, const IntVarArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntVarArgs& m, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntArgs& m, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntVarArgs& m, const IntVarArgs& s, const IntArgs& p, const IntVarArgs& e, const IntArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for the cumulatives constraint. * * \copydoc cumulatives() */ GECODE_INT_EXPORT void cumulatives(Home home, const IntArgs& m, const IntVarArgs& s, const IntArgs& p, const IntVarArgs& e, const IntArgs& u, const IntArgs& c, bool at_most, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on unary resources * * Schedule tasks with start times \a s and processing times \a p * on a unary resource. The propagator uses the algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined (default), all the above listed propagation * is performed. * * Posting the constraint might throw the following exceptions: * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s * and \a p are of different size. * - Throws an exception of type Int::ArgumentSame, if \a s contains * the same unassigned variable multiply. * - Throws an exception of type Int::OutOfLimits, if \a p contains * an integer that is negative or that could generate * an overflow. */ GECODE_INT_EXPORT void unary(Home home, const IntVarArgs& s, const IntArgs& p, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on unary resources * * Schedule optional tasks with start times \a s, processing times \a p, * and whether a task is mandatory \a m (a task is mandatory if the * Boolean variable is 1) on a unary resource. The propagator uses the * algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined (default), all the above listed propagation * is performed. * * Posting the constraint might throw the following exceptions: * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s, * \a p, or \a m are of different size. * - Throws an exception of type Int::ArgumentSame, if \a s contains * the same unassigned variable multiply. * - Throws an exception of type Int::OutOfLimits, if \a p contains * an integer that is negative or that could generate * an overflow. */ GECODE_INT_EXPORT void unary(Home home, const IntVarArgs& s, const IntArgs& p, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on unary resources * * Schedule tasks with flexible times \a flex and fixed times \a fix * on a unary resource. For each * task, it depends on \a t how the flexible and fix times are interpreted: * - If t[i] is TT_FIXP, then * flex[i] is the start time and fix[i] is the * processing time. * - If t[i] is TT_FIXS, then * flex[i] is the end time and fix[i] is the * start time. * - If t[i] is TT_FIXE, then * flex[i] is the start time and fix[i] is the * end time. * * The propagator uses the algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined (default), all the above listed propagation * is performed. * * Posting the constraint might throw the following exceptions: * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s * and \a p are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p contains * an integer that is negative for a task with type TT_FIXP * or that could generate an overflow. */ GECODE_INT_EXPORT void unary(Home home, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on unary resources * * Schedule optional tasks with flexible times \a flex, fixed times \a fix, * and whether a task is mandatory \a m (a task is mandatory if the * Boolean variable is 1) on a unary resource. For each * task, it depends on \a t how the flexible and fix times are interpreted: * - If t[i] is TT_FIXP, then * flex[i] is the start time and fix[i] is the * processing time. * - If t[i] is TT_FIXS, then * flex[i] is the end time and fix[i] is the * start time. * - If t[i] is TT_FIXE, then * flex[i] is the start time and fix[i] is the * end time. * * The propagator uses the * algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined (default), all the above listed propagation * is performed. * * Posting the constraint might throw the following exceptions: * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s, * \a p, or \a m are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p contains * an integer that is negative for a task with type TT_FIXP * or that could generate an overflow. */ GECODE_INT_EXPORT void unary(Home home, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on unary resources * * Schedule tasks with start times \a s, processing times \a p, and * end times \a e * on a unary resource. The propagator uses the algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator does not enforce \f$s_i+p_i=e_i\f$, this constraint * has to be posted in addition to ensure consistency of the task bounds. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined (default), all the above listed propagation * is performed. * * The processing times are constrained to be non-negative. * * Throws an exception of type Int::ArgumentSizeMismatch, if \a s * and \a p are of different size. */ GECODE_INT_EXPORT void unary(Home home, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on unary resources * * Schedule optional tasks with start times \a s, processing times \a p, * end times \a e, * and whether a task is mandatory \a m (a task is mandatory if the * Boolean variable is 1) on a unary resource. The propagator uses the * algorithms from: * Petr Vilím, Global Constraints in Scheduling, PhD thesis, * Charles University, Prague, Czech Republic, 2007. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking, * detectable precendence propagation, not-first-not-last propagation, * and edge finding. * - If both flags are combined, all the above listed propagation is * performed (default). * * The propagator does not enforce \f$s_i+p_i=e_i\f$, this constraint * has to be posted in addition to ensure consistency of the task bounds. * * The processing times are constrained to be non-negative. * * Throws an exception of type Int::ArgumentSizeMismatch, if \a s, * \a p, or \a m are of different size. */ GECODE_INT_EXPORT void unary(Home home, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * * Schedule tasks with flexible times \a flex, fixed times \a fix, and * use capacity \a u on a cumulative resource with capacity \a c. For each * task, it depends on \a t how the flexible and fix times are interpreted: * - If t[i] is TT_FIXP, then * flex[i] is the start time and fix[i] is the * processing time. * - If t[i] is TT_FIXS, then * flex[i] is the end time and fix[i] is the * start time. * - If t[i] is TT_FIXE, then * flex[i] is the start time and fix[i] is the * end time. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a t, \a s * \a p, or \a u are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p, \a u, or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * * \copydoc cumulative(Home,int,const TaskTypeArgs&,const IntVarArgs&,const IntArgs&,const IntArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * * Schedule tasks with flexible times \a flex, fixed times \a fix, * use capacity \a u, and whether a task is mandatory \a m (a task is * mandatory if the Boolean variable is 1) on a cumulative resource with * capacity \a c. For each * task, it depends on \a t how the flexible and fix times are interpreted: * - If t[i] is TT_FIXP, then * flex[i] is the start time and fix[i] is the * processing time. * - If t[i] is TT_FIXS, then * flex[i] is the end time and fix[i] is the * start time. * - If t[i] is TT_FIXE, then * flex[i] is the start time and fix[i] is the * end time. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a t, \a s * \a p, or \a u are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p, \a u, or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * \copydoc cumulative(Home,int,const TaskTypeArgs&,const IntVarArgs&,const IntArgs&,const IntArgs&,const BoolVarArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * * Schedule tasks with start times \a s, processing times \a p, and * use capacity \a u on a cumulative resource with capacity \a c. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s * \a p, or \a u are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p, \a u, or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const IntVarArgs& s, const IntArgs& p, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * \copydoc cumulative(Home,int,const IntVarArgs&,const IntArgs&,const IntArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const IntVarArgs& s, const IntArgs& p, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * * Schedule optional tasks with start times \a s, processing times \a p, * used capacity \a u, and whether a task is mandatory \a m (a task is * mandatory if the Boolean variable is 1) on a cumulative resource * with capacity \a c. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s, * \a p, \a u, or \a m are of different size. * - Throws an exception of type Int::OutOfLimits, if \a p, \a u, or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const IntVarArgs& s, const IntArgs& p, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * \copydoc cumulative(Home,int,const IntVarArgs&,const IntArgs&,const IntArgs&,const BoolVarArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const IntVarArgs& s, const IntArgs& p, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * * Schedule tasks with start times \a s, processing times \a p, * end times \a e, and * use capacity \a u on a cumulative resource with capacity \a c. * * The propagator does not enforce \f$s_i+p_i=e_i\f$, this constraint * has to be posted in addition to ensure consistency of the task bounds. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s * \a p, or \a u are of different size. * - Throws an exception of type Int::OutOfLimits, if \a u or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling tasks on cumulative resources * \copydoc cumulative(Home,int,const IntVarArgs&,const IntVarArgs&,const IntVarArgs&,const IntArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * * Schedule optional tasks with start times \a s, processing times \a p, * end times \a e, * used capacity \a u, and whether a task is mandatory \a m (a task is * mandatory if the Boolean variable is 1) on a cumulative resource * with capacity \a c. * * The propagator does not enforce \f$s_i+p_i=e_i\f$, this constraint * has to be posted in addition to ensure consistency of the task bounds. * * The propagator performs propagation that depends on the integer * propagation level \a ipl as follows: * - If \a IPL_BASIC is set, the propagator performs overload checking * and time-tabling propagation. * - If \a IPL_ADVANCED is set, the propagator performs overload checking * and edge finding. * - If both flags are combined, all the above listed propagation is * performed. * * The propagator uses algorithms taken from: * * Petr Vilím, Max Energy Filtering Algorithm for Discrete Cumulative * Resources, in W. J. van Hoeve and J. N. Hooker, editors, CPAIOR, volume * 5547 of LNCS, pages 294-308. Springer, 2009. * * and * * Petr Vilím, Edge finding filtering algorithm for discrete cumulative * resources in O(kn log n). In I. P. Gent, editor, CP, volume 5732 of LNCS, * pages 802-816. Springer, 2009. * * - Throws an exception of type Int::ArgumentSizeMismatch, if \a s, * \a p, \a u, or \a m are of different size. * - Throws an exception of type Int::OutOfLimits, if \a u or \a c * contain an integer that is not nonnegative, or that could generate * an overflow. */ GECODE_INT_EXPORT void cumulative(Home home, int c, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); /** \brief Post propagators for scheduling optional tasks on cumulative resources * \copydoc cumulative(Home,int,const IntVarArgs&,const IntVarArgs&,const IntVarArgs&,const IntArgs&,const BoolVarArgs&,IntPropLevel) */ GECODE_INT_EXPORT void cumulative(Home home, IntVar c, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntGraph Graph constraints * \ingroup TaskModelInt */ //@{ /** \brief Post propagator such that \a x forms a circuit * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_i=j\f$ has a single cycle covering all nodes. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. */ GECODE_INT_EXPORT void circuit(Home home, const IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a circuit * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_{i-\text{offset}}=j\f$ has a single cycle covering all nodes. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void circuit(Home home, int offset, const IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a circuit with costs \a y and \a z * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_i=j\f$ has a single cycle covering all nodes. * The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire circuit. The variables \a y define the cost * of the edge in \a x: that is, if \f$x_i=j\f$ then \f$y_i=c_{i*n+j}\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismatch, if \a x and \a y do not have the same * size or if \f$|x|\times|x|\neq|c|\f$. */ GECODE_INT_EXPORT void circuit(Home home, const IntArgs& c, const IntVarArgs& x, const IntVarArgs& y, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a circuit with costs \a y and \a z * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_{i-\text{offset}}=j\f$ has a single cycle covering all nodes. * The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire circuit. The variables \a y define the cost * of the edge in \a x: that is, if \f$x_i=j\f$ then \f$y_i=c_{i*n+j}\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismatch, if \a x and \a y do not have the same * size or if \f$|x|\times|x|\neq|c|\f$. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void circuit(Home home, const IntArgs& c, int offset, const IntVarArgs& x, const IntVarArgs& y, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a circuit with cost \a z * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_i=j\f$ has a single cycle covering all nodes. The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire circuit. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismatch, if \f$|x|\times|x|\neq|c|\f$. */ GECODE_INT_EXPORT void circuit(Home home, const IntArgs& c, const IntVarArgs& x, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a circuit with cost \a z * * \a x forms a circuit if the graph with edges \f$i\to j\f$ where * \f$x_{i-\text{offset}}=j\f$ has a single cycle covering all nodes. * The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire circuit. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismatch, if \f$|x|\times|x|\neq|c|\f$. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void circuit(Home home, const IntArgs& c, int offset, const IntVarArgs& x, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_i=j\f$ visits all nodes exactly once. The path starts at * node \a s and the successor of the last node \a e is equal to \f$|x|\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. */ GECODE_INT_EXPORT void path(Home home, const IntVarArgs& x, IntVar s, IntVar e, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_{i-\text{offset}}=j\f$ visits all nodes exactly once. * The path starts at node \a s and the successor of the last node \a e * is equal to \f$|x|+\text{offset}\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void path(Home home, int offset, const IntVarArgs& x, IntVar s, IntVar e, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path with costs \a y and \a z * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_i=j\f$ visits all nodes exactly once. The path starts at node * \a s and the successor of * the last node \a e is equal to \f$|x|\f$. The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire path. The variables \a y define the cost * of the edge in \a x: that is, if \f$x_i=j\f$ then \f$y_i=c_{i*n+j}\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismacth, if \a x and \a y do not have the same * size or if \f$|x|\times|x|\neq|c|\f$. */ GECODE_INT_EXPORT void path(Home home, const IntArgs& c, const IntVarArgs& x, IntVar s, IntVar e, const IntVarArgs& y, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path with costs \a y and \a z * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_{i-\text{offset}}=j\f$ visits all nodes exactly once. * The path starts at node \a s and the successor of * the last node \a e is equal to \f$|x|+\text{offset}\f$. * The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire path. The variables \a y define the cost * of the edge in \a x: that is, if \f$x_i=j\f$ then \f$y_i=c_{i*n+j}\f$. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismacth, if \a x and \a y do not have the same * size or if \f$|x|\times|x|\neq|c|\f$. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void path(Home home, const IntArgs& c, int offset, const IntVarArgs& x, IntVar s, IntVar e, const IntVarArgs& y, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path with cost \a z * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_i=j\f$ visits all nodes exactly once. The path starts at node * \a s and the successor of * the last node \a e is equal to \f$|x|\f$. The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire path. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismacth, if \f$|x|\times|x|\neq|c|\f$. */ GECODE_INT_EXPORT void path(Home home, const IntArgs& c, const IntVarArgs& x, IntVar s, IntVar e, IntVar z, IntPropLevel ipl=IPL_DEF); /** \brief Post propagator such that \a x forms a Hamiltonian path with cost \a z * * \a x forms a Hamiltonian path if the graph with edges \f$i\to j\f$ * where \f$x_{i-\text{offset}}=j\f$ visits all nodes exactly once. * The path starts at node \a s and the successor of * the last node \a e is equal to \f$|x|+\text{offset}\f$. * The integer array * \a c gives the costs of all possible edges where \f$c_{i*|x|+j}\f$ is * the cost of the edge \f$i\to j\f$. The variable \a z is the cost of * the entire circuit. * * Supports domain (\a ipl = IPL_DOM) and value propagation (all * other values for \a ipl), where this refers to whether value or * domain consistent distinct in enforced on \a x for circuit. * * Throws the following exceptions: * - Int::ArgumentSame, if \a x contains the same unassigned variable * multiply. * - Int::TooFewArguments, if \a x has no elements. * - Int::ArgumentSizeMismacth, if \f$|x|\times|x|\neq|c|\f$. * - Int::OutOfLimits, if \a offset is negative. */ GECODE_INT_EXPORT void path(Home home, const IntArgs& c, int offset, const IntVarArgs& x, IntVar s, IntVar e, IntVar z, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntExec Synchronized execution * \ingroup TaskModelInt * * Synchronized execution executes a function or a static member function * when a certain event happends. */ //@{ /// Execute \a c when \a x becomes assigned GECODE_INT_EXPORT void wait(Home home, IntVar x, std::function c, IntPropLevel ipl=IPL_DEF); /// Execute \a c when \a x becomes assigned GECODE_INT_EXPORT void wait(Home home, BoolVar x, std::function c, IntPropLevel ipl=IPL_DEF); /// Execute \a c when all variables in \a x become assigned GECODE_INT_EXPORT void wait(Home home, const IntVarArgs& x, std::function c, IntPropLevel ipl=IPL_DEF); /// Execute \a c when all variables in \a x become assigned GECODE_INT_EXPORT void wait(Home home, const BoolVarArgs& x, std::function c, IntPropLevel ipl=IPL_DEF); /// Execute \a t (then) when \a x is assigned one, and \a e (else) otherwise GECODE_INT_EXPORT void when(Home home, BoolVar x, std::function t, std::function e, IntPropLevel ipl=IPL_DEF); /// Execute \a t (then) when \a x is assigned one GECODE_INT_EXPORT void when(Home home, BoolVar x, std::function t, IntPropLevel ipl=IPL_DEF); //@} /** * \defgroup TaskModelIntUnshare Unsharing variables * \ingroup TaskModelInt * * Unsharing replaces multiple occurences of the same variable by * fresh yet equal (enforced through propagators for equality) * variables: after unsharing a variable appears at most once. Note * that this is only done for not yet assigned variables (as all * propagators can handle multiple occurences of the same variable * provided it is already assigned). * * Unsharing is useful for constraints that only accept variable * arrays without multiple occurences of the same variable, for * example extensional. * */ //@{ /** * \brief Replace multiple variable occurences in \a x by fresh variables * * Supports domain consistency (\a ipl = IPL_DOM, default) and * bounds consistency (\a ipl = IPL_BND). * */ GECODE_INT_EXPORT void unshare(Home home, IntVarArgs& x, IntPropLevel ipl=IPL_DEF); /// Replace multiple variable occurences in \a x by fresh variables GECODE_INT_EXPORT void unshare(Home home, BoolVarArgs& x, IntPropLevel ipl=IPL_DEF); //@} } namespace Gecode { /** * \defgroup TaskModelIntBranch Branching * \ingroup TaskModelInt */ /** * \brief Branch filter function type for integer variables * * The variable \a x is considered for selection and \a i refers to the * variable's position in the original array passed to the brancher. * * \ingroup TaskModelIntBranch */ typedef std::function IntBranchFilter; /** * \brief Branch filter function type for Boolean variables * * The variable \a x is considered for selection and \a i refers to the * variable's position in the original array passed to the brancher. * * \ingroup TaskModelIntBranch */ typedef std::function BoolBranchFilter; /** * \brief Branch merit function type for integer variables * * The function must return a merit value for the variable * \a x. The integer \a i refers to the variable's position * in the original array passed to the brancher. * * \ingroup TaskModelIntBranch */ typedef std::function IntBranchMerit; /** * \brief Branch merit function type for Boolean variables * * The function must return a merit value for the variable * \a x. The integer \a i refers to the variable's position * in the original array passed to the brancher. * * \ingroup TaskModelIntBranch */ typedef std::function BoolBranchMerit; /** * \brief Branch value function type for integer variables * * Returns a value for the variable \a x that is to be used in the * corresponding branch commit function. The integer \a i refers * to the variable's position in the original array passed to the * brancher. * * \ingroup TaskModelIntBranch */ typedef std::function IntBranchVal; /** * \brief Branch value function type for Boolean variables * * Returns a value for the variable \a x that is to be used in the * corresponding branch commit function. The integer \a i refers * to the variable's position in the original array passed to the * brancher. * * \ingroup TaskModelIntBranch */ typedef std::function BoolBranchVal; /** * \brief Branch commit function type for integer variables * * The function must post a constraint on the variable \a x which * corresponds to the alternative \a a. The integer \a i refers * to the variable's position in the original array passed to the * brancher. The value \a n is the value * computed by the corresponding branch value function. * * \ingroup TaskModelIntBranch */ typedef std::function IntBranchCommit; /** * \brief Branch commit function type for Boolean variables * * The function must post a constraint on the variable \a x which * corresponds to the alternative \a a. The integer \a i refers * to the variable's position in the original array passed to the * brancher. The value \a n is the value * computed by the corresponding branch value function. * * \ingroup TaskModelIntBranch */ typedef std::function BoolBranchCommit; } #include namespace Gecode { /** * \brief Recording AFC information for integer variables * * \ingroup TaskModelIntBranch */ class IntAFC : public AFC { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized AFC storage is init or the assignment operator. * */ IntAFC(void); /// Copy constructor IntAFC(const IntAFC& a); /// Assignment operator IntAFC& operator =(const IntAFC& a); /** * \brief Initialize for integer variables \a x and decay factor \a d * * If several AFC objects are created for a space or its clones, * the AFC values are shared between spaces. If the values should * not be shared, \a share should be false. */ IntAFC(Home home, const IntVarArgs& x, double d=1.0, bool share=true); /** * \brief Initialize for integer variables \a x with decay factor \a d * * This member function can only be used once and only if the * AFC storage has been constructed with the default constructor. * * If several AFC objects are created for a space or its clones, * the AFC values are shared between spaces. If the values should * not be shared, \a share should be false. */ void init(Home home, const IntVarArgs& x, double d=1.0, bool share=true); }; /** * \brief Recording AFC information for Boolean variables * * \ingroup TaskModelIntBranch */ class BoolAFC : public AFC { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized AFC storage is init or the assignment operator. * */ BoolAFC(void); /// Copy constructor BoolAFC(const BoolAFC& a); /// Assignment operator BoolAFC& operator =(const BoolAFC& a); /** * \brief Initialize for Boolean variables \a x and decay factor \a d * * If several AFC objects are created for a space or its clones, * the AFC values are shared between spaces. If the values should * not be shared, \a share should be false. */ BoolAFC(Home home, const BoolVarArgs& x, double d=1.0, bool share=true); /** * \brief Initialize for Boolean variables \a x with decay factor \a d * * This member function can only be used once and only if the * AFC storage has been constructed with the default constructor. * * If several AFC objects are created for a space or its clones, * the AFC values are shared between spaces. If the values should * not be shared, \a share should be false. */ void init(Home home, const BoolVarArgs& x, double d=1.0, bool share=true); }; } #include namespace Gecode { /** * \brief Recording actions for integer variables * * \ingroup TaskModelIntBranch */ class IntAction : public Action { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized action storage is init or the assignment operator. * */ IntAction(void); /// Copy constructor IntAction(const IntAction& a); /// Assignment operator IntAction& operator =(const IntAction& a); /** * \brief Initialize for integer variables \a x with decay factor \a d * * Counts propagation if \a p is true and failure if \a f is true. * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. */ GECODE_INT_EXPORT IntAction(Home home, const IntVarArgs& x, double d=1.0, bool p=true, bool f=true, IntBranchMerit bm=nullptr); /** * \brief Initialize for integer variables \a x with decay factor \a d * * Counts propagation if \a p is true and failure if \a f is true. * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * * This member function can only be used once and only if the * action storage has been constructed with the default constructor. * */ GECODE_INT_EXPORT void init(Home home, const IntVarArgs& x, double d=1.0, bool p=true, bool f=true, IntBranchMerit bm=nullptr); }; /** * \brief Recording actions for Boolean variables * * \ingroup TaskModelIntBranch */ class BoolAction : public Action { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized action storage is init or the assignment operator. * */ BoolAction(void); /// Copy constructor BoolAction(const BoolAction& a); /// Assignment operator BoolAction& operator =(const BoolAction& a); /** * \brief Initialize for Boolean variables \a x with decay factor \a d * * Counts propagation if \a p is true and failure if \a f is true. * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. */ GECODE_INT_EXPORT BoolAction(Home home, const BoolVarArgs& x, double d=1.0, bool p=true, bool f=true, BoolBranchMerit bm=nullptr); /** * \brief Initialize for Boolean variables \a x with decay factor \a d * * Counts propagation if \a p is true and failure if \a f is true. * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * * This member function can only be used once and only if the * action storage has been constructed with the default constructor. * */ GECODE_INT_EXPORT void init(Home home, const BoolVarArgs& x, double d=1.0, bool p=true, bool f=true, BoolBranchMerit bm=nullptr); }; } #include namespace Gecode { /** * \brief Recording CHB for integer variables * * \ingroup TaskModelIntBranch */ class IntCHB : public CHB { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized CHB storage is init or the assignment operator. * */ IntCHB(void); /// Copy constructor IntCHB(const IntCHB& chb); /// Assignment operator IntCHB& operator =(const IntCHB& chb); /** * \brief Initialize for integer variables \a x * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * */ GECODE_INT_EXPORT IntCHB(Home home, const IntVarArgs& x, IntBranchMerit bm=nullptr); /** * \brief Initialize for integer variables \a x * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * * This member function can only be used once and only if the * action storage has been constructed with the default constructor. * */ GECODE_INT_EXPORT void init(Home home, const IntVarArgs& x, IntBranchMerit bm=nullptr); }; /** * \brief Recording CHB for Boolean variables * * \ingroup TaskModelIntBranch */ class BoolCHB : public CHB { public: /** * \brief Construct as not yet initialized * * The only member functions that can be used on a constructed but not * yet initialized action storage is init or the assignment operator. * */ BoolCHB(void); /// Copy constructor BoolCHB(const BoolCHB& chb); /// Assignment operator BoolCHB& operator =(const BoolCHB& chb); /** * \brief Initialize for Boolean variables \a x * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * */ GECODE_INT_EXPORT BoolCHB(Home home, const BoolVarArgs& x, BoolBranchMerit bm=nullptr); /** * \brief Initialize for Boolean variables \a x * * If the branch merit function \a bm is different from nullptr, the * action for each variable is initialized with the merit returned * by \a bm. * * This member function can only be used once and only if the * action storage has been constructed with the default constructor. * */ GECODE_INT_EXPORT void init(Home home, const BoolVarArgs& x, BoolBranchMerit bm=nullptr); }; } #include namespace Gecode { /// Function type for printing branching alternatives for integer variables typedef std::function IntVarValPrint; /// Function type for printing branching alternatives for Boolean variables typedef std::function BoolVarValPrint; } namespace Gecode { /** * \brief Which integer variable to select for branching * * \ingroup TaskModelIntBranch */ class IntVarBranch : public VarBranch { public: /// Which variable selection enum Select { SEL_NONE = 0, ///< First unassigned SEL_RND, ///< Random (uniform, for tie breaking) SEL_MERIT_MIN, ///< With least merit SEL_MERIT_MAX, ///< With highest merit SEL_DEGREE_MIN, ///< With smallest degree SEL_DEGREE_MAX, ///< With largest degree SEL_AFC_MIN, ///< With smallest accumulated failure count SEL_AFC_MAX, ///< With largest accumulated failure count SEL_ACTION_MIN, ///< With lowest action SEL_ACTION_MAX, ///< With highest action SEL_CHB_MIN, ///< With lowest CHB Q-score SEL_CHB_MAX, ///< With highest CHB Q-score SEL_MIN_MIN, ///< With smallest min SEL_MIN_MAX, ///< With largest min SEL_MAX_MIN, ///< With smallest max SEL_MAX_MAX, ///< With largest max SEL_SIZE_MIN, ///< With smallest domain size SEL_SIZE_MAX, ///< With largest domain size SEL_DEGREE_SIZE_MIN, ///< With smallest degree divided by domain size SEL_DEGREE_SIZE_MAX, ///< With largest degree divided by domain size SEL_AFC_SIZE_MIN, ///< With smallest accumulated failure count divided by domain size SEL_AFC_SIZE_MAX, ///< With largest accumulated failure count divided by domain size SEL_ACTION_SIZE_MIN, ///< With smallest action divided by domain size SEL_ACTION_SIZE_MAX, ///< With largest action divided by domain size SEL_CHB_SIZE_MIN, ///< With smallest CHB Q-score divided by domain size SEL_CHB_SIZE_MAX, ///< With largest CHB Q-score divided by domain size /** \brief With smallest min-regret * * The min-regret of a variable is the difference between the * smallest and second-smallest value still in the domain. */ SEL_REGRET_MIN_MIN, /** \brief With largest min-regret * * The min-regret of a variable is the difference between the * smallest and second-smallest value still in the domain. */ SEL_REGRET_MIN_MAX, /** \brief With smallest max-regret * * The max-regret of a variable is the difference between the * largest and second-largest value still in the domain. */ SEL_REGRET_MAX_MIN, /** \brief With largest max-regret * * The max-regret of a variable is the difference between the * largest and second-largest value still in the domain. */ SEL_REGRET_MAX_MAX }; protected: /// Which variable to select Select s; public: /// Initialize with strategy SEL_NONE IntVarBranch(void); /// Initialize with random number generator \a r IntVarBranch(Rnd r); /// Initialize with selection strategy \a s and tie-break limit function \a t IntVarBranch(Select s, BranchTbl t); /// Initialize with selection strategy \a s, decay factor \a d, and tie-break limit function \a t IntVarBranch(Select s, double d, BranchTbl t); /// Initialize with selection strategy \a s, AFC \a a, and tie-break limit function \a t IntVarBranch(Select s, IntAFC a, BranchTbl t); /// Initialize with selection strategy \a s, action \a a, and tie-break limit function \a t IntVarBranch(Select s, IntAction a, BranchTbl t); /// Initialize with selection strategy \a s, CHB \a c, and tie-break limit function \a t IntVarBranch(Select s, IntCHB c, BranchTbl t); /// Initialize with selection strategy \a s, branch merit function \a mf, and tie-break limit function \a t IntVarBranch(Select s, IntBranchMerit mf, BranchTbl t); /// Return selection strategy Select select(void) const; /// Expand AFC, action, and CHB void expand(Home home, const IntVarArgs& x); }; /** * \brief Which Boolean variable to select for branching * * \ingroup TaskModelIntBranch */ class BoolVarBranch : public VarBranch { public: /// Which variable selection enum Select { SEL_NONE = 0, ///< First unassigned SEL_RND, ///< Random (uniform, for tie breaking) SEL_MERIT_MIN, ///< With least merit SEL_MERIT_MAX, ///< With highest merit SEL_DEGREE_MIN, ///< With smallest degree SEL_DEGREE_MAX, ///< With largest degree SEL_AFC_MIN, ///< With smallest accumulated failure count SEL_AFC_MAX, ///< With largest accumulated failure count SEL_ACTION_MIN, ///< With lowest action SEL_ACTION_MAX, ///< With highest action SEL_CHB_MIN, ///< With lowest CHB SEL_CHB_MAX ///< With highest CHB }; protected: /// Which variable to select Select s; public: /// Initialize with strategy SEL_NONE BoolVarBranch(void); /// Initialize with random number generator \a r BoolVarBranch(Rnd r); /// Initialize with selection strategy \a s and tie-break limit function \a t BoolVarBranch(Select s, BranchTbl t); /// Initialize with selection strategy \a s, decay factor \a d, and tie-break limit function \a t BoolVarBranch(Select s, double d, BranchTbl t); /// Initialize with selection strategy \a s, AFC \a a, and tie-break limit function \a t BoolVarBranch(Select s, BoolAFC a, BranchTbl t); /// Initialize with selection strategy \a s, action \a a, and tie-break limit function \a t BoolVarBranch(Select s, BoolAction a, BranchTbl t); /// Initialize with selection strategy \a s, CHB \a c, and tie-break limit function \a t BoolVarBranch(Select s, BoolCHB c, BranchTbl t); /// Initialize with selection strategy \a s, branch merit function \a mf, and tie-break limit function \a t BoolVarBranch(Select s, BoolBranchMerit mf, BranchTbl t); /// Return selection strategy Select select(void) const; /// Expand decay factor into AFC or action void expand(Home home, const BoolVarArgs& x); }; /** * \defgroup TaskModelIntBranchVar Variable selection for integer and Boolean variables * \ingroup TaskModelIntBranch */ //@{ /// Select first unassigned variable IntVarBranch INT_VAR_NONE(void); /// Select random variable (uniform distribution, for tie breaking) IntVarBranch INT_VAR_RND(Rnd r); /// Select variable with least merit according to branch merit function \a bm IntVarBranch INT_VAR_MERIT_MIN(IntBranchMerit bm, BranchTbl tbl=nullptr); /// Select variable with highest merit according to branch merit function \a bm IntVarBranch INT_VAR_MERIT_MAX(IntBranchMerit bm, BranchTbl tbl=nullptr); /// Select variable with smallest degree IntVarBranch INT_VAR_DEGREE_MIN(BranchTbl tbl=nullptr); /// Select variable with largest degree IntVarBranch INT_VAR_DEGREE_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count with decay factor \a d IntVarBranch INT_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count IntVarBranch INT_VAR_AFC_MIN(IntAFC a, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count with decay factor \a d IntVarBranch INT_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count IntVarBranch INT_VAR_AFC_MAX(IntAFC a, BranchTbl tbl=nullptr); /// Select variable with lowest action with decay factor \a d IntVarBranch INT_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with lowest action IntVarBranch INT_VAR_ACTION_MIN(IntAction a, BranchTbl tbl=nullptr); /// Select variable with highest action with decay factor \a d IntVarBranch INT_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with highest action IntVarBranch INT_VAR_ACTION_MAX(IntAction a, BranchTbl tbl=nullptr); /// Select variable with lowest CHB Q-score IntVarBranch INT_VAR_CHB_MIN(IntCHB c, BranchTbl tbl=nullptr); /// Select variable with lowest CHB Q-score IntVarBranch INT_VAR_CHB_MIN(BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score IntVarBranch INT_VAR_CHB_MAX(IntCHB c, BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score IntVarBranch INT_VAR_CHB_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest min IntVarBranch INT_VAR_MIN_MIN(BranchTbl tbl=nullptr); /// Select variable with largest min IntVarBranch INT_VAR_MIN_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest max IntVarBranch INT_VAR_MAX_MIN(BranchTbl tbl=nullptr); /// Select variable with largest max IntVarBranch INT_VAR_MAX_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest domain size IntVarBranch INT_VAR_SIZE_MIN(BranchTbl tbl=nullptr); /// Select variable with largest domain size IntVarBranch INT_VAR_SIZE_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest degree divided by domain size IntVarBranch INT_VAR_DEGREE_SIZE_MIN(BranchTbl tbl=nullptr); /// Select variable with largest degree divided by domain size IntVarBranch INT_VAR_DEGREE_SIZE_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count divided by domain size with decay factor \a d IntVarBranch INT_VAR_AFC_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count divided by domain size IntVarBranch INT_VAR_AFC_SIZE_MIN(IntAFC a, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count divided by domain size with decay factor \a d IntVarBranch INT_VAR_AFC_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count divided by domain size IntVarBranch INT_VAR_AFC_SIZE_MAX(IntAFC a, BranchTbl tbl=nullptr); /// Select variable with smallest action divided by domain size with decay factor \a d IntVarBranch INT_VAR_ACTION_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with smallest action divided by domain size IntVarBranch INT_VAR_ACTION_SIZE_MIN(IntAction a, BranchTbl tbl=nullptr); /// Select variable with largest action divided by domain size with decay factor \a d IntVarBranch INT_VAR_ACTION_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with largest action divided by domain size IntVarBranch INT_VAR_ACTION_SIZE_MAX(IntAction a, BranchTbl tbl=nullptr); /// Select variable with smallest CHB Q-score divided by domain size IntVarBranch INT_VAR_CHB_SIZE_MIN(IntCHB c, BranchTbl tbl=nullptr); /// Select variable with smallest CHB Q-score divided by domain size IntVarBranch INT_VAR_CHB_SIZE_MIN(BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score divided by domain size IntVarBranch INT_VAR_CHB_SIZE_MAX(IntCHB c, BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score divided by domain size IntVarBranch INT_VAR_CHB_SIZE_MAX(BranchTbl tbl=nullptr); /** \brief Select variable with smallest min-regret * * The min-regret of a variable is the difference between the * smallest and second-smallest value still in the domain. */ IntVarBranch INT_VAR_REGRET_MIN_MIN(BranchTbl tbl=nullptr); /** \brief Select variable with largest min-regret * * The min-regret of a variable is the difference between the * smallest and second-smallest value still in the domain. */ IntVarBranch INT_VAR_REGRET_MIN_MAX(BranchTbl tbl=nullptr); /** \brief Select variable with smallest max-regret * * The max-regret of a variable is the difference between the * largest and second-largest value still in the domain. */ IntVarBranch INT_VAR_REGRET_MAX_MIN(BranchTbl tbl=nullptr); /** \brief Select variable with largest max-regret * * The max-regret of a variable is the difference between the * largest and second-largest value still in the domain. */ IntVarBranch INT_VAR_REGRET_MAX_MAX(BranchTbl tbl=nullptr); /// Select first unassigned variable BoolVarBranch BOOL_VAR_NONE(void); /// Select random variable (uniform distribution, for tie breaking) BoolVarBranch BOOL_VAR_RND(Rnd r); /// Select variable with least merit according to branch merit function \a bm BoolVarBranch BOOL_VAR_MERIT_MIN(BoolBranchMerit bm, BranchTbl tbl=nullptr); /// Select variable with highest merit according to branch merit function \a bm BoolVarBranch BOOL_VAR_MERIT_MAX(BoolBranchMerit bm, BranchTbl tbl=nullptr); /// Select variable with smallest degree BoolVarBranch BOOL_VAR_DEGREE_MIN(BranchTbl tbl=nullptr); /// Select variable with largest degree BoolVarBranch BOOL_VAR_DEGREE_MAX(BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count with decay factor \a d BoolVarBranch BOOL_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with smallest accumulated failure count BoolVarBranch BOOL_VAR_AFC_MIN(BoolAFC a, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count with decay factor \a d BoolVarBranch BOOL_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with largest accumulated failure count BoolVarBranch BOOL_VAR_AFC_MAX(BoolAFC a, BranchTbl tbl=nullptr); /// Select variable with lowest action with decay factor \a d BoolVarBranch BOOL_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with lowest action BoolVarBranch BOOL_VAR_ACTION_MIN(BoolAction a, BranchTbl tbl=nullptr); /// Select variable with highest action with decay factor \a d BoolVarBranch BOOL_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr); /// Select variable with highest action BoolVarBranch BOOL_VAR_ACTION_MAX(BoolAction a, BranchTbl tbl=nullptr); /// Select variable with lowest CHB Q-score BoolVarBranch BOOL_VAR_CHB_MIN(BoolCHB c, BranchTbl tbl=nullptr); /// Select variable with lowest CHB Q-score BoolVarBranch BOOL_VAR_CHB_MIN(BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score BoolVarBranch BOOL_VAR_CHB_MAX(BoolCHB c, BranchTbl tbl=nullptr); /// Select variable with largest CHB Q-score BoolVarBranch BOOL_VAR_CHB_MAX(BranchTbl tbl=nullptr); //@} } #include namespace Gecode { /** * \brief Which values to select for branching first * * \ingroup TaskModelIntBranch */ class IntValBranch : public ValBranch { public: /// Which value selection enum Select { SEL_MIN, ///< Select smallest value SEL_MED, ///< Select greatest value not greater than the median SEL_MAX, ///< Select largest value SEL_RND, ///< Select random value SEL_SPLIT_MIN, ///< Select values not greater than mean of smallest and largest value SEL_SPLIT_MAX, ///< Select values greater than mean of smallest and largest value SEL_RANGE_MIN, ///< Select the smallest range of the variable domain if it has several ranges, otherwise select values not greater than mean of smallest and largest value SEL_RANGE_MAX, ///< Select the largest range of the variable domain if it has several ranges, otherwise select values greater than mean of smallest and largest value SEL_VAL_COMMIT, ///< Select value according to user-defined functions SEL_VALUES_MIN, ///< Select all values starting from smallest SEL_VALUES_MAX ///< Select all values starting from largest }; protected: /// Which value to select Select s; public: /// Initialize with selection strategy \a s IntValBranch(Select s = SEL_MIN); /// Initialize with random number generator \a r IntValBranch(Rnd r); /// Initialize with value function \a f and commit function \a c IntValBranch(IntBranchVal v, IntBranchCommit c); /// Return selection strategy Select select(void) const; }; /** * \brief Which values to select for branching first * * \ingroup TaskModelIntBranch */ class BoolValBranch : public ValBranch { public: /// Which value selection enum Select { SEL_MIN, ///< Select smallest value SEL_MAX, ///< Select largest value SEL_RND, ///< Select random value SEL_VAL_COMMIT ///< Select value according to user-defined functions }; protected: /// Which value to select Select s; public: /// Initialize with selection strategy \a s BoolValBranch(Select s = SEL_MIN); /// Initialize with random number generator \a r BoolValBranch(Rnd r); /// Initialize with value function \a f and commit function \a c BoolValBranch(BoolBranchVal v, BoolBranchCommit c); /// Return selection strategy Select select(void) const; }; /** * \defgroup TaskModelIntBranchVal Value selection for integer and Boolean variables * \ingroup TaskModelIntBranch */ //@{ /// Select smallest value IntValBranch INT_VAL_MIN(void); /// Select greatest value not greater than the median IntValBranch INT_VAL_MED(void); /// Select largest value IntValBranch INT_VAL_MAX(void); /// Select random value IntValBranch INT_VAL_RND(Rnd r); /// Select values not greater than mean of smallest and largest value IntValBranch INT_VAL_SPLIT_MIN(void); /// Select values greater than mean of smallest and largest value IntValBranch INT_VAL_SPLIT_MAX(void); /// Select the smallest range of the variable domain if it has several ranges, otherwise select values not greater than mean of smallest and largest value IntValBranch INT_VAL_RANGE_MIN(void); /// Select the largest range of the variable domain if it has several ranges, otherwise select values greater than mean of smallest and largest value IntValBranch INT_VAL_RANGE_MAX(void); /** * \brief Select value as defined by the value function \a v and commit function \a c * Uses a commit function as default that posts the constraints that * a variable \a x must be equal to a value \a n for the first alternative * and that \a x must be different from \a n for the second alternative. */ IntValBranch INT_VAL(IntBranchVal v, IntBranchCommit c=nullptr); /// Try all values starting from smallest IntValBranch INT_VALUES_MIN(void); /// Try all values starting from largest IntValBranch INT_VALUES_MAX(void); /// Select smallest value BoolValBranch BOOL_VAL_MIN(void); /// Select largest value BoolValBranch BOOL_VAL_MAX(void); /// Select random value BoolValBranch BOOL_VAL_RND(Rnd r); /** * \brief Select value as defined by the value function \a v and commit function \a c * Uses a commit function as default that posts the constraints that * a variable \a x must be equal to a value \a n for the first alternative * and that \a x must be different from \a n for the second alternative. */ BoolValBranch BOOL_VAL(BoolBranchVal v, BoolBranchCommit c=nullptr); //@} } #include namespace Gecode { /** * \brief Which values to select for assignment * * \ingroup TaskModelIntBranch */ class IntAssign : public ValBranch { public: /// Which value selection enum Select { SEL_MIN, ///< Select smallest value SEL_MED, ///< Select greatest value not greater than the median SEL_MAX, ///< Select largest value SEL_RND, ///< Select random value SEL_VAL_COMMIT ///< Select value according to user-defined functions }; protected: /// Which value to select Select s; public: /// Initialize with selection strategy \a s IntAssign(Select s = SEL_MIN); /// Initialize with random number generator \a r IntAssign(Rnd r); /// Initialize with value function \a f and commit function \a c IntAssign(IntBranchVal v, IntBranchCommit c); /// Return selection strategy Select select(void) const; }; /** * \brief Which values to select for assignment * * \ingroup TaskModelIntBranch */ class BoolAssign : public ValBranch { public: /// Which value selection enum Select { SEL_MIN, ///< Select smallest value SEL_MAX, ///< Select largest value SEL_RND, ///< Select random value SEL_VAL_COMMIT ///< Select value according to user-defined functions }; protected: /// Which value to select Select s; public: /// Initialize with selection strategy \a s BoolAssign(Select s = SEL_MIN); /// Initialize with random number generator \a r BoolAssign(Rnd r); /// Initialize with value function \a f and commit function \a c BoolAssign(BoolBranchVal v, BoolBranchCommit c); /// Return selection strategy Select select(void) const; }; /** * \defgroup TaskModelIntBranchAssign Value selection for assigning integer variables * \ingroup TaskModelIntBranch */ //@{ /// Select smallest value IntAssign INT_ASSIGN_MIN(void); /// Select greatest value not greater than the median IntAssign INT_ASSIGN_MED(void); /// Select largest value IntAssign INT_ASSIGN_MAX(void); /// Select random value IntAssign INT_ASSIGN_RND(Rnd r); /** * \brief Select value as defined by the value function \a v and commit function \a c * * Uses a commit function as default that posts the constraint that * a variable \a x must be equal to the value \a n. */ IntAssign INT_ASSIGN(IntBranchVal v, IntBranchCommit c=nullptr); /// Select smallest value BoolAssign BOOL_ASSIGN_MIN(void); /// Select largest value BoolAssign BOOL_ASSIGN_MAX(void); /// Select random value BoolAssign BOOL_ASSIGN_RND(Rnd r); /** * \brief Select value as defined by the value function \a v and commit function \a c * * Uses a commit function as default that posts the constraint that * a variable \a x must be equal to the value \a n. */ BoolAssign BOOL_ASSIGN(BoolBranchVal v, BoolBranchCommit c=nullptr); //@} } #include namespace Gecode { /** * \brief Branch over \a x with variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const IntVarArgs& x, IntVarBranch vars, IntValBranch vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with tie-breaking variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const IntVarArgs& x, TieBreak vars, IntValBranch vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, IntVar x, IntValBranch vals, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const BoolVarArgs& x, BoolVarBranch vars, BoolValBranch vals, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); /** * \brief Branch over \a x with tie-breaking variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const BoolVarArgs& x, TieBreak vars, BoolValBranch vals, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); /** * \brief Branch over \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, BoolVar x, BoolValBranch vals, BoolVarValPrint vvp=nullptr); /** * \brief Assign all \a x with variable selection \a vars with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, const IntVarArgs& x, IntVarBranch vars, IntAssign vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Assign all \a x with tie-breaking variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, const IntVarArgs& x, TieBreak vars, IntAssign vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Assign \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, IntVar x, IntAssign vals, IntVarValPrint vvp=nullptr); /** * \brief Assign all \a x with variable selection \a vars with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, const BoolVarArgs& x, BoolVarBranch vars, BoolAssign vals, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); /** * \brief Assign all \a x with tie-breaking variable selection \a vars and value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, const BoolVarArgs& x, TieBreak vars, BoolAssign vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Assign \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void assign(Home home, BoolVar x, BoolAssign vals, BoolVarValPrint vvp=nullptr); } namespace Gecode { /** * \brief Branch over \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ void branch(Home home, const IntVarArgs& x, IntValBranch vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ void branch(Home home, const BoolVarArgs& x, BoolValBranch vals, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); /** * \brief Assign all \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ void assign(Home home, const IntVarArgs& x, IntAssign vals, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Assign all \a x with value selection \a vals * * \ingroup TaskModelIntBranch */ void assign(Home home, const BoolVarArgs& x, BoolAssign vals, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); } #include namespace Gecode { /** Print DFA \a d * \relates Gecode::DFA */ template std::basic_ostream& operator <<(std::basic_ostream& os, const DFA& d); /** Print TupleSet \a ts * \relates Gecode::TupleSet */ template std::basic_ostream& operator <<(std::basic_ostream& os, const TupleSet& ts); } // LDSB-related declarations. namespace Gecode { namespace Int { namespace LDSB { class SymmetryObject; }} /** * \brief A reference-counted pointer to a SymmetryObject * * \ingroup TaskModelIntBranch */ class GECODE_INT_EXPORT SymmetryHandle { public: /// Symmetry object that this handle refers to. Int::LDSB::SymmetryObject* ref; /// Increment counter void increment(void); /// Decrement counter void decrement(void); public: /// Default constructor SymmetryHandle(void); /// Initialies with a SymmetryObject SymmetryHandle(Int::LDSB::SymmetryObject* o); /// Copy constructor SymmetryHandle(const SymmetryHandle& h); /// Assignment operator const SymmetryHandle& operator=(const SymmetryHandle& h); /// Destructor ~SymmetryHandle(void); }; class Symmetries; /// Traits of %Symmetries template<> class ArrayTraits > { public: typedef Symmetries StorageType; typedef SymmetryHandle ValueType; typedef Symmetries ArgsType; }; /** * \defgroup TaskModelIntBranchSymm Symmetry declarations * * \ingroup TaskModelIntBranch */ //@{ /// Collection of symmetries class Symmetries : public ArgArray {}; // If this is instead a typedef, strange things happen with the // overloading of the "branch" function. /// Variables in \a x are interchangeable GECODE_INT_EXPORT SymmetryHandle VariableSymmetry(const IntVarArgs& x); /// Variables in \a x are interchangeable GECODE_INT_EXPORT SymmetryHandle VariableSymmetry(const BoolVarArgs& x); /// Specified variables in \a x are interchangeable GECODE_INT_EXPORT SymmetryHandle VariableSymmetry(const IntVarArgs& x, const IntArgs& indices); /// Values in \a v are interchangeable GECODE_INT_EXPORT SymmetryHandle ValueSymmetry(const IntArgs& v); /// Values in \a v are interchangeable GECODE_INT_EXPORT SymmetryHandle ValueSymmetry(const IntSet& v); /// All values in the domain of the given variable are interchangeable GECODE_INT_EXPORT SymmetryHandle ValueSymmetry(IntVar vars); /** * \brief Variable sequences in \a x of size \a ss are interchangeable * * The size of \a x must be a multiple of \a ss. */ GECODE_INT_EXPORT SymmetryHandle VariableSequenceSymmetry(const IntVarArgs& x, int ss); /** * \brief Variable sequences in \a x of size \a ss are interchangeable * * The size of \a x must be a multiple of \a ss. */ GECODE_INT_EXPORT SymmetryHandle VariableSequenceSymmetry(const BoolVarArgs& x, int ss); /** * \brief Value sequences in \a v of size \a ss are interchangeable * * The size of \a v must be a multiple of \a ss. */ GECODE_INT_EXPORT SymmetryHandle ValueSequenceSymmetry(const IntArgs& v, int ss); /// The values from \a lower to \a upper (inclusive) can be reflected GECODE_INT_EXPORT SymmetryHandle values_reflect(int lower, int upper); /// The values in the domain of \x can be reflected GECODE_INT_EXPORT SymmetryHandle values_reflect(IntVar x); //@} /** * \brief Branch over \a x with variable selection \a vars and value * selection \a vals with symmetry breaking * * Throws LDSBBadValueSelection exception if \a vals is any of * SEL_SPLIT_MIN, SEL_SPLIT_MAX, SEL_RANGE_MIN, SEL_RANGE_MAX, * SEL_VALUES_MIN, and SEL_VALUES_MAX, or if \a vals is * SEL_VAL_COMMIT with a custom commit function. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const IntVarArgs& x, IntVarBranch vars, IntValBranch vals, const Symmetries& syms, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with tie-breaking variable selection \a * vars and value selection \a vals with symmetry breaking * * Throws LDSBBadValueSelection exception if \a vals is any of * SEL_SPLIT_MIN, SEL_SPLIT_MAX, SEL_RANGE_MIN, SEL_RANGE_MAX, * SEL_VALUES_MIN, and SEL_VALUES_MAX, or if \a vals is * SEL_VAL_COMMIT with a custom commit function. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const IntVarArgs& x, TieBreak vars, IntValBranch vals, const Symmetries& syms, IntBranchFilter bf=nullptr, IntVarValPrint vvp=nullptr); /** * \brief Branch over \a x with variable selection \a vars and value * selection \a vals with symmetry breaking * * Throws LDSBBadValueSelection exception if \a vals is any of * SEL_SPLIT_MIN, SEL_SPLIT_MAX, SEL_RANGE_MIN, SEL_RANGE_MAX, * SEL_VALUES_MIN, and SEL_VALUES_MAX, or if \a vals is * SEL_VAL_COMMIT with a custom commit function. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const BoolVarArgs& x, BoolVarBranch vars, BoolValBranch vals, const Symmetries& syms, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); /** * \brief Branch over \a x with tie-breaking variable selection \a * vars and value selection \a vals with symmetry breaking * * Throws LDSBBadValueSelection exception if \a vals is any of * SEL_SPLIT_MIN, SEL_SPLIT_MAX, SEL_RANGE_MIN, SEL_RANGE_MAX, * SEL_VALUES_MIN, and SEL_VALUES_MAX, or if \a vals is * SEL_VAL_COMMIT with a custom commit function. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void branch(Home home, const BoolVarArgs& x, TieBreak vars, BoolValBranch vals, const Symmetries& syms, BoolBranchFilter bf=nullptr, BoolVarValPrint vvp=nullptr); #ifdef GECODE_HAS_CBS /** * \brief Branch over \a x using counting-based search * * Branches on the pair that has the the highest solution * density across all active propagators. Computing solution density is * currently supported for the following propagators: * * - Gecode::Int::Distinct::Val * - Gecode::Int::Distinct::Bnd * - Gecode::Int::Distinct::Dom * - More to come... * * If the space does not contain any of the preceding propagators, this * brancher won't be able to make any branching choices. For more details, * please see the documentation in MPG, section ?. * * To use this brancher, Gecode needs to be compiled with --enable-cbs. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void cbsbranch(Home home, const IntVarArgs& x); /** * \brief Branch over \a x using counting-based search * * Branches on the pair that has the the highest solution * density across all active propagators. Computing solution density is * currently supported for the following propagators: * * - Gecode::Int::Distinct::Val * - Gecode::Int::Distinct::Bnd * - Gecode::Int::Distinct::Dom * - More to come... * * If the space does not contain any of the preceding propagators, this * brancher won't be able to make any branching choices. For more details, * please see the documentation in MPG, section ?. * * To use this brancher, Gecode needs to be compiled with --enable-cbs. * * \ingroup TaskModelIntBranch */ GECODE_INT_EXPORT void cbsbranch(Home home, const BoolVarArgs& x); #endif } namespace Gecode { /* * \brief Relaxed assignment of variables in \a x from values in \a sx * * The variables in \a x are assigned values from the assigned variables * in the solution \a sx with a relaxation probability \a p. That is, * if \f$p=0.1\f$ approximately 10% of the variables in \a x will be * assigned a value from \a sx. * * The random numbers are generated from the generator \a r. At least * one variable will not be assigned: in case the relaxation attempt * would suggest that all variables should be assigned, a single * variable will be selected randomly to remain unassigned. * * Throws an exception of type Int::ArgumentSizeMismatch, if \a x and * \a sx are of different size. * * Throws an exception of type Int::OutOfLimits, if \a p is not between * \a 0.0 and \a 1.0. * * \ingroup TaskModelInt */ GECODE_INT_EXPORT void relax(Home home, const IntVarArgs& x, const IntVarArgs& sx, Rnd r, double p); /* * \brief Relaxed assignment of variables in \a x from values in \a sx * * The variables in \a x are assigned values from the assigned variables * in the solution \a sx with a relaxation probability \a p. That is, * if \f$p=0.1\f$ approximately 10% of the variables in \a x will be * assigned a value from \a sx. * * The random numbers are generated from the generator \a r. At least * one variable will not be assigned: in case the relaxation attempt * would suggest that all variables should be assigned, a single * variable will be selected randomly to remain unassigned. * * Throws an exception of type Int::ArgumentSizeMismatch, if \a x and * \a sx are of different size. * * Throws an exception of type Int::OutOfLimits, if \a p is not between * \a 0.0 and \a 1.0. * * \ingroup TaskModelInt */ GECODE_INT_EXPORT void relax(Home home, const BoolVarArgs& x, const BoolVarArgs& sx, Rnd r, double p); } #include #include namespace Gecode { /** * \defgroup TaskIntTrace Tracing for integer and Boolean variables * \ingroup TaskTrace */ /** * \brief Trace delta information for integer variables * \ingroup TaskIntTrace */ class IntTraceDelta : public Iter::Ranges::Diff > { protected: /// Iterator over the new values Int::ViewRanges rn; /// Iterator over the old values Iter::Ranges::RangeList ro; public: /// \name Constructors and initialization //@{ /// Initialize with old trace view \a o, new view \a n, and delta \a d IntTraceDelta(Int::IntTraceView o, Int::IntView n, const Delta& d); //@} }; /** * \brief Trace delta information for Boolean variables * \ingroup TaskIntTrace */ class BoolTraceDelta { protected: /// Delta information int delta; public: /// \name Constructors and initialization //@{ /// Initialize with old trace view \a o, new view \a n, and delta \a d BoolTraceDelta(Int::BoolTraceView o, Int::BoolView n, const Delta& d); //@} /// \name Iteration control //@{ /// Test whether iterator is still at a range or done bool operator ()(void) const; /// Move iterator to next range (if possible) void operator ++(void); //@} /// \name Range access //@{ /// Return smallest value of range int min(void) const; /// Return largest value of range int max(void) const; /// Return width of range (distance between minimum and maximum) unsigned int width(void) const; //@} }; } #include #include #include namespace Gecode { /** * \brief Tracer for integer variables * \ingroup TaskIntTrace */ typedef ViewTracer IntTracer; /** * \brief Trace recorder for integer variables * \ingroup TaskIntTrace */ typedef ViewTraceRecorder IntTraceRecorder; /** * \brief Standard integer variable tracer * \ingroup TaskIntTrace */ class GECODE_INT_EXPORT StdIntTracer : public IntTracer { protected: /// Output stream to use std::ostream& os; public: /// Initialize with output stream \a os0 and events \ e StdIntTracer(std::ostream& os0 = std::cerr); /// Print init information virtual void init(const Space& home, const IntTraceRecorder& t); /// Print prune information virtual void prune(const Space& home, const IntTraceRecorder& t, const ViewTraceInfo& vti, int i, IntTraceDelta& d); /// Print fixpoint information virtual void fix(const Space& home, const IntTraceRecorder& t); /// Print failure information virtual void fail(const Space& home, const IntTraceRecorder& t); /// Print that trace recorder is done virtual void done(const Space& home, const IntTraceRecorder& t); /// Default tracer (printing to std::cerr) static StdIntTracer def; }; /** * \brief Tracer for Boolean variables * \ingroup TaskIntTrace */ typedef ViewTracer BoolTracer; /** * \brief Trace recorder for Boolean variables * \ingroup TaskIntTrace */ typedef ViewTraceRecorder BoolTraceRecorder; /** * \brief Standard Boolean variable tracer * \ingroup TaskIntTrace */ class GECODE_INT_EXPORT StdBoolTracer : public BoolTracer { protected: /// Output stream to use std::ostream& os; public: /// Initialize with output stream \a os0 StdBoolTracer(std::ostream& os0 = std::cerr); /// Print init information virtual void init(const Space& home, const BoolTraceRecorder& t); /// Print prune information virtual void prune(const Space& home, const BoolTraceRecorder& t, const ViewTraceInfo& vti, int i, BoolTraceDelta& d); /// Print fixpoint information virtual void fix(const Space& home, const BoolTraceRecorder& t); /// Print failure information virtual void fail(const Space& home, const BoolTraceRecorder& t); /// Print that trace recorder is done virtual void done(const Space& home, const BoolTraceRecorder& t); /// Default tracer (printing to std::cerr) static StdBoolTracer def; }; /** * \brief Create a tracer for integer variables * \ingroup TaskIntTrace */ GECODE_INT_EXPORT void trace(Home home, const IntVarArgs& x, TraceFilter tf, int te = (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE), IntTracer& t = StdIntTracer::def); /** * \brief Create a tracer for integer variables * \ingroup TaskIntTrace */ void trace(Home home, const IntVarArgs& x, int te = (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE), IntTracer& t = StdIntTracer::def); /** * \brief Create a tracer for Boolean Variables * \ingroup TaskIntTrace */ GECODE_INT_EXPORT void trace(Home home, const BoolVarArgs& x, TraceFilter tf, int te = (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE), BoolTracer& t = StdBoolTracer::def); /** * \brief Create a tracer for Boolean Variables * \ingroup TaskIntTrace */ void trace(Home home, const BoolVarArgs& x, int te = (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE), BoolTracer& t = StdBoolTracer::def); } #include #endif // IFDEF: GECODE_HAS_INT_VARS // STATISTICS: int-post