12 #include "CoinTime.hpp"
19 using namespace Ipopt;
20 using namespace Couenne;
23 void CouenneDisjCuts::generateCuts (
const OsiSolverInterface &si,
25 const CglTreeInfo
info)
26 #if CGL_VERSION_MAJOR == 0 && CGL_VERSION_MINOR <= 57
39 if (jnlst_ -> ProduceOutput (J_DETAILED,
J_DISJCUTS))
40 printf (
"--- generateDisjCuts: level = %d, pass = %d, intree = %d [%d]\n",
41 info.level, info.pass, info.inTree, depthStopSeparate_);
43 if ((depthStopSeparate_ >= 0) &&
44 (info.level > depthStopSeparate_))
47 int nInitCuts = nrootcuts_;
49 if ((info.level <= 0) && !(info.inTree)) {
52 "Disjunctive cuts (root node): ");
56 double time = CoinCpuTime ();
59 OsiSolverInterface *csi = si.clone ();
62 initRowCuts = cs.sizeRowCuts (),
63 initColCuts = cs.sizeColCuts ();
115 int maxDisj = (initDisjNumber_ >= 0) ?
116 CoinMin ((
int) (csi -> numberObjects () * initDisjPercentage_), initDisjNumber_) :
117 (
int) (csi -> numberObjects () * initDisjPercentage_);
120 numDisjunctions_ = (depthLevelling_ < 0 || info.level < depthLevelling_) ?
122 (
int) (maxDisj / (2 + info.level - depthLevelling_));
124 if (numDisjunctions_ < 1) numDisjunctions_ = 1;
131 couenneCG_ -> Problem () -> domain () -> push (&si, &cs,
false);
133 std::vector <std::pair <OsiCuts *, OsiCuts *> > disjunctions;
135 bool infeasNode =
false;
152 int result = getDisjunctions (disjunctions, *csi, cs, info);
156 iterations < max_iterations) start_over =
true;
158 if (disjunctions.empty ())
162 for (std::vector <std::pair <OsiCuts *, OsiCuts *> >::iterator disjI = disjunctions.begin ();
163 disjI != disjunctions.end (); ++disjI) {
165 if (CoinCpuTime () > couenneCG_ -> Problem () -> getMaxCpuTime ()) {
173 result = separateWithDisjunction (disjI -> first, *csi, cs, info);
181 result = separateWithDisjunction (disjI -> second, *csi, cs, info);
191 for (std::vector <std::pair <OsiCuts *, OsiCuts *> >::iterator disjI = disjunctions.begin ();
192 disjI != disjunctions.end (); ++disjI) {
193 delete disjI -> first;
194 delete disjI -> second;
197 disjunctions.erase (disjunctions.begin (), disjunctions.end ());
200 if (!start_over && jnlst_ -> ProduceOutput (J_VECTOR,
J_DISJCUTS))
203 for (std::vector <std::pair <OsiCuts *, OsiCuts *> >::iterator disjI = disjunctions.begin ();
204 disjI != disjunctions.end (); ++disjI) {
206 printf (
"=========================== CUTS for the LEFT part\n");
207 for (
int i=0; i<disjI->first->sizeColCuts (); i++) disjI->first->colCutPtr(i)->print();
208 for (
int i=0; i<disjI->first->sizeRowCuts (); i++) disjI->first->rowCutPtr(i)->print();
209 printf (
"=========================== CUTS for the RIGHT part\n");
210 for (
int i=0; i<disjI->second->sizeColCuts (); i++) disjI->second->colCutPtr(i)->print();
211 for (
int i=0; i<disjI->second->sizeRowCuts (); i++) disjI->second->rowCutPtr(i)->print();
212 printf (
"===========================\n");
215 }
while (start_over && (iterations < max_iterations));
228 throw exc_infeasible;
231 catch (
int exception) {
233 if (exception == exc_infeasible) {
235 jnlst_ -> Printf (J_DETAILED,
J_DISJCUTS,
"--- Disjunctive Cut separator: infeasible node\n");
242 for (std::vector <std::pair <OsiCuts *, OsiCuts *> >::iterator disjI = disjunctions.begin ();
243 disjI != disjunctions.end (); ++disjI) {
245 delete disjI -> first;
246 delete disjI -> second;
249 couenneCG_ -> Problem () -> domain () -> pop ();
260 *oldLo = si. getColLower (), *newLo = csi -> getColLower (),
261 *oldUp = si. getColUpper (), *newUp = csi -> getColUpper ();
263 int ncols = si.getNumCols ();
265 for (
int i=0; i<ncols; i++, newLo++, newUp++) {
267 if (*newLo > *oldLo++ +
COUENNE_EPS) tighterLower.insert (i, *newLo);
268 if (*newUp < *oldUp++ -
COUENNE_EPS) tighterUpper.insert (i, *newUp);
271 if ((tighterLower.getNumElements () > 0) ||
272 (tighterUpper.getNumElements () > 0)) {
274 tighter.setLbs (tighterLower);
275 tighter.setUbs (tighterUpper);
276 if (jnlst_ -> ProduceOutput (J_DETAILED,
J_DISJCUTS)) {
277 printf (
"tightened bounds in disjunctive cuts:");
284 cs.sizeRowCuts () - initRowCuts +
285 cs.sizeColCuts () - initColCuts;
287 if (info.level <= 0 && !(info.inTree))
288 nrootcuts_ += deltaNcuts;
289 ntotalcuts_ += deltaNcuts;
291 if (jnlst_ -> ProduceOutput (J_DETAILED,
J_DISJCUTS)) {
293 if (cs.sizeRowCuts()>initRowCuts) printf (
"added %d row cuts\n", cs.sizeRowCuts () - initRowCuts);
294 if (cs.sizeColCuts()>initColCuts) printf (
"added %d col cuts\n", cs.sizeColCuts () - initColCuts);
297 if ((info.level <= 0) && !(info.inTree))
299 "%d cuts\n", CoinMax (0, nrootcuts_ - nInitCuts));
302 "In-BB disjunctive cuts: %d row cuts, %d col cuts\n",
303 cs.sizeRowCuts () - initRowCuts,
304 cs.sizeColCuts () - initColCuts);
307 if (jnlst_ -> ProduceOutput (J_DETAILED,
J_DISJCUTS)) {
309 printf (
"Disjunctive cuts (%d row + %d col):\n", cs.sizeRowCuts () - initRowCuts, cs.sizeColCuts () - initColCuts);
310 for (
int i=initRowCuts; i<cs.sizeRowCuts (); ++i) cs.rowCutPtr (i) -> print ();
311 for (
int i=initColCuts; i<cs.sizeColCuts (); ++i) cs.colCutPtr (i) -> print ();
326 septime_ += (CoinCpuTime () - time);
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
const Ipopt::EJournalCategory J_DISJCUTS(Ipopt::J_USER6)
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
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...