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 Set { namespace LDSB {
00039
00040 template<class View, int n, class Val, unsigned int a,
00041 class Filter, class Print>
00042 LDSBSetBrancher<View,n,Val,a,Filter,Print>
00043 ::LDSBSetBrancher(Home home, ViewArray<View>& x,
00044 ViewSel<View>* vs[n],
00045 ValSelCommitBase<View,Val>* vsc,
00046 SymmetryImp<View>** syms, int nsyms,
00047 BranchFilter<Var> bf,
00048 VarValPrint<Var,Val> vvp)
00049 : LDSBBrancher<View,n,Val,a,Filter,Print>
00050 (home, x, vs, vsc, syms, nsyms, bf, vvp),
00051 _prevPos(-1),
00052 _copiedSyms(NULL),
00053 _nCopiedSyms(0),
00054 _stable(false) {
00055
00056 int seen = 0;
00057 int dest = this->_nsyms - 1;
00058 for (int i = 0 ; i < this->_nsyms - seen ; i++) {
00059 if (dynamic_cast<ValueSymmetryImp<View>*>(this->_syms[i])) {
00060 SymmetryImp<View>* t = this->_syms[i];
00061 this->_syms[i] = this->_syms[dest];
00062 this->_syms[dest] = t;
00063 dest--;
00064 seen++;
00065 }
00066 }
00067 _nValueSymmetries = seen;
00068 _nNonValueSymmetries = this->_nsyms - seen;
00069 }
00070
00071 template<class View, int n, class Val, unsigned int a,
00072 class Filter, class Print>
00073 LDSBSetBrancher<View,n,Val,a,Filter,Print>::
00074 LDSBSetBrancher(Space& home, bool shared,
00075 LDSBSetBrancher<View,n,Val,a,Filter,Print>& b)
00076 : LDSBBrancher<View,n,Val,a,Filter,Print>(home,shared,b),
00077 _prevPos(b._prevPos),
00078 _nNonValueSymmetries(b._nNonValueSymmetries),
00079 _nValueSymmetries(b._nValueSymmetries),
00080 _nCopiedSyms(b._nCopiedSyms),
00081 _leftBranchValues(b._leftBranchValues),
00082 _stable(b._stable) {
00083 if (_nCopiedSyms > 0) {
00084 _copiedSyms = home.alloc<ValueSymmetryImp<View>*>(_nCopiedSyms);
00085 for (int i = 0 ; i < _nCopiedSyms ; i++)
00086 _copiedSyms[i] = static_cast<ValueSymmetryImp<View>*>(
00087 b._copiedSyms[i]->copy(home, shared));
00088 } else {
00089 _copiedSyms = NULL;
00090 }
00091 }
00092
00102 template <class View>
00103 ValueSymmetryImp<View>*
00104 specialUpdate(Space& home, ValueSymmetryImp<View>* s, IntSet usedValues) {
00105
00106 IntArgs intersection;
00107 IntArgs difference;
00108 int n = 0;
00109 for (int i = s->values.next(s->values.offset()) ;
00110 i <= s->values.max_bit() ; i = s->values.next(i+1)) {
00111 n++;
00112 if (usedValues.in(i))
00113 intersection << i;
00114 else
00115 difference << i;
00116 }
00117
00118 for (IntSetValues v(usedValues) ; v() ; ++v) {
00119 s->update(Literal(0, v.val()));
00120 }
00121
00122 if (intersection.size() < 2)
00123 return NULL;
00124 int *a = new int[intersection.size()];
00125 for (int i = 0 ; i < intersection.size() ; i++) {
00126 a[i] = intersection[i];
00127 }
00128 ValueSymmetryImp<View>* ns =
00129 new (home) ValueSymmetryImp<View>(home, a, intersection.size());
00130 delete [] a;
00131 return ns;
00132 }
00133
00134 template<class View, int n, class Val, unsigned int a,
00135 class Filter, class Print>
00136 void
00137 LDSBSetBrancher<View,n,Val,a,Filter,Print>::
00138 updatePart1(Space& home, int choicePos) {
00139 if (_nValueSymmetries > 0) {
00140
00141
00142 if (choicePos != _prevPos) {
00143 if (_prevPos != -1) {
00144 int i = 0;
00145 for (int j = _nNonValueSymmetries ; j < this->_nsyms ; j++) {
00146 this->_syms[j] = _copiedSyms[i];
00147 i++;
00148 }
00149
00150 for (int i = 0 ; i < _nCopiedSyms ; i++) {
00151 ValueSymmetryImp<View>* ns =
00152 specialUpdate(home, _copiedSyms[i], _leftBranchValues);
00153 if (ns) {
00154 this->_syms = home.realloc<SymmetryImp<View>*>(this->_syms,
00155 this->_nsyms,
00156 this->_nsyms+1);
00157 this->_syms[this->_nsyms] = ns;
00158 this->_nsyms++;
00159 this->_nValueSymmetries++;
00160 }
00161 }
00162 }
00163
00164
00165 _leftBranchValues = IntSet::empty;
00166 _prevPos = choicePos;
00167 if (_nCopiedSyms > 0) home.free(_copiedSyms, _nCopiedSyms);
00168 _nCopiedSyms = _nValueSymmetries;
00169 _copiedSyms = home.alloc<ValueSymmetryImp<View>*>(_nCopiedSyms);
00170 int i = 0;
00171 for (int j = _nNonValueSymmetries ; j < this->_nsyms ; j++) {
00172 ValueSymmetryImp<View>* vsi =
00173 static_cast<ValueSymmetryImp<View>*>(this->_syms[j]);
00174 _copiedSyms[i] =
00175 static_cast<ValueSymmetryImp<View>*>(vsi->copy(home, false));
00176 i++;
00177 }
00178 }
00179 }
00180 }
00181
00182
00183 template<class View, int n, class Val, unsigned int a,
00184 class Filter, class Print>
00185 const Choice*
00186 LDSBSetBrancher<View,n,Val,a,Filter,Print>::choice(Space& home) {
00187
00188 const Choice* c = ViewValBrancher<View,n,Val,a,Filter,Print>::choice(home);
00189 const PosValChoice<Val>* pvc = static_cast<const PosValChoice<Val>* >(c);
00190
00191
00192
00193 int choicePos = pvc->pos().pos;
00194 delete c;
00195
00196 assert(!_stable);
00197 updatePart1(home, choicePos);
00198
00199 return LDSBBrancher<View,n,Val,a,Filter,Print>::choice(home);
00200 }
00201
00202 template<class View, int n, class Val, unsigned int a,
00203 class Filter, class Print>
00204 ExecStatus
00205 LDSBSetBrancher<View,n,Val,a,Filter,Print>
00206 ::commit(Space& home, const Choice& c, unsigned int b) {
00207 const LDSBChoice<Val>& pvc
00208 = static_cast<const LDSBChoice<Val>&>(c);
00209 int choicePos = pvc.pos().pos;
00210 int choiceVal = pvc.val();
00211
00212 if (!_stable)
00213 updatePart1(home, choicePos);
00214
00215 if (b == 0) {
00216 IntArgs ia;
00217 for (IntSetValues v(_leftBranchValues) ; v() ; ++v) {
00218 ia << v.val();
00219 }
00220 ia << choiceVal;
00221 _leftBranchValues = IntSet(ia);
00222
00223
00224 ExecStatus fromBase = ViewValBrancher<View,n,Val,a,Filter,Print>
00225 ::commit(home, c, b);
00226 GECODE_ES_CHECK(fromBase);
00227 for (int i = 0 ; i < this->_nsyms ; i++)
00228 this->_syms[i]->update(Literal(choicePos, choiceVal));
00229 } else if (b == 1) {
00230
00231 ExecStatus fromBase = ViewValBrancher<View,n,Val,a,Filter,Print>
00232 ::commit(home, c, b);
00233 GECODE_ES_CHECK(fromBase);
00234
00235
00236 int nliterals = pvc.nliterals();
00237 const Literal* literals = pvc.literals();
00238 for (int i = 0 ; i < nliterals ; i++) {
00239 const Literal& l = literals[i];
00240 ModEvent me = prune<View>(home, this->x[l._variable], l._value);
00241 GECODE_ME_CHECK(me);
00242 }
00243 }
00244
00245 return ES_OK;
00246 }
00247
00248 template<class View, int n, class Val, unsigned int a,
00249 class Filter, class Print>
00250 Actor*
00251 LDSBSetBrancher<View,n,Val,a,Filter,Print>::copy(Space& home, bool shared) {
00252 return new (home) LDSBSetBrancher<View,n,Val,a,Filter,Print>
00253 (home,shared,*this);
00254 }
00255
00256 template<class View, int n, class Val, unsigned int a,
00257 class Filter, class Print>
00258 forceinline void
00259 LDSBSetBrancher<View,n,Val,a,Filter,Print>::
00260 post(Home home, ViewArray<View>& x,
00261 ViewSel<View>* vs[n], ValSelCommitBase<View,Val>* vsc,
00262 SymmetryImp<View>** syms, int nsyms,
00263 BranchFilter<Var> bf,
00264 VarValPrint<Var,Val> vvp) {
00265 (void) new (home) LDSBSetBrancher<View,n,Val,a,Filter,Print>
00266 (home,x,vs,vsc,syms,nsyms,bf,vvp);
00267 }
00268
00269 template<class View, int n, class Val, unsigned int a>
00270 forceinline void
00271 postldsbsetbrancher(Home home,
00272 ViewArray<View>& x,
00273 ViewSel<View>* vs[n],
00274 ValSelCommitBase<View,Val>* vsc,
00275 SymmetryImp<View>** syms, int nsyms,
00276 BranchFilter<typename View::VarType> bf,
00277 VarValPrint<typename View::VarType,Val> vvp) {
00278 if (bf) {
00279 if (vvp) {
00280 LDSBSetBrancher<View,n,Val,a,BrancherFilter<View>,BrancherPrint<View,Val> >
00281 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp);
00282 } else {
00283 LDSBSetBrancher<View,n,Val,a,BrancherFilter<View>,BrancherNoPrint<View,Val> >
00284 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp);
00285 }
00286 } else {
00287 if (vvp) {
00288 LDSBSetBrancher<View,n,Val,a,BrancherNoFilter<View>,BrancherPrint<View,Val> >
00289 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp);
00290 } else {
00291 LDSBSetBrancher<View,n,Val,a,BrancherNoFilter<View>,BrancherNoPrint<View,Val> >
00292 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp);
00293 }
00294 }
00295 }
00296
00297 }}}
00298
00299