17 #include "CoinHelperFunctions.hpp"
24 using namespace Ipopt;
25 using namespace Couenne;
28 class OsiTMINLPInterface;
33 #define MAX_ABT_ITER 4 // max # aggressive BT iterations
34 #define THRES_ABT_IMPROVED 0 // only continue ABT if at least these bounds have improved
35 #define THRES_ABT_ORIG 100 // only do ABT on auxiliaries if they are less originals than this
38 register const double* xOrig,
39 register const double* lower,
40 register const double* upper,
41 register double cutoff_distance) {
43 register double Xdist = 0.;
45 for (; n--; ++upper, ++xOrig) {
49 if ( diff > 0.) {
if ((Xdist += diff) > cutoff_distance)
break;}
50 else if ((diff = *xOrig - *upper) > 0.) {
if ((Xdist += diff) > cutoff_distance)
break;}
64 const CglTreeInfo &
info,
67 if (info.level <= 0 && !(info.inTree)) {
68 jnlst_ -> Printf (J_ERROR,
J_COUENNE,
"Probing: ");
79 *olb = CoinCopyOfArray (Lb (), ncols),
80 *oub = CoinCopyOfArray (Ub (), ncols);
89 const std::list<SmartPtr<const CouenneInfo::NlpSolution> >& solList =
94 i != solList.end(); ++i) {
96 assert (nOrigVars_ - ndefined_ == (*i)->nVars());
98 const double thisDist =
distanceToBound (nOrigVars_ - ndefined_, (*i)->solution(), olb, oub, dist);
100 if (thisDist < dist) {
109 bool haveNLPsol =
false;
116 int nvars = nVars ();
118 double *lower =
new double [nvars];
119 double *upper =
new double [nvars];
124 CoinCopyN (nlp -> getColLower (), nOrigVars_ - ndefined_, lower);
125 CoinCopyN (nlp -> getColUpper (), nOrigVars_ - ndefined_, upper);
127 double *Y =
new double [nvars];
129 CoinZeroN (Y, nvars);
130 CoinCopyN (X (), nOrigVars_ - ndefined_, Y);
132 if (getIntegerCandidate (nlp -> getColSolution () ? nlp -> getColSolution () : X (), Y, lower, upper) < 0) {
134 jnlst_ -> Printf (J_ITERSUMMARY,
J_BOUNDTIGHTENING,
"TODO: find NLP point in ABT failed\n");
141 nlp -> setColLower (lower);
142 nlp -> setColUpper (upper);
143 nlp -> setColSolution (Y);
147 nlp -> options () -> SetNumericValue (
"max_cpu_time", CoinMax (0.1, getMaxCpuTime () - CoinCpuTime ()));
148 nlp -> initialSolve ();
157 if (nlp -> isProvenOptimal ()) {
168 jnlst_ -> Printf(J_ITERSUMMARY,
J_BOUNDTIGHTENING,
"TODO: NLP solve in ABT failed\n");
174 int nTotImproved = 0;
191 X =
new double [ncols];
192 CoinZeroN (X, nVars ());
193 CoinCopyN (closestSol -> solution(), nOrigVars_ - ndefined_, X);
195 }
else X = domain () ->
x ();
201 int objind = Obj (0) -> Body () -> Index ();
202 for (
int i=0; i<nOrigVars_ - ndefined_; i++) Jnlst()->Printf(J_MOREVECTOR,
J_BOUNDTIGHTENING,
" %2d %+20g [%+20g %+20g]\n",i, X [i], Lb (i), Ub (i));
203 if (objind >= 0) Jnlst()->Printf(J_ITERSUMMARY,
J_BOUNDTIGHTENING,
"-------------\nAggressive BT. Current bound = %g, cutoff = %g, %d vars\n", Lb (objind), getCutOff (), ncols);
206 int improved, second, iter = 0;
216 bool maxTimeReached =
false;
223 for (
int i=0; i<ncols; i++) {
225 if (CoinCpuTime () > maxCpuTime_) {
226 maxTimeReached =
true;
230 int index = evalOrder (i);
232 if ((Var (index) -> Multiplicity () <= 0) ||
235 (index >= nOrigVars_)))
254 if ((variables_ [index] -> sign () != expression::AUX_GEQ) &&
257 Jnlst()->Printf(J_DETAILED,
J_BOUNDTIGHTENING,
"------------- tighten left %d-th = x%d @%g [%g,%g]\n", i, index, X [index], olb [index], oub [index]);
260 if ((improved = fake_tighten (0, index, X, olb, oub, chg_bds, f_chg)) < 0) {
269 if (retval && (variables_ [index] -> sign () != expression::AUX_LEQ) &&
272 Jnlst()->Printf(J_DETAILED,
J_BOUNDTIGHTENING,
"------------- tighten right %d-th = x%d @%g [%g,%g]\n", i, index, X [index], olb [index], oub [index]);
275 if ((second = fake_tighten (1, index, X, olb, oub, chg_bds, f_chg) < 0)) {
283 nTotImproved += improved;
290 CoinCopyN (olb, ncols, Lb ());
291 CoinCopyN (oub, ncols, Ub ());
296 if (!retval) Jnlst()->Printf(J_ITERSUMMARY,
J_BOUNDTIGHTENING,
"Couenne infeasible node from aggressive BT\n");
298 int objind = Obj (0) -> Body () -> Index ();
300 if (objind >= 0)Jnlst()->Printf(J_ITERSUMMARY,
J_BOUNDTIGHTENING,
"-------------\ndone Aggressive BT. Current bound = %g, cutoff = %g, %d vars\n", Lb (objind), getCutOff (), ncols);
301 if (Jnlst()->ProduceOutput(J_DETAILED,
J_BOUNDTIGHTENING))
for (
int i=0; i<nOrigVars_; i++) printf (
" x%02d [%+20g %+20g] | %+20g\n", i, Lb (i), Ub (i), X [i]);
302 if (Jnlst()->ProduceOutput(J_MOREDETAILED,
J_BOUNDTIGHTENING))
for (
int i=nOrigVars_; i<ncols; i++) printf (
" w%02d [%+20g %+20g] | %+20g\n", i, Lb (i), Ub (i), X [i]);
316 if (info.level <= 0 && !(info.inTree)) {
317 if (!retval) jnlst_ -> Printf (J_ERROR,
J_COUENNE,
"infeasible\n");
318 else jnlst_ -> Printf (J_ERROR,
J_COUENNE,
"%d improved bounds\n", nTotImproved);
static Bigint * diff(Bigint *a, Bigint *b)
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
Class for storing an Nlp Solution.
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
static double distanceToBound(register int n, register const double *xOrig, register const double *lower, register const double *upper, register double cutoff_distance)
virtual double getObjValue() const
Get objective function value (can't use default)
virtual const double * getColSolution() const
Get pointer to array[getNumCols()] of primal solution vector.
Bonmin class for passing info between components of branch-and-cuts.
const std::list< Ipopt::SmartPtr< const NlpSolution > > & NlpSolutions() const
List of all stored NLP solutions.
void addSolution(Ipopt::SmartPtr< const NlpSolution > newSol)
Add a new NLP solution.
const Ipopt::EJournalCategory J_BOUNDTIGHTENING(Ipopt::J_USER2)
double CouNumber
main number type in Couenne
#define THRES_ABT_IMPROVED
We will throw this error when a problem is not solved.
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
Bonmin class for passing info between components of branch-and-cuts.
void fint fint fint real fint real * x