Generated on Wed Nov 1 15:04:31 2006 for Gecode by doxygen 1.4.5

val.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00004  *
00005  *  Copyright:
00006  *     Patrick Pekczynski, 2005
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  */
00020 
00021 namespace Gecode { namespace Int { namespace GCC {
00023   template <class View, class Card, bool isView>
00024   inline ExecStatus
00025   prop_val(Space* home, ViewArray<View>& x, ViewArray<Card>& k,
00026            bool& _cardall){
00027 
00028     bool mod = false;
00029     int  n   = x.size();
00030     int  m   = k.size();
00031 
00032     // count[i] denotes how often value k[i].card() occurs in x
00033     GECODE_AUTOARRAY(int,  count, m);
00034     // stack of values having reached their maximum occurence
00035     GECODE_AUTOARRAY(int,  rem,   m);
00036     // keep track whether a value is already on the stack
00037     GECODE_AUTOARRAY(bool, onrem, m);
00038     // stacksize
00039     int rs = 0;
00040 
00041     // initialization
00042     int sum_min = 0;
00043     int removed = 0;
00044     for (int i = m; i--; ) {
00045 
00046       removed += k[i].counter();
00047       sum_min += k[i].min();
00048 
00049       count[i] = 0;
00050       onrem[i] = false;
00051     }
00052 
00053     for (int i = m; i--; ) {
00054       // less than or equal than the total number of free variables
00055       // to satisfy the required occurences
00056       if (!k[i].assigned()) {
00057         int mub     = n + removed - (sum_min - k[i].min());
00058         ModEvent me = k[i].lq(home, mub);
00059         GECODE_ME_CHECK(me);
00060         mod |= (me_modified(me) && k[i].max() != mub);
00061       }
00062     }
00063 
00064     // Due to lookup operation counting requires O(n \cdot log(n)) time
00065     bool all_assigned = true;
00066     // number of assigned views with respect to the current problem size
00067     int  noa   = 0;
00068     // total number of assigned views wrt. the original probem size
00069     int  t_noa = 0;
00070     for (int i = n; i--; ) {
00071       bool b = x[i].assigned();
00072       all_assigned &= b;
00073       if (b) {
00074         int idx = lookupValue(k,x[i].val());
00075         if (idx == -1) {
00076           return ES_FAILED;
00077         }
00078         count[idx]++;
00079         noa++;
00080       }
00081     }
00082 
00083     // number of unassigned views
00084     int  non = x.size() - noa;
00085 
00086     // check for subsumption
00087     if (all_assigned) {
00088 
00089       for (int i = m; i--; ) {
00090         int ci = count[i] + k[i].counter();
00091         if (!(k[i].min() <= ci && ci <= k[i].max())) {
00092           return ES_FAILED;
00093         }
00094         // the solution contains ci occurences of value k[i].card();
00095         if (isView) {
00096           if (!k[i].assigned()) {
00097             ModEvent me = k[i].eq(home, ci);
00098             GECODE_ME_CHECK(me);
00099             mod |= k[i].assigned();
00100           }
00101         }
00102       }
00103       return ES_SUBSUMED;
00104     }
00105 
00106     // total number of unsatisfied miminum occurences
00107     int req = 0;
00108 
00109     // number of values whose min requirements are not yet met
00110     int n_r = 0;
00111 
00112     // if only one value is unsatisified single holds the index of that value
00113     int single = 0;
00114 
00115     for (int i = m; i--; ) {
00116       int ci = count[i] + k[i].counter();
00117       t_noa += ci;
00118       if (ci == 0) { // this works
00119         req += k[i].min();
00120         n_r++;
00121         single = i;
00122       }
00123 
00124       // number of unassigned views cannot satisfy
00125       // the required minimum occurence
00126       if (req > non) {
00127         return ES_FAILED;
00128       }
00129     }
00130 
00131     // if only one unsatisfied occurences is left
00132     if (req == non && n_r == 1) {
00133       for (int i = n; i--; ) {
00134         // try to assign it
00135         if (!x[i].assigned()) {
00136           ModEvent me = x[i].eq(home, k[single].card());
00137           count[single]++;
00138           GECODE_ME_CHECK(me);
00139         }
00140       }
00141 
00142       for (int i = m; i--; ) {
00143         int ci = count[i] + k[i].counter();
00144         // consistency check
00145         if (!(k[i].min() <= ci && ci <= k[i].max())) {
00146           return ES_FAILED;
00147         }
00148         // the solution contains ci occurences of value k[i].card();
00149         if (isView) {
00150           if (!k[i].assigned()) {
00151             ModEvent me = k[i].eq(home, ci);
00152             GECODE_ME_CHECK(me);
00153           }
00154         }
00155       }
00156       return ES_SUBSUMED;
00157     }
00158 
00159     for (int i = m; i--; ) {
00160       int ci = count[i] + k[i].counter();
00161       if (ci == k[i].max() && !onrem[i]) {
00162         rem[rs] = k[i].card();
00163         k[i].counter(ci);
00164         rs++;
00165         onrem[i] = true;
00166         if (isView) {
00167           // the solution contains ci occurences of value k[i].card();
00168           if (!k[i].assigned()) {
00169             ModEvent me = k[i].eq(home, ci);
00170             GECODE_ME_CHECK(me);
00171             mod |= k[i].assigned();
00172           }
00173         }
00174       } else {
00175         if (ci > k[i].max()) {
00176           return ES_FAILED;
00177         }
00178 
00179         // in case of variable cardinalities
00180         if (isView) {
00181           if (!k[i].assigned()) {
00182             if (ci > k[i].min()) {
00183               ModEvent me = k[i].gq(home, ci);
00184               GECODE_ME_CHECK(me);
00185               mod |= k[i].assigned();
00186               mod |= (me_modified(me) && k[i].min() != ci);
00187             }
00188             int occupied = t_noa - ci;
00189             int mub = x.size() + removed - occupied;
00190         
00191             ModEvent me = k[i].lq(home, mub);
00192             GECODE_ME_CHECK(me);
00193             mod |= k[i].assigned();
00194             mod |= (me_failed(me) && k[i].max() != mub);
00195           }
00196         }
00197       }
00198       // reset counter
00199       count[i] = 0;
00200     }
00201 
00202     // reduce the problem size
00203     for (int i = n; i--; ) {
00204       bool b = x[i].assigned();
00205       if (b) {
00206         int idx = lookupValue(k,x[i].val());
00207         if (idx == -1) {
00208           return ES_FAILED;
00209         }
00210         if (onrem[idx]) {
00211           x[i] = x[--n];
00212           x.size(n);
00213         }
00214       }
00215     }
00216 
00217     // remove alredy satisfied values
00218     if (rs > 0) {
00219       IntSet remset(&rem[0], rs);
00220       IntSetRanges rr(remset);
00221       for (int i = x.size(); i--;) {
00222         if (!x[i].assigned()) {
00223           ModEvent me = x[i].minus(home, rr);
00224           if (me_failed(me)) {
00225             return ES_FAILED;
00226           }
00227           mod |= x[i].assigned();
00228         }
00229       }
00230     }
00231 
00232     all_assigned = true;
00233 
00234     for (int i = x.size(); i--; ) {
00235       bool b = x[i].assigned();
00236       all_assigned &= b;
00237       if (b) {
00238         int idx = lookupValue(k,x[i].val());
00239         if (idx == -1) {
00240           return ES_FAILED;
00241         }
00242         count[idx]++;
00243       }
00244     }
00245 
00246     if (all_assigned) {
00247       for (int i = k.size(); i--; ) {
00248         int ci = count[i] + k[i].counter();
00249         if (!(k[i].min() <= ci && ci <= k[i].max())) {
00250           return ES_FAILED;
00251         }
00252         // the solution contains ci occurences of value k[i].card();
00253         if (isView) {
00254           if (!k[i].assigned()) {
00255             ModEvent me = k[i].eq(home, ci);
00256             GECODE_ME_CHECK(me);
00257             mod |= k[i].assigned();
00258           }
00259         }
00260       }
00261       return ES_SUBSUMED;
00262     }
00263 
00264     if (isView) {
00265       // check again consistnecy of cardinalities
00266       int reqmin = 0;
00267       int allmax = 0;
00268       m    = k.size();
00269       n    = x.size();
00270       for (int i = m; i--; ) {
00271         int ci = k[i].counter();
00272         if (ci > k[i].max() ) {
00273           return ES_FAILED;
00274         } else {
00275           allmax += (k[i].max() - ci);
00276           if (ci < k[i].min()) {
00277             reqmin += (k[i].min() - ci);
00278           }
00279         }
00280         if (k[i].min() > n) {
00281           return ES_FAILED;
00282         }
00283         if (!k[i].assigned()) {
00284           ModEvent me = k[i].lq(home, n);
00285           if (me_failed(me)) {
00286             return ES_FAILED;
00287           }
00288         }
00289       }
00290 
00291       if (n < reqmin) {
00292         return ES_FAILED;
00293       }
00294 
00295       if (_cardall && allmax < n) {
00296         return ES_FAILED;
00297       }
00298     }
00299     return mod ? ES_NOFIX : ES_FIX;
00300   }
00301 
00302   /*
00303    * The propagator proper
00304    *
00305    */
00306 
00307   template <class View, class Card, bool isView>
00308   inline
00309   Val<View, Card, isView>::Val(Space* home, ViewArray<View>& x0,
00310                                ViewArray<Card>& k0,
00311                                bool all)
00312     :Propagator(home,true), x(x0), k(k0), card_all(all){
00313     x.subscribe(home, this, PC_INT_VAL);
00314     k.subscribe(home, this, PC_INT_VAL);
00315   }
00316 
00317   template <class View, class Card, bool isView>
00318   forceinline
00319   Val<View, Card, isView>::Val(Space* home, bool share,
00320                                Val<View, Card, isView>& p)
00321     : Propagator(home,share,p), card_all(p.card_all){
00322     x.update(home,share, p.x);
00323     k.update(home,share, p.k);
00324   }
00325 
00326   template <class View, class Card, bool isView>
00327   size_t
00328   Val<View, Card, isView>::dispose(Space* home) {
00329     if (!home->failed()) {
00330       x.cancel(home,this, PC_INT_VAL);
00331       k.cancel(home,this, PC_INT_VAL);
00332     }
00333     (void) Propagator::dispose(home);
00334     return sizeof(*this);
00335   }
00336 
00337   template <class View, class Card, bool isView>
00338   Actor*
00339   Val<View, Card, isView>::copy(Space* home, bool share) {
00340     return new (home) Val<View, Card, isView>(home,share,*this);
00341   }
00342 
00343   template <class View, class Card, bool isView>
00344   ExecStatus
00345   Val<View, Card, isView>::post(Space* home,
00346                                 ViewArray<View>& x0,
00347                                 ViewArray<Card>& k0, bool all) {
00348     new (home) Val<View, Card, isView>(home, x0, k0, all);
00349     return ES_OK;
00350   }
00351 
00357   template <class View, class Card, bool isView>
00358   PropCost
00359   Val<View, Card, isView>::cost (void) const {
00360     return PC_LINEAR_HI;
00361   }
00362 
00363   template <class View, class Card, bool isView>
00364   ExecStatus
00365   Val<View, Card, isView>::propagate(Space* home) {
00366     assert(x.size() > 0);
00367     return prop_val<View, Card, isView>(home, x, k, card_all);
00368   }
00369 
00370 }}}
00371 
00372 // STATISTICS: int-prop
00373