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

Last change on this file since 808 was 808, checked in by pbelotti, 9 years ago

merged from trunk: last fixings on negative index objective

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