source: trunk/Clp/src/ClpDynamicExampleMatrix.cpp @ 2470

Last change on this file since 2470 was 2385, checked in by unxusr, 11 months ago

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 24.6 KB
Line 
1/* $Id: ClpDynamicExampleMatrix.cpp 2385 2019-01-06 19:43:06Z stefan $ */
2// Copyright (C) 2004, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include <cstdio>
7
8#include "CoinPragma.hpp"
9#include "CoinIndexedVector.hpp"
10#include "CoinHelperFunctions.hpp"
11
12#include "ClpSimplex.hpp"
13#include "ClpFactorization.hpp"
14#include "ClpQuadraticObjective.hpp"
15#include "ClpNonLinearCost.hpp"
16// at end to get min/max!
17#include "ClpDynamicExampleMatrix.hpp"
18#include "ClpMessage.hpp"
19//#define CLP_DEBUG
20//#define CLP_DEBUG_PRINT
21//#############################################################################
22// Constructors / Destructor / Assignment
23//#############################################################################
24
25//-------------------------------------------------------------------
26// Default Constructor
27//-------------------------------------------------------------------
28ClpDynamicExampleMatrix::ClpDynamicExampleMatrix()
29  : ClpDynamicMatrix()
30  , numberColumns_(0)
31  , startColumnGen_(NULL)
32  , rowGen_(NULL)
33  , elementGen_(NULL)
34  , costGen_(NULL)
35  , fullStartGen_(NULL)
36  , dynamicStatusGen_(NULL)
37  , idGen_(NULL)
38  , columnLowerGen_(NULL)
39  , columnUpperGen_(NULL)
40{
41  setType(25);
42}
43
44//-------------------------------------------------------------------
45// Copy constructor
46//-------------------------------------------------------------------
47ClpDynamicExampleMatrix::ClpDynamicExampleMatrix(const ClpDynamicExampleMatrix &rhs)
48  : ClpDynamicMatrix(rhs)
49{
50  numberColumns_ = rhs.numberColumns_;
51  startColumnGen_ = ClpCopyOfArray(rhs.startColumnGen_, numberColumns_ + 1);
52  CoinBigIndex numberElements = startColumnGen_[numberColumns_];
53  rowGen_ = ClpCopyOfArray(rhs.rowGen_, numberElements);
54  ;
55  elementGen_ = ClpCopyOfArray(rhs.elementGen_, numberElements);
56  ;
57  costGen_ = ClpCopyOfArray(rhs.costGen_, numberColumns_);
58  fullStartGen_ = ClpCopyOfArray(rhs.fullStartGen_, numberSets_ + 1);
59  dynamicStatusGen_ = ClpCopyOfArray(rhs.dynamicStatusGen_, numberColumns_);
60  idGen_ = ClpCopyOfArray(rhs.idGen_, maximumGubColumns_);
61  columnLowerGen_ = ClpCopyOfArray(rhs.columnLowerGen_, numberColumns_);
62  columnUpperGen_ = ClpCopyOfArray(rhs.columnUpperGen_, numberColumns_);
63}
64
65/* This is the real constructor*/
66ClpDynamicExampleMatrix::ClpDynamicExampleMatrix(ClpSimplex *model, int numberSets,
67  int numberGubColumns, const CoinBigIndex *starts,
68  const double *lower, const double *upper,
69  const CoinBigIndex *startColumn, const int *row,
70  const double *element, const double *cost,
71  const double *columnLower, const double *columnUpper,
72  const unsigned char *status,
73  const unsigned char *dynamicStatus,
74  int numberIds, const int *ids)
75  : ClpDynamicMatrix(model, numberSets, 0, NULL, lower, upper, NULL, NULL, NULL, NULL, NULL, NULL,
76      NULL, NULL)
77{
78  setType(25);
79  numberColumns_ = numberGubColumns;
80  // start with safe values - then experiment
81  maximumGubColumns_ = numberColumns_;
82  maximumElements_ = startColumn[numberColumns_];
83  // delete odd stuff created by ClpDynamicMatrix constructor
84  delete[] startSet_;
85  startSet_ = new int[numberSets_];
86  delete[] next_;
87  next_ = new int[maximumGubColumns_];
88  delete[] row_;
89  delete[] element_;
90  delete[] startColumn_;
91  delete[] cost_;
92  delete[] columnLower_;
93  delete[] columnUpper_;
94  delete[] dynamicStatus_;
95  delete[] status_;
96  delete[] id_;
97  // and size correctly
98  row_ = new int[maximumElements_];
99  element_ = new double[maximumElements_];
100  startColumn_ = new CoinBigIndex[maximumGubColumns_ + 1];
101  // say no columns yet
102  numberGubColumns_ = 0;
103  startColumn_[0] = 0;
104  cost_ = new double[maximumGubColumns_];
105  dynamicStatus_ = new unsigned char[2 * maximumGubColumns_];
106  memset(dynamicStatus_, 0, maximumGubColumns_);
107  id_ = new int[maximumGubColumns_];
108  if (columnLower)
109    columnLower_ = new double[maximumGubColumns_];
110  else
111    columnLower_ = NULL;
112  if (columnUpper)
113    columnUpper_ = new double[maximumGubColumns_];
114  else
115    columnUpper_ = NULL;
116  // space for ids
117  idGen_ = new int[maximumGubColumns_];
118  int iSet;
119  for (iSet = 0; iSet < numberSets_; iSet++)
120    startSet_[iSet] = -1;
121  // This starts code specific to this storage method
122  CoinBigIndex i;
123  fullStartGen_ = ClpCopyOfArray(starts, numberSets_ + 1);
124  startColumnGen_ = ClpCopyOfArray(startColumn, numberColumns_ + 1);
125  CoinBigIndex numberElements = startColumnGen_[numberColumns_];
126  rowGen_ = ClpCopyOfArray(row, numberElements);
127  elementGen_ = new double[numberElements];
128  for (i = 0; i < numberElements; i++)
129    elementGen_[i] = element[i];
130  costGen_ = new double[numberColumns_];
131  for (i = 0; i < numberColumns_; i++) {
132    costGen_[i] = cost[i];
133    // I don't think I need sorted but ...
134    CoinSort_2(rowGen_ + startColumnGen_[i], rowGen_ + startColumnGen_[i + 1], elementGen_ + startColumnGen_[i]);
135  }
136  if (columnLower) {
137    columnLowerGen_ = new double[numberColumns_];
138    for (i = 0; i < numberColumns_; i++) {
139      columnLowerGen_[i] = columnLower[i];
140      if (columnLowerGen_[i]) {
141        printf("Non-zero lower bounds not allowed - subtract from model\n");
142        abort();
143      }
144    }
145  } else {
146    columnLowerGen_ = NULL;
147  }
148  if (columnUpper) {
149    columnUpperGen_ = new double[numberColumns_];
150    for (i = 0; i < numberColumns_; i++)
151      columnUpperGen_[i] = columnUpper[i];
152  } else {
153    columnUpperGen_ = NULL;
154  }
155  // end specific coding
156  if (columnUpper_) {
157    // set all upper bounds so we have enough space
158    double *columnUpper = model->columnUpper();
159    for (i = firstDynamic_; i < lastDynamic_; i++)
160      columnUpper[i] = 1.0e10;
161  }
162  status_ = new unsigned char[2 * numberSets_ + 4];
163  if (status) {
164    memcpy(status_, status, numberSets_ * sizeof(char));
165    assert(dynamicStatus);
166    CoinMemcpyN(dynamicStatus, numberIds, dynamicStatus_);
167    assert(numberIds);
168  } else {
169    assert(!numberIds);
170    memset(status_, 0, numberSets_);
171    for (int i = 0; i < numberSets_; i++) {
172      // make slack key
173      setStatus(i, ClpSimplex::basic);
174    }
175  }
176  dynamicStatusGen_ = new unsigned char[numberColumns_];
177  memset(dynamicStatusGen_, 0, numberColumns_); // for clarity
178  for (int i = 0; i < numberColumns_; i++)
179    setDynamicStatusGen(i, atLowerBound);
180  // Populate with enough columns
181  if (!numberIds) {
182    // This could be made more sophisticated
183    for (iSet = 0; iSet < numberSets_; iSet++) {
184      CoinBigIndex sequence = fullStartGen_[iSet];
185      CoinBigIndex start = startColumnGen_[sequence];
186      addColumn(startColumnGen_[sequence + 1] - start,
187        rowGen_ + start,
188        elementGen_ + start,
189        costGen_[sequence],
190        columnLowerGen_ ? columnLowerGen_[sequence] : 0,
191        columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,
192        iSet, getDynamicStatusGen(sequence));
193      idGen_[iSet] = sequence; // say which one in
194      setDynamicStatusGen(sequence, inSmall);
195    }
196  } else {
197    // put back old ones
198    int *set = new int[numberColumns_];
199    for (iSet = 0; iSet < numberSets_; iSet++) {
200      for (CoinBigIndex j = fullStartGen_[iSet]; j < fullStartGen_[iSet + 1]; j++)
201        set[j] = iSet;
202    }
203    for (int i = 0; i < numberIds; i++) {
204      int sequence = ids[i];
205      CoinBigIndex start = startColumnGen_[sequence];
206      addColumn(startColumnGen_[sequence + 1] - start,
207        rowGen_ + start,
208        elementGen_ + start,
209        costGen_[sequence],
210        columnLowerGen_ ? columnLowerGen_[sequence] : 0,
211        columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,
212        set[sequence], getDynamicStatus(i));
213      idGen_[iSet] = sequence; // say which one in
214      setDynamicStatusGen(sequence, inSmall);
215    }
216    delete[] set;
217  }
218  if (!status) {
219    gubCrash();
220  } else {
221    initialProblem();
222  }
223}
224#if 0
225// This constructor just takes over ownership
226ClpDynamicExampleMatrix::ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets,
227          int numberGubColumns, int * starts,
228          const double * lower, const double * upper,
229          int * startColumn, int * row,
230          double * element, double * cost,
231          double * columnLower, double * columnUpper,
232          const unsigned char * status,
233          const unsigned char * dynamicStatus,
234          int numberIds, const int *ids)
235     : ClpDynamicMatrix(model, numberSets, 0, NULL, lower, upper, NULL, NULL, NULL, NULL, NULL, NULL,
236                        NULL, NULL)
237{
238     setType(25);
239     numberColumns_ = numberGubColumns;
240     // start with safe values - then experiment
241     maximumGubColumns_ = numberColumns_;
242     maximumElements_ = startColumn[numberColumns_];
243     // delete odd stuff created by ClpDynamicMatrix constructor
244     delete [] startSet_;
245     startSet_ = new int [numberSets_];
246     delete [] next_;
247     next_ = new int [maximumGubColumns_];
248     delete [] row_;
249     delete [] element_;
250     delete [] startColumn_;
251     delete [] cost_;
252     delete [] columnLower_;
253     delete [] columnUpper_;
254     delete [] dynamicStatus_;
255     delete [] status_;
256     delete [] id_;
257     // and size correctly
258     row_ = new int [maximumElements_];
259     element_ = new double [maximumElements_];
260     startColumn_ = new CoinBigIndex [maximumGubColumns_+1];
261     // say no columns yet
262     numberGubColumns_ = 0;
263     startColumn_[0] = 0;
264     cost_ = new double[maximumGubColumns_];
265     dynamicStatus_ = new unsigned char [2*maximumGubColumns_];
266     memset(dynamicStatus_, 0, maximumGubColumns_);
267     id_ = new int[maximumGubColumns_];
268     if (columnLower)
269          columnLower_ = new double[maximumGubColumns_];
270     else
271          columnLower_ = NULL;
272     if (columnUpper)
273          columnUpper_ = new double[maximumGubColumns_];
274     else
275          columnUpper_ = NULL;
276     // space for ids
277     idGen_ = new int [maximumGubColumns_];
278     int iSet;
279     for (iSet = 0; iSet < numberSets_; iSet++)
280          startSet_[iSet] = -1;
281     // This starts code specific to this storage method
282     CoinBigIndex i;
283     fullStartGen_ = starts;
284     startColumnGen_ = startColumn;
285     rowGen_ = row;
286     elementGen_ = element;
287     costGen_ = cost;
288     for (i = 0; i < numberColumns_; i++) {
289          // I don't think I need sorted but ...
290          CoinSort_2(rowGen_ + startColumnGen_[i], rowGen_ + startColumnGen_[i+1], elementGen_ + startColumnGen_[i]);
291     }
292     if (columnLower) {
293          columnLowerGen_ = columnLower;
294          for (i = 0; i < numberColumns_; i++) {
295               if (columnLowerGen_[i]) {
296                    printf("Non-zero lower bounds not allowed - subtract from model\n");
297                    abort();
298               }
299          }
300     } else {
301          columnLowerGen_ = NULL;
302     }
303     if (columnUpper) {
304          columnUpperGen_ = columnUpper;
305     } else {
306          columnUpperGen_ = NULL;
307     }
308     // end specific coding
309     if (columnUpper_) {
310          // set all upper bounds so we have enough space
311          double * columnUpper = model->columnUpper();
312          for(i = firstDynamic_; i < lastDynamic_; i++)
313               columnUpper[i] = 1.0e10;
314     }
315     status_ = new unsigned char [2*numberSets_+4];
316     if (status) {
317          memcpy(status_,status, numberSets_ * sizeof(char));
318          assert (dynamicStatus);
319          CoinMemcpyN(dynamicStatus, numberIds, dynamicStatus_);
320          assert (numberIds);
321     } else {
322          assert (!numberIds);
323          memset(status_, 0, numberSets_);
324          for (i = 0; i < numberSets_; i++) {
325               // make slack key
326               setStatus(i, ClpSimplex::basic);
327          }
328     }
329     dynamicStatusGen_ = new unsigned char [numberColumns_];
330     memset(dynamicStatusGen_, 0, numberColumns_); // for clarity
331     for (i = 0; i < numberColumns_; i++)
332          setDynamicStatusGen(i, atLowerBound);
333     // Populate with enough columns
334     if (!numberIds) {
335          // This could be made more sophisticated
336          for (iSet = 0; iSet < numberSets_; iSet++) {
337               int sequence = fullStartGen_[iSet];
338               CoinBigIndex start = startColumnGen_[sequence];
339               addColumn(startColumnGen_[sequence+1] - start,
340                         rowGen_ + start,
341                         elementGen_ + start,
342                         costGen_[sequence],
343                         columnLowerGen_ ? columnLowerGen_[sequence] : 0,
344                         columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,
345                         iSet, getDynamicStatusGen(sequence));
346               idGen_[iSet] = sequence; // say which one in
347               setDynamicStatusGen(sequence, inSmall);
348          }
349     } else {
350          // put back old ones
351          int * set = new int[numberColumns_];
352          for (iSet = 0; iSet < numberSets_; iSet++) {
353               for (CoinBigIndex j = fullStartGen_[iSet]; j < fullStartGen_[iSet+1]; j++)
354                    set[j] = iSet;
355          }
356          for (int i = 0; i < numberIds; i++) {
357               int sequence = ids[i];
358               int iSet = set[sequence];
359               CoinBigIndex start = startColumnGen_[sequence];
360               addColumn(startColumnGen_[sequence+1] - start,
361                         rowGen_ + start,
362                         elementGen_ + start,
363                         costGen_[sequence],
364                         columnLowerGen_ ? columnLowerGen_[sequence] : 0,
365                         columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,
366                         iSet, getDynamicStatus(i));
367               idGen_[i] = sequence; // say which one in
368               setDynamicStatusGen(sequence, inSmall);
369          }
370          delete [] set;
371     }
372     if (!status) {
373          gubCrash();
374     } else {
375          initialProblem();
376     }
377}
378#endif
379//-------------------------------------------------------------------
380// Destructor
381//-------------------------------------------------------------------
382ClpDynamicExampleMatrix::~ClpDynamicExampleMatrix()
383{
384  delete[] startColumnGen_;
385  delete[] rowGen_;
386  delete[] elementGen_;
387  delete[] costGen_;
388  delete[] fullStartGen_;
389  delete[] dynamicStatusGen_;
390  delete[] idGen_;
391  delete[] columnLowerGen_;
392  delete[] columnUpperGen_;
393}
394
395//----------------------------------------------------------------
396// Assignment operator
397//-------------------------------------------------------------------
398ClpDynamicExampleMatrix &
399ClpDynamicExampleMatrix::operator=(const ClpDynamicExampleMatrix &rhs)
400{
401  if (this != &rhs) {
402    ClpDynamicMatrix::operator=(rhs);
403    numberColumns_ = rhs.numberColumns_;
404    delete[] startColumnGen_;
405    delete[] rowGen_;
406    delete[] elementGen_;
407    delete[] costGen_;
408    delete[] fullStartGen_;
409    delete[] dynamicStatusGen_;
410    delete[] idGen_;
411    delete[] columnLowerGen_;
412    delete[] columnUpperGen_;
413    startColumnGen_ = ClpCopyOfArray(rhs.startColumnGen_, numberColumns_ + 1);
414    CoinBigIndex numberElements = startColumnGen_[numberColumns_];
415    rowGen_ = ClpCopyOfArray(rhs.rowGen_, numberElements);
416    elementGen_ = ClpCopyOfArray(rhs.elementGen_, numberElements);
417    costGen_ = ClpCopyOfArray(rhs.costGen_, numberColumns_);
418    fullStartGen_ = ClpCopyOfArray(rhs.fullStartGen_, numberSets_ + 1);
419    dynamicStatusGen_ = ClpCopyOfArray(rhs.dynamicStatusGen_, numberColumns_);
420    idGen_ = ClpCopyOfArray(rhs.idGen_, maximumGubColumns_);
421    columnLowerGen_ = ClpCopyOfArray(rhs.columnLowerGen_, numberColumns_);
422    columnUpperGen_ = ClpCopyOfArray(rhs.columnUpperGen_, numberColumns_);
423  }
424  return *this;
425}
426//-------------------------------------------------------------------
427// Clone
428//-------------------------------------------------------------------
429ClpMatrixBase *ClpDynamicExampleMatrix::clone() const
430{
431  return new ClpDynamicExampleMatrix(*this);
432}
433// Partial pricing
434void ClpDynamicExampleMatrix::partialPricing(ClpSimplex *model, double startFraction, double endFraction,
435  int &bestSequence, int &numberWanted)
436{
437  numberWanted = currentWanted_;
438  assert(!model->rowScale());
439  if (!numberSets_) {
440    // no gub
441    ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);
442  } else {
443    // and do some proportion of full set
444    int startG2 = static_cast< int >(startFraction * numberSets_);
445    int endG2 = static_cast< int >(endFraction * numberSets_ + 0.1);
446    endG2 = CoinMin(endG2, numberSets_);
447    //printf("gub price - set start %d end %d\n",
448    //   startG2,endG2);
449    double tolerance = model->currentDualTolerance();
450    double *reducedCost = model->djRegion();
451    const double *duals = model->dualRowSolution();
452    double bestDj;
453    int numberRows = model->numberRows();
454    int slackOffset = lastDynamic_ + numberRows;
455    int structuralOffset = slackOffset + numberSets_;
456    int structuralOffset2 = structuralOffset + maximumGubColumns_;
457    // If nothing found yet can go all the way to end
458    int endAll = endG2;
459    if (bestSequence < 0 && !startG2)
460      endAll = numberSets_;
461    if (bestSequence >= 0) {
462      if (bestSequence != savedBestSequence_)
463        bestDj = fabs(reducedCost[bestSequence]); // dj from slacks or permanent
464      else
465        bestDj = savedBestDj_;
466    } else {
467      bestDj = tolerance;
468    }
469    int saveSequence = bestSequence;
470    double djMod = 0.0;
471    double bestDjMod = 0.0;
472    //printf("iteration %d start %d end %d - wanted %d\n",model->numberIterations(),
473    //     startG2,endG2,numberWanted);
474    int bestSet = -1;
475    int minSet = minimumObjectsScan_ < 0 ? 5 : minimumObjectsScan_;
476    int minNeg = minimumGoodReducedCosts_ < 0 ? 5 : minimumGoodReducedCosts_;
477    for (int iSet = startG2; iSet < endAll; iSet++) {
478      if (numberWanted + minNeg < originalWanted_ && iSet > startG2 + minSet) {
479        // give up
480        numberWanted = 0;
481        break;
482      } else if (iSet == endG2 && bestSequence >= 0) {
483        break;
484      }
485      int gubRow = toIndex_[iSet];
486      if (gubRow >= 0) {
487        djMod = duals[gubRow + numberStaticRows_]; // have I got sign right?
488      } else {
489        int iBasic = keyVariable_[iSet];
490        if (iBasic >= numberColumns_) {
491          djMod = 0.0; // set not in
492        } else {
493          // get dj without
494          djMod = 0.0;
495          for (CoinBigIndex j = startColumn_[iBasic];
496               j < startColumn_[iBasic + 1]; j++) {
497            int jRow = row_[j];
498            djMod -= duals[jRow] * element_[j];
499          }
500          djMod += cost_[iBasic];
501          // See if gub slack possible - dj is djMod
502          if (getStatus(iSet) == ClpSimplex::atLowerBound) {
503            double value = -djMod;
504            if (value > tolerance) {
505              numberWanted--;
506              if (value > bestDj) {
507                // check flagged variable and correct dj
508                if (!flagged(iSet)) {
509                  bestDj = value;
510                  bestSequence = slackOffset + iSet;
511                  bestDjMod = djMod;
512                  bestSet = iSet;
513                } else {
514                  // just to make sure we don't exit before got something
515                  numberWanted++;
516                  abort();
517                }
518              }
519            }
520          } else if (getStatus(iSet) == ClpSimplex::atUpperBound) {
521            double value = djMod;
522            if (value > tolerance) {
523              numberWanted--;
524              if (value > bestDj) {
525                // check flagged variable and correct dj
526                if (!flagged(iSet)) {
527                  bestDj = value;
528                  bestSequence = slackOffset + iSet;
529                  bestDjMod = djMod;
530                  bestSet = iSet;
531                } else {
532                  // just to make sure we don't exit before got something
533                  numberWanted++;
534                  abort();
535                }
536              }
537            }
538          }
539        }
540      }
541      // do ones in small
542      CoinBigIndex iSequence = startSet_[iSet];
543      while (iSequence >= 0) {
544        DynamicStatus status = getDynamicStatus(iSequence);
545        if (status == atLowerBound || status == atUpperBound) {
546          double value = cost_[iSequence] - djMod;
547          for (CoinBigIndex j = startColumn_[iSequence];
548               j < startColumn_[iSequence + 1]; j++) {
549            int jRow = row_[j];
550            value -= duals[jRow] * element_[j];
551          }
552          // change sign if at lower bound
553          if (status == atLowerBound)
554            value = -value;
555          if (value > tolerance) {
556            numberWanted--;
557            if (value > bestDj) {
558              // check flagged variable and correct dj
559              if (!flagged(iSequence)) {
560                bestDj = value;
561                bestSequence = structuralOffset + iSequence;
562                bestDjMod = djMod;
563                bestSet = iSet;
564              } else {
565                // just to make sure we don't exit before got something
566                numberWanted++;
567              }
568            }
569          }
570        }
571        iSequence = next_[iSequence]; //onto next in set
572      }
573      // and now get best by column generation
574      // If no upper bounds we may not need status test
575      for (iSequence = fullStartGen_[iSet]; iSequence < fullStartGen_[iSet + 1]; iSequence++) {
576        DynamicStatus status = getDynamicStatusGen(iSequence);
577        assert(status != atUpperBound && status != soloKey);
578        if (status == atLowerBound) {
579          double value = costGen_[iSequence] - djMod;
580          for (CoinBigIndex j = startColumnGen_[iSequence];
581               j < startColumnGen_[iSequence + 1]; j++) {
582            int jRow = rowGen_[j];
583            value -= duals[jRow] * elementGen_[j];
584          }
585          // change sign as at lower bound
586          value = -value;
587          if (value > tolerance) {
588            numberWanted--;
589            if (value > bestDj) {
590              // check flagged variable and correct dj
591              if (!flaggedGen(iSequence)) {
592                bestDj = value;
593                bestSequence = structuralOffset2 + iSequence;
594                bestDjMod = djMod;
595                bestSet = iSet;
596              } else {
597                // just to make sure we don't exit before got something
598                numberWanted++;
599              }
600            }
601          }
602        }
603      }
604      if (numberWanted <= 0) {
605        numberWanted = 0;
606        break;
607      }
608    }
609    if (bestSequence != saveSequence) {
610      savedBestGubDual_ = bestDjMod;
611      savedBestDj_ = bestDj;
612      savedBestSequence_ = bestSequence;
613      savedBestSet_ = bestSet;
614    }
615    // Do packed part before gub
616    // always???
617    // Resize so just do to gub
618    numberActiveColumns_ = firstDynamic_;
619    int saveMinNeg = minimumGoodReducedCosts_;
620    if (bestSequence >= 0)
621      minimumGoodReducedCosts_ = -2;
622    currentWanted_ = numberWanted;
623    ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);
624    numberActiveColumns_ = matrix_->getNumCols();
625    minimumGoodReducedCosts_ = saveMinNeg;
626    // See if may be finished
627    if (!startG2 && bestSequence < 0)
628      infeasibilityWeight_ = model_->infeasibilityCost();
629    else if (bestSequence >= 0)
630      infeasibilityWeight_ = -1.0;
631    currentWanted_ = numberWanted;
632  }
633}
634/* Creates a variable.  This is called after partial pricing and may modify matrix.
635   May update bestSequence.
636*/
637void ClpDynamicExampleMatrix::createVariable(ClpSimplex *model, int &bestSequence)
638{
639  int numberRows = model->numberRows();
640  int slackOffset = lastDynamic_ + numberRows;
641  int structuralOffset = slackOffset + numberSets_;
642  int bestSequence2 = savedBestSequence_ - structuralOffset;
643  if (bestSequence2 >= 0) {
644    // See if needs new
645    if (bestSequence2 >= maximumGubColumns_) {
646      bestSequence2 -= maximumGubColumns_;
647      int sequence = addColumn(startColumnGen_[bestSequence2 + 1] - startColumnGen_[bestSequence2],
648        rowGen_ + startColumnGen_[bestSequence2],
649        elementGen_ + startColumnGen_[bestSequence2],
650        costGen_[bestSequence2],
651        columnLowerGen_ ? columnLowerGen_[bestSequence2] : 0,
652        columnUpperGen_ ? columnUpperGen_[bestSequence2] : 1.0e30,
653        savedBestSet_, getDynamicStatusGen(bestSequence2));
654      savedBestSequence_ = structuralOffset + sequence;
655      idGen_[sequence] = bestSequence2;
656      setDynamicStatusGen(bestSequence2, inSmall);
657    }
658  }
659  ClpDynamicMatrix::createVariable(model, bestSequence /*, bestSequence2*/);
660  // clear for next iteration
661  savedBestSequence_ = -1;
662}
663/* If addColumn forces compression then this allows descendant to know what to do.
664   If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero.
665   Entries at upper bound (really nonzero) never go out (at present).
666*/
667void ClpDynamicExampleMatrix::packDown(const int *in, int numberToPack)
668{
669  int put = 0;
670  for (int i = 0; i < numberToPack; i++) {
671    int id = idGen_[i];
672    if (in[i] >= 0) {
673      // stays in
674      assert(put == in[i]); // true for now
675      idGen_[put++] = id;
676    } else {
677      // out to lower bound
678      setDynamicStatusGen(id, atLowerBound);
679    }
680  }
681  assert(put == numberGubColumns_);
682}
683
684/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
685*/
Note: See TracBrowser for help on using the repository browser.