13 #include "CglCutGenerator.hpp"
29 using namespace Ipopt;
33 #define Couenne_large_bound2 9.99e12
49 int ind_obj = p -> Obj (0) -> Body () -> Index ();
51 if (ind_obj < 0)
return;
73 changed = (
int *) realloc (changed, ncols *
sizeof (
int));
76 for (
register int i=ncols,
j=0; i--;
j++, chg_bds++)
77 if (chg_bds -> lower() != t_chg_bounds::UNCHANGED ||
78 chg_bds -> upper() != t_chg_bounds::UNCHANGED ) {
90 t_chg_bounds *chg,
const CglTreeInfo &
info);
94 void CouenneCutGenerator::generateCuts (
const OsiSolverInterface &si,
96 const CglTreeInfo
info)
97 #if CGL_VERSION_MAJOR == 0 && CGL_VERSION_MINOR <= 57
105 int indObj = problem_ -> Obj (0) -> Body () -> Index ();
108 (si.getColLower () [indObj] > problem_ -> getCutOff () +
COUENNE_EPS)) {
119 (CoinCpuTime () > problem_ -> getMaxCpuTime ()))
122 #ifdef FM_TRACE_OPTSOL
123 double currCutOff = problem_->getCutOff();
124 double bestVal = 1e50;
129 if(currCutOff > bestVal) {
131 problem_ -> setCutOff (bestVal);
133 if ((indObj >= 0) && (si. getColUpper () [indObj] > bestVal)) {
134 OsiColCut *objCut =
new OsiColCut;
135 objCut->setUbs(1, &indObj, &bestVal);
143 if((BabPtr_ != NULL) && (info.level >= 0) && (info.pass == 0) &&
144 (BabPtr_->model().getNodeCount() > lastPrintLine)) {
152 int nInitCuts = cs.sizeRowCuts ();
155 *&realOpt = problem_ -> bestSol (),
156 *saveOptimum = realOpt;
158 if (!firstcall_ && realOpt) {
166 *sol = si.getColSolution (),
167 *lb = si.getColLower (),
168 *ub = si.getColUpper ();
170 int objind = problem_ -> Obj (0) -> Body () -> Index ();
172 for (
int j=0, i=problem_ -> nVars (); i--;
j++, opt++, lb++, ub++)
174 ((*opt < *lb -
COUENNE_EPS * (1 + CoinMin (fabs (*opt), fabs (*lb)))) ||
175 (*opt > *ub +
COUENNE_EPS * (1 + CoinMin (fabs (*opt), fabs (*ub)))))) {
178 "out of bounds, ignore x%d = %g [%g,%g] opt = %g\n",
179 problem_ -> nVars () - i - 1, *sol, *lb, *ub, *opt);
195 "generateCuts: level = %d, pass = %d, intree = %d\n",
196 info.level, info.pass, info.inTree);
201 babInfo -> setFeasibleNode ();
203 double now = CoinCpuTime ();
204 int ncols = problem_ -> nVars ();
218 problem_ -> installCutOff ();
230 for (
int i=0; i < ncols; i++)
231 if (problem_ -> Var (i) -> Multiplicity () > 0) {
232 chg_bds [i].
setLower (t_chg_bounds::CHANGED);
233 chg_bds [i].
setUpper (t_chg_bounds::CHANGED);
238 if (problem_ -> doFBBT () &&
239 (! (problem_ -> boundTightening (chg_bds, info, babInfo))))
241 "Couenne: WARNING, first convexification is infeasible\n");
247 int nnlc = problem_ -> nCons ();
249 for (
int i=0; i<nnlc; i++) {
251 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
258 int objindex = con -> Body () -> Index ();
260 if ((objindex >= 0) &&
261 ((con -> Body () -> Type () ==
AUX) ||
262 (con -> Body () -> Type () ==
VAR))) {
265 exprVar *conaux = problem_ -> Var (objindex);
268 (conaux -> Type () ==
AUX) &&
269 (conaux -> Image ()) &&
270 (conaux -> Image () -> Linearity () <=
LINEAR)) {
276 lb = (*(con -> Lb ())) (),
277 ub = (*(con -> Ub ())) ();
283 cs.insert (newBound);
324 if (cs.sizeRowCuts ()) {
325 jnlst_ -> Printf (J_ITERSUMMARY,
J_CONVEXIFYING,
"Couenne: %d constraint row cuts\n",
327 for (
int i=0; i<cs.sizeRowCuts (); i++)
328 cs.rowCutPtr (i) -> print ();
330 if (cs.sizeColCuts ()) {
331 jnlst_ -> Printf (J_ITERSUMMARY,
J_CONVEXIFYING,
"Couenne: %d constraint col cuts\n",
333 for (
int i=0; i<cs.sizeColCuts (); i++)
334 cs.colCutPtr (i) -> print ();
342 problem_ -> domain () -> push (&si, &cs);
348 double lp_bound = problem_ -> domain () ->
x (indObj);
351 {
if (lp_bound > problem_ -> Lb (indObj)) problem_ -> Lb (indObj) = lp_bound;}
359 for (
int i = problem_ -> nCons (); i--;) {
365 int objindex = con -> Body () -> Index ();
367 if ((objindex >= 0) &&
368 ((con -> Body () -> Type () ==
AUX) ||
369 (con -> Body () -> Type () ==
VAR))) {
373 l = con -> Lb () -> Value (),
374 u = con -> Ub () -> Value ();
377 problem_ -> Lb (objindex) = CoinMax (l, problem_ -> Lb (objindex));
378 problem_ -> Ub (objindex) = CoinMin (u, problem_ -> Ub (objindex));
382 problem_ -> installCutOff ();
386 int *changed = NULL, nchanged;
421 problem_ -> doRCBT () &&
422 problem_ -> redCostBT (&si, chg_bds) &&
423 !(problem_ -> btCore (chg_bds)))
427 if (problem_ -> doFBBT () &&
429 (! (problem_ -> boundTightening (chg_bds, info, babInfo))))
434 problem_ -> obbt (
this, si, cs, info, babInfo, chg_bds) < 0)
439 if ((problem_ -> doFBBT () ||
440 problem_ -> doOBBT () ||
441 problem_ -> doABT ()) &&
444 jnlst_ -> Printf(J_VECTOR,
J_CONVEXIFYING,
"== after bt =============\n");
445 for (
int i = 0; i < problem_ -> nVars (); i++)
446 if (problem_ -> Var (i) -> Multiplicity () > 0)
447 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
448 problem_ -> X (i), problem_ -> Lb (i), problem_ -> Ub (i));
449 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"=============================\n");
459 if (problem_ -> orbitalBranching () && !firstcall_) {
462 *lb = problem_ -> Lb (),
463 *ub = problem_ -> Ub ();
465 std::vector<std::vector<int> > *new_orbits = problem_ -> getNtyInfo () -> getOrbits();
467 for (
int i=0, ii = problem_ -> getNtyInfo () -> getNumOrbits (); ii--; i++){
473 std::vector <int> orbit = (*new_orbits)[i];
475 if (orbit.size () <= 1)
479 printf (
"orbit bounds: "); fflush (stdout);
480 for(
int j = 0;
j < orbit.size ();
j++) {
481 printf (
"x_%d [%g,%g] ", orbit[
j], lb [orbit [j]], ub [orbit [j]]);
486 for (
int j = 0;
j < orbit.size ();
j++) {
488 int indOrb = orbit [
j];
490 if (indOrb < problem_ -> nVars ()) {
492 if (lb [indOrb] > ll) ll = lb [indOrb];
493 if (ub [indOrb] < uu) uu = ub [indOrb];
498 " --> new common bounds: [%g,%g]\n", ll, uu);
500 for(
int j = 0;
j < orbit.size ();
j++) {
502 int indOrb = orbit [
j];
504 if (indOrb < problem_ -> nVars ()){
521 double *nlpSol = NULL;
528 nlpSol = const_cast <
double *> (babInfo -> nlpSolution ());
532 int logAbtLev = problem_ -> logAbtLev ();
534 if (problem_ -> doABT () &&
536 (info.level == 0)) &&
539 (info.level <= logAbtLev) ||
541 pow (2., (
double) logAbtLev - (info.level + 1))))) {
544 if (! (problem_ -> aggressiveBT (nlp_, chg_bds, info, babInfo)))
557 bool save_av = addviolated_;
558 addviolated_ =
false;
561 problem_ -> domain () -> push
562 (problem_ -> nVars (),
563 problem_ -> domain () ->
x (),
564 problem_ -> domain () -> lb (),
565 problem_ -> domain () -> ub (),
false);
569 CoinCopyN (nlpSol, problem_ -> nOrigVars (), problem_ -> domain () ->
x ());
572 problem_ -> getAuxs (problem_ -> domain () ->
x ());
576 jnlst_ -> Printf(J_VECTOR,
J_CONVEXIFYING,
"== genrowcuts on NLP =============\n");
577 for (
int i = 0; i < problem_ -> nVars (); i++)
578 if (problem_ -> Var (i) -> Multiplicity () > 0)
579 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
583 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"=============================\n");
586 problem_ -> domain () -> current () -> isNlp () =
true;
587 genRowCuts (si, cs, nchanged, changed, chg_bds);
589 problem_ -> domain () -> pop ();
591 addviolated_ = save_av;
595 babInfo -> setHasNlpSolution (
false);
600 jnlst_ -> Printf(J_VECTOR,
J_CONVEXIFYING,
"== genrowcuts on LP =============\n");
601 for (
int i = 0; i < problem_ -> nVars (); i++)
602 if (problem_ -> Var (i) -> Multiplicity () > 0)
603 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
607 jnlst_->Printf(J_VECTOR,
J_CONVEXIFYING,
"=============================\n");
610 genRowCuts (si, cs, nchanged, changed, chg_bds);
615 genColCuts (si, cs, nchanged, changed);
617 if (firstcall_ && (cs.sizeRowCuts () >= 1))
619 "Couenne: %d initial row cuts\n", cs.sizeRowCuts ());
624 "Warning: Optimal solution was cut\n");
627 catch (
int exception) {
629 if ((exception == infeasible) && (!firstcall_)) {
632 "Couenne: Infeasible node\n");
638 babInfo -> setInfeasibleNode ();
649 "Couenne: %d cuts (%d row, %d col) for linearization\n",
650 cs.sizeRowCuts () + cs.sizeColCuts (),
651 cs.sizeRowCuts (), cs.sizeColCuts ());
655 ntotalcuts_ = nrootcuts_ = cs.sizeRowCuts ();
659 problem_ -> domain () -> pop ();
661 ntotalcuts_ += (cs.sizeRowCuts () - nInitCuts);
664 realOpt = saveOptimum;
667 septime_ += CoinCpuTime () - now;
671 if (cs.sizeColCuts ()) {
672 jnlst_ -> Printf (J_ITERSUMMARY,
J_CONVEXIFYING,
"Couenne col cuts:\n");
673 for (
int i=0; i<cs.sizeColCuts (); i++)
674 cs.colCutPtr (i) -> print ();
679 rootTime_ = CoinCpuTime ();
void updateBranchInfo(const OsiSolverInterface &si, CouenneProblem *p, t_chg_bounds *chg, const CglTreeInfo &info)
get new bounds from parents' bounds + branching rules
bool isWiped(OsiCuts &cs)
Check whether the previous cut generators have added an infeasible cut.
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
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void setLower(ChangeStatus lower)
void sparse2dense(int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged)
translate sparse to dense vector (should be replaced)
CouNumber & Lb(int i) const
lower bound on
const Ipopt::EJournalCategory J_CONVEXIFYING(Ipopt::J_USER3)
void setUpper(ChangeStatus upper)
Class to represent nonlinear constraints.
const Ipopt::EJournalCategory J_BOUNDTIGHTENING(Ipopt::J_USER2)
Class for MINLP problems with symbolic information.
bool isOptimumCut(const CouNumber *opt, OsiCuts &cs, CouenneProblem *p)
#define Couenne_large_bound2
static const int infeasible
double CouNumber
main number type in Couenne
void fictitiousBound(OsiCuts &cs, CouenneProblem *p, bool action)
void WipeMakeInfeas(OsiCuts &cs)
Add a fictitious cut 1<= x_0 <= -1 as a signal to the node solver that this node is deemed infeasible...
Bonmin class for passing info between components of branch-and-cuts.
void fint fint fint real fint real * x