ranges-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, 2005 00008 * 00009 * Last modified: 00010 * $Date: 2009-09-08 21:10:29 +0200 (Tue, 08 Sep 2009) $ by $Author: schulte $ 00011 * $Revision: 9692 $ 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 #include <cmath> 00039 00040 namespace Gecode { namespace Iter { namespace Ranges { 00041 00052 template<class Val, class UnsVal, class I> 00053 class ScaleUp { 00054 private: 00056 IsRangeIter<I> _checkI; 00057 protected: 00059 I i; 00061 int a; 00063 Val cur; 00065 Val end; 00066 public: 00068 00069 00070 ScaleUp(void); 00072 ScaleUp(I& i, int a); 00074 void init(I& i, int a); 00076 00078 00079 00080 bool operator ()(void) const; 00082 void operator ++(void); 00084 00086 00087 00088 Val min(void) const; 00090 Val max(void) const; 00092 UnsVal width(void) const; 00094 }; 00095 00101 template<class I> 00102 class ScaleDown : public MinMax { 00103 private: 00105 IsRangeIter<I> _checkI; 00106 protected: 00108 I i; 00110 int a; 00111 public: 00113 00114 00115 ScaleDown(void); 00117 ScaleDown(I& i, int a); 00119 void init(I& i, int a); 00121 00123 00124 00125 void operator ++(void); 00127 }; 00128 00129 00130 00131 template<class Val, class UnsVal, class I> 00132 forceinline 00133 ScaleUp<Val,UnsVal,I>::ScaleUp(void) {} 00134 00135 template<class Val, class UnsVal, class I> 00136 inline void 00137 ScaleUp<Val,UnsVal,I>::init(I& i0, int a0) { 00138 i = i0; a = a0; 00139 if (i()) { 00140 cur = a * i.min(); 00141 end = a * i.max(); 00142 } else { 00143 cur = 1; 00144 end = 0; 00145 } 00146 } 00147 00148 template<class Val, class UnsVal, class I> 00149 inline 00150 ScaleUp<Val,UnsVal,I>::ScaleUp(I& i0, int a0) : i(i0), a(a0) { 00151 if (i()) { 00152 cur = a * i.min(); 00153 end = a * i.max(); 00154 } else { 00155 cur = 1; 00156 end = 0; 00157 } 00158 } 00159 00160 template<class Val, class UnsVal, class I> 00161 forceinline void 00162 ScaleUp<Val,UnsVal,I>::operator ++(void) { 00163 if (a == 1) { 00164 ++i; 00165 } else { 00166 cur += a; 00167 if (cur > end) { 00168 ++i; 00169 if (i()) { 00170 cur = a * i.min(); 00171 end = a * i.max(); 00172 } 00173 } 00174 } 00175 } 00176 template<class Val, class UnsVal, class I> 00177 forceinline bool 00178 ScaleUp<Val,UnsVal,I>::operator ()(void) const { 00179 return (a == 1) ? i() : (cur <= end); 00180 } 00181 00182 template<class Val, class UnsVal, class I> 00183 forceinline Val 00184 ScaleUp<Val,UnsVal,I>::min(void) const { 00185 return (a == 1) ? static_cast<Val>(i.min()) : cur; 00186 } 00187 template<class Val, class UnsVal, class I> 00188 forceinline Val 00189 ScaleUp<Val,UnsVal,I>::max(void) const { 00190 return (a == 1) ? static_cast<Val>(i.max()) : cur; 00191 } 00192 template<class Val, class UnsVal, class I> 00193 forceinline UnsVal 00194 ScaleUp<Val,UnsVal,I>::width(void) const { 00195 return (a == 1) ? 00196 static_cast<UnsVal>(i.width()) : 00197 static_cast<UnsVal>(max - min + 1); 00198 } 00199 00200 00201 00202 template<class I> 00203 forceinline void 00204 ScaleDown<I>::operator ++(void) { 00205 finish(); 00206 while ((mi > ma) && i()) { 00207 mi = static_cast<int>(ceil(static_cast<double>(i.min())/a)); 00208 ma = static_cast<int>(floor(static_cast<double>(i.max())/a)); 00209 ++i; 00210 } 00211 while (i()) { 00212 int n_mi = static_cast<int>(ceil(static_cast<double>(i.min())/a)); 00213 if (n_mi-ma > 1) 00214 break; 00215 int n_ma = static_cast<int>(floor(static_cast<double>(i.max())/a)); 00216 if (n_mi <= n_ma) { 00217 ma = n_ma; 00218 } 00219 ++i; 00220 } 00221 } 00222 00223 template<class I> 00224 forceinline 00225 ScaleDown<I>::ScaleDown(void) {} 00226 00227 template<class I> 00228 inline void 00229 ScaleDown<I>::init(I& i0, int a0) { 00230 i = i0; a = a0; 00231 operator ++(); 00232 } 00233 00234 template<class I> 00235 inline 00236 ScaleDown<I>::ScaleDown(I& i0, int a0) : i(i0), a(a0) { 00237 i = i0; a = a0; 00238 operator ++(); 00239 } 00240 00241 }}} 00242 00243 // STATISTICS: iter-any 00244