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 <gecode/set/ldsb.hh> 35#include <gecode/set/branch.hh> 36#include <map> 37 38namespace Gecode { 39 using namespace Int::LDSB; 40 /* 41 * Implementation of some SymmetryHandle methods. 42 */ 43 44 SymmetryHandle VariableSymmetry(const SetVarArgs& x) { 45 ArgArray<VarImpBase*> a(x.size()); 46 for (int i = 0 ; i < x.size() ; i++) 47 a[i] = x[i].varimp(); 48 return SymmetryHandle(new VariableSymmetryObject(a)); 49 } 50 SymmetryHandle VariableSequenceSymmetry(const SetVarArgs& x, int ss) { 51 ArgArray<VarImpBase*> a(x.size()); 52 for (int i = 0 ; i < x.size() ; i++) 53 a[i] = x[i].varimp(); 54 return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss)); 55 } 56} 57 58namespace Gecode { namespace Int { namespace LDSB { 59 template <> 60 ModEvent prune<Set::SetView>(Space& home, Set::SetView x, int v) { 61 return x.exclude(home, v); 62 } 63}}} 64 65namespace Gecode { namespace Set { namespace LDSB { 66 67 /// Map from variable implementation to index 68 class VariableMap : public std::map<VarImpBase*,int> {}; 69 70 /* 71 * The createSetSym function is an almost exact copy of 72 * createIntSym/createBoolSym. 73 */ 74 SymmetryImp<SetView>* createSetSym(Space& home, const SymmetryHandle& s, 75 VariableMap variableMap) { 76 VariableSymmetryObject* varref = 77 dynamic_cast<VariableSymmetryObject*>(s.ref); 78 ValueSymmetryObject* valref = 79 dynamic_cast<ValueSymmetryObject*>(s.ref); 80 VariableSequenceSymmetryObject* varseqref = 81 dynamic_cast<VariableSequenceSymmetryObject*>(s.ref); 82 ValueSequenceSymmetryObject* valseqref = 83 dynamic_cast<ValueSequenceSymmetryObject*>(s.ref); 84 if (varref) { 85 int n = varref->nxs; 86 int* indices = home.alloc<int>(n); 87 for (int i = 0 ; i < n ; i++) { 88 VariableMap::const_iterator index = variableMap.find(varref->xs[i]); 89 if (index == variableMap.end()) 90 throw 91 Int::LDSBUnbranchedVariable("VariableSymmetryObject::createSet"); 92 indices[i] = index->second; 93 } 94 return new (home) VariableSymmetryImp<SetView>(home, indices, n); 95 } 96 if (valref) { 97 int n = valref->values.size(); 98 int *vs = home.alloc<int>(n); 99 int i = 0; 100 for (IntSetValues v(valref->values) ; v() ; ++v) { 101 vs[i] = v.val(); 102 i++; 103 } 104 return new (home) ValueSymmetryImp<SetView>(home, vs, n); 105 } 106 if (varseqref) { 107 int n = varseqref->nxs; 108 int* indices = home.alloc<int>(n); 109 for (int i = 0 ; i < n ; i++) { 110 VariableMap::const_iterator index = 111 variableMap.find(varseqref->xs[i]); 112 if (index == variableMap.end()) 113 throw 114 Int::LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createSet"); 115 indices[i] = index->second; 116 } 117 return new (home) VariableSequenceSymmetryImp<SetView>(home, indices, n, 118 varseqref->seq_size); 119 } 120 if (valseqref) { 121 unsigned int n = valseqref->values.size(); 122 int *vs = home.alloc<int>(n); 123 for (unsigned int i = 0 ; i < n ; i++) 124 vs[i] = valseqref->values[i]; 125 return new (home) ValueSequenceSymmetryImp<SetView>(home, vs, n, 126 valseqref->seq_size); 127 } 128 GECODE_NEVER; 129 return nullptr; 130 } 131}}} 132 133namespace Gecode { 134 135 using namespace Set::LDSB; 136 137 void 138 branch(Home home, const SetVarArgs& x, 139 SetVarBranch vars, SetValBranch vals, 140 const Symmetries& syms, 141 SetBranchFilter bf, 142 SetVarValPrint vvp) { 143 using namespace Set; 144 if (home.failed()) return; 145 vars.expand(home,x); 146 ViewArray<SetView> xv(home,x); 147 ViewSel<SetView>* vs[1] = { 148 Branch::viewsel(home,vars) 149 }; 150 151 // Construct mapping from each variable in the array to its index 152 // in the array. 153 VariableMap variableMap; 154 for (int i = 0 ; i < x.size() ; i++) 155 variableMap[x[i].varimp()] = i; 156 157 // Convert the modelling-level Symmetries object into an array of 158 // SymmetryImp objects. 159 int n = syms.size(); 160 SymmetryImp<SetView>** array = 161 static_cast<Space&>(home).alloc<SymmetryImp<SetView>* >(n); 162 for (int i = 0 ; i < n ; i++) { 163 array[i] = createSetSym(home, syms[i], variableMap); 164 } 165 166 postldsbsetbrancher<SetView,1,int,2> 167 (home,xv,vs,Branch::valselcommit(home,vals),array,n,bf,vvp); 168 } 169 170 void 171 branch(Home home, const SetVarArgs& x, 172 TieBreak<SetVarBranch> vars, SetValBranch vals, 173 const Symmetries& syms, 174 SetBranchFilter bf, 175 SetVarValPrint vvp) { 176 using namespace Set; 177 if (home.failed()) return; 178 vars.a.expand(home,x); 179 if ((vars.a.select() == SetVarBranch::SEL_NONE) || 180 (vars.a.select() == SetVarBranch::SEL_RND)) 181 vars.b = SET_VAR_NONE(); 182 vars.b.expand(home,x); 183 if ((vars.b.select() == SetVarBranch::SEL_NONE) || 184 (vars.b.select() == SetVarBranch::SEL_RND)) 185 vars.c = SET_VAR_NONE(); 186 vars.c.expand(home,x); 187 if ((vars.c.select() == SetVarBranch::SEL_NONE) || 188 (vars.c.select() == SetVarBranch::SEL_RND)) 189 vars.d = SET_VAR_NONE(); 190 vars.d.expand(home,x); 191 if (vars.b.select() == SetVarBranch::SEL_NONE) { 192 branch(home,x,vars.a,vals,syms,bf,vvp); 193 } else { 194 // Construct mapping from each variable in the array to its index 195 // in the array. 196 VariableMap variableMap; 197 for (int i = 0 ; i < x.size() ; i++) 198 variableMap[x[i].varimp()] = i; 199 200 // Convert the modelling-level Symmetries object into an array of 201 // SymmetryImp objects. 202 int n = syms.size(); 203 SymmetryImp<SetView>** array = 204 static_cast<Space&>(home).alloc<SymmetryImp<SetView>* >(n); 205 for (int i = 0 ; i < n ; i++) { 206 array[i] = Set::LDSB::createSetSym(home, syms[i], variableMap); 207 } 208 209 ViewArray<SetView> xv(home,x); 210 ValSelCommitBase<SetView,int>* vsc = Branch::valselcommit(home,vals); 211 if (vars.c.select() == SetVarBranch::SEL_NONE) { 212 ViewSel<SetView>* vs[2] = { 213 Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b) 214 }; 215 postldsbsetbrancher<SetView,2,int,2>(home,xv,vs,vsc,array,n,bf,vvp); 216 } else if (vars.d.select() == SetVarBranch::SEL_NONE) { 217 ViewSel<SetView>* vs[3] = { 218 Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b), 219 Branch::viewsel(home,vars.c) 220 }; 221 postldsbsetbrancher<SetView,3,int,2>(home,xv,vs,vsc,array,n,bf,vvp); 222 } else { 223 ViewSel<SetView>* vs[4] = { 224 Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b), 225 Branch::viewsel(home,vars.c),Branch::viewsel(home,vars.d) 226 }; 227 postldsbsetbrancher<SetView,4,int,2>(home,xv,vs,vsc,array,n,bf,vvp); 228 } 229 } 230 } 231 232} 233 234// STATISTICS: set-branch