BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solver/QP__partial_base.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__partial_base.h $
00015 // $Id: QP__partial_base.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__PARTIAL_BASE_H
00024 #define CGAL_QP__PARTIAL_BASE_H
00025 
00026 // includes
00027 #include <CGAL/QP_solver/QP_pricing_strategy.h>
00028 #include <CGAL/Random.h>
00029 #include <algorithm>
00030 #include <vector>
00031 #include <cmath>
00032 
00033 CGAL_BEGIN_NAMESPACE
00034 
00035 // ==================
00036 // class declarations
00037 // ==================
00038 template < typename Q, typename ET, typename Tags >
00039 class QP__partial_base;
00040 
00041 template < class Solver >
00042 struct transition_sync_functor {
00043 
00044     // Note that we rely here on working_vars being the number of
00045     // variables without artificials and the solvers in_B variable
00046     // being up to date. Furthermore the operator() below relies on short
00047     // circuit evaluation   
00048 
00049     transition_sync_functor( const Solver& s, int w) : amb_solver(s),
00050         working_vars(w) { } 
00051          
00052     bool operator() (int i) {
00053         return (i < working_vars) && !amb_solver.is_basic(i);
00054     }
00055     
00056 private:    
00057     const Solver& amb_solver;
00058     int working_vars;
00059 };
00060 
00061 
00062 // ===============
00063 // class interface
00064 // ===============
00065 template < typename Q, typename ET, typename Tags >
00066 class QP__partial_base : virtual public QP_pricing_strategy<Q,ET,Tags> {
00067 
00068     // self
00069     typedef  QP__partial_base<Q,ET,Tags>     Self;
00070     typedef  QP_pricing_strategy<Q,ET,Tags>  Base;
00071 
00072     typedef  typename Base::QP_solver   QP_solver;
00073   protected:
00074 
00075     // types
00076     typedef  typename QP_solver::Indices               Indices;
00077     typedef  typename QP_solver::Index_iterator        Index_iterator;
00078     typedef  typename QP_solver::Index_const_iterator  Index_const_iterator;
00079 
00080     // construction
00081     QP__partial_base( bool  randomize, Random&  random);
00082 
00083     // initialization
00084     virtual  void  init( );
00085 
00086     // access
00087     Index_const_iterator    active_set_begin( ) const { return N.begin();   }
00088     Index_const_iterator    active_set_end  ( ) const { return N.begin()+s; }
00089 
00090     Index_const_iterator  inactive_set_begin( ) const { return N.begin()+s; }
00091     Index_const_iterator  inactive_set_end  ( ) const { return N.end  ();   }
00092 
00093     // operations
00094     void  entering_basis( Index_const_iterator  it);
00095     void  activating    ( Index_const_iterator& it);
00096 
00097     virtual  void  leaving_basis( int i);
00098     virtual  void  transition( );
00099 
00100   private:
00101   
00102     // data members
00103     Indices                  N;         // non-basis;
00104     int                      s;         // size of active set
00105 
00106     bool                     permute;   // flag: permute initial non-basis
00107     Random&                  rand_src;  // random source
00108     
00109     //basic_functor<QP_solver> is_non_basic;
00110 };
00111 
00112 // ----------------------------------------------------------------------------
00113 
00114 // ===============================
00115 // class implementation (template)
00116 // ===============================
00117 
00118 // construction
00119 template < typename Q, typename ET, typename Tags >  inline
00120 QP__partial_base<Q,ET,Tags>::
00121 QP__partial_base( bool  randomize, Random&  random)
00122     : permute( randomize), rand_src( random)
00123 { }
00124 
00125 // initialization
00126 template < typename Q, typename ET, typename Tags >
00127 void
00128 QP__partial_base<Q,ET,Tags>::
00129 init( )
00130 {
00131     // initialize indices of non-basic variables
00132     int  w = this->solver().number_of_working_variables();
00133     int  b = this->solver().number_of_basic_variables();
00134 
00135     if ( ! N.empty()) N.clear();
00136     N.reserve( w-b);                                        // use 'w' ???
00137     for ( int i = 0; i < w; ++i) {
00138         if ( ! this->solver().is_basic( i)) N.push_back( i);
00139     }
00140     if ( permute) std::random_shuffle( N.begin(), N.end(), rand_src);
00141 
00142     // initialize size of active set
00143     int  n = this->solver().number_of_variables();
00144     int  m = this->solver().number_of_constraints();
00145     // we also want to cover the high constraints/variable ratio
00146     if (n < m) (std::swap)(n,m); 
00147 
00148     s = (std::min)( static_cast< unsigned int>( m*std::sqrt( n/2.0)),
00149                     static_cast< unsigned int>(N.size()));
00150 
00151     //is_non_basic.init(this->solver());
00152 }
00153 
00154 // operations
00155 template < typename Q, typename ET, typename Tags >  inline
00156 void
00157 QP__partial_base<Q,ET,Tags>::
00158 entering_basis( Index_const_iterator it)
00159 {
00160     CGAL_qpe_precondition( it >= active_set_begin() && it < active_set_end());
00161 
00162     // remove from active set
00163     --s;
00164     const_cast< typename Indices::value_type&>( *it) = N[ s];
00165     N[ s] = N.back();
00166     N.pop_back();
00167 }
00168 
00169 template < typename Q, typename ET, typename Tags >  inline
00170 void
00171 QP__partial_base<Q,ET,Tags>::
00172 activating( Index_const_iterator& it)
00173 {
00174     CGAL_qpe_precondition(
00175         it >= inactive_set_begin() && it < inactive_set_end());
00176 
00177     // 'append' to active set
00178     std::swap( const_cast< typename Indices::value_type&>( *it), N[ s]);
00179     it = N.begin()+s;
00180     ++s;
00181 }
00182 
00183 template < typename Q, typename ET, typename Tags >
00184 void
00185 QP__partial_base<Q,ET,Tags>::
00186 leaving_basis( int i)
00187 {
00188     // all non-basic variables active?
00189     if ( s == static_cast< int>( N.size())) {
00190 
00191         // append at the end of all non-basic variables
00192         N.push_back( i);
00193 
00194     } else {
00195 
00196         // insert at the end of the current active subset
00197         N.push_back( N[ s]);
00198         N[ s] = i;
00199     }
00200     ++s;
00201 }
00202 
00203 
00204 template < typename Q, typename ET, typename Tags >
00205 void
00206 QP__partial_base<Q,ET,Tags>::
00207 transition( )
00208 {
00209     // Remove from N nonbasic slack and original variables that have become
00210     // basic during the expelling of artificial variables out of the basis
00211     // (between phaseI and phaseII), since these formerly nonbasic variables
00212     // have not entered the basis through pricing the set N has not accordingly
00213     // been updated.
00214     // Remove from N the artificial variables as well.
00215     // Note that we rely on the number of working variables including only
00216     // original and slack variables, the solvers in_B variable must be 
00217     // up to date.
00218     // Furthermore we rely on std::partition not destroying the randomness
00219     // of the order of the nonbasic variables in N.
00220     
00221     int  w = this->solver().number_of_working_variables();    
00222     transition_sync_functor<QP_solver> is_non_basic(this->solver(), w);
00223     N.erase( std::partition( N.begin(), N.end(),
00224                              is_non_basic), N.end());
00225     
00226     // initialize size of active set
00227     int  n = this->solver().number_of_variables();
00228     int  m = this->solver().number_of_constraints();
00229 
00230     s = (std::min)( static_cast< unsigned int>( m*std::sqrt( n/2.0)),
00231                     static_cast< unsigned int>(N.size()));
00232 }
00233 
00234 CGAL_END_NAMESPACE
00235 
00236 #endif // CGAL_QP__PARTIAL_BASE_H
00237 
00238 // ===== EOF ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines