Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

CoinPresolveForcing.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #include <stdio.h>
00004 #include <math.h>
00005 
00006 #include "CoinPresolveMatrix.hpp"
00007 #include "CoinPresolveEmpty.hpp"        // for DROP_COL/DROP_ROW
00008 #include "CoinPresolveFixed.hpp"
00009 #include "CoinPresolveSubst.hpp"
00010 #include "CoinPresolveUseless.hpp"
00011 #include "CoinPresolveForcing.hpp"
00012 #include "CoinMessage.hpp"
00013 
00014 #if 0
00015 inline double max(double x, double y)
00016 {
00017   return (x < y) ? y : x;
00018 }
00019 
00020 inline double min(double x, double y)
00021 {
00022   return (x < y) ? x : y;
00023 }
00024 #endif
00025 
00026 /*static*/ void implied_bounds(const double *els,
00027                            const double *clo, const double *cup,
00028                            const int *hcol,
00029                            CoinBigIndex krs, CoinBigIndex kre,
00030                            double *maxupp, double *maxdownp,
00031                            int jcol,
00032                            double rlo, double rup,
00033                            double *iclb, double *icub)
00034 {
00035   if (rlo<=-PRESOLVE_INF&&rup>=PRESOLVE_INF) {
00036     *iclb = -PRESOLVE_INF;
00037     *icub =  PRESOLVE_INF;
00038     return;
00039   }
00040   bool posinf = false;
00041   bool neginf = false;
00042   double maxup = 0.0;
00043   double maxdown = 0.0;
00044 
00045   int jcolk = -1;
00046 
00047   // compute sum of all bounds except for jcol
00048   CoinBigIndex kk;
00049   for (kk=krs; kk<kre; kk++) {
00050     if (hcol[kk] == jcol)
00051       jcolk = kk;
00052 
00053     // swap jcol with hcol[kre-1];
00054     // that is, consider jcol last
00055     // this assumes that jcol occurs in this row
00056     CoinBigIndex k = (hcol[kk] == jcol
00057              ? kre-1
00058              : kk == kre-1
00059              ? jcolk
00060              : kk);
00061 
00062     PRESOLVEASSERT(k != -1);    // i.e. jcol had better be in the row
00063 
00064     int col = hcol[k];
00065     double coeff = els[k];
00066     double lb = clo[col];
00067     double ub = cup[col];
00068 
00069     // quick!  compute the implied col bounds before maxup/maxdown are changed
00070     if (kk == kre-1) {
00071       PRESOLVEASSERT(fabs(coeff) > ZTOLDP);
00072 
00073       double ilb = (rlo - maxup) / coeff;
00074       bool finite_ilb = (-PRESOLVE_INF < rlo && !posinf && PRESOLVEFINITE(maxup));
00075 
00076       double iub = (rup - maxdown) / coeff;
00077       bool finite_iub = ( rup < PRESOLVE_INF && !neginf && PRESOLVEFINITE(maxdown));
00078 
00079       if (coeff > 0.0) {
00080         *iclb = (finite_ilb ? ilb : -PRESOLVE_INF);
00081         *icub = (finite_iub ? iub :  PRESOLVE_INF);
00082       } else {
00083         *iclb = (finite_iub ? iub : -PRESOLVE_INF);
00084         *icub = (finite_ilb ? ilb :  PRESOLVE_INF);
00085       }
00086     }
00087 
00088     if (coeff > 0.0) {
00089       if (PRESOLVE_INF <= ub) {
00090         posinf = true;
00091         if (neginf)
00092           break;        // pointless
00093       } else
00094         maxup += ub * coeff;
00095 
00096       if (lb <= -PRESOLVE_INF) {
00097         neginf = true;
00098         if (posinf)
00099           break;        // pointless
00100       } else
00101         maxdown += lb * coeff;
00102     } else {
00103       if (PRESOLVE_INF <= ub) {
00104         neginf = true;
00105         if (posinf)
00106           break;        // pointless
00107       } else
00108         maxdown += ub * coeff;
00109 
00110       if (lb <= -PRESOLVE_INF) {
00111         posinf = true;
00112         if (neginf)
00113           break;        // pointless
00114       } else
00115         maxup += lb * coeff;
00116     }
00117   }
00118 
00119   // If we broke from the loop, then the bounds are infinite.
00120   // However, since we put the column whose implied bounds we want
00121   // to know at the end, and it doesn't matter if its own bounds
00122   // are infinite, don't worry about breaking at the last iteration.
00123   if (kk<kre-1) {
00124     *iclb = -PRESOLVE_INF;
00125     *icub =  PRESOLVE_INF;
00126   } else
00127     PRESOLVEASSERT(jcolk != -1);
00128 
00129   // store row bounds
00130   *maxupp   = (posinf) ?  PRESOLVE_INF : maxup;
00131   *maxdownp = (neginf) ? -PRESOLVE_INF : maxdown;
00132 }
00133 
00134 static void implied_row_bounds(const double *els,
00135                                const double *clo, const double *cup,
00136                                const int *hcol,
00137                                CoinBigIndex krs, CoinBigIndex kre,
00138                                double *maxupp, double *maxdownp)
00139 {
00140    //  int jcol;
00141   double iclb, icub;
00142 
00143   implied_bounds(els, clo, cup, hcol, krs, kre, maxupp, maxdownp,
00144                  hcol[krs], 0.0, 0.0, &iclb, &icub);
00145 }
00146 
00147 const char *forcing_constraint_action::name() const
00148 {
00149   return ("forcing_constraint_action");
00150 }
00151 
00152 static bool some_col_was_fixed(const int *hcol, CoinBigIndex krs, CoinBigIndex kre,
00153                                const double *clo, 
00154                                const double *cup)
00155 {
00156   CoinBigIndex k;
00157   for (k=krs; k<kre; k++) {
00158     int jcol = hcol[k];
00159     if (clo[jcol] == cup[jcol])
00160       break;
00161   }
00162   return (k<kre);
00163 }
00164 
00165 
00166 //
00167 // It may be the case that the variable bounds are such that no matter what
00168 // feasible value they take, the constraint cannot be violated;
00169 // in this case, we obviously don't need to take it into account, and
00170 // we just drop it as a USELESS constraint.
00171 //
00172 // On the other hand, it may be that the only way to satisfy a constraint
00173 // is to jam all the constraint variables to one of their bounds;
00174 // in this case, these variables are essentially fixed, which
00175 // we do with a FORCING constraint.
00176 // For now, this just tightens the bounds; subsequently the fixed variables
00177 // will be removed, then the row will be dropped.
00178 //
00179 // Since both operations use similar information (the implied row bounds),
00180 // we combine them into one presolve routine.
00181 //
00182 // I claim that these checks could be performed in parallel,
00183 // that is, the tests could be carried out for all rows in parallel,
00184 // and then the rows deleted and columns tightened afterward.
00185 // Obviously, this is true for useless rows.
00186 // The potential problem is forcing constraints, but I think
00187 // that is ok.
00188 // By doing it in parallel rather than sequentially,
00189 // we may miss transformations due to variables that were fixed
00190 // by forcing constraints, though.
00191 //
00192 // Note that both of these operations will cause problems
00193 // if the variables in question really need to exceed their bounds in order
00194 // to make the problem feasible.
00195 const CoinPresolveAction *forcing_constraint_action::presolve(CoinPresolveMatrix *prob,
00196                                           const CoinPresolveAction *next)
00197 {
00198   double *clo   = prob->clo_;
00199   double *cup   = prob->cup_;
00200 
00201   const double *rowels  = prob->rowels_;
00202   const int *hcol       = prob->hcol_;
00203   const CoinBigIndex *mrstrt    = prob->mrstrt_;
00204   const int *hinrow     = prob->hinrow_;
00205   const int nrows       = prob->nrows_;
00206 
00207   const double *rlo     = prob->rlo_;
00208   const double *rup     = prob->rup_;
00209 
00210   //  const char *integerType = prob->integerType_;
00211 
00212   const double tol      = ZTOLDP;
00213   const double inftol   = prob->feasibilityTolerance_;
00214   const int ncols       = prob->ncols_;
00215 
00216   int *fixed_cols       = new int[ncols];
00217   int nfixed_cols       = 0;
00218 
00219   action *actions       = new action [nrows];
00220   int nactions = 0;
00221 
00222   int *useless_rows     = new int[nrows];
00223   int nuseless_rows     = 0;
00224 
00225   int numberLook = prob->numberRowsToDo_;
00226   int iLook;
00227   int * look = prob->rowsToDo_;
00228 
00229   for (iLook=0;iLook<numberLook;iLook++) {
00230     int irow = look[iLook];
00231     if (hinrow[irow] > 0) {
00232       CoinBigIndex krs = mrstrt[irow];
00233       CoinBigIndex kre = krs + hinrow[irow];
00234 
00235       double maxup, maxdown;
00236       implied_row_bounds(rowels, clo, cup, hcol, krs, kre,
00237                          &maxup, &maxdown);
00238 
00239       if (maxup < PRESOLVE_INF && maxup + inftol < rlo[irow]) {
00240         /* there is an upper bound and it can't be reached */
00241         prob->status_|= 1;
00242         prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00243                                              prob->messages())
00244                                                <<irow
00245                                                <<rlo[irow]
00246                                                <<rup[irow]
00247                                                <<CoinMessageEol;
00248         break;
00249       } else if (-PRESOLVE_INF < maxdown && rup[irow] < maxdown - inftol) {
00250         /* there is a lower bound and it can't be reached */
00251         prob->status_|= 1;
00252         prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00253                                              prob->messages())
00254                                                <<irow
00255                                                <<rlo[irow]
00256                                                <<rup[irow]
00257                                                <<CoinMessageEol;
00258         break;
00259       }
00260       // ADD TOLERANCE TO THESE TESTS
00261       else if ((rlo[irow] <= -PRESOLVE_INF ||
00262                 (-PRESOLVE_INF < maxdown && rlo[irow] <= maxdown)) &&
00263                (rup[irow] >= PRESOLVE_INF ||
00264                 (maxup < PRESOLVE_INF && rup[irow] >= maxup))) {
00265 
00266         // I'm not sure that these transforms don't intefere with each other
00267         // We can get it next time
00268         if (some_col_was_fixed(hcol, krs, kre, clo, cup)) {
00269           // make sure on next time
00270           prob->addRow(irow);
00271           continue;
00272         }
00273 
00274         // this constraint must always be satisfied - drop it
00275         useless_rows[nuseless_rows++] = irow;
00276 
00277       } else if ((maxup < PRESOLVE_INF && fabs(rlo[irow] - maxup) < tol) ||
00278                  (-PRESOLVE_INF < maxdown && fabs(rup[irow] - maxdown) < tol)) {
00279 
00280         // the lower bound can just be reached, or
00281         // the upper bound can just be reached;
00282         // called a "forcing constraint" in the paper (p. 226)
00283         const int lbound_tight = (maxup < PRESOLVE_INF &&
00284                                   fabs(rlo[irow] - maxup) < tol);
00285 
00286         // I'm not sure that these transforms don't intefere with each other
00287         // We can get it next time
00288         if (some_col_was_fixed(hcol, krs, kre, clo, cup)) {
00289           // make sure on next time
00290           prob->addRow(irow);
00291           continue;
00292         }
00293 
00294         // out of space - this probably never happens
00295         if (nfixed_cols + (kre-krs) >= ncols)
00296           break;
00297 
00298         double *bounds = new double[hinrow[irow]];
00299         int *rowcols = new int[hinrow[irow]];
00300         int lk = krs;   // load fix-to-down in front
00301         int uk = kre;   // load fix-to-up in back
00302         CoinBigIndex k;
00303         for ( k=krs; k<kre; k++) {
00304           int jcol = hcol[k];
00305           prob->addCol(jcol);
00306           double coeff = rowels[k];
00307 
00308           PRESOLVEASSERT(fabs(coeff) > ZTOLDP);
00309 
00310           // one of the two contributed to maxup - set the other to that
00311           if (lbound_tight == (coeff > 0.0)) {
00312             --uk;
00313             bounds[uk-krs] = clo[jcol];
00314             rowcols[uk-krs] = jcol;
00315               
00316             clo[jcol] = cup[jcol];
00317           } else {
00318             bounds[lk-krs] = cup[jcol];
00319             rowcols[lk-krs] = jcol;
00320             ++lk;
00321 
00322             cup[jcol] = clo[jcol];
00323           }
00324 
00325           fixed_cols[nfixed_cols++] = jcol;
00326         }
00327         PRESOLVEASSERT(uk == lk);
00328 
00329         action *f = &actions[nactions];
00330         nactions++;
00331 
00332         f->row = irow;
00333         f->nlo = lk-krs;
00334         f->nup = kre-uk;
00335         f->rowcols = rowcols;
00336         f->bounds = bounds;
00337       }
00338     }
00339   }
00340 
00341 
00342   if (nactions) {
00343 #if     PRESOLVE_SUMMARY
00344     printf("NFORCED:  %d\n", nactions);
00345 #endif
00346     next = new forcing_constraint_action(nactions, 
00347                                          copyOfArray(actions,nactions), next);
00348   }
00349   deleteAction(actions,action*);
00350   if (nuseless_rows) {
00351     next = useless_constraint_action::presolve(prob,
00352                                                useless_rows, nuseless_rows,
00353                                                next);
00354   }
00355   delete[]useless_rows;
00356 
00357   if (nfixed_cols) {
00358     next = remove_fixed_action::presolve(prob, fixed_cols, nfixed_cols, next);
00359   }
00360   delete[]fixed_cols;
00361 
00362   return (next);
00363 }
00364 
00365 void forcing_constraint_action::postsolve(CoinPostsolveMatrix *prob) const
00366 {
00367   const action *const actions = actions_;
00368   const int nactions = nactions_;
00369 
00370   const double *colels  = prob->colels_;
00371   const int *hrow               = prob->hrow_;
00372   const CoinBigIndex *mcstrt            = prob->mcstrt_;
00373   const int *hincol             = prob->hincol_;
00374   const int *link               = prob->link_;
00375 
00376   //  CoinBigIndex free_list = prob->free_list_;
00377 
00378   double *clo   = prob->clo_;
00379   double *cup   = prob->cup_;
00380 
00381   const double *sol     = prob->sol_;
00382   double *rcosts        = prob->rcosts_;
00383 
00384   //double *acts        = prob->acts_;
00385   double *rowduals = prob->rowduals_;
00386 
00387   const double ztoldj   = prob->ztoldj_;
00388   const double ztolzb   = prob->ztolzb_;
00389 
00390   for (const action *f = &actions[nactions-1]; actions<=f; f--) {
00391 
00392     const int irow      = f->row;
00393     const int nlo       = f->nlo;
00394     const int nup       = f->nup;
00395     const int ninrow    = nlo + nup;
00396     const int *rowcols  = f->rowcols;
00397     const double *bounds= f->bounds;
00398     int k;
00399 
00400     for (k=0; k<nlo; k++) {
00401       int jcol = rowcols[k];
00402       cup[jcol] = bounds[k];
00403       PRESOLVEASSERT(prob->getColumnStatus(jcol)!=CoinPrePostsolveMatrix::basic);
00404     }
00405 
00406     for (k=nlo; k<ninrow; k++) {
00407       int jcol = rowcols[k];
00408       clo[jcol] = bounds[k];
00409       PRESOLVEASSERT(prob->getColumnStatus(jcol)!=CoinPrePostsolveMatrix::basic);
00410     }
00411 
00412     PRESOLVEASSERT(prob->getRowStatus(irow)==CoinPrePostsolveMatrix::basic);
00413     PRESOLVEASSERT(rowduals[irow] == 0.0);
00414 
00415     // this is a lazy implementation.
00416     // we tightened the col bounds, then let them be eliminated
00417     // by repeated uses of FIX_VARIABLE and a final DROP_ROW.
00418     // Therefore, by this point the row has been marked basic,
00419     // the rowdual of this row is 0.0,
00420     // and the reduced costs for the cols may or may not be ok
00421     // for the relaxed column bounds.
00422     //
00423     // find the one most out of whack and fix it.
00424     int whacked = -1;
00425     double whack = 0.0;
00426     for (k=0; k<ninrow; k++) {
00427       int jcol = rowcols[k];
00428       CoinBigIndex kk = presolve_find_row2(irow, mcstrt[jcol], hincol[jcol], hrow, link);
00429 
00430       // choose rowdual to cancel out reduced cost
00431       double whack0 = rcosts[jcol] / colels[kk];
00432 
00433       if (((rcosts[jcol] > ztoldj  && !(fabs(sol[jcol] - clo[jcol]) <= ztolzb)) ||
00434            (rcosts[jcol] < -ztoldj && !(fabs(sol[jcol] - cup[jcol]) <= ztolzb))) &&
00435           fabs(whack0) > fabs(whack)) {
00436         whacked = jcol;
00437         whack = whack0;
00438       }
00439     }
00440 
00441     if (whacked != -1) {
00442       prob->setColumnStatus(whacked,CoinPrePostsolveMatrix::basic);
00443       prob->setRowStatus(irow,CoinPrePostsolveMatrix::atLowerBound);
00444       rowduals[irow] = whack;
00445 
00446       for (k=0; k<ninrow; k++) {
00447         int jcol = rowcols[k];
00448         CoinBigIndex kk = presolve_find_row2(irow, mcstrt[jcol], hincol[jcol], hrow, link);
00449               
00450         rcosts[jcol] -= (rowduals[irow] * colels[kk]);
00451       }
00452     }
00453   }
00454 }
00455 
00456 
00457 
00458 #if 0
00459 // Determine the maximum and minimum values the constraint sums
00460 // may take, given the bounds on the variables.
00461 // If there are infinite terms, record where the first one is,
00462 // and whether there is more than one.
00463 // It is possible to compute implied bounds for the (one) variable
00464 // with no bound.
00465 static void implied_bounds1(CoinPresolveMatrix * prob, const double *rowels,
00466                                 const int *mrstrt,
00467                                 const int *hrow,
00468                                 const int *hinrow,
00469                                 const double *clo, const double *cup,
00470                                 const int *hcol,
00471                                 int ncols,
00472                                 const double *rlo, const double *rup,
00473                                 const char *integerType,
00474                                 int nrows,
00475                                 double *ilbound, double *iubound)
00476 {
00477   const double tol = prob->feasibilityTolerance_;
00478 
00479   for (int irow=0; irow<nrows; irow++) {
00480     CoinBigIndex krs = mrstrt[irow];
00481     CoinBigIndex kre = krs + hinrow[irow];
00482 
00483     double irlo = rlo[irow];
00484     double irup = rup[irow];
00485 
00486     // These are used to set column bounds below.
00487     // If there are no (positive) infinite terms,
00488     // the loop will range from krs to kre;
00489     // if there is just one, it will range over that one variable;
00490     // otherwise, it will be empty.
00491     int ub_inf_index = -1;
00492     int lb_inf_index = -1;
00493 
00494     double maxup = 0.0;
00495     double maxdown = 0.0;
00496     CoinBigIndex k;
00497     for (k=krs; k<kre; k++) {
00498       int jcol = hcol[k];
00499       double coeff = rowels[k];
00500       double lb = clo[jcol];
00501       double ub = cup[jcol];
00502 
00503       // HAVE TO DEAL WITH BOUNDS OF INTEGER VARIABLES
00504       if (coeff > 0.0) {
00505         if (PRESOLVE_INF <= ub) {
00506           if (ub_inf_index == -1) {
00507             ub_inf_index = k;
00508           } else {
00509             ub_inf_index = -2;
00510             if (lb_inf_index == -2)
00511               break;    // pointless
00512           }
00513         } else
00514           maxup += ub * coeff;
00515 
00516         if (lb <= -PRESOLVE_INF) {
00517           if (lb_inf_index == -1) {
00518             lb_inf_index = k;
00519           } else {
00520             lb_inf_index = -2;
00521             if (ub_inf_index == -2)
00522               break;    // pointless
00523           }
00524         } else
00525           maxdown += lb * coeff;
00526       }
00527       else {
00528         if (PRESOLVE_INF <= ub) {
00529           if (lb_inf_index == -1) {
00530             lb_inf_index = k;
00531           } else {
00532             lb_inf_index = -2;
00533             if (ub_inf_index == -2)
00534               break;    // pointless
00535           }
00536         } else
00537           maxdown += ub * coeff;
00538 
00539         if (lb <= -PRESOLVE_INF) {
00540           if (ub_inf_index == -1) {
00541             ub_inf_index = k;
00542           } else {
00543             ub_inf_index = -2;
00544             if (lb_inf_index == -2)
00545               break;    // pointless
00546           }
00547         } else
00548           maxup += lb * coeff;
00549       }
00550     }
00551 
00552     // ub_inf says whether the sum of the "other" ub terms is infinite
00553     // in the loop below.
00554     // In the case where we only saw one infinite term, the loop
00555     // will only cover that case, in which case the other terms
00556     // are *not* infinite.
00557     // With two or more terms, it is infinite.
00558     // If we only saw one infinite term, then
00559     if (ub_inf_index == -2)
00560       maxup = PRESOLVE_INF;
00561 
00562     if (lb_inf_index == -2)
00563       maxdown = -PRESOLVE_INF;
00564 
00565     const bool maxup_finite = PRESOLVEFINITE(maxup);
00566     const bool maxdown_finite = PRESOLVEFINITE(maxdown);
00567 
00568     if (ub_inf_index == -1 && maxup_finite && maxup + tol < rlo[irow]) {
00569       /* infeasible */
00570         prob->status_|= 1;
00571         prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00572                                              prob->messages())
00573                                                <<irow
00574                                                <<rlo[irow]
00575                                                <<rup[irow]
00576                                                <<CoinMessageEol;
00577         break;
00578     } else if (lb_inf_index == -1 && maxdown_finite && rup[irow] < maxdown - tol) {
00579       /* infeasible */
00580         prob->status_|= 1;
00581         prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00582                                              prob->messages())
00583                                                <<irow
00584                                                <<rlo[irow]
00585                                                <<rup[irow]
00586                                                <<CoinMessageEol;
00587         break;
00588     }
00589 
00590     for (k = krs; k<kre; ++k) {
00591       int jcol = hcol[k];
00592       double coeff = rowels[k];
00593 
00594       // SHOULD GET RID OF THIS
00595       if (fabs(coeff) > ZTOLDP &&
00596           !integerType[jcol]) {
00597         double maxup1 = (ub_inf_index == -1 || ub_inf_index == k
00598                          ? maxup
00599                          : PRESOLVE_INF);
00600         bool maxup_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00601                               ? maxup_finite
00602                               : false);
00603         double maxdown1 = (lb_inf_index == -1 || lb_inf_index == k
00604                          ? maxdown
00605                          : PRESOLVE_INF);
00606         bool maxdown_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00607                               ? maxdown_finite
00608                               : false);
00609 
00610         double ilb = (irlo - maxup1) / coeff;
00611         bool finite_ilb = (-PRESOLVE_INF < irlo && maxup_finite1);
00612 
00613         double iub = (irup - maxdown1) / coeff;
00614         bool finite_iub = ( irup < PRESOLVE_INF && maxdown_finite1);
00615 
00616         double ilb1 = (coeff > 0.0
00617                        ? (finite_ilb ? ilb : -PRESOLVE_INF)
00618                        : (finite_iub ? iub : -PRESOLVE_INF));
00619 
00620         if (ilbound[jcol] < ilb1) {
00621           ilbound[jcol] = ilb1;
00622           if (jcol == 278001)
00623             printf("JCOL LB %g\n", ilb1);
00624         }
00625       }
00626     }
00627 
00628     for (k = krs; k<kre; ++k) {
00629       int jcol = hcol[k];
00630       double coeff = rowels[k];
00631 
00632       // SHOULD GET RID OF THIS
00633       if (fabs(coeff) > ZTOLDP &&
00634           !integerType[jcol]) {
00635         double maxup1 = (ub_inf_index == -1 || ub_inf_index == k
00636                          ? maxup
00637                          : PRESOLVE_INF);
00638         bool maxup_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00639                               ? maxup_finite
00640                               : false);
00641         double maxdown1 = (lb_inf_index == -1 || lb_inf_index == k
00642                          ? maxdown
00643                          : PRESOLVE_INF);
00644         bool maxdown_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00645                               ? maxdown_finite
00646                               : false);
00647 
00648 
00649         double ilb = (irlo - maxup1) / coeff;
00650         bool finite_ilb = (-PRESOLVE_INF < irlo && maxup_finite1);
00651 
00652         double iub = (irup - maxdown1) / coeff;
00653         bool finite_iub = ( irup < PRESOLVE_INF && maxdown_finite1);
00654 
00655         double iub1 = (coeff > 0.0
00656                        ? (finite_iub ? iub :  PRESOLVE_INF)
00657                        : (finite_ilb ? ilb :  PRESOLVE_INF));
00658 
00659         if (iub1 < iubound[jcol]) {
00660           iubound[jcol] = iub1;
00661           if (jcol == 278001)
00662             printf("JCOL UB %g\n", iub1);
00663         }
00664       }
00665     }
00666   }
00667 }
00668 
00669 #if 0
00670 postsolve for implied_bound
00671         {
00672           double lo0    = pa->clo;
00673           double up0    = pa->cup;
00674           int irow      = pa->irow;
00675           int jcol      = pa->icol;
00676           int *rowcols  = pa->rowcols;
00677           int ninrow    = pa->ninrow;
00678 
00679           clo[jcol] = lo0;
00680           cup[jcol] = up0;
00681 
00682           if ((colstat[jcol] & PRESOLVE_XBASIC) == 0 &&
00683               fabs(lo0 - sol[jcol]) > ztolzb &&
00684               fabs(up0 - sol[jcol]) > ztolzb) {
00685 
00686             // this non-basic variable is now away from its bound
00687             // it is ok just to force it to be basic
00688             // informally:  if this variable is at its implied bound,
00689             // then the other variables must be at their bounds,
00690             // which means the bounds will stop them even if the aren't basic.
00691             if (rowstat[irow] & PRESOLVE_XBASIC)
00692               rowstat[irow] = 0;
00693             else {
00694               int k;
00695               for (k=0; k<ninrow; k++) {
00696                 int col = rowcols[k];
00697                 if (cdone[col] &&
00698                     (colstat[col] & PRESOLVE_XBASIC) &&
00699                     ((fabs(clo[col] - sol[col]) <= ztolzb && rcosts[col] >= -ztoldj) || 
00700                      (fabs(cup[col] - sol[col]) <= ztolzb && rcosts[col] <= ztoldj)))
00701                   break;
00702               }
00703               if (k<ninrow) {
00704                 int col = rowcols[k];
00705                 // steal this basic variable
00706 #if     DEBUG_PRESOLVE
00707                 printf("PIVOTING ON COL:  %d %d -> %d\n", irow, col, jcol);
00708 #endif
00709                 colstat[col] = 0;
00710 
00711                 // since all vars were at their bounds, the slack must be 0
00712                 PRESOLVEASSERT(fabs(acts[irow]) < ZTOLDP);
00713                 rowstat[irow] = PRESOLVE_XBASIC;
00714               }
00715               else {
00716                 // should never happen?
00717                 abort();
00718               }
00719 
00720               // get rid of any remaining basic structurals, since their rcosts
00721               // are going to become non-zero in a second.
00722               abort();
00724             }
00725 
00726             double rdual_adjust;
00727             {
00728               CoinBigIndex kk = presolve_find_row(irow, mcstrt[jcol], mcstrt[jcol] + hincol[jcol], hrow);
00729               // adjust rowdual to cancel out reduced cost
00730               // should probably search for col with largest factor
00731               rdual_adjust = (rcosts[jcol] / colels[kk]);
00732               rowduals[irow] += rdual_adjust;
00733               colstat[jcol] = PRESOLVE_XBASIC;
00734             }
00735 
00736             for (k=0; k<ninrow; k++) {
00737               int jcol = rowcols[k];
00738               CoinBigIndex kk = presolve_find_row(irow, mcstrt[jcol], mcstrt[jcol] + hincol[jcol], hrow);
00739               
00740               rcosts[jcol] -= (rdual_adjust * colels[kk]);
00741             }
00742 
00743             {
00744               int k;
00745               int badbasic = -1;
00746 
00747               // we may have just screwed up the rcost of another basic variable
00748               for (k=0; k<ninrow; k++) {
00749                 int col = rowcols[k];
00750                 if (col != jcol &&
00751                     cdone[col] &&
00752                     (colstat[col] & PRESOLVE_XBASIC) &&
00753                     !(fabs(rcosts[col]) < ztoldj))
00754                   if (badbasic == -1)
00755                     badbasic = k;
00756                   else
00757                     abort();    // two!!  what to do???
00758               }
00759 
00760               if (badbasic != -1) {
00761                 int col = rowcols[badbasic];
00762 
00763                 if (fabs(acts[irow]) < ZTOLDP) {
00764 #if     DEBUG_PRESOLVE
00765                   printf("PIVOTING COL TO SLACK!:  %d %d\n", irow, col);
00766 #endif
00767                   colstat[col] = 0;
00768                   rowstat[irow] = PRESOLVE_XBASIC;
00769                 }
00770                 else
00771                   abort();
00772               }
00773             }
00774           }
00775         }
00776 #endif
00777 #endif
00778 forcing_constraint_action::~forcing_constraint_action() 
00779 { 
00780   int i;
00781   for (i=0;i<nactions_;i++) {
00782     //delete [] actions_[i].rowcols; MS Visual C++ V6 can not compile
00783     //delete [] actions_[i].bounds; MS Visual C++ V6 can not compile
00784     deleteAction(actions_[i].rowcols,int *);
00785     deleteAction(actions_[i].bounds,double *);
00786   }
00787   // delete [] actions_; MS Visual C++ V6 can not compile
00788   deleteAction(actions_,action *);
00789 }
00790 
00791 
00792 

Generated on Wed Dec 3 14:34:22 2003 for Coin by doxygen 1.3.5