this repo has no description
at develop 7.7 kB view raw
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, 2008 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 { namespace Int { namespace Branch { 35 36 /// %Choice storing position and values for integer views 37 class GECODE_VTABLE_EXPORT PosValuesChoice : public PosChoice { 38 private: 39 /// Information about position and minimum 40 class PosMin { 41 public: 42 /// Start position of range 43 unsigned int pos; 44 /// Minmum of range 45 int min; 46 }; 47 /// Number of ranges 48 unsigned int n; 49 /// Values to assign to 50 PosMin* pm; 51 public: 52 /// Initialize choice for brancher \a b, position \a p, and view \a x 53 GECODE_INT_EXPORT 54 PosValuesChoice(const Brancher& b, const Pos& p, IntView x); 55 /// Initialize choice for brancher \a b from archive \a e 56 GECODE_INT_EXPORT 57 PosValuesChoice(const Brancher& b, unsigned int alt, Pos p, Archive& e); 58 /// Return value to branch with for alternative \a a 59 int val(unsigned int a) const; 60 /// Deallocate 61 GECODE_INT_EXPORT 62 virtual ~PosValuesChoice(void); 63 /// Archive into \a e 64 GECODE_INT_EXPORT 65 virtual void archive(Archive& e) const; 66 }; 67 68 forceinline int 69 PosValuesChoice::val(unsigned int a) const { 70 PosMin* l = &pm[0]; 71 PosMin* r = &pm[n-1]; 72 while (true) { 73 PosMin* m = l + (r-l)/2; 74 if (a < m->pos) { 75 r=m-1; 76 } else if (a >= (m+1)->pos) { 77 l=m+1; 78 } else { 79 return m->min + static_cast<int>(a - m->pos); 80 } 81 } 82 GECODE_NEVER; 83 return 0; 84 } 85 86 87 template<int n, bool min, class Filter, class Print> 88 forceinline 89 ViewValuesBrancher<n,min,Filter,Print>:: 90 ViewValuesBrancher(Home home, ViewArray<IntView>& x, 91 ViewSel<IntView>* vs[n], 92 IntBranchFilter bf, 93 IntVarValPrint vvp) 94 : ViewBrancher<IntView,Filter,n>(home,x,vs,bf), p(vvp) { 95 if (p.notice()) 96 home.notice(*this,AP_DISPOSE,true); 97 } 98 99 template<int n, bool min, class Filter, class Print> 100 forceinline void 101 ViewValuesBrancher<n,min,Filter,Print>::post(Home home, 102 ViewArray<IntView>& x, 103 ViewSel<IntView>* vs[n], 104 IntBranchFilter bf, 105 IntVarValPrint vvp) { 106 (void) new (home) ViewValuesBrancher<n,min,Filter,Print>(home,x,vs,bf,vvp); 107 } 108 109 template<int n, bool min, class Filter, class Print> 110 forceinline 111 ViewValuesBrancher<n,min,Filter,Print>:: 112 ViewValuesBrancher(Space& home, ViewValuesBrancher& b) 113 : ViewBrancher<IntView,Filter,n>(home,b), p(b.p) {} 114 115 template<int n, bool min, class Filter, class Print> 116 Actor* 117 ViewValuesBrancher<n,min,Filter,Print>::copy(Space& home) { 118 return new (home) ViewValuesBrancher<n,min,Filter,Print> 119 (home,*this); 120 } 121 122 template<int n, bool min, class Filter, class Print> 123 const Choice* 124 ViewValuesBrancher<n,min,Filter,Print>::choice(Space& home) { 125 Pos p = ViewBrancher<IntView,Filter,n>::pos(home); 126 return new PosValuesChoice(*this,p, 127 ViewBrancher<IntView,Filter,n>::view(p)); 128 } 129 130 template<int n, bool min, class Filter, class Print> 131 const Choice* 132 ViewValuesBrancher<n,min,Filter,Print>::choice 133 (const Space& home, Archive& e) { 134 (void) home; 135 int p; 136 unsigned int a; 137 e >> p >> a; 138 return new PosValuesChoice(*this,a,p,e); 139 } 140 141 template<int n, bool min, class Filter, class Print> 142 ExecStatus 143 ViewValuesBrancher<n,min,Filter,Print>::commit(Space& home, const Choice& c, 144 unsigned int a) { 145 const PosValuesChoice& pvc 146 = static_cast<const PosValuesChoice&>(c); 147 IntView x(ViewBrancher<IntView,Filter,n>::view(pvc.pos())); 148 unsigned int b = min ? a : (pvc.alternatives() - 1 - a); 149 return me_failed(x.eq(home,pvc.val(b))) ? ES_FAILED : ES_OK; 150 } 151 152 template<int n, bool min, class Filter, class Print> 153 NGL* 154 ViewValuesBrancher<n,min,Filter,Print>::ngl(Space& home, const Choice& c, 155 unsigned int a) const { 156 const PosValuesChoice& pvc 157 = static_cast<const PosValuesChoice&>(c); 158 IntView x(ViewBrancher<IntView,Filter,n>::view(pvc.pos())); 159 unsigned int b = min ? a : (pvc.alternatives() - 1 - a); 160 return new (home) EqNGL<IntView>(home,x,pvc.val(b)); 161 } 162 163 template<int n, bool min, class Filter, class Print> 164 void 165 ViewValuesBrancher<n,min,Filter,Print>::print(const Space& home, 166 const Choice& c, 167 unsigned int a, 168 std::ostream& o) const { 169 const PosValuesChoice& pvc 170 = static_cast<const PosValuesChoice&>(c); 171 IntView x(ViewBrancher<IntView,Filter,n>::view(pvc.pos())); 172 unsigned int b = min ? a : (pvc.alternatives() - 1 - a); 173 int nn = pvc.val(b); 174 if (p) 175 p(home,*this,a,x,pvc.pos().pos,nn,o); 176 else 177 o << "var[" << pvc.pos().pos << "] = " << nn; 178 } 179 180 template<int n, bool min, class Filter, class Print> 181 forceinline size_t 182 ViewValuesBrancher<n,min,Filter,Print>::dispose(Space& home) { 183 if (p.notice()) 184 home.ignore(*this,AP_DISPOSE,true); 185 (void) ViewBrancher<IntView,Filter,n>::dispose(home); 186 return sizeof(ViewValuesBrancher<n,min,Filter,Print>); 187 } 188 189 template<int n, bool min> 190 forceinline void 191 postviewvaluesbrancher(Home home, ViewArray<IntView>& x, 192 ViewSel<IntView>* vs[n], 193 IntBranchFilter bf, 194 IntVarValPrint vvp) { 195 if (bf) { 196 if (vvp) { 197 ViewValuesBrancher<n,min,BrancherFilter<IntView>, 198 BrancherPrint<IntView,int> > 199 ::post(home,x,vs,bf,vvp); 200 } else { 201 ViewValuesBrancher<n,min,BrancherFilter<IntView>, 202 BrancherNoPrint<IntView,int> > 203 ::post(home,x,vs,bf,vvp); 204 } 205 } else { 206 if (vvp) { 207 ViewValuesBrancher<n,min,BrancherNoFilter<IntView>, 208 BrancherPrint<IntView,int> > 209 ::post(home,x,vs,bf,vvp); 210 } else { 211 ViewValuesBrancher<n,min,BrancherNoFilter<IntView>, 212 BrancherNoPrint<IntView,int> > 213 ::post(home,x,vs,bf,vvp); 214 } 215 } 216 } 217 218 219}}} 220 221// STATISTICS: int-branch