00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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