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 #include <gecode/int/ldsb.hh>
00039 #include <gecode/int/branch.hh>
00040
00041 #include <map>
00042
00043 namespace Gecode { namespace Int { namespace LDSB {
00044
00045 std::pair<int,int>
00046 findVar(int *indices, unsigned int n_values, unsigned int seq_size, int index) {
00047 unsigned int seq = 0;
00048 unsigned int pos = 0;
00049 for (unsigned int i = 0 ; i < n_values ; i++) {
00050 if (indices[i] == index)
00051 return std::pair<int,int>(seq,pos);
00052 pos++;
00053 if (pos == seq_size) {
00054 pos = 0;
00055 seq++;
00056 }
00057 }
00058 return std::pair<int,int>(-1,-1);
00059 }
00060
00061 }}}
00062
00063 namespace Gecode {
00064 using namespace Int::LDSB;
00065
00066 SymmetryHandle VariableSymmetry(const IntVarArgs& vars) {
00067 ArgArray<VarImpBase*> a(vars.size());
00068 for (int i = 0 ; i < vars.size() ; i++)
00069 a[i] = vars[i].varimp();
00070 return SymmetryHandle(new VariableSymmetryObject(a));
00071 }
00072 SymmetryHandle VariableSymmetry(const BoolVarArgs& vars) {
00073 ArgArray<VarImpBase*> a(vars.size());
00074 for (int i = 0 ; i < vars.size() ; i++)
00075 a[i] = vars[i].varimp();
00076 return SymmetryHandle(new VariableSymmetryObject(a));
00077 }
00078 SymmetryHandle VariableSymmetry(const IntVarArgs& x,
00079 const IntArgs& indices) {
00080 IntVarArgs xs(indices.size());
00081 for (int i = 0 ; i < indices.size() ; i++)
00082 xs[i] = x[indices[i]];
00083 return VariableSymmetry(xs);
00084 }
00085 SymmetryHandle ValueSymmetry(const IntArgs& vs) {
00086 return SymmetryHandle(new ValueSymmetryObject(IntSet(vs)));
00087 }
00088 SymmetryHandle ValueSymmetry(const IntSet& vs) {
00089 return SymmetryHandle(new ValueSymmetryObject(vs));
00090 }
00091 SymmetryHandle ValueSymmetry(IntVar x) {
00092 return ValueSymmetry(IntSet(x.min(), x.max()));
00093 }
00094 SymmetryHandle VariableSequenceSymmetry(const IntVarArgs& vars, int ss) {
00095 ArgArray<VarImpBase*> a(vars.size());
00096 for (int i = 0 ; i < vars.size() ; i++)
00097 a[i] = vars[i].varimp();
00098 return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss));
00099 }
00100 SymmetryHandle VariableSequenceSymmetry(const BoolVarArgs& vars, int ss) {
00101 ArgArray<VarImpBase*> a(vars.size());
00102 for (int i = 0 ; i < vars.size() ; i++)
00103 a[i] = vars[i].varimp();
00104 return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss));
00105 }
00106 SymmetryHandle ValueSequenceSymmetry(const IntArgs& vs, int ss) {
00107 return SymmetryHandle(new ValueSequenceSymmetryObject(vs, ss));
00108 }
00109
00110 SymmetryHandle values_reflect(int lower, int upper) {
00111 int n = (upper-lower+1)/2;
00112 IntArgs a(n*2);
00113 int i = lower;
00114 int j = upper;
00115 int k = 0;
00116 while (i < j) {
00117 a[k] = j;
00118 a[n+k] = i;
00119 i++;
00120 j--;
00121 k++;
00122 }
00123 return ValueSequenceSymmetry(a,n);
00124 }
00125 SymmetryHandle values_reflect(const IntVar& x) {
00126 return values_reflect(x.min(), x.max());
00127 }
00128 }
00129
00130
00131 namespace Gecode { namespace Int { namespace LDSB {
00132
00134 class VariableMap : public std::map<VarImpBase*,int> {};
00135
00136
00137
00138
00139
00140
00141
00143 SymmetryImp<IntView>*
00144 createIntSym(Space& home, const SymmetryHandle& s,
00145 VariableMap variableMap) {
00146 VariableSymmetryObject* varref =
00147 dynamic_cast<VariableSymmetryObject*>(s.ref);
00148 ValueSymmetryObject* valref =
00149 dynamic_cast<ValueSymmetryObject*>(s.ref);
00150 VariableSequenceSymmetryObject* varseqref =
00151 dynamic_cast<VariableSequenceSymmetryObject*>(s.ref);
00152 ValueSequenceSymmetryObject* valseqref =
00153 dynamic_cast<ValueSequenceSymmetryObject*>(s.ref);
00154 if (varref) {
00155 int n = varref->nxs;
00156 int* indices = home.alloc<int>(n);
00157 for (int i = 0 ; i < n ; i++) {
00158 VariableMap::const_iterator index = variableMap.find(varref->xs[i]);
00159 if (index == variableMap.end())
00160 throw LDSBUnbranchedVariable("VariableSymmetryObject::createInt");
00161 indices[i] = index->second;
00162 }
00163 return new (home) VariableSymmetryImp<IntView>(home, indices, n);
00164 }
00165 if (valref) {
00166 int n = valref->values.size();
00167 int *vs = home.alloc<int>(n);
00168 int i = 0;
00169 for (IntSetValues v(valref->values) ; v() ; ++v) {
00170 vs[i] = v.val();
00171 i++;
00172 }
00173 return new (home) ValueSymmetryImp<IntView>(home, vs, n);
00174 }
00175 if (varseqref) {
00176 int n = varseqref->nxs;
00177 int* indices = home.alloc<int>(n);
00178 for (int i = 0 ; i < n ; i++) {
00179 VariableMap::const_iterator index =
00180 variableMap.find(varseqref->xs[i]);
00181 if (index == variableMap.end())
00182 throw LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createInt");
00183 indices[i] = index->second;
00184 }
00185 return new (home) VariableSequenceSymmetryImp<IntView>(home, indices, n,
00186 varseqref->seq_size);
00187 }
00188 if (valseqref) {
00189 unsigned int n = valseqref->values.size();
00190 int *vs = home.alloc<int>(n);
00191 for (unsigned int i = 0 ; i < n ; i++)
00192 vs[i] = valseqref->values[i];
00193 return new (home) ValueSequenceSymmetryImp<IntView>(home, vs, n,
00194 valseqref->seq_size);
00195 }
00196 GECODE_NEVER;
00197 return NULL;
00198 }
00199
00201 SymmetryImp<BoolView>* createBoolSym(Space& home, const SymmetryHandle& s,
00202 VariableMap variableMap) {
00203 VariableSymmetryObject* varref =
00204 dynamic_cast<VariableSymmetryObject*>(s.ref);
00205 ValueSymmetryObject* valref =
00206 dynamic_cast<ValueSymmetryObject*>(s.ref);
00207 VariableSequenceSymmetryObject* varseqref =
00208 dynamic_cast<VariableSequenceSymmetryObject*>(s.ref);
00209 ValueSequenceSymmetryObject* valseqref =
00210 dynamic_cast<ValueSequenceSymmetryObject*>(s.ref);
00211 if (varref) {
00212 int n = varref->nxs;
00213 int* indices = home.alloc<int>(n);
00214 for (int i = 0 ; i < n ; i++) {
00215 VariableMap::const_iterator index = variableMap.find(varref->xs[i]);
00216 if (index == variableMap.end())
00217 throw LDSBUnbranchedVariable("VariableSymmetryObject::createBool");
00218 indices[i] = index->second;
00219 }
00220 return new (home) VariableSymmetryImp<BoolView>(home, indices, n);
00221 }
00222 if (valref) {
00223 int n = valref->values.size();
00224 int *vs = home.alloc<int>(n);
00225 int i = 0;
00226 for (IntSetValues v(valref->values) ; v() ; ++v) {
00227 vs[i] = v.val();
00228 i++;
00229 }
00230 return new (home) ValueSymmetryImp<BoolView>(home, vs, n);
00231 }
00232 if (varseqref) {
00233 int n = varseqref->nxs;
00234 int* indices = home.alloc<int>(n);
00235 for (int i = 0 ; i < n ; i++) {
00236 VariableMap::const_iterator index =
00237 variableMap.find(varseqref->xs[i]);
00238 if (index == variableMap.end())
00239 throw LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createBool");
00240 indices[i] = index->second;
00241 }
00242 return new (home) VariableSequenceSymmetryImp<BoolView>(home, indices,
00243 n, varseqref->seq_size);
00244 }
00245 if (valseqref) {
00246 unsigned int n = valseqref->values.size();
00247 int *vs = home.alloc<int>(n);
00248 for (unsigned int i = 0 ; i < n ; i++)
00249 vs[i] = valseqref->values[i];
00250 return new (home) ValueSequenceSymmetryImp<BoolView>(home, vs, n,
00251 valseqref->seq_size);
00252 }
00253 GECODE_NEVER;
00254 return NULL;
00255 }
00256 }}}
00257
00258 namespace Gecode {
00259
00260 using namespace Int::LDSB;
00261
00262 BrancherHandle
00263 branch(Home home, const IntVarArgs& x,
00264 IntVarBranch vars, IntValBranch vals,
00265 const Symmetries& syms,
00266 IntBranchFilter bf, IntVarValPrint vvp) {
00267 using namespace Int;
00268 if (home.failed()) return BrancherHandle();
00269 vars.expand(home,x);
00270 ViewArray<IntView> xv(home,x);
00271 ViewSel<IntView>* vs[1] = {
00272 Branch::viewselint(home,vars)
00273 };
00274 switch (vals.select()) {
00275 case IntValBranch::SEL_SPLIT_MIN:
00276 case IntValBranch::SEL_SPLIT_MAX:
00277 case IntValBranch::SEL_RANGE_MIN:
00278 case IntValBranch::SEL_RANGE_MAX:
00279 case IntValBranch::SEL_VALUES_MIN:
00280 case IntValBranch::SEL_VALUES_MAX:
00281 throw LDSBBadValueSelection("Int::LDSB::branch");
00282 break;
00283 case IntValBranch::SEL_VAL_COMMIT:
00284 if (vals.commit() != NULL)
00285 throw LDSBBadValueSelection("Int::LDSB::branch");
00286
00287
00288 default:
00289
00290
00291 VariableMap variableMap;
00292 for (int i = 0 ; i < x.size() ; i++)
00293 variableMap[x[i].varimp()] = i;
00294
00295
00296
00297 int n = syms.size();
00298 SymmetryImp<IntView>** array =
00299 static_cast<Space&>(home).alloc<SymmetryImp<IntView>* >(n);
00300 for (int i = 0 ; i < n ; i++) {
00301 array[i] = createIntSym(home, syms[i], variableMap);
00302 }
00303
00304 return LDSBBrancher<IntView,1,int,2>::post
00305 (home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00306 array,n,bf,vvp);
00307 }
00308 }
00309
00310 BrancherHandle
00311 branch(Home home, const IntVarArgs& x,
00312 TieBreak<IntVarBranch> vars, IntValBranch vals,
00313 const Symmetries& syms,
00314 IntBranchFilter bf, IntVarValPrint vvp) {
00315 using namespace Int;
00316 if (home.failed()) return BrancherHandle();
00317 vars.a.expand(home,x);
00318 if ((vars.a.select() == IntVarBranch::SEL_NONE) ||
00319 (vars.a.select() == IntVarBranch::SEL_RND))
00320 vars.b = INT_VAR_NONE();
00321 vars.b.expand(home,x);
00322 if ((vars.b.select() == IntVarBranch::SEL_NONE) ||
00323 (vars.b.select() == IntVarBranch::SEL_RND))
00324 vars.c = INT_VAR_NONE();
00325 vars.c.expand(home,x);
00326 if ((vars.c.select() == IntVarBranch::SEL_NONE) ||
00327 (vars.c.select() == IntVarBranch::SEL_RND))
00328 vars.d = INT_VAR_NONE();
00329 vars.d.expand(home,x);
00330 if (vars.b.select() == IntVarBranch::SEL_NONE) {
00331 return branch(home,x,vars.a,vals,syms,bf,vvp);
00332 } else {
00333
00334
00335 VariableMap variableMap;
00336 for (int i = 0 ; i < x.size() ; i++)
00337 variableMap[x[i].varimp()] = i;
00338
00339
00340
00341 int n = syms.size();
00342 SymmetryImp<IntView>** array =
00343 static_cast<Space&>(home).alloc<SymmetryImp<IntView>* >(n);
00344 for (int i = 0 ; i < n ; i++) {
00345 array[i] = createIntSym(home, syms[i], variableMap);
00346 }
00347
00348 ViewArray<IntView> xv(home,x);
00349 if (vars.c.select() == IntVarBranch::SEL_NONE) {
00350 ViewSel<IntView>* vs[2] = {
00351 Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b)
00352 };
00353 switch (vals.select()) {
00354 case IntValBranch::SEL_SPLIT_MIN:
00355 case IntValBranch::SEL_SPLIT_MAX:
00356 case IntValBranch::SEL_RANGE_MIN:
00357 case IntValBranch::SEL_RANGE_MAX:
00358 case IntValBranch::SEL_VALUES_MIN:
00359 case IntValBranch::SEL_VALUES_MAX:
00360 throw LDSBBadValueSelection("Int::LDSB::branch");
00361 break;
00362 case IntValBranch::SEL_VAL_COMMIT:
00363 if (vals.commit() != NULL)
00364 throw LDSBBadValueSelection("Int::LDSB::branch");
00365
00366
00367 default:
00368 return LDSBBrancher<IntView,2,int,2>
00369 ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00370 array,n,bf,vvp);
00371 }
00372 } else if (vars.d.select() == IntVarBranch::SEL_NONE) {
00373 ViewSel<IntView>* vs[3] = {
00374 Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b),
00375 Branch::viewselint(home,vars.c)
00376 };
00377 switch (vals.select()) {
00378 case IntValBranch::SEL_SPLIT_MIN:
00379 case IntValBranch::SEL_SPLIT_MAX:
00380 case IntValBranch::SEL_RANGE_MIN:
00381 case IntValBranch::SEL_RANGE_MAX:
00382 case IntValBranch::SEL_VALUES_MIN:
00383 case IntValBranch::SEL_VALUES_MAX:
00384 throw LDSBBadValueSelection("Int::LDSB::branch");
00385 break;
00386 case IntValBranch::SEL_VAL_COMMIT:
00387 if (vals.commit() != NULL)
00388 throw LDSBBadValueSelection("Int::LDSB::branch");
00389
00390
00391 default:
00392 return LDSBBrancher<IntView,3,int,2>
00393 ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00394 array,n,bf,vvp);
00395 }
00396 } else {
00397 ViewSel<IntView>* vs[4] = {
00398 Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b),
00399 Branch::viewselint(home,vars.c),Branch::viewselint(home,vars.d)
00400 };
00401 switch (vals.select()) {
00402 case IntValBranch::SEL_SPLIT_MIN:
00403 case IntValBranch::SEL_SPLIT_MAX:
00404 case IntValBranch::SEL_RANGE_MIN:
00405 case IntValBranch::SEL_RANGE_MAX:
00406 case IntValBranch::SEL_VALUES_MIN:
00407 case IntValBranch::SEL_VALUES_MAX:
00408 throw LDSBBadValueSelection("Int::LDSB::branch");
00409 break;
00410 case IntValBranch::SEL_VAL_COMMIT:
00411 if (vals.commit() != NULL)
00412 throw LDSBBadValueSelection("Int::LDSB::branch");
00413
00414
00415 default:
00416 return LDSBBrancher<IntView,4,int,2>
00417 ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00418 array,n,bf,vvp);
00419 }
00420 }
00421 }
00422 GECODE_NEVER;
00423 return BrancherHandle();
00424 }
00425
00426 BrancherHandle
00427 branch(Home home, const BoolVarArgs& x,
00428 IntVarBranch vars, IntValBranch vals,
00429 const Symmetries& syms,
00430 BoolBranchFilter bf, BoolVarValPrint vvp) {
00431 using namespace Int;
00432 if (home.failed()) return BrancherHandle();
00433 vars.expand(home,x);
00434 ViewArray<BoolView> xv(home,x);
00435 ViewSel<BoolView>* vs[1] = {
00436 Branch::viewselbool(home,vars)
00437 };
00438
00439
00440
00441 VariableMap variableMap;
00442 for (int i = 0 ; i < x.size() ; i++)
00443 variableMap[x[i].varimp()] = i;
00444
00445
00446
00447 int n = syms.size();
00448 SymmetryImp<BoolView>** array =
00449 static_cast<Space&>(home).alloc<SymmetryImp<BoolView>* >(n);
00450 for (int i = 0 ; i < n ; i++) {
00451 array[i] = createBoolSym(home, syms[i], variableMap);
00452 }
00453
00454
00455
00456
00457
00458 switch (vals.select()) {
00459 case IntValBranch::SEL_SPLIT_MIN:
00460 case IntValBranch::SEL_SPLIT_MAX:
00461 case IntValBranch::SEL_RANGE_MIN:
00462 case IntValBranch::SEL_RANGE_MAX:
00463 case IntValBranch::SEL_VALUES_MIN:
00464 case IntValBranch::SEL_VALUES_MAX:
00465 throw LDSBBadValueSelection("Int::LDSB::branch");
00466 break;
00467 case IntValBranch::SEL_VAL_COMMIT:
00468 if (vals.commit() != NULL)
00469 throw LDSBBadValueSelection("Int::LDSB::branch");
00470
00471
00472 default:
00473 return LDSBBrancher<BoolView,1,int,2>::post
00474 (home,xv,vs,Branch::valselcommitbool(home,x.size(),vals),array,n,bf,vvp);
00475 }
00476 GECODE_NEVER;
00477 return BrancherHandle();
00478 }
00479
00480
00481 BrancherHandle
00482 branch(Home home, const BoolVarArgs& x,
00483 TieBreak<IntVarBranch> vars, IntValBranch vals,
00484 const Symmetries& syms,
00485 BoolBranchFilter bf, BoolVarValPrint vvp) {
00486 using namespace Int;
00487 if (home.failed()) return BrancherHandle();
00488 vars.a.expand(home,x);
00489 if ((vars.a.select() == IntVarBranch::SEL_NONE) ||
00490 (vars.a.select() == IntVarBranch::SEL_RND))
00491 vars.b = INT_VAR_NONE();
00492 vars.b.expand(home,x);
00493 if ((vars.b.select() == IntVarBranch::SEL_NONE) ||
00494 (vars.b.select() == IntVarBranch::SEL_RND))
00495 vars.c = INT_VAR_NONE();
00496 vars.c.expand(home,x);
00497 if ((vars.c.select() == IntVarBranch::SEL_NONE) ||
00498 (vars.c.select() == IntVarBranch::SEL_RND))
00499 vars.d = INT_VAR_NONE();
00500 vars.d.expand(home,x);
00501 if (vars.b.select() == IntVarBranch::SEL_NONE) {
00502 return branch(home,x,vars.a,vals,syms,bf,vvp);
00503 } else {
00504
00505
00506 VariableMap variableMap;
00507 for (int i = 0 ; i < x.size() ; i++)
00508 variableMap[x[i].varimp()] = i;
00509
00510
00511
00512 int n = syms.size();
00513 SymmetryImp<BoolView>** array =
00514 static_cast<Space&>(home).alloc<SymmetryImp<BoolView>* >(n);
00515 for (int i = 0 ; i < n ; i++) {
00516 array[i] = createBoolSym(home, syms[i], variableMap);
00517 }
00518
00519
00520
00521
00522
00523 switch (vals.select()) {
00524 case IntValBranch::SEL_SPLIT_MIN:
00525 case IntValBranch::SEL_SPLIT_MAX:
00526 case IntValBranch::SEL_RANGE_MIN:
00527 case IntValBranch::SEL_RANGE_MAX:
00528 case IntValBranch::SEL_VALUES_MIN:
00529 case IntValBranch::SEL_VALUES_MAX:
00530 throw LDSBBadValueSelection("Int::LDSB::branch");
00531 break;
00532 case IntValBranch::SEL_VAL_COMMIT:
00533 if (vals.commit() != NULL)
00534 throw LDSBBadValueSelection("Int::LDSB::branch");
00535
00536
00537 default:
00538 ;
00539
00540 }
00541
00542 ViewArray<BoolView> xv(home,x);
00543 ValSelCommitBase<BoolView,int>*
00544 vsc = Branch::valselcommitbool(home,x.size(),vals);
00545 if (vars.c.select() == IntVarBranch::SEL_NONE) {
00546 ViewSel<BoolView>* vs[2] = {
00547 Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b)
00548 };
00549 return
00550 LDSBBrancher<BoolView,2,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00551 } else if (vars.d.select() == IntVarBranch::SEL_NONE) {
00552 ViewSel<BoolView>* vs[3] = {
00553 Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b),
00554 Branch::viewselbool(home,vars.c)
00555 };
00556 return
00557 LDSBBrancher<BoolView,3,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00558 } else {
00559 ViewSel<BoolView>* vs[4] = {
00560 Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b),
00561 Branch::viewselbool(home,vars.c),Branch::viewselbool(home,vars.d)
00562 };
00563 return
00564 LDSBBrancher<BoolView,4,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00565 }
00566 }
00567 GECODE_NEVER;
00568 return BrancherHandle();
00569 }
00570
00571 }
00572
00573
00574
00575