BWAPI
|
00001 // Copyright (c) 1997-2007 ETH Zurich (Switzerland). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/QP_solver/include/CGAL/QP_solver/QP_pricing_strategy.h $ 00015 // $Id: QP_pricing_strategy.h 38453 2007-04-27 00:34:44Z gaertner $ 00016 // 00017 // 00018 // Author(s) : Sven Schoenherr 00019 // Bernd Gaertner <gaertner@inf.ethz.ch> 00020 // Franz Wessendorp 00021 // Kaspar Fischer 00022 00023 #ifndef CGAL_QP_PRICING_STRATEGY_H 00024 #define CGAL_QP_PRICING_STRATEGY_H 00025 00026 // includes 00027 #include <CGAL/QP_solver/QP_solver.h> 00028 #include <CGAL/IO/Verbose_ostream.h> 00029 00030 #include <string> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 // ================== 00035 // class declarations 00036 // ================== 00037 template < typename Q, typename ET, typename Tags > 00038 class QP_pricing_strategy; 00039 00040 template < typename Q, typename ET, typename Tags > 00041 class QP_solver; 00042 00043 // =============== 00044 // class interface 00045 // =============== 00046 template < typename Q, typename ET, typename Tags > 00047 class QP_pricing_strategy { 00048 00049 public: 00050 00051 // self 00052 typedef QP_pricing_strategy<Q, ET, Tags> Self; 00053 00054 // types 00055 typedef CGAL::QP_solver<Q, ET, Tags> QP_solver; 00056 typedef CGAL::Verbose_ostream Verbose_ostream; 00057 typedef typename Tags::Is_nonnegative 00058 Is_nonnegative; 00059 typedef typename Tags::Is_linear Is_linear; 00060 typedef typename QP_solver::Bound_index Bound_index; 00061 00062 public: 00063 00064 // initialization 00065 void set ( const QP_solver& solver, Verbose_ostream& vout); 00066 void init( int dummy); 00067 00068 // operations 00069 virtual int pricing(int& /*direction*/ ) = 0; 00070 00071 virtual void leaving_basis( int /*i*/) { } 00072 virtual void transition( ) { } 00073 00074 protected: 00075 00076 // construction & destruction 00077 QP_pricing_strategy( const std::string& strategy_name); 00078 public: 00079 virtual ~QP_pricing_strategy( ) { } 00080 protected: 00081 QP_pricing_strategy( ); // detects error in virtual inheritance 00082 00083 // initialization (of derived classes) 00084 virtual void set ( ) { } 00085 virtual void init( ) { } 00086 00087 // operations 00088 ET mu_j( int j) const; 00089 00090 // access 00091 const QP_solver& solver( ) const { return *solverP; } 00092 Verbose_ostream& vout ( ) const { return *voutP; } 00093 00094 // constants (protected) 00095 const ET et0; 00096 00097 // used during pricing loop; finds out whether j is a 00098 // new best candidate for the entering variable w.r.t. 00099 // Dantzig's pivot rule (reduced cost pricing); the 00100 // return value is true iff j is the new best candidate 00101 template <typename NT> 00102 bool price_dantzig (int j, const NT& mu, const NT& nt0, 00103 int& min_j, NT& min_mu, int& direction); 00104 00105 // returns whether j satisfying mu_j = mu is a candidate 00106 // for the entering variable 00107 template <typename NT> 00108 bool is_improving (int j, const NT& mu, const NT& nt0) const; 00109 00110 private: 00111 00112 // data members 00113 const QP_solver* solverP; // the ambient QP solver 00114 Verbose_ostream* voutP; // used for verbose output 00115 std::string name; // derived strategy's name 00116 }; 00117 00118 // ---------------------------------------------------------------------------- 00119 00120 // ============================= 00121 // class implementation (inline) 00122 // ============================= 00123 00124 // construction 00125 template < typename Q, typename ET, typename Tags > inline 00126 QP_pricing_strategy<Q, ET, Tags>:: 00127 QP_pricing_strategy( const std::string& strategy_name) 00128 : et0( 0), name( strategy_name) 00129 { } 00130 00131 // detects error in virtual inheritance 00132 template < typename Q, typename ET, typename Tags > inline 00133 QP_pricing_strategy<Q, ET, Tags>:: 00134 QP_pricing_strategy( ) 00135 : et0(0) 00136 { 00137 CGAL_qpe_assertion_msg 00138 ( false, "call to 'QP_pricing_strategy<Q,ET,Tags>::\n'" \ 00139 "QP_pricing_strategy( const std::string& strategy_name)'\n" \ 00140 "is missing in most derived pricing class!"); 00141 } 00142 00143 // initialization 00144 template < typename Q, typename ET, typename Tags > inline 00145 void QP_pricing_strategy<Q, ET, Tags>:: 00146 set( const QP_solver& solver, Verbose_ostream& vout) 00147 { 00148 solverP = &solver; 00149 voutP = &vout; 00150 set(); 00151 } 00152 00153 template < typename Q, typename ET, typename Tags > inline 00154 void QP_pricing_strategy<Q, ET, Tags>:: 00155 init( int) 00156 { 00157 CGAL_qpe_debug { 00158 vout() << "pricing: " << name << std::endl; 00159 } 00160 init(); 00161 } 00162 00163 // operations 00164 template < typename Q, typename ET, typename Tags > inline 00165 ET QP_pricing_strategy<Q, ET, Tags>:: 00166 mu_j( int j) const 00167 { 00168 return this->solver().mu_j(j); 00169 } 00170 00171 template < typename Q, typename ET, typename Tags > 00172 template <typename NT> 00173 bool QP_pricing_strategy<Q, ET, Tags>:: 00174 is_improving (int j, const NT& mu, const NT& nt0 ) const 00175 { 00176 CGAL_qpe_assertion(!this->solver().is_basic(j)); 00177 CGAL_qpe_assertion(!this->solver().is_artificial(j)); 00178 if (this->solver().is_original(j)) { 00179 const Bound_index bnd_ind = 00180 this->solver().nonbasic_original_variable_bound_index(j); 00181 switch (bnd_ind) { 00182 case QP_solver::LOWER: 00183 return mu < nt0; 00184 case QP_solver::UPPER: 00185 return mu > nt0; 00186 case QP_solver::ZERO: 00187 { 00188 const int where = 00189 this->solver().state_of_zero_nonbasic_variable(j); 00190 return ((where >= 0 && mu > nt0) || (where <= 0 && mu < nt0)); 00191 } 00192 case QP_solver::FIXED: 00193 return false; 00194 case QP_solver::BASIC: 00195 default: 00196 CGAL_qpe_assertion(false); 00197 return false; 00198 } 00199 } else { 00200 // artficial variable 00201 return mu < nt0; 00202 } 00203 } 00204 00205 template < typename Q, typename ET, typename Tags > 00206 template <typename NT> 00207 bool QP_pricing_strategy<Q, ET, Tags>:: 00208 price_dantzig (int j, const NT& mu, const NT& nt0, 00209 int& min_j, NT& min_mu, int& direction) { 00210 CGAL_qpe_assertion(!this->solver().is_basic(j)); 00211 CGAL_qpe_assertion(!this->solver().is_artificial(j)); 00212 if (this->solver().is_original(j)) { 00213 // original variable 00214 const Bound_index bnd_ind = 00215 this->solver().nonbasic_original_variable_bound_index(j); 00216 switch (bnd_ind) { 00217 case QP_solver::LOWER: 00218 { 00219 CGAL_qpe_debug { 00220 this->vout() << "mu_" << j << ": " << mu 00221 << " LOWER" << std::endl; 00222 } 00223 00224 if (mu < nt0) { 00225 // new minimum? 00226 if (mu < min_mu) { 00227 min_j = j; min_mu = mu; 00228 direction = 1; 00229 } 00230 } 00231 break; 00232 } 00233 case QP_solver::ZERO: 00234 { 00235 // determine whether the variable is on lower or upper bound, or 00236 // somewhere it the middle: 00237 // 00238 // Note: it cannot be both on the lower and upper bound (as it is 00239 // not FIXED). 00240 const int where = 00241 this->solver().state_of_zero_nonbasic_variable(j); 00242 00243 CGAL_qpe_debug { 00244 this->vout() << "mu_" << j << ": " << mu 00245 << " ZERO " 00246 << (where == -1? "(LOWER)" : 00247 (where == 0? "(MIDDLE)" : "(UPPER)")) 00248 << std::endl; 00249 } 00250 00251 if (where >= 0 && // middle or on upper bound? 00252 mu > nt0) { 00253 // new minimum? 00254 if (-mu < min_mu) { 00255 min_j = j; min_mu = -mu; 00256 direction = -1; 00257 } 00258 } 00259 if (where <= 0 && // middle or on lower bound? 00260 mu < nt0) { 00261 // new minimum? 00262 if (mu < min_mu) { 00263 min_j = j; min_mu = mu; 00264 direction = 1; 00265 } 00266 } 00267 break; 00268 } 00269 case QP_solver::UPPER: 00270 { 00271 CGAL_qpe_debug { 00272 this->vout() << "mu_" << j << ": " << mu 00273 << " UPPER" << std::endl; 00274 } 00275 00276 if (mu > nt0) { 00277 // new minimum? 00278 if (-mu < min_mu) { 00279 min_j = j; min_mu = -mu; 00280 direction = -1; 00281 } 00282 } 00283 break; 00284 } 00285 case QP_solver::FIXED: 00286 CGAL_qpe_debug { 00287 this->vout() << "Fixed variable " << j << std::endl; 00288 } 00289 break; 00290 case QP_solver::BASIC: 00291 CGAL_qpe_assertion(false); 00292 break; 00293 } 00294 } else { 00295 // slack variable 00296 CGAL_qpe_debug { 00297 this->vout() << "mu_" << j << ": " << mu 00298 << " LOWER (slack)" << std::endl; 00299 } 00300 00301 // new minimum? 00302 if (mu < min_mu) { 00303 min_j = j; min_mu = mu; 00304 direction = 1; 00305 } 00306 } 00307 return (min_j == j); 00308 } 00309 00310 00311 00312 CGAL_END_NAMESPACE 00313 00314 #endif // CGAL_QP_PRICING_STRATEGY_H 00315 00316 // ===== EOF ==================================================================