00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 namespace Gecode { namespace Int { namespace Sequence {
00043
00044 template<class View, class Val>
00045 forceinline
00046 Sequence<View,Val>::Sequence(Home home, ViewArray<View>& x0, Val s0,
00047 int q0, int l0, int u0)
00048 : Propagator(home), x(x0), s(s0), q(q0), l(l0), u(u0),
00049 vvsamax(home,x,s0,q0), vvsamin(home,x,s0,q0), ac(home) {
00050 home.notice(*this,AP_DISPOSE);
00051 for (int i=x.size(); i--; ) {
00052 if (undecided(x[i],s)) {
00053 x[i].subscribe(home,*new (home) SupportAdvisor<View>(home,*this,ac,i));
00054 } else {
00055 x[i].schedule(home,*this,x[i].assigned() ? ME_INT_VAL : ME_INT_BND);
00056 }
00057 }
00058 }
00059
00060 namespace {
00062 template<class Val>
00063 class UpdateVal {
00064 public:
00065 static void update(Val& n, Space& home, bool share, Val& old);
00066 };
00068 template<>
00069 class UpdateVal<int> {
00070 public:
00071 static void update(int& n, Space&, bool, int& old) {
00072 n = old;
00073 }
00074 };
00076 template<>
00077 class UpdateVal<IntSet> {
00078 public:
00079 static void update(IntSet& n, Space& home, bool share,
00080 IntSet& old) {
00081 n.update(home,share,old);
00082 }
00083 };
00084 }
00085
00086 template<class View, class Val>
00087 forceinline
00088 Sequence<View,Val>::Sequence(Space& home, bool share, Sequence& p)
00089 : Propagator(home,share,p), q(p.q), l(p.l), u(p.u),
00090 vvsamax(), vvsamin() {
00091 UpdateVal<Val>::update(s,home,share,p.s);
00092 x.update(home,share,p.x);
00093 ac.update(home,share,p.ac);
00094 vvsamax.update(home,share,p.vvsamax);
00095 vvsamin.update(home,share,p.vvsamin);
00096 }
00097
00098 template<class View,class Val>
00099 ExecStatus
00100 Sequence<View,Val>::advise(Space& home, Advisor& _a, const Delta& d) {
00101 SupportAdvisor<View>& a = static_cast<SupportAdvisor<View>&>(_a);
00102 ExecStatus status = vvsamax.advise(home,x,s,q,a.i,d);
00103 if ( ES_NOFIX == vvsamin.advise(home,x,s,q,a.i,d) ) {
00104 status = ES_NOFIX;
00105 }
00106
00107 if (!undecided(x[a.i],s)) {
00108 if (!x[a.i].assigned())
00109 x[a.i].cancel(home,a);
00110
00111 if ( ES_NOFIX == status ) {
00112 return home.ES_NOFIX_DISPOSE(ac,a);
00113 } else {
00114 return home.ES_FIX_DISPOSE(ac,a);
00115 }
00116 }
00117
00118 return status;
00119 }
00120
00121 template<class View, class Val>
00122 forceinline size_t
00123 Sequence<View,Val>::dispose(Space& home) {
00124 home.ignore(*this,AP_DISPOSE);
00125 ac.dispose(home);
00126 s.~Val();
00127 (void) Propagator::dispose(home);
00128 return sizeof(*this);
00129 }
00130
00131 template<class View, class Val>
00132 forceinline ExecStatus
00133 Sequence<View,Val>::check(Space& home, ViewArray<View>& x, Val s, int q, int l, int u) {
00134 Region r(home);
00135
00136 int* upper = r.alloc<int>(x.size()+1);
00137 int* lower = r.alloc<int>(x.size()+1);
00138 upper[0] = 0;
00139 lower[0] = 0;
00140 for ( int j=0; j<x.size(); j++ ) {
00141 upper[j+1] = upper[j];
00142 lower[j+1] = lower[j];
00143 if (includes(x[j],s)) {
00144 upper[j+1] += 1;
00145 } else if (excludes(x[j],s)) {
00146 lower[j+1] += 1;
00147 }
00148 if ( j+1 >= q && (q - l < lower[j+1] - lower[j+1-q] || upper[j+1] - upper[j+1-q] > u) ) {
00149 return ES_FAILED;
00150 }
00151 }
00152 return ES_OK;
00153 }
00154
00155 template<class View, class Val>
00156 ExecStatus
00157 Sequence<View,Val>::post(Home home, ViewArray<View>& x, Val s, int q, int l, int u) {
00158 GECODE_ES_CHECK(check(home,x,s,q,l,u));
00159 Sequence<View,Val>* p = new (home) Sequence<View,Val>(home,x,s,q,l,u);
00160
00161 GECODE_ES_CHECK(p->vvsamax.propagate(home,x,s,q,l,u));
00162 GECODE_ES_CHECK(p->vvsamin.propagate(home,x,s,q,l,u));
00163
00164 return ES_OK;
00165 }
00166
00167 template<class View, class Val>
00168 Actor*
00169 Sequence<View,Val>::copy(Space& home, bool share) {
00170 return new (home) Sequence<View,Val>(home,share,*this);
00171 }
00172
00173 template<class View, class Val>
00174 PropCost
00175 Sequence<View,Val>::cost(const Space&, const ModEventDelta&) const {
00176 return PropCost::cubic(PropCost::HI,x.size());
00177 }
00178
00179 template<class View, class Val>
00180 ExecStatus
00181 Sequence<View,Val>::propagate(Space& home, const ModEventDelta&) {
00182 GECODE_ES_CHECK(vvsamax.propagate(home,x,s,q,l,u));
00183 GECODE_ES_CHECK(vvsamin.propagate(home,x,s,q,l,u));
00184
00185 for (int i=x.size(); i--; )
00186 if (undecided(x[i],s))
00187 return ES_FIX;
00188
00189 return home.ES_SUBSUMED(*this);
00190 }
00191
00192 }}}
00193
00194
00195