ranges-union.icc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
00211