source: stable/0.4/Couenne/src/convex/generateCuts.cpp @ 946

Last change on this file since 946 was 946, checked in by stefan, 8 years ago

merge r945 from trunk: allow compiling against Cgl 0.58

  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 KB
Line 
1/* $Id: generateCuts.cpp 946 2013-04-15 22:20:38Z stefan $
2 *
3 * Name:    generateCuts.cpp
4 * Author:  Pietro Belotti
5 * Purpose: the generateCuts() method of the convexification class CouenneCutGenerator
6 *
7 * (C) Carnegie-Mellon University, 2006-11.
8 * This file is licensed under the Eclipse Public License (EPL)
9 */
10
11#include "BonCbc.hpp"
12#include "BonBabInfos.hpp"
13#include "CglCutGenerator.hpp"
14
15#include "CouenneCutGenerator.hpp"
16#include "CouenneProblem.hpp"
17#include "CouenneProblemElem.hpp"
18#include "CouenneExprVar.hpp"
19#include "CouenneInfeasCut.hpp"
20
21#include "CouenneRecordBestSol.hpp"
22
23#ifdef COIN_HAS_NTY
24#include "Nauty.h"
25#endif
26
27using namespace Ipopt;
28
29namespace Couenne {
30
31#define Couenne_large_bound2 9.99e12
32
33// checks bad cuts against known optimum
34bool isOptimumCut (const CouNumber *opt, OsiCuts &cs, CouenneProblem *p);
35
36// set and lift bound for auxiliary variable associated with objective
37// function
38void fictitiousBound (OsiCuts &cs,
39                      CouenneProblem *p, 
40                      bool action) {     // true before convexifying, false afterwards
41
42  // fictitious bound for initial unbounded lp relaxations
43  const CouNumber large_tol = (Couenne_large_bound2 / 1e6);
44
45  // set trivial dual bound to objective function, if there is none
46
47  int ind_obj = p -> Obj (0) -> Body () -> Index ();
48
49  if (ind_obj < 0) return;
50
51  // we have a single variable objective function
52
53  //int sense = -1; //(p -> Obj (0) -> Sense () == MINIMIZE) ? -1 : 1;
54
55  if (action)
56    //if (sense<0)
57      {if (p -> Lb (ind_obj) < - Couenne_large_bound2) p -> Lb (ind_obj) = - Couenne_large_bound2;}
58  //else         {if (p -> Ub (ind_obj) >   large_bound2) p -> Ub (ind_obj) =   large_bound2;}
59  else
60    //if (sense>0) {if (fabs (p->Ub(ind_obj)-large_bound2)<large_tol) p->Ub(ind_obj)=COUENNE_INFINITY;}
61    //else         
62      {if (fabs (p->Lb(ind_obj)+Couenne_large_bound2)<large_tol) p->Lb(ind_obj) =-COUENNE_INFINITY;}
63}
64
65
66// translate changed bound sparse array into a dense one
67void sparse2dense (int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged) {
68
69  // convert sparse chg_bds in something handier
70
71  changed  = (int *) realloc (changed, ncols * sizeof (int));
72  nchanged = 0;
73
74  for (register int i=ncols, j=0; i--; j++, chg_bds++)
75    if (chg_bds -> lower() != t_chg_bounds::UNCHANGED ||
76        chg_bds -> upper() != t_chg_bounds::UNCHANGED ) {
77      *changed++ = j;
78      nchanged++;
79    }
80
81  changed -= nchanged;
82  //changed = (int *) realloc (changed, nchanged * sizeof (int));
83}
84
85
86/// get new bounds from parents' bounds + branching rules
87void updateBranchInfo (const OsiSolverInterface &si, CouenneProblem *p, 
88                       t_chg_bounds *chg, const CglTreeInfo &info);
89
90/// a convexifier cut generator
91
92void CouenneCutGenerator::generateCuts (const OsiSolverInterface &si,
93                                        OsiCuts &cs, 
94                                        const CglTreeInfo info)
95#if CGL_VERSION_MAJOR == 0 && CGL_VERSION_MINOR <= 57
96  const
97#endif
98  {
99
100  // check if out of time or if an infeasibility cut (iis of type 0)
101  // was added as a result of, e.g., pruning on BT. If so, no need to
102  // run this.
103
104  if (isWiped (cs) || 
105     (CoinCpuTime () > problem_ -> getMaxCpuTime ()))
106    return;
107
108#ifdef FM_TRACE_OPTSOL
109  double currCutOff = problem_->getCutOff();
110  double bestVal = 1e50;
111  CouenneRecordBestSol *rs = problem_->getRecordBestSol();
112  if(rs->getHasSol()) {
113    bestVal = rs->getVal(); 
114  }
115  if(currCutOff > bestVal) {
116    //problem_ -> setCutOff (bestVal - 1e-6); // FIXME: don't add numerical constants
117    problem_ -> setCutOff (bestVal);
118
119    int indObj = problem_->Obj(0)->Body()->Index();
120
121    if (indObj >= 0) {
122      OsiColCut *objCut = new OsiColCut;
123      objCut->setUbs(1, &indObj, &bestVal);
124      cs.insert(objCut);
125      delete objCut;
126    }
127  }
128#endif
129
130#ifdef FM_PRINT_INFO
131  if((BabPtr_ != NULL) && (info.level >= 0) && (info.pass == 0) && 
132     (BabPtr_->model().getNodeCount() > lastPrintLine)) {
133    printLineInfo();
134    lastPrintLine += 1;
135  }
136#endif
137
138  const int infeasible = 1;
139
140  int nInitCuts = cs.sizeRowCuts ();
141
142  CouNumber
143    *&realOpt = problem_ -> bestSol (),
144    *saveOptimum = realOpt;
145
146  if (!firstcall_ && realOpt) { 
147
148    // have a debug optimal solution. Check if current bounds
149    // contain it, otherwise pretend it does not exist
150
151    CouNumber *opt = realOpt;
152
153    const CouNumber
154      *sol = si.getColSolution (),
155      *lb  = si.getColLower (),
156      *ub  = si.getColUpper ();
157
158    int objind = problem_ -> Obj (0) -> Body () -> Index ();
159
160    for (int j=0, i=problem_ -> nVars (); i--; j++, opt++, lb++, ub++)
161      if ((j != objind) && 
162          ((*opt < *lb - COUENNE_EPS * (1 + CoinMin (fabs (*opt), fabs (*lb)))) || 
163           (*opt > *ub + COUENNE_EPS * (1 + CoinMin (fabs (*opt), fabs (*ub)))))) {
164       
165        jnlst_ -> Printf (J_VECTOR, J_CONVEXIFYING, 
166                          "out of bounds, ignore x%d = %g [%g,%g] opt = %g\n", 
167                          problem_ -> nVars () - i - 1, *sol, *lb, *ub, *opt);
168
169        // optimal point is not in current bounding box,
170        // pretend realOpt is NULL until we return from this procedure
171        realOpt = NULL;
172        break;
173      }
174  }
175
176  /*static int count = 0;
177  char fname [20];
178  sprintf (fname, "relax_%d", count++);
179  si.writeLp (fname);
180  printf ("writing %s\n", fname);*/
181
182  jnlst_ -> Printf (J_DETAILED, J_CONVEXIFYING,
183                    "generateCuts: level = %d, pass = %d, intree = %d\n",
184                    info.level, info.pass, info.inTree);
185
186  Bonmin::BabInfo * babInfo = dynamic_cast <Bonmin::BabInfo *> (si.getAuxiliaryInfo ());
187
188  if (babInfo)
189    babInfo -> setFeasibleNode ();
190
191  double now   = CoinCpuTime ();
192  int    ncols = problem_ -> nVars ();
193
194  // This vector contains variables whose bounds have changed due to
195  // branching, reduced cost fixing, or bound tightening below. To be
196  // used with malloc/realloc/free
197
198  t_chg_bounds *chg_bds = new t_chg_bounds [ncols];
199
200  /*for (int i=0; i < ncols; i++)
201    if (problem_ -> Var (i) -> Multiplicity () <= 0) {
202      chg_bds [i].setLower (t_chg_bounds::UNCHANGED);
203      chg_bds [i].setUpper (t_chg_bounds::UNCHANGED);
204      }*/
205
206  problem_ -> installCutOff (); // install upper bound
207
208  if (firstcall_) {
209
210    // First convexification //////////////////////////////////////
211
212    // OsiSolverInterface is empty yet, no information can be obtained
213    // on variables or bounds -- and none is needed since our
214    // constructor populated *problem_ with variables and bounds. We
215    // only need to update the auxiliary variables and bounds with
216    // their current value.
217
218    for (int i=0; i < ncols; i++) 
219      if (problem_ -> Var (i) -> Multiplicity () > 0) {
220        chg_bds [i].setLower (t_chg_bounds::CHANGED);
221        chg_bds [i].setUpper (t_chg_bounds::CHANGED);
222      }
223
224    // start with FBBT, should take advantage of cutoff found by NLP
225    // run AFTER initial FBBT...
226    if (problem_ -> doFBBT () &&
227        (! (problem_ -> boundTightening (chg_bds, babInfo))))
228          jnlst_ -> Printf (J_STRONGWARNING, J_CONVEXIFYING,
229            "Couenne: WARNING, first convexification is infeasible\n");
230
231    // For each auxiliary variable replacing the original (nonlinear)
232    // constraints, check if corresponding bounds are violated, and
233    // add cut to cs
234
235    int nnlc = problem_ -> nCons ();
236
237    for (int i=0; i<nnlc; i++) {
238
239      if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
240        break;
241
242      // for each constraint
243      CouenneConstraint *con = problem_ -> Con (i);
244
245      // (which has an aux as its body)
246      int objindex = con -> Body () -> Index ();
247
248      if ((objindex >= 0) && 
249          ((con -> Body () -> Type () == AUX) ||
250           (con -> Body () -> Type () == VAR))) {
251
252        // get the auxiliary that is at the lhs
253        exprVar *conaux = problem_ -> Var (objindex);
254
255        if (conaux &&
256            (conaux -> Type () == AUX) &&
257            (conaux -> Image ()) && 
258            (conaux -> Image () -> Linearity () <= LINEAR)) {
259
260          // reduce density of problem by adding w >= l rather than
261          // ax + b >= l for any linear auxiliary defined as w := ax+b
262
263          double 
264            lb = (*(con -> Lb ())) (), 
265            ub = (*(con -> Ub ())) ();
266
267          OsiColCut newBound;
268          if (lb > -COUENNE_INFINITY) newBound.setLbs (1, &objindex, &lb);
269          if (ub <  COUENNE_INFINITY) newBound.setUbs (1, &objindex, &ub);
270
271          cs.insert (newBound);
272
273          // the auxiliary w of constraint w <= b is associated with a
274          // linear expression w = ax: add constraint ax <= b
275          /*conaux -> Image () -> generateCuts (conaux, si, cs, this, chg_bds,
276                                              conaux -> Index (),
277                                              (*(con -> Lb ())) (),
278                                              (*(con -> Ub ())) ());*/
279
280          // take it from the list of the variables to be linearized
281          //
282          // DO NOT decrease multiplicity. Even if it is a linear
283          // term, its bounds can still be used in implied bounds
284          //
285          // Are we sure? That will happen only if its multiplicity is
286          // nonzero, for otherwise this aux is only used here, and is
287          // useless elsewhere
288          //
289          //conaux -> decreaseMult (); // !!!
290        }
291
292        // also, add constraint w <= b
293
294        // not now, do it later
295
296//      // if there exists violation, add constraint
297//      CouNumber l = con -> Lb () -> Value (),
298//                u = con -> Ub () -> Value ();
299
300//      // tighten bounds in Couenne's problem representation
301//      problem_ -> Lb (index) = CoinMax (l, problem_ -> Lb (index));
302//      problem_ -> Ub (index) = CoinMin (u, problem_ -> Ub (index));
303
304      } else { // body is more than just a variable, but it should be
305               // linear. If so, generate equivalent linear cut
306
307        assert (false); // TODO
308      }
309    }
310
311    if (jnlst_ -> ProduceOutput (J_ITERSUMMARY, J_CONVEXIFYING)) {
312      if (cs.sizeRowCuts ()) {
313        jnlst_ -> Printf (J_ITERSUMMARY, J_CONVEXIFYING,"Couenne: %d constraint row cuts\n",
314                          cs.sizeRowCuts ());
315        for (int i=0; i<cs.sizeRowCuts (); i++) 
316          cs.rowCutPtr (i) -> print ();
317      }
318      if (cs.sizeColCuts ()) {
319        jnlst_ -> Printf (J_ITERSUMMARY, J_CONVEXIFYING,"Couenne: %d constraint col cuts\n",
320                          cs.sizeColCuts ());
321        for (int i=0; i<cs.sizeColCuts (); i++) 
322          cs.colCutPtr (i) -> print ();
323      }
324    }
325  } else {
326
327    // use new optimum as lower bound for variable associated w/objective
328    int indobj = problem_ -> Obj (0) -> Body () -> Index ();
329
330    // transmit solution from OsiSolverInterface to problem
331    problem_ -> domain () -> push (&si, &cs);
332
333    if (indobj >= 0) {
334
335      // Use current value of objvalue's x as a lower bound for bound
336      // tightening
337      double lp_bound = problem_ -> domain () -> x (indobj);
338
339      //if (problem_ -> Obj (0) -> Sense () == MINIMIZE)
340      {if (lp_bound > problem_ -> Lb (indobj)) problem_ -> Lb (indobj) = lp_bound;}
341           //else {if (lp_bound < problem_ -> Ub (indobj)) problem_ -> Ub (indobj) = lp_bound;}
342    }
343
344    updateBranchInfo (si, problem_, chg_bds, info); // info.depth >= 0 || info.pass >= 0
345  }
346
347  // restore constraint bounds before tightening and cut generation
348  for (int i = problem_ -> nCons (); i--;) {
349
350    // for each constraint
351    CouenneConstraint *con = problem_ -> Con (i);
352
353    // (which has an aux as its body)
354    int objindex = con -> Body () -> Index ();
355
356    if ((objindex >= 0) && 
357        ((con -> Body () -> Type () == AUX) ||
358         (con -> Body () -> Type () == VAR))) {
359
360      // if there exists violation, add constraint
361      CouNumber
362        l = con -> Lb () -> Value (),   
363        u = con -> Ub () -> Value ();
364
365      // tighten bounds in Couenne's problem representation
366      problem_ -> Lb (objindex) = CoinMax (l, problem_ -> Lb (objindex));
367      problem_ -> Ub (objindex) = CoinMin (u, problem_ -> Ub (objindex));
368    }
369  }
370
371  problem_ -> installCutOff (); // install upper bound
372
373  fictitiousBound (cs, problem_, false); // install finite lower bound, if currently -inf
374
375  int *changed = NULL, nchanged;
376
377  // Bound tightening ///////////////////////////////////////////
378
379  // do bound tightening only at first pass of cutting plane in a node
380  // of BB tree (info.pass == 0) or if first call (creation of RLT,
381  // info.pass == -1)
382
383  try {
384
385    // Before bound tightening, compute symmetry group. After bound
386    // tightening is done, we can apply further tightening using orbit
387    // information.
388
389#ifdef COIN_HAS_NTY
390    //    ChangeBounds (psi -> getColLower (), 
391    //            psi -> getColUpper (),
392    //            psi -> getNumCols ());
393    if (problem_ -> orbitalBranching ())
394      problem_ -> Compute_Symmetry ();
395#endif
396
397    // Bound tightening ////////////////////////////////////
398
399    /*printf ("== BT ================\n");
400      for (int i = 0; i < problem_ -> nVars (); i++)
401      if (problem_ -> Var (i) -> Multiplicity () > 0)
402      printf ("%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
403      problem_ -> X  (i), problem_ -> Lb (i), problem_ -> Ub (i));
404      printf("=============================\n");*/
405
406    // Reduced Cost BT -- to be done first to use rcost correctly
407    if (!firstcall_  &&                         // have a linearization already
408        problem_ -> doRCBT () &&                // authorized to do reduced cost tightening
409        problem_ -> redCostBT (&si, chg_bds) && // some variables were tightened with reduced cost
410        !(problem_ -> btCore (chg_bds)))        // in this case, do another round of FBBT
411      throw infeasible;
412
413    // FBBT
414    if (problem_ -> doFBBT () && 
415        //(info.pass <= 0) && // do it in subsequent rounds too
416        (! (problem_ -> boundTightening (chg_bds, babInfo))))
417      throw infeasible;
418
419    // OBBT
420    if (!firstcall_ && // no obbt if first call (there is no LP to work with)
421        problem_ -> obbt (this, si, cs, info, babInfo, chg_bds) < 0)
422      throw infeasible;
423
424    // Bound tightening done /////////////////////////////
425
426    if ((problem_ -> doFBBT () ||
427         problem_ -> doOBBT () ||
428         problem_ -> doABT  ()) &&
429        (jnlst_ -> ProduceOutput (J_VECTOR, J_CONVEXIFYING))) {
430
431      jnlst_ -> Printf(J_VECTOR, J_CONVEXIFYING,"== after bt =============\n");
432      for (int i = 0; i < problem_ -> nVars (); i++)
433        if (problem_ -> Var (i) -> Multiplicity () > 0)
434          jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
435                         problem_ -> X  (i), problem_ -> Lb (i), problem_ -> Ub (i));
436      jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"=============================\n");
437    }
438
439    // Use orbit info to tighten bounds
440
441#ifdef COIN_HAS_NTY
442
443    // TODO: when independent bound tightener, can get original bounds
444    // through si.getCol{Low,Upp}er()
445
446    if (problem_ -> orbitalBranching () && !firstcall_) {
447
448      CouNumber
449        *lb = problem_ -> Lb (),
450        *ub = problem_ -> Ub ();
451
452      std::vector<std::vector<int> > *new_orbits = problem_ -> getNtyInfo () -> getOrbits();
453
454      for (int i=0, ii = problem_ -> getNtyInfo () -> getNumOrbits (); ii--; i++){
455
456        CouNumber
457          ll = -COUENNE_INFINITY,
458          uu =  COUENNE_INFINITY; 
459       
460        std::vector <int> orbit = (*new_orbits)[i];
461
462        if (orbit.size () <= 1)
463          continue; // not much to do when only one variable in this orbit
464
465        if (jnlst_ -> ProduceOutput (J_VECTOR, J_BOUNDTIGHTENING)) {
466          printf ("orbit bounds: "); fflush (stdout);
467          for(int j = 0; j < orbit.size (); j++) {
468            printf ("x_%d [%g,%g] ", orbit[j], lb [orbit [j]], ub [orbit [j]]);
469            fflush (stdout);
470          }
471          printf ("\n");
472        }
473
474        for (int j = 0; j < orbit.size (); j++) {
475 
476          int indOrb = orbit [j];
477
478          if (indOrb < problem_ -> nVars ()) {
479
480            if (lb [indOrb] > ll) ll = lb [indOrb];
481            if (ub [indOrb] < uu) uu = ub [indOrb];
482          }
483        }
484
485        jnlst_ -> Printf (J_VECTOR, J_BOUNDTIGHTENING, 
486                          " --> new common lower bounds: [%g,--]\n", ll);
487
488        for(int j = 0; j < orbit.size (); j++) {
489
490          int indOrb = orbit [j];
491
492          if (indOrb < problem_ -> nVars ()){
493
494            lb [indOrb] = ll;
495            ub [indOrb] = uu;
496          }
497        }
498      }
499
500      delete new_orbits;
501    }
502
503#endif
504
505    // Generate convexification cuts //////////////////////////////
506
507    sparse2dense (ncols, chg_bds, changed, nchanged);
508
509    double *nlpSol = NULL;
510
511    //--------------------------------------------
512
513    if (true) {
514
515      if (babInfo) 
516        nlpSol = const_cast <double *> (babInfo -> nlpSolution ());
517
518      // Aggressive Bound Tightening ////////////////////////////////
519
520      int logAbtLev = problem_ -> logAbtLev ();
521
522      if (problem_ -> doABT () &&             // flag is checked, AND
523          ((logAbtLev != 0) ||                // (parameter is nonzero OR
524           (info.level == 0)) &&              //  we are at root node), AND
525          (info.pass == 0) &&                 // at first round of cuts, AND
526          ((logAbtLev < 0) ||                 // (logAbtLev = -1, OR
527           (info.level <= logAbtLev) ||       //  depth is lower than COU_OBBT_CUTOFF_LEVEL, OR
528           (CoinDrand48 () <                  //  probability inversely proportional to the level)
529            pow (2., (double) logAbtLev - (info.level + 1))))) {
530
531        jnlst_ -> Printf(J_VECTOR, J_BOUNDTIGHTENING,"  performing ABT\n");
532        if (! (problem_ -> aggressiveBT (nlp_, chg_bds, info, babInfo)))
533          throw infeasible;
534
535        sparse2dense (ncols, chg_bds, changed, nchanged);
536      }
537
538      // obtain solution just found by nlp solver
539
540      // Auxiliaries should be correct. solution should be the one found
541      // at the node even if not as good as the best known.
542
543      // save violation flag and disregard it while adding cut at NLP
544      // point (which are not violated by the current, NLP, solution)
545      bool save_av = addviolated_;
546      addviolated_ = false;
547
548      // save values
549      problem_ -> domain () -> push
550        (problem_ -> nVars (), 
551         problem_ -> domain () -> x  (), 
552         problem_ -> domain () -> lb (), 
553         problem_ -> domain () -> ub (), false);
554
555      // fill originals with nlp values
556      if (nlpSol) {
557        CoinCopyN (nlpSol, problem_ -> nOrigVars (), problem_ -> domain () -> x ());
558      //problem_ -> initAuxs ();
559
560      problem_ -> getAuxs (problem_ -> domain () -> x ());
561      }
562
563      if (jnlst_ -> ProduceOutput (J_VECTOR, J_CONVEXIFYING)) {
564        jnlst_ -> Printf(J_VECTOR, J_CONVEXIFYING,"== genrowcuts on NLP =============\n");
565        for (int i = 0; i < problem_ -> nVars (); i++)
566          if (problem_ -> Var (i) -> Multiplicity () > 0)
567            jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
568                           problem_ -> X  (i),
569                           problem_ -> Lb (i),
570                           problem_ -> Ub (i));
571        jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"=============================\n");
572      }
573
574      problem_ -> domain () -> current () -> isNlp () = true;
575      genRowCuts (si, cs, nchanged, changed, chg_bds);  // add cuts
576
577      problem_ -> domain () -> pop (); // restore point
578
579      addviolated_ = save_av;     // restore previous value
580
581      //    if (!firstcall_) // keep solution if called from extractLinearRelaxation()
582      if (babInfo) 
583        babInfo -> setHasNlpSolution (false); // reset it after use //AW HERE
584
585    } else {
586
587      if (jnlst_ -> ProduceOutput (J_VECTOR, J_CONVEXIFYING)) {
588        jnlst_ -> Printf(J_VECTOR, J_CONVEXIFYING,"== genrowcuts on LP =============\n");
589        for (int i = 0; i < problem_ -> nVars (); i++)
590          if (problem_ -> Var (i) -> Multiplicity () > 0)
591            jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"%4d %+20.8g [%+20.8g,%+20.8g]\n", i,
592                           problem_ -> X  (i),
593                           problem_ -> Lb (i),
594                           problem_ -> Ub (i));
595        jnlst_->Printf(J_VECTOR, J_CONVEXIFYING,"=============================\n");
596      }
597
598      genRowCuts (si, cs, nchanged, changed, chg_bds);
599    }
600
601    // change tightened bounds through OsiCuts
602    if (nchanged)
603      genColCuts (si, cs, nchanged, changed);
604
605    if (firstcall_ && (cs.sizeRowCuts () >= 1))
606      jnlst_->Printf(J_ITERSUMMARY, J_CONVEXIFYING,
607                     "Couenne: %d initial row cuts\n", cs.sizeRowCuts ());
608
609    if (realOpt && // this is a good time to check if we have cut the optimal solution
610        isOptimumCut (realOpt, cs, problem_))
611      jnlst_->Printf(J_ITERSUMMARY, J_CONVEXIFYING,
612                     "Warning: Optimal solution was cut\n");
613  }
614
615  catch (int exception) {
616
617    if ((exception == infeasible) && (!firstcall_)) {
618
619      jnlst_ -> Printf (J_ITERSUMMARY, J_CONVEXIFYING,
620                        "Couenne: Infeasible node\n");
621
622      WipeMakeInfeas (cs);
623    }
624
625    if (babInfo) // set infeasibility to true in order to skip NLP heuristic
626      babInfo -> setInfeasibleNode ();
627  }
628
629  delete [] chg_bds;
630
631  if (changed) 
632    free (changed);
633
634  if (firstcall_) {
635
636    jnlst_ -> Printf (J_SUMMARY, J_CONVEXIFYING, 
637                      "Couenne: %d cuts (%d row, %d col) for linearization\n", 
638                      cs.sizeRowCuts () + cs.sizeColCuts (),
639                      cs.sizeRowCuts (),  cs.sizeColCuts ());
640
641    fictitiousBound (cs, problem_, true);
642    firstcall_  = false;
643    ntotalcuts_ = nrootcuts_ = cs.sizeRowCuts ();
644
645  } else { 
646
647    problem_ -> domain () -> pop ();
648
649    ntotalcuts_ += (cs.sizeRowCuts () - nInitCuts);
650
651    if (saveOptimum)
652      realOpt = saveOptimum; // restore debug optimum
653  }
654
655  septime_ += CoinCpuTime () - now;
656
657  if (jnlst_ -> ProduceOutput (J_ITERSUMMARY, J_CONVEXIFYING)) {
658
659    if (cs.sizeColCuts ()) {
660      jnlst_ -> Printf (J_ITERSUMMARY, J_CONVEXIFYING,"Couenne col cuts:\n");
661      for (int i=0; i<cs.sizeColCuts (); i++) 
662        cs.colCutPtr (i) -> print ();
663    }
664  }
665
666  if (!(info.inTree)) 
667    rootTime_ = CoinCpuTime ();
668}
669
670}
Note: See TracBrowser for help on using the repository browser.