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"
90 using namespace Bonmin;
93 using std::ostringstream;
98 using namespace Ipopt;
103 couenneErrorMsg =
"";
123 if(m_osilreader != NULL)
128 if(m_osolreader != NULL)
delete m_osolreader;
146 this->bCallbuildSolverInstance =
true;
150 std::ostringstream outStr;
152 if(osil.length() == 0 && osinstance == NULL)
throw ErrorClass(
"there is no instance");
153 if(osinstance == NULL)
156 osinstance = m_osilreader->readOSiL( osil);
159 osinstance->initForAlgDiff( );
163 couenne =
new CouenneProblem(NULL, NULL, NULL);
164 int n_allvars = osinstance->getVariableNumber();
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;
179 ub = osinstance->getVariableUpperBounds();
180 lb = osinstance->getVariableLowerBounds();
184 varType = osinstance->getVariableTypes();
185 for (i = 0; i < n_allvars; ++i)
187 if( (varType[i] ==
'B') || (varType[i]) ==
'I' )
189 couenne->addVariable(
true, couenne->domain() );
193 couenne->addVariable(
false, couenne->domain() );
199 couenne->domain()->push(n_allvars, x_, lb, ub);
206 if(osinstance->getObjectiveNumber() <= 0)
throw ErrorClass(
"Couenne NEEDS AN OBJECTIVE FUNCTION");
209 if (osinstance->getObjectiveNumber() > 1)
210 throw ErrorClass(
"Solver cannot handle multiple objectives --- please delete all but one");
213 SparseVector* sv = osinstance->getObjectiveCoefficients()[ 0];
215 exprGroup::lincoeff lin( nterms);
216 for ( i = 0; i < nterms; ++i)
218 lin[i].first = couenne->Var( sv->
indexes[ i] );
219 if( osinstance->getObjectiveMaxOrMins()[0] ==
"min")
221 lin[i].second = sv->
values[ i];
225 lin[i].second = -sv->
values[ i];
233 expression** nl =
new expression*[1];
234 if( osinstance->getObjectiveMaxOrMins()[0] ==
"min")
236 nl[0] = createCouenneExpression( exptree->
m_treeRoot );
240 nl[ 0] =
new exprOpp(createCouenneExpression( exptree->
m_treeRoot) );
243 obj_body =
new exprGroup(osinstance->getObjectiveConstants()[0], lin, nl, 1);
247 obj_body =
new exprGroup(osinstance->getObjectiveConstants()[0], lin, NULL, 0);
250 couenne->addObjective(obj_body,
"min");
254 SparseMatrix* sm = osinstance->getLinearConstraintCoefficientsInRowMajor();
256 int nconss = osinstance->getConstraintNumber();
260 double *rowlb = osinstance->getConstraintLowerBounds();
261 double *rowub = osinstance->getConstraintUpperBounds();
263 for (i = 0; i < nconss; ++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];
278 nl[0] = createCouenneExpression(exptree->
m_treeRoot);
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])
288 couenne->addEQConstraint(con_body,
new exprConst( rowub[ i] ));
293 couenne->addLEConstraint(con_body,
new exprConst( rowub[ i] ));
298 couenne->addGEConstraint(con_body,
new exprConst( rowlb[ i] ));
301 couenne->addRNGConstraint(con_body,
new exprConst( rowlb[ i]),
new
302 exprConst( rowub[ i] ));
310 osrl = osrlwriter->writeOSrL(
osresult);
319 std::ostringstream outStr;
324 return new exprSum(createCouenneExpression(node->
m_mChildren[0]), createCouenneExpression(node->
m_mChildren[1]));
329 return new exprConst(0.);
331 return createCouenneExpression(node->
m_mChildren[0]);
335 sumargs[i] = createCouenneExpression(node->
m_mChildren[i]);
339 return new exprSub(createCouenneExpression(node->
m_mChildren[0]), createCouenneExpression(node->
m_mChildren[1]));
341 return new exprOpp(createCouenneExpression(node->
m_mChildren[0]));
343 return new exprMul(createCouenneExpression(node->
m_mChildren[0]), createCouenneExpression(node->
m_mChildren[1]));
347 return new exprMul(createCouenneExpression(node->
m_mChildren[0]),
new exprInv(createCouenneExpression(node->
m_mChildren[1])));
349 return new exprDiv(createCouenneExpression(node->
m_mChildren[0]), createCouenneExpression(node->
m_mChildren[1]));
353 return new exprExp(
new exprMul(
new exprLog(createCouenneExpression(node->
m_mChildren[0])), createCouenneExpression(node->
m_mChildren[1])));
355 return new exprPow(createCouenneExpression(node->
m_mChildren[0]), createCouenneExpression(node->
m_mChildren[1]));
360 return new exprConst(1.);
362 return createCouenneExpression(node->
m_mChildren[0]);
366 args[i] = createCouenneExpression(node->
m_mChildren[i]);
371 return new exprAbs(createCouenneExpression(node->
m_mChildren[0]));
373 return new exprPow(createCouenneExpression(node->
m_mChildren[0]),
new exprConst(2.));
375 return new exprPow(createCouenneExpression(node->
m_mChildren[0]),
new exprConst(0.5));
377 return new exprLog(createCouenneExpression(node->
m_mChildren[0]));
379 return new exprExp(createCouenneExpression(node->
m_mChildren[0]));
381 return new exprSin(createCouenneExpression(node->
m_mChildren[0]));
383 return new exprCos(createCouenneExpression(node->
m_mChildren[0]));
388 return new exprConst(0.);
390 return createCouenneExpression(node->
m_mChildren[0]);
394 args[i] = createCouenneExpression(node->
m_mChildren[i]);
402 return new exprConst(0.);
404 return createCouenneExpression(node->
m_mChildren[0]);
408 args[i] = createCouenneExpression(node->
m_mChildren[i]);
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;
448 bSetSolverOptions =
true;
449 couenneSetup.initializeOptionsAndJournalist();
451 couenneSetup.options()->SetIntegerValue(
"bonmin.bb_log_level", 0);
452 couenneSetup.options()->SetIntegerValue(
"bonmin.nlp_log_level", 0 );
453 if(
osoption == NULL && osol.length() > 0)
456 osoption = m_osolreader->readOSoL( osol);
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 );
511 osrl = osrlwriter->writeOSrL(
osresult);
518 using namespace Ipopt;
523 #define PRINTED_PRECISION 1e-5
524 const int infeasible = 1;
526 if( this->bCallbuildSolverInstance ==
false) buildSolverInstance();
527 if(this->bSetSolverOptions ==
false) setSolverOptions() ;
535 bb.setProblem(couenne);
539 if(
osoption == NULL && osol.length() > 0)
542 osoption = m_osolreader->readOSoL( osol);
548 CouenneInterface *ci = NULL;
550 ci =
new CouenneInterface();
552 ci->initialize (couenneSetup.roptions(),
553 couenneSetup.options(),
554 couenneSetup.journalist(),
557 app_ =
new Bonmin::IpoptSolver(couenneSetup.roptions(),
558 couenneSetup.options(),
559 couenneSetup.journalist()
566 bool setupInit =
false;
567 setupInit = couenneSetup.InitializeCouenne(argv, couenne, NULL, ci);
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";
592 osrl = osrlwriter->writeOSrL(
osresult);
600 if(( ci->isProvenPrimalInfeasible() ==
false) && (ci -> isProvenOptimal () ==
false)
601 && (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() <= 0) )
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.";
623 osrl = osrlwriter->writeOSrL(
osresult);
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.");
642 status = tminlp->status;
650 osrl = osrlwriter->writeOSrL(
osresult);
656 catch(TNLPSolver::UnsolvedError *E)
659 E->printError(std::cerr);
667 osrl = osrlwriter->writeOSrL(
osresult);
671 catch(OsiTMINLPInterface::SimpleError &E)
673 ostringstream outStr;
674 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
678 osrl = osrlwriter->writeOSrL(
osresult);
684 ostringstream outStr;
685 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
689 osrl = osrlwriter->writeOSrL(
osresult);
693 catch (Ipopt::OPTION_INVALID &E)
695 ostringstream outStr;
696 outStr <<
"Ipopt exception : " << E.Message() << std::endl;
700 osrl = osrlwriter->writeOSrL(
osresult);
703 catch (
int generic_error)
705 if (generic_error == infeasible)
709 osrl = osrlwriter->writeOSrL(
osresult);
723 std::string solutionDescription =
"";
724 std::string message =
"Couenne solver finishes to the end.";
729 if(osinstance->getVariableNumber() > 0) x =
new double[osinstance->getVariableNumber() ];
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.";
758 if(osinstance->getObjectiveNumber() > 0)
761 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues(
const_cast<double*
>(bb.bestSolution()),
true)[ 0];
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.";
773 if(osinstance->getVariableNumber() > 0)
775 for(i=0; i < osinstance->getVariableNumber(); i++)
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.";
788 if(osinstance->getObjectiveNumber() > 0)
790 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues(
const_cast<double*
>(bb.model().getColSolution()),
true)[ 0];
794 if(osinstance->getVariableNumber() > 0)
796 for(i=0; i < osinstance->getVariableNumber(); i++)
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";
827 osrl = osrlwriter->writeOSrL(
osresult);
828 if(osinstance->getVariableNumber() > 0)
delete[] x;
843 osrl = osrlwriter->writeOSrL(
osresult);
const OSSmartPtr< OSOutput > osoutput
std::string OSgetVersionInfo()
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
double os_strtod(const char *s00, char **se)
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
CouenneSolver()
the CouenneSolver class constructor
Couenne::expression * createCouenneExpression(OSnLNode *node)
used for throwing exceptions.
std::string errormsg
errormsg is the error that is causing the exception to be thrown
OSnLNode ** m_mChildren
m_mChildren holds all the operands, that is, nodes that the current node operates on.
int inodeInt
inodeInt is the unique integer assigned to the OSnLNode or OSnLMNode in OSParameters....
unsigned int inumberOfChildren
inumberOfChildren is the number of OSnLNode child elements If this number is not fixed,...
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.
The OSnLNode Class for nonlinear expressions.
The OSnLNodeNumber Class.
virtual std::string getTokenName()
The OSnLNodeVariable Class.
int idx
idx is the index of the variable
double coef
coef is an option coefficient on the variable, the default value is 1.0
Used to read an OSoL string.
Take an OSResult object and write a string that validates against OSrL.
Used to hold part of the instance in memory.
OSnLNode * m_treeRoot
m_treeRoot holds the root node (of OSnLNode type) of the expression tree.
a sparse matrix data structure
int * indexes
indexes holds an integer array of rowIdx (or colIdx) elements in coefMatrix (AMatrix).
int * starts
starts holds an integer array of start elements in coefMatrix (AMatrix), which points to the start of...
double * values
values holds a double array of value elements in coefMatrix (AMatrix), which contains nonzero element...
a sparse vector data structure
double * values
values holds a double array of nonzero values.
int * indexes
indexes holds an integer array of indexes whose corresponding values are nonzero.
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