/* * Main authors: * Patrick Pekczynski * * Copyright: * Patrick Pekczynski, 2004 * * Last modified: $Date: 2006-08-24 11:25:05 +0200 (Thu, 24 Aug 2006) $ by $Author: schulte $ * $Revision: 3559 $ * * This file is part of Gecode, the generic constrain * development environment: * http://www.gecode.org * * * See the file "LICENSE" for information on usage and * redistribution of this file, and for a * DISCLAIMER OF ALL WARRANTIES. */ #include "gecode/iter.hh" namespace Gecode { namespace Int { namespace GCC { /** * \brief Tuple conataining the lower and upper cardinality bounds * */ class OccurBndsView { private: int _min; int _max; int c; int count; public: OccurBndsView(void); int min(void) const; int max(void) const; int card(void) const; int counter(void) const; void min(int); void max(int); void card(int c); void counter(int c); void init(Space* home, int min, int max, int c); ModEvent lq(Space* home, int n); ModEvent gq(Space* home, int n); ModEvent eq(Space* home, int n); bool assigned(void) const; bool modified(void) const; bool range(void) const; ModEvent inc(void); void cancel(Space* home, Propagator* , PropCond ) {} void subscribe(Space*, Propagator* , PropCond, bool=true) {} void update(Space*, bool, OccurBndsView&); }; forceinline OccurBndsView::OccurBndsView(void) {} forceinline int OccurBndsView::min(void) const { return _min; } forceinline int OccurBndsView::max(void) const { return _max; } forceinline int OccurBndsView::card(void) const { return c; } forceinline int OccurBndsView::counter(void) const { return count; } forceinline void OccurBndsView::min(int m) { _min = m; } forceinline void OccurBndsView::max(int m) { _max = m; } forceinline void OccurBndsView::card(int ca) { c = ca; } forceinline void OccurBndsView::counter(int count0) { count = count0; } forceinline void OccurBndsView::init(Space* home, int min, int max, int val) { _min = min; _max=max; c = val; count = 0; } forceinline ModEvent OccurBndsView::inc(void) { count++; if (count > _max) { return ME_GEN_FAILED; } else { return ME_GEN_NONE; } } forceinline bool OccurBndsView::assigned(void) const { return _min==_max; } forceinline bool OccurBndsView::modified(void) const { return false; } forceinline bool OccurBndsView::range(void) const { return true; } forceinline ModEvent OccurBndsView::lq(Space*, int i){ // the maximum can be made consistent if (_min > i) { return ME_GEN_FAILED; } else { return ME_GEN_NONE; } } forceinline ModEvent OccurBndsView::gq(Space*, int i){ // this bound is fix if (_max < i) { return ME_GEN_FAILED; } return ME_GEN_NONE; } forceinline ModEvent OccurBndsView::eq(Space*, int i){ if (_min > i || _max < i) { return ME_GEN_FAILED; } else { return ME_GEN_NONE; } } /// \brief Debugging: print a fixed cardinality forceinline std::ostream& operator<<(std::ostream& os, OccurBndsView& xs) { os << xs.card() << "("<< xs.counter() <<")["; os << xs.min() << "," << xs.max() << "]"; return os; } forceinline void OccurBndsView::update(Space*, bool, OccurBndsView& oc) { _min = oc._min; _max = oc._max; c = oc.c; count = oc.count; } /** * \brief Return the index of v in the array * * Complexity is \f$O(log(|k|))\f$ */ template forceinline int lookupValue(T& a, int v){ int idx = -1; int l = 0; int r = a.size() - 1; if (r == 0) { if (a[0].card() == v) { return 0; } else { return -1; } } while ( l < r ) { if ( a[l].card() == v) { idx = l; break; } if ( a[r].card() == v) { idx = r; break; } int p = (l + r) / 2; if ( v == a[p].card()) { idx = p; break; } else { if ( v < a[p].card()) { r = p; } else { l = p; } } if (l == r - 1) { break; } } return idx; } /** * \brief Card integer view * */ class CardView : public DerivedViewBase { protected: /// Card int c; /// Counter int count; using DerivedViewBase::view; public: CardView(void); /// Initialize with integer view \a x and value \a c CardView(const IntView& x, int c); /// Initialize with integer view \a x and value \a c void init(const IntView& x, int c); void init(Space* home, int mi, int ma , int c); /// Return value int card(void) const; void card(int ca); /// Increment counter ModEvent inc(void); /// Set the counter to the number of times value \a c occurs void counter(int); /// Return the number of times value \a c occurs int counter(void); /// \name Value access //@{ void operator=(const IntView& x); void operator=(const Gecode::Int::GCC::CardView& x); /// Return minimum of domain int min(void) const; /// Return maximum of domain int max(void) const; /// Return median of domain int med(void) const; /// Return assigned value (only if assigned) int val(void) const; /// Return used IntView IntView intview(void); /// 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 view is assigned bool assigned(void) const; /// Test whether \a n is contained in domain bool in(int n) const; /// Test whether \a n is contained in domain bool in(double n) const; ///@} /// \name Domain update by value ///@{ /// Restrict domain values to be less or equal than \a n ModEvent lq(Space* home, int n); /// Restrict domain values to be less or equal than \a n ModEvent lq(Space* home, double n); /// Restrict domain values to be less than \a n ModEvent le(Space* home, int n); /// Restrict domain values to be less than \a n ModEvent le(Space* home, double n); /// Restrict domain values to be greater or equal than \a n ModEvent gq(Space* home, int n); /// Restrict domain values to be greater or equal than \a n ModEvent gq(Space* home, double n); /// Restrict domain values to be greater than \a n ModEvent gr(Space* home, int n); /// Restrict domain values to be greater than \a n ModEvent gr(Space* home, double n); /// Restrict domain values to be different from \a n ModEvent nq(Space* home, int n); /// Restrict domain values to be different from \a n ModEvent nq(Space* home, double n); /// Restrict domain values to be equal to \a n ModEvent eq(Space* home, int n); /// Restrict domain values to be equal to \a n ModEvent eq(Space* home, double n); ///@} /// \name Domain update by range iterator ///@{ /// Replace domain by range sequence described by \a i /// Intersect domain with range sequence described by \a i template ModEvent inter(Space* home, I& i); /// Remove from domain the range sequence described by \a i template ModEvent minus(Space* home, I& i); ///@} /// \name Propagator modification events ///@{ /// Return modification event of propagator \a p for view static ModEvent pme(const Propagator* p); /// Translate modification event \a me to propagator modification event for view static PropModEvent pme(ModEvent me); ///@} /// \name Dependencies ///@{ /// Subscribe propagator \a p with propagation condition \a pc to view void subscribe(Space* home, Propagator* p, PropCond pc, bool process=true); /// Cancel subscription of propagator \a p with propagation condition \a pc to view void cancel(Space* home, Propagator* p, PropCond pc); ///@} /// \name Cloning ///@{ /// Update this view to be a clone of view \a x void update(Space* home, bool share, CardView& x); ///@} /// \name View comparison ///@{ /// Test whether this view is the same as \a x bool operator ==(const CardView& x) const; /// Test whether this view is not the same as \a x bool operator !=(const CardView& x) const; /// Test whether this view is smaller than \a x (arbitrary order) bool operator < (const CardView& x) const; /// Test whether this view is larger than \a x (arbitrary order) bool operator > (const CardView& x) const; ///@} }; /* * Constructors and initialization * */ forceinline CardView::CardView(void) {} forceinline CardView::CardView(const IntView& x, int d) : DerivedViewBase(x), c(d), count(0) {} forceinline void CardView::init(const IntView& x, int d) { view = x; c = d; count = 0; } forceinline void CardView::init(Space* home, int mi, int ma, int d) { IntVar ivar(home, mi, ma); IntView iview(ivar); view = iview; c = d; count = 0; } forceinline void CardView::card(int ca) { c = ca; } forceinline int CardView::card(void) const { return c; } forceinline ModEvent CardView::inc(void) { count++; if (count > this->max()) { return ME_GEN_FAILED; } else { return ME_GEN_NONE; } } forceinline void CardView::counter(int c) { count = c; } forceinline int CardView::counter(void) { return count; } /* * Value access * */ forceinline void CardView::operator=(const IntView& x) { view = x; c = 0; count = 0; } forceinline void CardView::operator=(const CardView& x) { view = x.view; c = x.c; count = x.count; } forceinline int CardView::min(void) const { return view.min(); } forceinline int CardView::max(void) const { return view.max(); } forceinline int CardView::med(void) const { return view.med(); } forceinline int CardView::val(void) const { return view.val(); } forceinline IntView CardView::intview(void){ return view; } forceinline unsigned int CardView::width(void) const { return view.width(); } forceinline unsigned int CardView::size(void) const { return view.size(); } forceinline unsigned int CardView::regret_min(void) const { return view.regret_min(); } forceinline unsigned int CardView::regret_max(void) const { return view.regret_max(); } /* * Domain tests * */ forceinline bool CardView::range(void) const { return view.range(); } forceinline bool CardView::assigned(void) const { return view.assigned(); } forceinline bool CardView::in(int n) const { return view.in(n); } forceinline bool CardView::in(double n) const { return view.in(n); } /* * Domain update by value * */ forceinline ModEvent CardView::lq(Space* home, int n) { return view.lq(home,n); } forceinline ModEvent CardView::lq(Space* home, double n) { return view.lq(home,n); } forceinline ModEvent CardView::le(Space* home, int n) { return view.le(home,n); } forceinline ModEvent CardView::le(Space* home, double n) { return view.le(home,n); } forceinline ModEvent CardView::gq(Space* home, int n) { return view.gq(home,n); } forceinline ModEvent CardView::gq(Space* home, double n) { return view.gq(home,n); } forceinline ModEvent CardView::gr(Space* home, int n) { return view.gr(home,n); } forceinline ModEvent CardView::gr(Space* home, double n) { return view.gr(home,n); } forceinline ModEvent CardView::nq(Space* home, int n) { return view.nq(home,n); } forceinline ModEvent CardView::nq(Space* home, double n) { return view.nq(home,n); } forceinline ModEvent CardView::eq(Space* home, int n) { return view.eq(home,n); } forceinline ModEvent CardView::eq(Space* home, double n) { return view.eq(home,n); } /* * Domain update by range iterator * */ template ModEvent CardView::inter(Space* home, I& i) { return view.inter(home,i); } template ModEvent CardView::minus(Space* home, I& i) { return view.minus(home,i); } /* * Propagator modification events * */ forceinline ModEvent CardView::pme(const Propagator* p) { return IntView::pme(p); } forceinline PropModEvent CardView::pme(ModEvent me) { return IntView::pme(me); } /* * Dependencies * */ forceinline void CardView::subscribe(Space* home, Propagator* p, PropCond pc, bool process) { view.subscribe(home, p, pc, process); } forceinline void CardView::cancel(Space* home, Propagator* p, PropCond pc) { view.cancel(home,p, pc); } /* * Cloning * */ forceinline void CardView::update(Space* home, bool share, CardView& x) { c = x.c; count = x.count; view.update(home,share,x.view); } } /** * \brief %Range iterator for indexed problem variables */ template <> class ViewRanges : public Gecode::Int::ViewRanges { public: /// \name Constructors and initialization ///@{ /// Default constructor ViewRanges(void); /// Initialize with ranges for view \a x ViewRanges(const GCC::CardView& x); /// Initialize with ranges for view \a x void init(const GCC::CardView& x); ///@} }; /// \brief Debugging: print a cardinality variable forceinline std::ostream& operator<<(std::ostream& os, GCC::CardView& v) { os << "("< iter(v); while(iter()){ os << iter.val() <<","; ++iter; } os << "}"; } } os << ")"; return os; } forceinline ViewRanges::ViewRanges(void) : Gecode::Int::ViewRanges() {} forceinline ViewRanges::ViewRanges (const GCC::CardView& x) : Gecode::Int::ViewRanges(x.base()) {} forceinline void ViewRanges::init(const GCC::CardView& x) { Gecode::Int::ViewRanges xi(x.base()); } }} // STATISTICS: int-prop