BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solver/QP_pricing_strategy.h
Go to the documentation of this file.
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 ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines