source: trunk/Cbc/examples/CbcSolverLongThin.cpp @ 2469

Last change on this file since 2469 was 2469, checked in by unxusr, 9 months ago

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.8 KB
Line 
1// $Id: CbcSolverLongThin.cpp 2469 2019-01-06 23:17:46Z unxusr $
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 <cassert>
7
8#include "CoinTime.hpp"
9
10#include "CoinHelperFunctions.hpp"
11#include "CoinIndexedVector.hpp"
12#include "ClpFactorization.hpp"
13#include "ClpObjective.hpp"
14#include "ClpSimplex.hpp"
15#include "CbcSolverLongThin.hpp"
16#include "CbcModel.hpp"
17#include "ClpPresolve.hpp"
18#include "CbcBranchActual.hpp"
19#include "CbcBranchFollow2.hpp"
20#include "CbcCutGenerator.hpp"
21#include "CbcCompareUser.hpp"
22// Cuts
23
24#include "CglGomory.hpp"
25#include "CglProbing.hpp"
26#include "CglKnapsackCover.hpp"
27#include "CglOddHole.hpp"
28#include "CglClique.hpp"
29#include "CglFlowCover.hpp"
30#include "CglMixedIntegerRounding.hpp"
31#include "CglTwomir.hpp"
32#include "CglDuplicateRow.hpp"
33#include "CbcFathomDynamicProgramming.hpp"
34
35static int timesBad_ = 0;
36//#############################################################################
37// Solve methods
38//#############################################################################
39static CglDuplicateRow *tryCut = NULL;
40void CbcSolverLongThin::initialSolve()
41{
42  modelPtr_->scaling(0);
43  setBasis(basis_, modelPtr_);
44  modelPtr_->dual();
45  basis_ = getBasis(modelPtr_);
46  assert(!modelPtr_->specialOptions());
47  modelPtr_->setLogLevel(0);
48  if (!tryCut) {
49    tryCut = new CglDuplicateRow(this);
50    tryCut->setLogLevel(2);
51  }
52}
53
54//-----------------------------------------------------------------------------
55void CbcSolverLongThin::resolve()
56{
57  int *whichRow = NULL;
58  int *whichColumn = NULL;
59  // problem may be small enough to do nested search
60  const double *colLower = modelPtr_->columnLower();
61  const double *colUpper = modelPtr_->columnUpper();
62
63  int numberIntegers = model_->numberIntegers();
64  const int *integerVariable = model_->integerVariable();
65  int numberRows = modelPtr_->numberRows();
66  int numberColumns = modelPtr_->numberColumns();
67
68  int i;
69  int nFix = 0;
70  int nNewRow = 0;
71  int nNewCol = 0;
72  int sizeDynamic = COIN_INT_MAX;
73  int smallOriginalNumberRows = 0;
74  if (algorithm_ == 0) {
75    for (i = 0; i < numberIntegers; i++) {
76      int iColumn = integerVariable[i];
77      if (colLower[iColumn] == colUpper[iColumn])
78        nFix++;
79    }
80  } else {
81    whichRow = new int[numberRows];
82    whichColumn = new int[numberColumns];
83    // more sophisticated
84    OsiCuts cs;
85    tryCut->generateCuts(*this, cs);
86    int numberCuts = cs.sizeColCuts();
87    if (numberCuts) {
88      for (i = 0; i < numberCuts; i++) {
89        const OsiColCut *thisCut = cs.colCutPtr(i);
90        const CoinPackedVector &ubs = thisCut->ubs();
91        int n = ubs.getNumElements();
92        const int *which = ubs.getIndices();
93        const double *values = ubs.getElements();
94        for (int j = 0; j < n; j++) {
95          int iColumn = which[j];
96          this->setColUpper(iColumn, values[j]);
97        }
98      }
99    }
100#if 1
101    const int *duplicate = tryCut->duplicate();
102    sizeDynamic = tryCut->sizeDynamic();
103    int nOrig = tryCut->numberOriginalRows();
104    for (i = 0; i < nOrig; i++) {
105      if (duplicate[i] == -1)
106        whichRow[nNewRow++] = i;
107      else
108        modelPtr_->setRowStatus(i, ClpSimplex::basic);
109    }
110    smallOriginalNumberRows = nNewRow;
111    for (; i < numberRows; i++) {
112      whichRow[nNewRow++] = i;
113    }
114#else
115    for (i = 0; i < numberRows; i++)
116      whichRow[i] = i;
117    nNewRow = numberRows;
118#endif
119    for (i = 0; i < numberIntegers; i++) {
120      int iColumn = integerVariable[i];
121      if (colLower[iColumn] == colUpper[iColumn])
122        nFix++;
123      bool choose;
124      if (algorithm_ == 1)
125        choose = true;
126      else
127        choose = (node_[i] > count_ - memory_ && node_[i] > 0);
128      if ((choose && colUpper[i])
129        || (modelPtr_->getStatus(i) != ClpSimplex::atLowerBound && modelPtr_->getStatus(i) != ClpSimplex::isFixed)
130        || colLower[i] > 0.0)
131        whichColumn[nNewCol++] = i;
132    }
133  }
134  if (nestedSearch_ < 1.0 && model_ && model_->phase() == 2) {
135    if (((double)sizeDynamic) * ((double)nNewCol) < 1000000000 && sizeDynamic < 10000000) {
136      // could do Dynamic Programming
137      // back to original number of rows
138      nNewRow = smallOriginalNumberRows;
139      // and get rid of any basics
140      int nNewCol = 0;
141      for (i = 0; i < numberColumns; i++) {
142        if (colUpper[i] || colLower[i] > 0.0)
143          whichColumn[nNewCol++] = i;
144      }
145      ClpSimplex temp(modelPtr_, nNewRow, whichRow, nNewCol, whichColumn);
146      int returnCode;
147      double *rowLower2 = temp.rowLower();
148      double *rowUpper2 = temp.rowUpper();
149      int numberColumns2 = temp.numberColumns();
150      double *colLower2 = temp.columnLower();
151      double *colUpper2 = temp.columnUpper();
152      const CoinPackedMatrix *matrix = temp.matrix();
153      const double *element = matrix->getElements();
154      const int *row = matrix->getIndices();
155      const CoinBigIndex *columnStart = matrix->getVectorStarts();
156      const int *columnLength = matrix->getVectorLengths();
157      double offset = 0.0;
158      const double *objective = temp.objective();
159      bool feasible = true;
160      for (i = 0; i < numberColumns2; i++) {
161        double value = colLower2[i];
162        if (value) {
163          offset += value * objective[i];
164          colLower2[i] = 0.0;
165          colUpper2[i] -= value;
166          for (int j = columnStart[i];
167               j < columnStart[i] + columnLength[i]; j++) {
168            int iRow = row[j];
169            rowLower2[iRow] -= value * element[j];
170            rowUpper2[iRow] -= value * element[j];
171            if (rowUpper2[iRow] < -1.0e-8) {
172              feasible = false;
173              printf("odd - problem is infeasible\n");
174            }
175          }
176        }
177      }
178      temp.setObjectiveOffset(-offset);
179      OsiClpSolverInterface temp2(&temp);
180      double *solutionDP = NULL;
181      if (feasible) {
182        for (i = 0; i < numberColumns2; i++)
183          temp2.setInteger(i);
184        CbcModel modelSmall(temp2);
185        modelSmall.messageHandler()->setLogLevel(0);
186        CbcFathomDynamicProgramming fathom1(modelSmall);
187        // Set maximum space allowed
188        fathom1.setMaximumSize(100000000);
189        temp2.writeMps("small");
190        returnCode = fathom1.fathom(solutionDP);
191        if (returnCode != 1) {
192          printf("probably not enough memory\n");
193          abort();
194        }
195      }
196      if (solutionDP) {
197        double objValue = 0.0;
198        double *solution = modelPtr_->primalColumnSolution();
199        const double *objective = modelPtr_->objective();
200        for (i = 0; i < numberColumns; i++)
201          solution[i] = colLower[i];
202        for (i = 0; i < nNewCol; i++) {
203          int iColumn = whichColumn[i];
204          solution[iColumn] += solutionDP[i];
205        }
206        for (i = 0; i < numberColumns; i++)
207          objValue += solution[i] * objective[i];
208        if (objValue < model_->getCutoff()) {
209          printf("good solution %g by dynamic programming\n", objValue);
210          returnCode = 0;
211          // paranoid check
212          double *rowLower = modelPtr_->rowLower();
213          double *rowUpper = modelPtr_->rowUpper();
214          // Column copy
215          const CoinPackedMatrix *matrix2 = modelPtr_->matrix();
216          element = matrix2->getElements();
217          row = matrix2->getIndices();
218          columnStart = matrix2->getVectorStarts();
219          columnLength = matrix2->getVectorLengths();
220          double *rowActivity = new double[numberRows];
221          memset(rowActivity, 0, numberRows * sizeof(double));
222          for (i = 0; i < numberColumns; i++) {
223            int j;
224            double value = solution[i];
225            assert(value >= colLower[i] && value <= colUpper[i]);
226            if (value) {
227              printf("%d has value %g\n", i, value);
228              for (j = columnStart[i];
229                   j < columnStart[i] + columnLength[i]; j++) {
230                int iRow = row[j];
231                rowActivity[iRow] += value * element[j];
232              }
233            }
234          }
235          // check was feasible
236          bool feasible = true;
237          for (i = 0; i < numberRows; i++) {
238            if (rowActivity[i] < rowLower[i]) {
239              if (rowActivity[i] < rowLower[i] - 1.0e-8)
240                feasible = false;
241            } else if (rowActivity[i] > rowUpper[i]) {
242              if (rowActivity[i] > rowUpper[i] + 1.0e-8)
243                feasible = false;
244            }
245          }
246          if (!feasible) {
247            printf("** Bad solution by dynamic programming\n");
248            abort();
249          }
250          delete[] rowActivity;
251          model_->setBestSolution(CBC_TREE_SOL, objValue, solution);
252        } else {
253          returnCode = 2;
254        }
255      } else {
256        returnCode = 2;
257      }
258      temp2.releaseClp();
259      modelPtr_->setProblemStatus(1);
260      delete[] whichRow;
261      delete[] whichColumn;
262      return;
263    }
264    if (nFix > nestedSearch_ * numberIntegers) {
265      // Do nested search
266      // back to original number of rows
267      nNewRow = smallOriginalNumberRows;
268      // and get rid of any basics
269      int nNewCol = 0;
270      for (i = 0; i < numberColumns; i++) {
271        if (colUpper[i] || colLower[i] > 0.0)
272          whichColumn[nNewCol++] = i;
273      }
274#if 0
275      // We clone from continuous solver so set some stuff
276      OsiSolverInterface * solver = model_->continuousSolver();
277      CbcSolverLongThin * osiclp = dynamic_cast< CbcSolverLongThin*> (solver);
278      assert (osiclp);
279      // up special options
280      if (osiclp->specialOptions()==3)
281        osiclp->setSpecialOptions(7);
282      double saveNested = osiclp->getNested();
283      int saveAlgorithm = osiclp->getAlgorithm();
284      osiclp->setNested(1.0);
285      osiclp->setAlgorithm(0);
286      int numberObjects = model_->numberObjects();
287      if (numberObjects>model_->numberIntegers()) {
288        // for now only integers
289        //assert (numberObjects == model_->numberIntegers()+1);
290        model_->setNumberObjects(model_->numberIntegers());
291        // try follow on
292        //model_->setNumberObjects(model_->numberIntegers()+1);
293      }
294      double saveMaxTime = model_->getDblParam(CbcModel::CbcMaximumSeconds);
295      model_->setDblParam(CbcModel::CbcMaximumSeconds,1.0e5);
296      // up special options
297#if 1
298      int returnCode= model_->subBranchAndBound(colLower,colUpper,2000);
299#else
300      CbcModel * model3 = model_->cleanModel(colLower,colUpper);
301      // integer presolve
302      int returnCode=0;
303      CbcModel * model2 = model3->integerPresolve(false);
304      if (!model2||!model2->getNumRows()) {
305        delete model2;
306        delete model3;
307        returnCode= 2;
308      } else {
309        if (handler_->logLevel()>1)
310          printf("Reduced model has %d rows and %d columns\n",
311                 model2->getNumRows(),model2->getNumCols());
312        if (true) {
313          OsiSolverInterface * solver = model2->solver();
314          OsiSolverInterface * osiclp = dynamic_cast< OsiSolverInterface*> (solver);
315          assert (osiclp);
316          int * priority = new int [numberColumns+1];
317          int n=0;
318          int iColumn;
319          for ( iColumn=0;iColumn<numberColumns;iColumn++) {
320            if (solver->isInteger(iColumn)) {
321              priority[n++]=10000;
322            }
323          }
324          priority[n]=1;
325          CbcObject * newObject =new CbcFollowOn2(model2);
326          model2->addObjects(1,&newObject);
327          delete newObject;
328          model2->passInPriorities(priority,false);
329          delete [] priority;
330        }
331        returnCode= model_->subBranchAndBound(model3,model2,4000);
332      }
333#endif
334      model_->setDblParam(CbcModel::CbcMaximumSeconds,saveMaxTime);
335      model_->setNumberObjects(numberObjects);
336      osiclp->setNested(saveNested);
337      osiclp->setAlgorithm(saveAlgorithm);
338#else
339      // start again very simply
340      ClpSimplex temp(modelPtr_, nNewRow, whichRow, nNewCol, whichColumn);
341      int returnCode;
342      OsiClpSolverInterface temp2(&temp);
343      temp2.setupForRepeatedUse(2);
344      int numberColumns2 = temp.numberColumns();
345      const double *colUpper2 = temp2.getColUpper();
346      const double *colLower2 = temp2.getColLower();
347      const double *solution2 = temp.getColSolution();
348      double *cleanSolution2 = new double[numberColumns2];
349      for (i = 0; i < numberColumns2; i++) {
350        temp2.setInteger(i);
351        double value = solution2[i];
352        value = CoinMin(CoinMax(value, colLower2[i]), colUpper2[i]);
353        cleanSolution2[i] = value;
354      }
355      temp2.setColSolution(cleanSolution2);
356      delete[] cleanSolution2;
357      CbcModel modelSmall(temp2);
358      modelSmall.setNumberStrong(0);
359      CglProbing generator1;
360      generator1.setUsingObjective(true);
361      generator1.setMaxPass(3);
362      generator1.setMaxProbe(100);
363      generator1.setMaxLook(50);
364      generator1.setRowCuts(3);
365
366      CglGomory generator2;
367      // try larger limit
368      generator2.setLimit(300);
369
370      CglKnapsackCover generator3;
371
372      CglOddHole generator4;
373      generator4.setMinimumViolation(0.005);
374      generator4.setMinimumViolationPer(0.00002);
375      // try larger limit
376      generator4.setMaximumEntries(200);
377
378      CglClique generator5;
379      generator5.setStarCliqueReport(false);
380      generator5.setRowCliqueReport(false);
381
382      CglMixedIntegerRounding mixedGen;
383      CglFlowCover flowGen;
384
385      // Add in generators
386      modelSmall.addCutGenerator(&generator1, -1, "Probing", true, false, false, -1);
387      modelSmall.addCutGenerator(&generator2, -99, "Gomory", true, false, false, -99);
388      modelSmall.addCutGenerator(&generator3, -99, "Knapsack", true, false, false, -99);
389      modelSmall.addCutGenerator(&generator4, -99, "OddHole", true, false, false, -99);
390      modelSmall.addCutGenerator(&generator5, -99, "Clique", true, false, false, -99);
391      modelSmall.addCutGenerator(&flowGen, -99, "FlowCover", true, false, false, -99);
392      modelSmall.addCutGenerator(&mixedGen, -99, "MixedIntegerRounding", true, false, false, -100);
393#if 1
394      const CoinPackedMatrix *matrix = temp2.getMatrixByCol();
395      const int *columnLength = matrix->getVectorLengths();
396      int *priority = new int[numberColumns2 + 1];
397      // do pseudo costs and priorities - take a reasonable guess
398      CbcObject **objects = new CbcObject *[numberColumns2 + 1];
399      int n = 0;
400      const double *objective = modelSmall.getObjCoefficients();
401      for (i = 0; i < numberColumns2; i++) {
402        CbcSimpleIntegerPseudoCost *newObject = new CbcSimpleIntegerPseudoCost(&modelSmall, n, i, objective[i], 0.5 * objective[i]);
403        newObject->setMethod(3);
404        objects[n] = newObject;
405        priority[n++] = 10000 - columnLength[i];
406      }
407      priority[n] = 1;
408      objects[n++] = new CbcFollowOn2(&modelSmall);
409      modelSmall.addObjects(n, objects);
410      for (i = 0; i < n; i++)
411        delete objects[i];
412      delete[] objects;
413      modelSmall.passInPriorities(priority, false);
414      delete[] priority;
415#endif
416      modelSmall.setCutoff(model_->getCutoff());
417      //if (!onPathX&&modelSmall.getCutoff()>480.5)
418      //modelSmall.setCutoff(480.5);
419      //printf("cutoff %g\n",model_->getCutoff());
420      modelSmall.messageHandler()->setLogLevel(1);
421      modelSmall.solver()->messageHandler()->setLogLevel(0);
422      modelSmall.messagesPointer()->setDetailMessage(3, 9);
423      modelSmall.messagesPointer()->setDetailMessage(3, 6);
424      modelSmall.messagesPointer()->setDetailMessage(3, 4);
425      modelSmall.messagesPointer()->setDetailMessage(3, 13);
426      modelSmall.messagesPointer()->setDetailMessage(3, 14);
427      modelSmall.messagesPointer()->setDetailMessage(3, 1);
428      modelSmall.messagesPointer()->setDetailMessage(3, 3007);
429      modelSmall.branchAndBound();
430      temp2.releaseClp();
431      if (modelSmall.bestSolution()) {
432        double objValue = 0.0;
433        const double *solution2 = modelSmall.bestSolution();
434        double *solution = modelPtr_->primalColumnSolution();
435        const double *objective = modelPtr_->objective();
436        for (i = 0; i < numberColumns; i++)
437          solution[i] = colLower[i];
438        for (i = 0; i < nNewCol; i++) {
439          int iColumn = whichColumn[i];
440          solution[iColumn] = solution2[i];
441        }
442        for (i = 0; i < numberColumns; i++)
443          objValue += solution[i] * objective[i];
444        assert(objValue < model_->getCutoff());
445        if (objValue < model_->getCutoff()) {
446          //printf("good solution \n");
447          model_->setBestSolution(CBC_TREE_SOL, objValue, solution);
448          returnCode = 0;
449        } else {
450          returnCode = 2;
451        }
452      } else {
453        returnCode = 2;
454      }
455#endif
456      if (returnCode != 0 && returnCode != 2) {
457        printf("pretending entire search done\n");
458        returnCode = 0;
459      }
460      if (returnCode == 0 || returnCode == 2) {
461        modelPtr_->setProblemStatus(1);
462        delete[] whichRow;
463        delete[] whichColumn;
464        return;
465      }
466    }
467  }
468  if ((count_ < 100 && algorithm_ == 2) || !algorithm_) {
469    delete[] whichRow;
470    delete[] whichColumn;
471    assert(!modelPtr_->specialOptions());
472    int saveOptions = modelPtr_->specialOptions();
473    bool takeHint;
474    OsiHintStrength strength;
475    getHintParam(OsiDoInBranchAndCut, takeHint, strength);
476    if (strength != OsiHintIgnore && takeHint) {
477      // could do something - think about it
478      //printf("thin hint %d %c\n",strength,takeHint ? 'T' :'F');
479    }
480    if ((specialOptions_ & 1) == 0) {
481      modelPtr_->setSpecialOptions(saveOptions | (64 | 1024));
482    } else {
483      if ((specialOptions_ & 4) == 0)
484        modelPtr_->setSpecialOptions(saveOptions | (64 | 128 | 512 | 1024 | 4096));
485      else
486        modelPtr_->setSpecialOptions(saveOptions | (64 | 128 | 512 | 1024 | 2048 | 4096));
487    }
488    //printf("thin options %d size %d\n",modelPtr_->specialOptions(),modelPtr_->numberColumns());
489    setBasis(basis_, modelPtr_);
490    //modelPtr_->setLogLevel(1);
491    modelPtr_->dual(0, 0);
492    basis_ = getBasis(modelPtr_);
493    modelPtr_->setSpecialOptions(saveOptions);
494    if (modelPtr_->status() == 0) {
495      count_++;
496      double *solution = modelPtr_->primalColumnSolution();
497      int i;
498      for (i = 0; i < numberColumns; i++) {
499        if (solution[i] > 1.0e-6 || modelPtr_->getStatus(i) == ClpSimplex::basic) {
500          node_[i] = CoinMax(count_, node_[i]);
501          howMany_[i]++;
502        }
503      }
504    } else {
505      if (!algorithm_ == 2)
506        printf("infeasible early on\n");
507    }
508  } else {
509    // use counts
510    int i;
511    const double *lower = modelPtr_->columnLower();
512    const double *upper = modelPtr_->columnUpper();
513    setBasis(basis_, modelPtr_);
514    ClpSimplex *temp = new ClpSimplex(modelPtr_, nNewRow, whichRow, nNewCol, whichColumn);
515    //temp->setLogLevel(2);
516    //printf("small has %d rows and %d columns\n",nNewRow,nNewCol);
517    temp->setSpecialOptions(128 + 512);
518    temp->setDualObjectiveLimit(1.0e50);
519    temp->dual();
520    if (temp->status()) {
521      // In some cases we know that it must be infeasible
522      if (believeInfeasible_ || algorithm_ == 1) {
523        modelPtr_->setProblemStatus(1);
524        printf("assuming infeasible!\n");
525        //modelPtr_->writeMps("infeas.mps");
526        //temp->writeMps("infeas2.mps");
527        //abort();
528        delete temp;
529        delete[] whichRow;
530        delete[] whichColumn;
531        return;
532      }
533    }
534    double *solution = modelPtr_->primalColumnSolution();
535    if (!temp->status()) {
536      const double *solution2 = temp->primalColumnSolution();
537      memset(solution, 0, numberColumns * sizeof(double));
538      for (i = 0; i < nNewCol; i++) {
539        int iColumn = whichColumn[i];
540        solution[iColumn] = solution2[i];
541        modelPtr_->setStatus(iColumn, temp->getStatus(i));
542      }
543      double *rowSolution = modelPtr_->primalRowSolution();
544      const double *rowSolution2 = temp->primalRowSolution();
545      double *dual = modelPtr_->dualRowSolution();
546      const double *dual2 = temp->dualRowSolution();
547      memset(dual, 0, numberRows * sizeof(double));
548      for (i = 0; i < nNewRow; i++) {
549        int iRow = whichRow[i];
550        modelPtr_->setRowStatus(iRow, temp->getRowStatus(i));
551        rowSolution[iRow] = rowSolution2[i];
552        dual[iRow] = dual2[i];
553      }
554      // See if optimal
555      double *dj = modelPtr_->dualColumnSolution();
556      // get reduced cost for large problem
557      // this assumes minimization
558      memcpy(dj, modelPtr_->objective(), numberColumns * sizeof(double));
559      modelPtr_->transposeTimes(-1.0, dual, dj);
560      modelPtr_->setObjectiveValue(temp->objectiveValue());
561      modelPtr_->setProblemStatus(0);
562      int nBad = 0;
563
564      for (i = 0; i < numberColumns; i++) {
565        if (modelPtr_->getStatus(i) == ClpSimplex::atLowerBound
566          && upper[i] > lower[i] && dj[i] < -1.0e-5)
567          nBad++;
568      }
569      //modelPtr_->writeMps("bada.mps");
570      //temp->writeMps("badb.mps");
571      if (nBad) {
572        assert(algorithm_ == 2);
573        //printf("%d bad\n",nBad);
574        timesBad_++;
575        modelPtr_->primal();
576      }
577    } else {
578      // infeasible - do all
579      modelPtr_->setSpecialOptions(64 + 128 + 512);
580      setBasis(basis_, modelPtr_);
581      //modelPtr_->setLogLevel(1);
582      modelPtr_->dual(0, 0);
583      basis_ = getBasis(modelPtr_);
584      modelPtr_->setSpecialOptions(0);
585      if (modelPtr_->status()) {
586        printf("really infeasible!\n");
587        delete temp;
588        delete[] whichRow;
589        delete[] whichColumn;
590        return;
591      } else {
592        printf("initially infeasible\n");
593      }
594    }
595    delete temp;
596    delete[] whichRow;
597    delete[] whichColumn;
598    basis_ = getBasis(modelPtr_);
599    modelPtr_->setSpecialOptions(0);
600    count_++;
601    if ((count_ % 100) == 0 && algorithm_ == 2)
602      printf("count %d, bad %d\n", count_, timesBad_);
603    for (i = 0; i < numberColumns; i++) {
604      if (solution[i] > 1.0e-6 || modelPtr_->getStatus(i) == ClpSimplex::basic) {
605        node_[i] = CoinMax(count_, node_[i]);
606        howMany_[i]++;
607      }
608    }
609    if (modelPtr_->objectiveValue() >= modelPtr_->dualObjectiveLimit())
610      modelPtr_->setProblemStatus(1);
611  }
612}
613
614//#############################################################################
615// Constructors, destructors clone and assignment
616//#############################################################################
617
618//-------------------------------------------------------------------
619// Default Constructor
620//-------------------------------------------------------------------
621CbcSolverLongThin::CbcSolverLongThin()
622  : OsiClpSolverInterface()
623{
624  node_ = NULL;
625  howMany_ = NULL;
626  count_ = 0;
627  model_ = NULL;
628  memory_ = 300;
629  believeInfeasible_ = false;
630  nestedSearch_ = 1.0;
631  algorithm_ = 0;
632}
633
634//-------------------------------------------------------------------
635// Clone
636//-------------------------------------------------------------------
637OsiSolverInterface *
638CbcSolverLongThin::clone(bool CopyData) const
639{
640  if (CopyData) {
641    return new CbcSolverLongThin(*this);
642  } else {
643    printf("warning CbcSolveUser clone with copyData false\n");
644    return new CbcSolverLongThin();
645  }
646}
647
648//-------------------------------------------------------------------
649// Copy constructor
650//-------------------------------------------------------------------
651CbcSolverLongThin::CbcSolverLongThin(
652  const CbcSolverLongThin &rhs)
653  : OsiClpSolverInterface(rhs)
654{
655  model_ = rhs.model_;
656  int numberColumns = modelPtr_->numberColumns();
657  node_ = CoinCopyOfArray(rhs.node_, numberColumns);
658  howMany_ = CoinCopyOfArray(rhs.howMany_, numberColumns);
659  count_ = rhs.count_;
660  memory_ = rhs.memory_;
661  believeInfeasible_ = rhs.believeInfeasible_;
662  nestedSearch_ = rhs.nestedSearch_;
663  algorithm_ = rhs.algorithm_;
664}
665
666//-------------------------------------------------------------------
667// Destructor
668//-------------------------------------------------------------------
669CbcSolverLongThin::~CbcSolverLongThin()
670{
671  delete[] node_;
672  delete[] howMany_;
673}
674
675//-------------------------------------------------------------------
676// Assignment operator
677//-------------------------------------------------------------------
678CbcSolverLongThin &
679CbcSolverLongThin::operator=(const CbcSolverLongThin &rhs)
680{
681  if (this != &rhs) {
682    OsiClpSolverInterface::operator=(rhs);
683    delete[] node_;
684    delete[] howMany_;
685    model_ = rhs.model_;
686    int numberColumns = modelPtr_->numberColumns();
687    node_ = CoinCopyOfArray(rhs.node_, numberColumns);
688    howMany_ = CoinCopyOfArray(rhs.howMany_, numberColumns);
689    count_ = rhs.count_;
690    memory_ = rhs.memory_;
691    believeInfeasible_ = rhs.believeInfeasible_;
692    nestedSearch_ = rhs.nestedSearch_;
693    algorithm_ = rhs.algorithm_;
694  }
695  return *this;
696}
697//-------------------------------------------------------------------
698// Real initializer
699//-------------------------------------------------------------------
700void CbcSolverLongThin::initialize(CbcModel *model, const char *keep)
701{
702  model_ = model;
703  int numberColumns = modelPtr_->numberColumns();
704  if (numberColumns) {
705    node_ = new int[numberColumns];
706    howMany_ = new int[numberColumns];
707    for (int i = 0; i < numberColumns; i++) {
708      if (keep[i])
709        node_[i] = COIN_INT_MAX;
710      else
711        node_[i] = 0;
712      howMany_[i] = 0;
713    }
714  } else {
715    node_ = NULL;
716    howMany_ = NULL;
717  }
718}
Note: See TracBrowser for help on using the repository browser.