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

ranges-union.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:05:50 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3515 $
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 #include "gecode/support/static-pqueue.hh"
00023 
00024 namespace Gecode { namespace Iter { namespace Ranges {
00025 
00033   template <class I, class J>
00034   class Union : public MinMax {
00036     I i;
00038     J j;
00039   public:
00041 
00042 
00043     Union(void);
00045     Union(I& i, J& j);
00047     void init(I& i, J& j);
00049 
00051 
00052 
00053     void operator++(void);
00055   };
00056 
00057 
00063   template <class I>
00064   class NaryUnion : public MinMax {
00065   protected:
00067     class RangeUnionOrder {
00068     public:
00069       bool operator()(const I&, const I&) const;
00070     };
00072     RangeUnionOrder order;
00074     Support::PQueue<I,RangeUnionOrder> r;
00075   public:
00077 
00078 
00079     NaryUnion(void);
00081     NaryUnion(I* i, int n);
00083     void init(I* i, int n);
00085 
00087 
00088 
00089     void operator++(void);
00091   };
00092 
00093 
00094 
00095   /*
00096    * Binary union
00097    *
00098    */
00099 
00100   template <class I, class J>
00101   inline void
00102   Union<I,J>::operator++(void) {
00103     if (!i() && !j()) {
00104       finish(); return;
00105     }
00106     if (!i()) {
00107       mi = j.min(); ma = j.max(); ++j; return;
00108     }
00109     if (!j()) {
00110       mi = i.min(); ma = i.max(); ++i; return;
00111     }
00112     if (i.min() < j.min()) {
00113       mi = i.min(); ma = i.max(); ++i;
00114     } else {
00115       mi = j.min(); ma = j.max(); ++j;
00116     }
00117     bool goOn;
00118     do {
00119       goOn = false;
00120       if (i() && (i.min() <= ma+1)) {
00121         ma = std::max(ma,i.max()); ++i; goOn=true;
00122       }
00123       if (j() && (j.min() <= ma+1)) {
00124         ma = std::max(ma,j.max()); ++j; goOn=true;
00125       }
00126     } while (goOn);
00127   }
00128 
00129 
00130   template <class I, class J>
00131   forceinline
00132   Union<I,J>::Union(void) {}
00133 
00134   template <class I, class J>
00135   forceinline
00136   Union<I,J>::Union(I& i0, J& j0)
00137     : i(i0), j(j0) {
00138     operator++();
00139   }
00140 
00141   template <class I, class J>
00142   forceinline void
00143   Union<I,J>::init(I& i0, J& j0) {
00144     i = i0; j = j0;
00145     operator++();
00146   }
00147 
00148 
00149 
00150   /*
00151    * Nary Union
00152    *
00153    */
00154 
00155   template <class I>
00156   forceinline bool
00157   NaryUnion<I>::RangeUnionOrder::operator()(const I& a, const I& b) const {
00158     return a.min() > b.min();
00159   }
00160 
00161   template <class I>
00162   inline void
00163   NaryUnion<I>::operator++(void) {
00164     if (r.empty()) {
00165       finish(); return;
00166     }
00167     mi = r.top().min();
00168     ma = r.top().max();
00169     do {
00170       if (ma < r.top().max())
00171         ma = r.top().max();
00172       ++(r.top());
00173       if (!(r.top())()) {
00174         r.remove();
00175         if (r.empty())
00176           return;
00177       } else {
00178         r.fix();
00179       }
00180     } while (ma+1 >= r.top().min());
00181   }
00182 
00183 
00184   template <class I>
00185   forceinline
00186   NaryUnion<I>::NaryUnion(void) {}
00187 
00188   template <class I>
00189   inline
00190   NaryUnion<I>::NaryUnion(I* r0, int n)
00191     : order(), r(n,order) {
00192     for (int i = n; i--; )
00193       if (r0[i]())
00194         r.insert(r0[i]);
00195     operator++();
00196   }
00197 
00198   template <class I>
00199   inline void
00200   NaryUnion<I>::init(I* r0, int n) {
00201     r.init(n,order);
00202     for (int i = n; i--; )
00203       if (r0[i]())
00204         r.insert(r0[i]);
00205     operator++();
00206   }
00207 
00208 }}}
00209 
00210 // STATISTICS: iter-any
00211