source: tags/move-to-subversion/ClpDynamicExampleMatrix.cpp @ 1355

Last change on this file since 1355 was 399, checked in by forrest, 16 years ago

to CoinMax? and CoinMin?

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