00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cpsp/gecode/GC_Neighbored3.hh"
00021 #include "cpsp/gecode/GC_StlSetRangeIterator.hh"
00022
00023 #include <biu/assertbiu.hh>
00024
00025 namespace cpsp
00026 {
00027 namespace gecode
00028 {
00029
00030 const unsigned int GC_Neighbored3::MAXPROPSIZEINIT = 50;
00031
00032
00033 GC_Neighbored3::GC_Neighbored3( Gecode::Space* home,
00034 Gecode::Int::IntView x0,
00035 Gecode::Int::IntView x1,
00036 Gecode::Int::IntView x2,
00037 const biu::LatticeFrame* lattice_,
00038 Gecode::IntConLevel conLvl,
00039 unsigned int maxPrSize,
00040 bool maxPrSizeBin,
00041 unsigned int minPrSize)
00042 : GC_TriProp(home,x0,x1,x2),
00043 lattice(lattice_), conLevel(conLvl), maxPropSize(maxPrSize),
00044 maxPropSizeBin(maxPrSizeBin), minPropSize(minPrSize)
00045 {
00046 assertbiu(lattice != NULL, "static lattice variable not initialised");
00047 neighborhood = lattice->getIndexedNeighborhood();
00048
00049
00050 switch (conLevel) {
00051 case Gecode::ICL_VAL : maxPropSize = 1; break;
00052 case Gecode::ICL_DOM : maxPropSize = UINT_MAX; break;
00053 case Gecode::ICL_DEF : conLevel = Gecode::ICL_BND;
00054 case Gecode::ICL_BND :
00055 default : ;
00056 }
00057 }
00058
00059 GC_Neighbored3::GC_Neighbored3( Gecode::Space* home,
00060 bool share,
00061 GC_Neighbored3& p) :
00062 GC_TriProp(home,share,p),
00063 lattice(p.lattice),
00064 neighborhood(p.neighborhood),
00065 conLevel(p.conLevel),
00066 maxPropSize(p.maxPropSize),
00067 maxPropSizeBin(p.maxPropSizeBin),
00068 minPropSize(p.minPropSize)
00069 {}
00070
00071 Gecode::ExecStatus
00072 GC_Neighbored3::post( Gecode::Space* home,
00073 Gecode::Int::IntView x0, Gecode::Int::IntView x1,
00074 Gecode::Int::IntView x2,
00075 const biu::LatticeFrame* lattice,
00076 Gecode::IntConLevel conLvl,
00077 unsigned int maxPrSize,
00078 bool maxPrSizeBin,
00079 unsigned int minPrSize)
00080 {
00081 if ( same(x0,x1) || same(x0,x2) || same(x1,x2) ) {
00082 return Gecode::ES_FAILED;
00083 } else {
00084 (void) new (home) GC_Neighbored3( home, x0, x1, x2, lattice, conLvl,
00085 maxPrSize, maxPrSizeBin, minPrSize);
00086 }
00087 return Gecode::ES_OK;
00088 }
00089
00090
00091 Gecode::Actor*
00092 GC_Neighbored3::copy(Gecode::Space* home, bool share) {
00093 return new (home) GC_Neighbored3(home,share,*this);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 Gecode::PropCost
00114 GC_Neighbored3::cost(void) const {
00115 if (x0.assigned() || x1.assigned() || x2.assigned()) {
00116 return Gecode::PC_QUADRATIC_HI;
00117 }
00118 return Gecode::PC_CUBIC_HI;
00119 }
00120
00121 Gecode::ExecStatus
00122 GC_Neighbored3::propagate(Gecode::Space* home) {
00123
00124
00125
00126 if ( x0.size() < minPropSize
00127 && x1.size() < minPropSize
00128 && x2.size() < minPropSize )
00129 return Gecode::ES_SUBSUMED;
00130
00131
00132 if ( maxPropSizeBin &&
00133 ( std::max(x0.size(), x1.size()) > maxPropSize
00134 || std::max(x1.size(), x2.size()) > maxPropSize) )
00135 return Gecode::ES_FIX;
00136
00137
00138 Gecode::ModEvent ret = Gecode::ME_GEN_NONE, ret1 = Gecode::ME_GEN_NONE;
00139 if (x1.assigned()) {
00140 ret1 = removeNonNeighbors(home,x0,x1.val());
00141 if (ret1 == Gecode::ME_GEN_FAILED) {
00142 ret = Gecode::ME_GEN_FAILED;
00143 } else {
00144 ret = removeNonNeighbors(home,x2,x1.val());
00145
00146 if ( ret == Gecode::ME_GEN_ASSIGNED
00147 && ret1 != Gecode::ME_GEN_ASSIGNED)
00148 { ret = Gecode::Int::ME_INT_DOM; }
00149 }
00150 } else if (x0.assigned()) {
00151 ret1 = removeNonNeighbors(home,x1,x0.val());
00152 if (ret1 == Gecode::ME_GEN_FAILED) {
00153 ret = Gecode::ME_GEN_FAILED;
00154 } else if(ret1 == Gecode::ME_GEN_ASSIGNED) {
00155 ret = removeNonNeighbors(home,x2,x1.val());
00156 } else {
00157 ret = removeNonNeighbors(home,x1, x2);
00158 }
00159 } else if (x2.assigned()) {
00160 ret1 = removeNonNeighbors(home,x1,x2.val());
00161 if (ret1 == Gecode::ME_GEN_FAILED) {
00162 ret = Gecode::ME_GEN_FAILED;
00163 } else if(ret1 == Gecode::ME_GEN_ASSIGNED) {
00164 ret = removeNonNeighbors(home,x0,x1.val());
00165 } else {
00166 ret = removeNonNeighbors(home,x0, x1);
00167 }
00168 } else {
00169 ret = removeNonNeighbors(home, x0, x1, x2);
00170 }
00171
00172
00173 GECODE_ME_CHECK(ret);
00174
00175 return (ret == Gecode::ME_GEN_ASSIGNED
00176 ? Gecode::ES_SUBSUMED
00177 : Gecode::ES_FIX);
00178 }
00179
00180
00181 biu::IndexSet
00182 GC_Neighbored3::getIndexedNeighbors(
00183 const biu::LatticeFrame::index_type center) const
00184 {
00185 biu::IndexSet retSet;
00186
00187 for(biu::IndexVec::const_iterator it = neighborhood.begin();
00188 it != neighborhood.end(); it++) {
00189 retSet.insert(center+(*it));
00190 }
00191 return retSet;
00192 }
00193
00194
00195 Gecode::ModEvent
00196 GC_Neighbored3::removeNonNeighbors( Gecode::Space* home,
00197 Gecode::Int::IntView& x,
00198 int center)
00199 {
00200 biu::IndexSet data = getIndexedNeighbors(center);
00201 GC_StlSetRangeIterator dataIt(&data);
00202 return x.inter(home, dataIt);
00203 }
00204
00205
00206 Gecode::ModEvent
00207 GC_Neighbored3::removeNonNeighbors( Gecode::Space* home,
00208 Gecode::Int::IntView& xA,
00209 Gecode::Int::IntView& xB)
00210 {
00211
00212
00213
00214 Gecode::Int::IntView* a = &xA, *b = &xB;
00215 if(a->size() > b->size()) {
00216 a = &xB, b = &xA;
00217 }
00218
00219
00220
00221 if (a->size() > maxPropSize) {
00222 return Gecode::ME_GEN_NONE;
00223 }
00224
00225
00226 unsigned int aSize = a->size(), bSize = b->size();
00227
00228
00229 Gecode::ModEvent aStat = Gecode::ME_GEN_NONE,
00230 bStat = Gecode::ME_GEN_NONE;
00231
00232
00233 Gecode::Int::ViewValues<Gecode::Int::IntView> aIt(*a);
00234 biu::IndexSet newDom, actNeighs, toRem;
00235 biu::IndexSet::const_iterator neigh;
00236 bool noNeighInB = true;
00237 while(aIt()) {
00238
00239 actNeighs = getIndexedNeighbors(aIt.val());
00240 noNeighInB = true;
00241
00242 for(neigh = actNeighs.begin(); neigh != actNeighs.end(); neigh++) {
00243 if (b->in(*neigh)) {
00244 noNeighInB = false;
00245 newDom.insert(*neigh);
00246 }
00247 }
00248
00249 if (noNeighInB) {
00250
00251 toRem.insert(aIt.val());
00252 }
00253
00254 ++aIt;
00255 }
00256
00257 GC_StlSetRangeIterator remDomIt(&toRem);
00258 aStat = a->minus(home,remDomIt);
00259
00260
00261 if (aStat != Gecode::ME_GEN_FAILED) {
00262 GC_StlSetRangeIterator newDomIt(&newDom);
00263 bStat = b->inter(home,newDomIt);
00264 } else {
00265 return Gecode::ME_GEN_FAILED;
00266 }
00267
00268
00269 if ( bStat == Gecode::ME_GEN_FAILED ) {
00270 return Gecode::ME_GEN_FAILED;
00271 }
00272 if ( aSize == a->size() && bSize == b->size())
00273 return Gecode::ME_GEN_NONE;
00274 if ( aStat == Gecode::ME_GEN_ASSIGNED
00275 && bStat == Gecode::ME_GEN_ASSIGNED)
00276 return Gecode::ME_GEN_ASSIGNED;
00277 return Gecode::Int::ME_INT_DOM;
00278 }
00279
00280 Gecode::ModEvent
00281 GC_Neighbored3::removeNonNeighbors( Gecode::Space* home,
00282 Gecode::Int::IntView& xA,
00283 Gecode::Int::IntView& xB,
00284 Gecode::Int::IntView& xC)
00285 {
00286
00287
00288 Gecode::Int::IntView* a = &xA, *b = &xB, *c = &xC;
00289 if(a->size() > c->size()) {
00290 a = &xC, c = &xA;
00291 }
00292
00293
00294
00295 if ( std::min(a->size(),b->size()) > maxPropSize )
00296 return Gecode::ME_GEN_NONE;
00297
00298
00299 unsigned int aSize = a->size(), bSize = b->size(), cSize = c->size();
00300
00301 if (bSize < aSize) {
00302
00303 biu::IndexSet bRem, aInter, cInter, actNeighs;
00304 Gecode::Int::ViewValues<Gecode::Int::IntView> bIt(*b);
00305 biu::IndexSet::const_iterator neighA, neighC;
00306
00307 while(bIt()) {
00308
00309 actNeighs = getIndexedNeighbors(bIt.val());
00310
00311 neighA = actNeighs.begin();
00312
00313 while( neighA != actNeighs.end() && !a->in(*neighA) ) {
00314 neighA++;
00315 }
00316 if (neighA == actNeighs.end()) {
00317 bRem.insert(bIt.val());
00318
00319 } else {
00320 neighC = actNeighs.begin();
00321
00322 while( neighC != actNeighs.end() && !c->in(*neighC) ) {
00323 neighC++;
00324 }
00325 if (neighC == actNeighs.end()) {
00326 bRem.insert(bIt.val());
00327
00328 } else {
00329
00330 aInter.insert(*neighA);
00331 while( ++neighA != actNeighs.end()) {
00332 if (a->in(*neighA))
00333 aInter.insert(*neighA);
00334 }
00335
00336 cInter.insert(*neighC);
00337 while( ++neighC != actNeighs.end()) {
00338 if (c->in(*neighC))
00339 cInter.insert(*neighC);
00340 }
00341 }
00342 }
00343 ++bIt;
00344 }
00345
00346
00347 GC_StlSetRangeIterator domIt(&bRem);
00348 GECODE_ME_CHECK( b->minus(home, domIt) );
00349
00350 domIt.init(&aInter);
00351 GECODE_ME_CHECK( a->inter(home, domIt) );
00352
00353 domIt.init(&cInter);
00354 GECODE_ME_CHECK( c->inter(home, domIt) );
00355
00356 } else {
00357
00358
00359 biu::IndexSet aRem, bInter, cInter, actNeighsA, actNeighsB;
00360 Gecode::Int::ViewValues<Gecode::Int::IntView> aIt(*a);
00361 biu::IndexSet::const_iterator neighB, neighC;
00362
00363
00364 bool pathFound = false;
00365
00366 while(aIt()) {
00367
00368 actNeighsA = getIndexedNeighbors(aIt.val());
00369 pathFound = false;
00370
00371 for ( neighB = actNeighsA.begin();
00372 neighB != actNeighsA.end();
00373 neighB++)
00374 {
00375
00376 if (b->in(*neighB)) {
00377 pathFound = false;
00378 actNeighsB = getIndexedNeighbors(*neighB);
00379
00380 for( neighC = actNeighsB.begin();
00381 neighC != actNeighsB.end();
00382 neighC++)
00383 {
00384 if (c->in(*neighC)) {
00385 pathFound = true;
00386 cInter.insert(*neighC);
00387 }
00388 }
00389
00390 if (pathFound) {
00391 bInter.insert(*neighB);
00392 }
00393 }
00394 }
00395
00396 if (!pathFound) {
00397 aRem.insert(aIt.val());
00398 }
00399 ++aIt;
00400 }
00401
00402
00403 GC_StlSetRangeIterator domIt(&aRem);
00404 GECODE_ME_CHECK( a->minus(home, domIt) );
00405
00406 domIt.init(&bInter);
00407 GECODE_ME_CHECK( b->inter(home, domIt) );
00408
00409 domIt.init(&cInter);
00410 GECODE_ME_CHECK( c->inter(home, domIt) );
00411
00412 }
00413
00414 if (a->assigned() && b->assigned() && c->assigned()) {
00415 return Gecode::ME_GEN_ASSIGNED;
00416 }
00417 if (a->size() < aSize || b->size() < bSize || c->size() < cSize) {
00418 return Gecode::Int::ME_INT_DOM;
00419 }
00420
00421 return Gecode::ME_GEN_NONE;
00422 }
00423 }
00424 }