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: 2010-07-28 17:35:33 +0200 (Wed, 28 Jul 2010) $ by $Author: schulte $ 00011 * $Revision: 11294 $ 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 protected: 00056 I i; 00058 int a; 00060 Val cur; 00062 Val end; 00063 public: 00065 00066 00067 ScaleUp(void); 00069 ScaleUp(I& i, int a); 00071 void init(I& i, int a); 00073 00075 00076 00077 bool operator ()(void) const; 00079 void operator ++(void); 00081 00083 00084 00085 Val min(void) const; 00087 Val max(void) const; 00089 UnsVal width(void) const; 00091 }; 00092 00098 template<class I> 00099 class ScaleDown : public MinMax { 00100 protected: 00102 I i; 00104 int a; 00105 public: 00107 00108 00109 ScaleDown(void); 00111 ScaleDown(I& i, int a); 00113 void init(I& i, int a); 00115 00117 00118 00119 void operator ++(void); 00121 }; 00122 00123 00124 00125 template<class Val, class UnsVal, class I> 00126 forceinline 00127 ScaleUp<Val,UnsVal,I>::ScaleUp(void) {} 00128 00129 template<class Val, class UnsVal, class I> 00130 inline void 00131 ScaleUp<Val,UnsVal,I>::init(I& i0, int a0) { 00132 i = i0; a = a0; 00133 if (i()) { 00134 cur = a * i.min(); 00135 end = a * i.max(); 00136 } else { 00137 cur = 1; 00138 end = 0; 00139 } 00140 } 00141 00142 template<class Val, class UnsVal, class I> 00143 inline 00144 ScaleUp<Val,UnsVal,I>::ScaleUp(I& i0, int a0) : i(i0), a(a0) { 00145 if (i()) { 00146 cur = a * i.min(); 00147 end = a * i.max(); 00148 } else { 00149 cur = 1; 00150 end = 0; 00151 } 00152 } 00153 00154 template<class Val, class UnsVal, class I> 00155 forceinline void 00156 ScaleUp<Val,UnsVal,I>::operator ++(void) { 00157 if (a == 1) { 00158 ++i; 00159 } else { 00160 cur += a; 00161 if (cur > end) { 00162 ++i; 00163 if (i()) { 00164 cur = a * i.min(); 00165 end = a * i.max(); 00166 } 00167 } 00168 } 00169 } 00170 template<class Val, class UnsVal, class I> 00171 forceinline bool 00172 ScaleUp<Val,UnsVal,I>::operator ()(void) const { 00173 return (a == 1) ? i() : (cur <= end); 00174 } 00175 00176 template<class Val, class UnsVal, class I> 00177 forceinline Val 00178 ScaleUp<Val,UnsVal,I>::min(void) const { 00179 return (a == 1) ? static_cast<Val>(i.min()) : cur; 00180 } 00181 template<class Val, class UnsVal, class I> 00182 forceinline Val 00183 ScaleUp<Val,UnsVal,I>::max(void) const { 00184 return (a == 1) ? static_cast<Val>(i.max()) : cur; 00185 } 00186 template<class Val, class UnsVal, class I> 00187 forceinline UnsVal 00188 ScaleUp<Val,UnsVal,I>::width(void) const { 00189 return (a == 1) ? 00190 static_cast<UnsVal>(i.width()) : 00191 static_cast<UnsVal>(max - min + 1); 00192 } 00193 00194 00195 00196 template<class I> 00197 forceinline void 00198 ScaleDown<I>::operator ++(void) { 00199 finish(); 00200 while ((mi > ma) && i()) { 00201 mi = static_cast<int>(ceil(static_cast<double>(i.min())/a)); 00202 ma = static_cast<int>(floor(static_cast<double>(i.max())/a)); 00203 ++i; 00204 } 00205 while (i()) { 00206 int n_mi = static_cast<int>(ceil(static_cast<double>(i.min())/a)); 00207 if (n_mi-ma > 1) 00208 break; 00209 int n_ma = static_cast<int>(floor(static_cast<double>(i.max())/a)); 00210 if (n_mi <= n_ma) { 00211 ma = n_ma; 00212 } 00213 ++i; 00214 } 00215 } 00216 00217 template<class I> 00218 forceinline 00219 ScaleDown<I>::ScaleDown(void) {} 00220 00221 template<class I> 00222 inline void 00223 ScaleDown<I>::init(I& i0, int a0) { 00224 i = i0; a = a0; 00225 operator ++(); 00226 } 00227 00228 template<class I> 00229 inline 00230 ScaleDown<I>::ScaleDown(I& i0, int a0) : i(i0), a(a0) { 00231 i = i0; a = a0; 00232 operator ++(); 00233 } 00234 00235 }}} 00236 00237 // STATISTICS: iter-any 00238