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

Last change on this file since 2030 was 1936, checked in by forrest, 7 years ago

fixes so examples will work

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