source/numeric/nlpmodel.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/nlpmodel.hxx"
00029 #include "numeric/nlpbase.hxx"
00030 #include "numeric/funcobj.hxx"
00031 #include "numeric/exception.hxx"
00032 #include "numeric/type.hxx"
00033 #include "tool/global.hxx"
00034 #include <vector>
00035 #include <iostream>
00036 #include <algorithm>
00037 
00038 #include <stdio.h>
00039 
00040 using namespace ::scsolver::numeric;
00041 using ::std::vector;
00042 using ::std::for_each;
00043 
00044 namespace scsolver { namespace numeric { namespace nlp {
00045 
00046 namespace {
00047 
00049 struct DecVar
00050 {
00051     double Value;
00052 
00053     bool   UpperBoundEnabled;
00054     double UpperBoundValue;
00055 
00056     bool   LowerBoundEnabled;
00057     double LowerBoundValue;
00058 
00059     DecVar() :
00060         Value(0.0),
00061         UpperBoundEnabled(false), 
00062         UpperBoundValue(0.0),
00063         LowerBoundEnabled(false), 
00064         LowerBoundValue(0.0)
00065     {}
00066 };
00067 
00068 class ConstraintPrinter : public ::std::unary_function<Constraint, void>
00069 {
00070 public:
00071     explicit ConstraintPrinter(FILE* fs) : 
00072         m_fs(fs) 
00073     {
00074     }
00075 
00076     void operator()(const Constraint& c) const
00077     {
00078         fprintf(m_fs, "%s ", c.FuncObj->getFuncString().c_str());
00079         switch (c.Equality)
00080         {
00081             case GREATER_EQUAL: fprintf(m_fs, ">= "); break;
00082             case EQUAL:         fprintf(m_fs, "= "); break;
00083             case LESS_EQUAL:    fprintf(m_fs, "<= "); break;
00084         }
00085         fprintf(m_fs, "%g", c.RightValue);
00086         fprintf(m_fs, "\n");
00087     }
00088 
00089 private:
00090     FILE* m_fs;
00091 };
00092 
00093 }
00094 
00095 Constraint::Constraint(BaseFuncObj* pFunc, EqualityType eq, double rightValue) :
00096     FuncObj(pFunc), Equality(eq), RightValue(rightValue) 
00097 {
00098 }
00099 
00100 // ============================================================================
00101 
00102 class ModelImpl
00103 {
00104 public:
00105     ModelImpl(Model* p);
00106     ModelImpl(const ModelImpl& other);
00107     ~ModelImpl() throw();
00108 
00109     void setPrecision( unsigned long n ) { m_nPrec = n; }
00110     unsigned long getPrecision() const { return m_nPrec; }
00111 
00112     void setGoal( GoalType e ) { m_eGoal = e; }
00113     GoalType getGoal() const { return m_eGoal; }
00114 
00115     void setVerbose( bool b ) { m_bVerbose = b; }
00116     bool getVerbose() const { return m_bVerbose; }
00117 
00118     void setFuncObject(BaseFuncObj* pFuncObj);
00119     BaseFuncObj* getFuncObject() const { return m_pFuncObj; }
00120 
00121     void pushVar( double value )
00122     {
00123         DecVar var;
00124         var.Value = value;
00125         m_Vars.push_back(var);
00126     }
00127 
00128     void getVars( vector<double>& vars ) const
00129     {
00130         size_t n = m_Vars.size();
00131         vector<double> tmp;
00132         tmp.reserve(n);
00133         vector<DecVar>::const_iterator itr = m_Vars.begin(), itrEnd = m_Vars.end();
00134         for (; itr != itrEnd; ++itr)
00135             tmp.push_back(itr->Value);
00136         vars.swap(tmp);
00137     }
00138 
00139     double getVarBound( size_t index, BoundType bound ) const
00140     {
00141         switch (bound)
00142         {
00143         case BOUND_LOWER:
00144             if ( !m_Vars.at(index).LowerBoundEnabled )
00145                 throw UnboundedException();
00146             return m_Vars.at(index).LowerBoundValue;
00147         case BOUND_UPPER:
00148             if ( !m_Vars.at(index).UpperBoundEnabled )
00149                 throw UnboundedException();
00150             return m_Vars.at(index).UpperBoundValue;
00151         }
00152         return 0.0;
00153     }
00154 
00155     void setVarBound( size_t index, BoundType bound, double value )
00156     {
00157         switch (bound)
00158         {
00159         case BOUND_LOWER:
00160             m_Vars.at(index).LowerBoundValue = value;
00161             m_Vars.at(index).LowerBoundEnabled = true;
00162             break;
00163         case BOUND_UPPER:
00164             m_Vars.at(index).UpperBoundValue = value;
00165             m_Vars.at(index).UpperBoundEnabled = true;
00166             break;
00167         }
00168     }
00169 
00170     bool isVarBounded( size_t index, BoundType bound ) const
00171     {
00172         switch (bound)
00173         {
00174         case BOUND_LOWER:
00175             return m_Vars.at(index).LowerBoundEnabled;
00176         case BOUND_UPPER:
00177             return m_Vars.at(index).UpperBoundEnabled;
00178         }
00179         throw AssertionWrong();
00180         return false;
00181     }
00182 
00183     void pushConstraint(BaseFuncObj* pFunc, EqualityType eq, double rightValue);
00184     const vector<Constraint>& getAllConstraints() const;
00185 
00186     void print() const;
00187 
00188 private:
00189     BaseFuncObj*    m_pFuncObj;
00190     vector<DecVar>      m_Vars;
00191     vector<Constraint>  m_Constraints;
00192 
00193     Model*          m_pSelf;
00194     unsigned long   m_nPrec;
00195     GoalType        m_eGoal;
00196     bool            m_bVerbose;
00197 };
00198 
00199 ModelImpl::ModelImpl(Model* p) : 
00200     m_pFuncObj(NULL),
00201     m_pSelf( p ),
00202     m_nPrec( 9 ), 
00203     m_eGoal( GOAL_UNKNOWN ), 
00204     m_bVerbose(false)
00205 {
00206 }
00207 
00208 ModelImpl::ModelImpl(const ModelImpl& other) : 
00209     m_pFuncObj(other.m_pFuncObj),
00210     m_nPrec(other.m_nPrec)
00211 {
00212 }
00213 
00214 ModelImpl::~ModelImpl() throw()
00215 {
00216 }
00217 
00218 void ModelImpl::setFuncObject(BaseFuncObj* pFuncObj)
00219 {
00220     m_pFuncObj = pFuncObj;
00221 }
00222 
00223 void ModelImpl::pushConstraint(BaseFuncObj* pFunc, EqualityType eq, double rightValue)
00224 {
00225     m_Constraints.push_back(Constraint(pFunc, eq, rightValue));
00226 }
00227 
00228 const vector<Constraint>& ModelImpl::getAllConstraints() const
00229 {
00230     return m_Constraints;
00231 }
00232 
00233 void ModelImpl::print() const
00234 {
00235     FILE* fs = stdout;
00236 
00237     // Objective function and goal.
00238     fprintf(fs, "--------------------------------------------------------------------\n");
00239     fprintf(fs, "objective: ");
00240     if (m_pFuncObj)
00241         fprintf(fs, "%s\n", m_pFuncObj->getFuncString().c_str());
00242     else
00243         fprintf(fs, "object function not set!\n");
00244 
00245     fprintf(fs, "goal: ");
00246     switch ( m_eGoal )
00247     {
00248     case GOAL_MAXIMIZE:
00249         fprintf(fs, "maximize");
00250         break;
00251     case GOAL_MINIMIZE:
00252         fprintf(fs, "minimize");
00253         break;
00254     default:
00255         fprintf(fs, "unknown");
00256     }
00257     fprintf(fs, "\n");
00258     fprintf(fs, "--------------------------------------------------------------------\n");
00259 
00260     size_t n = m_Vars.size();
00261     for (size_t i = 0; i < n; ++i)
00262     {
00263         const DecVar& var = m_Vars.at(i);
00264         fprintf(fs, "var %d: ", i);
00265         if (var.LowerBoundEnabled)
00266             fprintf(fs, "%.2f", var.LowerBoundValue);
00267         else 
00268             fprintf(fs, "[unbounded]");
00269         fprintf(fs, " - ");
00270 
00271         if (var.UpperBoundEnabled)
00272             fprintf(fs, "%.2f", var.UpperBoundValue);
00273         else
00274             fprintf(fs, "[unbounded]");
00275         fprintf(fs, "\n");
00276     }
00277     fprintf(fs, "--------------------------------------------------------------------\n");
00278     if (m_Constraints.empty())
00279         fprintf(fs, "model is unconstrained\n");
00280     else
00281     {
00282         fprintf(fs, "Constraints\n");
00283         for_each(m_Constraints.begin(), m_Constraints.end(), ConstraintPrinter(fs));
00284     }
00285     fprintf(fs, "--------------------------------------------------------------------\n");
00286     fflush(fs);
00287 }
00288 
00289 //---------------------------------------------------------------------------
00290 // ENVELOPE
00291 
00292 Model::Model() : m_pImpl( new ModelImpl( this ) )
00293 {
00294 }
00295 
00296 Model::Model( const Model& other ) : m_pImpl( new ModelImpl( *other.m_pImpl.get() ) )
00297 {
00298 }
00299 
00300 Model::~Model() throw()
00301 {
00302 }
00303 
00304 void Model::print() const
00305 {
00306     m_pImpl->print();
00307 }
00308 
00309 void Model::setPrecision( unsigned long n )
00310 {
00311     m_pImpl->setPrecision( n );
00312 }
00313 
00314 unsigned long Model::getPrecision() const
00315 {
00316     return m_pImpl->getPrecision();
00317 }
00318 
00319 void Model::setGoal( GoalType e )
00320 {
00321     m_pImpl->setGoal( e );
00322 }
00323 
00324 GoalType Model::getGoal() const
00325 {
00326     return m_pImpl->getGoal();
00327 }
00328 
00329 void Model::setVerbose( bool b )
00330 {
00331     m_pImpl->setVerbose( b );
00332 }
00333 
00334 bool Model::getVerbose() const
00335 {
00336     return m_pImpl->getVerbose();
00337 }
00338 
00339 void Model::setFuncObject(BaseFuncObj* pFuncObj)
00340 {
00341     m_pImpl->setFuncObject(pFuncObj);
00342 }
00343 
00344 BaseFuncObj* Model::getFuncObject() const
00345 {
00346     return m_pImpl->getFuncObject();
00347 }
00348 
00349 void Model::pushVar( double var )
00350 {
00351     m_pImpl->pushVar(var);
00352 }
00353 
00354 void Model::getVars( vector<double>& vars ) const
00355 {
00356     m_pImpl->getVars(vars);
00357 }
00358 
00359 double Model::getVarBound( size_t index, BoundType bound ) const
00360 {
00361     return m_pImpl->getVarBound(index, bound);
00362 }
00363 
00364 void Model::setVarBound( size_t index, BoundType bound, double value )
00365 {
00366     m_pImpl->setVarBound(index, bound, value);
00367 }
00368 
00369 bool Model::isVarBounded( size_t index, BoundType bound ) const
00370 {
00371     return m_pImpl->isVarBounded(index, bound);
00372 }
00373 
00374 void Model::pushConstraint(BaseFuncObj* pFunc, EqualityType eq, double rightValue)
00375 {
00376     m_pImpl->pushConstraint(pFunc, eq, rightValue);
00377 }
00378 
00379 const vector<Constraint>& Model::getAllConstraints() const
00380 {
00381     return m_pImpl->getAllConstraints();
00382 }
00383 
00384 }}}
00385 

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