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
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
00224