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

Last change on this file since 1574 was 1574, checked in by lou, 8 years ago

Change to EPL license notice.

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