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

ranges-union.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2007-09-11 15:58:22 +0200 (Tue, 11 Sep 2007) $ by $Author: schulte $
00011  *     $Revision: 4973 $
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 Iter { namespace Ranges {
00039 
00046   template <class I, class J>
00047   class Union : public MinMax {
00049     I i;
00051     J j;
00052   public:
00054 
00055 
00056     Union(void);
00058     Union(I& i, J& j);
00060     void init(I& i, J& j);
00062 
00064 
00065 
00066     void operator++(void);
00068   };
00069 
00070 
00076   template <class I>
00077   class NaryUnion : public MinMax {
00078   protected:
00080     class RangeUnionOrder {
00081     public:
00082       bool operator()(const I&, const I&) const;
00083     };
00085     RangeUnionOrder order;
00087     Support::PQueue<I,RangeUnionOrder> r;
00088   public:
00090 
00091 
00092     NaryUnion(void);
00094     NaryUnion(I* i, int n);
00096     void init(I* i, int n);
00098 
00100 
00101 
00102     void operator++(void);
00104   };
00105 
00106 
00107 
00108   /*
00109    * Binary union
00110    *
00111    */
00112 
00113   template <class I, class J>
00114   inline void
00115   Union<I,J>::operator++(void) {
00116     if (!i() && !j()) {
00117       finish(); return;
00118     }
00119     if (!i()) {
00120       mi = j.min(); ma = j.max(); ++j; return;
00121     }
00122     if (!j()) {
00123       mi = i.min(); ma = i.max(); ++i; return;
00124     }
00125     if (i.min() < j.min()) {
00126       mi = i.min(); ma = i.max(); ++i;
00127     } else {
00128       mi = j.min(); ma = j.max(); ++j;
00129     }
00130     bool goOn;
00131     do {
00132       goOn = false;
00133       if (i() && (i.min() <= ma+1)) {
00134         ma = std::max(ma,i.max()); ++i; goOn=true;
00135       }
00136       if (j() && (j.min() <= ma+1)) {
00137         ma = std::max(ma,j.max()); ++j; goOn=true;
00138       }
00139     } while (goOn);
00140   }
00141 
00142 
00143   template <class I, class J>
00144   forceinline
00145   Union<I,J>::Union(void) {}
00146 
00147   template <class I, class J>
00148   forceinline
00149   Union<I,J>::Union(I& i0, J& j0)
00150     : i(i0), j(j0) {
00151     operator++();
00152   }
00153 
00154   template <class I, class J>
00155   forceinline void
00156   Union<I,J>::init(I& i0, J& j0) {
00157     i = i0; j = j0;
00158     operator++();
00159   }
00160 
00161 
00162 
00163   /*
00164    * Nary Union
00165    *
00166    */
00167 
00168   template <class I>
00169   forceinline bool
00170   NaryUnion<I>::RangeUnionOrder::operator()(const I& a, const I& b) const {
00171     return a.min() > b.min();
00172   }
00173 
00174   template <class I>
00175   inline void
00176   NaryUnion<I>::operator++(void) {
00177     if (r.empty()) {
00178       finish(); return;
00179     }
00180     mi = r.top().min();
00181     ma = r.top().max();
00182     do {
00183       if (ma < r.top().max())
00184         ma = r.top().max();
00185       ++(r.top());
00186       if (!(r.top())()) {
00187         r.remove();
00188         if (r.empty())
00189           return;
00190       } else {
00191         r.fix();
00192       }
00193     } while (ma+1 >= r.top().min());
00194   }
00195 
00196 
00197   template <class I>
00198   forceinline
00199   NaryUnion<I>::NaryUnion(void) {}
00200 
00201   template <class I>
00202   inline
00203   NaryUnion<I>::NaryUnion(I* r0, int n)
00204     : order(), r(n,order) {
00205     for (int i = n; i--; )
00206       if (r0[i]())
00207         r.insert(r0[i]);
00208     operator++();
00209   }
00210 
00211   template <class I>
00212   inline void
00213   NaryUnion<I>::init(I* r0, int n) {
00214     r.init(n,order);
00215     for (int i = n; i--; )
00216       if (r0[i]())
00217         r.insert(r0[i]);
00218     operator++();
00219   }
00220 
00221 }}}
00222 
00223 // STATISTICS: iter-any
00224