22#include "OSParameters.h"
26#include "BonBonminSetup.hpp"
32#include "CouenneConfig.h"
33#include "CouenneTypes.hpp"
34#include "CouenneJournalist.hpp"
35#include "CouenneExprClone.hpp"
36#include "CouenneExprGroup.hpp"
37#include "CouenneExprAbs.hpp"
38#include "CouenneExprConst.hpp"
39#include "CouenneExprCos.hpp"
40#include "CouenneExprDiv.hpp"
41#include "CouenneExprExp.hpp"
42#include "CouenneExprInv.hpp"
43#include "CouenneExprLog.hpp"
44#include "CouenneExprMax.hpp"
45#include "CouenneExprMin.hpp"
46#include "CouenneExprMul.hpp"
47#include "CouenneExprOpp.hpp"
48#include "CouenneExprPow.hpp"
49#include "CouenneExprSin.hpp"
50#include "CouenneExprSub.hpp"
51#include "CouenneExprSum.hpp"
52#include "CouenneExprVar.hpp"
59#include "BonOsiTMINLPInterface.hpp"
60#include "BonIpoptSolver.hpp"
63#include "CoinTime.hpp"
64#include "BonminConfig.h"
65#include "BonCouenneInterface.hpp"
68#include "BonCouenneSetup.hpp"
71#ifdef COIN_HAS_FILTERSQP
72#include "BonFilterSolver.hpp"
75#include "CbcCutGenerator.hpp"
76#include "CouenneProblem.hpp"
77#include "CouenneCutGenerator.hpp"
78#include "CouenneBab.hpp"
90using namespace Bonmin;
93using std::ostringstream;
98 using namespace Ipopt;
150 std::ostringstream outStr;
163 couenne =
new CouenneProblem(NULL, NULL, NULL);
165 if( n_allvars < 0 )
throw ErrorClass(
"Couenne solver Cannot have a negatiave number of Variables");
169 outStr <<
"NUMBER OF VARIABLES = " << n_allvars << std::endl;
175 CouNumber *x_ = (CouNumber *)
malloc ((n_allvars) *
sizeof (CouNumber));
176 CouNumber *lb = NULL, *ub = NULL;
185 for (i = 0; i < n_allvars; ++i)
187 if( (varType[i] ==
'B') || (varType[i]) ==
'I' )
199 couenne->domain()->push(n_allvars, x_, lb, ub);
210 throw ErrorClass(
"Solver cannot handle multiple objectives --- please delete all but one");
215 exprGroup::lincoeff lin( nterms);
216 for ( i = 0; i < nterms; ++i)
218 lin[i].first =
couenne->Var( sv->indexes[ i] );
221 lin[i].second = sv->values[ i];
225 lin[i].second = -sv->values[ i];
233 expression** nl =
new expression*[1];
263 for (i = 0; i < nconss; ++i)
266 if( sm) row_nonz = sm->starts[ i +1] - sm->starts[ i];
267 exprGroup::lincoeff con_lin( row_nonz);
268 for (j = 0; j < row_nonz; ++j)
270 con_lin[j].first =
couenne->Var( sm->indexes[ kount] );
271 con_lin[j].second = sm->values[ kount];
277 expression** nl =
new expression*[1];
279 con_body =
new exprGroup(0., con_lin, nl, 1);
283 con_body =
new exprGroup(0., con_lin, NULL, 0);
286 if (rowlb[ i] == rowub[ i])
302 exprConst( rowub[ i] ));
319 std::ostringstream outStr;
321 switch (node->inodeInt)
326 switch ( node->inumberOfChildren )
329 return new exprConst(0.);
333 expression** sumargs =
new expression*[node->inumberOfChildren];
334 for(i = 0; i< node->inumberOfChildren; i++)
336 return new exprSum(sumargs, node->inumberOfChildren);
346 if (node->m_mChildren[0]->inodeInt ==
OS_NUMBER)
352 if (node->m_mChildren[1]->inodeInt !=
OS_NUMBER)
357 switch ( node->inumberOfChildren )
360 return new exprConst(1.);
364 expression** args =
new expression*[node->inumberOfChildren];
365 for( i = 0; i < node->inumberOfChildren; i++)
367 expression* base =
new exprMul(args, node->inumberOfChildren);
385 switch (node->inumberOfChildren)
388 return new exprConst(0.);
392 expression** args =
new expression*[node->inumberOfChildren];
393 for( i = 0; i <node->inumberOfChildren; i++)
395 expression* base =
new exprMin(args, node->inumberOfChildren);
399 switch (node->inumberOfChildren)
402 return new exprConst(0.);
406 expression** args =
new expression*[node->inumberOfChildren];
407 for(i = 0; i < node->inumberOfChildren; i++)
409 expression* base =
new exprMax(args, node->inumberOfChildren);
421 if (varnode->coef == 0.)
422 return new exprConst(0.);
423 if (varnode->coef == 1.)
424 return new exprClone(
couenne->Variables()[varnode->idx]);
425 if (varnode->coef == -1.)
426 return new exprOpp(
new exprClone(
couenne->Variables()[varnode->idx]));
427 return new exprMul(
new exprConst(varnode->coef),
new exprClone(
couenne->Variables()[varnode->idx]));
432 outStr << node->getTokenName() <<
" NOT IMPLEMENTED!!" << endl;
443 std::ostringstream outStr;
451 couenneSetup.options()->SetIntegerValue(
"bonmin.bb_log_level", 0);
452 couenneSetup.options()->SetIntegerValue(
"bonmin.nlp_log_level", 0 );
462 std::vector<SolverOption*> optionsVector;
464 int num_bonmin_options = optionsVector.size();
465 std::string optionName;
467 for(i = 0; i < num_bonmin_options; i++)
469 if(optionsVector[ i]->category ==
"ipopt")
471 optionName = optionsVector[ i]->name;
475 if(optionsVector[ i]->category ==
"bonmin" )
477 optionName =
"bonmin."+optionsVector[ i]->name;
481 optionName =
"couenne."+optionsVector[ i]->name;
487 outStr <<
"found option " << optionName <<
" of type " << optionsVector[ i]->type << std::endl;
490 if(optionsVector[ i]->type ==
"numeric" )
492 couenneSetup.options()->SetNumericValue(optionName,
os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
494 else if(optionsVector[ i]->type ==
"integer" )
496 couenneSetup.options()->SetIntegerValue(optionName, atoi( optionsVector[ i]->value.c_str() ) );
498 else if(optionsVector[ i]->type ==
"string" )
500 couenneSetup.options()->SetStringValue(optionName, optionsVector[ i]->value );
518using namespace Ipopt;
523#define PRINTED_PRECISION 1e-5
524 const int infeasible = 1;
548 CouenneInterface *ci = NULL;
550 ci =
new CouenneInterface();
566 bool setupInit =
false;
570 if(setupInit ==
false)
572 std::string solutionDescription =
"";
573 std::string message =
"Couenne solver finishes to the end.";
576 throw ErrorClass(
"OSResult error: setServiceName");
578 throw ErrorClass(
"OSResult error: setInstanceName");
580 throw ErrorClass(
"OSResult error: setVariableNumer");
582 throw ErrorClass(
"OSResult error: setObjectiveNumber");
584 throw ErrorClass(
"OSResult error: setConstraintNumber");
586 throw ErrorClass(
"OSResult error: setSolutionNumer");
588 throw ErrorClass(
"OSResult error: setGeneralMessage");
589 solutionDescription =
"COUENNE INITIALIZE PROBLEM: \n There was a problem with Couenne Initialize: \n the problem could be infeasible \n there may be zero decision variables";
600 if(( ci->isProvenPrimalInfeasible() ==
false) && (ci -> isProvenOptimal () ==
false)
603 std::string solutionDescription =
"";
604 std::string message =
"Success";
607 throw ErrorClass(
"OSResult error: setServiceName");
609 throw ErrorClass(
"OSResult error: setInstanceName");
611 throw ErrorClass(
"OSResult error: setVariableNumer");
613 throw ErrorClass(
"OSResult error: setObjectiveNumber");
615 throw ErrorClass(
"OSResult error: setConstraintNumber");
617 throw ErrorClass(
"OSResult error: setSolutionNumer");
619 throw ErrorClass(
"OSResult error: setGeneralMessage");
620 solutionDescription =
"CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
629 CouenneCutGenerator *cg = NULL;
631 if (
bb.model (). cutGenerators ())
632 cg =
dynamic_cast <CouenneCutGenerator *
>
633 (
bb.model (). cutGenerators () [0] -> generator ());
637 couenneSetup.options () -> GetNumericValue (
"couenne_check", global_opt,
"couenne.");
638 double timeLimit = 0;
639 couenneSetup.options () -> GetNumericValue (
"time_limit", timeLimit,
"couenne.");
656 catch(TNLPSolver::UnsolvedError *E)
659 E->printError(std::cerr);
671 catch(OsiTMINLPInterface::SimpleError &E)
673 ostringstream outStr;
674 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
684 ostringstream outStr;
685 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
693 catch (Ipopt::OPTION_INVALID &E)
695 ostringstream outStr;
696 outStr <<
"Ipopt exception : " << E.Message() << std::endl;
703 catch (
int generic_error)
705 if (generic_error == infeasible)
723 std::string solutionDescription =
"";
724 std::string message =
"Couenne solver finishes to the end.";
734 throw ErrorClass(
"OSResult error: setSolverInvoked");
736 throw ErrorClass(
"OSResult error: setServiceName");
738 throw ErrorClass(
"OSResult error: setInstanceName");
742 throw ErrorClass(
"OSResult error: setVariableNumer");
744 throw ErrorClass(
"OSResult error: setObjectiveNumber");
746 throw ErrorClass(
"OSResult error: setConstraintNumber");
748 throw ErrorClass(
"OSResult error: setSolutionNumer");
750 throw ErrorClass(
"OSResult error: setGeneralMessage");
754 case TMINLP::SUCCESS:
755 solutionDescription =
"SUCCESS[COUENNE]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
763 if(fabs(*(z + 0)) == 9.999e+12)
765 solutionDescription =
"CONTINUOUS_UNBOUNDED [COUENNE]: Continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
777 *(x + i) =
bb.bestSolution()[i];
784 case TMINLP::LIMIT_EXCEEDED:
785 solutionDescription =
"LIMIT_EXCEEDED[COUENNE]: A resource limit was exceeded, we provide the current solution.";
798 *(x + i) =
bb.model().getColSolution()[i];
804 case TMINLP::MINLP_ERROR:
805 solutionDescription =
"MINLP_ERROR [COUENNE]: Algorithm stopped with unspecified error.";
810 case TMINLP::CONTINUOUS_UNBOUNDED:
811 solutionDescription =
"CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
816 case TMINLP::INFEASIBLE:
817 solutionDescription =
"INFEASIBLE [COUENNE]: Problem may be infeasible.";
822 solutionDescription =
"OTHER[COUENNE]: other unknown solution status from Couenne solver";
const OSSmartPtr< OSOutput > osoutput
std::string OSgetVersionInfo()
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
double os_strtod(const char *s00, char **se)
Bonmin::TMINLP::SolverReturn status
virtual void solve()
solve results in an instance being read into the Couenne data structrues and optimized
virtual void buildSolverInstance()
buildSolverInstance is a virtual function – the actual solvers will implement their own buildSolverIn...
virtual void setSolverOptions()
The implementation of the virtual functions.
void writeResult()
use this to write the solution information to an OSResult object
~CouenneSolver()
the IpoptSolver class destructor
Couenne::expression * obj_body
OSoLReader * m_osolreader
m_osolreader is an OSoLReader object used to create an osoption from an osol string if needed
Ipopt::SmartPtr< Bonmin::TNLPSolver > app_
CouenneSolver()
the CouenneSolver class constructor
Couenne::CouenneProblem * couenne
Couenne::expression * con_body
OSiLReader * m_osilreader
m_osilreader is an OSiLReader object used to create an osinstance from an osil string if needed
Ipopt::SmartPtr< BonminProblem > tminlp
Couenne::expression * createCouenneExpression(OSnLNode *node)
std::string couenneErrorMsg
Couenne::CouenneSetup couenneSetup
std::string osol
osol holds the options for the solver
bool bSetSolverOptions
bSetSolverOptions is set to true if setSolverOptions has been called, false otherwise
std::string osrl
osrl holds the solution or result of the model
OSInstance * osinstance
osinstance holds the problem instance in-memory as an OSInstance object
bool bCallbuildSolverInstance
bCallbuildSolverInstance is set to true if buildSolverService has been called
std::string osil
osil holds the problem instance as a std::string
OSOption * osoption
osoption holds the solver options in-memory as an OSOption object
OSResult * osresult
osresult holds the solution or result of the model in-memory as an OSResult object
used for throwing exceptions.
double * getConstraintLowerBounds()
Get constraint lower bounds.
double * getVariableUpperBounds()
Get variable upper bounds.
int getNumberOfIntegerVariables()
getNumberOfIntegerVariables
int getNumberOfBinaryVariables()
getNumberOfBinaryVariables
int getConstraintNumber()
Get number of constraints.
SparseMatrix * getLinearConstraintCoefficientsInRowMajor()
Get linear constraint coefficients in row major.
char * getVariableTypes()
Get variable initial values.
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
SparseVector ** getObjectiveCoefficients()
Get objective coefficients.
double * getObjectiveConstants()
Get objective constants.
double * getVariableLowerBounds()
Get variable lower bounds.
int getVariableNumber()
Get number of variables.
std::string getInstanceName()
Get instance name.
ScalarExpressionTree * getNonlinearExpressionTree(int rowIdx)
Get the expression tree for a given row index.
std::string * getObjectiveMaxOrMins()
Get objective maxOrMins.
double * getConstraintUpperBounds()
Get constraint upper bounds.
int getObjectiveNumber()
Get number of objectives.
std::vector< SolverOption * > getSolverOptions(std::string solver_name)
Get the options associated with a given solver.
int getNumberOfSolverOptions()
Get the number of solver options.
bool setGeneralMessage(std::string message)
Set the general message.
bool setSolutionNumber(int number)
set the number of solutions.
bool setInstanceName(std::string instanceName)
Set instance name.
bool setObjectiveValuesDense(int solIdx, double *objectiveValues)
Set the [i]th optimization solution's objective values, where i equals the given solution index.
bool setGeneralStatusType(std::string type)
Set the general status type, which can be: success, error, warning.
bool setObjectiveNumber(int objectiveNumber)
Set the objective number.
bool setPrimalVariableValuesDense(int solIdx, double *x)
Set the [i]th optimization solution's primal variable values, where i equals the given solution index...
bool setServiceName(std::string serviceName)
Set service name.
bool setSolverInvoked(std::string solverInvoked)
Set solver invoked.
bool setVariableNumber(int variableNumber)
Set the variable number.
bool setSolutionStatus(int solIdx, std::string type, std::string description)
Set the [i]th optimization solution status, where i equals the given solution index.
bool setConstraintNumber(int constraintNumber)
Set the constraint number.
Used to read an OSiL string.
OSInstance * readOSiL(const std::string &osil)
parse the OSiL model instance.
The OSnLNode Class for nonlinear expressions.
The OSnLNodeNumber Class.
The OSnLNodeVariable Class.
Used to read an OSoL string.
OSOption * readOSoL(const std::string &osol)
parse the OSoL solver options.
Take an OSResult object and write a string that validates against OSrL.
std::string writeOSrL(OSResult *theosresult)
create an osrl string from an OSResult object
Used to hold part of the instance in memory.
a sparse matrix data structure
a sparse vector data structure
int number
number is the number of elements in the indexes and values arrays.
@ ENUM_OUTPUT_LEVEL_debug
@ ENUM_OUTPUT_LEVEL_error
@ ENUM_OUTPUT_AREA_OSSolverInterfaces