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

sortsup.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 Sortedness {
00023 
00025   template<class View>
00026   void pview(View& v){
00027     if (v.min() == v.max()) {
00028       std::cout << v.min() <<" ";
00029     } else {
00030       if (v.range()){
00031         std::cout << "["<<v.min() <<".."<<v.max()<<"] ";
00032       } else {
00033         std::cout << "{";
00034         ViewValues<View> iter(v);
00035         while(iter()){
00036           std::cout << iter.val() <<",";
00037           ++iter;
00038         }
00039         std::cout << "} ";
00040       }
00041     }
00042   }
00043 
00045   template <class T, unsigned int n>
00046   inline std::ostream&
00047   operator<<(std::ostream& os, ViewTuple<T,n>& xs) {
00048     if (n > 1) { os << "<";}
00049     if (xs[0].min() == xs[0].max()) {
00050       os << xs[0].min();
00051       if (n > 1) {
00052         std::cout << ",";
00053         if (xs[1].min() == xs[1].max()) {
00054           os << xs[1].min() <<" ";
00055         } else {
00056           os << "["<<xs[1].min() <<".."<<xs[1].max()<<"]("<<xs[1].range()<<") ";
00057         }
00058       }
00059     } else {
00060       os << "["<<xs[0].min() <<".."<<xs[0].max()<<"]("<<xs[0].range()<<")";
00061       if (n > 1) {
00062         std::cout << ", ";
00063         if (xs[1].min() == xs[1].max()) {
00064           os << xs[1].min() <<" ";
00065         } else {
00066           os << "["<<xs[1].min() <<".."<<xs[1].max()<<"]("<<xs[1].range()<<") ";
00067         }
00068       }
00069     }
00070 //  else {
00071 //      os << "{";
00072 //      ViewValues<View> iter(xs[0]);
00073 //      while(iter()){
00074 //        os << iter.val() <<",";
00075 //        ++iter;
00076 //      }
00077 //      os << "} ";
00078 //       }
00079     if (n > 1) { os << ">";}
00080     return os;
00081   }
00082 
00086   class Rank {
00087   public:
00088     // stores the mininmum of a variable
00089     int min;
00090     // stores the mininmum of a variable
00091     int max;
00092   };
00093 
00100   class SccComponent {
00101   public:
00103     int leftmost;
00105     int left;
00107     int right;
00109     int rightmost;
00110   };
00111 
00125   template<class View, class Tuple, bool Perm>
00126   forceinline bool
00127   check_subsumption(Space* home,
00128                     ViewArray<Tuple>& xz,
00129                     ViewArray<View>& y,
00130                     bool& subsumed,
00131                     int& dropfst) {
00132 
00133     dropfst  = 0;
00134     subsumed = true;
00135     int  xs  = xz.size();
00136     for (int i = 0; i < xs ; i++) {
00137       if (Perm) {
00138         subsumed &= (xz[i][0].assigned() &&
00139                      xz[i][1].assigned() &&
00140                      y[xz[i][1].val()].assigned());
00141         if (subsumed) {
00142           if (xz[i][0].val() != y[xz[i][1].val()].val()) {
00143             return false;
00144           } else {
00145             if (xz[i][1].val() == i) {
00146               dropfst++;
00147             }
00148           }
00149         }
00150       } else {
00151         subsumed &= (xz[i][0].assigned() && y[i].assigned());
00152         if (subsumed) {
00153           if (xz[i][0].val() != y[i].val()) {
00154             return false;
00155           } else {
00156             dropfst++;
00157           }
00158         }
00159       }
00160     }
00161     return true;
00162   }
00163 
00169   class OfflineMinItem{
00170   public:
00172     int root;
00174     int parent;
00176     int rank;
00178     int name;
00186     int iset;
00188     int succ;
00190     int pred;
00191   };
00192 
00198   class OfflineMin {
00199   private:
00200     OfflineMinItem* sequence;
00201     int* vertices;
00202     int  n;
00203   public:
00204     OfflineMin(void);
00205     OfflineMin(OfflineMinItem[], int[], int);
00210     int  find(int x);
00215     int  find_pc(int x);
00217     void unite(int a, int b, int c);
00219     void makeset(void);
00221     int  size(void);
00222     OfflineMinItem& operator[](int);
00223   };
00224 
00225   OfflineMin::OfflineMin(void){
00226     n = 0;
00227     sequence = NULL;
00228     vertices = NULL;
00229   }
00230 
00231   OfflineMin::OfflineMin(OfflineMinItem s[], int v[], int size){
00232     n = size;
00233     sequence = &s[0];
00234     vertices = &v[0];
00235   }
00236 
00237   forceinline int
00238   OfflineMin::find(int x) {
00239     while (sequence[x].parent != x) {
00240       x = sequence[x].parent;
00241     }
00242     // x is now the root of the tree
00243     // return the set, x belongs to
00244     return sequence[x].name;
00245   }
00246 
00247   forceinline int
00248   OfflineMin::find_pc(int x){
00249     int vsize = 0;
00250     while (sequence[x].parent != x) {
00251       vertices[x] = x;
00252       x = sequence[x].parent;
00253     }
00254     // x is now the root of the tree
00255     for (int i = vsize; i--; ) {
00256       sequence[vertices[i]].parent = x;
00257     }
00258     // return the set, x belongs to
00259     return sequence[x].name;
00260   }
00261 
00262   forceinline void
00263   OfflineMin::unite(int a, int b, int c){
00264     // c is the union of a and b
00265     int ra = sequence[a].root;
00266     int rb = sequence[b].root;
00267     int large = rb;
00268     int small = ra;
00269     if (sequence[ra].rank > sequence[rb].rank) {
00270       large = ra;
00271       small = rb;
00272     }
00273     sequence[small].parent =  large;
00274     sequence[large].rank   += sequence[small].rank;
00275     sequence[large].name   =  c;
00276     sequence[c].root       =  large;
00277   }
00278 
00279   forceinline void
00280   OfflineMin::makeset(void){
00281     for(int i = n; i--; ){
00282       OfflineMinItem& cur = sequence[i];
00283       cur.rank   = 0;     // initially each set is empty
00284       cur.name   = i;     // it has its own name
00285       cur.root   = i;     // it is the root node
00286       cur.parent = i;     // it is its own parent
00287       cur.pred   = i - 1;
00288       cur.succ   = i + 1;
00289       cur.iset   = -5;
00290     }
00291   }
00292 
00293   forceinline int
00294   OfflineMin::size(void){
00295     return n;
00296   }
00297 
00298   forceinline OfflineMinItem&
00299   OfflineMin::operator [](int i){
00300     return sequence[i];
00301   }
00302 
00304   forceinline std::ostream&
00305   operator<<(std::ostream& os,  OfflineMin seq){
00306     for (int i = 0; i < seq.size();i++) {
00307       os << "Succ(" <<seq[i].succ   << ") "
00308          << "Pred(" <<seq[i].pred   << ") "
00309          << "Root(" <<seq[i].root   << ") "
00310          << "Par (" <<seq[i].parent << ") "
00311          << "Rank(" <<seq[i].rank   << ") "
00312          << "Name(" <<seq[i].name   << ") "
00313          << "Set (" <<seq[i].iset   << ") \n";
00314     }
00315     return os;
00316   }
00317 
00327   template <class Tuple>
00328   class TupleMaxInc {
00329   protected:
00330     ViewArray<Tuple> x;
00331   public:
00332     TupleMaxInc(const ViewArray<Tuple>& x0) : x(x0) {}
00333     bool operator()(const int i, const int j) {
00334       if (x[i][0].max() == x[j][0].max()) {
00335         return x[i][0].min() < x[j][0].min();
00336       } else {
00337         return x[i][0].max() < x[j][0].max();
00338       }
00339     }
00340   };
00341 
00342 
00352   template <class Tuple>
00353   class TupleMaxIncExt {
00354   protected:
00355     ViewArray<Tuple> x;
00356   public:
00357     TupleMaxIncExt(const ViewArray<Tuple>& x0) : x(x0) {}
00358     bool operator()(const int i, const int j) {
00359       if (x[i][0].max() == x[j][0].max()) {
00360         if (x[i][0].min() == x[j][0].min()) {
00361           if (x[i][1].max() == x[j][1].max()) {
00362             return x[i][1].min() < x[j][1].min();
00363           } else {
00364             return x[i][1].max() < x[j][1].max();
00365           }
00366         } else {
00367           return x[i][0].min() < x[j][0].min();
00368         }
00369       } else {
00370         return x[i][0].max() < x[j][0].max();
00371       }
00372     }
00373   };
00374 
00384   template <class View>
00385   class TupleMinInc {
00386   public:
00387     bool operator()(const View& x, const View& y) {
00388       if (x[0].min() == y[0].min()) {
00389         return x[0].max() < y[0].max();
00390       } else {
00391         return x[0].min() < y[0].min();
00392       }
00393     }
00394   };
00395 
00407   template <class View>
00408   class TupleMinIncExt {
00409   public:
00410     bool operator()(const View& x, const View& y) {
00411       if (x[0].min() == y[0].min()) {
00412         if (x[0].max() == y[0].max()) {
00413           if (x[1].min() == y[1].min()) {
00414             return x[1].max() < y[1].max();
00415           } else {
00416             return x[1].min() < y[1].min();
00417           }
00418         } else {
00419           return x[0].max() < y[0].max();
00420         }
00421       } else {
00422         return x[0].min() < y[0].min();
00423       }
00424     }
00425   };
00426 
00435   template <class View>
00436   class TupleMinIncPerm {
00437   public:
00438     bool operator()(const View& x, const View& y) {
00439       if (x[1].min() == y[1].min()) {
00440         return x[1].max() < y[1].max();
00441       } else {
00442         return x[1].min() < y[1].min();
00443       }
00444     }
00445   };
00446 
00455   template <class View>
00456   class TupleMaxIncPerm {
00457   public:
00458     bool operator()(const View& x, const View& y) {
00459       if (x[1].max() == y[1].max()) {
00460         return x[1].min() < y[1].min();
00461       } else {
00462         return x[1].max() < y[1].max();
00463       }
00464     }
00465   };
00466 
00474   template<class View, class Tuple, bool Perm>
00475   forceinline bool
00476   array_assigned(Space* home,
00477                  ViewArray<Tuple>& xz,
00478                  ViewArray<View>& y,
00479                  bool& subsumed,
00480                  bool& match_fixed,
00481                  bool& nofix,
00482                  bool& noperm_bc) {
00483 
00484     bool x_complete = true;
00485     bool y_complete = true;
00486     bool z_complete = true;
00487 
00488     for (int i = y.size(); i--; ) {
00489       x_complete &= xz[i][0].assigned();
00490       y_complete &= y[i].assigned();
00491       if (Perm) {
00492         z_complete &= xz[i][1].assigned();
00493       }
00494     }
00495 
00496     if (x_complete) {
00497       for (int i = xz.size(); i--; ) {
00498         ModEvent me = y[i].eq(home, xz[i][0].val());
00499         if (me_failed(me)) {
00500           return false;
00501         }
00502       }
00503       if (Perm) {
00504         subsumed = false;
00505       } else {
00506         subsumed = true;
00507       }
00508     }
00509 
00510     if (y_complete) {
00511       bool y_equality = true;
00512       for (int i = y.size() - 1; i--; ) {
00513         y_equality &= (y[i].val() == y[i + 1].val());
00514       }
00515       if (y_equality) {
00516         for (int i = xz.size(); i--; ) {
00517           ModEvent me = xz[i][0].eq(home, y[i].val());
00518           if (me_failed(me)) {
00519             return false;
00520           }
00521         }
00522         if (Perm) {
00523           subsumed = false;
00524         } else {
00525           subsumed = true;
00526         }
00527         noperm_bc = true;
00528       }
00529     }
00530 
00531     if (Perm) {
00532       if (z_complete) {
00533         if (x_complete) {
00534           for (int i = xz.size(); i--; ) {
00535             ModEvent me = y[xz[i][1].val()].eq(home, xz[i][0].val());
00536             if (me_failed(me)) {
00537               return false;
00538             }
00539           }
00540           subsumed = true;
00541           return subsumed;
00542         }
00543         if (y_complete) {
00544           for (int i = xz.size(); i--; ) {
00545             ModEvent me = xz[i][0].eq(home, y[xz[i][1].val()].val());
00546             if (me_failed(me)) {
00547               return false;
00548             }
00549           }
00550           subsumed = true;
00551           return subsumed;
00552         }
00553 
00554         // validate the permutation
00555         int sum = 0;
00556         for (int i = xz.size(); i--; ) {
00557           int pi = xz[i][1].val();
00558           if (xz[i][0].max() < y[pi].min() ||
00559               xz[i][0].min() > y[pi].max()) {
00560             return false;
00561           }
00562           sum += pi;
00563         }
00564         int n = xz.size();
00565         int gauss = ( (n * (n + 1)) / 2);
00566         // if the sum over all assigned permutation variables is not
00567         // equal to the gaussian sum - n they are not distinct, hence invalid
00568         if (sum != gauss - n) {
00569           return false;
00570         }
00571         match_fixed = true;
00572       }
00573     }
00574     return true;
00575   }
00576 
00584   template<class View, class Tuple, bool Perm>
00585   forceinline bool
00586   channel(Space* home, ViewArray<Tuple>& xz, ViewArray<View>& y, bool& nofix) {
00587     int n = xz.size();
00588     for (int i = n; i--; ) {
00589       if (xz[i][1].assigned()) {
00590 
00591         // if the permutation variable is determined
00592         
00593         int v = xz[i][1].val();
00594         if (xz[i][0].assigned()) {
00595           // channel equality from x to y
00596           ModEvent me = y[v].eq(home, xz[i][0].val());
00597           if (me_failed(me)) {
00598             return false;
00599           }
00600         } else {
00601           if (y[v].assigned()) {
00602             // channel equality from y to x
00603             ModEvent me = xz[i][0].eq(home, y[v].val());
00604             if (me_failed(me)) {
00605               return false;
00606             }
00607           } else {
00608             // constrain upper bound
00609             ModEvent me = xz[i][0].lq(home, y[v].max());
00610             if (me_failed(me)) {
00611               return false;
00612             }
00613             nofix |= (me_modified(me) && xz[i][0].max() != y[v].max());
00614 
00615             // constrain lower bound
00616             me = xz[i][0].gq(home, y[v].min());
00617             if (me_failed(me)) {
00618               return false;
00619             }
00620             nofix |= (me_modified(me) && xz[i][0].min() != y[v].min());
00621 
00622             // constrain the sorted variable
00623             // constrain upper bound
00624             me = y[v].lq(home, xz[i][0].max());
00625             if (me_failed(me)) {
00626               return false;
00627             }
00628             nofix |= (me_modified(me) && y[v].max() != xz[i][0].max());
00629 
00630             // constrain lower bound
00631             me = y[v].gq(home, xz[i][0].min());
00632             if (me_failed(me)) {
00633               return false;
00634             }
00635             nofix |= (me_modified(me) && y[v].min() != xz[i][0].min());
00636           }
00637         }
00638       } else {
00639         
00640         // if the permutation variable is undetermined
00641         int l = xz[i][1].min();
00642         int r = xz[i][1].max();
00643         
00644         // upper bound
00645         ModEvent me = xz[i][0].lq(home, y[r].max());
00646         if (me_failed(me)) {
00647           return false;
00648         }
00649         nofix |= (me_modified(me) && xz[i][0].max() != y[r].max());
00650 
00651         // lower bound
00652         me = xz[i][0].gq(home, y[l].min());
00653         if (me_failed(me)) {
00654           return false;
00655         }
00656         nofix |= (me_modified(me) && xz[i][0].min() != y[l].min());
00657       }
00658     }
00659     return true;
00660   }
00661 
00662 
00663 }}}
00664 
00665 
00666 // STATISTICS: int-prop