scale.hpp
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Christian Schulte <schulte@gecode.org> 00005 * 00006 * Copyright: 00007 * Christian Schulte, 2002 00008 * 00009 * Last modified: 00010 * $Date: 2010-06-29 10:39:13 +0200 (Tue, 29 Jun 2010) $ by $Author: schulte $ 00011 * $Revision: 11118 $ 00012 * 00013 * This file is part of Gecode, the generic constraint 00014 * development environment: 00015 * http://www.gecode.org 00016 * 00017 * Permission is hereby granted, free of charge, to any person obtaining 00018 * a copy of this software and associated documentation files (the 00019 * "Software"), to deal in the Software without restriction, including 00020 * without limitation the rights to use, copy, modify, merge, publish, 00021 * distribute, sublicense, and/or sell copies of the Software, and to 00022 * permit persons to whom the Software is furnished to do so, subject to 00023 * the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be 00026 * included in all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00029 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00031 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00032 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00033 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00034 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00035 * 00036 */ 00037 00038 namespace Gecode { namespace Int { 00039 00040 /* 00041 * Support functions for division 00042 * 00043 */ 00044 template<class Val, class UnsVal> 00045 forceinline int 00046 ScaleView<Val,UnsVal>::floor_div(double y) const { 00047 return static_cast<int>(floor(y / a)); 00048 } 00049 00050 template<class Val, class UnsVal> 00051 forceinline int 00052 ScaleView<Val,UnsVal>::ceil_div(double y) const { 00053 return static_cast<int>(ceil(y / a)); 00054 } 00055 00056 template<class Val, class UnsVal> 00057 forceinline int 00058 ScaleView<Val,UnsVal>::exact_div(double y, bool& exact) const { 00059 double ya = y / a; 00060 if (ceil(ya) == ya) { 00061 exact = true; return static_cast<int>(ya); 00062 } else { 00063 exact = false; return 0; 00064 } 00065 } 00066 00067 #if GECODE_INT_RND_TWDS_ZERO 00068 00069 template<class Val, class UnsVal> 00070 forceinline int 00071 ScaleView<Val,UnsVal>::floor_div(int y) const { 00072 return ((y >= 0) ? y : (y-a+1))/a; 00073 } 00074 00075 template<class Val, class UnsVal> 00076 forceinline int 00077 ScaleView<Val,UnsVal>::ceil_div(int y) const { 00078 return ((y >= 0) ? (y+a-1) : y)/a; 00079 } 00080 00081 template<class Val, class UnsVal> 00082 forceinline int 00083 ScaleView<Val,UnsVal>::exact_div(int y, bool& exact) const { 00084 int ya = y / a; 00085 if (a * ya == y) { 00086 exact = true; return ya; 00087 } else { 00088 exact = false; return 0; 00089 } 00090 } 00091 00092 #endif 00093 00094 00095 /* 00096 * Constructors and initialization 00097 * 00098 */ 00099 template<class Val, class UnsVal> 00100 forceinline 00101 ScaleView<Val,UnsVal>::ScaleView(void) {} 00102 00103 template<class Val, class UnsVal> 00104 forceinline 00105 ScaleView<Val,UnsVal>::ScaleView(int b, const IntView& y) 00106 : DerivedView<IntView>(y), a(b) {} 00107 00108 00109 /* 00110 * Value access 00111 * 00112 */ 00113 template<class Val, class UnsVal> 00114 forceinline int 00115 ScaleView<Val,UnsVal>::scale(void) const { 00116 return a; 00117 } 00118 template<class Val, class UnsVal> 00119 forceinline Val 00120 ScaleView<Val,UnsVal>::min(void) const { 00121 Val c = x.min(); c *= a; return c; 00122 } 00123 00124 template<class Val, class UnsVal> 00125 forceinline Val 00126 ScaleView<Val,UnsVal>::max(void) const { 00127 Val c = x.max(); c *= a; return c; 00128 } 00129 00130 template<class Val, class UnsVal> 00131 forceinline Val 00132 ScaleView<Val,UnsVal>::med(void) const { 00133 Val c = x.med(); c *= a; return c; 00134 } 00135 00136 template<class Val, class UnsVal> 00137 forceinline Val 00138 ScaleView<Val,UnsVal>::val(void) const { 00139 Val c = x.val(); c *= a; return c; 00140 } 00141 00142 template<class Val, class UnsVal> 00143 forceinline UnsVal 00144 ScaleView<Val,UnsVal>::size(void) const { 00145 return static_cast<UnsVal>(x.size()); 00146 } 00147 00148 template<class Val, class UnsVal> 00149 forceinline UnsVal 00150 ScaleView<Val,UnsVal>::width(void) const { 00151 UnsVal c = x.width(); c *= a; return c; 00152 } 00153 00154 template<class Val, class UnsVal> 00155 forceinline UnsVal 00156 ScaleView<Val,UnsVal>::regret_min(void) const { 00157 UnsVal c = x.regret_min(); c *= a; return c; 00158 } 00159 00160 template<class Val, class UnsVal> 00161 forceinline UnsVal 00162 ScaleView<Val,UnsVal>::regret_max(void) const { 00163 UnsVal c = x.regret_max(); c *= a; return c; 00164 } 00165 00166 00167 /* 00168 * Domain tests 00169 * 00170 */ 00171 template<class Val, class UnsVal> 00172 forceinline bool 00173 ScaleView<Val,UnsVal>::range(void) const { 00174 return x.range(); 00175 } 00176 template<class Val, class UnsVal> 00177 forceinline bool 00178 ScaleView<Val,UnsVal>::in(Val n) const { 00179 bool exact; 00180 int nda = exact_div(n, exact); 00181 return exact && x.in(nda); 00182 } 00183 00184 00185 00186 00187 /* 00188 * Domain update by value 00189 * 00190 */ 00191 template<class Val, class UnsVal> 00192 forceinline ModEvent 00193 ScaleView<Val,UnsVal>::lq(Space& home, Val n) { 00194 return (n >= max()) ? ME_INT_NONE : x.lq(home,floor_div(n)); 00195 } 00196 00197 template<class Val, class UnsVal> 00198 forceinline ModEvent 00199 ScaleView<Val,UnsVal>::le(Space& home, Val n) { 00200 return (n > max()) ? ME_INT_NONE : x.le(home,floor_div(n)); 00201 } 00202 00203 template<class Val, class UnsVal> 00204 forceinline ModEvent 00205 ScaleView<Val,UnsVal>::gq(Space& home, Val n) { 00206 return (n <= min()) ? ME_INT_NONE : x.gq(home,ceil_div(n)); 00207 } 00208 template<class Val, class UnsVal> 00209 forceinline ModEvent 00210 ScaleView<Val,UnsVal>::gr(Space& home, Val n) { 00211 return (n < min()) ? ME_INT_NONE : x.gr(home,ceil_div(n)); 00212 } 00213 00214 template<class Val, class UnsVal> 00215 forceinline ModEvent 00216 ScaleView<Val,UnsVal>::nq(Space& home, Val n) { 00217 bool exact; 00218 int nda = exact_div(n,exact); 00219 return exact ? x.nq(home,nda) : ME_INT_NONE; 00220 } 00221 00222 template<class Val, class UnsVal> 00223 forceinline ModEvent 00224 ScaleView<Val,UnsVal>::eq(Space& home, Val n) { 00225 bool exact; 00226 int nda = exact_div(n,exact); 00227 return exact ? x.eq(home,nda) : ME_INT_FAILED; 00228 } 00229 00230 00231 /* 00232 * Propagator modification events 00233 * 00234 */ 00235 template<class Val, class UnsVal> 00236 forceinline ModEventDelta 00237 ScaleView<Val,UnsVal>::med(ModEvent me) { 00238 return IntView::med(me); 00239 } 00240 00241 00242 00243 /* 00244 * Delta information for advisors 00245 * 00246 */ 00247 template<class Val, class UnsVal> 00248 forceinline Val 00249 ScaleView<Val,UnsVal>::min(const Delta& d) const { 00250 Val c = x.min(d); c *= a; return c; 00251 } 00252 template<class Val, class UnsVal> 00253 forceinline Val 00254 ScaleView<Val,UnsVal>::max(const Delta& d) const { 00255 Val c = x.max(d); c *= a; return c; 00256 } 00257 template<class Val, class UnsVal> 00258 forceinline bool 00259 ScaleView<Val,UnsVal>::any(const Delta& d) const { 00260 return x.any(d); 00261 } 00262 00263 00264 00265 /* 00266 * Cloning 00267 * 00268 */ 00269 template<class Val, class UnsVal> 00270 forceinline void 00271 ScaleView<Val,UnsVal>::update(Space& home, bool share, 00272 ScaleView<Val,UnsVal>& y) { 00273 DerivedView<IntView>::update(home,share,y); 00274 a=y.a; 00275 } 00276 00277 00278 00283 template<> 00284 class ViewRanges<IntScaleView> 00285 : public Iter::Ranges::ScaleUp<int,unsigned int,ViewRanges<IntView> > { 00286 public: 00288 00289 00290 ViewRanges(void); 00292 ViewRanges(const IntScaleView& x); 00294 void init(const IntScaleView& x); 00296 }; 00297 00298 forceinline 00299 ViewRanges<IntScaleView>::ViewRanges(void) {} 00300 forceinline 00301 ViewRanges<IntScaleView>::ViewRanges(const IntScaleView& x) { 00302 ViewRanges<IntView> xi(x.base()); 00303 Iter::Ranges::ScaleUp<int,unsigned int,ViewRanges<IntView> >::init 00304 (xi,x.scale()); 00305 } 00306 forceinline void 00307 ViewRanges<IntScaleView>::init(const IntScaleView& x) { 00308 ViewRanges<IntView> xi(x.base()); 00309 Iter::Ranges::ScaleUp<int,unsigned int,ViewRanges<IntView> >::init 00310 (xi,x.scale()); 00311 } 00312 00313 00318 template<> 00319 class ViewRanges<DoubleScaleView> 00320 : public Iter::Ranges::ScaleUp<double,double,ViewRanges<IntView> > { 00321 public: 00323 00324 00325 ViewRanges(void); 00327 ViewRanges(const DoubleScaleView& x); 00329 void init(const DoubleScaleView& x); 00331 }; 00332 00333 forceinline 00334 ViewRanges<DoubleScaleView>::ViewRanges(void) {} 00335 forceinline 00336 ViewRanges<DoubleScaleView>::ViewRanges(const DoubleScaleView& x) { 00337 ViewRanges<IntView> xi(x.base()); 00338 Iter::Ranges::ScaleUp<double,double,ViewRanges<IntView> >::init 00339 (xi,x.scale()); 00340 } 00341 forceinline void 00342 ViewRanges<DoubleScaleView>::init(const DoubleScaleView& x) { 00343 ViewRanges<IntView> xi(x.base()); 00344 Iter::Ranges::ScaleUp<double,double,ViewRanges<IntView> >::init 00345 (xi,x.scale()); 00346 } 00347 00348 00349 /* 00350 * View comparison 00351 * 00352 */ 00353 template<class Val, class UnsVal> 00354 forceinline bool 00355 same(const ScaleView<Val,UnsVal>& x, const ScaleView<Val,UnsVal>& y) { 00356 return same(x.base(),y.base()) && (x.scale() == y.scale()); 00357 } 00358 template<class Val, class UnsVal> 00359 forceinline bool 00360 before(const ScaleView<Val,UnsVal>& x, const ScaleView<Val,UnsVal>& y) { 00361 return before(x.base(),y.base()) 00362 || (same(x.base(),y.base()) && (x.scale() < y.scale())); 00363 } 00364 00365 }} 00366 00367 // STATISTICS: int-var 00368