Ignore:
Timestamp:
Jan 6, 2019 2:43:06 PM (4 months ago)
Author:
unxusr
Message:

formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Clp/src/ClpPEDualRowSteepest.cpp

    r2150 r2385  
    2626//-------------------------------------------------------------------
    2727ClpPEDualRowSteepest::ClpPEDualRowSteepest(double psi, int mode)
    28 : ClpDualRowSteepest(mode), modelPE_(NULL), psi_(psi),
    29 iCurrent_(0), iInterval_(100), updateCompatibles_(true),
    30 coDegenCompatibles_(0), coConsecutiveCompatibles_(0)
    31 {
    32         iInterval_ = 100;
     28  : ClpDualRowSteepest(mode)
     29  , modelPE_(NULL)
     30  , psi_(psi)
     31  , iCurrent_(0)
     32  , iInterval_(100)
     33  , updateCompatibles_(true)
     34  , coDegenCompatibles_(0)
     35  , coConsecutiveCompatibles_(0)
     36{
     37  iInterval_ = 100;
    3338}
    3439
     
    3641// Copy constructor
    3742//-------------------------------------------------------------------
    38 ClpPEDualRowSteepest::ClpPEDualRowSteepest(const ClpPEDualRowSteepest & source)
    39 : ClpDualRowSteepest(source)
    40 {
    41         modelPE_    = NULL;
    42         psi_        = source.psi_;
    43         iCurrent_  = source.iCurrent_;
    44         iInterval_ = source.iInterval_;
    45         updateCompatibles_ = source.updateCompatibles_;
    46         coDegenCompatibles_ = source.coDegenCompatibles_;
    47         coConsecutiveCompatibles_ = source.coConsecutiveCompatibles_;
     43ClpPEDualRowSteepest::ClpPEDualRowSteepest(const ClpPEDualRowSteepest &source)
     44  : ClpDualRowSteepest(source)
     45{
     46  modelPE_ = NULL;
     47  psi_ = source.psi_;
     48  iCurrent_ = source.iCurrent_;
     49  iInterval_ = source.iInterval_;
     50  updateCompatibles_ = source.updateCompatibles_;
     51  coDegenCompatibles_ = source.coDegenCompatibles_;
     52  coConsecutiveCompatibles_ = source.coConsecutiveCompatibles_;
    4853}
    4954
     
    5156// Destructor
    5257//-------------------------------------------------------------------
    53 ClpPEDualRowSteepest::~ClpPEDualRowSteepest ()
     58ClpPEDualRowSteepest::~ClpPEDualRowSteepest()
    5459{
    5560  delete modelPE_;
     
    6065//-------------------------------------------------------------------
    6166ClpPEDualRowSteepest &
    62 ClpPEDualRowSteepest::operator=(const ClpPEDualRowSteepest& rhs)
    63 {
    64         if (this != &rhs) {
    65                 ClpDualRowSteepest::operator=(rhs);
    66                 delete modelPE_;
    67                 modelPE_=NULL;
    68         }
    69         return *this;
     67ClpPEDualRowSteepest::operator=(const ClpPEDualRowSteepest &rhs)
     68{
     69  if (this != &rhs) {
     70    ClpDualRowSteepest::operator=(rhs);
     71    delete modelPE_;
     72    modelPE_ = NULL;
     73  }
     74  return *this;
    7075}
    7176
     
    7378// Clone
    7479//-------------------------------------------------------------------
    75 ClpDualRowPivot * ClpPEDualRowSteepest::clone(bool CopyData) const
    76 {
    77         if (CopyData) {
    78                 return new ClpPEDualRowSteepest(*this);
    79         } else {
    80                 return new ClpPEDualRowSteepest(psi_);
    81         }
     80ClpDualRowPivot *ClpPEDualRowSteepest::clone(bool CopyData) const
     81{
     82  if (CopyData) {
     83    return new ClpPEDualRowSteepest(*this);
     84  } else {
     85    return new ClpPEDualRowSteepest(psi_);
     86  }
    8287}
    8388//extern int thinkDegenerate;
    8489// Returns pivot row, -1 if none
    85 int
    86 ClpPEDualRowSteepest::pivotRow()
    87 {
    88         assert(model_);
    89 
    90 // Determine whether the set of compatible variables should be updated
    91 //
    92 // store the number of degenerate pivots on compatible variables and the
    93 // overal number of degenerate pivots
    94         //double progress = fabs(modelPE_->lastObjectiveValue() - model_->objectiveValue());
    95         //bool isLastDegenerate = progress <= 1.0e-12*fabs(model_->objectiveValue()) ? true:false;
    96         bool isLastDegenerate = fabs(model_->theta()) < 1.0e-7;
    97         bool isLastDegenerate2;
    98         // could fine tune a bit e.g. use 0.0 rather than tolerance
    99         if (model_->directionIn()>0) {
    100           // coming in from lower bound
    101           isLastDegenerate2 = (model_->dualIn()<model_->dualTolerance());
    102         } else {
    103           // coming in from upper bound
    104           isLastDegenerate2 = (model_->dualIn()>-model_->dualTolerance());
    105         }
     90int ClpPEDualRowSteepest::pivotRow()
     91{
     92  assert(model_);
     93
     94  // Determine whether the set of compatible variables should be updated
     95  //
     96  // store the number of degenerate pivots on compatible variables and the
     97  // overal number of degenerate pivots
     98  //double progress = fabs(modelPE_->lastObjectiveValue() - model_->objectiveValue());
     99  //bool isLastDegenerate = progress <= 1.0e-12*fabs(model_->objectiveValue()) ? true:false;
     100  bool isLastDegenerate = fabs(model_->theta()) < 1.0e-7;
     101  bool isLastDegenerate2;
     102  // could fine tune a bit e.g. use 0.0 rather than tolerance
     103  if (model_->directionIn() > 0) {
     104    // coming in from lower bound
     105    isLastDegenerate2 = (model_->dualIn() < model_->dualTolerance());
     106  } else {
     107    // coming in from upper bound
     108    isLastDegenerate2 = (model_->dualIn() > -model_->dualTolerance());
     109  }
    106110#if 0
    107111        if ( isLastDegenerate2 &&!isLastDegenerate)
     
    118122        //printf("PE thinks non degenerate - dualColumn says yes\n");
    119123#else
    120         isLastDegenerate=isLastDegenerate2;
    121 #endif
    122         if ( isLastDegenerate ) {
    123                 modelPE_->addDegeneratePivot();
    124                 modelPE_->addDegeneratePivotConsecutive();
    125 
    126                 if ( modelPE_->isLastPivotCompatible() ) {
    127                         modelPE_->addDegenerateCompatiblePivot();
    128                 }
    129         }
    130         else {
    131                 modelPE_->resetDegeneratePivotsConsecutive();
    132         }
    133 
    134 // the compatible variables are updated when the number of degenerate pivots
    135 // on compatible variables is more than 20% the overall number of degenerate pivots
    136         if ( modelPE_->isLastPivotCompatible() ) {
    137                 coConsecutiveCompatibles_++;
    138                 if (isLastDegenerate) {
    139                         coDegenCompatibles_++;
    140                         if ( coConsecutiveCompatibles_ >= 10 && 5*coDegenCompatibles_*model_->numberIterations() > modelPE_->coDegeneratePivots()*coConsecutiveCompatibles_ )  {
    141                                 updateCompatibles_ = true;
    142                         }
    143                 }
    144         }
    145 
    146 // For results comparison.
    147 // count the number of degenerate variables if psi==1
    148 // add the time spent in counting to the time limit
    149 //
    150         if (modelPE_->doStatistics()) {
    151         modelPE_->startTimer();
    152         if (psi_ >= 1 && iCurrent_ >= 100)  {
    153                 modelPE_->updateDualDegenerates();
    154                 modelPE_->updateDualDegeneratesAvg(100);
    155                 model_->setMaximumSeconds(36000.0+modelPE_->timeCompatibility()-CoinCpuTime());
    156                 iCurrent_ = 0;
    157         }
    158         modelPE_->stopTimer();
    159         }
    160 
    161 
    162 // Update the set of compatible variables if necessary
    163 //
    164         if (modelPE_->doStatistics())
    165         modelPE_->startTimer();
    166         double psiTmp = psi_;
    167         if ( (psi_ < 1.0) && (iCurrent_ >= iInterval_) && (updateCompatibles_||iCurrent_ >= 1000 /*|| !model_->factorization()->pivots()*/) )
    168         {
    169 // the compatible variables are never updated if the last pivot is non degenerate
    170                 if (isLastDegenerate) {
    171                         modelPE_->updateDualDegenerates();
    172                         if (modelPE_->doStatistics()) {
    173                           for (int i=0;i<4;i++)
    174                             assert(!model_->rowArray(i)->getNumElements());
    175                         }
    176                         modelPE_->identifyCompatibleRows(model_->rowArray(2),
    177                                                          model_->rowArray(1));
    178                         if (modelPE_->doStatistics()>3) {
    179                           for (int i=0;i<4;i++)
    180                             assert(!model_->rowArray(i)->getNumElements());
    181                           char generalPrint[100];
    182                           sprintf(generalPrint,"updating - iCurrent,iInterval %d,%d degenerate pivots %d ? %d codegen since last %d",
    183                                  iCurrent_,iInterval_,
    184                                  modelPE_->coDegeneratePivots(),
    185                                  modelPE_->coDualDegenerates(),
    186                                  coDegenCompatibles_);
    187                           model_->messageHandler()->message(CLP_GENERAL,
    188                                                  *model_->messagesPointer())
    189                             << generalPrint << CoinMessageEol;
    190 // update the average number of degenerates and compatibles for statistics
    191                         modelPE_->updateDualDegeneratesAvg(iCurrent_);
    192                         modelPE_->updateCompatibleRowsAvg(iCurrent_);   
    193         }
     124  isLastDegenerate = isLastDegenerate2;
     125#endif
     126  if (isLastDegenerate) {
     127    modelPE_->addDegeneratePivot();
     128    modelPE_->addDegeneratePivotConsecutive();
     129
     130    if (modelPE_->isLastPivotCompatible()) {
     131      modelPE_->addDegenerateCompatiblePivot();
     132    }
     133  } else {
     134    modelPE_->resetDegeneratePivotsConsecutive();
     135  }
     136
     137  // the compatible variables are updated when the number of degenerate pivots
     138  // on compatible variables is more than 20% the overall number of degenerate pivots
     139  if (modelPE_->isLastPivotCompatible()) {
     140    coConsecutiveCompatibles_++;
     141    if (isLastDegenerate) {
     142      coDegenCompatibles_++;
     143      if (coConsecutiveCompatibles_ >= 10 && 5 * coDegenCompatibles_ * model_->numberIterations() > modelPE_->coDegeneratePivots() * coConsecutiveCompatibles_) {
     144        updateCompatibles_ = true;
     145      }
     146    }
     147  }
     148
     149  // For results comparison.
     150  // count the number of degenerate variables if psi==1
     151  // add the time spent in counting to the time limit
     152  //
     153  if (modelPE_->doStatistics()) {
     154    modelPE_->startTimer();
     155    if (psi_ >= 1 && iCurrent_ >= 100) {
     156      modelPE_->updateDualDegenerates();
     157      modelPE_->updateDualDegeneratesAvg(100);
     158      model_->setMaximumSeconds(36000.0 + modelPE_->timeCompatibility() - CoinCpuTime());
     159      iCurrent_ = 0;
     160    }
     161    modelPE_->stopTimer();
     162  }
     163
     164  // Update the set of compatible variables if necessary
     165  //
     166  if (modelPE_->doStatistics())
     167    modelPE_->startTimer();
     168  double psiTmp = psi_;
     169  if ((psi_ < 1.0) && (iCurrent_ >= iInterval_) && (updateCompatibles_ || iCurrent_ >= 1000 /*|| !model_->factorization()->pivots()*/)) {
     170    // the compatible variables are never updated if the last pivot is non degenerate
     171    if (isLastDegenerate) {
     172      modelPE_->updateDualDegenerates();
     173      if (modelPE_->doStatistics()) {
     174        for (int i = 0; i < 4; i++)
     175          assert(!model_->rowArray(i)->getNumElements());
     176      }
     177      modelPE_->identifyCompatibleRows(model_->rowArray(2),
     178        model_->rowArray(1));
     179      if (modelPE_->doStatistics() > 3) {
     180        for (int i = 0; i < 4; i++)
     181          assert(!model_->rowArray(i)->getNumElements());
     182        char generalPrint[100];
     183        sprintf(generalPrint, "updating - iCurrent,iInterval %d,%d degenerate pivots %d ? %d codegen since last %d",
     184          iCurrent_, iInterval_,
     185          modelPE_->coDegeneratePivots(),
     186          modelPE_->coDualDegenerates(),
     187          coDegenCompatibles_);
     188        model_->messageHandler()->message(CLP_GENERAL,
     189          *model_->messagesPointer())
     190          << generalPrint << CoinMessageEol;
     191        // update the average number of degenerates and compatibles for statistics
     192        modelPE_->updateDualDegeneratesAvg(iCurrent_);
     193        modelPE_->updateCompatibleRowsAvg(iCurrent_);
     194      }
    194195#if PE_DEBUG >= 1
    195                         std::cout << "Number of compatible rows = " << modelPE_->coCompatibleRows() << " ; average  = " << modelPE_->coCompatibleRowsAvg() <<  std::endl;
    196                         std::cout << "Number of degenerates = " << modelPE_->coDualDegenerates() << " ; average  = " << modelPE_->coDualDegeneratesAvg() <<  std::endl;
    197 #endif
    198 
    199 // the checking frequency is modified to reflect what appears to be needed
    200                         if (iCurrent_ == iInterval_) iInterval_ = std::max(50, iInterval_-50);
    201                         else                                                              iInterval_ = std::min(300, iInterval_+50);
    202 
    203 // reset all the indicators that are used to decide whether the compatible
    204 // variables must be updated
    205                         iCurrent_ = 0;
    206                         updateCompatibles_ = false;
    207                         coConsecutiveCompatibles_ = 0;
    208                         coDegenCompatibles_ = 0;
    209                 }
    210                 else {
     196      std::cout << "Number of compatible rows = " << modelPE_->coCompatibleRows() << " ; average  = " << modelPE_->coCompatibleRowsAvg() << std::endl;
     197      std::cout << "Number of degenerates = " << modelPE_->coDualDegenerates() << " ; average  = " << modelPE_->coDualDegeneratesAvg() << std::endl;
     198#endif
     199
     200      // the checking frequency is modified to reflect what appears to be needed
     201      if (iCurrent_ == iInterval_)
     202        iInterval_ = std::max(50, iInterval_ - 50);
     203      else
     204        iInterval_ = std::min(300, iInterval_ + 50);
     205
     206      // reset all the indicators that are used to decide whether the compatible
     207      // variables must be updated
     208      iCurrent_ = 0;
     209      updateCompatibles_ = false;
     210      coConsecutiveCompatibles_ = 0;
     211      coDegenCompatibles_ = 0;
     212    } else {
    211213#if 0
    212214                  if ((iCurrent_%500)==0)
     
    217219                               coDegenCompatibles_);
    218220#endif
    219                   iInterval_++;
    220                 }
    221         }
    222 // otherwise, update the value of the priority factor depending on the number of
    223 // consecutive degenerate pivots
    224 //
    225         else {
    226 // the idea is that when a lot of consecutive pivots are degenerate, there is
    227 // a potentially high added value in putting a very high priroity on compatible
    228 // variables
    229                 if (modelPE_->coDegeneratePivotsConsecutive() >= 10) {
    230                   //psiTmp = 0.01;
    231                         psiTmp = 0.25*psi_;
     221      iInterval_++;
     222    }
     223  }
     224  // otherwise, update the value of the priority factor depending on the number of
     225  // consecutive degenerate pivots
     226  //
     227  else {
     228    // the idea is that when a lot of consecutive pivots are degenerate, there is
     229    // a potentially high added value in putting a very high priroity on compatible
     230    // variables
     231    if (modelPE_->coDegeneratePivotsConsecutive() >= 10) {
     232      //psiTmp = 0.01;
     233      psiTmp = 0.25 * psi_;
    232234
    233235#if PE_DEBUG >= 1
    234                         std::cout << "Lower the priority factor to " << psiTmp << std::endl;
    235                         std::cout << "Consecutive degenerate pivots=" << modelPE_->coDegeneratePivotsConsecutive() << std::endl;
    236 #endif
    237                 }
    238         }
    239         iCurrent_++;
    240         if (modelPE_->doStatistics())
    241         modelPE_->stopTimer();
    242 
    243 // Do the pricing and give priority to dual compatible variables
    244 //
    245         int i, iRow;
    246         double * infeas = infeasible_->denseVector();
    247         double largest = 0.0;
    248         int * index = infeasible_->getIndices();
    249         int number = infeasible_->getNumElements();
    250         const int * pivotVariable = model_->pivotVariable();
    251         int chosenRow = -1;
    252         int lastPivotRow = model_->pivotRow();
    253         assert (lastPivotRow < model_->numberRows());
    254         double tolerance = model_->currentPrimalTolerance();
    255 // we can't really trust infeasibilities if there is primal error
    256 // this coding has to mimic coding in checkPrimalSolution
    257         double error = CoinMin(1.0e-2, model_->largestPrimalError());
    258 // allow tolerance at least slightly bigger than standard
    259         tolerance = tolerance + error;
    260 // But cap
    261         tolerance = CoinMin(1000.0, tolerance);
    262 tolerance *= tolerance; // as we are using squares
    263 bool toleranceChanged = false;
    264 double * solution = model_->solutionRegion();
    265 double * lower = model_->lowerRegion();
    266 double * upper = model_->upperRegion();
    267 // do last pivot row one here
    268 //#define CLP_DUAL_FIXED_COLUMN_MULTIPLIER 10.0
    269 if (lastPivotRow >= 0 && lastPivotRow < model_->numberRows()) {
     236      std::cout << "Lower the priority factor to " << psiTmp << std::endl;
     237      std::cout << "Consecutive degenerate pivots=" << modelPE_->coDegeneratePivotsConsecutive() << std::endl;
     238#endif
     239    }
     240  }
     241  iCurrent_++;
     242  if (modelPE_->doStatistics())
     243    modelPE_->stopTimer();
     244
     245  // Do the pricing and give priority to dual compatible variables
     246  //
     247  int i, iRow;
     248  double *infeas = infeasible_->denseVector();
     249  double largest = 0.0;
     250  int *index = infeasible_->getIndices();
     251  int number = infeasible_->getNumElements();
     252  const int *pivotVariable = model_->pivotVariable();
     253  int chosenRow = -1;
     254  int lastPivotRow = model_->pivotRow();
     255  assert(lastPivotRow < model_->numberRows());
     256  double tolerance = model_->currentPrimalTolerance();
     257  // we can't really trust infeasibilities if there is primal error
     258  // this coding has to mimic coding in checkPrimalSolution
     259  double error = CoinMin(1.0e-2, model_->largestPrimalError());
     260  // allow tolerance at least slightly bigger than standard
     261  tolerance = tolerance + error;
     262  // But cap
     263  tolerance = CoinMin(1000.0, tolerance);
     264  tolerance *= tolerance; // as we are using squares
     265  bool toleranceChanged = false;
     266  double *solution = model_->solutionRegion();
     267  double *lower = model_->lowerRegion();
     268  double *upper = model_->upperRegion();
     269  // do last pivot row one here
     270  //#define CLP_DUAL_FIXED_COLUMN_MULTIPLIER 10.0
     271  if (lastPivotRow >= 0 && lastPivotRow < model_->numberRows()) {
    270272#ifdef CLP_DUAL_COLUMN_MULTIPLIER
    271         int numberColumns = model_->numberColumns();
    272 #endif
    273         int iPivot = pivotVariable[lastPivotRow];
    274         double value = solution[iPivot];
    275         double lower = model_->lower(iPivot);
    276         double upper = model_->upper(iPivot);
    277         if (value > upper + tolerance) {
    278                 value -= upper;
    279                 value *= value;
     273    int numberColumns = model_->numberColumns();
     274#endif
     275    int iPivot = pivotVariable[lastPivotRow];
     276    double value = solution[iPivot];
     277    double lower = model_->lower(iPivot);
     278    double upper = model_->upper(iPivot);
     279    if (value > upper + tolerance) {
     280      value -= upper;
     281      value *= value;
    280282#ifdef CLP_DUAL_COLUMN_MULTIPLIER
    281                 if (iPivot < numberColumns)
    282 value *= CLP_DUAL_COLUMN_MULTIPLIER; // bias towards columns
    283 #endif
    284 // store square in list
    285 if (infeas[lastPivotRow])
    286 infeas[lastPivotRow] = value; // already there
    287 else
    288         infeasible_->quickAdd(lastPivotRow, value);
    289 } else if (value < lower - tolerance) {
    290         value -= lower;
    291         value *= value;
     283      if (iPivot < numberColumns)
     284        value *= CLP_DUAL_COLUMN_MULTIPLIER; // bias towards columns
     285#endif
     286      // store square in list
     287      if (infeas[lastPivotRow])
     288        infeas[lastPivotRow] = value; // already there
     289      else
     290        infeasible_->quickAdd(lastPivotRow, value);
     291    } else if (value < lower - tolerance) {
     292      value -= lower;
     293      value *= value;
    292294#ifdef CLP_DUAL_COLUMN_MULTIPLIER
    293         if (iPivot < numberColumns)
    294 value *= CLP_DUAL_COLUMN_MULTIPLIER; // bias towards columns
    295 #endif
    296 // store square in list
    297 if (infeas[lastPivotRow])
    298 infeas[lastPivotRow] = value; // already there
    299 else
    300         infeasible_->add(lastPivotRow, value);
    301 } else {
    302 // feasible - was it infeasible - if so set tiny
    303         if (infeas[lastPivotRow])
    304                 infeas[lastPivotRow] = COIN_INDEXED_REALLY_TINY_ELEMENT;
    305 }
    306 number = infeasible_->getNumElements();
    307 }
    308 if(model_->numberIterations() < model_->lastBadIteration() + 200) {
    309 // we can't really trust infeasibilities if there is dual error
    310         if (model_->largestDualError() > model_->largestPrimalError()) {
    311                 tolerance *= CoinMin(model_->largestDualError() / model_->largestPrimalError(), 1000.0);
    312                 toleranceChanged = true;
    313         }
    314 }
    315 int numberWanted;
    316 if (mode_ < 2 ) {
    317         numberWanted = number + 1;
    318 } else if (mode_ == 2) {
    319         numberWanted = CoinMax(2000, number / 8);
    320 } else {
    321         int numberElements = model_->factorization()->numberElements();
    322         double ratio = static_cast<double> (numberElements) /
    323         static_cast<double> (model_->numberRows());
    324         numberWanted = CoinMax(2000, number / 8);
    325         if (ratio < 1.0) {
    326                 numberWanted = CoinMax(2000, number / 20);
    327         } else if (ratio > 10.0) {
    328                 ratio = number * (ratio / 80.0);
    329                 if (ratio > number)
    330                         numberWanted = number + 1;
    331                 else
    332                         numberWanted = CoinMax(2000, static_cast<int> (ratio));
    333         }
    334 }
    335 if (model_->largestPrimalError() > 1.0e-3)
    336 numberWanted = number + 1; // be safe
    337 int iPass;
    338 // Setup two passes
    339 int start[4];
    340 start[1] = number;
    341 start[2] = 0;
    342 double dstart = static_cast<double> (number) * model_->randomNumberGenerator()->randomDouble();
    343 start[0] = static_cast<int> (dstart);
    344 start[3] = start[0];
    345 
    346 int chosenRowComp  = -1;
    347 double largestComp = 0.0;
    348 
    349 // only check the compatible variables when the bidimensional factor is less than 1
    350 // and the ratio of compatible variables is larger than 0.01
    351 // the percentage of compatible variables is computed as the ratio to the
    352 // smallest number among columns and rows
    353 bool checkCompatibles = true;
    354  double ratioCompatibles = static_cast<double> ( modelPE_->coCompatibleRows())/
    355    static_cast<double> (std::min(model_->numberRows(),model_->numberColumns()));
    356 
    357 if (psi_ >= 1.0|| ratioCompatibles < 0.01) checkCompatibles = false;
    358 
    359 
    360 // potentially, a partial pricing may be done
    361 for (iPass = 0; iPass < 2; iPass++) {
    362         int end = start[2*iPass+1];
    363         for (i = start[2*iPass]; i < end; i++) {
    364                 iRow = index[i];
    365                 double value = infeas[iRow];
    366                 if (value > tolerance) {
     295      if (iPivot < numberColumns)
     296        value *= CLP_DUAL_COLUMN_MULTIPLIER; // bias towards columns
     297#endif
     298      // store square in list
     299      if (infeas[lastPivotRow])
     300        infeas[lastPivotRow] = value; // already there
     301      else
     302        infeasible_->add(lastPivotRow, value);
     303    } else {
     304      // feasible - was it infeasible - if so set tiny
     305      if (infeas[lastPivotRow])
     306        infeas[lastPivotRow] = COIN_INDEXED_REALLY_TINY_ELEMENT;
     307    }
     308    number = infeasible_->getNumElements();
     309  }
     310  if (model_->numberIterations() < model_->lastBadIteration() + 200) {
     311    // we can't really trust infeasibilities if there is dual error
     312    if (model_->largestDualError() > model_->largestPrimalError()) {
     313      tolerance *= CoinMin(model_->largestDualError() / model_->largestPrimalError(), 1000.0);
     314      toleranceChanged = true;
     315    }
     316  }
     317  int numberWanted;
     318  if (mode_ < 2) {
     319    numberWanted = number + 1;
     320  } else if (mode_ == 2) {
     321    numberWanted = CoinMax(2000, number / 8);
     322  } else {
     323    int numberElements = model_->factorization()->numberElements();
     324    double ratio = static_cast< double >(numberElements) / static_cast< double >(model_->numberRows());
     325    numberWanted = CoinMax(2000, number / 8);
     326    if (ratio < 1.0) {
     327      numberWanted = CoinMax(2000, number / 20);
     328    } else if (ratio > 10.0) {
     329      ratio = number * (ratio / 80.0);
     330      if (ratio > number)
     331        numberWanted = number + 1;
     332      else
     333        numberWanted = CoinMax(2000, static_cast< int >(ratio));
     334    }
     335  }
     336  if (model_->largestPrimalError() > 1.0e-3)
     337    numberWanted = number + 1; // be safe
     338  int iPass;
     339  // Setup two passes
     340  int start[4];
     341  start[1] = number;
     342  start[2] = 0;
     343  double dstart = static_cast< double >(number) * model_->randomNumberGenerator()->randomDouble();
     344  start[0] = static_cast< int >(dstart);
     345  start[3] = start[0];
     346
     347  int chosenRowComp = -1;
     348  double largestComp = 0.0;
     349
     350  // only check the compatible variables when the bidimensional factor is less than 1
     351  // and the ratio of compatible variables is larger than 0.01
     352  // the percentage of compatible variables is computed as the ratio to the
     353  // smallest number among columns and rows
     354  bool checkCompatibles = true;
     355  double ratioCompatibles = static_cast< double >(modelPE_->coCompatibleRows()) / static_cast< double >(std::min(model_->numberRows(), model_->numberColumns()));
     356
     357  if (psi_ >= 1.0 || ratioCompatibles < 0.01)
     358    checkCompatibles = false;
     359
     360  // potentially, a partial pricing may be done
     361  for (iPass = 0; iPass < 2; iPass++) {
     362    int end = start[2 * iPass + 1];
     363    for (i = start[2 * iPass]; i < end; i++) {
     364      iRow = index[i];
     365      double value = infeas[iRow];
     366      if (value > tolerance) {
    367367//#define OUT_EQ
    368368#ifdef OUT_EQ
    369                         {
    370                                 int iSequence = pivotVariable[iRow];
    371                                 if (upper[iSequence] == lower[iSequence])
    372                                         value *= 2.0;
    373                         }
    374 #endif
    375                         double weight = CoinMin(weights_[iRow], 1.0e50);
    376                         double largestMax = std::max(psiTmp*largest, largestComp);
    377                         if (value >  weight * largestMax ) {
    378 // make last pivot row last resort choice
    379                                 if (iRow == lastPivotRow) {
    380                                         if (value * 1.0e-10 < largestMax * weight)
    381                                                 continue;
    382                                         else
    383                                                 value *= 1.0e-10;
    384                                 }
    385                                 int iSequence = pivotVariable[iRow];
    386                                 if (model_->flagged(iSequence)) {
    387 // just to make sure we don't exit before got something
    388                                         numberWanted++;
    389                                 }
    390                                 else if (checkCompatibles && modelPE_->isCompatibleRow(iRow) && value > weight * largestComp)   {
    391                                         chosenRowComp = iRow;
    392                                         largestComp = value / weight;
    393                                 }
    394                                 else if (value > largest * weight) {
    395                                         chosenRow = iRow;
    396                                         largest = value / weight;
    397                                 }
    398                         }
    399                         numberWanted--;
    400                         if (!numberWanted)
    401                                 break;
    402                 }
    403         }
    404         if (!numberWanted)
    405                 break;
    406 }
    407 // choose the a compatible or an incompatible row depending on the
    408 // largest values and on the factor of preference psiTmp
    409  if (modelPE_->doStatistics())
    410 modelPE_->startTimer();
    411 if ( chosenRowComp >= 0 && largestComp >= psiTmp * largest)  {
    412 
    413   if (modelPE_->doStatistics()) {
    414 // record the number of pivots done on compatible variables
    415 // that would not have been done without positive edge
    416         if (largestComp < largest)
    417                 modelPE_->addPriorityPivot();
     369        {
     370          int iSequence = pivotVariable[iRow];
     371          if (upper[iSequence] == lower[iSequence])
     372            value *= 2.0;
     373        }
     374#endif
     375        double weight = CoinMin(weights_[iRow], 1.0e50);
     376        double largestMax = std::max(psiTmp * largest, largestComp);
     377        if (value > weight * largestMax) {
     378          // make last pivot row last resort choice
     379          if (iRow == lastPivotRow) {
     380            if (value * 1.0e-10 < largestMax * weight)
     381              continue;
     382            else
     383              value *= 1.0e-10;
     384          }
     385          int iSequence = pivotVariable[iRow];
     386          if (model_->flagged(iSequence)) {
     387            // just to make sure we don't exit before got something
     388            numberWanted++;
     389          } else if (checkCompatibles && modelPE_->isCompatibleRow(iRow) && value > weight * largestComp) {
     390            chosenRowComp = iRow;
     391            largestComp = value / weight;
     392          } else if (value > largest * weight) {
     393            chosenRow = iRow;
     394            largest = value / weight;
     395          }
     396        }
     397        numberWanted--;
     398        if (!numberWanted)
     399          break;
     400      }
     401    }
     402    if (!numberWanted)
     403      break;
     404  }
     405  // choose the a compatible or an incompatible row depending on the
     406  // largest values and on the factor of preference psiTmp
     407  if (modelPE_->doStatistics())
     408    modelPE_->startTimer();
     409  if (chosenRowComp >= 0 && largestComp >= psiTmp * largest) {
     410
     411    if (modelPE_->doStatistics()) {
     412      // record the number of pivots done on compatible variables
     413      // that would not have been done without positive edge
     414      if (largestComp < largest)
     415        modelPE_->addPriorityPivot();
    418416#if 0
    419417        if (largestComp < largest)
     
    424422                 chosenRowComp,largestComp,largest);
    425423#endif
    426   }
    427         chosenRow = chosenRowComp;
     424    }
     425    chosenRow = chosenRowComp;
    428426
    429427#if PE_DEBUG >= 1
    430         modelPE_->checkCompatibilityRow(chosenRow);
    431 #endif
    432 }
    433 if ( chosenRow >= 0 && psiTmp < 1.0 && modelPE_->isCompatibleRow(chosenRow) ) {
    434         modelPE_->isLastPivotCompatible(true);
    435         modelPE_->addCompatiblePivot();
    436 }
    437 else modelPE_->isLastPivotCompatible(false);
    438 
    439  if (modelPE_->doStatistics())
    440 modelPE_->stopTimer();
    441 
    442 if (chosenRow < 0 && toleranceChanged) {
    443 // won't line up with checkPrimalSolution - do again
    444         double saveError = model_->largestDualError();
    445         model_->setLargestDualError(0.0);
    446 // can't loop
    447         chosenRow = pivotRow();
    448         model_->setLargestDualError(saveError);
    449 }
    450 if (chosenRow < 0 && lastPivotRow < 0) {
    451         int nLeft = 0;
    452         for (int i = 0; i < number; i++) {
    453                 int iRow = index[i];
    454                 if (fabs(infeas[iRow]) > 1.0e-50) {
    455                         index[nLeft++] = iRow;
    456                 } else {
    457                         infeas[iRow] = 0.0;
    458                 }
    459         }
    460         infeasible_->setNumElements(nLeft);
    461         model_->setNumberPrimalInfeasibilities(nLeft);
    462 }
    463 
    464 modelPE_->updateLastObjectiveValue();
    465 return chosenRow;
     428    modelPE_->checkCompatibilityRow(chosenRow);
     429#endif
     430  }
     431  if (chosenRow >= 0 && psiTmp < 1.0 && modelPE_->isCompatibleRow(chosenRow)) {
     432    modelPE_->isLastPivotCompatible(true);
     433    modelPE_->addCompatiblePivot();
     434  } else
     435    modelPE_->isLastPivotCompatible(false);
     436
     437  if (modelPE_->doStatistics())
     438    modelPE_->stopTimer();
     439
     440  if (chosenRow < 0 && toleranceChanged) {
     441    // won't line up with checkPrimalSolution - do again
     442    double saveError = model_->largestDualError();
     443    model_->setLargestDualError(0.0);
     444    // can't loop
     445    chosenRow = pivotRow();
     446    model_->setLargestDualError(saveError);
     447  }
     448  if (chosenRow < 0 && lastPivotRow < 0) {
     449    int nLeft = 0;
     450    for (int i = 0; i < number; i++) {
     451      int iRow = index[i];
     452      if (fabs(infeas[iRow]) > 1.0e-50) {
     453        index[nLeft++] = iRow;
     454      } else {
     455        infeas[iRow] = 0.0;
     456      }
     457    }
     458    infeasible_->setNumElements(nLeft);
     459    model_->setNumberPrimalInfeasibilities(nLeft);
     460  }
     461
     462  modelPE_->updateLastObjectiveValue();
     463  return chosenRow;
    466464}
    467465/* Save weights - this may initialize weights as well
    468466   This is as parent but may initialize ClpPESimplex
    469467*/
    470 void
    471 ClpPEDualRowSteepest::saveWeights(ClpSimplex * model, int mode)
     468void ClpPEDualRowSteepest::saveWeights(ClpSimplex *model, int mode)
    472469{
    473470  // See if we need to initialize ClpPESimplex
    474   if (!modelPE_||model!=modelPE_->clpModel()||
    475       !modelPE_->checkSize()) {
     471  if (!modelPE_ || model != modelPE_->clpModel() || !modelPE_->checkSize()) {
    476472    delete modelPE_;
    477473    modelPE_ = new ClpPESimplex(model);
    478474  }
    479   ClpDualRowSteepest::saveWeights(model,mode);
     475  ClpDualRowSteepest::saveWeights(model, mode);
    480476}
    481477/* Updates primal solution (and maybe list of candidates)
     
    484480   As ordinary steepest but checks for zero moves
    485481*/
    486 void
    487 ClpPEDualRowSteepest::updatePrimalSolution(CoinIndexedVector * input,
    488                                            double theta,
    489                                            double & changeInObjective)
     482void ClpPEDualRowSteepest::updatePrimalSolution(CoinIndexedVector *input,
     483  double theta,
     484  double &changeInObjective)
    490485{
    491486  int iColumn = model_->sequenceIn();
    492   if (iColumn>=0)
     487  if (iColumn >= 0)
    493488    modelPE_->updateCompatibleRows(iColumn);
    494   ClpDualRowSteepest::updatePrimalSolution(input,theta,changeInObjective);
    495 }
    496 
     489  ClpDualRowSteepest::updatePrimalSolution(input, theta, changeInObjective);
     490}
     491
     492/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
     493*/
Note: See TracChangeset for help on using the changeset viewer.