source/numeric/lpuno.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 #include "numeric/lpuno.hxx"
00029 #include "numeric/lpmodel.hxx"
00030 #include "numeric/matrix.hxx"
00031 #include "xcalc.hxx"
00032 #include "tool/global.hxx"
00033 #include "unoglobal.hxx"
00034 
00035 #include "org/openoffice/sc/solver/XLpModel.hpp"
00036 #include "org/openoffice/sc/solver/XLpAlgorithm.hpp"
00037 #include "org/openoffice/sc/solver/Goal.hpp"
00038 #include "org/openoffice/sc/solver/Equality.hpp"
00039 #include "com/sun/star/uno/RuntimeException.hpp"
00040 
00041 #include <exception>
00042 
00043 using namespace ::com::sun::star::uno;
00044 
00045 namespace scsolver { namespace numeric { namespace lp {
00046 
00047 class UnoServiceNotFound : public ::std::exception
00048 {
00049         const char* what() const throw() { return "UNO Servcie not found"; }
00050 };
00051 
00052 class LpModelNotFound : public ::std::exception
00053 {
00054         const char* what() const throw() { return "LpModel service not found"; }
00055 };
00056 
00057 class UnknownGoal : public ::std::exception
00058 {
00059         const char* what() const throw() { return "Unknown goal"; }
00060 };
00061 
00062 class UnknownConstraintType : public ::std::exception
00063 {
00064         const char* what() const throw() { return "Unknown constraint type"; }
00065 };
00066 
00067 class UnoAlgorithmImpl
00068 {
00069 public:
00070         UnoAlgorithmImpl( const rtl::OUString& service, CalcInterface* pCalc ) :
00071                 m_sServiceName( service ),
00072                 m_pCalc( pCalc ),
00073                 m_mxSolution( 0, 0 ),
00074                 m_pModel( NULL )
00075         {
00076         }
00077 
00078         ~UnoAlgorithmImpl() throw() 
00079         {
00080         }
00081 
00082         void solve();
00083         Matrix getSolution() const;
00084 
00085         void setModel( Model* p ) { m_pModel = p; }
00086         Model* getModel() const { return m_pModel; }
00087 
00088         const rtl::OUString getServiceName() const { return m_sServiceName; }
00089 
00090 private:
00091         rtl::OUString m_sServiceName;
00092         CalcInterface* m_pCalc;
00093         Matrix m_mxSolution;
00094         Model* m_pModel;
00095 
00096         CalcInterface* getCalcInterface() const { return m_pCalc; }
00097 };
00098 
00108 void UnoAlgorithmImpl::solve()
00109 {
00110         using namespace ::org::openoffice::sc::solver;
00111         using numeric::Matrix;
00112 
00113         static const rtl::OUString sLpModelSrv = ascii( "org.openoffice.sc.solver.LpModel" );
00114 
00115         Reference< uno::XComponentContext >       xCC = getCalcInterface()->getComponentContext();
00116         Reference< lang::XMultiComponentFactory > xSM = getCalcInterface()->getServiceManager();
00117 
00118         Reference< uno::XInterface > svModel = xSM->createInstanceWithContext( sLpModelSrv, xCC );
00119         if ( svModel == NULL )
00120                 throw LpModelNotFound();
00121 
00122         Reference< XLpModel > xModel( svModel, UNO_QUERY );
00123 
00124         numeric::lp::Model* model = getModel();
00125 
00126         // Map LP model properties into XLpModel.
00127 
00128         // --- Goal ---
00129 
00130         switch ( model->getGoal() )
00131         {
00132         case GOAL_MINIMIZE:
00133                 xModel->setGoal( Goal_MINIMIZE );
00134                 break;
00135         case GOAL_MAXIMIZE:
00136                 xModel->setGoal( Goal_MAXIMIZE );
00137                 break;
00138         default:
00139                 throw UnknownGoal();
00140         }
00141 
00142         // --- Costs ---
00143 
00144         Matrix mxCosts = model->getCostVector();
00145         size_t nDecVarSize = mxCosts.cols();
00146         xModel->setDecisionVarSize( nDecVarSize );
00147         for ( size_t i = 0; i < nDecVarSize; ++i )
00148                 xModel->setCost( i, mxCosts( 0, i ) );
00149 
00150         // --- Constraints ---
00151 
00152         Matrix mxConstraint = model->getConstraintMatrix();
00153         Matrix mxRhs = model->getRhsVector();
00154 
00155         size_t nConstraintSize = mxConstraint.rows();
00156         xModel->setConstraintCount( nConstraintSize );
00157         for ( size_t i = 0; i < nConstraintSize; ++i )
00158         {
00159                 for ( size_t j = 0; j < nDecVarSize; ++j )
00160                         xModel->setConstraint( i, j, mxConstraint( i, j ) );
00161 
00162                 switch ( model->getEquality(i) )
00163                 {
00164                 case GREATER_EQUAL:
00165                         xModel->setEquality( i, Equality_GREATER_EQUAL );
00166                         break;
00167                 case EQUAL:
00168                         xModel->setEquality( i, Equality_EQUAL );
00169                         break;
00170                 case LESS_EQUAL:
00171                         xModel->setEquality( i, Equality_LESS_EQUAL );
00172                         break;
00173                 default:
00174                         throw UnknownConstraintType();
00175                 }
00176 
00177                 xModel->setRhsValue( i, mxRhs( i, 0 ) );
00178         }
00179 
00180         // Instantiate the UNO algorithm and run it.
00181 
00182         Reference< uno::XInterface > algorithm = xSM->createInstanceWithContext( getServiceName(), xCC );
00183         if ( algorithm == NULL )
00184                 throw UnoServiceNotFound();
00185 
00186         Reference< XLpAlgorithm > xAlgorithm( algorithm, UNO_QUERY );
00187         xAlgorithm->setModel( xModel );
00188         try
00189         {
00190                 xAlgorithm->solve();
00191         }
00192         catch ( const RuntimeException& e )
00193         {
00194                 throw lp::ModelInfeasible();
00195         }
00196 
00197         Matrix mxSol( nDecVarSize, 1 );
00198         for ( size_t i = 0; i < nDecVarSize; ++i )
00199                 mxSol( i, 0 ) = xAlgorithm->getVar(i);
00200 
00201         m_mxSolution.swap( mxSol );
00202 }
00203 
00204 Matrix UnoAlgorithmImpl::getSolution() const
00205 {
00206         return m_mxSolution;
00207 }
00208 
00209 
00210 
00211 
00212 UnoAlgorithm::UnoAlgorithm( const rtl::OUString& service, CalcInterface* pCalc ) :
00213         m_pImpl( new UnoAlgorithmImpl( service, pCalc ) )
00214 {
00215 }
00216 
00217 UnoAlgorithm::~UnoAlgorithm() throw()
00218 {
00219 }
00220 
00221 void UnoAlgorithm::solve()
00222 {
00223         m_pImpl->setModel( getModel() );
00224         m_pImpl->solve();
00225         setSolution( m_pImpl->getSolution() );
00226 }
00227 
00228 }}}}

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