source: trunk/Test/CoinSolve.cpp @ 258

Last change on this file since 258 was 258, checked in by forrest, 15 years ago

for docs

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