Generated on Thu Apr 11 13:59:18 2019 for Gecode by doxygen 1.6.3

nogoods.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2013
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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     // Create subscriptions
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     // Eliminate the alternatives which are not no-goods at the end
00097     while ((n > s) && (p.ds[n-1].truealt() == 0U))
00098       n--;
00099 
00100     // A sentinel element
00101     NoNGL nn;
00102     // Current no-good literal
00103     NGL* c = &nn;
00104 
00105     // Commit no-goods at the beginning
00106     while ((s < n) && (p.ds[s].truealt() > 0U))
00107       // Try whether this is a rightmost alternative
00108       if (p.ds[s].rightmost()) {
00109         // No literal needed, directly try to commit
00110         home.trycommit(*p.ds[s].choice(),p.ds[s].truealt());
00111         s++;
00112       } else {
00113         // Prune using no-good literals
00114         for (unsigned int a=0U; a<p.ds[s].truealt(); a++) {
00115           NGL* l = home.ngl(*p.ds[s].choice(),a);
00116           // Does the brancher support no-good literals?
00117           if (l == NULL)
00118             return ES_OK;
00119           GECODE_ES_CHECK(l->prune(home));
00120         }
00121         // Add literal as root if needed and stop
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     // There are no literals
00129     if (home.failed())
00130       return ES_FAILED;
00131     if (s >= n)
00132       return ES_OK;
00133 
00134     // There must be at least two literals
00135     assert((n-s > 1) ||
00136            ((n-s == 1) && (c != &nn)));
00137 
00138     // Remember the last leaf
00139     NGL* ll = NULL;
00140 
00141     // Create literals
00142     for (int i=s; i<n; i++) {
00143       // Add leaves
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           // The brancher does not support no-goods
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       // Check whether to add an additional subtree
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         // The brancher does not support no-goods
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 // STATISTICS: search-other