11 #include "CoinHelperFunctions.hpp" 
   12 #include "OsiClpSolverInterface.hpp" 
   13 #include "OsiCuts.hpp" 
   14 #include "CoinTime.hpp" 
   23 using namespace Ipopt;
 
   24 using namespace Couenne;
 
   28 void CouenneFixPoint::generateCuts (
const OsiSolverInterface &si,
 
   30                                     const CglTreeInfo treeInfo)
 
   31 #if CGL_VERSION_MAJOR == 0 && CGL_VERSION_MINOR <= 57 
   59   if (treeInfo.inTree && 
 
   67   if ((levelStop_ < 0) &&                  
 
   68       ((treeInfo.level > -2*levelStop_) || 
 
   69        ((treeInfo.level > -levelStop_) &&  
 
   70         (treeInfo.level & 1))))            
 
   73   double startTime = CoinCpuTime ();
 
   75   int nInitTightened = nTightened_;
 
   77   if (treeInfo.inTree && 
 
   78       treeInfo.level <= 0) {
 
   80     problem_ -> Jnlst () -> Printf (J_ERROR, 
J_COUENNE, 
"Fixed Point FBBT: "); 
 
   86   double now = CoinCpuTime ();
 
   88   problem_ -> domain () -> push (&si, &cs);
 
   91     *oldLB = CoinCopyOfArray (problem_ -> Lb (), problem_ -> nVars ()),
 
   92     *oldUB = CoinCopyOfArray (problem_ -> Ub (), problem_ -> nVars ());
 
   94   perfIndicator_. setOldBounds (problem_ -> Lb (), problem_ -> Ub ());
 
  115   OsiSolverInterface *fplp = NULL;
 
  120     fplp = 
new OsiClpSolverInterface;
 
  142   const CoinPackedMatrix *A = si. getMatrixByRow ();
 
  145     n     = si.  getNumCols (),
 
  146     m     = si.  getNumRows (),
 
  147     nCuts = cs.sizeRowCuts  (),
 
  148     *ind  = A -> getIndices ();
 
  151     *lb  = problem_ -> Lb (), 
 
  152     *ub  = problem_ -> Ub (), 
 
  153     *rlb = si.  getRowLower (),
 
  154     *rub = si.  getRowUpper (),
 
  155     *coe = A -> getElements ();
 
  158     for (
int i=0; i<
n; i++) 
 
  159       printf (
"----------- x_%d in [%g,%g]\n", i, lb [i], ub [i]);
 
  162   fplp -> messageHandler () -> setLogLevel (0);
 
  165   for (
int i=0; i<
n; i++) {
 
  166     bool isActive = problem_ -> Var (i) -> Multiplicity () > 0;
 
  167     fplp -> addCol (0, NULL, NULL, lb [i], ub [i], isActive ? -1. : 0.); 
 
  170   for (
int i=0; i<
n; i++) {
 
  171     bool isActive = problem_ -> Var (i) -> Multiplicity () > 0;
 
  172     fplp -> addCol (0, NULL, NULL, lb [i], ub [i], isActive ? +1. : 0.); 
 
  175   if (extendedModel_) {
 
  177     for (
int j=0; 
j<
m; 
j++) fplp -> addCol (0, NULL, NULL, rlb [
j],       COIN_DBL_MAX, 0.); 
 
  178     for (
int j=0; j<
m; j++) fplp -> addCol (0, NULL, NULL, -COIN_DBL_MAX, rub [j],      0.); 
 
  183   for (
int j=0; 
j<
m; 
j++) { 
 
  185     const int nEl = A->getVectorLast(
j) - A->getVectorFirst(
j), 
 
  186       *rind = &ind [A->getVectorFirst (
j)];
 
  187     const double *rcoe = &coe [A->getVectorFirst (
j)];
 
  194       printf (
"row %4d, %4d elements: ", 
j, nEl);
 
  196       for (
int i=0; i<nEl; i++) {
 
  197         printf (
"%+g x%d ", rcoe [i], rind [i]);
 
  207       for (
int i = A->getVectorFirst(
j); i < A->getVectorLast(
j); i++) 
 
  208         createRow (-1, ind [i], n, fplp, rind, rcoe, rlb [
j], nEl, extendedModel_, j, m + nCuts); 
 
  211       for (
int i = A->getVectorFirst(j); i < A->getVectorLast(j); i++) 
 
  212         createRow (+1, ind [i], n, fplp, rind, rcoe, rub [j], nEl, extendedModel_, j, m + nCuts); 
 
  216     if (extendedModel_) {
 
  217       createRow (-1, 2*n     + j, n, fplp, rind, rcoe, rlb [j], nEl, extendedModel_, j, m + nCuts); 
 
  218       createRow (+1, 2*n + m + j, n, fplp, rind, rcoe, rub [j], nEl, extendedModel_, j, m + nCuts); 
 
  224   for (
int j = 0, jj = nCuts; jj--; 
j++) {
 
  228     OsiRowCut *cut = cs.rowCutPtr (
j);
 
  230     const CoinPackedVector &row = cut -> row ();
 
  233       nEl = row.getNumElements (),
 
  234       *ind = row.getIndices ();
 
  236     const double *coe = row.getElements ();
 
  238     if (extendedModel_) {
 
  239       fplp -> addCol (0, NULL, NULL, cut -> lb (),       COIN_DBL_MAX, 0.); 
 
  240       fplp -> addCol (0, NULL, NULL, -COIN_DBL_MAX, cut -> ub (),      0.); 
 
  244       for (
int i=0; i<nEl; i++) 
 
  245         createRow (-1, ind [i], n, fplp, ind, coe, cut -> lb (), nEl, extendedModel_, m + 
j, m + nCuts); 
 
  248       for (
int i=0; i<nEl; i++)
 
  249         createRow (+1, ind [i], n, fplp, ind, coe, cut -> ub (), nEl, extendedModel_, m + 
j, m + nCuts); 
 
  253     if (extendedModel_) {
 
  254       createRow (-1, 2*n             + 
j, n, fplp, ind, coe, cut -> lb (), nEl, extendedModel_, m + 
j, m + nCuts); 
 
  255       createRow (+1, 2*n + m + nCuts + 
j, n, fplp, ind, coe, cut -> ub (), nEl, extendedModel_, m + 
j, m + nCuts); 
 
  261   for (
int j=0; 
j<
n; 
j++) { 
 
  263     int    ind [2] = {
j,   n + 
j};
 
  264     double coe [2] = {1., -1.};
 
  266     CoinPackedVector row (2, ind, coe);
 
  267     fplp -> addRow (row, -COIN_DBL_MAX, 0.);
 
  274     for (
int j=0; 
j<
m; 
j++) { 
 
  276       int    ind [2] = {2*n + 
j, 2*n + m + j};
 
  277       double coe [2] = {1.,      -1.};
 
  279       CoinPackedVector row (2, ind, coe);
 
  280       fplp -> addRow (row, -COIN_DBL_MAX, 0.);
 
  286   fplp -> setObjSense (-1.); 
 
  288   fplp -> initialSolve ();
 
  294   if (fplp -> isProvenDualInfeasible ()) {
 
  296     problem_ -> Jnlst () -> Printf (J_WARNING, 
J_BOUNDTIGHTENING, 
"FPLP unbounded: extra BT\n");
 
  298     if (!(problem_ -> doFBBT ()) &&   
 
  299         !(problem_ -> btCore (NULL))) 
 
  304     for (
int i=0; i<
n; i++) {
 
  305       fplp -> setColLower (  i, problem_ -> Lb (i)); 
 
  306       fplp -> setColLower (n+i, problem_ -> Lb (i)); 
 
  307       fplp -> setColUpper (  i, problem_ -> Ub (i)); 
 
  308       fplp -> setColUpper (n+i, problem_ -> Ub (i)); 
 
  315     *newLB = fplp -> getColSolution (),
 
  318   double infeasBounds [] = {1,-1};
 
  320   if (fplp -> isProvenOptimal ()) {
 
  327       *indLB = 
new int [
n],
 
  328       *indUB = 
new int [
n],
 
  333       *valLB = 
new double [
n],
 
  334       *valUB = 
new double [
n];
 
  336     for (
int i=0; i<
n; i++) {
 
  339         printf (
"x%d: [%g,%g] --> [%g,%g]\n", i, 
 
  340                 oldLB [i], oldUB [i], 
 
  341                 newLB [i], newUB [i]);
 
  345         indLB [ntightenedL]   = i;
 
  346         valLB [ntightenedL++] = newLB [i];
 
  353         indUB [ntightenedU]   = i;
 
  354         valUB [ntightenedU++] = newUB [i];
 
  360     if (ntightenedL || ntightenedU) {
 
  364       newBound.setLbs (ntightenedL, indLB, valLB);
 
  365       newBound.setUbs (ntightenedU, indUB, valUB);
 
  367       cs.insert (newBound);
 
  375     CPUtime_ += CoinCpuTime () - now;
 
  377     if (treeInfo.inTree && 
 
  379       problem_ -> Jnlst () -> Printf (J_ERROR, 
J_COUENNE, 
"%d bounds tightened (%g seconds)\n", 
 
  380                                       nTightened_ - nInitTightened, CoinCpuTime () - now); 
 
  382   } 
else if (fplp -> isProvenPrimalInfeasible ()) {
 
  384     if (treeInfo.inTree &&
 
  386       problem_ -> Jnlst () -> Printf (J_ERROR, 
J_COUENNE, 
" FPLP infeasible.\n");
 
  390     newLB = infeasBounds;
 
  391     newUB = infeasBounds + 1;
 
  398     if (treeInfo.inTree && 
 
  400       problem_ -> Jnlst () -> Printf (J_ERROR, 
J_COUENNE, 
" FPLP inconclusive, won't be used.\n");
 
  408   perfIndicator_. update (newLB, newUB, treeInfo.level);
 
  409   perfIndicator_. addToTimer (CoinCpuTime () - startTime);
 
  413   problem_ -> domain () -> pop ();
 
  436 void CouenneFixPoint::createRow (
int sign,
 
  439                                  OsiSolverInterface *p,
 
  553     printf (
"creating constraint from: ");
 
  555     for (
int i=0; i<nEl; i++)
 
  556       printf (
"%+g x%d ", coe [i], indices [i]);
 
  558     printf (
"%c= %g for variable index %d: ", sign > 0 ? 
'<' : 
'>', rhs, indexVar);
 
  566   int    *iInd = 
new int    [nTerms];
 
  567   double *elem = 
new double [nTerms];
 
  571   CoinCopyN (coe, nEl, elem);
 
  575     iInd [nEl] = 2*nVars + indCon + ((sign > 0) ? nCon : 0);
 
  580   for (
int k=0; 
k<nEl; 
k++) {
 
  582     int curInd = indices [
k];
 
  588     if (curInd == indexVar) { 
 
  589       if (((sign > 0) && (coe [
k] > 0.)) || 
 
  590           ((sign < 0) && (coe [
k] < 0.)))
 
  594     } 
else if (((coe [
k] > 0.) && (sign < 0)) ||
 
  595                ((coe [
k] < 0.) && (sign > 0)))
 
  600   CoinPackedVector vec (nTerms, iInd, elem);
 
  603     lb = sign > 0 ? -COIN_DBL_MAX : extMod ? 0. : rhs,
 
  604     ub = sign < 0 ? +COIN_DBL_MAX : extMod ? 0. : rhs;
 
  606   p -> addRow (vec, lb, ub);
 
  612     for (
int i=0; i<nEl; i++)
 
  613       printf (
"%+g x%d ", elem [i], iInd [i]);
 
  615     printf (
"in [%g,%g]\n", lb, ub);
 
bool isWiped(OsiCuts &cs)
Check whether the previous cut generators have added an infeasible cut. 
 
const Ipopt::EJournalCategory J_BOUNDTIGHTENING(Ipopt::J_USER2)
 
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...