nogoods.hpp
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 namespace Gecode { namespace Search {
00035
00036 forceinline
00037 NoNGL::NoNGL(void) {}
00038
00039 forceinline
00040 NoNGL::NoNGL(Space& home)
00041 : NGL(home) {}
00042
00043 forceinline
00044 NoNGL::NoNGL(Space& home, NoNGL& ngl)
00045 : NGL(home,ngl) {}
00046
00047
00048
00049 forceinline
00050 NoGoodsProp::NoGoodsProp(Space& home, NGL* root0)
00051 : Propagator(Home(home)), root(root0), n(0U) {
00052
00053 root->subscribe(home,*this); n++;
00054 bool notice = root->notice();
00055 NGL* l = root->next();
00056 while ((l != NULL) && l->leaf()) {
00057 l->subscribe(home,*this); n++;
00058 notice = notice || l->notice();
00059 l = l->next();
00060 }
00061 if (l != NULL) {
00062 l->subscribe(home,*this); n++;
00063 }
00064 while (!notice && (l != NULL)) {
00065 notice = notice || l->notice();
00066 l = l->next();
00067 }
00068 if (notice)
00069 home.notice(*this,AP_DISPOSE);
00070 }
00071
00072 forceinline
00073 NoGoodsProp::NoGoodsProp(Space& home, NoGoodsProp& p)
00074 : Propagator(home,p), n(p.n) {
00075 assert(p.root != NULL);
00076 NoNGL s;
00077 NGL* c = &s;
00078 for (NGL* pc = p.root; pc != NULL; pc = pc->next()) {
00079 NGL* n = pc->copy(home);
00080 n->leaf(pc->leaf());
00081 c->next(n); c=n;
00082 }
00083 root = s.next();
00084 }
00085
00086
00087
00088 template<class Path>
00089 forceinline ExecStatus
00090 NoGoodsProp::post(Space& home, const Path& p) {
00091 int s = 0;
00092 int n = std::min(p.ds.entries(),static_cast<int>(p.ngdl()));
00093
00094 unsigned long int n_nogood = 0;
00095
00096
00097 while ((n > s) && (p.ds[n-1].truealt() == 0U))
00098 n--;
00099
00100
00101 NoNGL nn;
00102
00103 NGL* c = &nn;
00104
00105
00106 while ((s < n) && (p.ds[s].truealt() > 0U))
00107
00108 if (p.ds[s].rightmost()) {
00109
00110 home.trycommit(*p.ds[s].choice(),p.ds[s].truealt());
00111 s++;
00112 } else {
00113
00114 for (unsigned int a=0U; a<p.ds[s].truealt(); a++) {
00115 NGL* l = home.ngl(*p.ds[s].choice(),a);
00116
00117 if (l == NULL)
00118 return ES_OK;
00119 GECODE_ES_CHECK(l->prune(home));
00120 }
00121
00122 if (NGL* l = home.ngl(*p.ds[s].choice(),p.ds[s].truealt())) {
00123 c = c->add(l,false);
00124 s++; break;
00125 }
00126 }
00127
00128
00129 if (home.failed())
00130 return ES_FAILED;
00131 if (s >= n)
00132 return ES_OK;
00133
00134
00135 assert((n-s > 1) ||
00136 ((n-s == 1) && (c != &nn)));
00137
00138
00139 NGL* ll = NULL;
00140
00141
00142 for (int i=s; i<n; i++) {
00143
00144 for (unsigned int a=0U; a<p.ds[i].truealt(); a++) {
00145 NGL* l = home.ngl(*p.ds[i].choice(),a);
00146 if (l == NULL) {
00147
00148 if (ll == NULL)
00149 return ES_OK;
00150 ll->next(NULL);
00151 break;
00152 }
00153 c = c->add(l,true); ll = c;
00154 n_nogood++;
00155 }
00156
00157 if (NGL* l = home.ngl(*p.ds[i].choice(),p.ds[i].truealt())) {
00158 c = c->add(l,false);
00159 } else if (!p.ds[i].rightmost()) {
00160
00161 if (ll == NULL)
00162 return ES_OK;
00163 ll->next(NULL);
00164 break;
00165 }
00166 }
00167
00168 const_cast<Path&>(p).ng(n_nogood);
00169
00170 (void) new (home) NoGoodsProp(home,nn.next());
00171 return ES_OK;
00172 }
00173
00174 }}
00175
00176