source: trunk/Test/CoinSolve.cpp @ 242

Last change on this file since 242 was 242, checked in by forrest, 14 years ago

infeasible on preprocessing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 100.6 KB
Line 
1// Copyright (C) 2004, International Business Machines
2// Corporation and others.  All Rights Reserved.
3   
4#include "CoinPragma.hpp"
5
6#include <cassert>
7#include <cstdio>
8#include <cmath>
9#include <cfloat>
10#include <string>
11#include <iostream>
12
13
14#include "CoinPragma.hpp"
15#include "CoinHelperFunctions.hpp"
16// Same version as CBC
17#define CBCVERSION "1.00.02"
18
19#include "CoinMpsIO.hpp"
20
21#include "ClpFactorization.hpp"
22#include "CoinTime.hpp"
23#include "ClpSimplex.hpp"
24#include "ClpSolve.hpp"
25#include "ClpPackedMatrix.hpp"
26#include "ClpPlusMinusOneMatrix.hpp"
27#include "ClpNetworkMatrix.hpp"
28#include "ClpDualRowSteepest.hpp"
29#include "ClpDualRowDantzig.hpp"
30#include "ClpLinearObjective.hpp"
31#include "ClpPrimalColumnSteepest.hpp"
32#include "ClpPrimalColumnDantzig.hpp"
33#include "ClpPresolve.hpp"
34#include "CbcOrClpParam.hpp"
35#include "OsiRowCutDebugger.hpp"
36#ifdef DMALLOC
37#include "dmalloc.h"
38#endif
39#ifdef WSSMP_BARRIER
40#define FOREIGN_BARRIER
41#endif
42#ifdef UFL_BARRIER
43#define FOREIGN_BARRIER
44#endif
45#ifdef TAUCS_BARRIER
46#define FOREIGN_BARRIER
47#endif
48#include "CoinWarmStartBasis.hpp"
49
50#include "OsiSolverInterface.hpp"
51#include "OsiCuts.hpp"
52#include "OsiRowCut.hpp"
53#include "OsiColCut.hpp"
54
55#include "CglPreProcess.hpp"
56#include "CglCutGenerator.hpp"
57#include "CglGomory.hpp"
58#include "CglProbing.hpp"
59#include "CglKnapsackCover.hpp"
60#include "CglRedSplit.hpp"
61#include "CglClique.hpp"
62#include "CglFlowCover.hpp"
63#include "CglMixedIntegerRounding2.hpp"
64#include "CglTwomir.hpp"
65
66#include "CbcModel.hpp"
67#include "CbcHeuristic.hpp"
68#include "CbcHeuristicLocal.hpp"
69#include "CbcHeuristicGreedy.hpp"
70#include "CbcHeuristicFPump.hpp"
71#include "CbcTreeLocal.hpp"
72#include "CbcCompareActual.hpp"
73#include "CbcBranchActual.hpp"
74#include  "CbcOrClpParam.hpp"
75#include  "CbcCutGenerator.hpp"
76
77#include "OsiClpSolverInterface.hpp"
78#ifdef CBC_AMPL
79#include "Cbc_ampl.h"
80static bool usingAmpl=false;
81#endif
82static double totalTime=0.0;
83
84//#############################################################################
85
86#ifdef NDEBUG
87#undef NDEBUG
88#endif
89// Allow for interrupts
90// But is this threadsafe ? (so switched off by option)
91
92#include "CoinSignal.hpp"
93static CbcModel * currentBranchModel = NULL;
94
95extern "C" {
96   static void signal_handler(int whichSignal)
97   {
98      if (currentBranchModel!=NULL) 
99         currentBranchModel->setMaximumNodes(0); // stop at next node
100      return;
101   }
102}
103
104int mainTest (int argc, const char *argv[],int algorithm,
105              ClpSimplex empty, bool doPresolve,int switchOff);
106int CbcOrClpRead_mode=1;
107FILE * CbcOrClpReadCommand=stdin;
108static bool noPrinting=false;
109static int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment,
110                     bool changeInt)
111{
112  OsiSolverInterface * solver = solverMod->clone();
113  if (0) {
114    // just get increment
115    CbcModel model(*solver);
116    model.analyzeObjective();
117    double increment2=model.getCutoffIncrement();
118    printf("initial cutoff increment %g\n",increment2);
119  }
120  const double *objective = solver->getObjCoefficients() ;
121  const double *lower = solver->getColLower() ;
122  const double *upper = solver->getColUpper() ;
123  int numberColumns = solver->getNumCols() ;
124  int numberRows = solver->getNumRows();
125  double direction = solver->getObjSense();
126  int iRow,iColumn;
127
128  // Row copy
129  CoinPackedMatrix matrixByRow(*solver->getMatrixByRow());
130  const double * elementByRow = matrixByRow.getElements();
131  const int * column = matrixByRow.getIndices();
132  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
133  const int * rowLength = matrixByRow.getVectorLengths();
134
135  // Column copy
136  CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
137  const double * element = matrixByCol.getElements();
138  const int * row = matrixByCol.getIndices();
139  const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
140  const int * columnLength = matrixByCol.getVectorLengths();
141
142  const double * rowLower = solver->getRowLower();
143  const double * rowUpper = solver->getRowUpper();
144
145  char * ignore = new char [numberRows];
146  int * changed = new int[numberColumns];
147  int * which = new int[numberRows];
148  double * changeRhs = new double[numberRows];
149  memset(changeRhs,0,numberRows*sizeof(double));
150  memset(ignore,0,numberRows);
151  numberChanged=0;
152  int numberInteger=0;
153  for (iColumn=0;iColumn<numberColumns;iColumn++) {
154    if (upper[iColumn] > lower[iColumn]+1.0e-8&&solver->isInteger(iColumn)) 
155      numberInteger++;
156  }
157  bool finished=false;
158  while (!finished) {
159    int saveNumberChanged = numberChanged;
160    for (iRow=0;iRow<numberRows;iRow++) {
161      int numberContinuous=0;
162      double value1=0.0,value2=0.0;
163      bool allIntegerCoeff=true;
164      double sumFixed=0.0;
165      int jColumn1=-1,jColumn2=-1;
166      for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
167        int jColumn = column[j];
168        double value = elementByRow[j];
169        if (upper[jColumn] > lower[jColumn]+1.0e-8) {
170          if (!solver->isInteger(jColumn)) {
171            if (numberContinuous==0) {
172              jColumn1=jColumn;
173              value1=value;
174            } else {
175              jColumn2=jColumn;
176              value2=value;
177            }
178            numberContinuous++;
179          } else {
180            if (fabs(value-floor(value+0.5))>1.0e-12)
181              allIntegerCoeff=false;
182          }
183        } else {
184          sumFixed += lower[jColumn]*value;
185        }
186      }
187      double low = rowLower[iRow];
188      if (low>-1.0e20) {
189        low -= sumFixed;
190        if (fabs(low-floor(low+0.5))>1.0e-12)
191          allIntegerCoeff=false;
192      }
193      double up = rowUpper[iRow];
194      if (up<1.0e20) {
195        up -= sumFixed;
196        if (fabs(up-floor(up+0.5))>1.0e-12)
197          allIntegerCoeff=false;
198      }
199      if (numberContinuous==1) {
200        // see if really integer
201        // This does not allow for complicated cases
202        if (low==up) {
203          if (fabs(value1)>1.0e-3) {
204            value1 = 1.0/value1;
205            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
206              // integer
207              changed[numberChanged++]=jColumn1;
208              solver->setInteger(jColumn1);
209              if (upper[jColumn1]>1.0e20)
210                solver->setColUpper(jColumn1,1.0e20);
211              if (lower[jColumn1]<-1.0e20)
212                solver->setColLower(jColumn1,-1.0e20);
213            }
214          }
215        } else {
216          if (fabs(value1)>1.0e-3) {
217            value1 = 1.0/value1;
218            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
219              // This constraint will not stop it being integer
220              ignore[iRow]=1;
221            }
222          }
223        }
224      } else if (numberContinuous==2) {
225        if (low==up) {
226          /* need general theory - for now just look at 2 cases -
227             1 - +- 1 one in column and just costs i.e. matching objective
228             2 - +- 1 two in column but feeds into G/L row which will try and minimize
229          */
230          if (fabs(value1)==1.0&&value1*value2==-1.0&&!lower[jColumn1]
231              &&!lower[jColumn2]) {
232            int n=0;
233            int i;
234            double objChange=direction*(objective[jColumn1]+objective[jColumn2]);
235            double bound = CoinMin(upper[jColumn1],upper[jColumn2]);
236            bound = CoinMin(bound,1.0e20);
237            for ( i=columnStart[jColumn1];i<columnStart[jColumn1]+columnLength[jColumn1];i++) {
238              int jRow = row[i];
239              double value = element[i];
240              if (jRow!=iRow) {
241                which[n++]=jRow;
242                changeRhs[jRow]=value;
243              }
244            }
245            for ( i=columnStart[jColumn1];i<columnStart[jColumn1]+columnLength[jColumn1];i++) {
246              int jRow = row[i];
247              double value = element[i];
248              if (jRow!=iRow) {
249                if (!changeRhs[jRow]) {
250                  which[n++]=jRow;
251                  changeRhs[jRow]=value;
252                } else {
253                  changeRhs[jRow]+=value;
254                }
255              }
256            }
257            if (objChange>=0.0) {
258              // see if all rows OK
259              bool good=true;
260              for (i=0;i<n;i++) {
261                int jRow = which[i];
262                double value = changeRhs[jRow];
263                if (value) {
264                  value *= bound;
265                  if (rowLength[jRow]==1) {
266                    if (value>0.0) {
267                      double rhs = rowLower[jRow];
268                      if (rhs>0.0) {
269                        double ratio =rhs/value;
270                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
271                          good=false;
272                      }
273                    } else {
274                      double rhs = rowUpper[jRow];
275                      if (rhs<0.0) {
276                        double ratio =rhs/value;
277                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
278                          good=false;
279                      }
280                    }
281                  } else if (rowLength[jRow]==2) {
282                    if (value>0.0) {
283                      if (rowLower[jRow]>-1.0e20)
284                        good=false;
285                    } else {
286                      if (rowUpper[jRow]<1.0e20)
287                        good=false;
288                    }
289                  } else {
290                    good=false;
291                  }
292                }
293              }
294              if (good) {
295                // both can be integer
296                changed[numberChanged++]=jColumn1;
297                solver->setInteger(jColumn1);
298                if (upper[jColumn1]>1.0e20)
299                  solver->setColUpper(jColumn1,1.0e20);
300                if (lower[jColumn1]<-1.0e20)
301                  solver->setColLower(jColumn1,-1.0e20);
302                changed[numberChanged++]=jColumn2;
303                solver->setInteger(jColumn2);
304                if (upper[jColumn2]>1.0e20)
305                  solver->setColUpper(jColumn2,1.0e20);
306                if (lower[jColumn2]<-1.0e20)
307                  solver->setColLower(jColumn2,-1.0e20);
308              }
309            }
310            // clear
311            for (i=0;i<n;i++) {
312              changeRhs[which[i]]=0.0;
313            }
314          }
315        }
316      }
317    }
318    for (iColumn=0;iColumn<numberColumns;iColumn++) {
319      if (upper[iColumn] > lower[iColumn]+1.0e-8&&!solver->isInteger(iColumn)) {
320        double value;
321        value = upper[iColumn];
322        if (value<1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
323          continue;
324        value = lower[iColumn];
325        if (value>-1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
326          continue;
327        bool integer=true;
328        for (CoinBigIndex j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn];j++) {
329          int iRow = row[j];
330          if (!ignore[iRow]) {
331            integer=false;
332            break;
333          }
334        }
335        if (integer) {
336          // integer
337          changed[numberChanged++]=iColumn;
338          solver->setInteger(iColumn);
339          if (upper[iColumn]>1.0e20)
340            solver->setColUpper(iColumn,1.0e20);
341          if (lower[iColumn]<-1.0e20)
342            solver->setColLower(iColumn,-1.0e20);
343        }
344      }
345    }
346    finished = numberChanged==saveNumberChanged;
347  }
348  delete [] which;
349  delete [] changeRhs;
350  delete [] ignore;
351  if (numberInteger&&!noPrinting)
352    printf("%d integer variables",numberInteger);
353  if (changeInt) {
354    if (!noPrinting) {
355      if (numberChanged)
356        printf(" and %d variables made integer\n",numberChanged);
357      else
358        printf("\n");
359    }
360    delete [] ignore;
361    //increment=0.0;
362    if (!numberChanged) {
363      delete [] changed;
364      delete solver;
365      return NULL;
366    } else {
367      for (iColumn=0;iColumn<numberColumns;iColumn++) {
368        if (solver->isInteger(iColumn))
369          solverMod->setInteger(iColumn);
370      }
371      delete solver;
372      return changed;
373    }
374  } else {
375    if (!noPrinting) {
376      if (numberChanged)
377        printf(" and %d variables could be made integer\n",numberChanged);
378      else
379        printf("\n");
380    }
381    // just get increment
382    CbcModel model(*solver);
383    if (noPrinting)
384      model.setLogLevel(0);
385    model.analyzeObjective();
386    double increment2=model.getCutoffIncrement();
387    if (increment2>increment) {
388      if (!noPrinting)
389        printf("cutoff increment increased from %g to %g\n",increment,increment2);
390      increment=increment2;
391    }
392    delete solver;
393    numberChanged=0;
394    delete [] changed;
395    return NULL;
396  }
397}
398int main (int argc, const char *argv[])
399{
400  /* Note
401     This is meant as a stand-alone executable to do as much of coin as possible.
402     It should only have one solver known to it.
403  */
404  {
405    double time1 = CoinCpuTime(),time2;
406    bool goodModel=false;
407    CoinSighandler_t saveSignal=SIG_DFL;
408    // register signal handler
409    saveSignal = signal(SIGINT,signal_handler);
410    // Set up all non-standard stuff
411    OsiClpSolverInterface solver1;
412    CbcModel model(solver1);
413    CbcModel * babModel = NULL;
414    model.setNumberBeforeTrust(21);
415    int cutPass=-1234567;
416    OsiSolverInterface * solver = model.solver();
417    OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
418    ClpSimplex * lpSolver = clpSolver->getModelPtr();
419    clpSolver->messageHandler()->setLogLevel(0) ;
420    model.messageHandler()->setLogLevel(1);
421#ifdef CBC_AMPL
422    ampl_info info;
423    if (argc>2&&!strcmp(argv[2],"-AMPL")) {
424      usingAmpl=true;
425      int returnCode = readAmpl(&info,argc,const_cast<char **>(argv));
426      if (returnCode)
427        return returnCode;
428      CbcOrClpRead_mode=2; // so will start with parameters
429      // see if log in list
430      noPrinting=true;
431      for (int i=1;i<info.numberArguments;i++) {
432        if (!strcmp(info.arguments[i],"log")) {
433          if (i<info.numberArguments-1&&atoi(info.arguments[i+1])>0)
434            noPrinting=false;
435          break;
436        }
437      }
438      if (noPrinting) {
439        model.messageHandler()->setLogLevel(0);
440        setCbcOrClpPrinting(false);
441      }
442      if (!noPrinting)
443        printf("%d rows, %d columns and %d elements\n",
444               info.numberRows,info.numberColumns,info.numberElements);
445      solver->loadProblem(info.numberColumns,info.numberRows,info.starts,
446                          info.rows,info.elements,
447                          info.columnLower,info.columnUpper,info.objective,
448                          info.rowLower,info.rowUpper);
449      // If we had a solution use it
450      if (info.primalSolution) {
451        solver->setColSolution(info.primalSolution);
452      }
453      // status
454      if (info.rowStatus) {
455        unsigned char * statusArray = lpSolver->statusArray();
456        int i;
457        for (i=0;i<info.numberColumns;i++)
458          statusArray[i]=(char)info.columnStatus[i];
459        statusArray+=info.numberColumns;
460        for (i=0;i<info.numberRows;i++)
461          statusArray[i]=(char)info.rowStatus[i];
462        CoinWarmStartBasis * basis = lpSolver->getBasis();
463        solver->setWarmStart(basis);
464        delete basis;
465      }
466      freeArrays1(&info);
467      // modify objective if necessary
468      solver->setObjSense(info.direction);
469      solver->setDblParam(OsiObjOffset,info.offset);
470      // Set integer variables
471      for (int i=info.numberColumns-info.numberBinary-info.numberIntegers;
472           i<info.numberColumns;i++)
473        solver->setInteger(i);
474      goodModel=true;
475      // change argc etc
476      argc = info.numberArguments;
477      argv = const_cast<const char **>(info.arguments);
478    }
479#endif   
480    // default action on import
481    int allowImportErrors=0;
482    int keepImportNames=1;
483    int doIdiot=-1;
484    int outputFormat=2;
485    int slpValue=-1;
486    int printOptions=0;
487    int printMode=0;
488    int presolveOptions=0;
489    int doCrash=0;
490    int doSprint=-1;
491    int doScaling=1;
492    // set reasonable defaults
493    int preSolve=5;
494    int preProcess=4;
495    bool preSolveFile=false;
496   
497    double djFix=1.0e100;
498    double gapRatio=1.0e100;
499    double tightenFactor=0.0;
500    lpSolver->setPerturbation(50);
501    lpSolver->messageHandler()->setPrefix(false);
502    const char dirsep =  CoinFindDirSeparator();
503    std::string directory = (dirsep == '/' ? "./" : ".\\");
504    std::string defaultDirectory = directory;
505    std::string importFile ="";
506    std::string exportFile ="default.mps";
507    std::string importBasisFile ="";
508    std::string debugFile="";
509    double * debugValues = NULL;
510    int numberDebugValues = -1;
511    int basisHasValues=0;
512    std::string exportBasisFile ="default.bas";
513    std::string saveFile ="default.prob";
514    std::string restoreFile ="default.prob";
515    std::string solutionFile ="stdout";
516    std::string solutionSaveFile ="solution.file";
517#define CBCMAXPARAMETERS 200
518    CbcOrClpParam parameters[CBCMAXPARAMETERS];
519    int numberParameters ;
520    establishParams(numberParameters,parameters) ;
521    parameters[whichParam(BASISIN,numberParameters,parameters)].setStringValue(importBasisFile);
522    parameters[whichParam(BASISOUT,numberParameters,parameters)].setStringValue(exportBasisFile);
523    parameters[whichParam(DEBUG,numberParameters,parameters)].setStringValue(debugFile);
524    parameters[whichParam(DIRECTORY,numberParameters,parameters)].setStringValue(directory);
525    parameters[whichParam(DUALBOUND,numberParameters,parameters)].setDoubleValue(lpSolver->dualBound());
526    parameters[whichParam(DUALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->dualTolerance());
527    parameters[whichParam(EXPORT,numberParameters,parameters)].setStringValue(exportFile);
528    parameters[whichParam(IDIOT,numberParameters,parameters)].setIntValue(doIdiot);
529    parameters[whichParam(IMPORT,numberParameters,parameters)].setStringValue(importFile);
530    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].setDoubleValue(1.0e-8);
531    int slog = whichParam(SOLVERLOGLEVEL,numberParameters,parameters);
532    int log = whichParam(LOGLEVEL,numberParameters,parameters);
533    parameters[slog].setIntValue(0);
534    parameters[log].setIntValue(1);
535    parameters[whichParam(MAXFACTOR,numberParameters,parameters)].setIntValue(lpSolver->factorizationFrequency());
536    parameters[whichParam(MAXITERATION,numberParameters,parameters)].setIntValue(lpSolver->maximumIterations());
537    parameters[whichParam(OUTPUTFORMAT,numberParameters,parameters)].setIntValue(outputFormat);
538    parameters[whichParam(PRESOLVEPASS,numberParameters,parameters)].setIntValue(preSolve);
539    parameters[whichParam(PERTVALUE,numberParameters,parameters)].setIntValue(lpSolver->perturbation());
540    parameters[whichParam(PRIMALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->primalTolerance());
541    parameters[whichParam(PRIMALWEIGHT,numberParameters,parameters)].setDoubleValue(lpSolver->infeasibilityCost());
542    parameters[whichParam(RESTORE,numberParameters,parameters)].setStringValue(restoreFile);
543    parameters[whichParam(SAVE,numberParameters,parameters)].setStringValue(saveFile);
544    //parameters[whichParam(TIMELIMIT,numberParameters,parameters)].setDoubleValue(1.0e8);
545    parameters[whichParam(TIMELIMIT_BAB,numberParameters,parameters)].setDoubleValue(1.0e8);
546    parameters[whichParam(SOLUTION,numberParameters,parameters)].setStringValue(solutionFile);
547    parameters[whichParam(SAVESOL,numberParameters,parameters)].setStringValue(solutionSaveFile);
548    parameters[whichParam(SPRINT,numberParameters,parameters)].setIntValue(doSprint);
549    model.setNumberBeforeTrust(5);
550    parameters[whichParam(NUMBERBEFORE,numberParameters,parameters)].setIntValue(5);
551    parameters[whichParam(MAXNODES,numberParameters,parameters)].setIntValue(model.getMaximumNodes());
552    model.setNumberStrong(5);
553    parameters[whichParam(STRONGBRANCHING,numberParameters,parameters)].setIntValue(model.numberStrong());
554    parameters[whichParam(INFEASIBILITYWEIGHT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcInfeasibilityWeight));
555    parameters[whichParam(INTEGERTOLERANCE,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcIntegerTolerance));
556    parameters[whichParam(INCREMENT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcCutoffIncrement));
557    // Set up likely cut generators and defaults
558    parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("sos");
559    parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(128|64|1);
560    parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].setIntValue(-1);
561    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].setIntValue(100);
562
563    CglGomory gomoryGen;
564    // try larger limit
565    gomoryGen.setLimitAtRoot(512);
566    gomoryGen.setLimit(50);
567    // set default action (0=off,1=on,2=root)
568    int gomoryAction=3;
569    parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
570
571    CglProbing probingGen;
572    probingGen.setUsingObjective(true);
573    probingGen.setMaxPass(3);
574    probingGen.setMaxPassRoot(3);
575    // Number of unsatisfied variables to look at
576    probingGen.setMaxProbe(10);
577    probingGen.setMaxProbeRoot(50);
578    // How far to follow the consequences
579    probingGen.setMaxLook(10);
580    probingGen.setMaxLookRoot(50);
581    probingGen.setMaxLookRoot(10);
582    // Only look at rows with fewer than this number of elements
583    probingGen.setMaxElements(200);
584    probingGen.setRowCuts(3);
585    // set default action (0=off,1=on,2=root)
586    int probingAction=3;
587    parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
588
589    CglKnapsackCover knapsackGen;
590    //knapsackGen.switchOnExpensive();
591    // set default action (0=off,1=on,2=root)
592    int knapsackAction=3;
593    parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
594
595    CglRedSplit redsplitGen;
596    //redsplitGen.setLimit(100);
597    // set default action (0=off,1=on,2=root)
598    // Off as seems to give some bad cuts
599    int redsplitAction=2;
600    parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption("root");
601
602    CglClique cliqueGen(false,true);
603    cliqueGen.setStarCliqueReport(false);
604    cliqueGen.setRowCliqueReport(false);
605    cliqueGen.setMinViolation(0.1);
606    // set default action (0=off,1=on,2=root)
607    int cliqueAction=3;
608    parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption("ifmove");
609
610    CglMixedIntegerRounding2 mixedGen;
611    // set default action (0=off,1=on,2=root)
612    int mixedAction=3;
613    parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
614
615    CglFlowCover flowGen;
616    // set default action (0=off,1=on,2=root)
617    int flowAction=3;
618    parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
619
620    CglTwomir twomirGen;
621    twomirGen.setMaxElements(250);
622    // set default action (0=off,1=on,2=root)
623    int twomirAction=2;
624    parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption("root");
625
626    bool useRounding=true;
627    parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption("on");
628    bool useFpump=true;
629    parameters[whichParam(FPUMP,numberParameters,parameters)].setCurrentOption("on");
630    bool useGreedy=true;
631    parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption("on");
632    bool useCombine=true;
633    parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption("on");
634    bool useLocalTree=false;
635    parameters[whichParam(COSTSTRATEGY,numberParameters,parameters)].setCurrentOption("off");
636    bool useCosts=false;
637   
638    // total number of commands read
639    int numberGoodCommands=0;
640    // Set false if user does anything advanced
641    bool defaultSettings=true;
642
643    // Hidden stuff for barrier
644    int choleskyType = 0;
645    int gamma=0;
646    int scaleBarrier=0;
647    int doKKT=0;
648    int crossover=2; // do crossover unless quadratic
649    // For names
650    int lengthName = 0;
651    std::vector<std::string> rowNames;
652    std::vector<std::string> columnNames;
653   
654    std::string field;
655    if (!noPrinting) {
656      std::cout<<"Coin Cbc and Clp Solver version "<<CBCVERSION
657               <<", build "<<__DATE__<<std::endl;
658      // Print command line
659      if (argc>1) {
660        printf("command line - ");
661        for (int i=0;i<argc;i++)
662          printf("%s ",argv[i]);
663        printf("\n");
664      }
665    }
666    while (1) {
667      // next command
668      field=CoinReadGetCommand(argc,argv);
669      // exit if null or similar
670      if (!field.length()) {
671        if (numberGoodCommands==1&&goodModel) {
672          // we just had file name - do branch and bound
673          field="branch";
674        } else if (!numberGoodCommands) {
675          // let's give the sucker a hint
676          std::cout
677            <<"CoinSolver takes input from arguments ( - switches to stdin)"
678            <<std::endl
679            <<"Enter ? for list of commands or help"<<std::endl;
680          field="-";
681        } else {
682          break;
683        }
684      }
685     
686      // see if ? at end
687      int numberQuery=0;
688      if (field!="?"&&field!="???") {
689        int length = field.length();
690        int i;
691        for (i=length-1;i>0;i--) {
692          if (field[i]=='?') 
693            numberQuery++;
694          else
695            break;
696        }
697        field=field.substr(0,length-numberQuery);
698      }
699      // find out if valid command
700      int iParam;
701      int numberMatches=0;
702      int firstMatch=-1;
703      for ( iParam=0; iParam<numberParameters; iParam++ ) {
704        int match = parameters[iParam].matches(field);
705        if (match==1) {
706          numberMatches = 1;
707          firstMatch=iParam;
708          break;
709        } else {
710          if (match&&firstMatch<0)
711            firstMatch=iParam;
712          numberMatches += match>>1;
713        }
714      }
715      if (iParam<numberParameters&&!numberQuery) {
716        // found
717        CbcOrClpParam found = parameters[iParam];
718        CbcOrClpParameterType type = found.type();
719        int valid;
720        numberGoodCommands++;
721        if (type==BAB&&goodModel) {
722          // check if any integers
723          if (!lpSolver->integerInformation())
724            type=DUALSIMPLEX;
725        }
726        if (type==GENERALQUERY) {
727          std::cout<<"In argument list keywords have leading - "
728            ", -stdin or just - switches to stdin"<<std::endl;
729          std::cout<<"One command per line (and no -)"<<std::endl;
730          std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
731          std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
732          std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
733          std::cout<<"abcd value sets value"<<std::endl;
734          std::cout<<"Commands are:"<<std::endl;
735          int maxAcross=5;
736          int limits[]={1,51,101,151,201,251,301,351,401};
737          std::vector<std::string> types;
738          types.push_back("Double parameters:");
739          types.push_back("Branch and Cut double parameters:");
740          types.push_back("Integer parameters:");
741          types.push_back("Branch and Cut integer parameters:");
742          types.push_back("Keyword parameters and others:");
743          types.push_back("Branch and Cut keyword parameters and others:");
744          types.push_back("Actions:");
745          types.push_back("Branch and Cut actions:");
746          int iType;
747          for (iType=0;iType<8;iType++) {
748            int across=0;
749            std::cout<<types[iType]<<"   ";
750            for ( iParam=0; iParam<numberParameters; iParam++ ) {
751              int type = parameters[iParam].type();
752              if (parameters[iParam].displayThis()&&type>=limits[iType]
753                  &&type<limits[iType+1]) {
754                if (!across)
755                  std::cout<<"  ";
756                std::cout<<parameters[iParam].matchName()<<"  ";
757                across++;
758                if (across==maxAcross) {
759                  std::cout<<std::endl;
760                  across=0;
761                }
762              }
763            }
764            if (across)
765              std::cout<<std::endl;
766          }
767        } else if (type==FULLGENERALQUERY) {
768          std::cout<<"Full list of commands is:"<<std::endl;
769          int maxAcross=5;
770          int limits[]={1,51,101,151,201,251,301,351,401};
771          std::vector<std::string> types;
772          types.push_back("Double parameters:");
773          types.push_back("Branch and Cut double parameters:");
774          types.push_back("Integer parameters:");
775          types.push_back("Branch and Cut integer parameters:");
776          types.push_back("Keyword parameters and others:");
777          types.push_back("Branch and Cut keyword parameters and others:");
778          types.push_back("Actions:");
779          types.push_back("Branch and Cut actions:");
780          int iType;
781          for (iType=0;iType<8;iType++) {
782            int across=0;
783            std::cout<<types[iType]<<"  ";
784            for ( iParam=0; iParam<numberParameters; iParam++ ) {
785              int type = parameters[iParam].type();
786              if (type>=limits[iType]
787                  &&type<limits[iType+1]) {
788                if (!across)
789                  std::cout<<"  ";
790                std::cout<<parameters[iParam].matchName()<<"  ";
791                across++;
792                if (across==maxAcross) {
793                  std::cout<<std::endl;
794                  across=0;
795                }
796              }
797            }
798            if (across)
799              std::cout<<std::endl;
800          }
801        } else if (type<101) {
802          // get next field as double
803          double value = CoinReadGetDoubleField(argc,argv,&valid);
804          if (!valid) {
805            if (type<51) {
806              parameters[iParam].setDoubleParameter(lpSolver,value);
807            } else if (type<81) {
808              parameters[iParam].setDoubleParameter(model,value);
809            } else {
810              parameters[iParam].setDoubleParameter(lpSolver,value);
811              switch(type) {
812              case DJFIX:
813                djFix=value;
814                preSolve=5;
815                defaultSettings=false; // user knows what she is doing
816                break;
817              case GAPRATIO:
818                gapRatio=value;
819                break;
820              case TIGHTENFACTOR:
821                tightenFactor=value;
822                defaultSettings=false; // user knows what she is doing
823                break;
824              default:
825                abort();
826              }
827            }
828          } else if (valid==1) {
829            abort();
830          } else {
831            std::cout<<parameters[iParam].name()<<" has value "<<
832              parameters[iParam].doubleValue()<<std::endl;
833          }
834        } else if (type<201) {
835          // get next field as int
836          int value = CoinReadGetIntField(argc,argv,&valid);
837          if (!valid) {
838            if (type<151) {
839              if (parameters[iParam].type()==PRESOLVEPASS)
840                preSolve = value;
841              else if (parameters[iParam].type()==IDIOT)
842                doIdiot = value;
843              else if (parameters[iParam].type()==SPRINT)
844                doSprint = value;
845              else if (parameters[iParam].type()==OUTPUTFORMAT)
846                outputFormat = value;
847              else if (parameters[iParam].type()==SLPVALUE)
848                slpValue = value;
849              else if (parameters[iParam].type()==PRESOLVEOPTIONS)
850                presolveOptions = value;
851              else if (parameters[iParam].type()==PRINTOPTIONS)
852                printOptions = value;
853              else if (parameters[iParam].type()==CUTPASS)
854                cutPass = value;
855              else if (parameters[iParam].type()==FPUMPITS)
856                { useFpump = true;parameters[iParam].setIntValue(value);}
857              parameters[iParam].setIntParameter(lpSolver,value);
858            } else {
859              parameters[iParam].setIntParameter(model,value);
860            }
861          } else if (valid==1) {
862            abort();
863          } else {
864            std::cout<<parameters[iParam].name()<<" has value "<<
865              parameters[iParam].intValue()<<std::endl;
866          }
867        } else if (type<301) {
868          // one of several strings
869          std::string value = CoinReadGetString(argc,argv);
870          int action = parameters[iParam].parameterOption(value);
871          if (action<0) {
872            if (value!="EOL") {
873              // no match
874              parameters[iParam].printOptions();
875            } else {
876              // print current value
877              std::cout<<parameters[iParam].name()<<" has value "<<
878                parameters[iParam].currentOption()<<std::endl;
879            }
880          } else {
881            parameters[iParam].setCurrentOption(action,!noPrinting);
882            // for now hard wired
883            switch (type) {
884            case DIRECTION:
885              if (action==0)
886                lpSolver->setOptimizationDirection(1);
887              else if (action==1)
888                lpSolver->setOptimizationDirection(-1);
889              else
890                lpSolver->setOptimizationDirection(0);
891              break;
892            case DUALPIVOT:
893              if (action==0) {
894                ClpDualRowSteepest steep(3);
895                lpSolver->setDualRowPivotAlgorithm(steep);
896              } else if (action==1) {
897                //ClpDualRowDantzig dantzig;
898                ClpDualRowSteepest dantzig(5);
899                lpSolver->setDualRowPivotAlgorithm(dantzig);
900              } else if (action==2) {
901                // partial steep
902                ClpDualRowSteepest steep(2);
903                lpSolver->setDualRowPivotAlgorithm(steep);
904              } else {
905                ClpDualRowSteepest steep;
906                lpSolver->setDualRowPivotAlgorithm(steep);
907              }
908              break;
909            case PRIMALPIVOT:
910              if (action==0) {
911                ClpPrimalColumnSteepest steep(3);
912                lpSolver->setPrimalColumnPivotAlgorithm(steep);
913              } else if (action==1) {
914                ClpPrimalColumnSteepest steep(0);
915                lpSolver->setPrimalColumnPivotAlgorithm(steep);
916              } else if (action==2) {
917                ClpPrimalColumnDantzig dantzig;
918                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
919              } else if (action==3) {
920                ClpPrimalColumnSteepest steep(2);
921                lpSolver->setPrimalColumnPivotAlgorithm(steep);
922              } else if (action==4) {
923                ClpPrimalColumnSteepest steep(1);
924                lpSolver->setPrimalColumnPivotAlgorithm(steep);
925              } else if (action==5) {
926                ClpPrimalColumnSteepest steep(4);
927                lpSolver->setPrimalColumnPivotAlgorithm(steep);
928              } else if (action==6) {
929                ClpPrimalColumnSteepest steep(10);
930                lpSolver->setPrimalColumnPivotAlgorithm(steep);
931              }
932              break;
933            case SCALING:
934              lpSolver->scaling(action);
935              solver->setHintParam(OsiDoScale,action!=0,OsiHintTry);
936              doScaling = 1-action;
937              break;
938            case AUTOSCALE:
939              lpSolver->setAutomaticScaling(action!=0);
940              break;
941            case SPARSEFACTOR:
942              lpSolver->setSparseFactorization((1-action)!=0);
943              break;
944            case BIASLU:
945              lpSolver->factorization()->setBiasLU(action);
946              break;
947            case PERTURBATION:
948              if (action==0)
949                lpSolver->setPerturbation(50);
950              else
951                lpSolver->setPerturbation(100);
952              break;
953            case ERRORSALLOWED:
954              allowImportErrors = action;
955              break;
956            case INTPRINT:
957              printMode=action;
958              break;
959              //case ALGORITHM:
960              //algorithm  = action;
961              //defaultSettings=false; // user knows what she is doing
962              //abort();
963              //break;
964            case KEEPNAMES:
965              keepImportNames = 1-action;
966              break;
967            case PRESOLVE:
968              if (action==0)
969                preSolve = 5;
970              else if (action==1)
971                preSolve=0;
972              else if (action==2)
973                preSolve=10;
974              else
975                preSolveFile=true;
976              break;
977            case PFI:
978              lpSolver->factorization()->setForrestTomlin(action==0);
979              break;
980            case CRASH:
981              doCrash=action;
982              break;
983            case MESSAGES:
984              lpSolver->messageHandler()->setPrefix(action!=0);
985              break;
986            case CHOLESKY:
987              choleskyType = action;
988              break;
989            case GAMMA:
990              gamma=action;
991              break;
992            case BARRIERSCALE:
993              scaleBarrier=action;
994              break;
995            case KKT:
996              doKKT=action;
997              break;
998            case CROSSOVER:
999              crossover=action;
1000              break;
1001            case GOMORYCUTS:
1002              defaultSettings=false; // user knows what she is doing
1003              gomoryAction = action;
1004              break;
1005            case PROBINGCUTS:
1006              defaultSettings=false; // user knows what she is doing
1007              probingAction = action;
1008              break;
1009            case KNAPSACKCUTS:
1010              defaultSettings=false; // user knows what she is doing
1011              knapsackAction = action;
1012              break;
1013            case REDSPLITCUTS:
1014              defaultSettings=false; // user knows what she is doing
1015              redsplitAction = action;
1016              break;
1017            case CLIQUECUTS:
1018              defaultSettings=false; // user knows what she is doing
1019              cliqueAction = action;
1020              break;
1021            case FLOWCUTS:
1022              defaultSettings=false; // user knows what she is doing
1023              flowAction = action;
1024              break;
1025            case MIXEDCUTS:
1026              defaultSettings=false; // user knows what she is doing
1027              mixedAction = action;
1028              break;
1029            case TWOMIRCUTS:
1030              defaultSettings=false; // user knows what she is doing
1031              twomirAction = action;
1032              break;
1033            case ROUNDING:
1034              defaultSettings=false; // user knows what she is doing
1035              useRounding = action;
1036              break;
1037            case FPUMP:
1038              defaultSettings=false; // user knows what she is doing
1039              useFpump=action;
1040              break;
1041            case CUTSSTRATEGY:
1042              gomoryAction = action;
1043              probingAction = action;
1044              knapsackAction = action;
1045              cliqueAction = action;
1046              flowAction = action;
1047              mixedAction = action;
1048              twomirAction = action;
1049              parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption(action);
1050              parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption(action);
1051              parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption(action);
1052              if (!action) {
1053                redsplitAction = action;
1054                parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption(action);
1055              }
1056              parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption(action);
1057              parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption(action);
1058              parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption(action);
1059              parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption(action);
1060              break;
1061            case HEURISTICSTRATEGY:
1062              useRounding = action;
1063              useGreedy = action;
1064              useCombine = action;
1065              //useLocalTree = action;
1066              useFpump=action;
1067              parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption(action);
1068              parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption(action);
1069              parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption(action);
1070              //parameters[whichParam(LOCALTREE,numberParameters,parameters)].setCurrentOption(action);
1071              parameters[whichParam(FPUMP,numberParameters,parameters)].setCurrentOption(action);
1072              break;
1073            case GREEDY:
1074              defaultSettings=false; // user knows what she is doing
1075              useGreedy = action;
1076              break;
1077            case COMBINE:
1078              defaultSettings=false; // user knows what she is doing
1079              useCombine = action;
1080              break;
1081            case LOCALTREE:
1082              defaultSettings=false; // user knows what she is doing
1083              useLocalTree = action;
1084              break;
1085            case COSTSTRATEGY:
1086              if (action!=1&&action!=0) {
1087                printf("Pseudo costs not implemented yet\n");
1088              } else {
1089                useCosts=action;
1090              }
1091              break;
1092            case PREPROCESS:
1093              preProcess = action;
1094              break;
1095            default:
1096              abort();
1097            }
1098          }
1099        } else {
1100          // action
1101          if (type==EXIT) {
1102#ifdef CBC_AMPL
1103            if(usingAmpl) {
1104              if (info.numberIntegers||info.numberBinary) {
1105                // integer
1106              } else {
1107                // linear
1108              }
1109              writeAmpl(&info);
1110              freeArrays2(&info);
1111              freeArgs(&info);
1112            }
1113#endif
1114            break; // stop all
1115          }
1116          switch (type) {
1117          case DUALSIMPLEX:
1118          case PRIMALSIMPLEX:
1119          case SOLVECONTINUOUS:
1120          case BARRIER:
1121            if (goodModel) {
1122              ClpSolve::SolveType method;
1123              ClpSolve::PresolveType presolveType;
1124              ClpSimplex * model2 = lpSolver;
1125              if (noPrinting)
1126                lpSolver->setLogLevel(0);
1127              ClpSolve solveOptions;
1128              if (preSolve!=5&&preSolve)
1129                presolveType=ClpSolve::presolveNumber;
1130              else if (preSolve)
1131                presolveType=ClpSolve::presolveOn;
1132              else
1133                presolveType=ClpSolve::presolveOff;
1134              solveOptions.setPresolveType(presolveType,preSolve);
1135              if (type==DUALSIMPLEX||SOLVECONTINUOUS) {
1136                method=ClpSolve::useDual;
1137              } else if (type==PRIMALSIMPLEX) {
1138                method=ClpSolve::usePrimalorSprint;
1139              } else {
1140                method = ClpSolve::useBarrier;
1141                if (crossover==1) {
1142                  method=ClpSolve::useBarrierNoCross;
1143                } else if (crossover==2) {
1144                  ClpObjective * obj = lpSolver->objectiveAsObject();
1145                  if (obj->type()>1) {
1146                    method=ClpSolve::useBarrierNoCross;
1147                    presolveType=ClpSolve::presolveOff;
1148                    solveOptions.setPresolveType(presolveType,preSolve);
1149                  } 
1150                }
1151              }
1152              solveOptions.setSolveType(method);
1153              if(preSolveFile)
1154                presolveOptions |= 0x40000000;
1155              solveOptions.setSpecialOption(4,presolveOptions);
1156              solveOptions.setSpecialOption(5,printOptions);
1157              if (method==ClpSolve::useDual) {
1158                // dual
1159                if (doCrash)
1160                  solveOptions.setSpecialOption(0,1,doCrash); // crash
1161                else if (doIdiot)
1162                  solveOptions.setSpecialOption(0,2,doIdiot); // possible idiot
1163              } else if (method==ClpSolve::usePrimalorSprint) {
1164                // primal
1165                // if slp turn everything off
1166                if (slpValue>0) {
1167                  doCrash=false;
1168                  doSprint=0;
1169                  doIdiot=-1;
1170                  solveOptions.setSpecialOption(1,10,slpValue); // slp
1171                  method=ClpSolve::usePrimal;
1172                }
1173                if (doCrash) {
1174                  solveOptions.setSpecialOption(1,1,doCrash); // crash
1175                } else if (doSprint>0) {
1176                  // sprint overrides idiot
1177                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
1178                } else if (doIdiot>0) {
1179                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
1180                } else if (slpValue<=0) {
1181                  if (doIdiot==0) {
1182                    if (doSprint==0)
1183                      solveOptions.setSpecialOption(1,4); // all slack
1184                    else
1185                      solveOptions.setSpecialOption(1,9); // all slack or sprint
1186                  } else {
1187                    if (doSprint==0)
1188                      solveOptions.setSpecialOption(1,8); // all slack or idiot
1189                    else
1190                      solveOptions.setSpecialOption(1,7); // initiative
1191                  }
1192                }
1193                if (basisHasValues==-1)
1194                  solveOptions.setSpecialOption(1,11); // switch off values
1195              } else if (method==ClpSolve::useBarrier||method==ClpSolve::useBarrierNoCross) {
1196                int barrierOptions = choleskyType;
1197                if (scaleBarrier)
1198                  barrierOptions |= 8;
1199                if (gamma)
1200                  barrierOptions |= 16;
1201                if (doKKT)
1202                  barrierOptions |= 32;
1203                solveOptions.setSpecialOption(4,barrierOptions);
1204              }
1205              model2->initialSolve(solveOptions);
1206              basisHasValues=1;
1207#ifdef CBC_AMPL
1208              if (usingAmpl) {
1209                double value = model2->getObjValue()*model2->getObjSense();
1210                char buf[300];
1211                int pos=0;
1212                int iStat = model2->status();
1213                if (iStat==0) {
1214                  pos += sprintf(buf+pos,"optimal," );
1215                } else if (iStat==1) {
1216                  // infeasible
1217                  pos += sprintf(buf+pos,"infeasible,");
1218                } else if (iStat==2) {
1219                  // unbounded
1220                  pos += sprintf(buf+pos,"unbounded,");
1221                } else if (iStat==3) {
1222                  pos += sprintf(buf+pos,"stopped on iterations or time,");
1223                } else if (iStat==4) {
1224                  iStat = 7;
1225                  pos += sprintf(buf+pos,"stopped on difficulties,");
1226                } else if (iStat==5) {
1227                  iStat = 3;
1228                  pos += sprintf(buf+pos,"stopped on ctrl-c,");
1229                } else {
1230                  pos += sprintf(buf+pos,"status unknown,");
1231                  iStat=6;
1232                }
1233                info.problemStatus=iStat;
1234                info.objValue = value;
1235                pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
1236                               value);
1237                sprintf(buf+pos,"\n%d iterations",
1238                        model2->getIterationCount());
1239                free(info.primalSolution);
1240                int numberColumns=model2->numberColumns();
1241                info.primalSolution = (double *) malloc(numberColumns*sizeof(double));
1242                CoinCopyN(model2->primalColumnSolution(),numberColumns,info.primalSolution);
1243                int numberRows = model2->numberRows();
1244                free(info.dualSolution);
1245                info.dualSolution = (double *) malloc(numberRows*sizeof(double));
1246                CoinCopyN(model2->dualRowSolution(),numberRows,info.dualSolution);
1247                CoinWarmStartBasis * basis = model2->getBasis();
1248                free(info.rowStatus);
1249                info.rowStatus = (int *) malloc(numberRows*sizeof(int));
1250                free(info.columnStatus);
1251                info.columnStatus = (int *) malloc(numberColumns*sizeof(int));
1252                // Put basis in
1253                int i;
1254                // free,basic,ub,lb are 0,1,2,3
1255                for (i=0;i<numberRows;i++) {
1256                  CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
1257                  info.rowStatus[i]=status;
1258                }
1259                for (i=0;i<numberColumns;i++) {
1260                  CoinWarmStartBasis::Status status = basis->getStructStatus(i);
1261                  info.columnStatus[i]=status;
1262                }
1263                // put buffer into info
1264                strcpy(info.buffer,buf);
1265                delete basis;
1266              }
1267#endif
1268            } else {
1269              std::cout<<"** Current model not valid"<<std::endl;
1270            }
1271            break;
1272          case TIGHTEN:
1273            if (goodModel) {
1274              int numberInfeasibilities = lpSolver->tightenPrimalBounds();
1275              if (numberInfeasibilities)
1276                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
1277            } else {
1278              std::cout<<"** Current model not valid"<<std::endl;
1279            }
1280            break;
1281          case PLUSMINUS:
1282            if (goodModel) {
1283              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1284              ClpPackedMatrix* clpMatrix =
1285                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1286              if (clpMatrix) {
1287                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
1288                if (newMatrix->getIndices()) {
1289                  lpSolver->replaceMatrix(newMatrix);
1290                  delete saveMatrix;
1291                  std::cout<<"Matrix converted to +- one matrix"<<std::endl;
1292                } else {
1293                  std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
1294                }
1295              } else {
1296                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1297              }
1298            } else {
1299              std::cout<<"** Current model not valid"<<std::endl;
1300            }
1301            break;
1302          case NETWORK:
1303            if (goodModel) {
1304              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1305              ClpPackedMatrix* clpMatrix =
1306                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1307              if (clpMatrix) {
1308                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
1309                if (newMatrix->getIndices()) {
1310                  lpSolver->replaceMatrix(newMatrix);
1311                  delete saveMatrix;
1312                  std::cout<<"Matrix converted to network matrix"<<std::endl;
1313                } else {
1314                  std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
1315                }
1316              } else {
1317                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1318              }
1319            } else {
1320              std::cout<<"** Current model not valid"<<std::endl;
1321            }
1322            break;
1323/*
1324  Run branch-and-cut. First set a few options -- node comparison, scaling. If
1325  the solver is Clp, consider running some presolve code (not yet converted
1326  this to generic OSI) with branch-and-cut. If presolve is disabled, or the
1327  solver is not Clp, simply run branch-and-cut. Print elapsed time at the end.
1328*/
1329          case BAB: // branchAndBound
1330          case STRENGTHEN:
1331            if (goodModel) {
1332              int logLevel = parameters[slog].intValue();
1333              // Reduce printout
1334              if (logLevel<=1)
1335                model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
1336              // Don't switch off all output
1337              {
1338                OsiSolverInterface * solver = model.solver();
1339                OsiClpSolverInterface * si =
1340                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1341                assert (si != NULL);
1342                si->setSpecialOptions(0x40000000);
1343              }
1344              model.initialSolve();
1345              // If user made settings then use them
1346              if (!defaultSettings) {
1347                OsiSolverInterface * solver = model.solver();
1348                if (!doScaling)
1349                  solver->setHintParam(OsiDoScale,false,OsiHintTry);
1350                OsiClpSolverInterface * si =
1351                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1352                assert (si != NULL);
1353                // get clp itself
1354                ClpSimplex * modelC = si->getModelPtr();
1355                //if (modelC->tightenPrimalBounds()!=0) {
1356                //std::cout<<"Problem is infeasible!"<<std::endl;
1357                //break;
1358                //}
1359                // bounds based on continuous
1360                if (tightenFactor) {
1361                  if (modelC->tightenPrimalBounds(tightenFactor)!=0) {
1362                    std::cout<<"Problem is infeasible!"<<std::endl;
1363                    break;
1364                  }
1365                }
1366                if (djFix<1.0e20) {
1367                  // do some fixing
1368                  int numberColumns = modelC->numberColumns();
1369                  int i;
1370                  const char * type = modelC->integerInformation();
1371                  double * lower = modelC->columnLower();
1372                  double * upper = modelC->columnUpper();
1373                  double * solution = modelC->primalColumnSolution();
1374                  double * dj = modelC->dualColumnSolution();
1375                  int numberFixed=0;
1376                  for (i=0;i<numberColumns;i++) {
1377                    if (type[i]) {
1378                      double value = solution[i];
1379                      if (value<lower[i]+1.0e-5&&dj[i]>djFix) {
1380                        solution[i]=lower[i];
1381                        upper[i]=lower[i];
1382                        numberFixed++;
1383                      } else if (value>upper[i]-1.0e-5&&dj[i]<-djFix) {
1384                        solution[i]=upper[i];
1385                        lower[i]=upper[i];
1386                        numberFixed++;
1387                      }
1388                    }
1389                  }
1390                  printf("%d columns fixed\n",numberFixed);
1391                }
1392              }
1393              // See if we want preprocessing
1394              OsiSolverInterface * saveSolver=NULL;
1395              CglPreProcess process;
1396              delete babModel;
1397              babModel = new CbcModel(model);
1398              OsiSolverInterface * solver3 = clpSolver->clone();
1399              babModel->assignSolver(solver3);
1400              OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1401              int numberChanged=0;
1402              if (clpSolver2->messageHandler()->logLevel())
1403                clpSolver2->messageHandler()->setLogLevel(1);
1404              if (logLevel>-1)
1405                clpSolver2->messageHandler()->setLogLevel(logLevel);
1406              lpSolver = clpSolver2->getModelPtr();
1407              if (lpSolver->factorizationFrequency()==200) {
1408                // User did not touch preset
1409                int numberRows = lpSolver->numberRows();
1410                const int cutoff1=10000;
1411                const int cutoff2=100000;
1412                const int base=75;
1413                const int freq0 = 50;
1414                const int freq1=200;
1415                const int freq2=400;
1416                const int maximum=1000;
1417                int frequency;
1418                if (numberRows<cutoff1)
1419                  frequency=base+numberRows/freq0;
1420                else if (numberRows<cutoff2)
1421                  frequency=base+cutoff1/freq0 + (numberRows-cutoff1)/freq1;
1422                else
1423                  frequency=base+cutoff1/freq0 + (cutoff2-cutoff1)/freq1 + (numberRows-cutoff2)/freq2;
1424                lpSolver->setFactorizationFrequency(CoinMin(maximum,frequency));
1425              }
1426              time2 = CoinCpuTime();
1427              totalTime += time2-time1;
1428              time1 = time2;
1429              double timeLeft = babModel->getMaximumSeconds();
1430              if (preProcess&&type==BAB) {
1431                saveSolver=babModel->solver()->clone();
1432                /* Do not try and produce equality cliques and
1433                   do up to 10 passes */
1434                OsiSolverInterface * solver2;
1435                {
1436                  // Tell solver we are in Branch and Cut
1437                  saveSolver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
1438                  // Default set of cut generators
1439                  CglProbing generator1;
1440                  generator1.setUsingObjective(true);
1441                  generator1.setMaxPass(3);
1442                  generator1.setMaxProbeRoot(saveSolver->getNumCols());
1443                  generator1.setMaxElements(100);
1444                  generator1.setMaxLookRoot(50);
1445                  generator1.setRowCuts(3);
1446                  // Add in generators
1447                  process.addCutGenerator(&generator1);
1448                  int translate[]={9999,0,0,-1,2};
1449                  process.messageHandler()->setLogLevel(babModel->logLevel());
1450                  solver2 = process.preProcessNonDefault(*saveSolver,translate[preProcess],10);
1451                  // Tell solver we are not in Branch and Cut
1452                  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
1453                  if (solver2)
1454                    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
1455                }
1456#ifdef CBC_AMPL
1457                if (!solver2&&usingAmpl) {
1458                  // infeasible
1459                  info.problemStatus=1;
1460                  info.objValue = 1.0e100;
1461                  sprintf(info.buffer,"infeasible by pre-processing");
1462                  info.primalSolution=NULL;
1463                  info.dualSolution=NULL;
1464                }
1465#endif
1466                if (!noPrinting) {
1467                  if (!solver2) {
1468                    printf("Pre-processing says infeasible\n");
1469                    break;
1470                  } else {
1471                    printf("processed model has %d rows, %d columns and %d elements\n",
1472                           solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
1473                  }
1474                }
1475                //solver2->resolve();
1476                if (preProcess==2) {
1477                  OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
1478                  ClpSimplex * lpSolver = clpSolver2->getModelPtr();
1479                  lpSolver->writeMps("presolved.mps",0,1,lpSolver->optimizationDirection());
1480                  printf("Preprocessed model (minimization) on presolved.mps\n");
1481                }
1482                // we have to keep solver2 so pass clone
1483                solver2 = solver2->clone();
1484                babModel->assignSolver(solver2);
1485                babModel->initialSolve();
1486                babModel->setMaximumSeconds(timeLeft-(CoinCpuTime()-time1));
1487              }
1488              // now tighten bounds
1489              {
1490                OsiClpSolverInterface * si =
1491                  dynamic_cast<OsiClpSolverInterface *>(babModel->solver()) ;
1492                assert (si != NULL);
1493                // get clp itself
1494                ClpSimplex * modelC = si->getModelPtr();
1495                if (noPrinting)
1496                  modelC->setLogLevel(0);
1497                if (modelC->tightenPrimalBounds()!=0) {
1498                  std::cout<<"Problem is infeasible!"<<std::endl;
1499                  break;
1500                }
1501                modelC->dual();
1502              }
1503              if (debugValues) {
1504                // for debug
1505                std::string problemName ;
1506                babModel->solver()->getStrParam(OsiProbName,problemName) ;
1507                //babModel->solver()->activateRowCutDebugger(problemName.c_str()) ;
1508                twomirGen.probname_=strdup(problemName.c_str());
1509                // checking seems odd
1510                //redsplitGen.set_given_optsol(babModel->solver()->getRowCutDebuggerAlways()->optimalSolution(),
1511                //                         babModel->getNumCols());
1512              }
1513              if (useCosts) {
1514                int numberColumns = babModel->getNumCols();
1515                int * sort = new int[numberColumns];
1516                double * dsort = new double[numberColumns];
1517                int * priority = new int [numberColumns];
1518                const double * objective = babModel->getObjCoefficients();
1519                int iColumn;
1520                int n=0;
1521                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1522                  if (babModel->isInteger(iColumn)) {
1523                    sort[n]=n;
1524                    dsort[n++]=-objective[iColumn];
1525                  }
1526                }
1527                CoinSort_2(dsort,dsort+n,sort);
1528                int level=0;
1529                double last = -1.0e100;
1530                for (int i=0;i<n;i++) {
1531                  int iPut=sort[i];
1532                  if (dsort[i]!=last) {
1533                    level++;
1534                    last=dsort[i];
1535                  }
1536                  priority[iPut]=level;
1537                }
1538                babModel->passInPriorities( priority,false);
1539                delete [] priority;
1540                delete [] sort;
1541                delete [] dsort;
1542              }
1543              // FPump done first as it only works if no solution
1544              CbcHeuristicFPump heuristic4(*babModel);
1545              if (useFpump) {
1546                heuristic4.setMaximumPasses(parameters[whichParam(FPUMPITS,numberParameters,parameters)].intValue());
1547                babModel->addHeuristic(&heuristic4);
1548              }
1549              CbcRounding heuristic1(*babModel);
1550              if (useRounding)
1551                babModel->addHeuristic(&heuristic1) ;
1552              CbcHeuristicLocal heuristic2(*babModel);
1553              heuristic2.setSearchType(1);
1554              if (useCombine)
1555                babModel->addHeuristic(&heuristic2);
1556              CbcHeuristicGreedyCover heuristic3(*babModel);
1557              CbcHeuristicGreedyEquality heuristic3a(*babModel);
1558              if (useGreedy) {
1559                babModel->addHeuristic(&heuristic3);
1560                babModel->addHeuristic(&heuristic3a);
1561              }
1562              if (useLocalTree) {
1563                CbcTreeLocal localTree(babModel,NULL,10,0,0,10000,2000);
1564                babModel->passInTreeHandler(localTree);
1565              }
1566              // add cut generators if wanted
1567              int switches[20];
1568              int numberGenerators=0;
1569              if (probingAction==1) {
1570                babModel->addCutGenerator(&probingGen,-1,"Probing");
1571                switches[numberGenerators++]=0;
1572              } else if (probingAction>=2) {
1573                babModel->addCutGenerator(&probingGen,-101+probingAction,"Probing");
1574                switches[numberGenerators++]=0;
1575              }
1576              if (gomoryAction==1) {
1577                babModel->addCutGenerator(&gomoryGen,-1,"Gomory");
1578                switches[numberGenerators++]=1;
1579              } else if (gomoryAction>=2) {
1580                babModel->addCutGenerator(&gomoryGen,-101+gomoryAction,"Gomory");
1581                switches[numberGenerators++]=-1;
1582              }
1583              if (knapsackAction==1) {
1584                babModel->addCutGenerator(&knapsackGen,-1,"Knapsack");
1585                switches[numberGenerators++]=0;
1586              } else if (knapsackAction>=2) {
1587                babModel->addCutGenerator(&knapsackGen,-101+knapsackAction,"Knapsack");
1588                switches[numberGenerators++]=0;
1589              }
1590              if (redsplitAction==1) {
1591                babModel->addCutGenerator(&redsplitGen,-1,"Reduce-and-split");
1592                switches[numberGenerators++]=1;
1593              } else if (redsplitAction>=2) {
1594                babModel->addCutGenerator(&redsplitGen,-101+redsplitAction,"Reduce-and-split");
1595                switches[numberGenerators++]=1;
1596              }
1597              if (cliqueAction==1) {
1598                babModel->addCutGenerator(&cliqueGen,-1,"Clique");
1599                switches[numberGenerators++]=1;
1600              } else if (cliqueAction>=2) {
1601                babModel->addCutGenerator(&cliqueGen,-101+cliqueAction,"Clique");
1602                switches[numberGenerators++]=-1;
1603              }
1604              if (mixedAction==1) {
1605                babModel->addCutGenerator(&mixedGen,-1,"MixedIntegerRounding2");
1606                switches[numberGenerators++]=1;
1607              } else if (mixedAction>=2) {
1608                babModel->addCutGenerator(&mixedGen,-101+mixedAction,"MixedIntegerRounding2");
1609                switches[numberGenerators++]=-1;
1610              }
1611              if (flowAction==1) {
1612                babModel->addCutGenerator(&flowGen,-1,"FlowCover");
1613                switches[numberGenerators++]=1;
1614              } else if (flowAction>=2) {
1615                babModel->addCutGenerator(&flowGen,-101+flowAction,"FlowCover");
1616                switches[numberGenerators++]=1;
1617              }
1618              if (twomirAction==1) {
1619                babModel->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
1620                switches[numberGenerators++]=1;
1621              } else if (twomirAction>=2) {
1622                babModel->addCutGenerator(&twomirGen,-101+twomirAction,"TwoMirCuts");
1623                switches[numberGenerators++]=1;
1624              }
1625              // Say we want timings
1626              numberGenerators = babModel->numberCutGenerators();
1627              int iGenerator;
1628              int cutDepth=
1629                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
1630              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1631                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1632                int howOften = generator->howOften();
1633                if (howOften==-98||howOften==-99) 
1634                  generator->setSwitchOffIfLessThan(switches[iGenerator]);
1635                generator->setTiming(true);
1636                if (cutDepth>=0)
1637                  generator->setWhatDepth(cutDepth) ;
1638              }
1639              // Could tune more
1640              babModel->setMinimumDrop(min(5.0e-2,
1641                                        fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
1642              if (cutPass==-1234567) {
1643                if (babModel->getNumCols()<500)
1644                  babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
1645                else if (babModel->getNumCols()<5000)
1646                  babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
1647                else
1648                  babModel->setMaximumCutPassesAtRoot(20);
1649              } else {
1650                babModel->setMaximumCutPassesAtRoot(cutPass);
1651              }
1652              babModel->setMaximumCutPasses(1);
1653             
1654              // Do more strong branching if small
1655              //if (babModel->getNumCols()<5000)
1656              //babModel->setNumberStrong(20);
1657              // Switch off strong branching if wanted
1658              //if (babModel->getNumCols()>10*babModel->getNumRows())
1659              //babModel->setNumberStrong(0);
1660              if (!noPrinting) {
1661                babModel->messageHandler()->setLogLevel(parameters[log].intValue());
1662                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
1663                    babModel->messageHandler()->logLevel()>1)
1664                  babModel->setPrintFrequency(100);
1665              }
1666             
1667              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,
1668                    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].intValue());
1669              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1670              // go faster stripes
1671              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
1672                osiclp->setupForRepeatedUse(2,parameters[slog].intValue());
1673              } else {
1674                osiclp->setupForRepeatedUse(0,parameters[slog].intValue());
1675              }
1676              double increment=babModel->getCutoffIncrement();;
1677              int * changed = analyze( osiclp,numberChanged,increment,false);
1678              if (debugValues) {
1679                if (numberDebugValues==babModel->getNumCols()) {
1680                  // for debug
1681                  babModel->solver()->activateRowCutDebugger(debugValues) ;
1682                } else {
1683                  printf("debug file has incorrect number of columns\n");
1684                }
1685              }
1686              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
1687              // Turn this off if you get problems
1688              // Used to be automatically set
1689              int mipOptions = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue();
1690              if (mipOptions!=(128|64|1))
1691                printf("mip options %d\n",mipOptions);
1692              osiclp->setSpecialOptions(mipOptions);
1693              if (gapRatio < 1.0e100) {
1694                double value = babModel->solver()->getObjValue() ;
1695                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
1696                babModel->setAllowableGap(value2) ;
1697                std::cout << "Continuous " << value
1698                          << ", so allowable gap set to "
1699                          << value2 << std::endl ;
1700              }
1701              // probably faster to use a basis to get integer solutions
1702              babModel->setSpecialOptions(2);
1703              currentBranchModel = babModel;
1704              OsiSolverInterface * strengthenedModel=NULL;
1705              if (type==BAB) {
1706                int moreMipOptions = parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].intValue();
1707                if (moreMipOptions>=0) {
1708                  printf("more mip options %d\n",moreMipOptions);
1709                  babModel->setSearchStrategy(moreMipOptions);
1710                }
1711                if (preProcess&&process.numberSOS()) {
1712                  int numberSOS = process.numberSOS();
1713                  int numberIntegers = babModel->numberIntegers();
1714                  /* model may not have created objects
1715                     If none then create
1716                  */
1717                  if (!numberIntegers||!babModel->numberObjects()) {
1718                    babModel->findIntegers(true);
1719                    numberIntegers = babModel->numberIntegers();
1720                  }
1721                  CbcObject ** oldObjects = babModel->objects();
1722                  // Do sets and priorities
1723                  CbcObject ** objects = new CbcObject * [numberSOS];
1724                  // set old objects to have low priority
1725                  int numberOldObjects = babModel->numberObjects();
1726                  int numberColumns = babModel->getNumCols();
1727                  for (int iObj = 0;iObj<numberOldObjects;iObj++)
1728                    oldObjects[iObj]->setPriority(numberColumns+1);
1729                  const int * starts = process.startSOS();
1730                  const int * which = process.whichSOS();
1731                  const int * type = process.typeSOS();
1732                  const double * weight = process.weightSOS();
1733                  int iSOS;
1734                  for (iSOS =0;iSOS<numberSOS;iSOS++) {
1735                    int iStart = starts[iSOS];
1736                    int n=starts[iSOS+1]-iStart;
1737                    objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
1738                                               iSOS,type[iSOS]);
1739                    // branch on long sets first
1740                    objects[iSOS]->setPriority(numberColumns-n);
1741                  }
1742                  babModel->addObjects(numberSOS,objects);
1743                  for (iSOS=0;iSOS<numberSOS;iSOS++)
1744                    delete objects[iSOS];
1745                  delete [] objects;
1746                }
1747                int statistics = (printOptions>0) ? printOptions: 0;
1748                babModel->branchAndBound(statistics);
1749              } else {
1750                strengthenedModel = babModel->strengthenedModel();
1751              }
1752              currentBranchModel = NULL;
1753              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1754              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
1755                lpSolver = osiclp->getModelPtr();
1756                //move best solution (should be there -- but ..)
1757                int n = lpSolver->getNumCols();
1758                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
1759                saveSolution(osiclp->getModelPtr(),"debug.file");
1760              }
1761              if (!noPrinting) {
1762                // Print more statistics
1763                std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
1764                         <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
1765               
1766                for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1767                  CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1768                  std::cout<<generator->cutGeneratorName()<<" was tried "
1769                           <<generator->numberTimesEntered()<<" times and created "
1770                           <<generator->numberCutsInTotal()<<" cuts of which "
1771                           <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
1772                  if (generator->timing())
1773                    std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
1774                  else
1775                    std::cout<<std::endl;
1776                }
1777              }
1778              time2 = CoinCpuTime();
1779              totalTime += time2-time1;
1780              // For best solution
1781              double * bestSolution = NULL;
1782              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
1783                // post process
1784                if (preProcess) {
1785                  int n = saveSolver->getNumCols();
1786                  bestSolution = new double [n];
1787                  process.postProcess(*babModel->solver());
1788                  // Solution now back in saveSolver
1789                  babModel->assignSolver(saveSolver);
1790                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
1791                } else {
1792                  int n = babModel->solver()->getNumCols();
1793                  bestSolution = new double [n];
1794                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
1795                }
1796              }
1797              if (type==STRENGTHEN&&strengthenedModel)
1798                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
1799              lpSolver = clpSolver->getModelPtr();
1800              if (debugFile=="create"&&bestSolution) {
1801                saveSolution(lpSolver,"debug.file");
1802              }
1803              if (numberChanged) {
1804                for (int i=0;i<numberChanged;i++) {
1805                  int iColumn=changed[i];
1806                  clpSolver->setContinuous(iColumn);
1807                }
1808                delete [] changed;
1809              }
1810              if (type==BAB) {
1811                //move best solution (should be there -- but ..)
1812                int n = lpSolver->getNumCols();
1813                if (bestSolution)
1814                  memcpy(lpSolver->primalColumnSolution(),bestSolution,n*sizeof(double));
1815                delete [] bestSolution;
1816                std::string statusName[]={"Finished","Stopped on ","Difficulties",
1817                                          "","","User ctrl-c"};
1818                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
1819                int iStat = babModel->status();
1820                int iStat2 = babModel->secondaryStatus();
1821                if (!noPrinting)
1822                  std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
1823                           <<" objective "<<babModel->getObjValue()<<
1824                    " after "<<babModel->getNodeCount()<<" nodes and "
1825                           <<babModel->getIterationCount()<<
1826                    " iterations - took "<<time2-time1<<" seconds"<<std::endl;
1827#ifdef CBC_AMPL
1828                if (usingAmpl) {
1829                  double value = babModel->getObjValue()*lpSolver->getObjSense();
1830                  char buf[300];
1831                  int pos=0;
1832                  if (iStat==0) {
1833                    if (babModel->getObjValue()<1.0e40) {
1834                      pos += sprintf(buf+pos,"optimal," );
1835                    } else {
1836                      // infeasible
1837                      iStat=1;
1838                      pos += sprintf(buf+pos,"infeasible,");
1839                    }
1840                  } else if (iStat==1) {
1841                    if (iStat2!=6)
1842                      iStat=3;
1843                    else
1844                      iStat=4;
1845                    pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
1846                  } else if (iStat==2) {
1847                    iStat = 7;
1848                    pos += sprintf(buf+pos,"stopped on difficulties,");
1849                  } else if (iStat==5) {
1850                    iStat = 3;
1851                    pos += sprintf(buf+pos,"stopped on ctrl-c,");
1852                  } else {
1853                    pos += sprintf(buf+pos,"status unknown,");
1854                    iStat=6;
1855                  }
1856                  info.problemStatus=iStat;
1857                  info.objValue = value;
1858                  if (babModel->getObjValue()<1.0e40) 
1859                    pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
1860                                   value);
1861                  sprintf(buf+pos,"\n%d nodes, %d iterations",
1862                          babModel->getNodeCount(),
1863                          babModel->getIterationCount());
1864                  if (bestSolution) {
1865                    free(info.primalSolution);
1866                    info.primalSolution = (double *) malloc(n*sizeof(double));
1867                    CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
1868                    int numberRows = lpSolver->numberRows();
1869                    free(info.dualSolution);
1870                    info.dualSolution = (double *) malloc(numberRows*sizeof(double));
1871                    CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
1872                  } else {
1873                    info.primalSolution=NULL;
1874                    info.dualSolution=NULL;
1875                  }
1876                  // put buffer into info
1877                  strcpy(info.buffer,buf);
1878                }
1879#endif
1880              } else {
1881                std::cout<<"Model strengthend - now has "<<clpSolver->getNumRows()
1882                         <<" rows"<<std::endl;
1883              }
1884              time1 = time2;
1885              delete babModel;
1886              babModel=NULL;
1887            } else {
1888              std::cout << "** Current model not valid" << std::endl ; 
1889            }
1890            break ;
1891          case IMPORT:
1892            {
1893              delete babModel;
1894              babModel=NULL;
1895              // get next field
1896              field = CoinReadGetString(argc,argv);
1897              if (field=="$") {
1898                field = parameters[iParam].stringValue();
1899              } else if (field=="EOL") {
1900                parameters[iParam].printString();
1901                break;
1902              } else {
1903                parameters[iParam].setStringValue(field);
1904              }
1905              std::string fileName;
1906              bool canOpen=false;
1907              if (field=="-") {
1908                // stdin
1909                canOpen=true;
1910                fileName = "-";
1911              } else {
1912                bool absolutePath;
1913                if (dirsep=='/') {
1914                  // non Windows (or cygwin)
1915                  absolutePath=(field[0]=='/');
1916                } else {
1917                  //Windows (non cycgwin)
1918                  absolutePath=(field[0]=='\\');
1919                  // but allow for :
1920                  if (strchr(field.c_str(),':'))
1921                    absolutePath=true;
1922                }
1923                if (absolutePath) {
1924                  fileName = field;
1925                } else if (field[0]=='~') {
1926                  char * environVar = getenv("HOME");
1927                  if (environVar) {
1928                    std::string home(environVar);
1929                    field=field.erase(0,1);
1930                    fileName = home+field;
1931                  } else {
1932                    fileName=field;
1933                  }
1934                } else {
1935                  fileName = directory+field;
1936                }
1937                FILE *fp=fopen(fileName.c_str(),"r");
1938                if (fp) {
1939                  // can open - lets go for it
1940                  fclose(fp);
1941                  canOpen=true;
1942                } else {
1943                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1944                }
1945              }
1946              if (canOpen) {
1947                int status =lpSolver->readMps(fileName.c_str(),
1948                                                   keepImportNames!=0,
1949                                                   allowImportErrors!=0);
1950                if (!status||(status>0&&allowImportErrors)) {
1951                  if (keepImportNames) {
1952                    lengthName = lpSolver->lengthNames();
1953                    rowNames = *(lpSolver->rowNames());
1954                    columnNames = *(lpSolver->columnNames());
1955                  } else {
1956                    lengthName=0;
1957                  }
1958                  goodModel=true;
1959                  //Set integers in clpsolver
1960                  const char * info = lpSolver->integerInformation();
1961                  if (info) {
1962                    int numberColumns = lpSolver->numberColumns();
1963                    int i;
1964                    for (i=0;i<numberColumns;i++) {
1965                      if (info[i]) 
1966                        clpSolver->setInteger(i);
1967                    }
1968                  }
1969                  // sets to all slack (not necessary?)
1970                  lpSolver->createStatus();
1971                  time2 = CoinCpuTime();
1972                  totalTime += time2-time1;
1973                  time1=time2;
1974                  // Go to canned file if just input file
1975                  if (CbcOrClpRead_mode==2&&argc==2) {
1976                    // only if ends .mps
1977                    char * find = strstr(fileName.c_str(),".mps");
1978                    if (find&&find[4]=='\0') {
1979                      find[1]='p'; find[2]='a';find[3]='r';
1980                      FILE *fp=fopen(fileName.c_str(),"r");
1981                      if (fp) {
1982                        CbcOrClpReadCommand=fp; // Read from that file
1983                        CbcOrClpRead_mode=-1;
1984                      }
1985                    }
1986                  }
1987                } else {
1988                  // errors
1989                  std::cout<<"There were "<<status<<
1990                    " errors on input"<<std::endl;
1991                }
1992              }
1993            }
1994            break;
1995          case EXPORT:
1996            if (goodModel) {
1997              // get next field
1998              field = CoinReadGetString(argc,argv);
1999              if (field=="$") {
2000                field = parameters[iParam].stringValue();
2001              } else if (field=="EOL") {
2002                parameters[iParam].printString();
2003                break;
2004              } else {
2005                parameters[iParam].setStringValue(field);
2006              }
2007              std::string fileName;
2008              bool canOpen=false;
2009              if (field[0]=='/'||field[0]=='\\') {
2010                fileName = field;
2011              } else if (field[0]=='~') {
2012                char * environVar = getenv("HOME");
2013                if (environVar) {
2014                  std::string home(environVar);
2015                  field=field.erase(0,1);
2016                  fileName = home+field;
2017                } else {
2018                  fileName=field;
2019                }
2020              } else {
2021                fileName = directory+field;
2022              }
2023              FILE *fp=fopen(fileName.c_str(),"w");
2024              if (fp) {
2025                // can open - lets go for it
2026                fclose(fp);
2027                canOpen=true;
2028              } else {
2029                std::cout<<"Unable to open file "<<fileName<<std::endl;
2030              }
2031              if (canOpen) {
2032                // If presolve on then save presolved
2033                bool deleteModel2=false;
2034                ClpSimplex * model2 = lpSolver;
2035                if (preSolve) {
2036                  ClpPresolve pinfo;
2037                  int presolveOptions2 = presolveOptions&~0x40000000;
2038                  if ((presolveOptions2&0xffff)!=0)
2039                    pinfo.setPresolveActions(presolveOptions2);
2040                  if ((printOptions&1)!=0)
2041                    pinfo.statistics();
2042                  double presolveTolerance = 
2043                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
2044                  model2 = 
2045                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
2046                                         true,preSolve);
2047                  if (model2) {
2048                    printf("Saving presolved model on %s\n",
2049                           fileName.c_str());
2050                    deleteModel2=true;
2051                  } else {
2052                    printf("Presolved model looks infeasible - saving original on %s\n",
2053                           fileName.c_str());
2054                    deleteModel2=false;
2055                    model2 = lpSolver;
2056
2057                  }
2058                } else {
2059                  printf("Saving model on %s\n",
2060                           fileName.c_str());
2061                }
2062#if 0
2063                // Convert names
2064                int iRow;
2065                int numberRows=model2->numberRows();
2066                int iColumn;
2067                int numberColumns=model2->numberColumns();
2068
2069                char ** rowNames = NULL;
2070                char ** columnNames = NULL;
2071                if (model2->lengthNames()) {
2072                  rowNames = new char * [numberRows];
2073                  for (iRow=0;iRow<numberRows;iRow++) {
2074                    rowNames[iRow] =
2075                      strdup(model2->rowName(iRow).c_str());
2076#ifdef STRIPBLANKS
2077                    char * xx = rowNames[iRow];
2078                    int i;
2079                    int length = strlen(xx);
2080                    int n=0;
2081                    for (i=0;i<length;i++) {
2082                      if (xx[i]!=' ')
2083                        xx[n++]=xx[i];
2084                    }
2085                    xx[n]='\0';
2086#endif
2087                  }
2088                 
2089                  columnNames = new char * [numberColumns];
2090                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2091                    columnNames[iColumn] =
2092                      strdup(model2->columnName(iColumn).c_str());
2093#ifdef STRIPBLANKS
2094                    char * xx = columnNames[iColumn];
2095                    int i;
2096                    int length = strlen(xx);
2097                    int n=0;
2098                    for (i=0;i<length;i++) {
2099                      if (xx[i]!=' ')
2100                        xx[n++]=xx[i];
2101                    }
2102                    xx[n]='\0';
2103#endif
2104                  }
2105                }
2106                CoinMpsIO writer;
2107                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
2108                                  model2->getColLower(), model2->getColUpper(),
2109                                  model2->getObjCoefficients(),
2110                                  (const char*) 0 /*integrality*/,
2111                                  model2->getRowLower(), model2->getRowUpper(),
2112                                  columnNames, rowNames);
2113                // Pass in array saying if each variable integer
2114                writer.copyInIntegerInformation(model2->integerInformation());
2115                writer.setObjectiveOffset(model2->objectiveOffset());
2116                writer.writeMps(fileName.c_str(),0,1,1);
2117                if (rowNames) {
2118                  for (iRow=0;iRow<numberRows;iRow++) {
2119                    free(rowNames[iRow]);
2120                  }
2121                  delete [] rowNames;
2122                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2123                    free(columnNames[iColumn]);
2124                  }
2125                  delete [] columnNames;
2126                }
2127#else
2128                model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
2129#endif
2130                if (deleteModel2)
2131                  delete model2;
2132                time2 = CoinCpuTime();
2133                totalTime += time2-time1;
2134                time1=time2;
2135              }
2136            } else {
2137              std::cout<<"** Current model not valid"<<std::endl;
2138            }
2139            break;
2140          case BASISIN:
2141            if (goodModel) {
2142              // get next field
2143              field = CoinReadGetString(argc,argv);
2144              if (field=="$") {
2145                field = parameters[iParam].stringValue();
2146              } else if (field=="EOL") {
2147                parameters[iParam].printString();
2148                break;
2149              } else {
2150                parameters[iParam].setStringValue(field);
2151              }
2152              std::string fileName;
2153              bool canOpen=false;
2154              if (field=="-") {
2155                // stdin
2156                canOpen=true;
2157                fileName = "-";
2158              } else {
2159                if (field[0]=='/'||field[0]=='\\') {
2160                  fileName = field;
2161                } else if (field[0]=='~') {
2162                  char * environVar = getenv("HOME");
2163                  if (environVar) {
2164                    std::string home(environVar);
2165                    field=field.erase(0,1);
2166                    fileName = home+field;
2167                  } else {
2168                    fileName=field;
2169                  }
2170                } else {
2171                  fileName = directory+field;
2172                }
2173                FILE *fp=fopen(fileName.c_str(),"r");
2174                if (fp) {
2175                  // can open - lets go for it
2176                  fclose(fp);
2177                  canOpen=true;
2178                } else {
2179                  std::cout<<"Unable to open file "<<fileName<<std::endl;
2180                }
2181              }
2182              if (canOpen) {
2183                int values = lpSolver->readBasis(fileName.c_str());
2184                if (values==0)
2185                  basisHasValues=-1;
2186                else
2187                  basisHasValues=1;
2188              }
2189            } else {
2190              std::cout<<"** Current model not valid"<<std::endl;
2191            }
2192            break;
2193          case DEBUG:
2194            if (goodModel) {
2195              delete [] debugValues;
2196              debugValues=NULL;
2197              // get next field
2198              field = CoinReadGetString(argc,argv);
2199              if (field=="$") {
2200                field = parameters[iParam].stringValue();
2201              } else if (field=="EOL") {
2202                parameters[iParam].printString();
2203                break;
2204              } else {
2205                parameters[iParam].setStringValue(field);
2206                debugFile=field;
2207                if (debugFile=="create"||
2208                    debugFile=="createAfterPre") {
2209                  printf("Will create a debug file so this run should be a good one\n");
2210                  break;
2211                }
2212              }
2213              std::string fileName;
2214              if (field[0]=='/'||field[0]=='\\') {
2215                fileName = field;
2216              } else if (field[0]=='~') {
2217                char * environVar = getenv("HOME");
2218                if (environVar) {
2219                  std::string home(environVar);
2220                  field=field.erase(0,1);
2221                  fileName = home+field;
2222                } else {
2223                  fileName=field;
2224                }
2225              } else {
2226                fileName = directory+field;
2227              }
2228              FILE *fp=fopen(fileName.c_str(),"rb");
2229              if (fp) {
2230                // can open - lets go for it
2231                int numRows;
2232                double obj;
2233                fread(&numRows,sizeof(int),1,fp);
2234                fread(&numberDebugValues,sizeof(int),1,fp);
2235                fread(&obj,sizeof(double),1,fp);
2236                debugValues = new double[numberDebugValues+numRows];
2237                fread(debugValues,sizeof(double),numRows,fp);
2238                fread(debugValues,sizeof(double),numRows,fp);
2239                fread(debugValues,sizeof(double),numberDebugValues,fp);
2240                printf("%d doubles read into debugValues\n",numberDebugValues);
2241                fclose(fp);
2242              } else {
2243                std::cout<<"Unable to open file "<<fileName<<std::endl;
2244              }
2245            } else {
2246              std::cout<<"** Current model not valid"<<std::endl;
2247            }
2248            break;
2249          case BASISOUT:
2250            if (goodModel) {
2251              // get next field
2252              field = CoinReadGetString(argc,argv);
2253              if (field=="$") {
2254                field = parameters[iParam].stringValue();
2255              } else if (field=="EOL") {
2256                parameters[iParam].printString();
2257                break;
2258              } else {
2259                parameters[iParam].setStringValue(field);
2260              }
2261              std::string fileName;
2262              bool canOpen=false;
2263              if (field[0]=='/'||field[0]=='\\') {
2264                fileName = field;
2265              } else if (field[0]=='~') {
2266                char * environVar = getenv("HOME");
2267                if (environVar) {
2268                  std::string home(environVar);
2269                  field=field.erase(0,1);
2270                  fileName = home+field;
2271                } else {
2272                  fileName=field;
2273                }
2274              } else {
2275                fileName = directory+field;
2276              }
2277              FILE *fp=fopen(fileName.c_str(),"w");
2278              if (fp) {
2279                // can open - lets go for it
2280                fclose(fp);
2281                canOpen=true;
2282              } else {
2283                std::cout<<"Unable to open file "<<fileName<<std::endl;
2284              }
2285              if (canOpen) {
2286                ClpSimplex * model2 = lpSolver;
2287                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
2288                time2 = CoinCpuTime();
2289                totalTime += time2-time1;
2290                time1=time2;
2291              }
2292            } else {
2293              std::cout<<"** Current model not valid"<<std::endl;
2294            }
2295            break;
2296          case SAVE:
2297            {
2298              // get next field
2299              field = CoinReadGetString(argc,argv);
2300              if (field=="$") {
2301                field = parameters[iParam].stringValue();
2302              } else if (field=="EOL") {
2303                parameters[iParam].printString();
2304                break;
2305              } else {
2306                parameters[iParam].setStringValue(field);
2307              }
2308              std::string fileName;
2309              bool canOpen=false;
2310              if (field[0]=='/'||field[0]=='\\') {
2311                fileName = field;
2312              } else if (field[0]=='~') {
2313                char * environVar = getenv("HOME");
2314                if (environVar) {
2315                  std::string home(environVar);
2316                  field=field.erase(0,1);
2317                  fileName = home+field;
2318                } else {
2319                  fileName=field;
2320                }
2321              } else {
2322                fileName = directory+field;
2323              }
2324              FILE *fp=fopen(fileName.c_str(),"wb");
2325              if (fp) {
2326                // can open - lets go for it
2327                fclose(fp);
2328                canOpen=true;
2329              } else {
2330                std::cout<<"Unable to open file "<<fileName<<std::endl;
2331              }
2332              if (canOpen) {
2333                int status;
2334                // If presolve on then save presolved
2335                bool deleteModel2=false;
2336                ClpSimplex * model2 = lpSolver;
2337                if (preSolve) {
2338                  ClpPresolve pinfo;
2339                  double presolveTolerance = 
2340                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
2341                  model2 = 
2342                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
2343                                         false,preSolve);
2344                  if (model2) {
2345                    printf("Saving presolved model on %s\n",
2346                           fileName.c_str());
2347                    deleteModel2=true;
2348                  } else {
2349                    printf("Presolved model looks infeasible - saving original on %s\n",
2350                           fileName.c_str());
2351                    deleteModel2=false;
2352                    model2 = lpSolver;
2353
2354                  }
2355                } else {
2356                  printf("Saving model on %s\n",
2357                           fileName.c_str());
2358                }
2359                status =model2->saveModel(fileName.c_str());
2360                if (deleteModel2)
2361                  delete model2;
2362                if (!status) {
2363                  goodModel=true;
2364                  time2 = CoinCpuTime();
2365                  totalTime += time2-time1;
2366                  time1=time2;
2367                } else {
2368                  // errors
2369                  std::cout<<"There were errors on output"<<std::endl;
2370                }
2371              }
2372            }
2373            break;
2374          case RESTORE:
2375            {
2376              // get next field
2377              field = CoinReadGetString(argc,argv);
2378              if (field=="$") {
2379                field = parameters[iParam].stringValue();
2380              } else if (field=="EOL") {
2381                parameters[iParam].printString();
2382                break;
2383              } else {
2384                parameters[iParam].setStringValue(field);
2385              }
2386              std::string fileName;
2387              bool canOpen=false;
2388              if (field[0]=='/'||field[0]=='\\') {
2389                fileName = field;
2390              } else if (field[0]=='~') {
2391                char * environVar = getenv("HOME");
2392                if (environVar) {
2393                  std::string home(environVar);
2394                  field=field.erase(0,1);
2395                  fileName = home+field;
2396                } else {
2397                  fileName=field;
2398                }
2399              } else {
2400                fileName = directory+field;
2401              }
2402              FILE *fp=fopen(fileName.c_str(),"rb");
2403              if (fp) {
2404                // can open - lets go for it
2405                fclose(fp);
2406                canOpen=true;
2407              } else {
2408                std::cout<<"Unable to open file "<<fileName<<std::endl;
2409              }
2410              if (canOpen) {
2411                int status =lpSolver->restoreModel(fileName.c_str());
2412                if (!status) {
2413                  goodModel=true;
2414                  time2 = CoinCpuTime();
2415                  totalTime += time2-time1;
2416                  time1=time2;
2417                } else {
2418                  // errors
2419                  std::cout<<"There were errors on input"<<std::endl;
2420                }
2421              }
2422            }
2423            break;
2424          case MAXIMIZE:
2425            lpSolver->setOptimizationDirection(-1);
2426            break;
2427          case MINIMIZE:
2428            lpSolver->setOptimizationDirection(1);
2429            break;
2430          case ALLSLACK:
2431            lpSolver->allSlackBasis(true);
2432            break;
2433          case REVERSE:
2434            if (goodModel) {
2435              int iColumn;
2436              int numberColumns=lpSolver->numberColumns();
2437              double * dualColumnSolution = 
2438                lpSolver->dualColumnSolution();
2439              ClpObjective * obj = lpSolver->objectiveAsObject();
2440              assert(dynamic_cast<ClpLinearObjective *> (obj));
2441              double offset;
2442              double * objective = obj->gradient(NULL,NULL,offset,true);
2443              for (iColumn=0;iColumn<numberColumns;iColumn++) {
2444                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
2445                objective[iColumn] = -objective[iColumn];
2446              }
2447              int iRow;
2448              int numberRows=lpSolver->numberRows();
2449              double * dualRowSolution = 
2450                lpSolver->dualRowSolution();
2451              for (iRow=0;iRow<numberRows;iRow++) 
2452                dualRowSolution[iRow] = dualRowSolution[iRow];
2453            }
2454            break;
2455          case DIRECTORY:
2456            {
2457              std::string name = CoinReadGetString(argc,argv);
2458              if (name!="EOL") {
2459                int length=name.length();
2460                if (name[length-1]=='/'||name[length-1]=='\\')
2461                  directory=name;
2462                else
2463                  directory = name+"/";
2464                parameters[iParam].setStringValue(directory);
2465              } else {
2466                parameters[iParam].printString();
2467              }
2468            }
2469            break;
2470          case STDIN:
2471            CbcOrClpRead_mode=-1;
2472            break;
2473          case NETLIB_DUAL:
2474          case NETLIB_EITHER:
2475          case NETLIB_BARRIER:
2476          case NETLIB_PRIMAL:
2477          case NETLIB_TUNE:
2478            {
2479              // create fields for unitTest
2480              const char * fields[4];
2481              int nFields=2;
2482              fields[0]="fake main from unitTest";
2483              fields[1]="-netlib";
2484              if (directory!=defaultDirectory) {
2485                fields[2]="-netlibDir";
2486                fields[3]=directory.c_str();
2487                nFields=4;
2488              }
2489              int algorithm;
2490              if (type==NETLIB_DUAL) {
2491                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
2492                algorithm =0;
2493              } else if (type==NETLIB_BARRIER) {
2494                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
2495                algorithm =2;
2496              } else if (type==NETLIB_EITHER) {
2497                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
2498                algorithm =3;
2499              } else if (type==NETLIB_TUNE) {
2500                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
2501                algorithm =5;
2502                // uncomment next to get active tuning
2503                // algorithm=6;
2504              } else {
2505                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
2506                algorithm=1;
2507              }
2508              int specialOptions = lpSolver->specialOptions();
2509              lpSolver->setSpecialOptions(0);
2510              mainTest(nFields,fields,algorithm,*lpSolver,
2511                       (preSolve!=0),specialOptions);
2512            }
2513            break;
2514          case UNITTEST:
2515            {
2516              // create fields for unitTest
2517              const char * fields[3];
2518              int nFields=1;
2519              fields[0]="fake main from unitTest";
2520              if (directory!=defaultDirectory) {
2521                fields[1]="-mpsDir";
2522                fields[2]=directory.c_str();
2523                nFields=3;
2524              }
2525              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
2526                       false);
2527            }
2528            break;
2529          case FAKEBOUND:
2530            if (goodModel) {
2531              // get bound
2532              double value = CoinReadGetDoubleField(argc,argv,&valid);
2533              if (!valid) {
2534                std::cout<<"Setting "<<parameters[iParam].name()<<
2535                  " to DEBUG "<<value<<std::endl;
2536                int iRow;
2537                int numberRows=lpSolver->numberRows();
2538                double * rowLower = lpSolver->rowLower();
2539                double * rowUpper = lpSolver->rowUpper();
2540                for (iRow=0;iRow<numberRows;iRow++) {
2541                  // leave free ones for now
2542                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
2543                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
2544                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
2545                  }
2546                }
2547                int iColumn;
2548                int numberColumns=lpSolver->numberColumns();
2549                double * columnLower = lpSolver->columnLower();
2550                double * columnUpper = lpSolver->columnUpper();
2551                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2552                  // leave free ones for now
2553                  if (columnLower[iColumn]>-1.0e20||
2554                      columnUpper[iColumn]<1.0e20) {
2555                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
2556                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
2557                  }
2558                }
2559              } else if (valid==1) {
2560                abort();
2561              } else {
2562                std::cout<<"enter value for "<<parameters[iParam].name()<<
2563                  std::endl;
2564              }
2565            }
2566            break;
2567          case REALLY_SCALE:
2568            if (goodModel) {
2569              ClpSimplex newModel(*lpSolver,
2570                                  lpSolver->scalingFlag());
2571              printf("model really really scaled\n");
2572              *lpSolver=newModel;
2573            }
2574            break;
2575          case HELP:
2576            std::cout<<"Coin Solver version "<<CBCVERSION
2577                     <<", build "<<__DATE__<<std::endl;
2578            std::cout<<"Non default values:-"<<std::endl;
2579            std::cout<<"Perturbation "<<lpSolver->perturbation()<<" (default 100)"
2580                     <<std::endl;
2581            CoinReadPrintit(
2582                    "Presolve being done with 5 passes\n\
2583Dual steepest edge steep/partial on matrix shape and factorization density\n\
2584Clpnnnn taken out of messages\n\
2585If Factorization frequency default then done on size of matrix\n\n\
2586(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
2587You can switch to interactive mode at any time so\n\
2588clp watson.mps -scaling off -primalsimplex\nis the same as\n\
2589clp watson.mps -\nscaling off\nprimalsimplex"
2590                    );
2591            break;
2592          case SOLUTION:
2593            if (goodModel) {
2594              // get next field
2595              field = CoinReadGetString(argc,argv);
2596              if (field=="$") {
2597                field = parameters[iParam].stringValue();
2598              } else if (field=="EOL") {
2599                parameters[iParam].printString();
2600                break;
2601              } else {
2602                parameters[iParam].setStringValue(field);
2603              }
2604              std::string fileName;
2605              FILE *fp=NULL;
2606              if (field=="-"||field=="EOL"||field=="stdout") {
2607                // stdout
2608                fp=stdout;
2609              } else if (field=="stderr") {
2610                // stderr
2611                fp=stderr;
2612              } else {
2613                if (field[0]=='/'||field[0]=='\\') {
2614                  fileName = field;
2615                } else if (field[0]=='~') {
2616                  char * environVar = getenv("HOME");
2617                  if (environVar) {
2618                    std::string home(environVar);
2619                    field=field.erase(0,1);
2620                    fileName = home+field;
2621                  } else {
2622                    fileName=field;
2623                  }
2624                } else {
2625                  fileName = directory+field;
2626                }
2627                fp=fopen(fileName.c_str(),"w");
2628              }
2629              if (fp) {
2630                // make fancy later on
2631                int iRow;
2632                int numberRows=lpSolver->numberRows();
2633                double * dualRowSolution = lpSolver->dualRowSolution();
2634                double * primalRowSolution = 
2635                  lpSolver->primalRowSolution();
2636                double * rowLower = lpSolver->rowLower();
2637                double * rowUpper = lpSolver->rowUpper();
2638                double primalTolerance = lpSolver->primalTolerance();
2639                char format[6];
2640                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
2641                if (printMode>2) {
2642                  for (iRow=0;iRow<numberRows;iRow++) {
2643                    int type=printMode-3;
2644                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
2645                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
2646                      fprintf(fp,"** ");
2647                      type=2;
2648                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
2649                      type=1;
2650                    } else if (numberRows<50) {
2651                      type=3;
2652                    }
2653                    if (type) {
2654                      fprintf(fp,"%7d ",iRow);
2655                      if (lengthName)
2656                        fprintf(fp,format,rowNames[iRow].c_str());
2657                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
2658                              dualRowSolution[iRow]);
2659                    }
2660                  }
2661                }
2662                int iColumn;
2663                int numberColumns=lpSolver->numberColumns();
2664                double * dualColumnSolution = 
2665                  lpSolver->dualColumnSolution();
2666                double * primalColumnSolution = 
2667                  lpSolver->primalColumnSolution();
2668                double * columnLower = lpSolver->columnLower();
2669                double * columnUpper = lpSolver->columnUpper();
2670                if (printMode!=2) {
2671                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2672                    int type=0;
2673                    if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
2674                        primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
2675                      fprintf(fp,"** ");
2676                      type=2;
2677                    } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
2678                      type=1;
2679                    } else if (numberColumns<50) {
2680                      type=3;
2681                    }
2682                    // see if integer
2683                    if ((!lpSolver->isInteger(iColumn)||fabs(primalColumnSolution[iColumn])<1.0e-8)
2684                         &&printMode==1)
2685                      type=0;
2686                    if (type) {
2687                      fprintf(fp,"%7d ",iColumn);
2688                      if (lengthName)
2689                        fprintf(fp,format,columnNames[iColumn].c_str());
2690                      fprintf(fp,"%15.8g        %15.8g\n",
2691                              primalColumnSolution[iColumn],
2692                              dualColumnSolution[iColumn]);
2693                    }
2694                  }
2695                } else {
2696                  // special format suitable for OsiRowCutDebugger
2697                  int n=0;
2698                  bool comma=false;
2699                  bool newLine=false;
2700                  fprintf(fp,"\tint intIndicesV[]={\n");
2701                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2702                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
2703                      if (comma)
2704                        fprintf(fp,",");
2705                      if (newLine)
2706                        fprintf(fp,"\n");
2707                      fprintf(fp,"%d ",iColumn);
2708                      comma=true;
2709                      newLine=false;
2710                      n++;
2711                      if (n==10) {
2712                        n=0;
2713                        newLine=true;
2714                      }
2715                    }
2716                  }
2717                  fprintf(fp,"};\n");
2718                  n=0;
2719                  comma=false;
2720                  newLine=false;
2721                  fprintf(fp,"\tdouble intSolnV[]={\n");
2722                  for ( iColumn=0;iColumn<numberColumns;iColumn++) {
2723                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
2724                      if (comma)
2725                        fprintf(fp,",");
2726                      if (newLine)
2727                        fprintf(fp,"\n");
2728                      int value = (int) (primalColumnSolution[iColumn]+0.5);
2729                      fprintf(fp,"%d. ",value);
2730                      comma=true;
2731                      newLine=false;
2732                      n++;
2733                      if (n==10) {
2734                        n=0;
2735                        newLine=true;
2736                      }
2737                    }
2738                  }
2739                  fprintf(fp,"};\n");
2740                }
2741                if (fp!=stdout)
2742                  fclose(fp);
2743              } else {
2744                std::cout<<"Unable to open file "<<fileName<<std::endl;
2745              }
2746            } else {
2747              std::cout<<"** Current model not valid"<<std::endl;
2748             
2749            }
2750            break;
2751          case SAVESOL:
2752            if (goodModel) {
2753              // get next field
2754              field = CoinReadGetString(argc,argv);
2755              if (field=="$") {
2756                field = parameters[iParam].stringValue();
2757              } else if (field=="EOL") {
2758                parameters[iParam].printString();
2759                break;
2760              } else {
2761                parameters[iParam].setStringValue(field);
2762              }
2763              std::string fileName;
2764              if (field[0]=='/'||field[0]=='\\') {
2765                fileName = field;
2766              } else if (field[0]=='~') {
2767                char * environVar = getenv("HOME");
2768                if (environVar) {
2769                  std::string home(environVar);
2770                  field=field.erase(0,1);
2771                  fileName = home+field;
2772                } else {
2773                  fileName=field;
2774                }
2775              } else {
2776                fileName = directory+field;
2777              }
2778              saveSolution(lpSolver,fileName);
2779            } else {
2780              std::cout<<"** Current model not valid"<<std::endl;
2781             
2782            }
2783            break;
2784          default:
2785            abort();
2786          }
2787        } 
2788      } else if (!numberMatches) {
2789        std::cout<<"No match for "<<field<<" - ? for list of commands"
2790                 <<std::endl;
2791      } else if (numberMatches==1) {
2792        if (!numberQuery) {
2793          std::cout<<"Short match for "<<field<<" - completion: ";
2794          std::cout<<parameters[firstMatch].matchName()<<std::endl;
2795        } else if (numberQuery) {
2796          std::cout<<parameters[firstMatch].matchName()<<" : ";
2797          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
2798          if (numberQuery>=2) 
2799            parameters[firstMatch].printLongHelp();
2800        }
2801      } else {
2802        if (!numberQuery) 
2803          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
2804                   <<std::endl;
2805        else
2806          std::cout<<"Completions of "<<field<<":"<<std::endl;
2807        for ( iParam=0; iParam<numberParameters; iParam++ ) {
2808          int match = parameters[iParam].matches(field);
2809          if (match&&parameters[iParam].displayThis()) {
2810            std::cout<<parameters[iParam].matchName();
2811            if (numberQuery>=2) 
2812              std::cout<<" : "<<parameters[iParam].shortHelp();
2813            std::cout<<std::endl;
2814          }
2815        }
2816      }
2817    }
2818  }
2819  // By now all memory should be freed
2820#ifdef DMALLOC
2821  dmalloc_log_unfreed();
2822  dmalloc_shutdown();
2823#endif
2824  return 0;
2825}   
2826/*
2827  Version 1.00.00 November 16 2005.
2828  This is to stop me (JJF) messing about too much.
2829  Tuning changes should be noted here.
2830  The testing next version may be activated by CBC_NEXT_VERSION
2831  This applies to OsiClp, Clp etc
2832  Version 1.00.01 November 24 2005
2833  Added several classes for advanced users.  This can't affect code (if you don't use it)
2834  Made some tiny changes (for N way branching) which should not change anything.
2835  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
2836  CbcBranchAllDifferent object class - for branching on general integer variables
2837  to stop them having same value so branches are x >= y+1 and x <= y-1.
2838  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
2839  and CglStored which just has a list of cuts which can be activated.
2840  Modified preprocess option to SOS
2841  Version 1.00.02 December 9 2005
2842  Added use of CbcStrategy to do clean preprocessing
2843  Added use of referenceSolver for cleaner repetition of Cbc
2844*/
Note: See TracBrowser for help on using the repository browser.