source/numeric/lpsolve.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/lpsolve.hxx"
00030 #include "numeric/lpmodel.hxx"
00031 #include "numeric/exception.hxx"
00032 #include "numeric/matrix.hxx"
00033 #include "unoglobal.hxx"
00034 #include "tool/global.hxx"
00035 #include "numeric/type.hxx"
00036 #include "lpsolve/lp_lib.h"
00037 
00038 #include <string>
00039 #include <memory>
00040 #include <iostream>
00041 #include <stdio.h>
00042 
00043 using namespace ::scsolver::numeric;
00044 
00045 namespace scsolver {
00046 
00047 namespace numeric { namespace lp {
00048 
00049 class LpSolveImpl
00050 {
00051 public:
00052         LpSolveImpl() {}
00053         ~LpSolveImpl() throw() {}
00054 
00055         void solve();
00056         Matrix getSolution() const { return m_mxSolution; }
00057 
00058         void setModel( Model* model ) { m_pModel = model; }
00059     Model* getModel() const { return m_pModel; }        
00060 
00061 private:
00062         Matrix m_mxSolution;
00063         Model* m_pModel;
00064 };
00065 
00066 void LpSolveImpl::solve()
00067 {
00068     using ::std::vector;
00069 
00070         Model* model = getModel();
00071         size_t nDecVarSize = model->getDecisionVarSize();
00072         size_t nConstCount = model->getConstraintCount();
00073 
00074 #if SCSOLVER_DEBUG      
00075         printf("decision var (%d)\n", nDecVarSize);
00076         printf("constraint   (%d)\n", nConstCount);
00077 #endif  
00078 
00079         lprec* lp = make_lp(0, nDecVarSize);
00080         if ( lp == NULL )
00081                 throw RuntimeError( ascii("Initialization error") );
00082 
00083         for ( int i = 1; i <= nDecVarSize; ++i )
00084         {
00085                 if( model->getVarPositive() )
00086                         set_lowbo(lp, i, 0.0); // positive variable constraint
00087                 else
00088                         set_unbounded(lp, i);
00089                 if ( model->getVarInteger() )
00090                         set_int(lp, i, 1);
00091                 else
00092                         set_int(lp, i, 0);
00093         }
00094 
00095         // map constraints
00096         set_add_rowmode( lp, true );
00097         vector<double> row( nDecVarSize );
00098         vector<int>   cols( nDecVarSize );
00099         try
00100         {
00101                 for ( int i = 0; i < nDecVarSize; ++i )
00102                         cols.at(i) = i+1;
00103 
00104                 for ( int i = 0; i < nConstCount; ++i )
00105                 {
00106                         for ( int j = 0; j < nDecVarSize; ++j )
00107                                 row.at(j) = model->getConstraint( i, j );
00108                         int nEqual = EQ;
00109                         switch ( model->getEquality(i) )
00110                         {
00111                         case GREATER_EQUAL:
00112                                 nEqual = GE;
00113                                 break;
00114                         case LESS_EQUAL:
00115                                 nEqual = LE;
00116                                 break;
00117                         case EQUAL:
00118                                 nEqual = EQ;
00119                                 break;
00120                         }
00121                         add_constraintex( lp, nDecVarSize, &row[0], &cols[0], nEqual,
00122                                                           model->getRhsValue(i) );
00123                 }
00124 
00125                 set_add_rowmode( lp, false );
00126 
00127                 // set objective function
00128                 for ( int i = 0; i < nDecVarSize; ++i )
00129                 {
00130 #if SCSOLVER_DEBUG
00131                         printf("var %d = %f\n", i+1, model->getCost(i));
00132 #endif
00133                         row.at(i) = model->getCost(i);
00134                 }
00135                 set_obj_fnex( lp, nDecVarSize,  &row[0],  &cols[0] );
00136         }
00137         catch ( ::std::out_of_range& e )
00138         {
00139                 Debug( e.what() );
00140                 delete_lp(lp);
00141                 throw RuntimeError( ascii(e.what()) );
00142         }
00143 
00144         // set goal
00145         switch ( model->getGoal() )
00146         {
00147         case GOAL_MAXIMIZE:
00148                 set_maxim(lp);
00149                 break;
00150         case GOAL_MINIMIZE:
00151                 set_minim(lp);
00152                 break;
00153         default:
00154                 delete_lp(lp);
00155                 throw RuntimeError( ascii("Unknown goal") );
00156         }
00157 
00158         write_LP(lp, stdout);
00159 
00160 #if SCSOLVER_DEBUG      
00161     set_verbose(lp, IMPORTANT);
00162 #else
00163     set_verbose(lp, NEUTRAL);
00164 #endif    
00165 
00166         if ( ::solve(lp) == OPTIMAL )
00167         {
00168                 // solution found
00169 
00170                 // variable values
00171                 get_variables(lp, &row[0]);
00172                 Matrix mxSolution( nDecVarSize, 1 );
00173                 for ( size_t i = 0; i < nDecVarSize; ++i )
00174                         mxSolution( i, 0 ) = row[i];
00175                 m_mxSolution.swap( mxSolution );
00176         }
00177         else
00178         {
00179                 // solution not found
00180                 delete_lp(lp);
00181                 throw ModelInfeasible();
00182         }
00183 
00184         delete_lp(lp);
00185 }
00186 
00187 //-----------------------------------------------------------------
00188 
00189 LpSolve::LpSolve() : m_pImpl( new LpSolveImpl )
00190 {
00191 }
00192 
00193 LpSolve::~LpSolve() throw()
00194 {
00195 }
00196 
00197 void LpSolve::solve()
00198 {
00199         m_pImpl->setModel( getModel() );
00200         m_pImpl->solve();
00201         setSolution( m_pImpl->getSolution() );
00202 }
00203 
00204 
00205 
00206 }}}

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