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

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

remove include of missing file

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.2 KB
Line 
1// $Id: CbcSolverLongThin.cpp 1793 2012-08-08 09:02:01Z stefan $
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    int startFinishOptions;
476    bool takeHint;
477    OsiHintStrength strength;
478    bool gotHint = (getHintParam(OsiDoInBranchAndCut,takeHint,strength));
479    assert (gotHint);
480    if (strength!=OsiHintIgnore&&takeHint) {
481      // could do something - think about it
482      //printf("thin hint %d %c\n",strength,takeHint ? 'T' :'F');
483    }
484    if((specialOptions_&1)==0) {
485      startFinishOptions=0;
486      modelPtr_->setSpecialOptions(saveOptions|(64|1024));
487    } else {
488      startFinishOptions=1+2+4;
489      if((specialOptions_&4)==0) 
490        modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|4096));
491      else
492        modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|2048|4096));
493    }
494    //printf("thin options %d size %d\n",modelPtr_->specialOptions(),modelPtr_->numberColumns());
495    setBasis(basis_,modelPtr_);
496    //modelPtr_->setLogLevel(1);
497    modelPtr_->dual(0,0);
498    basis_ = getBasis(modelPtr_);
499    modelPtr_->setSpecialOptions(saveOptions);
500    if (modelPtr_->status()==0) {
501      count_++;
502      double * solution = modelPtr_->primalColumnSolution();
503      int i;
504      for (i=0;i<numberColumns;i++) {
505        if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
506          node_[i]=CoinMax(count_,node_[i]);
507          howMany_[i]++;
508        }
509      }
510    } else {
511      if (!algorithm_==2)
512        printf("infeasible early on\n");
513    }
514  } else {
515    // use counts
516    int i;
517    const double * lower = modelPtr_->columnLower();
518    const double * upper = modelPtr_->columnUpper();
519    setBasis(basis_,modelPtr_);
520    ClpSimplex * temp = new ClpSimplex(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
521    //temp->setLogLevel(2);
522    //printf("small has %d rows and %d columns\n",nNewRow,nNewCol);
523    temp->setSpecialOptions(128+512);
524    temp->setDualObjectiveLimit(1.0e50);
525    temp->dual();
526    if (temp->status()) {
527      // In some cases we know that it must be infeasible
528      if (believeInfeasible_||algorithm_==1) {
529        modelPtr_->setProblemStatus(1);
530        printf("assuming infeasible!\n");
531        //modelPtr_->writeMps("infeas.mps");
532        //temp->writeMps("infeas2.mps");
533        //abort();
534        delete temp;
535        delete [] whichRow;
536        delete [] whichColumn;
537        return;
538      }
539    }
540    double * solution = modelPtr_->primalColumnSolution();
541    if (!temp->status()) {
542      const double * solution2 = temp->primalColumnSolution();
543      memset(solution,0,numberColumns*sizeof(double));
544      for (i=0;i<nNewCol;i++) {
545        int iColumn = whichColumn[i];
546        solution[iColumn]=solution2[i];
547        modelPtr_->setStatus(iColumn,temp->getStatus(i));
548      }
549      double * rowSolution = modelPtr_->primalRowSolution();
550      const double * rowSolution2 = temp->primalRowSolution();
551      double * dual = modelPtr_->dualRowSolution();
552      const double * dual2 = temp->dualRowSolution();
553      memset(dual,0,numberRows*sizeof(double));
554      for (i=0;i<nNewRow;i++) {
555        int iRow=whichRow[i];
556        modelPtr_->setRowStatus(iRow,temp->getRowStatus(i));
557        rowSolution[iRow]=rowSolution2[i];
558        dual[iRow]=dual2[i];
559      }
560      // See if optimal
561      double * dj = modelPtr_->dualColumnSolution();
562      // get reduced cost for large problem
563      // this assumes minimization
564      memcpy(dj,modelPtr_->objective(),numberColumns*sizeof(double));
565      modelPtr_->transposeTimes(-1.0,dual,dj);
566      modelPtr_->setObjectiveValue(temp->objectiveValue());
567      modelPtr_->setProblemStatus(0);
568      int nBad=0;
569     
570      for (i=0;i<numberColumns;i++) {
571        if (modelPtr_->getStatus(i)==ClpSimplex::atLowerBound
572            &&upper[i]>lower[i]&&dj[i]<-1.0e-5)
573          nBad++;
574      }
575      //modelPtr_->writeMps("bada.mps");
576      //temp->writeMps("badb.mps");
577      if (nBad) {
578        assert (algorithm_==2);
579        //printf("%d bad\n",nBad);
580        timesBad_++;
581        modelPtr_->primal();
582      }
583    } else {
584      // infeasible - do all
585      modelPtr_->setSpecialOptions(64+128+512);
586      setBasis(basis_,modelPtr_);
587      //modelPtr_->setLogLevel(1);
588      modelPtr_->dual(0,0);
589      basis_ = getBasis(modelPtr_);
590      modelPtr_->setSpecialOptions(0);
591      if (modelPtr_->status()) {
592        printf("really infeasible!\n");
593        delete temp;
594        delete [] whichRow;
595        delete [] whichColumn;
596        return;
597      } else {
598        printf("initially infeasible\n");
599      }
600    }
601    delete temp;
602    delete [] whichRow;
603    delete [] whichColumn;
604    basis_ = getBasis(modelPtr_);
605    modelPtr_->setSpecialOptions(0);
606    count_++;
607    if ((count_%100)==0&&algorithm_==2)
608      printf("count %d, bad %d\n",count_,timesBad_);
609    for (i=0;i<numberColumns;i++) {
610      if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
611        node_[i]=CoinMax(count_,node_[i]);
612        howMany_[i]++;
613      }
614    }
615    if (modelPtr_->objectiveValue()>=modelPtr_->dualObjectiveLimit())
616      modelPtr_->setProblemStatus(1);
617  }
618}
619
620//#############################################################################
621// Constructors, destructors clone and assignment
622//#############################################################################
623
624//-------------------------------------------------------------------
625// Default Constructor
626//-------------------------------------------------------------------
627CbcSolverLongThin::CbcSolverLongThin ()
628  : OsiClpSolverInterface()
629{
630  node_=NULL;
631  howMany_=NULL;
632  count_=0;
633  model_ = NULL;
634  memory_=300;
635  believeInfeasible_=false;
636  nestedSearch_ = 1.0;
637  algorithm_=0;
638}
639
640//-------------------------------------------------------------------
641// Clone
642//-------------------------------------------------------------------
643OsiSolverInterface * 
644CbcSolverLongThin::clone(bool CopyData) const
645{
646  if (CopyData) {
647    return new CbcSolverLongThin(*this);
648  } else {
649    printf("warning CbcSolveUser clone with copyData false\n");
650    return new CbcSolverLongThin();
651  }
652}
653
654
655//-------------------------------------------------------------------
656// Copy constructor
657//-------------------------------------------------------------------
658CbcSolverLongThin::CbcSolverLongThin (
659                  const CbcSolverLongThin & rhs)
660  : OsiClpSolverInterface(rhs)
661{
662  model_ = rhs.model_;
663  int numberColumns = modelPtr_->numberColumns();
664  node_=CoinCopyOfArray(rhs.node_,numberColumns);
665  howMany_=CoinCopyOfArray(rhs.howMany_,numberColumns);
666  count_=rhs.count_;
667  memory_=rhs.memory_;
668  believeInfeasible_ = rhs.believeInfeasible_;
669  nestedSearch_ = rhs.nestedSearch_;
670  algorithm_=rhs.algorithm_;
671}
672
673//-------------------------------------------------------------------
674// Destructor
675//-------------------------------------------------------------------
676CbcSolverLongThin::~CbcSolverLongThin ()
677{
678  delete [] node_;
679  delete [] howMany_;
680}
681
682//-------------------------------------------------------------------
683// Assignment operator
684//-------------------------------------------------------------------
685CbcSolverLongThin &
686CbcSolverLongThin::operator=(const CbcSolverLongThin& rhs)
687{
688  if (this != &rhs) { 
689    OsiClpSolverInterface::operator=(rhs);
690    delete [] node_;
691    delete [] howMany_;
692    model_ = rhs.model_;
693    int numberColumns = modelPtr_->numberColumns();
694    node_=CoinCopyOfArray(rhs.node_,numberColumns);
695    howMany_=CoinCopyOfArray(rhs.howMany_,numberColumns);
696    count_=rhs.count_;
697    memory_=rhs.memory_;
698    believeInfeasible_ = rhs.believeInfeasible_;
699    nestedSearch_ = rhs.nestedSearch_;
700    algorithm_=rhs.algorithm_;
701  }
702  return *this;
703}
704//-------------------------------------------------------------------
705// Real initializer
706//-------------------------------------------------------------------
707void
708CbcSolverLongThin::initialize (CbcModel * model, const char * keep)
709{
710  model_=model;
711  int numberColumns = modelPtr_->numberColumns();
712  if (numberColumns) {
713    node_ = new int[numberColumns];
714    howMany_ = new int[numberColumns];
715    for (int i=0;i<numberColumns;i++) {
716      if (keep[i])
717        node_[i]=COIN_INT_MAX;
718      else
719        node_[i]=0;
720      howMany_[i]=0;
721    }
722  } else {
723    node_=NULL;
724    howMany_=NULL;
725  }
726}
Note: See TracBrowser for help on using the repository browser.