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

gccbndsup.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, 2004
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 
00022 namespace Gecode { namespace Int { namespace GCC {
00023 
00025 
00026 
00032   class UnReachable {
00033   public:
00034     unsigned int minb;
00035     unsigned int maxb;
00036     unsigned int eq;
00037     unsigned int le;
00038     unsigned int gr;
00039   };
00040 
00045   template <class View, class Card, bool shared>
00046   forceinline ExecStatus
00047   prop_card(Space* home, ViewArray<View>& x, ViewArray<Card>& k, bool& mod) {
00048     int n = x.size();
00049     int m = k.size();
00050     GECODE_AUTOARRAY(UnReachable, rv, m);
00051     for(int i = m; i--; ) {
00052       rv[i].minb    = 0;
00053       rv[i].maxb    = 0;
00054       rv[i].le = 0;
00055       rv[i].gr = 0;
00056       rv[i].eq = 0;
00057     }
00058 
00059     for (int i = n; i--; ) {
00060       int b = x[i].assigned();
00061       int min_idx = 0;
00062       int max_idx = 0;
00063       min_idx = lookupValue(k,x[i].min());
00064       if (min_idx == -1) {
00065         return ES_FAILED;
00066       }
00067       if (b) {
00068         rv[min_idx].minb++;
00069         rv[min_idx].maxb++;
00070         rv[min_idx].eq++;
00071       } else {
00072         max_idx = lookupValue(k,x[i].max());
00073         if (max_idx == -1) {
00074           return ES_FAILED;
00075         }
00076         // count the number of variables
00077         // with lower bound k[min_idx].card()
00078         rv[min_idx].minb++;
00079 
00080         // count the number of variables
00081         // with upper bound k[max_idx].card()
00082         rv[max_idx].maxb++;
00083       }
00084     }
00085 
00086     rv[0].le = 0;
00087     int c_min = 0;
00088     for (int i = 1; i < m; i++) {
00089       rv[i].le = c_min + rv[i - 1].maxb;
00090       c_min += rv[i - 1].maxb;
00091     }
00092 
00093     rv[m-1].gr = 0;
00094     int c_max = 0;
00095     for (int i = m-1; i--; ) {
00096       rv[i].gr = c_max + rv[i + 1].minb;
00097       c_max += rv[i + 1].minb;
00098     }
00099 
00100     for (int i = m; i--; ) {
00101       int reachable = (int) (x.size() - rv[i].le - rv[i].gr);
00102       if (!k[i].assigned()) {
00103         ModEvent me = k[i].lq(home, reachable);
00104         if (me_failed(me)) {
00105           return ES_FAILED;
00106         }
00107         mod |= (k[i].modified() && (k[i].max() != reachable));
00108         mod |= shared && k[i].modified();
00109         
00110         if (rv[i].eq > 0) {
00111           ModEvent me = k[i].gq(home, (int) rv[i].eq);
00112           if (me_failed(me)) {
00113             return ES_FAILED;
00114           }
00115           mod |= (k[i].modified() && (k[i].min() != (int) rv[i].eq));
00116           mod |= shared && k[i].modified();
00117         }
00118       } else {
00119         // check validity of the cardinality value
00120         int v = k[i].max();
00121         if ( !( (int) rv[i].eq <= v && v <= reachable) ) {
00122           return ES_FAILED;
00123         }
00124       }
00125     }
00126 
00127     return ES_OK;
00128   }
00129 
00130 
00134   template <class View, class Card>
00135   inline bool
00136   card_consistent(int& smin, int& smax, ViewArray<View>& x,
00137                   ViewArray<Card>& k, bool& all) {
00138 
00139     int m = k.size();
00140     int n = x.size();
00141     for (int i = m; i--; ) {
00142       smax += k[i].max();
00143       smin += k[i].min();
00144     }
00145 
00146     // not enough variables to satifsy cardinality requirements
00147     if (n < smin) {
00148       return false;
00149     }
00150 
00151     // if we use all variables
00152     // not all variables can be assigned
00153     if (all && smax < n) {
00154       return false;
00155     }
00156 
00157     return true;
00158   }
00159 
00163   class Rank {
00164   public:
00169     int min;
00174     int max;
00175   };
00176 
00184   template <class View>
00185   class MaxInc {
00186   protected:
00187     ViewArray<View> x;
00188   public:
00189     MaxInc(const ViewArray<View>& x0) : x(x0) {}
00190     forceinline bool
00191     operator()(const int i, const int j) {
00192       return x[i].max() < x[j].max();
00193     }
00194   };
00195 
00203   template <class View>
00204   class MinInc {
00205   protected:
00206     ViewArray<View> x;
00207   public:
00208     MinInc(const ViewArray<View>& x0) : x(x0) {}
00209     forceinline bool
00210     operator()(const int i, const int j) {
00211       return x[i].min() < x[j].min();
00212     }
00213   };
00214 
00215 
00221   template <class Card>
00222   class PartialSum {
00223   private:
00225     char* mem;
00227     int* sum;
00232     int* ds;
00234     int size;
00235   public:
00237 
00238     PartialSum( int, int, ViewArray<Card>& , bool);
00239     ~PartialSum(void);
00241 
00242 
00243     int firstValue;
00244     int lastValue;
00245     int sumup(int, int);
00246     int minValue(void);
00247     int maxValue(void);
00248     int skipNonNullElementsRight(int);
00249     int skipNonNullElementsLeft(int);
00250     void* operator new(size_t s);
00251     void operator delete(void* p);
00252     void print(void);
00253     bool check_update_max(ViewArray<Card>& k);
00254     bool check_update_min(ViewArray<Card>& k);
00255     int getsize(void);
00257   };
00258 
00260   template <class Card>
00261   forceinline
00262   PartialSum<Card>::~PartialSum(void){
00263     assert(mem != NULL);
00264     Memory::free(mem);
00265   }
00266 
00268   template <class Card>
00269   forceinline void*
00270   PartialSum<Card>::operator new(size_t t){
00271     void* allocated = Memory::malloc(t);
00272     return allocated;
00273   }
00274 
00276   template <class Card>
00277   forceinline void
00278   PartialSum<Card>::operator delete(void* p){
00279       Memory::free(p);
00280   }
00281 
00294   template <class Card>
00295   inline
00296   PartialSum<Card>::PartialSum(int first,
00297                                int count,
00298                                ViewArray<Card>& elements,
00299                                bool up) {
00300     int i = 0;
00301     int j = 0;
00302     // we add three elements at the beginning and two at the end
00303     size  = count + 5;
00304     // memory allocation
00305     size_t sum_size = (size) * sizeof(int);
00306     size_t ds_size  = (size) * sizeof(int);
00307     size_t total    = sum_size + ds_size;
00308 
00309     mem = reinterpret_cast<char*> (Memory::malloc(total));
00310     sum = reinterpret_cast<int*> (mem);
00311     ds  = reinterpret_cast<int*> (mem + sum_size);
00312 
00313     for (int z = 0; z < size; z++) {
00314       sum[z] = 0;
00315       ds[z]  = 0;
00316     }
00317 
00318     /*
00319      * firstValue and lastValue are sentinels
00320      * indicating whether an end of the sum has been reached
00321      *
00322      */
00323     firstValue = first - 3;
00324     lastValue  = first + count + 1;
00325 
00326 
00327     // the first three elements
00328     for (i = 3; i--; ){
00329       sum[i] = i;
00330     }
00331 
00332     int shift  = count + 2;
00333 
00334     /*
00335      * copy the bounds into sum
00336      * optimization only those values being indeed
00337      * variable bounds
00338      */
00339     for (i = 2; i < shift; i++){
00340       if (up) {
00341         sum[i + 1] = sum[i] + elements[i - 2].max();
00342       } else {
00343         sum[i + 1] = sum[i] + elements[i - 2].min();
00344       }
00345     }
00346     sum[i + 1] = sum[i] + 1;
00347     sum[i + 2] = sum[i + 1] + 1;
00348 
00349 
00350     // check for doublets
00351     i = count + 3;
00352     j = i + 1;
00353     for ( ; i > 0; ){
00354       while(sum[i] == sum[i - 1]) {
00355         ds[i] = j;
00356         i--;
00357       }
00358       ds[j] = i;
00359       i--;
00360       j = ds[j];
00361     }
00362     ds[j] = 0;
00363     // for the sake of having no seg fault
00364     ds[0] = 0;
00365   }
00366 
00370   template <class Card>
00371   forceinline int
00372   PartialSum<Card>::sumup(int from, int to){
00373     if (from <= to) {
00374       return sum[to - firstValue] - sum[from - firstValue - 1];
00375     } else {
00376       return sum[to - firstValue - 1] - sum[from - firstValue];
00377     }
00378   }
00379 
00384   template <class Card>
00385   forceinline int
00386   PartialSum<Card>::minValue(void){
00387     return firstValue + 3;
00388   }
00389 
00395   template <class Card>
00396   forceinline int
00397   PartialSum<Card>::maxValue(void){
00398     return lastValue - 2;
00399   }
00400 
00401 
00407   template <class Card>
00408   forceinline int
00409   PartialSum<Card>::skipNonNullElementsRight(int value) {
00410     value -= firstValue;
00411     return (ds[value] < value ? value : ds[value]) + firstValue;
00412   }
00413 
00419   template <class Card>
00420   forceinline int
00421   PartialSum<Card>::skipNonNullElementsLeft(int value) {
00422     value -= firstValue;
00423     return (ds[value] > value ? ds[ds[value]] : value) + firstValue;
00424   }
00425 
00427   template <class Card>
00428   void
00429   PartialSum<Card>::print(void){
00430     std::cout << "----------\n";
00431     std::cout << "smallest elem = "<< minValue() << " - "
00432               << "largest  elem = "<< maxValue() << "\n";
00433     std::cout << "fsv: "<< firstValue <<" lsv: " << lastValue
00434               << " size = "<< size << "\n";
00435     std::cout << "number of elements = "<< size - 5<<"\n";
00436     std::cout << "elements: ";
00437     for (int i = 3; i < size - 2; i++) {
00438       std::cout << sum[i] - sum[i-1] << " ";
00439     }
00440     std::cout <<"\n";
00441 
00442     std::cout << "sum: ";
00443     for (int i = 0; i < size; i++) {
00444       std::cout <<sum[i] << " ";
00445     }
00446     std::cout <<"\n";
00447     std::cout << "ds: ";
00448     for (int i = 0; i < size; i++) {
00449       std::cout <<sum[i] << " ";
00450     }
00451     std::cout <<"\n";
00452 
00453   }
00454 
00463   template <class Card>
00464   inline bool
00465   PartialSum<Card>::check_update_max(ViewArray<Card>& k){
00466     if (k.size() <= size - 5) {
00467       return true;
00468     } else {
00469       for (int i = 3; i < size - 2; i++) {
00470         if ((sum[i] - sum[i - 1]) != k[i - 3].max()) {
00471           return true;
00472         }
00473       }
00474       return false;
00475     }
00476   }
00477 
00486   template <class Card>
00487   inline bool
00488   PartialSum<Card>::check_update_min(ViewArray<Card>& k){
00489     if (k.size() <= size - 5) {
00490       return true;
00491     } else {
00492       for (int i = 3; i < size - 2; i++) {
00493         if ((sum[i] - sum[i - 1]) != k[i - 3].min()) {
00494           return true;
00495         }
00496       }
00497       return false;
00498     }
00499   }
00500 
00502   template <class Card>
00503   forceinline int
00504   PartialSum<Card>::getsize(void){
00505     return size;
00506   }
00507 
00508 
00519   class HallInfo {
00520   public:
00522     int bounds;
00528     int t;
00536     int d;
00545     int h;
00550     int s;
00555     int ps;
00562     int newBound;
00563   };
00564 
00565 
00575 
00576   inline void
00577   pathset_ps(HallInfo hall[], int start, int end, int to) {
00578     int k, l;
00579     for (l=start; (k=l) != end; hall[k].ps=to) {
00580       l = hall[k].ps;
00581     }
00582   }
00583 
00585   inline void
00586   pathset_s(HallInfo hall[], int start, int end, int to) {
00587     int k, l;
00588     for (l=start; (k=l) != end; hall[k].s=to) {
00589       l = hall[k].s;
00590     }
00591   }
00592 
00594   inline void
00595   pathset_t(HallInfo hall[], int start, int end, int to) {
00596     int k, l;
00597     for (l=start; (k=l) != end; hall[k].t=to) {
00598       l = hall[k].t;
00599     }
00600   }
00601 
00603   inline void
00604   pathset_h(HallInfo hall[], int start, int end, int to) {
00605     int k, l;
00606     for (l=start; (k=l) != end; hall[k].h=to) {
00607       l = hall[k].h;
00608     }
00609   }
00611 
00619 
00620   forceinline int
00621   pathmin_h(const HallInfo hall[], int i) {
00622     while (hall[i].h < i)
00623       i = hall[i].h;
00624     return i;
00625   }
00627   forceinline int
00628   pathmin_t(const HallInfo hall[], int i) {
00629     while (hall[i].t < i)
00630       i = hall[i].t;
00631     return i;
00632   }
00634 
00641 
00642   forceinline int
00643   pathmax_h(const HallInfo hall[], int i) {
00644     while (hall[i].h > i)
00645       i = hall[i].h;
00646     return i;
00647   }
00648 
00649 
00651   forceinline int
00652   pathmax_t(const HallInfo hall[], int i) {
00653     while (hall[i].t > i) {
00654       i = hall[i].t;
00655     }
00656     return i;
00657   }
00658 
00660   forceinline int
00661   pathmax_s(const HallInfo hall[], int i) {
00662     while (hall[i].s > i)
00663       i = hall[i].s;
00664     return i;
00665   }
00666 
00668   forceinline int
00669   pathmax_ps(const HallInfo hall[], int i) {
00670     while (hall[i].ps > i)
00671       i = hall[i].ps;
00672     return i;
00673   }
00675 
00676 
00686   template <class Card>
00687   void
00688   reduce_card(int cmin, int cmax, ViewArray<Card>& k) {
00689     if (cmin == cmax) {
00690       int idx = 0;
00691       while (k[idx].card() != cmax) {
00692         idx++;
00693       }
00694       k[0] = k[idx];
00695       k.size(1);
00696     } else {
00697 
00698       GECODE_AUTOARRAY(bool, zero, k.size());
00699       int ks = k.size();
00700       int zc = 0;
00701       for (int i = 0; i < ks; i++) {
00702         bool impossible  = ( (k[i].counter() == 0) &&
00703                              (k[i].card() < cmin ||
00704                               k[i].card() > cmax));
00705         
00706         if (impossible) {
00707           zero[i] = true;
00708           zc++;
00709         } else {
00710           zero[i] = false;
00711         }
00712       }
00713 
00714 
00715       if (zero[ks - 1]) {
00716         int m = ks;
00717         while(zero[m - 1]) {
00718           m--;
00719           zc--;
00720         }
00721         k.size(m);
00722       }
00723 
00724       if (zc > 0) {
00725         int ks = k.size();
00726         // if there are still zero entries left
00727         for (int i = 0; i < ks; i++) {
00728           assert(0 <= i && i < ks);
00729           if  (zero[i]) {
00730             if (i == ks - 1) {
00731               break;
00732             }
00733             // this cardinality does not occur
00734             // remove it
00735             // we need the next non-null entry
00736             int j = i + 1;
00737             assert(0 <= j && j < ks);
00738             if (j < ks) {
00739               while (zero[j]) {
00740                 j++;
00741               }
00742             }
00743             if (j > ks - 1) {
00744               break;
00745             }
00746             k[i] = k[j];
00747             zero[j] = true;
00748           }
00749         }
00750         k.size(ks - zc);
00751       }
00752 
00753     }
00754 
00755   }
00756 
00757 }}}
00758 
00759 // STATISTICS: int-prop
00760