this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christopher Mears <chris.mears@monash.edu> 5 * 6 * Copyright: 7 * Christopher Mears, 2012 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include <deque> 35#include <set> 36 37namespace Gecode { namespace Int { namespace LDSB { 38 39 forceinline 40 Literal::Literal(void) 41 : _variable(-1), _value(-1) {} 42 43 forceinline 44 Literal::Literal(int idx, int val) 45 : _variable(idx), _value(val) {} 46 47 forceinline 48 bool 49 Literal::operator <(const Literal &rhs) const { 50 int d = rhs._variable - _variable; 51 if (d > 0) return true; 52 else if (d == 0) return rhs._value > _value; 53 else return false; 54 } 55 56 57 template<class Val> 58 inline 59 LDSBChoice<Val>::LDSBChoice(const Brancher& b, unsigned int a, const Pos& p, 60 const Val& n, const Literal* literals, 61 int nliterals) 62 : PosValChoice<Val>(b,a,p,n), _literals(literals), _nliterals(nliterals) 63 {} 64 65 template<class Val> 66 LDSBChoice<Val>::~LDSBChoice(void) { 67 delete [] _literals; 68 } 69 70 template<class Val> 71 forceinline const Literal* 72 LDSBChoice<Val>::literals(void) const { return _literals; } 73 74 template<class Val> 75 forceinline int 76 LDSBChoice<Val>::nliterals(void) const { return _nliterals; } 77 78 template<class Val> 79 void 80 LDSBChoice<Val>::archive(Archive& e) const { 81 PosValChoice<Val>::archive(e); 82 e << _nliterals; 83 for (int i = 0 ; i < _nliterals ; i++) { 84 e << _literals[i]._variable; 85 e << _literals[i]._value; 86 } 87 } 88 89 90 91 template<class View, int n, class Val, unsigned int a, 92 class Filter, class Print> 93 LDSBBrancher<View,n,Val,a,Filter,Print> 94 ::LDSBBrancher(Home home, ViewArray<View>& x, 95 ViewSel<View>* vs[n], 96 ValSelCommitBase<View,Val>* vsc, 97 SymmetryImp<View>** syms, int nsyms, 98 BranchFilter<typename LDSBBrancher<View,n,Val,a,Filter,Print>::Var> bf, 99 VarValPrint<typename LDSBBrancher<View,n,Val,a,Filter,Print>::Var,Val> vvp) 100 : ViewValBrancher<View,n,Val,a,Filter,Print>(home, x, vs, vsc, bf, vvp), 101 _syms(syms), 102 _nsyms(nsyms), 103 _prevPos(-1) 104 { 105 home.notice(*this, AP_DISPOSE, true); 106 } 107 108 template<class View, int n, class Val, unsigned int a, 109 class Filter, class Print> 110 forceinline void 111 LDSBBrancher<View,n,Val,a,Filter,Print>:: 112 post(Home home, ViewArray<View>& x, 113 ViewSel<View>* vs[n], ValSelCommitBase<View,Val>* vsc, 114 SymmetryImp<View>** syms, int nsyms, 115 BranchFilter<typename LDSBBrancher<View,n,Val,a,Filter,Print>::Var> bf, 116 VarValPrint<typename LDSBBrancher<View,n,Val,a,Filter,Print>::Var,Val> vvp) { 117 (void) new (home) LDSBBrancher<View,n,Val,a,Filter,Print> 118 (home,x,vs,vsc,syms,nsyms,bf,vvp); 119 } 120 121 template<class View, int n, class Val, unsigned int a, 122 class Filter, class Print> 123 forceinline 124 LDSBBrancher<View,n,Val,a,Filter,Print>:: 125 LDSBBrancher(Space& home, 126 LDSBBrancher<View,n,Val,a,Filter,Print>& b) 127 : ViewValBrancher<View,n,Val,a,Filter,Print>(home,b), 128 _nsyms(b._nsyms), 129 _prevPos(b._prevPos) { 130 _syms = home.alloc<SymmetryImp<View>*>(_nsyms); 131 for (int i = 0 ; i < _nsyms ; i++) 132 _syms[i] = b._syms[i]->copy(home); 133 } 134 135 template<class View, int n, class Val, unsigned int a, 136 class Filter, class Print> 137 Actor* 138 LDSBBrancher<View,n,Val,a,Filter,Print>::copy(Space& home) { 139 return new (home) LDSBBrancher<View,n,Val,a,Filter,Print> 140 (home,*this); 141 } 142 143 144 // Compute choice 145 template<class View, int n, class Val, unsigned int a, 146 class Filter, class Print> 147 const Choice* 148 LDSBBrancher<View,n,Val,a,Filter,Print>::choice(Space& home) { 149 // Making the PVC here is not so nice, I think. 150 const Choice* c = ViewValBrancher<View,n,Val,a,Filter,Print>::choice(home); 151 const PosValChoice<Val>* pvc = static_cast<const PosValChoice<Val>* >(c); 152 153 // Compute symmetries. 154 155 int choicePos = pvc->pos().pos; 156 int choiceVal = pvc->val(); 157 delete c; 158 159 _prevPos = choicePos; 160 161 // TODO: It should be possible to use simpler containers than the 162 // STL ones here. 163 std::deque<Literal> queue; 164 std::set<Literal> seen; 165 166 seen.insert(Literal(choicePos, choiceVal)); 167 queue.push_back(Literal(choicePos, choiceVal)); 168 169 do { 170 Literal l = queue[0]; 171 queue.pop_front(); 172 173 for (int i = 0 ; i < _nsyms ; i++) { 174 ArgArray<Literal> toExclude = _syms[i]->symmetric(l, this->x); 175 for (int j = 0 ; j < toExclude.size() ; ++j) { 176 if (seen.find(toExclude[j]) == seen.end()) 177 queue.push_back(toExclude[j]); 178 seen.insert(toExclude[j]); 179 } 180 } 181 } while (queue.size() > 0); 182 183 // Convert "seen" vector into array. 184 int nliterals = static_cast<int>(seen.size()); 185 Literal* literals = new Literal[nliterals]; 186 std::set<Literal>::iterator it = seen.begin(); 187 for (int i = 0 ; i < nliterals ; i++) { 188 literals[i] = *it; 189 ++it; 190 } 191 192 return new LDSBChoice<Val>(*this,a,choicePos,choiceVal, literals, nliterals); 193 } 194 195 196 template<class View, int n, class Val, unsigned int a, 197 class Filter, class Print> 198 const Choice* 199 LDSBBrancher<View,n,Val,a,Filter,Print>::choice(const Space& home, 200 Archive& e) { 201 (void) home; 202 int p; e >> p; 203 Val v; e >> v; 204 int nliterals; e >> nliterals; 205 Literal* literals = new Literal[nliterals]; 206 for (int i = 0 ; i < nliterals ; i++) { 207 e >> literals[i]._variable; 208 e >> literals[i]._value; 209 } 210 return new LDSBChoice<Val>(*this,a,p,v, literals, nliterals); 211 } 212 213 template <> 214 inline 215 ModEvent 216 prune<Int::IntView>(Space& home, Int::IntView x, int v) { 217 return x.nq(home, v); 218 } 219 220 template <> 221 inline 222 ModEvent 223 prune<Int::BoolView>(Space& home, Int::BoolView x, int v) { 224 return x.nq(home, v); 225 } 226 227 228 template<class View, int n, class Val, unsigned int a, 229 class Filter, class Print> 230 ExecStatus 231 LDSBBrancher<View,n,Val,a,Filter,Print> 232 ::commit(Space& home, const Choice& c, unsigned int b) { 233 const LDSBChoice<Val>& pvc 234 = static_cast<const LDSBChoice<Val>&>(c); 235 int choicePos = pvc.pos().pos; 236 int choiceVal = pvc.val(); 237 238 if (b == 0) { 239 // Post the branching constraint. 240 ExecStatus fromBase = ViewValBrancher<View,n,Val,a,Filter,Print> 241 ::commit(home, c, b); 242 GECODE_ES_CHECK(fromBase); 243 for (int i = 0 ; i < this->_nsyms ; i++) 244 this->_syms[i]->update(Literal(choicePos, choiceVal)); 245 } else if (b == 1) { 246 // Post the branching constraint. 247 ExecStatus fromBase = ViewValBrancher<View,n,Val,a,Filter,Print> 248 ::commit(home, c, b); 249 GECODE_ES_CHECK(fromBase); 250 251 // Post prunings. 252 int nliterals = pvc.nliterals(); 253 const Literal* literals = pvc.literals(); 254 for (int i = 0 ; i < nliterals ; i++) { 255 const Literal& l = literals[i]; 256 ModEvent me = prune<View>(home, this->x[l._variable], l._value); 257 GECODE_ME_CHECK(me); 258 } 259 } 260 261 return ES_OK; 262 } 263 264 template<class View, int n, class Val, unsigned int a, 265 class Filter, class Print> 266 size_t 267 LDSBBrancher<View,n,Val,a,Filter,Print>::dispose(Space& home) { 268 home.ignore(*this,AP_DISPOSE,true); 269 (void) ViewValBrancher<View,n,Val,a,Filter,Print>::dispose(home); 270 return sizeof(LDSBBrancher<View,n,Val,a,Filter,Print>); 271 } 272 273 template<class View, int n, class Val, unsigned int a> 274 forceinline void 275 postldsbbrancher(Home home, 276 ViewArray<View>& x, 277 ViewSel<View>* vs[n], 278 ValSelCommitBase<View,Val>* vsc, 279 SymmetryImp<View>** syms, int nsyms, 280 BranchFilter<typename View::VarType> bf, 281 VarValPrint<typename View::VarType,Val> vvp) { 282 if (bf) { 283 if (vvp) { 284 LDSBBrancher<View,n,Val,a,BrancherFilter<View>,BrancherPrint<View,Val>> 285 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp); 286 } else { 287 LDSBBrancher<View,n,Val,a,BrancherFilter<View>,BrancherNoPrint<View,Val> > 288 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp); 289 } 290 } else { 291 if (vvp) { 292 LDSBBrancher<View,n,Val,a,BrancherNoFilter<View>,BrancherPrint<View,Val>> 293 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp); 294 } else { 295 LDSBBrancher<View,n,Val,a,BrancherNoFilter<View>,BrancherNoPrint<View,Val> > 296 ::post(home,x,vs,vsc,syms,nsyms,bf,vvp); 297 } 298 } 299 } 300 301}}} 302 303// STATISTICS: int-branch