source/numeric/lpbase.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  The Contents of this file are made available subject to
00004  *  the terms of GNU Lesser General Public License Version 2.1.
00005  *
00006  *
00007  *    GNU Lesser General Public License Version 2.1
00008  *    =============================================
00009  *    Copyright 2005 by Kohei Yoshida.
00010  *    1039 Kingsway Dr., Apex, NC 27502, USA
00011  *
00012  *    This library is free software; you can redistribute it and/or
00013  *    modify it under the terms of the GNU Lesser General Public
00014  *    License version 2.1, as published by the Free Software Foundation.
00015  *
00016  *    This library is distributed in the hope that it will be useful,
00017  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *    Lesser General Public License for more details.
00020  *
00021  *    You should have received a copy of the GNU Lesser General Public
00022  *    License along with this library; if not, write to the Free Software
00023  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00024  *    MA  02111-1307  USA
00025  *
00026  ************************************************************************/
00027 
00028 
00029 #include "numeric/lpbase.hxx"
00030 #include "numeric/lpmodel.hxx"
00031 #include "numeric/matrix.hxx"
00032 #include <list>
00033 #include <vector>
00034 #include <cstddef>
00035 #include "tool/global.hxx"
00036 
00037 using ::std::vector;
00038 using ::std::list;
00039 using ::std::cout;
00040 using ::std::endl;
00041 
00042 namespace scsolver { namespace numeric { namespace lp {
00043 
00044 
00045 class BaseAlgorithmImpl
00046 {
00047 public:
00048         BaseAlgorithmImpl();
00049         ~BaseAlgorithmImpl() throw();
00050 
00051         Model* getModel() const { return m_pModel; }
00052         void setModel( Model* p ) { m_pModel = p; }
00053         Model* getCanonicalModel();
00054         
00055         Matrix getSolution() const { return m_mxSolution; }
00056         void setSolution( const Matrix& );
00057         void setCanonicalSolution( const Matrix& );
00058 
00059 private:
00060         Model* m_pModel;                                                // original model
00061         ::std::auto_ptr<Model> m_pCanonModel;   // canonical model
00062         Matrix m_mxSolution;
00063 
00064     /* permutation of variable indices to map IDs of canonical model
00065        those of original model */
00066     std::list<size_t> m_cnPermVarIndex;
00067 
00068         struct ConstDecVar
00069         {
00070                 size_t Id;
00071                 double Value;
00072         };
00073 
00074     /* This list is used to store IDs and values of constant equivalent
00075        values. */
00076         std::list<ConstDecVar> m_cnConstDecVarList;
00077 
00078         void initCanonicalModel();
00079         void initPermIndex();
00080 };
00081 
00082 BaseAlgorithmImpl::BaseAlgorithmImpl() :
00083         m_pModel( NULL ),
00084         m_pCanonModel( static_cast<Model*>(NULL) ),
00085         m_mxSolution( 0, 0 )
00086 {
00087 }
00088 
00089 BaseAlgorithmImpl::~BaseAlgorithmImpl() throw()
00090 {
00091 }
00092 
00098 void BaseAlgorithmImpl::initCanonicalModel()
00099 {
00100         Debug( "initCanonicalModel" );
00101 
00102         initPermIndex();
00103 
00104         m_pCanonModel.reset( new Model( *getModel() ) );
00105         m_cnConstDecVarList.empty();
00106         size_t nColSize = m_pCanonModel->getCostVector().cols();
00107         size_t nRhsSize = m_pCanonModel->getRhsVector().rows();
00108         double fObjConst = 0.0;
00109         std::vector<double> cnRhsConstants( nRhsSize );
00110         std::vector<size_t> cnColsNuked;
00111         
00112         for ( size_t i = 0; i < nColSize; ++i )
00113         {
00114                 if ( m_pCanonModel->isVarBounded( i, BOUND_LOWER ) && 
00115                          m_pCanonModel->isVarBounded( i, BOUND_UPPER ) )
00116                 {
00117                         double fLBound = m_pCanonModel->getVarBound( i, BOUND_LOWER );
00118                         double fUBound = m_pCanonModel->getVarBound( i, BOUND_UPPER );
00119                         if ( fLBound == fUBound )
00120                         {
00121                                 cout << "var " << i << " == " << fLBound << endl;
00122 
00123                                 // This variable is constant-equivalent.  Remove it from 
00124                                 // the temporary model.
00125                                 ConstDecVar cdv;
00126                                 cdv.Id = i;
00127                                 cdv.Value = fLBound;
00128                                 m_cnConstDecVarList.push_back( cdv );
00129         
00130                                 double fCost = m_pCanonModel->getCostVector().operator()( 0, i );
00131                                 fObjConst -= fCost*fLBound;
00132                                 cnColsNuked.push_back( i );
00133                                 cout << "  (equal) fObjConstant = " << fObjConst << endl;
00134                                 for( size_t nRow = 0; nRow < nRhsSize; ++nRow )
00135                                 {
00136                                         double f = m_pCanonModel->getConstraint( nRow, i )*fLBound;
00137                                         cout << "  " << f;
00138                                         cnRhsConstants[nRow] -= f;
00139                                         cout << ":\t" << cnRhsConstants.at( nRow ) << endl;
00140                                 }
00141                         }
00142                 }
00143         }
00144 
00145         if ( !cnColsNuked.empty() )
00146         {
00147                 // Delete designated columns from all affected matrices, and turn them
00148                 // into constant values to be added to the RHS vector and objective function.
00149                 // Also, remove the IDs of deleted columns from the permutation index list, 
00150                 // and update the constant objective value list.
00151 
00152                 m_pCanonModel->deleteVariables( cnColsNuked );
00153                 for ( size_t i = 0; i < nRhsSize; ++i )
00154                 {
00155                         double fRhsVal = m_pCanonModel->getRhsValue(i);
00156                         m_pCanonModel->setRhsValue( i, fRhsVal + cnRhsConstants.at(i) );
00157                 }
00158 
00159                 // Actually this may not be needed since this value will not affect
00160                 // the solution at all.  But set this anyway.
00161                 m_pCanonModel->setObjectiveFuncConstant( fObjConst );
00162 
00163                 vector<size_t>::iterator it,
00164                         itBeg = cnColsNuked.begin(), itEnd = cnColsNuked.end();
00165 
00166                 // Remove its index from permutation index list.
00167                 list<size_t>::iterator itPerm = m_cnPermVarIndex.begin();
00168                 for ( it = itBeg; it != itEnd; ++it )
00169                         m_cnPermVarIndex.remove( *it );
00170         }
00171 }
00172 
00173 Model* BaseAlgorithmImpl::getCanonicalModel()
00174 {
00175         if ( m_pCanonModel.get() == NULL )
00176                 initCanonicalModel();
00177         return m_pCanonModel.get();
00178 }
00179 
00180 void BaseAlgorithmImpl::setSolution( const Matrix& other )
00181 {
00182         Matrix m( other );
00183         m_mxSolution.swap( m );
00184 }
00185 
00186 void BaseAlgorithmImpl::setCanonicalSolution( const Matrix& mxCanonSol )
00187 {
00188         size_t nCostSize = getModel()->getCostVector().cols();
00189         cout << "original cost size is " << nCostSize << endl;
00190         Matrix mxSol( nCostSize, 1 );
00191         mxSol.setResizable( false );
00192 
00193         // Map solved variables into their original position.
00194         list<size_t>::const_iterator itBeg = m_cnPermVarIndex.begin(),
00195                 itEnd = m_cnPermVarIndex.end(), it;
00196         for ( it = itBeg; it != itEnd; ++it )
00197         {
00198                 size_t nSrcId = ::std::distance( itBeg, it );
00199                 size_t nDstId = *it;
00200                 cout << "mapped var id: " << nSrcId << " -> " << nDstId << endl;
00201                 mxSol( nDstId, 0 ) = mxCanonSol( nSrcId, 0 );
00202         }
00203 
00204         // Insert constant variables if any
00205         list<ConstDecVar>::const_iterator itCdvBeg = m_cnConstDecVarList.begin(),
00206                 itCdvEnd = m_cnConstDecVarList.end(), itCdv;
00207         for ( itCdv = itCdvBeg; itCdv != itCdvEnd; ++itCdv )
00208         {
00209                 cout << "constant-equivalent variable: " << itCdv->Id << "\t" << itCdv->Value << endl;
00210                 mxSol( itCdv->Id, 0 ) = itCdv->Value;
00211         }
00212 
00213         m_mxSolution.swap( mxSol );
00214         m_pCanonModel.reset( static_cast<Model*>(NULL) );
00215 }
00216 
00222 void BaseAlgorithmImpl::initPermIndex()
00223 {
00224         m_cnPermVarIndex.clear();
00225         size_t nCostSize = getModel()->getCostVector().cols();
00226         for ( size_t i = 0; i < nCostSize; ++i )
00227                 m_cnPermVarIndex.push_back( i );
00228 }
00229 
00230 
00231 //---------------------------------------------------------------------------
00232 // BaseAlgorithm
00233 
00234 BaseAlgorithm::BaseAlgorithm() :
00235         m_pImpl( new BaseAlgorithmImpl() )
00236 {
00237 }
00238 
00239 BaseAlgorithm::~BaseAlgorithm()
00240 {
00241 }
00242 
00243 Model* BaseAlgorithm::getModel() const
00244 {
00245         return m_pImpl->getModel();
00246 }
00247 
00248 void BaseAlgorithm::setModel( Model* p )
00249 {
00250         m_pImpl->setModel( p );
00251 }
00252 
00253 Model* BaseAlgorithm::getCanonicalModel() const
00254 {
00255         return m_pImpl->getCanonicalModel();
00256 }
00257 
00258 Matrix BaseAlgorithm::getSolution() const
00259 {
00260         return m_pImpl->getSolution();
00261 }
00262 
00263 void BaseAlgorithm::setSolution( const Matrix& mx )
00264 {
00265         m_pImpl->setSolution( mx );
00266 }
00267 
00268 void BaseAlgorithm::setCanonicalSolution( const Matrix& mx )
00269 {
00270         m_pImpl->setCanonicalSolution( mx );
00271 }
00272 
00273 }}}

Generated on Mon Jul 28 09:13:20 2008 for scsolver by  doxygen 1.5.3