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

sortsup.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: 2008-07-11 09:33:32 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7290 $
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 Sorted {
00039 
00043   class Rank {
00044   public:
00046     int min;
00048     int max;
00049   };
00050 
00057   class SccComponent {
00058   public:
00060     int leftmost;
00062     int left;
00064     int right;
00066     int rightmost;
00067   };
00068 
00080   template<class View, bool Perm>
00081   inline bool
00082   check_subsumption(ViewArray<View>& x, ViewArray<View>& y, ViewArray<View>& z,
00083                     bool& subsumed, int& dropfst) {
00084 
00085     dropfst  = 0;
00086     subsumed = true;
00087     int  xs  = x.size();
00088     for (int i = 0; i < xs ; i++) {
00089       if (Perm) {
00090         subsumed &= (x[i].assigned() &&
00091                      z[i].assigned() &&
00092                      y[z[i].val()].assigned());
00093         if (subsumed) {
00094           if (x[i].val() != y[z[i].val()].val()) {
00095             return false;
00096           } else {
00097             if (z[i].val() == i) {
00098               dropfst++;
00099             }
00100           }
00101         }
00102       } else {
00103         subsumed &= (x[i].assigned() && y[i].assigned());
00104         if (subsumed) {
00105           if (x[i].val() != y[i].val()) {
00106             return false;
00107           } else {
00108             dropfst++;
00109           }
00110         }
00111       }
00112     }
00113     return true;
00114   }
00115 
00121   class OfflineMinItem {
00122   public:
00124     int root;
00126     int parent;
00128     int rank;
00130     int name;
00138     int iset;
00140     int succ;
00142     int pred;
00143   };
00144 
00150   class OfflineMin {
00151   private:
00152     OfflineMinItem* sequence;
00153     int* vertices;
00154     int  n;
00155   public:
00156     OfflineMin(void);
00157     OfflineMin(OfflineMinItem[], int[], int);
00162     int  find(int x);
00167     int  find_pc(int x);
00169     void unite(int a, int b, int c);
00171     void makeset(void);
00173     int  size(void);
00174     OfflineMinItem& operator[](int);
00175   };
00176 
00177   OfflineMin::OfflineMin(void){
00178     n = 0;
00179     sequence = NULL;
00180     vertices = NULL;
00181   }
00182 
00183   OfflineMin::OfflineMin(OfflineMinItem s[], int v[], int size){
00184     n = size;
00185     sequence = &s[0];
00186     vertices = &v[0];
00187   }
00188 
00189   forceinline int
00190   OfflineMin::find(int x) {
00191     while (sequence[x].parent != x) {
00192       x = sequence[x].parent;
00193     }
00194     // x is now the root of the tree
00195     // return the set, x belongs to
00196     return sequence[x].name;
00197   }
00198 
00199   forceinline int
00200   OfflineMin::find_pc(int x){
00201     int vsize = 0;
00202     while (sequence[x].parent != x) {
00203       vertices[x] = x;
00204       x = sequence[x].parent;
00205     }
00206     // x is now the root of the tree
00207     for (int i = vsize; i--; ) {
00208       sequence[vertices[i]].parent = x;
00209     }
00210     // return the set, x belongs to
00211     return sequence[x].name;
00212   }
00213 
00214   forceinline void
00215   OfflineMin::unite(int a, int b, int c){
00216     // c is the union of a and b
00217     int ra = sequence[a].root;
00218     int rb = sequence[b].root;
00219     int large = rb;
00220     int small = ra;
00221     if (sequence[ra].rank > sequence[rb].rank) {
00222       large = ra;
00223       small = rb;
00224     }
00225     sequence[small].parent =  large;
00226     sequence[large].rank   += sequence[small].rank;
00227     sequence[large].name   =  c;
00228     sequence[c].root       =  large;
00229   }
00230 
00231   forceinline void
00232   OfflineMin::makeset(void){
00233     for(int i = n; i--; ){
00234       OfflineMinItem& cur = sequence[i];
00235       cur.rank   = 0;     // initially each set is empty
00236       cur.name   = i;     // it has its own name
00237       cur.root   = i;     // it is the root node
00238       cur.parent = i;     // it is its own parent
00239       cur.pred   = i - 1;
00240       cur.succ   = i + 1;
00241       cur.iset   = -5;
00242     }
00243   }
00244 
00245   forceinline int
00246   OfflineMin::size(void){
00247     return n;
00248   }
00249 
00250   forceinline OfflineMinItem&
00251   OfflineMin::operator [](int i){
00252     return sequence[i];
00253   }
00254 
00264   template <class View>
00265   class TupleMaxInc {
00266   protected:
00267     ViewArray<View> x;
00268   public:
00269     TupleMaxInc(const ViewArray<View>& x0) : x(x0) {}
00270     bool operator()(const int i, const int j) {
00271       if (x[i].max() == x[j].max()) {
00272         return x[i].min() < x[j].min();
00273       } else {
00274         return x[i].max() < x[j].max();
00275       }
00276     }
00277   };
00278 
00279 
00289   template <class View>
00290   class TupleMaxIncExt {
00291   protected:
00292     ViewArray<View> x;
00293     ViewArray<View> z;
00294   public:
00295     TupleMaxIncExt(const ViewArray<View>& x0,
00296                    const ViewArray<View>& z0) : x(x0), z(z0) {}
00297     bool operator()(const int i, const int j) {
00298       if (x[i].max() == x[j].max()) {
00299         if (x[i].min() == x[j].min()) {
00300           if (z[i].max() == z[j].max()) {
00301             return z[i].min() < z[j].min();
00302           } else {
00303             return z[i].max() < z[j].max();
00304           }
00305         } else {
00306           return x[i].min() < x[j].min();
00307         }
00308       } else {
00309         return x[i].max() < x[j].max();
00310       }
00311     }
00312   };
00313 
00323   template <class View>
00324   class TupleMinInc {
00325   public:
00326     bool operator()(const View& x, const View& y) {
00327       if (x.min() == y.min()) {
00328         return x.max() < y.max();
00329       } else {
00330         return x.min() < y.min();
00331       }
00332     }
00333   };
00334 
00346   template <class View>
00347   class ViewPair {
00348   public:
00349     View x;
00350     View z;
00351   };
00352 
00353   template <class View>
00354   class TupleMinIncExt {
00355   public:
00356     bool operator()(const ViewPair<View>& x, const ViewPair<View>& y) {
00357       if (x.x.min() == y.x.min()) {
00358         if (x.x.max() == y.x.max()) {
00359           if (x.z.min() == y.z.min()) {
00360             return x.z.max() < y.z.max();
00361           } else {
00362             return x.z.min() < y.z.min();
00363           }
00364         } else {
00365           return x.x.max() < y.x.max();
00366         }
00367       } else {
00368         return x.x.min() < y.x.min();
00369       }
00370     }
00371   };
00372 
00380   template<class View, bool Perm>
00381   inline bool
00382   array_assigned(Space* home,
00383                  ViewArray<View>& x,
00384                  ViewArray<View>& y,
00385                  ViewArray<View>& z,
00386                  bool& subsumed,
00387                  bool& match_fixed,
00388                  bool&,
00389                  bool& noperm_bc) {
00390 
00391     bool x_complete = true;
00392     bool y_complete = true;
00393     bool z_complete = true;
00394 
00395     for (int i = y.size(); i--; ) {
00396       x_complete &= x[i].assigned();
00397       y_complete &= y[i].assigned();
00398       if (Perm) {
00399         z_complete &= z[i].assigned();
00400       }
00401     }
00402 
00403     if (x_complete) {
00404       for (int i = x.size(); i--; ) {
00405         ModEvent me = y[i].eq(home, x[i].val());
00406         if (me_failed(me)) {
00407           return false;
00408         }
00409       }
00410       if (Perm) {
00411         subsumed = false;
00412       } else {
00413         subsumed = true;
00414       }
00415     }
00416 
00417     if (y_complete) {
00418       bool y_equality = true;
00419       for (int i = y.size() - 1; i--; ) {
00420         y_equality &= (y[i].val() == y[i + 1].val());
00421       }
00422       if (y_equality) {
00423         for (int i = x.size(); i--; ) {
00424           ModEvent me = x[i].eq(home, y[i].val());
00425           if (me_failed(me)) {
00426             return false;
00427           }
00428         }
00429         if (Perm) {
00430           subsumed = false;
00431         } else {
00432           subsumed = true;
00433         }
00434         noperm_bc = true;
00435       }
00436     }
00437 
00438     if (Perm) {
00439       if (z_complete) {
00440         if (x_complete) {
00441           for (int i = x.size(); i--; ) {
00442             ModEvent me = y[z[i].val()].eq(home, x[i].val());
00443             if (me_failed(me)) {
00444               return false;
00445             }
00446           }
00447           subsumed = true;
00448           return subsumed;
00449         }
00450         if (y_complete) {
00451           for (int i = x.size(); i--; ) {
00452             ModEvent me = x[i].eq(home, y[z[i].val()].val());
00453             if (me_failed(me)) {
00454               return false;
00455             }
00456           }
00457           subsumed = true;
00458           return subsumed;
00459         }
00460 
00461         // validate the permutation
00462         int sum = 0;
00463         for (int i = x.size(); i--; ) {
00464           int pi = z[i].val();
00465           if (x[i].max() < y[pi].min() ||
00466               x[i].min() > y[pi].max()) {
00467             return false;
00468           }
00469           sum += pi;
00470         }
00471         int n = x.size();
00472         int gauss = ( (n * (n + 1)) / 2);
00473         // if the sum over all assigned permutation variables is not
00474         // equal to the gaussian sum - n they are not distinct, hence invalid
00475         if (sum != gauss - n) {
00476           return false;
00477         }
00478         match_fixed = true;
00479       }
00480     }
00481     return true;
00482   }
00483 
00491   template<class View>
00492   forceinline bool
00493   channel(Space* home, ViewArray<View>& x, ViewArray<View>& y, 
00494           ViewArray<View>& z, bool& nofix) {
00495     int n = x.size();
00496     for (int i = n; i--; ) {
00497       if (z[i].assigned()) {
00498         int v = z[i].val();
00499         if (x[i].assigned()) {
00500           // channel equality from x to y
00501           ModEvent me = y[v].eq(home, x[i].val());
00502           if (me_failed(me))
00503             return false;
00504           nofix |= me_modified(me);
00505         } else {
00506           if (y[v].assigned()) {
00507             // channel equality from y to x
00508             ModEvent me = x[i].eq(home, y[v].val());
00509             if (me_failed(me))
00510               return false;
00511             nofix |= me_modified(me);
00512           } else {
00513             // constrain upper bound
00514             ModEvent me = x[i].lq(home, y[v].max());
00515             if (me_failed(me))
00516               return false;
00517             nofix |= me_modified(me);
00518 
00519             // constrain lower bound
00520             me = x[i].gq(home, y[v].min());
00521             if (me_failed(me))
00522               return false;
00523             nofix |= me_modified(me);
00524 
00525             // constrain the sorted variable
00526             // constrain upper bound
00527             me = y[v].lq(home, x[i].max());
00528             if (me_failed(me))
00529               return false;
00530             nofix |= me_modified(me);
00531 
00532             // constrain lower bound
00533             me = y[v].gq(home, x[i].min());
00534             if (me_failed(me))
00535               return false;
00536             nofix |= me_modified(me);
00537           }
00538         }
00539       } else {
00540         // if the permutation variable is undetermined
00541         int l = z[i].min();
00542         int r = z[i].max();
00543         // upper bound
00544         ModEvent me = x[i].lq(home, y[r].max());
00545         if (me_failed(me))
00546           return false;
00547         nofix |= me_modified(me);
00548 
00549         // lower bound
00550         me = x[i].gq(home, y[l].min());
00551         if (me_failed(me))
00552           return false;
00553         nofix |= me_modified(me);
00554       }
00555     }
00556     return true;
00557   }
00558 
00559 
00560 }}}
00561 
00562 
00563 // STATISTICS: int-prop