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

Last change on this file since 705 was 705, checked in by forrest, 12 years ago

INT_MAX to COIN_INT_MAX in Cbc/examples

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.1 KB
Line 
1// Copyright (C) 2004, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include <cassert>
5
6#include "CoinTime.hpp"
7
8#include "CoinHelperFunctions.hpp"
9#include "CoinIndexedVector.hpp"
10#include "ClpFactorization.hpp"
11#include "ClpObjective.hpp"
12#include "ClpSimplex.hpp"
13#include "CbcSolverLongThin.hpp"
14#include "CbcModel.hpp"
15#include "ClpPresolve.hpp"
16#include "CbcHeuristicUser.hpp"
17#include "CbcBranchActual.hpp"
18#include "CbcBranchFollow2.hpp"
19#include "CbcCutGenerator.hpp"
20#include "CbcCompareUser.hpp"
21// Cuts
22
23#include "CglGomory.hpp"
24#include "CglProbing.hpp"
25#include "CglKnapsackCover.hpp"
26#include "CglOddHole.hpp"
27#include "CglClique.hpp"
28#include "CglFlowCover.hpp"
29#include "CglMixedIntegerRounding.hpp"
30#include "CglTwomir.hpp"
31#include "CglDuplicateRow.hpp"
32#include "CbcFathomDynamicProgramming.hpp"
33
34static int timesBad_=0;
35//#############################################################################
36// Solve methods
37//#############################################################################
38static CglDuplicateRow * tryCut=NULL;
39void CbcSolverLongThin::initialSolve()
40{
41  modelPtr_->scaling(0);
42  setBasis(basis_,modelPtr_);
43  modelPtr_->dual();
44  basis_ = getBasis(modelPtr_);
45  assert(!modelPtr_->specialOptions());
46  modelPtr_->setLogLevel(0);
47  if (!tryCut) {
48    tryCut = new CglDuplicateRow(this);
49    tryCut->setLogLevel(2);
50  }
51}
52
53//-----------------------------------------------------------------------------
54void CbcSolverLongThin::resolve()
55{
56  int * whichRow = NULL;
57  int * whichColumn = NULL;
58  // problem may be small enough to do nested search
59  const double * colLower = modelPtr_->columnLower();
60  const double * colUpper = modelPtr_->columnUpper();
61 
62  int numberIntegers = model_->numberIntegers();
63  const int * integerVariable = model_->integerVariable();
64  int numberRows=modelPtr_->numberRows();
65  int numberColumns = modelPtr_->numberColumns();
66 
67  int i;
68  int nFix=0;
69  int nNewRow=0;
70  int nNewCol=0;
71  int sizeDynamic = COIN_INT_MAX;
72  int smallOriginalNumberRows=0;
73  if (algorithm_==0) {
74    for (i=0;i<numberIntegers;i++) {
75      int iColumn=integerVariable[i];
76      if (colLower[iColumn]==colUpper[iColumn])
77        nFix++;
78    }
79  } else {
80    whichRow = new int[numberRows];
81    whichColumn = new int [numberColumns];
82    // more sophisticated
83    OsiCuts cs;
84    tryCut->generateCuts(*this,cs);
85    int numberCuts = cs.sizeColCuts();
86    if (numberCuts) {
87      for ( i = 0 ; i < numberCuts ; i++) {
88        const OsiColCut *thisCut = cs.colCutPtr(i) ;
89        const CoinPackedVector & ubs = thisCut->ubs() ;
90        int n = ubs.getNumElements() ;
91        const int * which = ubs.getIndices() ;
92        const double * values = ubs.getElements() ;
93        for (int j = 0;j<n;j++) {
94          int iColumn = which[j] ;
95          this->setColUpper(iColumn,values[j]) ;
96        }
97      }
98    }
99#if 1
100    const int * duplicate = tryCut->duplicate();
101    sizeDynamic = tryCut->sizeDynamic();
102    int nOrig = tryCut->numberOriginalRows();
103    for (i=0;i<nOrig;i++) {
104      if (duplicate[i]==-1)
105        whichRow[nNewRow++]=i;
106      else
107        modelPtr_->setRowStatus(i,ClpSimplex::basic);
108    }
109    smallOriginalNumberRows=nNewRow;
110    for (;i<numberRows;i++) {
111      whichRow[nNewRow++]=i;
112    }
113#else
114    for (i=0;i<numberRows;i++) 
115      whichRow[i]=i;
116    nNewRow=numberRows;
117#endif
118    for (i=0;i<numberIntegers;i++) {
119      int iColumn=integerVariable[i];
120      if (colLower[iColumn]==colUpper[iColumn])
121        nFix++;
122      bool choose;
123      if (algorithm_==1)
124        choose = true;
125      else
126        choose = (node_[i]>count_-memory_&&node_[i]>0);
127      if ((choose&&colUpper[i])
128          ||(modelPtr_->getStatus(i)!=ClpSimplex::atLowerBound&&
129             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 =
403          new CbcSimpleIntegerPseudoCost(&modelSmall,n,i,objective[i],0.5*objective[i]);
404        newObject->setMethod(3);
405        objects[n]= newObject;
406        priority[n++]=10000-columnLength[i];
407      }
408      priority[n]=1;
409      objects[n++]=new CbcFollowOn2(&modelSmall);
410      modelSmall.addObjects(n,objects);
411      for (i=0;i<n;i++)
412        delete objects[i];
413      delete [] objects;
414      modelSmall.passInPriorities(priority,false);
415      delete [] priority;
416#endif
417      modelSmall.setCutoff(model_->getCutoff());
418      //if (!onPathX&&modelSmall.getCutoff()>480.5)
419      //modelSmall.setCutoff(480.5);
420      //printf("cutoff %g\n",model_->getCutoff());
421      modelSmall.messageHandler()->setLogLevel(1);
422      modelSmall.solver()->messageHandler()->setLogLevel(0);
423      modelSmall.messagesPointer()->setDetailMessage(3,9);
424      modelSmall.messagesPointer()->setDetailMessage(3,6);
425      modelSmall.messagesPointer()->setDetailMessage(3,4);
426      modelSmall.messagesPointer()->setDetailMessage(3,13);
427      modelSmall.messagesPointer()->setDetailMessage(3,14);
428      modelSmall.messagesPointer()->setDetailMessage(3,1);
429      modelSmall.messagesPointer()->setDetailMessage(3,3007);
430      modelSmall.branchAndBound();
431      temp2.releaseClp();
432      if (modelSmall.bestSolution()) {
433        double objValue = 0.0;
434        const double * solution2 = modelSmall.bestSolution();
435        double * solution = modelPtr_->primalColumnSolution();
436        const double * objective = modelPtr_->objective();
437        for (i=0;i<numberColumns;i++)
438          solution[i]=colLower[i];
439        for (i=0;i<nNewCol;i++) {
440          int iColumn = whichColumn[i];
441          solution[iColumn]=solution2[i];
442        }
443        for (i=0;i<numberColumns;i++)
444          objValue += solution[i]*objective[i];
445        assert (objValue<model_->getCutoff());
446        if (objValue<model_->getCutoff()) {
447          //printf("good solution \n");
448          model_->setBestSolution(CBC_TREE_SOL,objValue,solution);
449          returnCode = 0;
450        } else {
451          returnCode=2;
452        }
453      } else {
454        returnCode=2;
455      }
456#endif
457      if (returnCode!=0&&returnCode!=2) {
458        printf("pretending entire search done\n");
459        returnCode=0;
460      }
461      if (returnCode==0||returnCode==2) {
462        modelPtr_->setProblemStatus(1);
463        delete [] whichRow;
464        delete [] whichColumn;
465        return;
466     }
467    }
468  }
469  if ((count_<100&&algorithm_==2)||!algorithm_) {
470    delete [] whichRow;
471    delete [] whichColumn;
472    assert(!modelPtr_->specialOptions());
473    int saveOptions = modelPtr_->specialOptions();
474    int startFinishOptions;
475    bool takeHint;
476    OsiHintStrength strength;
477    bool gotHint = (getHintParam(OsiDoInBranchAndCut,takeHint,strength));
478    assert (gotHint);
479    if (strength!=OsiHintIgnore&&takeHint) {
480      // could do something - think about it
481      //printf("thin hint %d %c\n",strength,takeHint ? 'T' :'F');
482    }
483    if((specialOptions_&1)==0) {
484      startFinishOptions=0;
485      modelPtr_->setSpecialOptions(saveOptions|(64|1024));
486    } else {
487      startFinishOptions=1+2+4;
488      if((specialOptions_&4)==0) 
489        modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|4096));
490      else
491        modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|2048|4096));
492    }
493    //printf("thin options %d size %d\n",modelPtr_->specialOptions(),modelPtr_->numberColumns());
494    setBasis(basis_,modelPtr_);
495    //modelPtr_->setLogLevel(1);
496    modelPtr_->dual(0,0);
497    basis_ = getBasis(modelPtr_);
498    modelPtr_->setSpecialOptions(saveOptions);
499    if (modelPtr_->status()==0) {
500      count_++;
501      double * solution = modelPtr_->primalColumnSolution();
502      int i;
503      for (i=0;i<numberColumns;i++) {
504        if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
505          node_[i]=CoinMax(count_,node_[i]);
506          howMany_[i]++;
507        }
508      }
509    } else {
510      if (!algorithm_==2)
511        printf("infeasible early on\n");
512    }
513  } else {
514    // use counts
515    int i;
516    const double * lower = modelPtr_->columnLower();
517    const double * upper = modelPtr_->columnUpper();
518    setBasis(basis_,modelPtr_);
519    ClpSimplex * temp = new ClpSimplex(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
520    //temp->setLogLevel(2);
521    //printf("small has %d rows and %d columns\n",nNewRow,nNewCol);
522    temp->setSpecialOptions(128+512);
523    temp->setDualObjectiveLimit(1.0e50);
524    temp->dual();
525    if (temp->status()) {
526      // In some cases we know that it must be infeasible
527      if (believeInfeasible_||algorithm_==1) {
528        modelPtr_->setProblemStatus(1);
529        printf("assuming infeasible!\n");
530        //modelPtr_->writeMps("infeas.mps");
531        //temp->writeMps("infeas2.mps");
532        //abort();
533        delete temp;
534        delete [] whichRow;
535        delete [] whichColumn;
536        return;
537      }
538    }
539    double * solution = modelPtr_->primalColumnSolution();
540    if (!temp->status()) {
541      const double * solution2 = temp->primalColumnSolution();
542      memset(solution,0,numberColumns*sizeof(double));
543      for (i=0;i<nNewCol;i++) {
544        int iColumn = whichColumn[i];
545        solution[iColumn]=solution2[i];
546        modelPtr_->setStatus(iColumn,temp->getStatus(i));
547      }
548      double * rowSolution = modelPtr_->primalRowSolution();
549      const double * rowSolution2 = temp->primalRowSolution();
550      double * dual = modelPtr_->dualRowSolution();
551      const double * dual2 = temp->dualRowSolution();
552      memset(dual,0,numberRows*sizeof(double));
553      for (i=0;i<nNewRow;i++) {
554        int iRow=whichRow[i];
555        modelPtr_->setRowStatus(iRow,temp->getRowStatus(i));
556        rowSolution[iRow]=rowSolution2[i];
557        dual[iRow]=dual2[i];
558      }
559      // See if optimal
560      double * dj = modelPtr_->dualColumnSolution();
561      // get reduced cost for large problem
562      // this assumes minimization
563      memcpy(dj,modelPtr_->objective(),numberColumns*sizeof(double));
564      modelPtr_->transposeTimes(-1.0,dual,dj);
565      modelPtr_->setObjectiveValue(temp->objectiveValue());
566      modelPtr_->setProblemStatus(0);
567      int nBad=0;
568     
569      for (i=0;i<numberColumns;i++) {
570        if (modelPtr_->getStatus(i)==ClpSimplex::atLowerBound
571            &&upper[i]>lower[i]&&dj[i]<-1.0e-5)
572          nBad++;
573      }
574      //modelPtr_->writeMps("bada.mps");
575      //temp->writeMps("badb.mps");
576      if (nBad) {
577        assert (algorithm_==2);
578        //printf("%d bad\n",nBad);
579        timesBad_++;
580        modelPtr_->primal();
581      }
582    } else {
583      // infeasible - do all
584      modelPtr_->setSpecialOptions(64+128+512);
585      setBasis(basis_,modelPtr_);
586      //modelPtr_->setLogLevel(1);
587      modelPtr_->dual(0,0);
588      basis_ = getBasis(modelPtr_);
589      modelPtr_->setSpecialOptions(0);
590      if (modelPtr_->status()) {
591        printf("really infeasible!\n");
592        delete temp;
593        delete [] whichRow;
594        delete [] whichColumn;
595        return;
596      } else {
597        printf("initially infeasible\n");
598      }
599    }
600    delete temp;
601    delete [] whichRow;
602    delete [] whichColumn;
603    basis_ = getBasis(modelPtr_);
604    modelPtr_->setSpecialOptions(0);
605    count_++;
606    if ((count_%100)==0&&algorithm_==2)
607      printf("count %d, bad %d\n",count_,timesBad_);
608    for (i=0;i<numberColumns;i++) {
609      if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
610        node_[i]=CoinMax(count_,node_[i]);
611        howMany_[i]++;
612      }
613    }
614    if (modelPtr_->objectiveValue()>=modelPtr_->dualObjectiveLimit())
615      modelPtr_->setProblemStatus(1);
616  }
617}
618
619//#############################################################################
620// Constructors, destructors clone and assignment
621//#############################################################################
622
623//-------------------------------------------------------------------
624// Default Constructor
625//-------------------------------------------------------------------
626CbcSolverLongThin::CbcSolverLongThin ()
627  : OsiClpSolverInterface()
628{
629  node_=NULL;
630  howMany_=NULL;
631  count_=0;
632  model_ = NULL;
633  memory_=300;
634  believeInfeasible_=false;
635  nestedSearch_ = 1.0;
636  algorithm_=0;
637}
638
639//-------------------------------------------------------------------
640// Clone
641//-------------------------------------------------------------------
642OsiSolverInterface * 
643CbcSolverLongThin::clone(bool CopyData) const
644{
645  if (CopyData) {
646    return new CbcSolverLongThin(*this);
647  } else {
648    printf("warning CbcSolveUser clone with copyData false\n");
649    return new CbcSolverLongThin();
650  }
651}
652
653
654//-------------------------------------------------------------------
655// Copy constructor
656//-------------------------------------------------------------------
657CbcSolverLongThin::CbcSolverLongThin (
658                  const CbcSolverLongThin & rhs)
659  : OsiClpSolverInterface(rhs)
660{
661  model_ = rhs.model_;
662  int numberColumns = modelPtr_->numberColumns();
663  node_=CoinCopyOfArray(rhs.node_,numberColumns);
664  howMany_=CoinCopyOfArray(rhs.howMany_,numberColumns);
665  count_=rhs.count_;
666  memory_=rhs.memory_;
667  believeInfeasible_ = rhs.believeInfeasible_;
668  nestedSearch_ = rhs.nestedSearch_;
669  algorithm_=rhs.algorithm_;
670}
671
672//-------------------------------------------------------------------
673// Destructor
674//-------------------------------------------------------------------
675CbcSolverLongThin::~CbcSolverLongThin ()
676{
677  delete [] node_;
678  delete [] howMany_;
679}
680
681//-------------------------------------------------------------------
682// Assignment operator
683//-------------------------------------------------------------------
684CbcSolverLongThin &
685CbcSolverLongThin::operator=(const CbcSolverLongThin& rhs)
686{
687  if (this != &rhs) { 
688    OsiClpSolverInterface::operator=(rhs);
689    delete [] node_;
690    delete [] howMany_;
691    model_ = rhs.model_;
692    int numberColumns = modelPtr_->numberColumns();
693    node_=CoinCopyOfArray(rhs.node_,numberColumns);
694    howMany_=CoinCopyOfArray(rhs.howMany_,numberColumns);
695    count_=rhs.count_;
696    memory_=rhs.memory_;
697    believeInfeasible_ = rhs.believeInfeasible_;
698    nestedSearch_ = rhs.nestedSearch_;
699    algorithm_=rhs.algorithm_;
700  }
701  return *this;
702}
703//-------------------------------------------------------------------
704// Real initializer
705//-------------------------------------------------------------------
706void
707CbcSolverLongThin::initialize (CbcModel * model, const char * keep)
708{
709  model_=model;
710  int numberColumns = modelPtr_->numberColumns();
711  if (numberColumns) {
712    node_ = new int[numberColumns];
713    howMany_ = new int[numberColumns];
714    for (int i=0;i<numberColumns;i++) {
715      if (keep[i])
716        node_[i]=COIN_INT_MAX;
717      else
718        node_[i]=0;
719      howMany_[i]=0;
720    }
721  } else {
722    node_=NULL;
723    howMany_=NULL;
724  }
725}
Note: See TracBrowser for help on using the repository browser.