14 #include "CoinHelperFunctions.hpp"
21 using namespace Couenne;
26 have_nlp_solution_ (false)
32 have_nlp_solution_ (false)
44 #ifdef COUENNEINTERFACE_FROM_ASL
51 AmplInterface::readAmplNlFile(argv, roptions, options, journalist);
73 options () -> GetIntegerValue (
"nlp_log_level", nlpLogLevel,
"couenne.");
74 messageHandler () -> setLogLevel (nlpLogLevel);
78 bool is_feasible =
true;
82 int nvars = p -> nVars();
89 for (
int i=0; i < p -> nCons (); i++) {
95 int index = con -> Body () -> Index ();
97 if ((index >= 0) && (con -> Body () -> Type () ==
AUX)) {
101 l = con -> Lb () -> Value (),
102 u = con -> Ub () -> Value ();
105 p -> Lb (index) = CoinMax (l, p -> Lb (index));
106 p -> Ub (index) = CoinMin (u, p -> Ub (index));
112 for (
int i=0; i<nvars; i++) {
117 if (!(p -> boundTightening (chg_bds, CglTreeInfo (), NULL))) {
125 *nlb = getColLower (),
126 *nub = getColUpper ();
128 for (
int i=0; i < p -> nOrigVars () - p -> nDefVars (); i++)
129 if (p -> Var (i) -> Multiplicity () > 0) {
138 if (lower > upper) CoinSwap (lower, upper);
139 if (p -> Lb (i) > p -> Ub (i)) CoinSwap (p -> Lb (i), p -> Ub (i));
141 if (lower < p -> Lb (i) -
COUENNE_EPS) setColLower (i, CoinMin (nub[i], p -> Lb (i)));
142 if (upper > p -> Ub (i) +
COUENNE_EPS) setColUpper (i, CoinMax (nlb[i], p -> Ub (i)));
146 setColLower (i, -COIN_DBL_MAX);
147 setColUpper (i, COIN_DBL_MAX);
153 options () -> SetNumericValue (
"max_cpu_time", CoinMax (0.1, (p -> getMaxCpuTime () - CoinCpuTime ()) / 2));
157 if (isDualObjectiveLimitReached() &&
158 (getNumIntegers () == 0))
159 *messageHandler () <<
"Couenne: Warning, NLP is unbounded" << CoinMessageEol;
168 OsiAuxInfo * auxInfo = si.getAuxiliaryInfo ();
172 babInfo -> setInfeasibleNode ();
175 if (is_feasible && isProvenOptimal ()) {
178 const CouNumber *solution = getColSolution ();
180 if (getNumIntegers () > 0) {
183 norig = p -> nOrigVars () - p -> nDefVars (),
184 nvars = p -> nVars ();
186 bool fractional =
false;
191 for (
int i=0; i<norig; i++)
192 if ((p -> Var (i) -> Multiplicity () > 0) &&
193 p -> Var (i) -> isDefinedInteger () &&
202 *lbSave =
new double [norig],
203 *ubSave =
new double [norig],
205 *lbCur =
new double [nvars],
206 *ubCur =
new double [nvars],
208 *Y =
new double [nvars];
210 CoinCopyN (getColLower (), norig, lbSave);
211 CoinCopyN (getColUpper (), norig, ubSave);
213 CoinFillN (Y, nvars, 0.);
217 CoinCopyN (getColLower (), norig, lbCur);
218 CoinCopyN (getColUpper (), norig, ubCur);
220 if (p -> getIntegerCandidate (solution, Y, lbCur, ubCur) >= 0) {
222 for (
int i = getNumCols (); i--;) {
224 if (lbCur [i] > ubCur [i])
225 CoinSwap (lbCur [i], ubCur [i]);
227 if (Y [i] < lbCur [i]) Y [i] = lbCur [i];
228 else if (Y [i] > ubCur [i]) Y [i] = ubCur [i];
231 for (
int i=0; i<norig; i++)
232 if ((p -> Var (i) -> Multiplicity () > 0) &&
233 p -> Var (i) -> isDefinedInteger ()) {
235 setColLower (i, lbCur [i]);
236 setColUpper (i, ubCur [i]);
242 options () -> SetNumericValue (
"max_cpu_time", CoinMax (0.1, p -> getMaxCpuTime () - CoinCpuTime ()));
246 if (isDualObjectiveLimitReached() &&
247 (getNumIntegers () == 0))
248 *messageHandler () <<
"Couenne: Warning, NLP is is unbounded" << CoinMessageEol;
255 obj = getObjValue ();
256 solution = getColSolution ();
259 for (
int i=0; i<norig; i++)
260 if ((p -> Var (i) -> Multiplicity () > 0) &&
261 p -> Var (i) -> isDefinedInteger ()) {
263 if (lbSave [i] > ubSave [i])
264 CoinSwap (lbSave [i], ubSave [i]);
266 setColLower (i, lbSave [i]);
267 setColUpper (i, ubSave [i]);
280 if (isProvenOptimal () &&
287 p -> checkNLP (solution, obj,
true) &&
288 (obj < p -> getCutOff ())
293 have_nlp_solution_ =
true;
301 p -> setCutOff (obj, solution);
303 OsiAuxInfo * auxInfo = si.getAuxiliaryInfo ();
312 babInfo -> setNlpSolution (solution, getNumCols (), obj);
314 babInfo -> setHasNlpSolution (
true);
317 #ifdef FM_TRACE_OPTSOL
337 numcols = p -> nOrigVars (),
338 numcolsconv = p -> nVars ();
345 for (
int i=0; i<numcols; i++)
346 if (p -> Var (i) -> Multiplicity () > 0) si.addCol (0, NULL,NULL, lb [i], ub [i], 0);
347 else si.addCol (0, NULL,NULL, -COIN_DBL_MAX,COIN_DBL_MAX,0);
348 for (
int i=numcols; i<numcolsconv; i++) si.addCol (0, NULL,NULL, -COIN_DBL_MAX,COIN_DBL_MAX,0);
362 for (
int i = numcolsconv; i--;)
363 if (p -> Var (i) -> Multiplicity () > 0) {
367 colLower [i] = -COIN_DBL_MAX;
368 colUpper [i] = COIN_DBL_MAX;
371 int numrowsconv = cs.sizeRowCuts ();
374 CoinBigIndex * start =
new CoinBigIndex [numrowsconv + 1];
376 int * length =
new int [numrowsconv];
377 double * rowLower =
new double [numrowsconv];
378 double * rowUpper =
new double [numrowsconv];
383 for(
int i = 0 ; i < numrowsconv ; i++)
385 OsiRowCut * cut = cs.rowCutPtr (i);
387 const CoinPackedVector &v = cut->row();
388 start[i+1] = start[i] + v.getNumElements();
389 nnz += v.getNumElements();
390 length[i] = v.getNumElements();
392 rowLower[i] = cut->lb();
393 rowUpper[i] = cut->ub();
396 assert (nnz == start [numrowsconv]);
398 int * ind =
new int[start[numrowsconv]];
399 double * elem =
new double[start[numrowsconv]];
400 for(
int i = 0 ; i < numrowsconv ; i++) {
402 OsiRowCut * cut = cs.rowCutPtr (i);
404 const CoinPackedVector &v = cut->row();
406 if(v.getNumElements() != length[i])
407 std::cout<<
"Empty row"<<std::endl;
409 CoinCopyN (v.getIndices(), length[i], ind + start[i]);
410 CoinCopyN (v.getElements(), length[i], elem + start[i]);
415 A.assignMatrix(
false, numcolsconv, numrowsconv,
416 start[numrowsconv], elem, ind,
418 if(A.getNumCols() != numcolsconv || A.getNumRows() != numrowsconv){
419 std::cout<<
"Error in row number"<<std::endl;
421 assert(A.getNumElements() ==
nnz);
423 double * obj =
new double[numcolsconv];
424 CoinFillN(obj,numcolsconv,0.);
427 if (p -> nObjs () > 0)
428 p -> fillObjCoeff (obj);
431 si.loadProblem (A, colLower, colUpper, obj, rowLower, rowUpper);
439 for (
int i=0; i<numcolsconv; i++)
440 if ((p -> Var (i) -> Multiplicity () > 0) &&
441 (p -> Var (i) -> isDefinedInteger ()))
446 app_ -> enableWarmStart();
449 if (problem () -> x_sol ()) {
450 setColSolution (problem () -> x_sol ());
451 setRowPrice (problem () -> duals_sol ());
458 Options->SetStringValue(
"bonmin.algorithm",
"B-Couenne",
true,
true);
459 Options->SetIntegerValue(
"bonmin.filmint_ecp_cuts", 1,
true,
true);
Cut Generator for linear convexifications.
void update(const double *givenSol, const int givenCard, const double givenVal, const double givenMaxViol)
virtual CouenneInterface * clone(bool CopyData)
virutal copy constructor.
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void setLower(ChangeStatus lower)
CouenneInterface()
Default constructor.
bool checkNLP2(const double *solution, const double obj, const bool careAboutObj, const bool stopAtFirstViol, const bool checkAll, const double precision) const
Return true if either solution or recomputed_solution obtained using getAuxs() from the original vari...
CouenneProblem * Problem() const
return pointer to symbolic problem
CouNumber getCutOff() const
Get cutoff.
void setUpper(ChangeStatus upper)
Class to represent nonlinear constraints.
CouenneRecordBestSol * getRecordBestSol() const
returns recorded best solution
virtual void setAppDefaultOptions(Ipopt::SmartPtr< Ipopt::OptionsList > Options)
To set some application specific defaults.
virtual void readAmplNlFile(char **&argv, Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions, Ipopt::SmartPtr< Ipopt::OptionsList > options, Ipopt::SmartPtr< Ipopt::Journalist > journalist, std::string *nl_file_content=NULL)
Class for MINLP problems with symbolic information.
double getModSolVal() const
virtual ~CouenneInterface()
Destructor.
double CouNumber
main number type in Couenne
virtual void extractLinearRelaxation(OsiSolverInterface &si, CouenneCutGenerator &couenneCg, bool getObj=1, bool solveNlp=1)
Extract a linear relaxation of the MINLP.
We will throw this error when a problem is not solved.
double getFeasTol()
returns feasibility tolerance
int nnz
ATTENTION: Filter expect the jacobian to be ordered by row.
void generateCuts(const OsiSolverInterface &, OsiCuts &, const CglTreeInfo=CglTreeInfo()) const
the main CglCutGenerator
Bonmin class for passing info between components of branch-and-cuts.
bool isInteger(CouNumber x)
is this number integer?