source: trunk/Cbc/examples/CbcSolverLongThin.cpp

Last change on this file was 1898, checked in by stefan, 6 years ago

fixup examples

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