nogoods.hh
Go to the documentation of this file.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 #ifndef __GECODE_SEARCH_META_NO_GOODS_HH__
00039 #define __GECODE_SEARCH_META_NO_GOODS_HH__
00040
00041 #include <gecode/search.hh>
00042
00043 namespace Gecode { namespace Search { namespace Meta {
00044
00046 class GECODE_VTABLE_EXPORT NoNGL : public NGL {
00047 public:
00049 NoNGL(void);
00051 NoNGL(Space& home);
00053 NoNGL(Space& home, bool share, NoNGL& ngl);
00055 virtual void subscribe(Space& home, Propagator& p);
00057 virtual void cancel(Space& home, Propagator& p);
00059 virtual NGL::Status status(const Space& home) const;
00061 virtual ExecStatus prune(Space& home);
00063 virtual NGL* copy(Space& home, bool share);
00064 };
00065
00067 class GECODE_SEARCH_EXPORT NoGoodsProp : public Propagator {
00068 protected:
00070 NGL* root;
00072 unsigned int n;
00074 NoGoodsProp(Home home, NGL* root);
00076 NoGoodsProp(Space& home, bool shared, NoGoodsProp& p);
00077 public:
00079 virtual Actor* copy(Space& home, bool share);
00081 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00083 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00085 template<class Path>
00086 static ExecStatus post(Space& home, const Path& p);
00088 virtual size_t dispose(Space& home);
00089 };
00090
00091 forceinline
00092 NoNGL::NoNGL(void) {}
00093
00094 forceinline
00095 NoNGL::NoNGL(Space& home)
00096 : NGL(home) {}
00097
00098 forceinline
00099 NoNGL::NoNGL(Space& home, bool share, NoNGL& ngl)
00100 : NGL(home,share,ngl) {}
00101
00102
00103
00104 forceinline
00105 NoGoodsProp::NoGoodsProp(Home home, NGL* root0)
00106 : Propagator(home), root(root0), n(0U) {
00107
00108 root->subscribe(home,*this); n++;
00109 bool notice = root->notice();
00110 NGL* l = root->next();
00111 while ((l != NULL) && l->leaf()) {
00112 l->subscribe(home,*this); n++;
00113 notice = notice || l->notice();
00114 l = l->next();
00115 }
00116 if (l != NULL) {
00117 l->subscribe(home,*this); n++;
00118 }
00119 while (!notice && (l != NULL)) {
00120 notice = notice || l->notice();
00121 l = l->next();
00122 }
00123 if (notice)
00124 home.notice(*this,AP_DISPOSE);
00125 }
00126
00127 forceinline
00128 NoGoodsProp::NoGoodsProp(Space& home, bool shared, NoGoodsProp& p)
00129 : Propagator(home,shared,p), n(p.n) {
00130 assert(p.root != NULL);
00131 NoNGL s;
00132 NGL* c = &s;
00133 for (NGL* pc = p.root; pc != NULL; pc = pc->next()) {
00134 NGL* n = pc->copy(home,shared);
00135 n->leaf(pc->leaf());
00136 c->next(n); c=n;
00137 }
00138 root = s.next();
00139 }
00140
00141
00142
00143 template<class Path>
00144 forceinline ExecStatus
00145 NoGoodsProp::post(Space& home, const Path& p) {
00146 int s = 0;
00147 int n = std::min(p.ds.entries(),static_cast<int>(p.ngdl()));
00148
00149 unsigned long int n_nogood = 0;
00150
00151
00152 while ((n > s) && (p.ds[n-1].truealt() == 0U))
00153 n--;
00154
00155
00156 NoNGL nn;
00157
00158 NGL* c = &nn;
00159
00160
00161 while ((s < n) && (p.ds[s].truealt() > 0U))
00162
00163 if (p.ds[s].rightmost()) {
00164
00165 home.trycommit(*p.ds[s].choice(),p.ds[s].truealt());
00166 s++;
00167 } else {
00168
00169 for (unsigned int a=0U; a<p.ds[s].truealt(); a++) {
00170 NGL* l = home.ngl(*p.ds[s].choice(),a);
00171
00172 if (l == NULL)
00173 return ES_OK;
00174 GECODE_ES_CHECK(l->prune(home));
00175 }
00176
00177 if (NGL* l = home.ngl(*p.ds[s].choice(),p.ds[s].truealt())) {
00178 c = c->add(l,false);
00179 s++; break;
00180 }
00181 }
00182
00183
00184 if (home.failed())
00185 return ES_FAILED;
00186 if (s >= n)
00187 return ES_OK;
00188
00189
00190 assert((n-s > 1) ||
00191 ((n-s == 1) && (c != &nn)));
00192
00193
00194 NGL* ll = NULL;
00195
00196
00197 for (int i=s; i<n; i++) {
00198
00199 for (unsigned int a=0U; a<p.ds[i].truealt(); a++) {
00200 NGL* l = home.ngl(*p.ds[i].choice(),a);
00201 if (l == NULL) {
00202
00203 if (ll == NULL)
00204 return ES_OK;
00205 ll->next(NULL);
00206 break;
00207 }
00208 c = c->add(l,true); ll = c;
00209 n_nogood++;
00210 }
00211
00212 if (NGL* l = home.ngl(*p.ds[i].choice(),p.ds[i].truealt())) {
00213 c = c->add(l,false);
00214 } else if (!p.ds[i].rightmost()) {
00215
00216 if (ll == NULL)
00217 return ES_OK;
00218 ll->next(NULL);
00219 break;
00220 }
00221 }
00222
00223 const_cast<Path&>(p).ng(n_nogood);
00224
00225 (void) new (home) NoGoodsProp(home,nn.next());
00226 return ES_OK;
00227 }
00228
00229 }}}
00230
00231 #endif
00232
00233