this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * Christian Schulte <schulte@gecode.org> 6 * 7 * Copyright: 8 * Guido Tack, 2004 9 * Christian Schulte, 2004 10 * 11 * This file is part of Gecode, the generic constraint 12 * development environment: 13 * http://www.gecode.org 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining 16 * a copy of this software and associated documentation files (the 17 * "Software"), to deal in the Software without restriction, including 18 * without limitation the rights to use, copy, modify, merge, publish, 19 * distribute, sublicense, and/or sell copies of the Software, and to 20 * permit persons to whom the Software is furnished to do so, subject to 21 * the following conditions: 22 * 23 * The above copyright notice and this permission notice shall be 24 * included in all copies or substantial portions of the Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 * 34 */ 35 36namespace Gecode { namespace Set { namespace Element { 37 38 template<class SView, class RView> 39 forceinline 40 ElementDisjoint<SView,RView>::ElementDisjoint(Home home, 41 IdxViewArray& iv0, 42 RView y1) 43 : Propagator(home), iv(iv0), x1(y1) { 44 45 x1.subscribe(home,*this, PC_SET_ANY); 46 iv.subscribe(home,*this, PC_SET_ANY); 47 } 48 49 template<class SView, class RView> 50 forceinline 51 ElementDisjoint<SView,RView>::ElementDisjoint(Space& home, 52 ElementDisjoint& p) 53 : Propagator(home,p) { 54 x1.update(home,p.x1); 55 iv.update(home,p.iv); 56 } 57 58 template<class SView, class RView> 59 forceinline ExecStatus 60 ElementDisjoint<SView,RView>::post(Home home, IdxViewArray& xs, 61 RView x1) { 62 int n = xs.size(); 63 64 // s2 \subseteq {0,...,n-1} 65 Iter::Ranges::Singleton s(0, n-1); 66 GECODE_ME_CHECK(x1.intersectI(home,s)); 67 (void) new (home) 68 ElementDisjoint(home,xs,x1); 69 return ES_OK; 70 } 71 72 template<class SView, class RView> 73 PropCost 74 ElementDisjoint<SView,RView>::cost(const Space&, const ModEventDelta&) const { 75 return PropCost::quadratic(PropCost::LO, iv.size()+2); 76 } 77 78 template<class SView, class RView> 79 void 80 ElementDisjoint<SView,RView>::reschedule(Space& home) { 81 x1.reschedule(home,*this, PC_SET_ANY); 82 iv.reschedule(home,*this, PC_SET_ANY); 83 } 84 85 template<class SView, class RView> 86 forceinline size_t 87 ElementDisjoint<SView,RView>::dispose(Space& home) { 88 x1.cancel(home,*this, PC_SET_ANY); 89 iv.cancel(home,*this,PC_SET_ANY); 90 (void) Propagator::dispose(home); 91 return sizeof(*this); 92 } 93 94 template<class SView, class RView> 95 Actor* 96 ElementDisjoint<SView,RView>::copy(Space& home) { 97 return new (home) ElementDisjoint(home,*this); 98 } 99 100 template<class SView, class RView> 101 ExecStatus 102 ElementDisjoint<SView,RView>::propagate(Space& home, const ModEventDelta&) { 103 int n = iv.size(); 104 105 Region r; 106 107 bool fix_flag = false; 108 do { 109 fix_flag = false; 110 // Compute union of all selected elements' lower bounds 111 GlbRanges<RView> x1lb(x1); 112 Iter::Ranges::ToValues<GlbRanges<RView> > vx1lb(x1lb); 113 GLBndSet unionOfSelected(home); 114 for(int i=0; vx1lb(); ++vx1lb) { 115 while (iv[i].idx < vx1lb.val()) i++; 116 GlbRanges<SView> clb(iv[i].view); 117 unionOfSelected.includeI(home,clb); 118 } 119 120 { 121 LubRanges<RView> x1ub(x1); 122 Iter::Ranges::ToValues<LubRanges<RView> > vx1ub(x1ub); 123 int i=0; 124 int j=0; 125 // Cancel all elements that are no longer in the upper bound 126 while (vx1ub()) { 127 if (iv[i].idx < vx1ub.val()) { 128 iv[i].view.cancel(home,*this, PC_SET_ANY); 129 i++; 130 continue; 131 } 132 iv[j] = iv[i]; 133 ++vx1ub; 134 ++i; ++j; 135 } 136 137 // cancel the variables with index greater than 138 // max of lub(x1) 139 for (int k=i; k<n; k++) { 140 iv[k].view.cancel(home,*this, PC_SET_ANY); 141 } 142 n = j; 143 iv.size(n); 144 } 145 146 { 147 UnknownRanges<RView> x1u(x1); 148 Iter::Ranges::Cache x1uc(r,x1u); 149 Iter::Ranges::ToValues<Iter::Ranges::Cache> 150 vx1u(x1uc); 151 int i=0; 152 int j=0; 153 while (vx1u()) { 154 while (iv[i].idx < vx1u.val()) { 155 iv[j] = iv[i]; 156 i++; j++; 157 } 158 assert(iv[i].idx == vx1u.val()); 159 160 SView candidate = iv[i].view; 161 int candidateInd = iv[i].idx; 162 163 GlbRanges<SView> clb(candidate); 164 BndSetRanges uos(unionOfSelected); 165 Iter::Ranges::Inter<GlbRanges<SView>, BndSetRanges> 166 inter(clb, uos); 167 if (inter()) { 168 ModEvent me = x1.exclude(home,candidateInd); 169 fix_flag |= me_modified(me); 170 GECODE_ME_CHECK(me); 171 172 candidate.cancel(home,*this, PC_SET_ANY); 173 ++i; 174 ++vx1u; 175 continue; 176 } 177 iv[j] = iv[i]; 178 ++vx1u; 179 ++i; ++j; 180 } 181 182 unionOfSelected.dispose(home); 183 184 // copy remaining variables 185 for (int k=i; k<n; k++) { 186 iv[j] = iv[k]; 187 j++; 188 } 189 n = j; 190 iv.size(n); 191 } 192 193 if (x1.cardMax()==0) { 194 // Selector is empty, we're done 195 return home.ES_SUBSUMED(*this); 196 } 197 198 { 199 // remove all elements in a selected variable from 200 // all other selected variables 201 GlbRanges<RView> x1lb(x1); 202 Iter::Ranges::ToValues<GlbRanges<RView> > vx1lb(x1lb); 203 int i=0; 204 for (; vx1lb(); ++vx1lb) { 205 while (iv[i].idx < vx1lb.val()) i++; 206 assert(iv[i].idx==vx1lb.val()); 207 GlbRanges<RView> x1lb2(x1); 208 Iter::Ranges::ToValues<GlbRanges<RView> > vx1lb2(x1lb2); 209 for (int j=0; vx1lb2(); ++vx1lb2) { 210 while (iv[j].idx < vx1lb2.val()) j++; 211 assert(iv[j].idx==vx1lb2.val()); 212 if (iv[i].idx!=iv[j].idx) { 213 GlbRanges<SView> xilb(iv[i].view); 214 ModEvent me = iv[j].view.excludeI(home,xilb); 215 fix_flag |= me_modified(me); 216 GECODE_ME_CHECK(me); 217 } 218 } 219 } 220 } 221 222 // remove all elements from the selector that overlap 223 // with all other possibly selected elements, if 224 // at least two more elements need to be selected 225 if (x1.cardMin()-x1.glbSize() > 1) { 226 UnknownRanges<RView> x1u(x1); 227 Iter::Ranges::Cache x1uc(r,x1u); 228 Iter::Ranges::ToValues<Iter::Ranges::Cache> 229 vx1u(x1uc); 230 231 for (; vx1u() && x1.cardMin()-x1.glbSize() > 1; ++vx1u) { 232 int i = 0; 233 while (iv[i].idx < vx1u.val()) i++; 234 assert(iv[i].idx == vx1u.val()); 235 bool flag=true; 236 237 UnknownRanges<RView> x1u2(x1); 238 Iter::Ranges::ToValues<UnknownRanges<RView> > vx1u2(x1u2); 239 for (; vx1u2(); ++vx1u2) { 240 int j = 0; 241 while (iv[j].idx < vx1u2.val()) j++; 242 assert(iv[j].idx == vx1u2.val()); 243 if (iv[i].idx!=iv[j].idx) { 244 GlbRanges<SView> xjlb(iv[j].view); 245 GlbRanges<SView> xilb(iv[i].view); 246 Iter::Ranges::Inter<GlbRanges<SView>, GlbRanges<SView> > 247 inter(xjlb, xilb); 248 if (!inter()) { 249 flag = false; 250 goto here; 251 } 252 } 253 } 254 here: 255 if (flag) { 256 ModEvent me = x1.exclude(home,iv[i].idx); 257 fix_flag |= me_modified(me); 258 GECODE_ME_CHECK(me); 259 } 260 } 261 } 262 263 // if exactly two more elements need to be selected 264 // and there is a possible element i such that all other pairs of 265 // elements overlap, select i 266 UnknownRanges<RView> x1u(x1); 267 Iter::Ranges::Cache x1uc(r,x1u); 268 Iter::Ranges::ToValues<Iter::Ranges::Cache> 269 vx1u(x1uc); 270 271 for (; x1.cardMin()-x1.glbSize() == 2 && vx1u(); ++vx1u) { 272 int i = 0; 273 while (iv[i].idx < vx1u.val()) i++; 274 assert (iv[i].idx == vx1u.val()); 275 bool flag=true; 276 277 UnknownRanges<RView> x1u2(x1); 278 Iter::Ranges::ToValues<UnknownRanges<RView> > vx1u2(x1u2); 279 for (; vx1u2(); ++vx1u2) { 280 int j = 0; 281 while (iv[j].idx < vx1u2.val()) j++; 282 assert (iv[j].idx == vx1u2.val()); 283 if (iv[i].idx!=iv[j].idx) { 284 UnknownRanges<RView> x1u3(x1); 285 Iter::Ranges::ToValues<UnknownRanges<RView> > vx1u3(x1u3); 286 for (; vx1u3(); ++vx1u3) { 287 int k = 0; 288 while (iv[k].idx < vx1u3.val()) k++; 289 assert (iv[k].idx == vx1u3.val()); 290 if (iv[j].idx!=iv[k].idx && iv[i].idx!=iv[k].idx) { 291 GlbRanges<SView> xjlb(iv[j].view); 292 GlbRanges<SView> xilb(iv[k].view); 293 Iter::Ranges::Inter<GlbRanges<SView>, GlbRanges<SView> > 294 inter(xjlb, xilb); 295 if (!inter()) { 296 flag = false; 297 goto here2; 298 } 299 } 300 } 301 } 302 } 303 here2: 304 if (flag) { 305 ModEvent me = x1.include(home,iv[i].idx); 306 fix_flag |= me_modified(me); 307 GECODE_ME_CHECK(me); 308 } 309 } 310 } while (fix_flag); 311 312 for (int i=iv.size(); i--;) 313 if (!iv[i].view.assigned()) 314 return ES_FIX; 315 if (!x1.assigned()) 316 return ES_FIX; 317 return home.ES_SUBSUMED(*this); 318 } 319 320 321}}} 322 323// STATISTICS: set-prop