Generated on Mon Aug 25 11:35:37 2008 for Gecode by doxygen 1.5.6

gccbndsup.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00005  *
00006  *  Copyright:
00007  *     Patrick Pekczynski, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2007-12-17 16:27:54 +0100 (Mon, 17 Dec 2007) $ by $Author: schulte $
00011  *     $Revision: 5731 $
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 GCC {
00039 
00041 
00042 
00048   class UnReachable {
00049   public:
00050     unsigned int minb;
00051     unsigned int maxb;
00052     unsigned int eq;
00053     unsigned int le;
00054     unsigned int gr;
00055   };
00056 
00061   template <class View, class Card, bool shared>
00062   inline ExecStatus
00063   prop_card(Space* home, ViewArray<View>& x, ViewArray<Card>& k, bool& mod) {
00064     int n = x.size();
00065     int m = k.size();
00066     GECODE_AUTOARRAY(UnReachable, rv, m);
00067     for(int i = m; i--; ) {
00068       rv[i].minb    = 0;
00069       rv[i].maxb    = 0;
00070       rv[i].le = 0;
00071       rv[i].gr = 0;
00072       rv[i].eq = 0;
00073     }
00074 
00075     for (int i = n; i--; ) {
00076       int b = x[i].assigned();
00077       int min_idx = 0;
00078       int max_idx = 0;
00079       min_idx = lookupValue(k,x[i].min());
00080       if (min_idx == -1) {
00081         return ES_FAILED;
00082       }
00083       if (b) {
00084         rv[min_idx].minb++;
00085         rv[min_idx].maxb++;
00086         rv[min_idx].eq++;
00087       } else {
00088         max_idx = lookupValue(k,x[i].max());
00089         if (max_idx == -1) {
00090           return ES_FAILED;
00091         }
00092         // count the number of variables
00093         // with lower bound k[min_idx].card()
00094         rv[min_idx].minb++;
00095 
00096         // count the number of variables
00097         // with upper bound k[max_idx].card()
00098         rv[max_idx].maxb++;
00099       }
00100     }
00101 
00102     rv[0].le = 0;
00103     int c_min = 0;
00104     for (int i = 1; i < m; i++) {
00105       rv[i].le = c_min + rv[i - 1].maxb;
00106       c_min += rv[i - 1].maxb;
00107     }
00108 
00109     rv[m-1].gr = 0;
00110     int c_max = 0;
00111     for (int i = m-1; i--; ) {
00112       rv[i].gr = c_max + rv[i + 1].minb;
00113       c_max += rv[i + 1].minb;
00114     }
00115 
00116     for (int i = m; i--; ) {
00117       int reachable = (int) (x.size() - rv[i].le - rv[i].gr);
00118       if (!k[i].assigned()) {
00119         ModEvent me = k[i].lq(home, reachable);
00120         if (me_failed(me))
00121           return ES_FAILED;
00122         mod |= (me_modified(me) && (k[i].max() != reachable));
00123         mod |= shared && me_modified(me);
00124         
00125         if (rv[i].eq > 0) {
00126           ModEvent me = k[i].gq(home, (int) rv[i].eq);
00127           if (me_failed(me))
00128             return ES_FAILED;
00129           mod |= (me_modified(me) && (k[i].min() != (int) rv[i].eq));
00130           mod |= shared && me_modified(me);
00131         }
00132       } else {
00133         // check validity of the cardinality value
00134         int v = k[i].max();
00135         if ( !( (int) rv[i].eq <= v && v <= reachable) )
00136           return ES_FAILED;
00137       }
00138     }
00139 
00140     return ES_OK;
00141   }
00142 
00143 
00147   template <class View, class Card>
00148   inline bool
00149   card_consistent(int& smin, int& smax, ViewArray<View>& x,
00150                   ViewArray<Card>& k) {
00151 
00152     int m = k.size();
00153     int n = x.size();
00154     for (int i = m; i--; ) {
00155       smax += k[i].max();
00156       smin += k[i].min();
00157     }
00158 
00159     // not enough variables to satifsy cardinality requirements
00160     if (n < smin) {
00161       return false;
00162     }
00163 
00164     // we are using ALL variables
00165     // not all variables can be assigned
00166     if (smax < n) {
00167       return false;
00168     }
00169 
00170     return true;
00171   }
00172 
00176   class Rank {
00177   public:
00182     int min;
00187     int max;
00188   };
00189 
00197   template <class View>
00198   class MaxInc {
00199   protected:
00200     ViewArray<View> x;
00201   public:
00202     MaxInc(const ViewArray<View>& x0) : x(x0) {}
00203     forceinline bool
00204     operator()(const int i, const int j) {
00205       return x[i].max() < x[j].max();
00206     }
00207   };
00208 
00216   template <class View>
00217   class MinInc {
00218   protected:
00219     ViewArray<View> x;
00220   public:
00221     MinInc(const ViewArray<View>& x0) : x(x0) {}
00222     forceinline bool
00223     operator()(const int i, const int j) {
00224       return x[i].min() < x[j].min();
00225     }
00226   };
00227 
00228 
00234   template <class Card>
00235   class PartialSum {
00236   private:
00238     char* mem;
00240     size_t _allocated;
00242     int* sum;
00247     int* ds;
00249     int size;
00250   public:
00252 
00253     PartialSum( int, int, ViewArray<Card>& , bool);
00254     ~PartialSum(void);
00256 
00257 
00258     int firstValue;
00259     int lastValue;
00260     int sumup(int, int);
00261     int minValue(void);
00262     int maxValue(void);
00263     int skipNonNullElementsRight(int);
00264     int skipNonNullElementsLeft(int);
00265     void* operator new(size_t s);
00266     void operator delete(void* p);
00267     void print(void);
00268     bool check_update_max(ViewArray<Card>& k);
00269     bool check_update_min(ViewArray<Card>& k);
00270     int getsize(void) const;
00271     size_t allocated(void) const;
00273   };
00274 
00276   template <class Card>
00277   forceinline
00278   PartialSum<Card>::~PartialSum(void){
00279     assert(mem != NULL);
00280     Memory::free(mem);
00281   }
00282 
00284   template <class Card>
00285   forceinline void*
00286   PartialSum<Card>::operator new(size_t t){
00287     return Memory::malloc(t);
00288   }
00289 
00291   template <class Card>
00292   forceinline void
00293   PartialSum<Card>::operator delete(void* p){
00294       Memory::free(p);
00295   }
00296 
00309   template <class Card>
00310   inline
00311   PartialSum<Card>::PartialSum(int first,
00312                                int count,
00313                                ViewArray<Card>& elements,
00314                                bool up) {
00315     int i = 0;
00316     int j = 0;
00317     // we add three elements at the beginning and two at the end
00318     size  = count + 5;
00319     // memory allocation
00320     size_t sum_size = (size) * sizeof(int);
00321     size_t ds_size  = (size) * sizeof(int);
00322     size_t total    = sum_size + ds_size;
00323     _allocated = total;
00324 
00325     mem = static_cast<char*>(Memory::malloc(total));
00326     sum = Support::ptr_cast<int*>(mem);
00327     ds  = Support::ptr_cast<int*>(mem + sum_size);
00328 
00329     for (int z = 0; z < size; z++) {
00330       sum[z] = 0;
00331       ds[z]  = 0;
00332     }
00333 
00334     /*
00335      * firstValue and lastValue are sentinels
00336      * indicating whether an end of the sum has been reached
00337      *
00338      */
00339     firstValue = first - 3;
00340     lastValue  = first + count + 1;
00341 
00342 
00343     // the first three elements
00344     for (i = 3; i--; ){
00345       sum[i] = i;
00346     }
00347 
00348     int shift  = count + 2;
00349 
00350     /*
00351      * copy the bounds into sum
00352      * optimization only those values being indeed
00353      * variable bounds
00354      */
00355     for (i = 2; i < shift; i++){
00356       if (up) {
00357         sum[i + 1] = sum[i] + elements[i - 2].max();
00358       } else {
00359         sum[i + 1] = sum[i] + elements[i - 2].min();
00360       }
00361     }
00362     sum[i + 1] = sum[i] + 1;
00363     sum[i + 2] = sum[i + 1] + 1;
00364 
00365 
00366     // check for doublets
00367     i = count + 3;
00368     j = i + 1;
00369     for ( ; i > 0; ){
00370       while(sum[i] == sum[i - 1]) {
00371         ds[i] = j;
00372         i--;
00373       }
00374       ds[j] = i;
00375       i--;
00376       j = ds[j];
00377     }
00378     ds[j] = 0;
00379     // for the sake of having no seg fault
00380     ds[0] = 0;
00381   }
00382 
00386   template <class Card>
00387   forceinline int
00388   PartialSum<Card>::sumup(int from, int to){
00389     if (from <= to) {
00390       return sum[to - firstValue] - sum[from - firstValue - 1];
00391     } else {
00392       return sum[to - firstValue - 1] - sum[from - firstValue];
00393     }
00394   }
00395 
00400   template <class Card>
00401   forceinline int
00402   PartialSum<Card>::minValue(void){
00403     return firstValue + 3;
00404   }
00405 
00411   template <class Card>
00412   forceinline int
00413   PartialSum<Card>::maxValue(void){
00414     return lastValue - 2;
00415   }
00416 
00417 
00423   template <class Card>
00424   forceinline int
00425   PartialSum<Card>::skipNonNullElementsRight(int value) {
00426     value -= firstValue;
00427     return (ds[value] < value ? value : ds[value]) + firstValue;
00428   }
00429 
00435   template <class Card>
00436   forceinline int
00437   PartialSum<Card>::skipNonNullElementsLeft(int value) {
00438     value -= firstValue;
00439     return (ds[value] > value ? ds[ds[value]] : value) + firstValue;
00440   }
00441 
00443   template <class Card>
00444   void
00445   PartialSum<Card>::print(void){
00446     std::cout << "----------\n";
00447     std::cout << "smallest elem = "<< minValue() << " - "
00448               << "largest  elem = "<< maxValue() << "\n";
00449     std::cout << "fsv: "<< firstValue <<" lsv: " << lastValue
00450               << " size = "<< size << "\n";
00451     std::cout << "number of elements = "<< size - 5<<"\n";
00452     std::cout << "elements: ";
00453     for (int i = 3; i < size - 2; i++) {
00454       std::cout << sum[i] - sum[i-1] << " ";
00455     }
00456     std::cout <<"\n";
00457 
00458     std::cout << "sum: ";
00459     for (int i = 0; i < size; i++) {
00460       std::cout <<sum[i] << " ";
00461     }
00462     std::cout <<"\n";
00463     std::cout << "ds: ";
00464     for (int i = 0; i < size; i++) {
00465       std::cout <<sum[i] << " ";
00466     }
00467     std::cout <<"\n";
00468 
00469   }
00470 
00479   template <class Card>
00480   inline bool
00481   PartialSum<Card>::check_update_max(ViewArray<Card>& k){
00482     if (k.size() <= size - 5) {
00483       return true;
00484     } else {
00485       for (int i = 3; i < size - 2; i++) {
00486         if ((sum[i] - sum[i - 1]) != k[i - 3].max()) {
00487           return true;
00488         }
00489       }
00490       return false;
00491     }
00492   }
00493 
00502   template <class Card>
00503   inline bool
00504   PartialSum<Card>::check_update_min(ViewArray<Card>& k){
00505     if (k.size() <= size - 5) {
00506       return true;
00507     } else {
00508       for (int i = 3; i < size - 2; i++) {
00509         if ((sum[i] - sum[i - 1]) != k[i - 3].min()) {
00510           return true;
00511         }
00512       }
00513       return false;
00514     }
00515   }
00516 
00518   template <class Card>
00519   forceinline int
00520   PartialSum<Card>::getsize(void) const {
00521     return size;
00522   }
00523   template <class Card>
00524   forceinline size_t
00525   PartialSum<Card>::allocated(void) const {
00526     return sizeof(PartialSum<Card>) + _allocated;
00527   }
00528 
00529 
00540   class HallInfo {
00541   public:
00543     int bounds;
00549     int t;
00557     int d;
00566     int h;
00571     int s;
00576     int ps;
00583     int newBound;
00584   };
00585 
00586 
00596 
00597   inline void
00598   pathset_ps(HallInfo hall[], int start, int end, int to) {
00599     int k, l;
00600     for (l=start; (k=l) != end; hall[k].ps=to) {
00601       l = hall[k].ps;
00602     }
00603   }
00604 
00606   inline void
00607   pathset_s(HallInfo hall[], int start, int end, int to) {
00608     int k, l;
00609     for (l=start; (k=l) != end; hall[k].s=to) {
00610       l = hall[k].s;
00611     }
00612   }
00613 
00615   inline void
00616   pathset_t(HallInfo hall[], int start, int end, int to) {
00617     int k, l;
00618     for (l=start; (k=l) != end; hall[k].t=to) {
00619       l = hall[k].t;
00620     }
00621   }
00622 
00624   inline void
00625   pathset_h(HallInfo hall[], int start, int end, int to) {
00626     int k, l;
00627     for (l=start; (k=l) != end; hall[k].h=to) {
00628       l = hall[k].h;
00629     }
00630   }
00632 
00640 
00641   forceinline int
00642   pathmin_h(const HallInfo hall[], int i) {
00643     while (hall[i].h < i)
00644       i = hall[i].h;
00645     return i;
00646   }
00648   forceinline int
00649   pathmin_t(const HallInfo hall[], int i) {
00650     while (hall[i].t < i)
00651       i = hall[i].t;
00652     return i;
00653   }
00655 
00662 
00663   forceinline int
00664   pathmax_h(const HallInfo hall[], int i) {
00665     while (hall[i].h > i)
00666       i = hall[i].h;
00667     return i;
00668   }
00669 
00670 
00672   forceinline int
00673   pathmax_t(const HallInfo hall[], int i) {
00674     while (hall[i].t > i) {
00675       i = hall[i].t;
00676     }
00677     return i;
00678   }
00679 
00681   forceinline int
00682   pathmax_s(const HallInfo hall[], int i) {
00683     while (hall[i].s > i)
00684       i = hall[i].s;
00685     return i;
00686   }
00687 
00689   forceinline int
00690   pathmax_ps(const HallInfo hall[], int i) {
00691     while (hall[i].ps > i)
00692       i = hall[i].ps;
00693     return i;
00694   }
00696 
00697 
00707   template <class Card>
00708   void
00709   reduce_card(int cmin, int cmax, ViewArray<Card>& k) {
00710     if (cmin == cmax) {
00711       int idx = 0;
00712       while (k[idx].card() != cmax) {
00713         idx++;
00714       }
00715       k[0] = k[idx];
00716       k.size(1);
00717     } else {
00718       GECODE_AUTOARRAY(bool, zero, k.size());
00719       int ks = k.size();
00720       int zc = 0;
00721       for (int i = 0; i < ks; i++) {
00722         bool impossible  = ( (k[i].counter() == 0) &&
00723                              (k[i].card() < cmin ||
00724                               k[i].card() > cmax));
00725         
00726         if (impossible) {
00727           zero[i] = true;
00728           zc++;
00729         } else {
00730           zero[i] = false;
00731         }
00732       }
00733 
00734 
00735       if (zero[ks - 1]) {
00736         int m = ks;
00737         while(zero[m - 1]) {
00738           m--;
00739           zc--;
00740         }
00741         k.size(m);
00742       }
00743 
00744       if (zc > 0) {
00745         int ks = k.size();
00746         // if there are still zero entries left
00747         for (int i = 0; i < ks; i++) {
00748           assert(0 <= i && i < ks);
00749           if  (zero[i]) {
00750             if (i == ks - 1) {
00751               break;
00752             }
00753             // this cardinality does not occur
00754             // remove it
00755             // we need the next non-null entry
00756             int j = i + 1;
00757             assert(0 <= j && j < ks);
00758             if (j < ks) {
00759               while (zero[j]) {
00760                 j++;
00761               }
00762             }
00763             if (j > ks - 1) {
00764               break;
00765             }
00766             k[i] = k[j];
00767             zero[j] = true;
00768           }
00769         }
00770         k.size(ks - zc);
00771       }
00772 
00773     }
00774 
00775   }
00776 
00777 }}}
00778 
00779 // STATISTICS: int-prop
00780