Generated on Tue May 22 09:39:59 2018 for Gecode by doxygen 1.6.3

int.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     David Rijsman <David.Rijsman@quintiq.com>
00005  *
00006  *  Contributing authors:
00007  *     Christian Schulte <schulte@gecode.org>
00008  *
00009  *  Copyright:
00010  *     David Rijsman, 2009
00011  *     Christian Schulte, 2009
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode { namespace Int { namespace Sequence {
00039 
00040   template<class View, class Val>
00041   forceinline
00042   Sequence<View,Val>::Sequence(Home home, ViewArray<View>& x0, Val s0,
00043                                int q0, int l0, int u0)
00044     : Propagator(home), x(x0), s(s0), q(q0), l(l0), u(u0),
00045       vvsamax(home,x,s0,q0), vvsamin(home,x,s0,q0), ac(home),
00046       tofail(false) {
00047     home.notice(*this,AP_DISPOSE);
00048     for (int i=x.size(); i--; ) {
00049       if (undecided(x[i],s)) {
00050         x[i].subscribe(home,*new (home) SupportAdvisor<View>(home,*this,ac,i));
00051       } else {
00052         x[i].schedule(home,*this,x[i].assigned() ? ME_INT_VAL : ME_INT_BND);
00053       }
00054     }
00055   }
00056 
00057   template<class View, class Val>
00058   forceinline
00059   Sequence<View,Val>::Sequence(Space& home, Sequence& p)
00060     : Propagator(home,p), s(p.s), q(p.q), l(p.l), u(p.u),
00061       vvsamax(), vvsamin(), tofail(p.tofail) {
00062     x.update(home,p.x);
00063     ac.update(home,p.ac);
00064     vvsamax.update(home,p.vvsamax);
00065     vvsamin.update(home,p.vvsamin);
00066   }
00067 
00068   template<class View,class Val>
00069   ExecStatus
00070   Sequence<View,Val>::advise(Space& home, Advisor& _a, const Delta& d) {
00071     SupportAdvisor<View>& a = static_cast<SupportAdvisor<View>&>(_a);
00072     ExecStatus status = vvsamax.advise(home,x,s,q,a.i,d);
00073     if ( ES_NOFIX == vvsamin.advise(home,x,s,q,a.i,d) ) {
00074       status = ES_NOFIX;
00075     }
00076 
00077     if (!undecided(x[a.i],s)) {
00078       if (!x[a.i].assigned())
00079         x[a.i].cancel(home,a);
00080 
00081       if ( ES_NOFIX == status ) {
00082         return home.ES_NOFIX_DISPOSE(ac,a);
00083       } else {
00084         return home.ES_FIX_DISPOSE(ac,a);
00085       }
00086     }
00087 
00088     if ((status == ES_FAILED) && disabled()) {
00089       tofail = true;
00090       return ES_FIX;
00091     }
00092 
00093     return status;
00094   }
00095 
00096   template<class View, class Val>
00097   forceinline size_t
00098   Sequence<View,Val>::dispose(Space& home) {
00099     home.ignore(*this,AP_DISPOSE);
00100     ac.dispose(home);
00101     s.~Val();
00102     (void) Propagator::dispose(home);
00103     return sizeof(*this);
00104   }
00105 
00106   template<class View, class Val>
00107   forceinline ExecStatus
00108   Sequence<View,Val>::check(ViewArray<View>& x, Val s, int q, int l, int u) {
00109     Region r;
00110     // could do this with an array of length q...
00111     int* upper = r.alloc<int>(x.size()+1);
00112     int* lower = r.alloc<int>(x.size()+1);
00113     upper[0] = 0;
00114     lower[0] = 0;
00115     for ( int j=0; j<x.size(); j++ ) {
00116       upper[j+1] = upper[j];
00117       lower[j+1] = lower[j];
00118       if (includes(x[j],s)) {
00119         upper[j+1] += 1;
00120       } else if (excludes(x[j],s)) {
00121         lower[j+1] += 1;
00122       }
00123       if ( j+1 >= q && (q - l < lower[j+1] - lower[j+1-q] || upper[j+1] - upper[j+1-q] > u) ) {
00124         return ES_FAILED;
00125       }
00126     }
00127     return ES_OK;
00128   }
00129 
00130   template<class View, class Val>
00131   ExecStatus
00132   Sequence<View,Val>::post(Home home, ViewArray<View>& x, Val s, int q, int l, int u) {
00133     GECODE_ES_CHECK(check(x,s,q,l,u));
00134     Sequence<View,Val>* p = new (home) Sequence<View,Val>(home,x,s,q,l,u);
00135 
00136     GECODE_ES_CHECK(p->vvsamax.propagate(home,x,s,q,l,u));
00137     GECODE_ES_CHECK(p->vvsamin.propagate(home,x,s,q,l,u));
00138 
00139    return ES_OK;
00140   }
00141 
00142   template<class View, class Val>
00143   Actor*
00144   Sequence<View,Val>::copy(Space& home) {
00145     return new (home) Sequence<View,Val>(home,*this);
00146   }
00147 
00148   template<class View, class Val>
00149   PropCost
00150   Sequence<View,Val>::cost(const Space&, const ModEventDelta&) const {
00151     return PropCost::cubic(PropCost::HI,x.size());
00152   }
00153 
00154   template<class View, class Val>
00155   void
00156   Sequence<View,Val>::reschedule(Space& home) {
00157     for (int i=x.size(); i--; )
00158       if (!undecided(x[i],s))
00159         x[i].schedule(home,*this,x[i].assigned() ? ME_INT_VAL : ME_INT_BND);
00160     if (tofail)
00161       View::schedule(home,*this,ME_INT_BND);
00162   }
00163 
00164   template<class View, class Val>
00165   ExecStatus
00166   Sequence<View,Val>::propagate(Space& home, const ModEventDelta&) {
00167     if (tofail)
00168       return ES_FAILED;
00169 
00170     GECODE_ES_CHECK(vvsamax.propagate(home,x,s,q,l,u));
00171     GECODE_ES_CHECK(vvsamin.propagate(home,x,s,q,l,u));
00172 
00173     for (int i=x.size(); i--; )
00174       if (undecided(x[i],s))
00175         return ES_FIX;
00176 
00177     return home.ES_SUBSUMED(*this);
00178   }
00179 
00180 }}}
00181 
00182 // STATISTICS: int-prop
00183