this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 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 34namespace Gecode { 35 36 /** 37 * \defgroup TaskBranchView Generic brancher based on view selection 38 * 39 * Implements view-based brancher for an array of views and value. 40 * \ingroup TaskActor 41 */ 42 //@{ 43 /// Position information 44 class Pos { 45 public: 46 /// Position of view 47 const int pos; 48 /// Create position information 49 Pos(int p); 50 /// Create position information 51 Pos(const Pos& p); 52 }; 53 54 /// %Choices storing position 55 class GECODE_VTABLE_EXPORT PosChoice : public Choice { 56 private: 57 /// Position information 58 const Pos _pos; 59 protected: 60 /// Initialize 61 PosChoice(const PosChoice& c); 62 public: 63 /// Initialize choice for brancher \a b, number of alternatives \a a, and position \a p 64 PosChoice(const Brancher& b, unsigned int a, const Pos& p); 65 /// Return position in array 66 const Pos& pos(void) const; 67 /// Archive into \a e 68 virtual void archive(Archive& e) const; 69 }; 70 71 /** 72 * \brief Generic brancher by view selection 73 * 74 * Defined for views of type \a View and \a n view selectors for 75 * tie-breaking. 76 */ 77 template<class View, class Filter, int n> 78 class ViewBrancher : public Brancher { 79 protected: 80 /// The corresponding variable 81 typedef typename View::VarType Var; 82 /// Views to branch on 83 ViewArray<View> x; 84 /// Unassigned views start at x[start] 85 mutable int start; 86 /// View selection objects 87 ViewSel<View>* vs[n]; 88 /// Filter function 89 Filter f; 90 /// Return position information 91 Pos pos(Space& home); 92 /// Return view according to position information \a p 93 View view(const Pos& p) const; 94 /// Constructor for cloning \a b 95 ViewBrancher(Space& home, ViewBrancher<View,Filter,n>& b); 96 /// Constructor for creation 97 ViewBrancher(Home home, ViewArray<View>& x, ViewSel<View>* vs[n], 98 BranchFilter<Var> bf); 99 public: 100 /// Check status of brancher, return true if alternatives left 101 virtual bool status(const Space& home) const; 102 /// Delete brancher and return its size 103 virtual size_t dispose(Space& home); 104 }; 105 106 //@} 107 108 109 /* 110 * Position information 111 * 112 */ 113 forceinline 114 Pos::Pos(int p) : pos(p) {} 115 forceinline 116 Pos::Pos(const Pos& p) : pos(p.pos) {} 117 118 /* 119 * Choice with position 120 * 121 */ 122 forceinline 123 PosChoice::PosChoice(const Brancher& b, unsigned int a, const Pos& p) 124 : Choice(b,a), _pos(p) {} 125 forceinline const Pos& 126 PosChoice::pos(void) const { 127 return _pos; 128 } 129 forceinline void 130 PosChoice::archive(Archive& e) const { 131 Choice::archive(e); 132 e << _pos.pos; 133 } 134 135 template<class View, class Filter, int n> 136 forceinline 137 ViewBrancher<View,Filter,n>::ViewBrancher(Home home, ViewArray<View>& x0, 138 ViewSel<View>* vs0[n], 139 BranchFilter<Var> bf) 140 : Brancher(home), x(x0), start(0), f(bf) { 141 for (int i=0; i<n; i++) 142 vs[i] = vs0[i]; 143 for (int i=0; i<n; i++) 144 if (f.notice() || vs[i]->notice()) { 145 home.notice(*this,AP_DISPOSE,true); 146 break; 147 } 148 } 149 150 template<class View, class Filter, int n> 151 forceinline 152 ViewBrancher<View,Filter,n>::ViewBrancher(Space& home, 153 ViewBrancher<View,Filter,n>& vb) 154 : Brancher(home,vb), start(vb.start), f(vb.f) { 155 x.update(home,vb.x); 156 for (int i=0; i<n; i++) 157 vs[i] = vb.vs[i]->copy(home); 158 } 159 160 template<class View, class Filter, int n> 161 bool 162 ViewBrancher<View,Filter,n>::status(const Space& home) const { 163 for (int i=start; i < x.size(); i++) 164 if (!x[i].assigned() && f(home,x[i],i)) { 165 start = i; 166 return true; 167 } 168 return false; 169 } 170 171 template<class View, class Filter, int n> 172 inline Pos 173 ViewBrancher<View,Filter,n>::pos(Space& home) { 174 assert(!x[start].assigned()); 175 int s; 176 if (f) { 177 if (n == 1) { 178 s = vs[0]->select(home,x,start,f); 179 } else { 180 Region r; 181 int* ties = r.alloc<int>(x.size()-start+1); 182 int n_ties; 183 vs[0]->ties(home,x,start,ties,n_ties,f); 184 for (int i=1; (i < n-1) && (n_ties > 1); i++) 185 vs[i]->brk(home,x,ties,n_ties); 186 if (n_ties > 1) 187 s = vs[n-1]->select(home,x,ties,n_ties); 188 else 189 s = ties[0]; 190 } 191 } else { 192 if (n == 1) { 193 s = vs[0]->select(home,x,start); 194 } else { 195 Region r; 196 int* ties = r.alloc<int>(x.size()-start+1); 197 int n_ties; 198 vs[0]->ties(home,x,start,ties,n_ties); 199 for (int i=1; (i < n-1) && (n_ties > 1); i++) 200 vs[i]->brk(home,x,ties,n_ties); 201 if (n_ties > 1) 202 s = vs[n-1]->select(home,x,ties,n_ties); 203 else 204 s = ties[0]; 205 } 206 } 207 Pos p(s); 208 return p; 209 } 210 211 template<class View, class Filter, int n> 212 forceinline View 213 ViewBrancher<View,Filter,n>::view(const Pos& p) const { 214 return x[p.pos]; 215 } 216 217 template<class View, class Filter, int n> 218 forceinline size_t 219 ViewBrancher<View,Filter,n>::dispose(Space& home) { 220 for (int i=0; i<n; i++) 221 if (f.notice() || vs[i]->notice()) { 222 home.ignore(*this,AP_DISPOSE,true); 223 break; 224 } 225 for (int i=0; i<n; i++) 226 vs[i]->dispose(home); 227 (void) Brancher::dispose(home); 228 return sizeof(ViewBrancher<View,Filter,n>); 229 } 230 231} 232 233// STATISTICS: kernel-branch