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);
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;
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);
206 if(
osinstance->getObjectiveNumber() <= 0)
throw ErrorClass(
"Couenne NEEDS AN OBJECTIVE FUNCTION");
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)
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")
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)
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] ));
309 osresult->setGeneralStatusType(
"error");
319 std::ostringstream outStr;
329 return new exprConst(0.);
360 return new exprConst(1.);
388 return new exprConst(0.);
402 return new exprConst(0.);
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;
463 optionsVector =
osoption->getSolverOptions(
"couenne",
true);
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 );
510 osresult->setGeneralStatusType(
"error");
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.";
575 if(
osresult->setServiceName(
"Couenne solver service") !=
true)
576 throw ErrorClass(
"OSResult error: setServiceName");
578 throw ErrorClass(
"OSResult error: setInstanceName");
580 throw ErrorClass(
"OSResult error: setVariableNumer");
581 if(
osresult->setObjectiveNumber( 1) !=
true)
582 throw ErrorClass(
"OSResult error: setObjectiveNumber");
584 throw ErrorClass(
"OSResult error: setConstraintNumber");
585 if(
osresult->setSolutionNumber( 1) !=
true)
586 throw ErrorClass(
"OSResult error: setSolutionNumer");
587 if(
osresult->setGeneralMessage( message) !=
true)
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";
590 osresult->setSolutionStatus(solIdx,
"error", solutionDescription);
591 osresult->setGeneralStatusType(
"normal");
600 if(( ci->isProvenPrimalInfeasible() ==
false) && (ci -> isProvenOptimal () ==
false)
601 && (
osinstance->getNumberOfIntegerVariables() +
osinstance->getNumberOfBinaryVariables() <= 0) )
603 std::string solutionDescription =
"";
604 std::string message =
"Success";
606 if(
osresult->setServiceName(
"Couenne solver service") !=
true)
607 throw ErrorClass(
"OSResult error: setServiceName");
609 throw ErrorClass(
"OSResult error: setInstanceName");
611 throw ErrorClass(
"OSResult error: setVariableNumer");
612 if(
osresult->setObjectiveNumber( 1) !=
true)
613 throw ErrorClass(
"OSResult error: setObjectiveNumber");
615 throw ErrorClass(
"OSResult error: setConstraintNumber");
616 if(
osresult->setSolutionNumber( 1) !=
true)
617 throw ErrorClass(
"OSResult error: setSolutionNumer");
618 if(
osresult->setGeneralMessage( message) !=
true)
619 throw ErrorClass(
"OSResult error: setGeneralMessage");
620 solutionDescription =
"CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
621 osresult->setSolutionStatus(solIdx,
"error", solutionDescription);
622 osresult->setGeneralStatusType(
"normal");
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.");
649 osresult->setGeneralStatusType(
"error");
656 catch(TNLPSolver::UnsolvedError *E)
659 E->printError(std::cerr);
665 osresult->setGeneralMessage(
"Ipopt has failed to solve a problem");
666 osresult->setGeneralStatusType(
"error");
671 catch(OsiTMINLPInterface::SimpleError &E)
673 ostringstream outStr;
674 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
676 osresult->setGeneralMessage(outStr.str());
677 osresult->setGeneralStatusType(
"error");
684 ostringstream outStr;
685 outStr << E.className() <<
"::"<< E.methodName() << std::endl << E.message() << std::endl;
687 osresult->setGeneralMessage(outStr.str());
688 osresult->setGeneralStatusType(
"error");
693 catch (Ipopt::OPTION_INVALID &E)
695 ostringstream outStr;
696 outStr <<
"Ipopt exception : " << E.Message() << std::endl;
698 osresult->setGeneralMessage(outStr.str());
699 osresult->setGeneralStatusType(
"error");
703 catch (
int generic_error)
705 if (generic_error == infeasible)
707 osresult->setGeneralMessage(
"generic error: problem infeasible");
708 osresult->setGeneralStatusType(
"error");
723 std::string solutionDescription =
"";
724 std::string message =
"Couenne solver finishes to the end.";
733 if(
osresult->setSolverInvoked(
"COIN-OR Couenne") !=
true)
734 throw ErrorClass(
"OSResult error: setSolverInvoked");
736 throw ErrorClass(
"OSResult error: setServiceName");
738 throw ErrorClass(
"OSResult error: setInstanceName");
742 throw ErrorClass(
"OSResult error: setVariableNumer");
743 if(
osresult->setObjectiveNumber( 1) !=
true)
744 throw ErrorClass(
"OSResult error: setObjectiveNumber");
746 throw ErrorClass(
"OSResult error: setConstraintNumber");
747 if(
osresult->setSolutionNumber( 1) !=
true)
748 throw ErrorClass(
"OSResult error: setSolutionNumer");
749 if(
osresult->setGeneralMessage( message) !=
true)
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.";
756 osresult->setSolutionStatus(solIdx,
"locallyOptimal", solutionDescription);
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.";
766 osresult->setSolutionStatus(solIdx,
"error", solutionDescription);
769 osresult->setObjectiveValuesDense(solIdx, z);
775 for(i=0; i <
osinstance->getVariableNumber(); i++)
777 *(x + i) =
bb.bestSolution()[i];
779 osresult->setPrimalVariableValuesDense(solIdx, x);
784 case TMINLP::LIMIT_EXCEEDED:
785 solutionDescription =
"LIMIT_EXCEEDED[COUENNE]: A resource limit was exceeded, we provide the current solution.";
786 osresult->setSolutionStatus(solIdx,
"other", solutionDescription);
790 *(z + 0) =
osinstance->calculateAllObjectiveFunctionValues(
const_cast<double*
>(
bb.model().getColSolution()),
true)[ 0];
791 osresult->setObjectiveValuesDense(solIdx, z);
796 for(i=0; i <
osinstance->getVariableNumber(); i++)
798 *(x + i) =
bb.model().getColSolution()[i];
800 osresult->setPrimalVariableValuesDense(solIdx, x);
804 case TMINLP::MINLP_ERROR:
805 solutionDescription =
"MINLP_ERROR [COUENNE]: Algorithm stopped with unspecified error.";
806 osresult->setSolutionStatus(solIdx,
"error", solutionDescription);
810 case TMINLP::CONTINUOUS_UNBOUNDED:
811 solutionDescription =
"CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
812 osresult->setSolutionStatus(solIdx,
"error", solutionDescription);
816 case TMINLP::INFEASIBLE:
817 solutionDescription =
"INFEASIBLE [COUENNE]: Problem may be infeasible.";
818 osresult->setSolutionStatus(solIdx,
"infeasible", solutionDescription);
822 solutionDescription =
"OTHER[COUENNE]: other unknown solution status from Couenne solver";
823 osresult->setSolutionStatus(solIdx,
"other", solutionDescription);
826 osresult->setGeneralStatusType(
"normal");
828 if(
osinstance->getVariableNumber() > 0)
delete[] x;
842 osresult->setGeneralStatusType(
"error");
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.
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,...
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