11 #include "CoinHelperFunctions.hpp"
12 #include "CglCutGenerator.hpp"
13 #include "OsiClpSolverInterface.hpp"
22 using namespace Ipopt;
23 using namespace Couenne;
25 #define THRESH_OBBT_AUX 50 // if more than this originals, don't do OBBT on auxs
27 #define MAX_OBBT_LP_ITERATION 100
28 #define MAX_OBBT_ATTEMPTS 1 // number of OBBT iterations at root node
33 #define THRES_NBD_CHANGED 1
36 #define MAX_OBBT_ITER 1
43 int CouenneProblem::call_iter (OsiSolverInterface *csi,
45 const CoinWarmStart *warmstart,
51 int ncols = csi -> getNumCols (),
54 for (
int ii=0; ii<ncols; ii++) {
56 if (CoinCpuTime () > maxCpuTime_)
59 int i = evalOrder (ii);
63 if ((Var (i) -> Type () == type) &&
64 (Var (i) -> Multiplicity () > 0) &&
66 (aSign == expression::AUX_EQ) ||
67 ((aSign == expression::AUX_LEQ) && (sense > 0)) ||
68 ((aSign == expression::AUX_GEQ) && (sense < 0)))) {
70 int ni = obbt_iter (csi, chg_bds, warmstart, babInfo, objcoe, sense, i);
88 if (ni < 0)
return ni;
99 int CouenneProblem::obbtInner (OsiSolverInterface *csi,
106 int ncols = csi -> getNumCols ();
107 const double *lb = csi -> getColLower (),
108 *ub = csi -> getColUpper ();
110 double inf = csi -> getInfinity ();
112 for (
int i=ncols; i--;) {
120 csi -> setObjSense (1);
122 csi -> applyCuts (cs);
123 csi -> initialSolve ();
125 const CoinWarmStart *warmstart = csi -> getWarmStart ();
129 double *objcoe = (
double *) malloc (ncols *
sizeof (
double));
132 for (
int i=ncols; i--;)
136 csi -> setObjective (objcoe);
137 csi -> setObjSense (1);
141 const int Infeasible = 1;
147 if ((ni = call_iter (csi, chg_bds, warmstart, babInfo, objcoe,
VAR, 1)) < 0)
throw Infeasible;
150 if ((ni = call_iter (csi, chg_bds, warmstart, babInfo, objcoe,
VAR, -1)) < 0)
throw Infeasible;
155 if ((ni = call_iter (csi, chg_bds, warmstart, babInfo, objcoe,
AUX, 1)) < 0)
throw Infeasible;
158 if ((ni = call_iter (csi, chg_bds, warmstart, babInfo, objcoe,
AUX, -1)) < 0)
throw Infeasible;
163 catch (
int exception) {
165 if (exception == Infeasible)
178 const OsiSolverInterface &si,
180 const CglTreeInfo &
info,
197 double startTime = CoinCpuTime ();
199 int nTotImproved = 0;
203 ((logObbtLev_ != 0) ||
204 (info.level == 0)) &&
206 ((logObbtLev_ < 0) ||
207 (info.level <= logObbtLev_) ||
209 (CoinDrand48 () < pow (2., (
double) logObbtLev_ - (info.level + 1))))) {
211 OBBTperfIndicator_ -> setOldBounds (Lb (), Ub ());
213 if ((info.level <= 0 && !(info.inTree)) ||
214 jnlst_ -> ProduceOutput (J_STRONGWARNING,
J_COUENNE)) {
216 jnlst_ -> Printf (J_ERROR,
J_COUENNE,
"Optimality Based BT: ");
227 OsiSolverInterface *csi = si.clone (
true);
229 csi -> messageHandler () -> setLogLevel (0);
232 OsiClpSolverInterface *clpcsi = dynamic_cast <OsiClpSolverInterface *> (csi);
235 clpcsi -> setupForRepeatedUse ();
240 int nImprov, nIter = 0;
242 bool notImproved =
false;
244 while (!notImproved &&
246 ((nImprov = obbtInner (csi, cs, chg_bds, babInfo)) > 0) &&
247 (CoinCpuTime () < maxCpuTime_)) {
249 int nchanged, *changed = NULL;
253 cg -> genColCuts (*csi, cs, nchanged, changed);
255 nTotImproved += nImprov;
261 int nCurCuts = cs.sizeRowCuts ();
262 cg -> genRowCuts (*csi, cs, nchanged, changed, chg_bds);
264 if (nCurCuts == cs.sizeRowCuts ())
267 }
else notImproved =
true;
277 if ((info.level <= 0 && !(info.inTree)) ||
278 jnlst_ -> ProduceOutput (J_STRONGWARNING,
J_COUENNE))
279 jnlst_ -> Printf (J_ERROR,
J_COUENNE,
"%d improved bounds\n", nTotImproved);
282 jnlst_->Printf(J_ITERSUMMARY,
J_BOUNDTIGHTENING,
" Couenne: infeasible node after OBBT\n");
286 OBBTperfIndicator_ -> update (Lb (), Ub (), info.level);
287 OBBTperfIndicator_ -> addToTimer (CoinCpuTime () - startTime);
Cut Generator for linear convexifications.
#define MAX_OBBT_LP_ITERATION
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
#define MAX_OBBT_ATTEMPTS
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void sparse2dense(int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged)
translate sparse to dense vector (should be replaced)
auxSign
"sign" of the constraint defining an auxiliary.
const Ipopt::EJournalCategory J_BOUNDTIGHTENING(Ipopt::J_USER2)
#define THRES_NBD_CHANGED
nodeType
type of a node in an expression tree
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
Bonmin class for passing info between components of branch-and-cuts.