source: trunk/Cbc/src/CoinSolve.cpp @ 369

Last change on this file since 369 was 369, checked in by andreasw, 13 years ago

Enabled Ampl executable for Cbc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 158.4 KB
Line 
1// Copyright (C) 2004, International Business Machines
2// Corporation and others.  All Rights Reserved.
3   
4#include "CbcConfig.h"
5#include "CoinPragma.hpp"
6
7#include <cassert>
8#include <cstdio>
9#include <cmath>
10#include <cfloat>
11#include <cstring>
12#include <iostream>
13
14
15#include "CoinPragma.hpp"
16#include "CoinHelperFunctions.hpp"
17// Same version as CBC
18#define CBCVERSION "1.01.00"
19
20#include "CoinMpsIO.hpp"
21
22#include "ClpFactorization.hpp"
23#include "CoinTime.hpp"
24#include "ClpSimplex.hpp"
25#include "ClpSimplexOther.hpp"
26#include "ClpSolve.hpp"
27#include "ClpPackedMatrix.hpp"
28#include "ClpPlusMinusOneMatrix.hpp"
29#include "ClpNetworkMatrix.hpp"
30#include "ClpDualRowSteepest.hpp"
31#include "ClpDualRowDantzig.hpp"
32#include "ClpLinearObjective.hpp"
33#include "ClpPrimalColumnSteepest.hpp"
34#include "ClpPrimalColumnDantzig.hpp"
35#include "ClpPresolve.hpp"
36#include "CbcOrClpParam.hpp"
37#include "OsiRowCutDebugger.hpp"
38#ifdef DMALLOC
39#include "dmalloc.h"
40#endif
41#ifdef WSSMP_BARRIER
42#define FOREIGN_BARRIER
43#endif
44#ifdef UFL_BARRIER
45#define FOREIGN_BARRIER
46#endif
47#ifdef TAUCS_BARRIER
48#define FOREIGN_BARRIER
49#endif
50#include "CoinWarmStartBasis.hpp"
51
52#include "OsiSolverInterface.hpp"
53#include "OsiCuts.hpp"
54#include "OsiRowCut.hpp"
55#include "OsiColCut.hpp"
56
57#include "CglPreProcess.hpp"
58#include "CglCutGenerator.hpp"
59#include "CglGomory.hpp"
60#include "CglProbing.hpp"
61#include "CglKnapsackCover.hpp"
62#include "CglRedSplit.hpp"
63#include "CglClique.hpp"
64#include "CglFlowCover.hpp"
65#include "CglMixedIntegerRounding2.hpp"
66#include "CglTwomir.hpp"
67#include "CglDuplicateRow.hpp"
68
69#include "CbcModel.hpp"
70#include "CbcHeuristic.hpp"
71#include "CbcHeuristicLocal.hpp"
72#include "CbcHeuristicGreedy.hpp"
73#include "CbcHeuristicFPump.hpp"
74#include "CbcTreeLocal.hpp"
75#include "CbcCompareActual.hpp"
76#include "CbcBranchActual.hpp"
77#include  "CbcOrClpParam.hpp"
78#include  "CbcCutGenerator.hpp"
79#include  "CbcStrategy.hpp"
80
81#include "OsiClpSolverInterface.hpp"
82#ifdef COIN_HAS_ASL
83#include "Cbc_ampl.h"
84static bool usingAmpl=false;
85#endif
86static double totalTime=0.0;
87static void statistics(ClpSimplex * originalModel, ClpSimplex * model);
88static bool maskMatches(const int * starts, char ** masks,
89                        std::string & check);
90static void generateCode(const char * fileName,int type,int preProcess);
91//#############################################################################
92
93#ifdef NDEBUG
94#undef NDEBUG
95#endif
96// Allow for interrupts
97// But is this threadsafe ? (so switched off by option)
98
99#include "CoinSignal.hpp"
100static CbcModel * currentBranchModel = NULL;
101
102extern "C" {
103   static void signal_handler(int whichSignal)
104   {
105      if (currentBranchModel!=NULL) 
106         currentBranchModel->setMaximumNodes(0); // stop at next node
107      return;
108   }
109}
110
111int mainTest (int argc, const char *argv[],int algorithm,
112              ClpSimplex empty, bool doPresolve,int switchOff);
113void CbcClpUnitTest (const CbcModel & saveModel);
114int CbcOrClpRead_mode=1;
115FILE * CbcOrClpReadCommand=stdin;
116static bool noPrinting=false;
117static int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment,
118                     bool changeInt)
119{
120  OsiSolverInterface * solver = solverMod->clone();
121  if (0) {
122    // just get increment
123    CbcModel model(*solver);
124    model.analyzeObjective();
125    double increment2=model.getCutoffIncrement();
126    printf("initial cutoff increment %g\n",increment2);
127  }
128  const double *objective = solver->getObjCoefficients() ;
129  const double *lower = solver->getColLower() ;
130  const double *upper = solver->getColUpper() ;
131  int numberColumns = solver->getNumCols() ;
132  int numberRows = solver->getNumRows();
133  double direction = solver->getObjSense();
134  int iRow,iColumn;
135
136  // Row copy
137  CoinPackedMatrix matrixByRow(*solver->getMatrixByRow());
138  const double * elementByRow = matrixByRow.getElements();
139  const int * column = matrixByRow.getIndices();
140  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
141  const int * rowLength = matrixByRow.getVectorLengths();
142
143  // Column copy
144  CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
145  const double * element = matrixByCol.getElements();
146  const int * row = matrixByCol.getIndices();
147  const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
148  const int * columnLength = matrixByCol.getVectorLengths();
149
150  const double * rowLower = solver->getRowLower();
151  const double * rowUpper = solver->getRowUpper();
152
153  char * ignore = new char [numberRows];
154  int * changed = new int[numberColumns];
155  int * which = new int[numberRows];
156  double * changeRhs = new double[numberRows];
157  memset(changeRhs,0,numberRows*sizeof(double));
158  memset(ignore,0,numberRows);
159  numberChanged=0;
160  int numberInteger=0;
161  for (iColumn=0;iColumn<numberColumns;iColumn++) {
162    if (upper[iColumn] > lower[iColumn]+1.0e-8&&solver->isInteger(iColumn)) 
163      numberInteger++;
164  }
165  bool finished=false;
166  while (!finished) {
167    int saveNumberChanged = numberChanged;
168    for (iRow=0;iRow<numberRows;iRow++) {
169      int numberContinuous=0;
170      double value1=0.0,value2=0.0;
171      bool allIntegerCoeff=true;
172      double sumFixed=0.0;
173      int jColumn1=-1,jColumn2=-1;
174      for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
175        int jColumn = column[j];
176        double value = elementByRow[j];
177        if (upper[jColumn] > lower[jColumn]+1.0e-8) {
178          if (!solver->isInteger(jColumn)) {
179            if (numberContinuous==0) {
180              jColumn1=jColumn;
181              value1=value;
182            } else {
183              jColumn2=jColumn;
184              value2=value;
185            }
186            numberContinuous++;
187          } else {
188            if (fabs(value-floor(value+0.5))>1.0e-12)
189              allIntegerCoeff=false;
190          }
191        } else {
192          sumFixed += lower[jColumn]*value;
193        }
194      }
195      double low = rowLower[iRow];
196      if (low>-1.0e20) {
197        low -= sumFixed;
198        if (fabs(low-floor(low+0.5))>1.0e-12)
199          allIntegerCoeff=false;
200      }
201      double up = rowUpper[iRow];
202      if (up<1.0e20) {
203        up -= sumFixed;
204        if (fabs(up-floor(up+0.5))>1.0e-12)
205          allIntegerCoeff=false;
206      }
207      if (!allIntegerCoeff)
208        continue; // can't do
209      if (numberContinuous==1) {
210        // see if really integer
211        // This does not allow for complicated cases
212        if (low==up) {
213          if (fabs(value1)>1.0e-3) {
214            value1 = 1.0/value1;
215            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
216              // integer
217              changed[numberChanged++]=jColumn1;
218              solver->setInteger(jColumn1);
219              if (upper[jColumn1]>1.0e20)
220                solver->setColUpper(jColumn1,1.0e20);
221              if (lower[jColumn1]<-1.0e20)
222                solver->setColLower(jColumn1,-1.0e20);
223            }
224          }
225        } else {
226          if (fabs(value1)>1.0e-3) {
227            value1 = 1.0/value1;
228            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
229              // This constraint will not stop it being integer
230              ignore[iRow]=1;
231            }
232          }
233        }
234      } else if (numberContinuous==2) {
235        if (low==up) {
236          /* need general theory - for now just look at 2 cases -
237             1 - +- 1 one in column and just costs i.e. matching objective
238             2 - +- 1 two in column but feeds into G/L row which will try and minimize
239          */
240          if (fabs(value1)==1.0&&value1*value2==-1.0&&!lower[jColumn1]
241              &&!lower[jColumn2]) {
242            int n=0;
243            int i;
244            double objChange=direction*(objective[jColumn1]+objective[jColumn2]);
245            double bound = CoinMin(upper[jColumn1],upper[jColumn2]);
246            bound = CoinMin(bound,1.0e20);
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                which[n++]=jRow;
252                changeRhs[jRow]=value;
253              }
254            }
255            for ( i=columnStart[jColumn1];i<columnStart[jColumn1]+columnLength[jColumn1];i++) {
256              int jRow = row[i];
257              double value = element[i];
258              if (jRow!=iRow) {
259                if (!changeRhs[jRow]) {
260                  which[n++]=jRow;
261                  changeRhs[jRow]=value;
262                } else {
263                  changeRhs[jRow]+=value;
264                }
265              }
266            }
267            if (objChange>=0.0) {
268              // see if all rows OK
269              bool good=true;
270              for (i=0;i<n;i++) {
271                int jRow = which[i];
272                double value = changeRhs[jRow];
273                if (value) {
274                  value *= bound;
275                  if (rowLength[jRow]==1) {
276                    if (value>0.0) {
277                      double rhs = rowLower[jRow];
278                      if (rhs>0.0) {
279                        double ratio =rhs/value;
280                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
281                          good=false;
282                      }
283                    } else {
284                      double rhs = rowUpper[jRow];
285                      if (rhs<0.0) {
286                        double ratio =rhs/value;
287                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
288                          good=false;
289                      }
290                    }
291                  } else if (rowLength[jRow]==2) {
292                    if (value>0.0) {
293                      if (rowLower[jRow]>-1.0e20)
294                        good=false;
295                    } else {
296                      if (rowUpper[jRow]<1.0e20)
297                        good=false;
298                    }
299                  } else {
300                    good=false;
301                  }
302                }
303              }
304              if (good) {
305                // both can be integer
306                changed[numberChanged++]=jColumn1;
307                solver->setInteger(jColumn1);
308                if (upper[jColumn1]>1.0e20)
309                  solver->setColUpper(jColumn1,1.0e20);
310                if (lower[jColumn1]<-1.0e20)
311                  solver->setColLower(jColumn1,-1.0e20);
312                changed[numberChanged++]=jColumn2;
313                solver->setInteger(jColumn2);
314                if (upper[jColumn2]>1.0e20)
315                  solver->setColUpper(jColumn2,1.0e20);
316                if (lower[jColumn2]<-1.0e20)
317                  solver->setColLower(jColumn2,-1.0e20);
318              }
319            }
320            // clear
321            for (i=0;i<n;i++) {
322              changeRhs[which[i]]=0.0;
323            }
324          }
325        }
326      }
327    }
328    for (iColumn=0;iColumn<numberColumns;iColumn++) {
329      if (upper[iColumn] > lower[iColumn]+1.0e-8&&!solver->isInteger(iColumn)) {
330        double value;
331        value = upper[iColumn];
332        if (value<1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
333          continue;
334        value = lower[iColumn];
335        if (value>-1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
336          continue;
337        bool integer=true;
338        for (CoinBigIndex j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn];j++) {
339          int iRow = row[j];
340          if (!ignore[iRow]) {
341            integer=false;
342            break;
343          }
344        }
345        if (integer) {
346          // integer
347          changed[numberChanged++]=iColumn;
348          solver->setInteger(iColumn);
349          if (upper[iColumn]>1.0e20)
350            solver->setColUpper(iColumn,1.0e20);
351          if (lower[iColumn]<-1.0e20)
352            solver->setColLower(iColumn,-1.0e20);
353        }
354      }
355    }
356    finished = numberChanged==saveNumberChanged;
357  }
358  delete [] which;
359  delete [] changeRhs;
360  delete [] ignore;
361  if (numberInteger&&!noPrinting)
362    printf("%d integer variables",numberInteger);
363  if (changeInt) {
364    if (!noPrinting) {
365      if (numberChanged)
366        printf(" and %d variables made integer\n",numberChanged);
367      else
368        printf("\n");
369    }
370    delete [] ignore;
371    //increment=0.0;
372    if (!numberChanged) {
373      delete [] changed;
374      delete solver;
375      return NULL;
376    } else {
377      for (iColumn=0;iColumn<numberColumns;iColumn++) {
378        if (solver->isInteger(iColumn))
379          solverMod->setInteger(iColumn);
380      }
381      delete solver;
382      return changed;
383    }
384  } else {
385    if (!noPrinting) {
386      if (numberChanged)
387        printf(" and %d variables could be made integer\n",numberChanged);
388      else
389        printf("\n");
390    }
391    // just get increment
392    CbcModel model(*solver);
393    if (noPrinting)
394      model.setLogLevel(0);
395    model.analyzeObjective();
396    double increment2=model.getCutoffIncrement();
397    if (increment2>increment) {
398      if (!noPrinting)
399        printf("cutoff increment increased from %g to %g\n",increment,increment2);
400      increment=increment2;
401    }
402    delete solver;
403    numberChanged=0;
404    delete [] changed;
405    return NULL;
406  }
407}
408static int outDupRow(OsiSolverInterface * solver) 
409{
410  CglDuplicateRow dupCuts(solver);
411  CglTreeInfo info;
412  info.level = 0;
413  info.pass = 0;
414  int numberRows = solver->getNumRows();
415  info.formulation_rows = numberRows;
416  info.inTree = false;
417  info.strengthenRow= NULL;
418  info.pass = 0;
419  OsiCuts cs;
420  dupCuts.generateCuts(*solver,cs,info);
421  const int * duplicate = dupCuts.duplicate();
422  // Get rid of duplicate rows
423  int * which = new int[numberRows]; 
424  int numberDrop=0;
425  for (int iRow=0;iRow<numberRows;iRow++) {
426    if (duplicate[iRow]==-2||duplicate[iRow]>=0) 
427      which[numberDrop++]=iRow;
428  }
429  if (numberDrop) {
430    solver->deleteRows(numberDrop,which);
431  }
432  delete [] which;
433  // see if we have any column cuts
434  int numberColumnCuts = cs.sizeColCuts() ;
435  const double * columnLower = solver->getColLower();
436  const double * columnUpper = solver->getColUpper();
437  for (int k = 0;k<numberColumnCuts;k++) {
438    OsiColCut * thisCut = cs.colCutPtr(k) ;
439    const CoinPackedVector & lbs = thisCut->lbs() ;
440    const CoinPackedVector & ubs = thisCut->ubs() ;
441    int j ;
442    int n ;
443    const int * which ;
444    const double * values ;
445    n = lbs.getNumElements() ;
446    which = lbs.getIndices() ;
447    values = lbs.getElements() ;
448    for (j = 0;j<n;j++) {
449      int iColumn = which[j] ;
450      if (values[j]>columnLower[iColumn]) 
451        solver->setColLower(iColumn,values[j]) ;
452    }
453    n = ubs.getNumElements() ;
454    which = ubs.getIndices() ;
455    values = ubs.getElements() ;
456    for (j = 0;j<n;j++) {
457      int iColumn = which[j] ;
458      if (values[j]<columnUpper[iColumn]) 
459        solver->setColUpper(iColumn,values[j]) ;
460    }
461  }
462  return numberDrop;
463}
464int main (int argc, const char *argv[])
465{
466  /* Note
467     This is meant as a stand-alone executable to do as much of coin as possible.
468     It should only have one solver known to it.
469  */
470  {
471    double time1 = CoinCpuTime(),time2;
472    bool goodModel=false;
473    CoinSighandler_t saveSignal=SIG_DFL;
474    // register signal handler
475    saveSignal = signal(SIGINT,signal_handler);
476    // Set up all non-standard stuff
477    OsiClpSolverInterface solver1;
478    CbcModel model(solver1);
479    CbcModel * babModel = NULL;
480    model.setNumberBeforeTrust(21);
481    int cutPass=-1234567;
482    OsiSolverInterface * solver = model.solver();
483    OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
484    ClpSimplex * lpSolver = clpSolver->getModelPtr();
485    clpSolver->messageHandler()->setLogLevel(0) ;
486    model.messageHandler()->setLogLevel(1);
487    // For priorities etc
488    int * priorities=NULL;
489    int * branchDirection=NULL;
490    double * pseudoDown=NULL;
491    double * pseudoUp=NULL;
492    double * solutionIn = NULL;
493    int * prioritiesIn = NULL;
494#ifdef COIN_HAS_ASL
495    ampl_info info;
496    if (argc>2&&!strcmp(argv[2],"-AMPL")) {
497      usingAmpl=true;
498      int returnCode = readAmpl(&info,argc,const_cast<char **>(argv));
499      if (returnCode)
500        return returnCode;
501      CbcOrClpRead_mode=2; // so will start with parameters
502      // see if log in list
503      noPrinting=true;
504      for (int i=1;i<info.numberArguments;i++) {
505        if (!strcmp(info.arguments[i],"log")) {
506          if (i<info.numberArguments-1&&atoi(info.arguments[i+1])>0)
507            noPrinting=false;
508          break;
509        }
510      }
511      if (noPrinting) {
512        model.messageHandler()->setLogLevel(0);
513        setCbcOrClpPrinting(false);
514      }
515      if (!noPrinting)
516        printf("%d rows, %d columns and %d elements\n",
517               info.numberRows,info.numberColumns,info.numberElements);
518      solver->loadProblem(info.numberColumns,info.numberRows,info.starts,
519                          info.rows,info.elements,
520                          info.columnLower,info.columnUpper,info.objective,
521                          info.rowLower,info.rowUpper);
522      // If we had a solution use it
523      if (info.primalSolution) {
524        solver->setColSolution(info.primalSolution);
525      }
526      // status
527      if (info.rowStatus) {
528        unsigned char * statusArray = lpSolver->statusArray();
529        int i;
530        for (i=0;i<info.numberColumns;i++)
531          statusArray[i]=(char)info.columnStatus[i];
532        statusArray+=info.numberColumns;
533        for (i=0;i<info.numberRows;i++)
534          statusArray[i]=(char)info.rowStatus[i];
535        CoinWarmStartBasis * basis = lpSolver->getBasis();
536        solver->setWarmStart(basis);
537        delete basis;
538      }
539      freeArrays1(&info);
540      // modify objective if necessary
541      solver->setObjSense(info.direction);
542      solver->setDblParam(OsiObjOffset,info.offset);
543      // Set integer variables
544      for (int i=info.numberColumns-info.numberBinary-info.numberIntegers;
545           i<info.numberColumns;i++)
546        solver->setInteger(i);
547      goodModel=true;
548      // change argc etc
549      argc = info.numberArguments;
550      argv = const_cast<const char **>(info.arguments);
551    }
552#endif   
553    // default action on import
554    int allowImportErrors=0;
555    int keepImportNames=1;
556    int doIdiot=-1;
557    int outputFormat=2;
558    int slpValue=-1;
559    int cppValue=-1;
560    int printOptions=0;
561    int printMode=0;
562    int presolveOptions=0;
563    int substitution=3;
564    int dualize=0;
565    int doCrash=0;
566    int doSprint=-1;
567    int doScaling=1;
568    // set reasonable defaults
569    int preSolve=5;
570    int preProcess=4;
571    bool useStrategy=false;
572    bool preSolveFile=false;
573   
574    double djFix=1.0e100;
575    double gapRatio=1.0e100;
576    double tightenFactor=0.0;
577    lpSolver->setPerturbation(50);
578    lpSolver->messageHandler()->setPrefix(false);
579    const char dirsep =  CoinFindDirSeparator();
580    std::string directory = (dirsep == '/' ? "./" : ".\\");
581    std::string defaultDirectory = directory;
582    std::string importFile ="";
583    std::string exportFile ="default.mps";
584    std::string importBasisFile ="";
585    std::string importPriorityFile ="";
586    std::string debugFile="";
587    std::string printMask="";
588    double * debugValues = NULL;
589    int numberDebugValues = -1;
590    int basisHasValues=0;
591    std::string exportBasisFile ="default.bas";
592    std::string saveFile ="default.prob";
593    std::string restoreFile ="default.prob";
594    std::string solutionFile ="stdout";
595    std::string solutionSaveFile ="solution.file";
596#define CBCMAXPARAMETERS 200
597    CbcOrClpParam parameters[CBCMAXPARAMETERS];
598    int numberParameters ;
599    establishParams(numberParameters,parameters) ;
600    parameters[whichParam(BASISIN,numberParameters,parameters)].setStringValue(importBasisFile);
601    parameters[whichParam(PRIORITYIN,numberParameters,parameters)].setStringValue(importPriorityFile);
602    parameters[whichParam(BASISOUT,numberParameters,parameters)].setStringValue(exportBasisFile);
603    parameters[whichParam(DEBUG,numberParameters,parameters)].setStringValue(debugFile);
604    parameters[whichParam(PRINTMASK,numberParameters,parameters)].setStringValue(printMask);
605    parameters[whichParam(DIRECTORY,numberParameters,parameters)].setStringValue(directory);
606    parameters[whichParam(DUALBOUND,numberParameters,parameters)].setDoubleValue(lpSolver->dualBound());
607    parameters[whichParam(DUALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->dualTolerance());
608    parameters[whichParam(EXPORT,numberParameters,parameters)].setStringValue(exportFile);
609    parameters[whichParam(IDIOT,numberParameters,parameters)].setIntValue(doIdiot);
610    parameters[whichParam(IMPORT,numberParameters,parameters)].setStringValue(importFile);
611    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].setDoubleValue(1.0e-8);
612    int slog = whichParam(SOLVERLOGLEVEL,numberParameters,parameters);
613    int log = whichParam(LOGLEVEL,numberParameters,parameters);
614    parameters[slog].setIntValue(0);
615    parameters[log].setIntValue(1);
616    parameters[whichParam(MAXFACTOR,numberParameters,parameters)].setIntValue(lpSolver->factorizationFrequency());
617    parameters[whichParam(MAXITERATION,numberParameters,parameters)].setIntValue(lpSolver->maximumIterations());
618    parameters[whichParam(OUTPUTFORMAT,numberParameters,parameters)].setIntValue(outputFormat);
619    parameters[whichParam(PRESOLVEPASS,numberParameters,parameters)].setIntValue(preSolve);
620    parameters[whichParam(PERTVALUE,numberParameters,parameters)].setIntValue(lpSolver->perturbation());
621    parameters[whichParam(PRIMALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->primalTolerance());
622    parameters[whichParam(PRIMALWEIGHT,numberParameters,parameters)].setDoubleValue(lpSolver->infeasibilityCost());
623    parameters[whichParam(RESTORE,numberParameters,parameters)].setStringValue(restoreFile);
624    parameters[whichParam(SAVE,numberParameters,parameters)].setStringValue(saveFile);
625    //parameters[whichParam(TIMELIMIT,numberParameters,parameters)].setDoubleValue(1.0e8);
626    parameters[whichParam(TIMELIMIT_BAB,numberParameters,parameters)].setDoubleValue(1.0e8);
627    parameters[whichParam(SOLUTION,numberParameters,parameters)].setStringValue(solutionFile);
628    parameters[whichParam(SAVESOL,numberParameters,parameters)].setStringValue(solutionSaveFile);
629    parameters[whichParam(SPRINT,numberParameters,parameters)].setIntValue(doSprint);
630    parameters[whichParam(SUBSTITUTION,numberParameters,parameters)].setIntValue(substitution);
631    parameters[whichParam(DUALIZE,numberParameters,parameters)].setIntValue(dualize);
632    model.setNumberBeforeTrust(5);
633    parameters[whichParam(NUMBERBEFORE,numberParameters,parameters)].setIntValue(5);
634    parameters[whichParam(MAXNODES,numberParameters,parameters)].setIntValue(model.getMaximumNodes());
635    model.setNumberStrong(5);
636    parameters[whichParam(STRONGBRANCHING,numberParameters,parameters)].setIntValue(model.numberStrong());
637    parameters[whichParam(INFEASIBILITYWEIGHT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcInfeasibilityWeight));
638    parameters[whichParam(INTEGERTOLERANCE,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcIntegerTolerance));
639    parameters[whichParam(INCREMENT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcCutoffIncrement));
640    // Set up likely cut generators and defaults
641    parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("sos");
642    parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(128|64|1);
643    parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].setIntValue(-1);
644    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].setIntValue(100);
645    parameters[whichParam(CUTSSTRATEGY,numberParameters,parameters)].setCurrentOption("on");
646    parameters[whichParam(HEURISTICSTRATEGY,numberParameters,parameters)].setCurrentOption("on");
647    int doSOS=1;
648    int verbose=0;
649    CglGomory gomoryGen;
650    // try larger limit
651    gomoryGen.setLimitAtRoot(512);
652    gomoryGen.setLimit(50);
653    // set default action (0=off,1=on,2=root)
654    int gomoryAction=3;
655    parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
656
657    CglProbing probingGen;
658    probingGen.setUsingObjective(true);
659    probingGen.setMaxPass(3);
660    probingGen.setMaxPassRoot(3);
661    // Number of unsatisfied variables to look at
662    probingGen.setMaxProbe(10);
663    probingGen.setMaxProbeRoot(50);
664    // How far to follow the consequences
665    probingGen.setMaxLook(10);
666    probingGen.setMaxLookRoot(50);
667    probingGen.setMaxLookRoot(10);
668    // Only look at rows with fewer than this number of elements
669    probingGen.setMaxElements(200);
670    probingGen.setRowCuts(3);
671    // set default action (0=off,1=on,2=root)
672    int probingAction=3;
673    parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
674
675    CglKnapsackCover knapsackGen;
676    //knapsackGen.switchOnExpensive();
677    // set default action (0=off,1=on,2=root)
678    int knapsackAction=3;
679    parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
680
681    CglRedSplit redsplitGen;
682    //redsplitGen.setLimit(100);
683    // set default action (0=off,1=on,2=root)
684    // Off as seems to give some bad cuts
685    int redsplitAction=2;
686    parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption("root");
687
688    CglClique cliqueGen(false,true);
689    cliqueGen.setStarCliqueReport(false);
690    cliqueGen.setRowCliqueReport(false);
691    cliqueGen.setMinViolation(0.1);
692    // set default action (0=off,1=on,2=root)
693    int cliqueAction=3;
694    parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption("ifmove");
695
696    CglMixedIntegerRounding2 mixedGen;
697    // set default action (0=off,1=on,2=root)
698    int mixedAction=3;
699    parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
700
701    CglFlowCover flowGen;
702    // set default action (0=off,1=on,2=root)
703    int flowAction=3;
704    parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
705
706    CglTwomir twomirGen;
707    twomirGen.setMaxElements(250);
708    // set default action (0=off,1=on,2=root)
709    int twomirAction=2;
710    parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption("root");
711
712    bool useRounding=true;
713    parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption("on");
714    bool useFpump=true;
715    parameters[whichParam(FPUMP,numberParameters,parameters)].setCurrentOption("on");
716    bool useGreedy=true;
717    parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption("on");
718    bool useCombine=true;
719    parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption("on");
720    bool useLocalTree=false;
721    parameters[whichParam(COSTSTRATEGY,numberParameters,parameters)].setCurrentOption("off");
722    int useCosts=0;
723    // don't use input solution
724    int useSolution=0;
725   
726    // total number of commands read
727    int numberGoodCommands=0;
728    // Set false if user does anything advanced
729    bool defaultSettings=true;
730
731    // Hidden stuff for barrier
732    int choleskyType = 0;
733    int gamma=0;
734    int scaleBarrier=0;
735    int doKKT=0;
736    int crossover=2; // do crossover unless quadratic
737    // For names
738    int lengthName = 0;
739    std::vector<std::string> rowNames;
740    std::vector<std::string> columnNames;
741   
742    std::string field;
743    if (!noPrinting) {
744      std::cout<<"Coin Cbc and Clp Solver version "<<CBCVERSION
745               <<", build "<<__DATE__<<std::endl;
746      // Print command line
747      if (argc>1) {
748        printf("command line - ");
749        for (int i=0;i<argc;i++)
750          printf("%s ",argv[i]);
751        printf("\n");
752      }
753    }
754    while (1) {
755      // next command
756      field=CoinReadGetCommand(argc,argv);
757      // exit if null or similar
758      if (!field.length()) {
759        if (numberGoodCommands==1&&goodModel) {
760          // we just had file name - do branch and bound
761          field="branch";
762        } else if (!numberGoodCommands) {
763          // let's give the sucker a hint
764          std::cout
765            <<"CoinSolver takes input from arguments ( - switches to stdin)"
766            <<std::endl
767            <<"Enter ? for list of commands or help"<<std::endl;
768          field="-";
769        } else {
770          break;
771        }
772      }
773     
774      // see if ? at end
775      int numberQuery=0;
776      if (field!="?"&&field!="???") {
777        int length = field.length();
778        int i;
779        for (i=length-1;i>0;i--) {
780          if (field[i]=='?') 
781            numberQuery++;
782          else
783            break;
784        }
785        field=field.substr(0,length-numberQuery);
786      }
787      // find out if valid command
788      int iParam;
789      int numberMatches=0;
790      int firstMatch=-1;
791      for ( iParam=0; iParam<numberParameters; iParam++ ) {
792        int match = parameters[iParam].matches(field);
793        if (match==1) {
794          numberMatches = 1;
795          firstMatch=iParam;
796          break;
797        } else {
798          if (match&&firstMatch<0)
799            firstMatch=iParam;
800          numberMatches += match>>1;
801        }
802      }
803      if (iParam<numberParameters&&!numberQuery) {
804        // found
805        CbcOrClpParam found = parameters[iParam];
806        CbcOrClpParameterType type = found.type();
807        int valid;
808        numberGoodCommands++;
809        if (type==BAB&&goodModel) {
810          // check if any integers
811          if (!lpSolver->integerInformation())
812            type=DUALSIMPLEX;
813        }
814        if (type==GENERALQUERY) {
815          bool evenHidden=false;
816          if ((verbose&8)!=0) {
817            // even hidden
818            evenHidden = true;
819            verbose &= ~8;
820          }
821#ifdef COIN_HAS_ASL
822          if (verbose<4&&usingAmpl)
823            verbose +=4;
824#endif
825          if (verbose<4) {
826            std::cout<<"In argument list keywords have leading - "
827              ", -stdin or just - switches to stdin"<<std::endl;
828            std::cout<<"One command per line (and no -)"<<std::endl;
829            std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
830            std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
831            std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
832            std::cout<<"abcd value sets value"<<std::endl;
833            std::cout<<"Commands are:"<<std::endl;
834          } else {
835            std::cout<<"Cbc options are set within AMPL with commands like:"<<std::endl<<std::endl;
836            std::cout<<"         option cbc_options \"cuts=root log=2 feas=on slog=1\""<<std::endl<<std::endl;
837            std::cout<<"only maximize, dual, primal, help and quit are recognized without ="<<std::endl;
838          }
839          int maxAcross=5;
840          if ((verbose%4)!=0)
841            maxAcross=1;
842          int limits[]={1,51,101,151,201,251,301,351,401};
843          std::vector<std::string> types;
844          types.push_back("Double parameters:");
845          types.push_back("Branch and Cut double parameters:");
846          types.push_back("Integer parameters:");
847          types.push_back("Branch and Cut integer parameters:");
848          types.push_back("Keyword parameters:");
849          types.push_back("Branch and Cut keyword parameters:");
850          types.push_back("Actions or string parameters:");
851          types.push_back("Branch and Cut actions:");
852          int iType;
853          for (iType=0;iType<8;iType++) {
854            int across=0;
855            if ((verbose%4)!=0)
856              std::cout<<std::endl;
857            std::cout<<types[iType]<<std::endl;
858            if ((verbose&2)!=0)
859              std::cout<<std::endl;
860            for ( iParam=0; iParam<numberParameters; iParam++ ) {
861              int type = parameters[iParam].type();
862              if ((parameters[iParam].displayThis()||evenHidden)&&
863                  type>=limits[iType]
864                  &&type<limits[iType+1]) {
865                // but skip if not useful for ampl (and in ampl mode)
866                if (verbose>=4&&(parameters[iParam].whereUsed()&4)==0)
867                  continue;
868                if (!across) {
869                  if ((verbose&2)==0) 
870                    std::cout<<"  ";
871                  else
872                    std::cout<<"Command ";
873                }
874                std::cout<<parameters[iParam].matchName()<<"  ";
875                across++;
876                if (across==maxAcross) {
877                  across=0;
878                  if ((verbose%4)!=0) {
879                    // put out description as well
880                    if ((verbose&1)!=0) 
881                      std::cout<<parameters[iParam].shortHelp();
882                    std::cout<<std::endl;
883                    if ((verbose&2)!=0) {
884                      std::cout<<"---- description"<<std::endl;
885                      parameters[iParam].printLongHelp();
886                      std::cout<<"----"<<std::endl<<std::endl;
887                    }
888                  } else {
889                    std::cout<<std::endl;
890                  }
891                }
892              }
893            }
894            if (across)
895              std::cout<<std::endl;
896          }
897        } else if (type==FULLGENERALQUERY) {
898          std::cout<<"Full list of commands is:"<<std::endl;
899          int maxAcross=5;
900          int limits[]={1,51,101,151,201,251,301,351,401};
901          std::vector<std::string> types;
902          types.push_back("Double parameters:");
903          types.push_back("Branch and Cut double parameters:");
904          types.push_back("Integer parameters:");
905          types.push_back("Branch and Cut integer parameters:");
906          types.push_back("Keyword parameters:");
907          types.push_back("Branch and Cut keyword parameters:");
908          types.push_back("Actions or string parameters:");
909          types.push_back("Branch and Cut actions:");
910          int iType;
911          for (iType=0;iType<8;iType++) {
912            int across=0;
913            std::cout<<types[iType]<<"  ";
914            for ( iParam=0; iParam<numberParameters; iParam++ ) {
915              int type = parameters[iParam].type();
916              if (type>=limits[iType]
917                  &&type<limits[iType+1]) {
918                if (!across)
919                  std::cout<<"  ";
920                std::cout<<parameters[iParam].matchName()<<"  ";
921                across++;
922                if (across==maxAcross) {
923                  std::cout<<std::endl;
924                  across=0;
925                }
926              }
927            }
928            if (across)
929              std::cout<<std::endl;
930          }
931        } else if (type<101) {
932          // get next field as double
933          double value = CoinReadGetDoubleField(argc,argv,&valid);
934          if (!valid) {
935            if (type<51) {
936              parameters[iParam].setDoubleParameter(lpSolver,value);
937            } else if (type<81) {
938              parameters[iParam].setDoubleParameter(model,value);
939            } else {
940              parameters[iParam].setDoubleParameter(lpSolver,value);
941              switch(type) {
942              case DJFIX:
943                djFix=value;
944                preSolve=5;
945                defaultSettings=false; // user knows what she is doing
946                break;
947              case GAPRATIO:
948                gapRatio=value;
949                break;
950              case TIGHTENFACTOR:
951                tightenFactor=value;
952                defaultSettings=false; // user knows what she is doing
953                break;
954              default:
955                abort();
956              }
957            }
958          } else if (valid==1) {
959            abort();
960          } else {
961            std::cout<<parameters[iParam].name()<<" has value "<<
962              parameters[iParam].doubleValue()<<std::endl;
963          }
964        } else if (type<201) {
965          // get next field as int
966          int value = CoinReadGetIntField(argc,argv,&valid);
967          if (!valid) {
968            if (type<151) {
969              if (parameters[iParam].type()==PRESOLVEPASS)
970                preSolve = value;
971              else if (parameters[iParam].type()==IDIOT)
972                doIdiot = value;
973              else if (parameters[iParam].type()==SPRINT)
974                doSprint = value;
975              else if (parameters[iParam].type()==OUTPUTFORMAT)
976                outputFormat = value;
977              else if (parameters[iParam].type()==SLPVALUE)
978                slpValue = value;
979              else if (parameters[iParam].type()==CPP)
980                cppValue = value;
981              else if (parameters[iParam].type()==PRESOLVEOPTIONS)
982                presolveOptions = value;
983              else if (parameters[iParam].type()==PRINTOPTIONS)
984                printOptions = value;
985              else if (parameters[iParam].type()==SUBSTITUTION)
986                substitution = value;
987              else if (parameters[iParam].type()==DUALIZE)
988                dualize = value;
989              else if (parameters[iParam].type()==CUTPASS)
990                cutPass = value;
991              else if (parameters[iParam].type()==VERBOSE)
992                verbose = value;
993              else if (parameters[iParam].type()==FPUMPITS)
994                { useFpump = true;parameters[iParam].setIntValue(value);}
995              parameters[iParam].setIntParameter(lpSolver,value);
996            } else {
997              parameters[iParam].setIntParameter(model,value);
998            }
999          } else if (valid==1) {
1000            abort();
1001          } else {
1002            std::cout<<parameters[iParam].name()<<" has value "<<
1003              parameters[iParam].intValue()<<std::endl;
1004          }
1005        } else if (type<301) {
1006          // one of several strings
1007          std::string value = CoinReadGetString(argc,argv);
1008          int action = parameters[iParam].parameterOption(value);
1009          if (action<0) {
1010            if (value!="EOL") {
1011              // no match
1012              parameters[iParam].printOptions();
1013            } else {
1014              // print current value
1015              std::cout<<parameters[iParam].name()<<" has value "<<
1016                parameters[iParam].currentOption()<<std::endl;
1017            }
1018          } else {
1019            parameters[iParam].setCurrentOption(action,!noPrinting);
1020            // for now hard wired
1021            switch (type) {
1022            case DIRECTION:
1023              if (action==0)
1024                lpSolver->setOptimizationDirection(1);
1025              else if (action==1)
1026                lpSolver->setOptimizationDirection(-1);
1027              else
1028                lpSolver->setOptimizationDirection(0);
1029              break;
1030            case DUALPIVOT:
1031              if (action==0) {
1032                ClpDualRowSteepest steep(3);
1033                lpSolver->setDualRowPivotAlgorithm(steep);
1034              } else if (action==1) {
1035                //ClpDualRowDantzig dantzig;
1036                ClpDualRowSteepest dantzig(5);
1037                lpSolver->setDualRowPivotAlgorithm(dantzig);
1038              } else if (action==2) {
1039                // partial steep
1040                ClpDualRowSteepest steep(2);
1041                lpSolver->setDualRowPivotAlgorithm(steep);
1042              } else {
1043                ClpDualRowSteepest steep;
1044                lpSolver->setDualRowPivotAlgorithm(steep);
1045              }
1046              break;
1047            case PRIMALPIVOT:
1048              if (action==0) {
1049                ClpPrimalColumnSteepest steep(3);
1050                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1051              } else if (action==1) {
1052                ClpPrimalColumnSteepest steep(0);
1053                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1054              } else if (action==2) {
1055                ClpPrimalColumnDantzig dantzig;
1056                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
1057              } else if (action==3) {
1058                ClpPrimalColumnSteepest steep(2);
1059                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1060              } else if (action==4) {
1061                ClpPrimalColumnSteepest steep(1);
1062                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1063              } else if (action==5) {
1064                ClpPrimalColumnSteepest steep(4);
1065                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1066              } else if (action==6) {
1067                ClpPrimalColumnSteepest steep(10);
1068                lpSolver->setPrimalColumnPivotAlgorithm(steep);
1069              }
1070              break;
1071            case SCALING:
1072              lpSolver->scaling(action);
1073              solver->setHintParam(OsiDoScale,action!=0,OsiHintTry);
1074              doScaling = 1-action;
1075              break;
1076            case AUTOSCALE:
1077              lpSolver->setAutomaticScaling(action!=0);
1078              break;
1079            case SPARSEFACTOR:
1080              lpSolver->setSparseFactorization((1-action)!=0);
1081              break;
1082            case BIASLU:
1083              lpSolver->factorization()->setBiasLU(action);
1084              break;
1085            case PERTURBATION:
1086              if (action==0)
1087                lpSolver->setPerturbation(50);
1088              else
1089                lpSolver->setPerturbation(100);
1090              break;
1091            case ERRORSALLOWED:
1092              allowImportErrors = action;
1093              break;
1094            case INTPRINT:
1095              printMode=action;
1096              break;
1097              //case ALGORITHM:
1098              //algorithm  = action;
1099              //defaultSettings=false; // user knows what she is doing
1100              //abort();
1101              //break;
1102            case KEEPNAMES:
1103              keepImportNames = 1-action;
1104              break;
1105            case PRESOLVE:
1106              if (action==0)
1107                preSolve = 5;
1108              else if (action==1)
1109                preSolve=0;
1110              else if (action==2)
1111                preSolve=10;
1112              else
1113                preSolveFile=true;
1114              break;
1115            case PFI:
1116              lpSolver->factorization()->setForrestTomlin(action==0);
1117              break;
1118            case CRASH:
1119              doCrash=action;
1120              break;
1121            case MESSAGES:
1122              lpSolver->messageHandler()->setPrefix(action!=0);
1123              break;
1124            case CHOLESKY:
1125              choleskyType = action;
1126              break;
1127            case GAMMA:
1128              gamma=action;
1129              break;
1130            case BARRIERSCALE:
1131              scaleBarrier=action;
1132              break;
1133            case KKT:
1134              doKKT=action;
1135              break;
1136            case CROSSOVER:
1137              crossover=action;
1138              break;
1139            case SOS:
1140              doSOS=action;
1141              break;
1142            case GOMORYCUTS:
1143              defaultSettings=false; // user knows what she is doing
1144              gomoryAction = action;
1145              break;
1146            case PROBINGCUTS:
1147              defaultSettings=false; // user knows what she is doing
1148              probingAction = action;
1149              break;
1150            case KNAPSACKCUTS:
1151              defaultSettings=false; // user knows what she is doing
1152              knapsackAction = action;
1153              break;
1154            case REDSPLITCUTS:
1155              defaultSettings=false; // user knows what she is doing
1156              redsplitAction = action;
1157              break;
1158            case CLIQUECUTS:
1159              defaultSettings=false; // user knows what she is doing
1160              cliqueAction = action;
1161              break;
1162            case FLOWCUTS:
1163              defaultSettings=false; // user knows what she is doing
1164              flowAction = action;
1165              break;
1166            case MIXEDCUTS:
1167              defaultSettings=false; // user knows what she is doing
1168              mixedAction = action;
1169              break;
1170            case TWOMIRCUTS:
1171              defaultSettings=false; // user knows what she is doing
1172              twomirAction = action;
1173              break;
1174            case ROUNDING:
1175              defaultSettings=false; // user knows what she is doing
1176              useRounding = action;
1177              break;
1178            case FPUMP:
1179              defaultSettings=false; // user knows what she is doing
1180              useFpump=action;
1181              break;
1182            case CUTSSTRATEGY:
1183              gomoryAction = action;
1184              probingAction = action;
1185              knapsackAction = action;
1186              cliqueAction = action;
1187              flowAction = action;
1188              mixedAction = action;
1189              twomirAction = action;
1190              parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption(action);
1191              parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption(action);
1192              parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption(action);
1193              if (!action) {
1194                redsplitAction = action;
1195                parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption(action);
1196              }
1197              parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption(action);
1198              parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption(action);
1199              parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption(action);
1200              parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption(action);
1201              break;
1202            case HEURISTICSTRATEGY:
1203              useRounding = action;
1204              useGreedy = action;
1205              useCombine = action;
1206              //useLocalTree = action;
1207              useFpump=action;
1208              parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption(action);
1209              parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption(action);
1210              parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption(action);
1211              //parameters[whichParam(LOCALTREE,numberParameters,parameters)].setCurrentOption(action);
1212              parameters[whichParam(FPUMP,numberParameters,parameters)].setCurrentOption(action);
1213              break;
1214            case GREEDY:
1215              defaultSettings=false; // user knows what she is doing
1216              useGreedy = action;
1217              break;
1218            case COMBINE:
1219              defaultSettings=false; // user knows what she is doing
1220              useCombine = action;
1221              break;
1222            case LOCALTREE:
1223              defaultSettings=false; // user knows what she is doing
1224              useLocalTree = action;
1225              break;
1226            case COSTSTRATEGY:
1227              useCosts=action;
1228              break;
1229            case PREPROCESS:
1230              preProcess = action;
1231              break;
1232            case USESOLUTION:
1233              useSolution = action;
1234              break;
1235            default:
1236              abort();
1237            }
1238          }
1239        } else {
1240          // action
1241          if (type==EXIT) {
1242#ifdef COIN_HAS_ASL
1243            if(usingAmpl) {
1244              if (info.numberIntegers||info.numberBinary) {
1245                // integer
1246              } else {
1247                // linear
1248              }
1249              writeAmpl(&info);
1250              freeArrays2(&info);
1251              freeArgs(&info);
1252            }
1253#endif
1254            break; // stop all
1255          }
1256          switch (type) {
1257          case DUALSIMPLEX:
1258          case PRIMALSIMPLEX:
1259          case SOLVECONTINUOUS:
1260          case BARRIER:
1261            if (goodModel) {
1262              double objScale = 
1263                parameters[whichParam(OBJSCALE2,numberParameters,parameters)].doubleValue();
1264              if (objScale!=1.0) {
1265                int iColumn;
1266                int numberColumns=lpSolver->numberColumns();
1267                double * dualColumnSolution = 
1268                  lpSolver->dualColumnSolution();
1269                ClpObjective * obj = lpSolver->objectiveAsObject();
1270                assert(dynamic_cast<ClpLinearObjective *> (obj));
1271                double offset;
1272                double * objective = obj->gradient(NULL,NULL,offset,true);
1273                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1274                  dualColumnSolution[iColumn] *= objScale;
1275                  objective[iColumn] *= objScale;;
1276                }
1277                int iRow;
1278                int numberRows=lpSolver->numberRows();
1279                double * dualRowSolution = 
1280                  lpSolver->dualRowSolution();
1281                for (iRow=0;iRow<numberRows;iRow++) 
1282                  dualRowSolution[iRow] *= objScale;
1283                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
1284              }
1285              ClpSolve::SolveType method;
1286              ClpSolve::PresolveType presolveType;
1287              ClpSimplex * model2 = lpSolver;
1288              if (dualize) {
1289                model2 = ((ClpSimplexOther *) model2)->dualOfModel();
1290                printf("Dual of model has %d rows and %d columns\n",
1291                       model2->numberRows(),model2->numberColumns());
1292                model2->setOptimizationDirection(1.0);
1293              }
1294              if (noPrinting)
1295                lpSolver->setLogLevel(0);
1296              ClpSolve solveOptions;
1297              solveOptions.setPresolveActions(presolveOptions);
1298              solveOptions.setSubstitution(substitution);
1299              if (preSolve!=5&&preSolve) {
1300                presolveType=ClpSolve::presolveNumber;
1301                if (preSolve<0) {
1302                  preSolve = - preSolve;
1303                  if (preSolve<=100) {
1304                    presolveType=ClpSolve::presolveNumber;
1305                    printf("Doing %d presolve passes - picking up non-costed slacks\n",
1306                           preSolve);
1307                    solveOptions.setDoSingletonColumn(true);
1308                  } else {
1309                    preSolve -=100;
1310                    presolveType=ClpSolve::presolveNumberCost;
1311                    printf("Doing %d presolve passes - picking up costed slacks\n",
1312                           preSolve);
1313                  }
1314                } 
1315              } else if (preSolve) {
1316                presolveType=ClpSolve::presolveOn;
1317              } else {
1318                presolveType=ClpSolve::presolveOff;
1319              }
1320              solveOptions.setPresolveType(presolveType,preSolve);
1321              if (type==DUALSIMPLEX||type==SOLVECONTINUOUS) {
1322                method=ClpSolve::useDual;
1323              } else if (type==PRIMALSIMPLEX) {
1324                method=ClpSolve::usePrimalorSprint;
1325              } else {
1326                method = ClpSolve::useBarrier;
1327                if (crossover==1) {
1328                  method=ClpSolve::useBarrierNoCross;
1329                } else if (crossover==2) {
1330                  ClpObjective * obj = lpSolver->objectiveAsObject();
1331                  if (obj->type()>1) {
1332                    method=ClpSolve::useBarrierNoCross;
1333                    presolveType=ClpSolve::presolveOff;
1334                    solveOptions.setPresolveType(presolveType,preSolve);
1335                  } 
1336                }
1337              }
1338              solveOptions.setSolveType(method);
1339              if(preSolveFile)
1340                presolveOptions |= 0x40000000;
1341              solveOptions.setSpecialOption(4,presolveOptions);
1342              solveOptions.setSpecialOption(5,printOptions);
1343              if (method==ClpSolve::useDual) {
1344                // dual
1345                if (doCrash)
1346                  solveOptions.setSpecialOption(0,1,doCrash); // crash
1347                else if (doIdiot)
1348                  solveOptions.setSpecialOption(0,2,doIdiot); // possible idiot
1349              } else if (method==ClpSolve::usePrimalorSprint) {
1350                // primal
1351                // if slp turn everything off
1352                if (slpValue>0) {
1353                  doCrash=false;
1354                  doSprint=0;
1355                  doIdiot=-1;
1356                  solveOptions.setSpecialOption(1,10,slpValue); // slp
1357                  method=ClpSolve::usePrimal;
1358                }
1359                if (doCrash) {
1360                  solveOptions.setSpecialOption(1,1,doCrash); // crash
1361                } else if (doSprint>0) {
1362                  // sprint overrides idiot
1363                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
1364                } else if (doIdiot>0) {
1365                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
1366                } else if (slpValue<=0) {
1367                  if (doIdiot==0) {
1368                    if (doSprint==0)
1369                      solveOptions.setSpecialOption(1,4); // all slack
1370                    else
1371                      solveOptions.setSpecialOption(1,9); // all slack or sprint
1372                  } else {
1373                    if (doSprint==0)
1374                      solveOptions.setSpecialOption(1,8); // all slack or idiot
1375                    else
1376                      solveOptions.setSpecialOption(1,7); // initiative
1377                  }
1378                }
1379                if (basisHasValues==-1)
1380                  solveOptions.setSpecialOption(1,11); // switch off values
1381              } else if (method==ClpSolve::useBarrier||method==ClpSolve::useBarrierNoCross) {
1382                int barrierOptions = choleskyType;
1383                if (scaleBarrier)
1384                  barrierOptions |= 8;
1385                if (doKKT)
1386                  barrierOptions |= 16;
1387                if (gamma)
1388                  barrierOptions |= 32*gamma;
1389                if (crossover==3) 
1390                  barrierOptions |= 256; // try presolve in crossover
1391                solveOptions.setSpecialOption(4,barrierOptions);
1392              }
1393              model2->initialSolve(solveOptions);
1394              basisHasValues=1;
1395              if (dualize) {
1396                ((ClpSimplexOther *) lpSolver)->restoreFromDual(model2);
1397                delete model2;
1398                model2=lpSolver;
1399              }
1400#ifdef COIN_HAS_ASL
1401              if (usingAmpl) {
1402                double value = model2->getObjValue()*model2->getObjSense();
1403                char buf[300];
1404                int pos=0;
1405                int iStat = model2->status();
1406                if (iStat==0) {
1407                  pos += sprintf(buf+pos,"optimal," );
1408                } else if (iStat==1) {
1409                  // infeasible
1410                  pos += sprintf(buf+pos,"infeasible,");
1411                } else if (iStat==2) {
1412                  // unbounded
1413                  pos += sprintf(buf+pos,"unbounded,");
1414                } else if (iStat==3) {
1415                  pos += sprintf(buf+pos,"stopped on iterations or time,");
1416                } else if (iStat==4) {
1417                  iStat = 7;
1418                  pos += sprintf(buf+pos,"stopped on difficulties,");
1419                } else if (iStat==5) {
1420                  iStat = 3;
1421                  pos += sprintf(buf+pos,"stopped on ctrl-c,");
1422                } else {
1423                  pos += sprintf(buf+pos,"status unknown,");
1424                  iStat=6;
1425                }
1426                info.problemStatus=iStat;
1427                info.objValue = value;
1428                pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
1429                               value);
1430                sprintf(buf+pos,"\n%d iterations",
1431                        model2->getIterationCount());
1432                free(info.primalSolution);
1433                int numberColumns=model2->numberColumns();
1434                info.primalSolution = (double *) malloc(numberColumns*sizeof(double));
1435                CoinCopyN(model2->primalColumnSolution(),numberColumns,info.primalSolution);
1436                int numberRows = model2->numberRows();
1437                free(info.dualSolution);
1438                info.dualSolution = (double *) malloc(numberRows*sizeof(double));
1439                CoinCopyN(model2->dualRowSolution(),numberRows,info.dualSolution);
1440                CoinWarmStartBasis * basis = model2->getBasis();
1441                free(info.rowStatus);
1442                info.rowStatus = (int *) malloc(numberRows*sizeof(int));
1443                free(info.columnStatus);
1444                info.columnStatus = (int *) malloc(numberColumns*sizeof(int));
1445                // Put basis in
1446                int i;
1447                // free,basic,ub,lb are 0,1,2,3
1448                for (i=0;i<numberRows;i++) {
1449                  CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
1450                  info.rowStatus[i]=status;
1451                }
1452                for (i=0;i<numberColumns;i++) {
1453                  CoinWarmStartBasis::Status status = basis->getStructStatus(i);
1454                  info.columnStatus[i]=status;
1455                }
1456                // put buffer into info
1457                strcpy(info.buffer,buf);
1458                delete basis;
1459              }
1460#endif
1461            } else {
1462              std::cout<<"** Current model not valid"<<std::endl;
1463            }
1464            break;
1465          case STATISTICS:
1466            if (goodModel) {
1467              // If presolve on look at presolved
1468              bool deleteModel2=false;
1469              ClpSimplex * model2 = lpSolver;
1470              if (preSolve) {
1471                ClpPresolve pinfo;
1472                int presolveOptions2 = presolveOptions&~0x40000000;
1473                if ((presolveOptions2&0xffff)!=0)
1474                  pinfo.setPresolveActions(presolveOptions2);
1475                pinfo.setSubstitution(substitution);
1476                if ((printOptions&1)!=0)
1477                  pinfo.statistics();
1478                double presolveTolerance = 
1479                  parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
1480                model2 = 
1481                  pinfo.presolvedModel(*lpSolver,presolveTolerance,
1482                                       true,preSolve);
1483                if (model2) {
1484                  printf("Statistics for presolved model\n");
1485                  deleteModel2=true;
1486                } else {
1487                  printf("Presolved model looks infeasible - will use unpresolved\n");
1488                  model2 = lpSolver;
1489                }
1490              } else {
1491                printf("Statistics for unpresolved model\n");
1492                model2 =  lpSolver;
1493              }
1494              statistics(lpSolver,model2);
1495              if (deleteModel2)
1496                delete model2;
1497            } else {
1498              std::cout<<"** Current model not valid"<<std::endl;
1499            }
1500            break;
1501          case TIGHTEN:
1502            if (goodModel) {
1503              int numberInfeasibilities = lpSolver->tightenPrimalBounds();
1504              if (numberInfeasibilities)
1505                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
1506            } else {
1507              std::cout<<"** Current model not valid"<<std::endl;
1508            }
1509            break;
1510          case PLUSMINUS:
1511            if (goodModel) {
1512              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1513              ClpPackedMatrix* clpMatrix =
1514                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1515              if (clpMatrix) {
1516                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
1517                if (newMatrix->getIndices()) {
1518                  lpSolver->replaceMatrix(newMatrix);
1519                  delete saveMatrix;
1520                  std::cout<<"Matrix converted to +- one matrix"<<std::endl;
1521                } else {
1522                  std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
1523                }
1524              } else {
1525                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1526              }
1527            } else {
1528              std::cout<<"** Current model not valid"<<std::endl;
1529            }
1530            break;
1531          case OUTDUPROWS:
1532            if (goodModel) {
1533              int nOut = outDupRow(clpSolver);
1534              if (nOut&&!noPrinting)
1535                printf("%d rows eliminated\n",nOut);
1536            } else {
1537              std::cout<<"** Current model not valid"<<std::endl;
1538            }
1539            break;
1540          case NETWORK:
1541            if (goodModel) {
1542              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1543              ClpPackedMatrix* clpMatrix =
1544                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1545              if (clpMatrix) {
1546                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
1547                if (newMatrix->getIndices()) {
1548                  lpSolver->replaceMatrix(newMatrix);
1549                  delete saveMatrix;
1550                  std::cout<<"Matrix converted to network matrix"<<std::endl;
1551                } else {
1552                  std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
1553                }
1554              } else {
1555                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1556              }
1557            } else {
1558              std::cout<<"** Current model not valid"<<std::endl;
1559            }
1560            break;
1561          case MIPLIB:
1562            // User can set options - main differenec is lack of model and CglPreProcess
1563            goodModel=true;
1564/*
1565  Run branch-and-cut. First set a few options -- node comparison, scaling. If
1566  the solver is Clp, consider running some presolve code (not yet converted
1567  this to generic OSI) with branch-and-cut. If presolve is disabled, or the
1568  solver is not Clp, simply run branch-and-cut. Print elapsed time at the end.
1569*/
1570          case BAB: // branchAndBound
1571          case STRENGTHEN:
1572            if (goodModel) {
1573              bool miplib = type==MIPLIB;
1574              int logLevel = parameters[slog].intValue();
1575              // Reduce printout
1576              if (logLevel<=1)
1577                model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
1578              // Don't switch off all output
1579              {
1580                OsiSolverInterface * solver = model.solver();
1581                OsiClpSolverInterface * si =
1582                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1583                assert (si != NULL);
1584                si->setSpecialOptions(0x40000000);
1585              }
1586              if (!miplib) {
1587                model.initialSolve();
1588                OsiSolverInterface * solver = model.solver();
1589                OsiClpSolverInterface * si =
1590                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1591                if (si->getModelPtr()->tightenPrimalBounds()!=0) {
1592                  std::cout<<"Problem is infeasible - tightenPrimalBounds!"<<std::endl;
1593                  exit(1);
1594                }
1595                si->getModelPtr()->dual();  // clean up
1596              }
1597              // If user made settings then use them
1598              if (!defaultSettings) {
1599                OsiSolverInterface * solver = model.solver();
1600                if (!doScaling)
1601                  solver->setHintParam(OsiDoScale,false,OsiHintTry);
1602                OsiClpSolverInterface * si =
1603                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1604                assert (si != NULL);
1605                // get clp itself
1606                ClpSimplex * modelC = si->getModelPtr();
1607                //if (modelC->tightenPrimalBounds()!=0) {
1608                //std::cout<<"Problem is infeasible!"<<std::endl;
1609                //break;
1610                //}
1611                // bounds based on continuous
1612                if (tightenFactor) {
1613                  if (modelC->tightenPrimalBounds(tightenFactor)!=0) {
1614                    std::cout<<"Problem is infeasible!"<<std::endl;
1615                    break;
1616                  }
1617                }
1618                if (djFix<1.0e20) {
1619                  // do some fixing
1620                  int numberColumns = modelC->numberColumns();
1621                  int i;
1622                  const char * type = modelC->integerInformation();
1623                  double * lower = modelC->columnLower();
1624                  double * upper = modelC->columnUpper();
1625                  double * solution = modelC->primalColumnSolution();
1626                  double * dj = modelC->dualColumnSolution();
1627                  int numberFixed=0;
1628                  for (i=0;i<numberColumns;i++) {
1629                    if (type[i]) {
1630                      double value = solution[i];
1631                      if (value<lower[i]+1.0e-5&&dj[i]>djFix) {
1632                        solution[i]=lower[i];
1633                        upper[i]=lower[i];
1634                        numberFixed++;
1635                      } else if (value>upper[i]-1.0e-5&&dj[i]<-djFix) {
1636                        solution[i]=upper[i];
1637                        lower[i]=upper[i];
1638                        numberFixed++;
1639                      }
1640                    }
1641                  }
1642                  printf("%d columns fixed\n",numberFixed);
1643                }
1644              }
1645              // See if we want preprocessing
1646              OsiSolverInterface * saveSolver=NULL;
1647              CglPreProcess process;
1648              delete babModel;
1649              babModel = new CbcModel(model);
1650              OsiSolverInterface * solver3 = clpSolver->clone();
1651              babModel->assignSolver(solver3);
1652              OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1653              int numberChanged=0;
1654              if (clpSolver2->messageHandler()->logLevel())
1655                clpSolver2->messageHandler()->setLogLevel(1);
1656              if (logLevel>-1)
1657                clpSolver2->messageHandler()->setLogLevel(logLevel);
1658              lpSolver = clpSolver2->getModelPtr();
1659              if (lpSolver->factorizationFrequency()==200&&!miplib) {
1660                // User did not touch preset
1661                int numberRows = lpSolver->numberRows();
1662                const int cutoff1=10000;
1663                const int cutoff2=100000;
1664                const int base=75;
1665                const int freq0 = 50;
1666                const int freq1=200;
1667                const int freq2=400;
1668                const int maximum=1000;
1669                int frequency;
1670                if (numberRows<cutoff1)
1671                  frequency=base+numberRows/freq0;
1672                else if (numberRows<cutoff2)
1673                  frequency=base+cutoff1/freq0 + (numberRows-cutoff1)/freq1;
1674                else
1675                  frequency=base+cutoff1/freq0 + (cutoff2-cutoff1)/freq1 + (numberRows-cutoff2)/freq2;
1676                lpSolver->setFactorizationFrequency(CoinMin(maximum,frequency));
1677              }
1678              time2 = CoinCpuTime();
1679              totalTime += time2-time1;
1680              time1 = time2;
1681              double timeLeft = babModel->getMaximumSeconds();
1682              int numberOriginalColumns = babModel->solver()->getNumCols();
1683#ifdef COIN_HAS_ASL
1684              if (usingAmpl&&info.numberSos&&doSOS) {
1685                // SOS
1686                assert (!preProcess); // do later
1687                int numberSOS = info.numberSos;
1688                int numberIntegers = babModel->numberIntegers();
1689                int numberColumns = babModel->getNumCols();
1690                /* model may not have created objects
1691                   If none then create
1692                */
1693                if (!numberIntegers||!babModel->numberObjects()) {
1694                  int type = (pseudoUp) ? 1 : 0;
1695                  babModel->findIntegers(true,type);
1696                  numberIntegers = babModel->numberIntegers();
1697                }
1698                // Do sets and priorities
1699                CbcObject ** objects = new CbcObject * [numberSOS];
1700                const int * starts = info.sosStart;
1701                const int * which = info.sosIndices;
1702                const char * type = info.sosType;
1703                const double * weight = info.sosReference;
1704                // see if any priorities
1705                int i;
1706                bool gotPriorities=false;
1707                int * priorities=info.priorities;
1708                if (priorities) {
1709                  for (i=0;i<numberColumns;i++) {
1710                    if (priorities[i]) {
1711                      gotPriorities=true;
1712                      break;
1713                    }
1714                  }
1715                }
1716                priorities=info.sosPriority;
1717                if (priorities) {
1718                  for (i=0;i<numberSOS;i++) {
1719                    if (priorities[i]) {
1720                      gotPriorities=true;
1721                      break;
1722                    }
1723                  }
1724                }
1725                int iSOS;
1726                for (iSOS =0;iSOS<numberSOS;iSOS++) {
1727                  int iStart = starts[iSOS];
1728                  int n=starts[iSOS+1]-iStart;
1729                  objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
1730                                             iSOS,type[iSOS]);
1731                  // higher for set
1732                  objects[iSOS]->setPriority(10);
1733                  if (gotPriorities&&info.sosPriority&&info.sosPriority[iSOS])
1734                    objects[iSOS]->setPriority(info.sosPriority[iSOS]);
1735                }
1736                babModel->addObjects(numberSOS,objects);
1737                for (iSOS=0;iSOS<numberSOS;iSOS++)
1738                  delete objects[iSOS];
1739                delete [] objects;
1740              }
1741#endif
1742              if (preProcess==6) {
1743                // use strategy instead
1744                preProcess=0;
1745                useStrategy=true;
1746              }
1747              if (preProcess&&type==BAB) {
1748                saveSolver=babModel->solver()->clone();
1749                /* Do not try and produce equality cliques and
1750                   do up to 10 passes */
1751                OsiSolverInterface * solver2;
1752                {
1753                  // Tell solver we are in Branch and Cut
1754                  saveSolver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
1755                  // Default set of cut generators
1756                  CglProbing generator1;
1757                  generator1.setUsingObjective(true);
1758                  generator1.setMaxPass(3);
1759                  generator1.setMaxProbeRoot(saveSolver->getNumCols());
1760                  generator1.setMaxElements(100);
1761                  generator1.setMaxLookRoot(50);
1762                  generator1.setRowCuts(3);
1763                  // Add in generators
1764                  process.addCutGenerator(&generator1);
1765                  int translate[]={9999,0,0,-1,2,3};
1766                  process.messageHandler()->setLogLevel(babModel->logLevel());
1767                  solver2 = process.preProcessNonDefault(*saveSolver,translate[preProcess],10);
1768                  // Tell solver we are not in Branch and Cut
1769                  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
1770                  if (solver2)
1771                    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
1772                }
1773#ifdef COIN_HAS_ASL
1774                if (!solver2&&usingAmpl) {
1775                  // infeasible
1776                  info.problemStatus=1;
1777                  info.objValue = 1.0e100;
1778                  sprintf(info.buffer,"infeasible by pre-processing");
1779                  info.primalSolution=NULL;
1780                  info.dualSolution=NULL;
1781                  break;
1782                }
1783#endif
1784                if (!noPrinting) {
1785                  if (!solver2) {
1786                    printf("Pre-processing says infeasible\n");
1787                    break;
1788                  } else {
1789                    printf("processed model has %d rows, %d columns and %d elements\n",
1790                           solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
1791                  }
1792                }
1793                //solver2->resolve();
1794                if (preProcess==2) {
1795                  OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
1796                  ClpSimplex * lpSolver = clpSolver2->getModelPtr();
1797                  lpSolver->writeMps("presolved.mps",0,1,lpSolver->optimizationDirection());
1798                  printf("Preprocessed model (minimization) on presolved.mps\n");
1799                }
1800                // we have to keep solver2 so pass clone
1801                solver2 = solver2->clone();
1802                babModel->assignSolver(solver2);
1803                babModel->initialSolve();
1804                babModel->setMaximumSeconds(timeLeft-(CoinCpuTime()-time1));
1805              }
1806              // now tighten bounds
1807              if (!miplib) {
1808                OsiClpSolverInterface * si =
1809                  dynamic_cast<OsiClpSolverInterface *>(babModel->solver()) ;
1810                assert (si != NULL);
1811                // get clp itself
1812                ClpSimplex * modelC = si->getModelPtr();
1813                if (noPrinting)
1814                  modelC->setLogLevel(0);
1815                if (modelC->tightenPrimalBounds()!=0) {
1816                  std::cout<<"Problem is infeasible!"<<std::endl;
1817                  break;
1818                }
1819                modelC->dual();
1820              }
1821              if (debugValues) {
1822                // for debug
1823                std::string problemName ;
1824                babModel->solver()->getStrParam(OsiProbName,problemName) ;
1825                //babModel->solver()->activateRowCutDebugger(problemName.c_str()) ;
1826                twomirGen.probname_=strdup(problemName.c_str());
1827                // checking seems odd
1828                //redsplitGen.set_given_optsol(babModel->solver()->getRowCutDebuggerAlways()->optimalSolution(),
1829                //                         babModel->getNumCols());
1830              }
1831              if (useCosts) {
1832                int numberColumns = babModel->getNumCols();
1833                int * sort = new int[numberColumns];
1834                double * dsort = new double[numberColumns];
1835                int * priority = new int [numberColumns];
1836                const double * objective = babModel->getObjCoefficients();
1837                int iColumn;
1838                int n=0;
1839                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1840                  if (babModel->isInteger(iColumn)) {
1841                    sort[n]=n;
1842                    if (useCosts==1)
1843                      dsort[n++]=-objective[iColumn];
1844                    else
1845                      dsort[n++]=iColumn;
1846                  }
1847                }
1848                CoinSort_2(dsort,dsort+n,sort);
1849                int level=0;
1850                double last = -1.0e100;
1851                for (int i=0;i<n;i++) {
1852                  int iPut=sort[i];
1853                  if (dsort[i]!=last) {
1854                    level++;
1855                    last=dsort[i];
1856                  }
1857                  priority[iPut]=level;
1858                }
1859                babModel->passInPriorities( priority,false);
1860                delete [] priority;
1861                delete [] sort;
1862                delete [] dsort;
1863              }
1864              // FPump done first as it only works if no solution
1865              CbcHeuristicFPump heuristic4(*babModel);
1866              if (useFpump) {
1867                heuristic4.setMaximumPasses(parameters[whichParam(FPUMPITS,numberParameters,parameters)].intValue());
1868                babModel->addHeuristic(&heuristic4);
1869              }
1870              if (!miplib) {
1871                CbcRounding heuristic1(*babModel);
1872                if (useRounding)
1873                  babModel->addHeuristic(&heuristic1) ;
1874                CbcHeuristicLocal heuristic2(*babModel);
1875                heuristic2.setSearchType(1);
1876                if (useCombine)
1877                  babModel->addHeuristic(&heuristic2);
1878                CbcHeuristicGreedyCover heuristic3(*babModel);
1879                CbcHeuristicGreedyEquality heuristic3a(*babModel);
1880                if (useGreedy) {
1881                  babModel->addHeuristic(&heuristic3);
1882                  babModel->addHeuristic(&heuristic3a);
1883                }
1884                if (useLocalTree) {
1885                  CbcTreeLocal localTree(babModel,NULL,10,0,0,10000,2000);
1886                  babModel->passInTreeHandler(localTree);
1887                }
1888              }
1889              // add cut generators if wanted
1890              int switches[20];
1891              int numberGenerators=0;
1892              if (probingAction==1) {
1893                babModel->addCutGenerator(&probingGen,-1,"Probing");
1894                switches[numberGenerators++]=0;
1895              } else if (probingAction>=2) {
1896                babModel->addCutGenerator(&probingGen,-101+probingAction,"Probing");
1897                switches[numberGenerators++]=0;
1898              }
1899              if (gomoryAction==1) {
1900                babModel->addCutGenerator(&gomoryGen,-1,"Gomory");
1901                switches[numberGenerators++]=1;
1902              } else if (gomoryAction>=2) {
1903                babModel->addCutGenerator(&gomoryGen,-101+gomoryAction,"Gomory");
1904                switches[numberGenerators++]=-1;
1905              }
1906              if (knapsackAction==1) {
1907                babModel->addCutGenerator(&knapsackGen,-1,"Knapsack");
1908                switches[numberGenerators++]=0;
1909              } else if (knapsackAction>=2) {
1910                babModel->addCutGenerator(&knapsackGen,-101+knapsackAction,"Knapsack");
1911                switches[numberGenerators++]=0;
1912              }
1913              if (redsplitAction==1) {
1914                babModel->addCutGenerator(&redsplitGen,-1,"Reduce-and-split");
1915                switches[numberGenerators++]=1;
1916              } else if (redsplitAction>=2) {
1917                babModel->addCutGenerator(&redsplitGen,-101+redsplitAction,"Reduce-and-split");
1918                switches[numberGenerators++]=1;
1919              }
1920              if (cliqueAction==1) {
1921                babModel->addCutGenerator(&cliqueGen,-1,"Clique");
1922                switches[numberGenerators++]=1;
1923              } else if (cliqueAction>=2) {
1924                babModel->addCutGenerator(&cliqueGen,-101+cliqueAction,"Clique");
1925                switches[numberGenerators++]=-1;
1926              }
1927              if (mixedAction==1) {
1928                babModel->addCutGenerator(&mixedGen,-1,"MixedIntegerRounding2");
1929                switches[numberGenerators++]=1;
1930              } else if (mixedAction>=2) {
1931                babModel->addCutGenerator(&mixedGen,-101+mixedAction,"MixedIntegerRounding2");
1932                switches[numberGenerators++]=-1;
1933              }
1934              if (flowAction==1) {
1935                babModel->addCutGenerator(&flowGen,-1,"FlowCover");
1936                switches[numberGenerators++]=1;
1937              } else if (flowAction>=2) {
1938                babModel->addCutGenerator(&flowGen,-101+flowAction,"FlowCover");
1939                switches[numberGenerators++]=1;
1940              }
1941              if (twomirAction==1) {
1942                babModel->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
1943                switches[numberGenerators++]=1;
1944              } else if (twomirAction>=2) {
1945                babModel->addCutGenerator(&twomirGen,-101+twomirAction,"TwoMirCuts");
1946                switches[numberGenerators++]=1;
1947              }
1948              // Say we want timings
1949              numberGenerators = babModel->numberCutGenerators();
1950              int iGenerator;
1951              int cutDepth=
1952                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
1953              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1954                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1955                int howOften = generator->howOften();
1956                if (howOften==-98||howOften==-99) 
1957                  generator->setSwitchOffIfLessThan(switches[iGenerator]);
1958                generator->setTiming(true);
1959                if (cutDepth>=0)
1960                  generator->setWhatDepth(cutDepth) ;
1961              }
1962              // Could tune more
1963              if (!miplib) {
1964                babModel->setMinimumDrop(min(5.0e-2,
1965                                             fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
1966                if (cutPass==-1234567) {
1967                  if (babModel->getNumCols()<500)
1968                    babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
1969                  else if (babModel->getNumCols()<5000)
1970                    babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
1971                  else
1972                    babModel->setMaximumCutPassesAtRoot(20);
1973                } else {
1974                  babModel->setMaximumCutPassesAtRoot(cutPass);
1975                }
1976                babModel->setMaximumCutPasses(1);
1977              }
1978              // Do more strong branching if small
1979              //if (babModel->getNumCols()<5000)
1980              //babModel->setNumberStrong(20);
1981              // Switch off strong branching if wanted
1982              //if (babModel->getNumCols()>10*babModel->getNumRows())
1983              //babModel->setNumberStrong(0);
1984              if (!noPrinting) {
1985                babModel->messageHandler()->setLogLevel(parameters[log].intValue());
1986                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
1987                    babModel->messageHandler()->logLevel()>1)
1988                  babModel->setPrintFrequency(100);
1989              }
1990             
1991              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,
1992                    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].intValue());
1993              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1994              // go faster stripes
1995              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
1996                osiclp->setupForRepeatedUse(2,parameters[slog].intValue());
1997              } else {
1998                osiclp->setupForRepeatedUse(0,parameters[slog].intValue());
1999              }
2000              double increment=babModel->getCutoffIncrement();;
2001              int * changed = NULL;
2002              if (!miplib)
2003                changed=analyze( osiclp,numberChanged,increment,false);
2004              if (debugValues) {
2005                if (numberDebugValues==babModel->getNumCols()) {
2006                  // for debug
2007                  babModel->solver()->activateRowCutDebugger(debugValues) ;
2008                } else {
2009                  printf("debug file has incorrect number of columns\n");
2010                }
2011              }
2012              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
2013              // Turn this off if you get problems
2014              // Used to be automatically set
2015              int mipOptions = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue();
2016              if (mipOptions!=(128|64|1))
2017                printf("mip options %d\n",mipOptions);
2018              osiclp->setSpecialOptions(mipOptions);
2019              if (gapRatio < 1.0e100) {
2020                double value = babModel->solver()->getObjValue() ;
2021                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
2022                babModel->setAllowableGap(value2) ;
2023                std::cout << "Continuous " << value
2024                          << ", so allowable gap set to "
2025                          << value2 << std::endl ;
2026              }
2027              // probably faster to use a basis to get integer solutions
2028              babModel->setSpecialOptions(2);
2029              currentBranchModel = babModel;
2030              OsiSolverInterface * strengthenedModel=NULL;
2031              if (type==BAB||type==MIPLIB) {
2032                int moreMipOptions = parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].intValue();
2033                if (moreMipOptions>=0) {
2034                  printf("more mip options %d\n",moreMipOptions);
2035                  babModel->setSearchStrategy(moreMipOptions);
2036                }
2037              }
2038              if (type==BAB) {
2039#ifdef COIN_HAS_ASL
2040                if (usingAmpl) {
2041                  priorities=info.priorities;
2042                  branchDirection=info.branchDirection;
2043                  pseudoDown=info.pseudoDown;
2044                  pseudoUp=info.pseudoUp;
2045                  solutionIn=info.primalSolution;
2046                  prioritiesIn = info.priorities;
2047                }
2048#endif               
2049                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
2050                if (solutionIn&&useSolution) {
2051                  if (preProcess) {
2052                    int numberColumns = babModel->getNumCols();
2053                    // extend arrays in case SOS
2054                    int n = originalColumns[numberColumns-1]+1;
2055                    int nSmaller = CoinMin(n,numberOriginalColumns);
2056                    double * solutionIn2 = new double [n];
2057                    int * prioritiesIn2 = new int[n];
2058                    int i;
2059                    for (i=0;i<nSmaller;i++) {
2060                      solutionIn2[i]=solutionIn[i];
2061                      prioritiesIn2[i]=prioritiesIn[i];
2062                    }
2063                    for (;i<n;i++) {
2064                      solutionIn2[i]=0.0;
2065                      prioritiesIn2[i]=1000000;
2066                    }
2067                    int iLast=-1;
2068                    for (i=0;i<numberColumns;i++) {
2069                      int iColumn = originalColumns[i];
2070                      assert (iColumn>iLast);
2071                      iLast=iColumn;
2072                      solutionIn2[i]=solutionIn2[iColumn];
2073                      if (prioritiesIn)
2074                        prioritiesIn2[i]=prioritiesIn2[iColumn];
2075                    }
2076                    babModel->setHotstartSolution(solutionIn2,prioritiesIn2);
2077                    delete [] solutionIn2;
2078                    delete [] prioritiesIn2;
2079                  } else {
2080                    babModel->setHotstartSolution(solutionIn,prioritiesIn);
2081                  }
2082                }
2083                if (preProcess&&process.numberSOS()) {
2084                  int numberSOS = process.numberSOS();
2085                  int numberIntegers = babModel->numberIntegers();
2086                  /* model may not have created objects
2087                     If none then create
2088                  */
2089                  if (!numberIntegers||!babModel->numberObjects()) {
2090                    int type = (pseudoUp) ? 1 : 0;
2091                    babModel->findIntegers(true,type);
2092                    numberIntegers = babModel->numberIntegers();
2093                  }
2094                  CbcObject ** oldObjects = babModel->objects();
2095                  // Do sets and priorities
2096                  CbcObject ** objects = new CbcObject * [numberSOS];
2097                  // set old objects to have low priority
2098                  int numberOldObjects = babModel->numberObjects();
2099                  int numberColumns = babModel->getNumCols();
2100                  for (int iObj = 0;iObj<numberOldObjects;iObj++) {
2101                    oldObjects[iObj]->setPriority(numberColumns+1);
2102                    int iColumn = oldObjects[iObj]->columnNumber();
2103                    assert (iColumn>=0);
2104                    if (iColumn>=numberOriginalColumns)
2105                      continue;
2106                    if (originalColumns)
2107                      iColumn = originalColumns[iColumn];
2108                    if (branchDirection)
2109                      oldObjects[iObj]->setPreferredWay(branchDirection[iColumn]);
2110                    if (pseudoUp) {
2111                      CbcSimpleIntegerPseudoCost * obj1a =
2112                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
2113                      assert (obj1a);
2114                      if (pseudoDown[iColumn]>0.0)
2115                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2116                      if (pseudoUp[iColumn]>0.0)
2117                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2118                    }
2119                  }
2120                  const int * starts = process.startSOS();
2121                  const int * which = process.whichSOS();
2122                  const int * type = process.typeSOS();
2123                  const double * weight = process.weightSOS();
2124                  int iSOS;
2125                  for (iSOS =0;iSOS<numberSOS;iSOS++) {
2126                    int iStart = starts[iSOS];
2127                    int n=starts[iSOS+1]-iStart;
2128                    objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
2129                                               iSOS,type[iSOS]);
2130                    // branch on long sets first
2131                    objects[iSOS]->setPriority(numberColumns-n);
2132                  }
2133                  babModel->addObjects(numberSOS,objects);
2134                  for (iSOS=0;iSOS<numberSOS;iSOS++)
2135                    delete objects[iSOS];
2136                  delete [] objects;
2137                } else if (priorities||branchDirection||pseudoDown||pseudoUp) {
2138                  // do anyway for priorities etc
2139                  int numberIntegers = babModel->numberIntegers();
2140                  /* model may not have created objects
2141                     If none then create
2142                  */
2143                  if (!numberIntegers||!babModel->numberObjects()) {
2144                    int type = (pseudoUp) ? 1 : 0;
2145                    babModel->findIntegers(true,type);
2146                  }
2147                  CbcObject ** objects = babModel->objects();
2148                  int numberObjects = babModel->numberObjects();
2149                  for (int iObj = 0;iObj<numberObjects;iObj++) {
2150                    // skip sos
2151                    CbcSOS * objSOS =
2152                      dynamic_cast <CbcSOS *>(objects[iObj]) ;
2153                    if (objSOS)
2154                      continue;
2155                    int iColumn = objects[iObj]->columnNumber();
2156                    assert (iColumn>=0);
2157                    if (originalColumns)
2158                      iColumn = originalColumns[iColumn];
2159                    if (branchDirection)
2160                      objects[iObj]->setPreferredWay(branchDirection[iColumn]);
2161                    if (priorities) {
2162                      int iPriority = priorities[iColumn];
2163                      if (iPriority>0)
2164                        objects[iObj]->setPriority(iPriority);
2165                    }
2166                    if (pseudoUp&&pseudoUp[iColumn]) {
2167                      CbcSimpleIntegerPseudoCost * obj1a =
2168                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
2169                      assert (obj1a);
2170                      if (pseudoDown[iColumn]>0.0)
2171                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2172                      if (pseudoUp[iColumn]>0.0)
2173                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2174                    }
2175                  }
2176                }
2177                int statistics = (printOptions>0) ? printOptions: 0;
2178#ifdef COIN_HAS_ASL
2179                if (!usingAmpl) {
2180#endif
2181                  free(priorities);
2182                  priorities=NULL;
2183                  free(branchDirection);
2184                  branchDirection=NULL;
2185                  free(pseudoDown);
2186                  pseudoDown=NULL;
2187                  free(pseudoUp);
2188                  pseudoUp=NULL;
2189                  free(solutionIn);
2190                  solutionIn=NULL;
2191                  free(prioritiesIn);
2192                  prioritiesIn=NULL;
2193#ifdef COIN_HAS_ASL
2194                }
2195#endif               
2196                if (cppValue>=0) {
2197                  int prepro = useStrategy ? -1 : preProcess;
2198                  // generate code
2199                  FILE * fp = fopen("user_driver.cpp","w");
2200                  if (fp) {
2201                    // generate enough to do BAB
2202                    babModel->generateCpp(fp,1);
2203                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2204                    // Make general so do factorization
2205                    int factor = osiclp->getModelPtr()->factorizationFrequency();
2206                    osiclp->getModelPtr()->setFactorizationFrequency(200);
2207                    osiclp->generateCpp(fp);
2208                    osiclp->getModelPtr()->setFactorizationFrequency(factor);
2209                    //solveOptions.generateCpp(fp);
2210                    fclose(fp);
2211                    // now call generate code
2212                    generateCode("user_driver.cpp",cppValue,prepro);
2213                  } else {
2214                    std::cout<<"Unable to open file user_driver.cpp"<<std::endl;
2215                  }
2216                }
2217                if (useStrategy) {
2218                  CbcStrategyDefault strategy(true,5,5);
2219                  strategy.setupPreProcessing(1);
2220                  babModel->setStrategy(strategy);
2221                }
2222                babModel->branchAndBound(statistics);
2223              } else if (type==MIPLIB) {
2224                CbcStrategyDefault strategy(true,5,5);
2225                // Set up pre-processing to find sos if wanted
2226                if (preProcess)
2227                  strategy.setupPreProcessing(2);
2228                babModel->setStrategy(strategy);
2229                CbcClpUnitTest(*babModel);
2230                goodModel=false;
2231                break;
2232              } else {
2233                strengthenedModel = babModel->strengthenedModel();
2234              }
2235              currentBranchModel = NULL;
2236              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2237              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
2238                lpSolver = osiclp->getModelPtr();
2239                //move best solution (should be there -- but ..)
2240                int n = lpSolver->getNumCols();
2241                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
2242                saveSolution(osiclp->getModelPtr(),"debug.file");
2243              }
2244              if (!noPrinting) {
2245                // Print more statistics
2246                std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
2247                         <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
2248               
2249                for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
2250                  CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
2251                  std::cout<<generator->cutGeneratorName()<<" was tried "
2252                           <<generator->numberTimesEntered()<<" times and created "
2253                           <<generator->numberCutsInTotal()<<" cuts of which "
2254                           <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
2255                  if (generator->timing())
2256                    std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
2257                  else
2258                    std::cout<<std::endl;
2259                }
2260              }
2261              time2 = CoinCpuTime();
2262              totalTime += time2-time1;
2263              // For best solution
2264              double * bestSolution = NULL;
2265              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
2266                // post process
2267                if (preProcess) {
2268                  int n = saveSolver->getNumCols();
2269                  bestSolution = new double [n];
2270                  process.postProcess(*babModel->solver());
2271                  // Solution now back in saveSolver
2272                  babModel->assignSolver(saveSolver);
2273                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2274                } else {
2275                  int n = babModel->solver()->getNumCols();
2276                  bestSolution = new double [n];
2277                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2278                }
2279              }
2280              if (type==STRENGTHEN&&strengthenedModel)
2281                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
2282              lpSolver = clpSolver->getModelPtr();
2283              if (numberChanged) {
2284                for (int i=0;i<numberChanged;i++) {
2285                  int iColumn=changed[i];
2286                  clpSolver->setContinuous(iColumn);
2287                }
2288                delete [] changed;
2289              }
2290              if (type==BAB) {
2291                //move best solution (should be there -- but ..)
2292                int n = lpSolver->getNumCols();
2293                if (bestSolution)
2294                  memcpy(lpSolver->primalColumnSolution(),bestSolution,n*sizeof(double));
2295                if (debugFile=="create"&&bestSolution) {
2296                  saveSolution(lpSolver,"debug.file");
2297                }
2298                delete [] bestSolution;
2299                std::string statusName[]={"Finished","Stopped on ","Difficulties",
2300                                          "","","User ctrl-c"};
2301                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
2302                int iStat = babModel->status();
2303                int iStat2 = babModel->secondaryStatus();
2304                if (!noPrinting)
2305                  std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
2306                           <<" objective "<<babModel->getObjValue()<<
2307                    " after "<<babModel->getNodeCount()<<" nodes and "
2308                           <<babModel->getIterationCount()<<
2309                    " iterations - took "<<time2-time1<<" seconds"<<std::endl;
2310#ifdef COIN_HAS_ASL
2311                if (usingAmpl) {
2312                  double value = babModel->getObjValue()*lpSolver->getObjSense();
2313                  char buf[300];
2314                  int pos=0;
2315                  if (iStat==0) {
2316                    if (babModel->getObjValue()<1.0e40) {
2317                      pos += sprintf(buf+pos,"optimal," );
2318                    } else {
2319                      // infeasible
2320                      iStat=1;
2321                      pos += sprintf(buf+pos,"infeasible,");
2322                    }
2323                  } else if (iStat==1) {
2324                    if (iStat2!=6)
2325                      iStat=3;
2326                    else
2327                      iStat=4;
2328                    pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
2329                  } else if (iStat==2) {
2330                    iStat = 7;
2331                    pos += sprintf(buf+pos,"stopped on difficulties,");
2332                  } else if (iStat==5) {
2333                    iStat = 3;
2334                    pos += sprintf(buf+pos,"stopped on ctrl-c,");
2335                  } else {
2336                    pos += sprintf(buf+pos,"status unknown,");
2337                    iStat=6;
2338                  }
2339                  info.problemStatus=iStat;
2340                  info.objValue = value;
2341                  if (babModel->getObjValue()<1.0e40) 
2342                    pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
2343                                   value);
2344                  sprintf(buf+pos,"\n%d nodes, %d iterations",
2345                          babModel->getNodeCount(),
2346                          babModel->getIterationCount());
2347                  if (bestSolution) {
2348                    free(info.primalSolution);
2349                    info.primalSolution = (double *) malloc(n*sizeof(double));
2350                    CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
2351                    int numberRows = lpSolver->numberRows();
2352                    free(info.dualSolution);
2353                    info.dualSolution = (double *) malloc(numberRows*sizeof(double));
2354                    CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
2355                  } else {
2356                    info.primalSolution=NULL;
2357                    info.dualSolution=NULL;
2358                  }
2359                  // put buffer into info
2360                  strcpy(info.buffer,buf);
2361                }
2362#endif
2363              } else {
2364                std::cout<<"Model strengthend - now has "<<clpSolver->getNumRows()
2365                         <<" rows"<<std::endl;
2366              }
2367              time1 = time2;
2368              delete babModel;
2369              babModel=NULL;
2370            } else {
2371              std::cout << "** Current model not valid" << std::endl ; 
2372            }
2373            break ;
2374          case IMPORT:
2375            {
2376#ifdef COIN_HAS_ASL
2377              if (!usingAmpl) {
2378#endif
2379                free(priorities);
2380                priorities=NULL;
2381                free(branchDirection);
2382                branchDirection=NULL;
2383                free(pseudoDown);
2384                pseudoDown=NULL;
2385                free(pseudoUp);
2386                pseudoUp=NULL;
2387                free(solutionIn);
2388                solutionIn=NULL;
2389                free(prioritiesIn);
2390                prioritiesIn=NULL;
2391#ifdef COIN_HAS_ASL
2392              }
2393#endif               
2394              delete babModel;
2395              babModel=NULL;
2396              // get next field
2397              field = CoinReadGetString(argc,argv);
2398              if (field=="$") {
2399                field = parameters[iParam].stringValue();
2400              } else if (field=="EOL") {
2401                parameters[iParam].printString();
2402                break;
2403              } else {
2404                parameters[iParam].setStringValue(field);
2405              }
2406              std::string fileName;
2407              bool canOpen=false;
2408              if (field=="-") {
2409                // stdin
2410                canOpen=true;
2411                fileName = "-";
2412              } else {
2413                bool absolutePath;
2414                if (dirsep=='/') {
2415                  // non Windows (or cygwin)
2416                  absolutePath=(field[0]=='/');
2417                } else {
2418                  //Windows (non cycgwin)
2419                  absolutePath=(field[0]=='\\');
2420                  // but allow for :
2421                  if (strchr(field.c_str(),':'))
2422                    absolutePath=true;
2423                }
2424                if (absolutePath) {
2425                  fileName = field;
2426                } else if (field[0]=='~') {
2427                  char * environVar = getenv("HOME");
2428                  if (environVar) {
2429                    std::string home(environVar);
2430                    field=field.erase(0,1);
2431                    fileName = home+field;
2432                  } else {
2433                    fileName=field;
2434                  }
2435                } else {
2436                  fileName = directory+field;
2437                }
2438                FILE *fp=fopen(fileName.c_str(),"r");
2439                if (fp) {
2440                  // can open - lets go for it
2441                  fclose(fp);
2442                  canOpen=true;
2443                } else {
2444                  std::cout<<"Unable to open file "<<fileName<<std::endl;
2445                }
2446              }
2447              if (canOpen) {
2448                int status =lpSolver->readMps(fileName.c_str(),
2449                                                   keepImportNames!=0,
2450                                                   allowImportErrors!=0);
2451                if (!status||(status>0&&allowImportErrors)) {
2452                  if (keepImportNames) {
2453                    lengthName = lpSolver->lengthNames();
2454                    rowNames = *(lpSolver->rowNames());
2455                    columnNames = *(lpSolver->columnNames());
2456                  } else {
2457                    lengthName=0;
2458                  }
2459                  goodModel=true;
2460                  //Set integers in clpsolver
2461                  const char * info = lpSolver->integerInformation();
2462                  if (info) {
2463                    int numberColumns = lpSolver->numberColumns();
2464                    int i;
2465                    for (i=0;i<numberColumns;i++) {
2466                      if (info[i]) 
2467                        clpSolver->setInteger(i);
2468                    }
2469                  }
2470                  // sets to all slack (not necessary?)
2471                  lpSolver->createStatus();
2472                  time2 = CoinCpuTime();
2473                  totalTime += time2-time1;
2474                  time1=time2;
2475                  // Go to canned file if just input file
2476                  if (CbcOrClpRead_mode==2&&argc==2) {
2477                    // only if ends .mps
2478                    std::string::size_type loc = fileName.find(".mps") ;
2479                    if (loc != std::string::npos &&
2480                        fileName.length() == loc+3)
2481                    { fileName.replace(loc+1,3,"par") ;
2482                      FILE *fp=fopen(fileName.c_str(),"r");
2483                      if (fp) {
2484                        CbcOrClpReadCommand=fp; // Read from that file
2485                        CbcOrClpRead_mode=-1;
2486                      }
2487                    }
2488                  }
2489                } else {
2490                  // errors
2491                  std::cout<<"There were "<<status<<
2492                    " errors on input"<<std::endl;
2493                }
2494              }
2495            }
2496            break;
2497          case EXPORT:
2498            if (goodModel) {
2499              // get next field
2500              field = CoinReadGetString(argc,argv);
2501              if (field=="$") {
2502                field = parameters[iParam].stringValue();
2503              } else if (field=="EOL") {
2504                parameters[iParam].printString();
2505                break;
2506              } else {
2507                parameters[iParam].setStringValue(field);
2508              }
2509              std::string fileName;
2510              bool canOpen=false;
2511              if (field[0]=='/'||field[0]=='\\') {
2512                fileName = field;
2513              } else if (field[0]=='~') {
2514                char * environVar = getenv("HOME");
2515                if (environVar) {
2516                  std::string home(environVar);
2517                  field=field.erase(0,1);
2518                  fileName = home+field;
2519                } else {
2520                  fileName=field;
2521                }
2522              } else {
2523                fileName = directory+field;
2524              }
2525              FILE *fp=fopen(fileName.c_str(),"w");
2526              if (fp) {
2527                // can open - lets go for it
2528                fclose(fp);
2529                canOpen=true;
2530              } else {
2531                std::cout<<"Unable to open file "<<fileName<<std::endl;
2532              }
2533              if (canOpen) {
2534                // If presolve on then save presolved
2535                bool deleteModel2=false;
2536                ClpSimplex * model2 = lpSolver;
2537                if (preSolve) {
2538                  ClpPresolve pinfo;
2539                  int presolveOptions2 = presolveOptions&~0x40000000;
2540                  if ((presolveOptions2&0xffff)!=0)
2541                    pinfo.setPresolveActions(presolveOptions2);
2542                  if ((printOptions&1)!=0)
2543                    pinfo.statistics();
2544                  double presolveTolerance = 
2545                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
2546                  model2 = 
2547                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
2548                                         true,preSolve);
2549                  if (model2) {
2550                    printf("Saving presolved model on %s\n",
2551                           fileName.c_str());
2552                    deleteModel2=true;
2553                  } else {
2554                    printf("Presolved model looks infeasible - saving original on %s\n",
2555                           fileName.c_str());
2556                    deleteModel2=false;
2557                    model2 = lpSolver;
2558
2559                  }
2560                } else {
2561                  printf("Saving model on %s\n",
2562                           fileName.c_str());
2563                }
2564#if 0
2565                // Convert names
2566                int iRow;
2567                int numberRows=model2->numberRows();
2568                int iColumn;
2569                int numberColumns=model2->numberColumns();
2570
2571                char ** rowNames = NULL;
2572                char ** columnNames = NULL;
2573                if (model2->lengthNames()) {
2574                  rowNames = new char * [numberRows];
2575                  for (iRow=0;iRow<numberRows;iRow++) {
2576                    rowNames[iRow] =
2577                      strdup(model2->rowName(iRow).c_str());
2578#ifdef STRIPBLANKS
2579                    char * xx = rowNames[iRow];
2580                    int i;
2581                    int length = strlen(xx);
2582                    int n=0;
2583                    for (i=0;i<length;i++) {
2584                      if (xx[i]!=' ')
2585                        xx[n++]=xx[i];
2586                    }
2587                    xx[n]='\0';
2588#endif
2589                  }
2590                 
2591                  columnNames = new char * [numberColumns];
2592                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2593                    columnNames[iColumn] =
2594                      strdup(model2->columnName(iColumn).c_str());
2595#ifdef STRIPBLANKS
2596                    char * xx = columnNames[iColumn];
2597                    int i;
2598                    int length = strlen(xx);
2599                    int n=0;
2600                    for (i=0;i<length;i++) {
2601                      if (xx[i]!=' ')
2602                        xx[n++]=xx[i];
2603                    }
2604                    xx[n]='\0';
2605#endif
2606                  }
2607                }
2608                CoinMpsIO writer;
2609                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
2610                                  model2->getColLower(), model2->getColUpper(),
2611                                  model2->getObjCoefficients(),
2612                                  (const char*) 0 /*integrality*/,
2613                                  model2->getRowLower(), model2->getRowUpper(),
2614                                  columnNames, rowNames);
2615                // Pass in array saying if each variable integer
2616                writer.copyInIntegerInformation(model2->integerInformation());
2617                writer.setObjectiveOffset(model2->objectiveOffset());
2618                writer.writeMps(fileName.c_str(),0,1,1);
2619                if (rowNames) {
2620                  for (iRow=0;iRow<numberRows;iRow++) {
2621                    free(rowNames[iRow]);
2622                  }
2623                  delete [] rowNames;
2624                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2625                    free(columnNames[iColumn]);
2626                  }
2627                  delete [] columnNames;
2628                }
2629#else
2630                model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
2631#endif
2632                if (deleteModel2)
2633                  delete model2;
2634                time2 = CoinCpuTime();
2635                totalTime += time2-time1;
2636                time1=time2;
2637              }
2638            } else {
2639              std::cout<<"** Current model not valid"<<std::endl;
2640            }
2641            break;
2642          case BASISIN:
2643            if (goodModel) {
2644              // get next field
2645              field = CoinReadGetString(argc,argv);
2646              if (field=="$") {
2647                field = parameters[iParam].stringValue();
2648              } else if (field=="EOL") {
2649                parameters[iParam].printString();
2650                break;
2651              } else {
2652                parameters[iParam].setStringValue(field);
2653              }
2654              std::string fileName;
2655              bool canOpen=false;
2656              if (field=="-") {
2657                // stdin
2658                canOpen=true;
2659                fileName = "-";
2660              } else {
2661                if (field[0]=='/'||field[0]=='\\') {
2662                  fileName = field;
2663                } else if (field[0]=='~') {
2664                  char * environVar = getenv("HOME");
2665                  if (environVar) {
2666                    std::string home(environVar);
2667                    field=field.erase(0,1);
2668                    fileName = home+field;
2669                  } else {
2670                    fileName=field;
2671                  }
2672                } else {
2673                  fileName = directory+field;
2674                }
2675                FILE *fp=fopen(fileName.c_str(),"r");
2676                if (fp) {
2677                  // can open - lets go for it
2678                  fclose(fp);
2679                  canOpen=true;
2680                } else {
2681                  std::cout<<"Unable to open file "<<fileName<<std::endl;
2682                }
2683              }
2684              if (canOpen) {
2685                int values = lpSolver->readBasis(fileName.c_str());
2686                if (values==0)
2687                  basisHasValues=-1;
2688                else
2689                  basisHasValues=1;
2690              }
2691            } else {
2692              std::cout<<"** Current model not valid"<<std::endl;
2693            }
2694            break;
2695          case PRIORITYIN:
2696            if (goodModel) {
2697              // get next field
2698              field = CoinReadGetString(argc,argv);
2699              if (field=="$") {
2700                field = parameters[iParam].stringValue();
2701              } else if (field=="EOL") {
2702                parameters[iParam].printString();
2703                break;
2704              } else {
2705                parameters[iParam].setStringValue(field);
2706              }
2707              std::string fileName;
2708              if (field[0]=='/'||field[0]=='\\') {
2709                fileName = field;
2710              } else if (field[0]=='~') {
2711                char * environVar = getenv("HOME");
2712                if (environVar) {
2713                  std::string home(environVar);
2714                  field=field.erase(0,1);
2715                  fileName = home+field;
2716                } else {
2717                  fileName=field;
2718                }
2719              } else {
2720                fileName = directory+field;
2721              }
2722              FILE *fp=fopen(fileName.c_str(),"r");
2723              if (fp) {
2724                // can open - lets go for it
2725                std::string headings[]={"name","number","direction","priority","up","down",
2726                                        "solution","priin"};
2727                int got[]={-1,-1,-1,-1,-1,-1,-1,-1};
2728                int order[8];
2729                assert(sizeof(got)==sizeof(order));
2730                int nAcross=0;
2731                char line[1000];
2732                int numberColumns = lpSolver->numberColumns();
2733                if (!fgets(line,1000,fp)) {
2734                  std::cout<<"Odd file "<<fileName<<std::endl;
2735                } else {
2736                  char * pos = line;
2737                  char * put = line;
2738                  while (*pos>=' '&&*pos!='\n') {
2739                    if (*pos!=' '&&*pos!='\t') {
2740                      *put=tolower(*pos);
2741                      put++;
2742                    }
2743                    pos++;
2744                  }
2745                  *put='\0';
2746                  pos=line;
2747                  int i;
2748                  bool good=true;
2749                  while (pos) {
2750                    char * comma = strchr(pos,',');
2751                    if (comma)
2752                      *comma='\0';
2753                    for (i=0;i<(int) (sizeof(got)/sizeof(int));i++) {
2754                      if (headings[i]==pos) {
2755                        if (got[i]<0) {
2756                          order[nAcross]=i;
2757                          got[i]=nAcross++;
2758                        } else {
2759                          // duplicate
2760                          good=false;
2761                        }
2762                        break;
2763                      }
2764                    }
2765                    if (i==(int) (sizeof(got)/sizeof(int)))
2766                      good=false;
2767                    if (comma) {
2768                      *comma=',';
2769                      pos=comma+1;
2770                    } else {
2771                      break;
2772                    }
2773                  }
2774                  if (got[0]<0&&got[1]<0)
2775                    good=false;
2776                  if (got[0]>=0&&got[1]>=0)
2777                    good=false;
2778                  if (got[0]>=0&&!lpSolver->lengthNames())
2779                    good=false;
2780                  if (good) {
2781                    char ** columnNames = columnNames = new char * [numberColumns];
2782                    pseudoDown= (double *) malloc(numberColumns*sizeof(double));
2783                    pseudoUp = (double *) malloc(numberColumns*sizeof(double));
2784                    branchDirection = (int *) malloc(numberColumns*sizeof(int));
2785                    priorities= (int *) malloc(numberColumns*sizeof(int));
2786                    free(solutionIn);
2787                    solutionIn=NULL;
2788                    free(prioritiesIn);
2789                    prioritiesIn=NULL;
2790                    int iColumn;
2791                    if (got[6]>=0) {
2792                      solutionIn = (double *) malloc(numberColumns*sizeof(double));
2793                      CoinZeroN(solutionIn,numberColumns);
2794                    }
2795                    if (got[7]>=0) {
2796                      prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
2797                      for (iColumn=0;iColumn<numberColumns;iColumn++) 
2798                        prioritiesIn[iColumn]=10000;
2799                    }
2800                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
2801                      columnNames[iColumn] = 
2802                        strdup(lpSolver->columnName(iColumn).c_str());
2803                      pseudoDown[iColumn]=0.0;
2804                      pseudoUp[iColumn]=0.0;
2805                      branchDirection[iColumn]=0;
2806                      priorities[iColumn]=0;
2807                    }
2808                    int nBadPseudo=0;
2809                    int nBadDir=0;
2810                    int nBadPri=0;
2811                    int nBadName=0;
2812                    int nBadLine=0;
2813                    int nLine=0;
2814                    while (fgets(line,1000,fp)) {
2815                      nLine++;
2816                      iColumn = -1;
2817                      double up =0.0;
2818                      double down=0.0;
2819                      int pri=0;
2820                      int dir=0;
2821                      double solValue=COIN_DBL_MAX;
2822                      int priValue=1000000;
2823                      char * pos = line;
2824                      char * put = line;
2825                      while (*pos>=' '&&*pos!='\n') {
2826                        if (*pos!=' '&&*pos!='\t') {
2827                          *put=tolower(*pos);
2828                          put++;
2829                        }
2830                        pos++;
2831                      }
2832                      *put='\0';
2833                      pos=line;
2834                      for (int i=0;i<nAcross;i++) {
2835                        char * comma = strchr(pos,',');
2836                        if (comma) {
2837                          *comma='\0';
2838                        } else if (i<nAcross-1) {
2839                          nBadLine++;
2840                          break;
2841                        }
2842                        switch (order[i]) {
2843                          // name
2844                        case 0:
2845                          for (iColumn=0;iColumn<numberColumns;iColumn++) {
2846                            if (!strcmp(columnNames[iColumn],pos))
2847                              break;
2848                          }
2849                          if (iColumn==numberColumns)
2850                            iColumn=-1;
2851                          break;
2852                          // number
2853                        case 1:
2854                          iColumn = atoi(pos);
2855                          if (iColumn<0||iColumn>=numberColumns)
2856                            iColumn=-1;
2857                          break;
2858                          // direction
2859                        case 2:
2860                          if (*pos=='D')
2861                            dir=-1;
2862                          else if (*pos=='U')
2863                            dir=1;
2864                          else if (*pos=='N')
2865                            dir=0;
2866                          else if (*pos=='1'&&*(pos+1)=='\0')
2867                            dir=1;
2868                          else if (*pos=='0'&&*(pos+1)=='\0')
2869                            dir=0;
2870                          else if (*pos=='1'&&*(pos+1)=='1'&&*(pos+2)=='\0')
2871                            dir=-1;
2872                          else
2873                            dir=-2; // bad
2874                          break;
2875                          // priority
2876                        case 3:
2877                          pri=atoi(pos);
2878                          break;
2879                          // up
2880                        case 4:
2881                          up = atof(pos);
2882                          break;
2883                          // down
2884                        case 5:
2885                          down = atof(pos);
2886                          break;
2887                          // sol value
2888                        case 6:
2889                          solValue = atof(pos);
2890                          break;
2891                          // priority in value
2892                        case 7:
2893                          priValue = atoi(pos);
2894                          break;
2895                        }
2896                        if (comma) {
2897                          *comma=',';
2898                          pos=comma+1;
2899                        }
2900                      }
2901                      if (iColumn>=0) {
2902                        if (down<0.0) {
2903                          nBadPseudo++;
2904                          down=0.0;
2905                        }
2906                        if (up<0.0) {
2907                          nBadPseudo++;
2908                          up=0.0;
2909                        }
2910                        if (!up)
2911                          up=down;
2912                        if (!down)
2913                          down=up;
2914                        if (dir<-1||dir>1) {
2915                          nBadDir++;
2916                          dir=0;
2917                        }
2918                        if (pri<0) {
2919                          nBadPri++;
2920                          pri=0;
2921                        }
2922                        pseudoDown[iColumn]=down;
2923                        pseudoUp[iColumn]=up;
2924                        branchDirection[iColumn]=dir;
2925                        priorities[iColumn]=pri;
2926                        if (solValue!=COIN_DBL_MAX) {
2927                          assert (solutionIn);
2928                          solutionIn[iColumn]=solValue;
2929                        }
2930                        if (priValue!=1000000) {
2931                          assert (prioritiesIn);
2932                          prioritiesIn[iColumn]=priValue;
2933                        }
2934                      } else {
2935                        nBadName++;
2936                      }
2937                    }
2938                    if (!noPrinting) {
2939                      printf("%d fields and %d records",nAcross,nLine);
2940                      if (nBadPseudo)
2941                        printf(" %d bad pseudo costs",nBadPseudo);
2942                      if (nBadDir)
2943                        printf(" %d bad directions",nBadDir);
2944                      if (nBadPri)
2945                        printf(" %d bad priorities",nBadPri);
2946                      if (nBadName)
2947                        printf(" ** %d records did not match on name/sequence",nBadName);
2948                      printf("\n");
2949                    }
2950                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
2951                      free(columnNames[iColumn]);
2952                    }
2953                    delete [] columnNames;
2954                  } else {
2955                    std::cout<<"Duplicate or unknown keyword - or name/number fields wrong"<<line<<std::endl;
2956                  }
2957                }
2958                fclose(fp);
2959              } else {
2960                std::cout<<"Unable to open file "<<fileName<<std::endl;
2961              }
2962            } else {
2963              std::cout<<"** Current model not valid"<<std::endl;
2964            }
2965            break;
2966          case DEBUG:
2967            if (goodModel) {
2968              delete [] debugValues;
2969              debugValues=NULL;
2970              // get next field
2971              field = CoinReadGetString(argc,argv);
2972              if (field=="$") {
2973                field = parameters[iParam].stringValue();
2974              } else if (field=="EOL") {
2975                parameters[iParam].printString();
2976                break;
2977              } else {
2978                parameters[iParam].setStringValue(field);
2979                debugFile=field;
2980                if (debugFile=="create"||
2981                    debugFile=="createAfterPre") {
2982                  printf("Will create a debug file so this run should be a good one\n");
2983                  break;
2984                }
2985              }
2986              std::string fileName;
2987              if (field[0]=='/'||field[0]=='\\') {
2988                fileName = field;
2989              } else if (field[0]=='~') {
2990                char * environVar = getenv("HOME");
2991                if (environVar) {
2992                  std::string home(environVar);
2993                  field=field.erase(0,1);
2994                  fileName = home+field;
2995                } else {
2996                  fileName=field;
2997                }
2998              } else {
2999                fileName = directory+field;
3000              }
3001              FILE *fp=fopen(fileName.c_str(),"rb");
3002              if (fp) {
3003                // can open - lets go for it
3004                int numRows;
3005                double obj;
3006                fread(&numRows,sizeof(int),1,fp);
3007                fread(&numberDebugValues,sizeof(int),1,fp);
3008                fread(&obj,sizeof(double),1,fp);
3009                debugValues = new double[numberDebugValues+numRows];
3010                fread(debugValues,sizeof(double),numRows,fp);
3011                fread(debugValues,sizeof(double),numRows,fp);
3012                fread(debugValues,sizeof(double),numberDebugValues,fp);
3013                printf("%d doubles read into debugValues\n",numberDebugValues);
3014                fclose(fp);
3015              } else {
3016                std::cout<<"Unable to open file "<<fileName<<std::endl;
3017              }
3018            } else {
3019              std::cout<<"** Current model not valid"<<std::endl;
3020            }
3021            break;
3022          case PRINTMASK:
3023            // get next field
3024            {
3025              std::string name = CoinReadGetString(argc,argv);
3026              if (name!="EOL") {
3027                parameters[iParam].setStringValue(name);
3028                printMask = name;
3029              } else {
3030                parameters[iParam].printString();
3031              }
3032            }
3033            break;
3034          case BASISOUT:
3035            if (goodModel) {
3036              // get next field
3037              field = CoinReadGetString(argc,argv);
3038              if (field=="$") {
3039                field = parameters[iParam].stringValue();
3040              } else if (field=="EOL") {
3041                parameters[iParam].printString();
3042                break;
3043              } else {
3044                parameters[iParam].setStringValue(field);
3045              }
3046              std::string fileName;
3047              bool canOpen=false;
3048              if (field[0]=='/'||field[0]=='\\') {
3049                fileName = field;
3050              } else if (field[0]=='~') {
3051                char * environVar = getenv("HOME");
3052                if (environVar) {
3053                  std::string home(environVar);
3054                  field=field.erase(0,1);
3055                  fileName = home+field;
3056                } else {
3057                  fileName=field;
3058                }
3059              } else {
3060                fileName = directory+field;
3061              }
3062              FILE *fp=fopen(fileName.c_str(),"w");
3063              if (fp) {
3064                // can open - lets go for it
3065                fclose(fp);
3066                canOpen=true;
3067              } else {
3068                std::cout<<"Unable to open file "<<fileName<<std::endl;
3069              }
3070              if (canOpen) {
3071                ClpSimplex * model2 = lpSolver;
3072                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
3073                time2 = CoinCpuTime();
3074                totalTime += time2-time1;
3075                time1=time2;
3076              }
3077            } else {
3078              std::cout<<"** Current model not valid"<<std::endl;
3079            }
3080            break;
3081          case SAVE:
3082            {
3083              // get next field
3084              field = CoinReadGetString(argc,argv);
3085              if (field=="$") {
3086                field = parameters[iParam].stringValue();
3087              } else if (field=="EOL") {
3088                parameters[iParam].printString();
3089                break;
3090              } else {
3091                parameters[iParam].setStringValue(field);
3092              }
3093              std::string fileName;
3094              bool canOpen=false;
3095              if (field[0]=='/'||field[0]=='\\') {
3096                fileName = field;
3097              } else if (field[0]=='~') {
3098                char * environVar = getenv("HOME");
3099                if (environVar) {
3100                  std::string home(environVar);
3101                  field=field.erase(0,1);
3102                  fileName = home+field;
3103                } else {
3104                  fileName=field;
3105                }
3106              } else {
3107                fileName = directory+field;
3108              }
3109              FILE *fp=fopen(fileName.c_str(),"wb");
3110              if (fp) {
3111                // can open - lets go for it
3112                fclose(fp);
3113                canOpen=true;
3114              } else {
3115                std::cout<<"Unable to open file "<<fileName<<std::endl;
3116              }
3117              if (canOpen) {
3118                int status;
3119                // If presolve on then save presolved
3120                bool deleteModel2=false;
3121                ClpSimplex * model2 = lpSolver;
3122                if (preSolve) {
3123                  ClpPresolve pinfo;
3124                  double presolveTolerance = 
3125                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
3126                  model2 = 
3127                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
3128                                         false,preSolve);
3129                  if (model2) {
3130                    printf("Saving presolved model on %s\n",
3131                           fileName.c_str());
3132                    deleteModel2=true;
3133                  } else {
3134                    printf("Presolved model looks infeasible - saving original on %s\n",
3135                           fileName.c_str());
3136                    deleteModel2=false;
3137                    model2 = lpSolver;
3138
3139                  }
3140                } else {
3141                  printf("Saving model on %s\n",
3142                           fileName.c_str());
3143                }
3144                status =model2->saveModel(fileName.c_str());
3145                if (deleteModel2)
3146                  delete model2;
3147                if (!status) {
3148                  goodModel=true;
3149                  time2 = CoinCpuTime();
3150                  totalTime += time2-time1;
3151                  time1=time2;
3152                } else {
3153                  // errors
3154                  std::cout<<"There were errors on output"<<std::endl;
3155                }
3156              }
3157            }
3158            break;
3159          case RESTORE:
3160            {
3161              // get next field
3162              field = CoinReadGetString(argc,argv);
3163              if (field=="$") {
3164                field = parameters[iParam].stringValue();
3165              } else if (field=="EOL") {
3166                parameters[iParam].printString();
3167                break;
3168              } else {
3169                parameters[iParam].setStringValue(field);
3170              }
3171              std::string fileName;
3172              bool canOpen=false;
3173              if (field[0]=='/'||field[0]=='\\') {
3174                fileName = field;
3175              } else if (field[0]=='~') {
3176                char * environVar = getenv("HOME");
3177                if (environVar) {
3178                  std::string home(environVar);
3179                  field=field.erase(0,1);
3180                  fileName = home+field;
3181                } else {
3182                  fileName=field;
3183                }
3184              } else {
3185                fileName = directory+field;
3186              }
3187              FILE *fp=fopen(fileName.c_str(),"rb");
3188              if (fp) {
3189                // can open - lets go for it
3190                fclose(fp);
3191                canOpen=true;
3192              } else {
3193                std::cout<<"Unable to open file "<<fileName<<std::endl;
3194              }
3195              if (canOpen) {
3196                int status =lpSolver->restoreModel(fileName.c_str());
3197                if (!status) {
3198                  goodModel=true;
3199                  time2 = CoinCpuTime();
3200                  totalTime += time2-time1;
3201                  time1=time2;
3202                } else {
3203                  // errors
3204                  std::cout<<"There were errors on input"<<std::endl;
3205                }
3206              }
3207            }
3208            break;
3209          case MAXIMIZE:
3210            lpSolver->setOptimizationDirection(-1);
3211            break;
3212          case MINIMIZE:
3213            lpSolver->setOptimizationDirection(1);
3214            break;
3215          case ALLSLACK:
3216            lpSolver->allSlackBasis(true);
3217            break;
3218          case REVERSE:
3219            if (goodModel) {
3220              int iColumn;
3221              int numberColumns=lpSolver->numberColumns();
3222              double * dualColumnSolution = 
3223                lpSolver->dualColumnSolution();
3224              ClpObjective * obj = lpSolver->objectiveAsObject();
3225              assert(dynamic_cast<ClpLinearObjective *> (obj));
3226              double offset;
3227              double * objective = obj->gradient(NULL,NULL,offset,true);
3228              for (iColumn=0;iColumn<numberColumns;iColumn++) {
3229                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
3230                objective[iColumn] = -objective[iColumn];
3231              }
3232              int iRow;
3233              int numberRows=lpSolver->numberRows();
3234              double * dualRowSolution = 
3235                lpSolver->dualRowSolution();
3236              for (iRow=0;iRow<numberRows;iRow++) 
3237                dualRowSolution[iRow] = dualRowSolution[iRow];
3238            }
3239            break;
3240          case DIRECTORY:
3241            {
3242              std::string name = CoinReadGetString(argc,argv);
3243              if (name!="EOL") {
3244                int length=name.length();
3245                if (name[length-1]=='/'||name[length-1]=='\\')
3246                  directory=name;
3247                else
3248                  directory = name+"/";
3249                parameters[iParam].setStringValue(directory);
3250              } else {
3251                parameters[iParam].printString();
3252              }
3253            }
3254            break;
3255          case STDIN:
3256            CbcOrClpRead_mode=-1;
3257            break;
3258          case NETLIB_DUAL:
3259          case NETLIB_EITHER:
3260          case NETLIB_BARRIER:
3261          case NETLIB_PRIMAL:
3262          case NETLIB_TUNE:
3263            {
3264              // create fields for unitTest
3265              const char * fields[4];
3266              int nFields=2;
3267              fields[0]="fake main from unitTest";
3268              fields[1]="-netlib";
3269              if (directory!=defaultDirectory) {
3270                fields[2]="-netlibDir";
3271                fields[3]=directory.c_str();
3272                nFields=4;
3273              }
3274              int algorithm;
3275              if (type==NETLIB_DUAL) {
3276                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
3277                algorithm =0;
3278              } else if (type==NETLIB_BARRIER) {
3279                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
3280                algorithm =2;
3281              } else if (type==NETLIB_EITHER) {
3282                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
3283                algorithm =3;
3284              } else if (type==NETLIB_TUNE) {
3285                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
3286                algorithm =5;
3287                // uncomment next to get active tuning
3288                // algorithm=6;
3289              } else {
3290                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
3291                algorithm=1;
3292              }
3293              int specialOptions = lpSolver->specialOptions();
3294              lpSolver->setSpecialOptions(0);
3295              mainTest(nFields,fields,algorithm,*lpSolver,
3296                       (preSolve!=0),specialOptions);
3297            }
3298            break;
3299          case UNITTEST:
3300            {
3301              // create fields for unitTest
3302              const char * fields[3];
3303              int nFields=1;
3304              fields[0]="fake main from unitTest";
3305              if (directory!=defaultDirectory) {
3306                fields[1]="-mpsDir";
3307                fields[2]=directory.c_str();
3308                nFields=3;
3309              }
3310              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
3311                       false);
3312            }
3313            break;
3314          case FAKEBOUND:
3315            if (goodModel) {
3316              // get bound
3317              double value = CoinReadGetDoubleField(argc,argv,&valid);
3318              if (!valid) {
3319                std::cout<<"Setting "<<parameters[iParam].name()<<
3320                  " to DEBUG "<<value<<std::endl;
3321                int iRow;
3322                int numberRows=lpSolver->numberRows();
3323                double * rowLower = lpSolver->rowLower();
3324                double * rowUpper = lpSolver->rowUpper();
3325                for (iRow=0;iRow<numberRows;iRow++) {
3326                  // leave free ones for now
3327                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
3328                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
3329                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
3330                  }
3331                }
3332                int iColumn;
3333                int numberColumns=lpSolver->numberColumns();
3334                double * columnLower = lpSolver->columnLower();
3335                double * columnUpper = lpSolver->columnUpper();
3336                for (iColumn=0;iColumn<numberColumns;iColumn++) {
3337                  // leave free ones for now
3338                  if (columnLower[iColumn]>-1.0e20||
3339                      columnUpper[iColumn]<1.0e20) {
3340                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
3341                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
3342                  }
3343                }
3344              } else if (valid==1) {
3345                abort();
3346              } else {
3347                std::cout<<"enter value for "<<parameters[iParam].name()<<
3348                  std::endl;
3349              }
3350            }
3351            break;
3352          case REALLY_SCALE:
3353            if (goodModel) {
3354              ClpSimplex newModel(*lpSolver,
3355                                  lpSolver->scalingFlag());
3356              printf("model really really scaled\n");
3357              *lpSolver=newModel;
3358            }
3359            break;
3360          case USERCLP:
3361            // Replace the sample code by whatever you want
3362            if (goodModel) {
3363              printf("Dummy user clp code - model has %d rows and %d columns\n",
3364                     lpSolver->numberRows(),lpSolver->numberColumns());
3365            }
3366            break;
3367          case USERCBC:
3368            // Replace the sample code by whatever you want
3369            if (goodModel) {
3370              printf("Dummy user cbc code - model has %d rows and %d columns\n",
3371                     model.getNumRows(),model.getNumCols());
3372  // Reduce printout
3373  //solver1.setHintParam(OsiDoReducePrint,true,OsiHintTry);
3374  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (model.solver());
3375  // go faster stripes
3376  if (osiclp&&0) {
3377    // Turn this off if you get problems
3378    // Used to be automatically set
3379    osiclp->setSpecialOptions(128);
3380    if(osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
3381      //osiclp->setupForRepeatedUse(2,0);
3382      osiclp->setupForRepeatedUse(0,0);
3383    }
3384  } 
3385  // Allow rounding heuristic
3386
3387  CbcRounding heuristic1(model);
3388  model.addHeuristic(&heuristic1);
3389
3390  // Do initial solve to continuous
3391  ClpPrimalColumnSteepest steepest(5);
3392  osiclp->getModelPtr()->setPrimalColumnPivotAlgorithm(steepest);
3393  osiclp->getModelPtr()->setPerturbation(50);
3394  osiclp->getModelPtr()->setInfeasibilityCost(1.0e9);
3395  osiclp->setHintParam(OsiDoPresolveInInitial,false,OsiHintTry);
3396  osiclp->setHintParam(OsiDoDualInInitial,false,OsiHintTry);
3397  //osiclp->setHintParam(OsiDoDualInResolve,false,OsiHintTry);
3398  model.setSpecialOptions(model.specialOptions()|4);
3399  osiclp->getModelPtr()->defaultFactorizationFrequency();
3400  {
3401    ClpSimplex * clp = osiclp->getModelPtr();
3402    // fix integers to 1
3403    int numberColumns = clp->numberColumns();
3404    double * lower = clp->columnLower();
3405    int i;
3406    for (i=0;i<numberColumns;i++) {
3407      if (osiclp->isInteger(i))
3408        lower[i]=1.0;
3409    }
3410    clp->primal();
3411    double objValue = clp->objectiveValue();
3412    osiclp->setDblParam(OsiDualObjectiveLimit,objValue+1.0e-4);
3413    // unfix integers
3414    for (i=0;i<numberColumns;i++) {
3415      if (osiclp->isInteger(i))
3416        lower[i]=0.0;
3417    }
3418    clp->primal();
3419    //clp->dual();
3420    int nArt=0;
3421    int nFixed0=0,nFixed1=0;
3422    double gap=objValue-clp->objectiveValue();
3423    // for those at one fix anyway
3424    double gap2=1.0;
3425    const double * solution = clp->primalColumnSolution();
3426    const double * dj = clp->dualColumnSolution();
3427    const double * objective = clp->objective();
3428    double * upper = clp->columnUpper();
3429    for (i=0;i<numberColumns;i++) {
3430      if (objective[i]>1.0e5&&solution[i]>1.0e-8)
3431        nArt++;
3432      if (osiclp->isInteger(i)) {
3433        if(dj[i]>gap+1.0e-4) {
3434          nFixed0++;
3435          upper[i]=0.0;
3436        }
3437        if(-dj[i]>gap2+1.0e-4) {
3438          nFixed1++;
3439        lower[i]=1.0;
3440        }
3441      }
3442    }
3443    printf("%d artificials, %d fixed to 0, %d fixed to 1\n",nArt,nFixed0,nFixed1);
3444    //osiclp->getModelPtr()->setPerturbation(100);
3445    osiclp->setWarmStart(NULL); // set basis in osiclp
3446  }
3447  osiclp->initialSolve();
3448
3449  // Switch off strong branching if wanted
3450  // model.setNumberStrong(0);
3451  // Do more strong branching if small
3452  model.setNumberStrong(0);
3453  model.setNumberBeforeTrust(0);
3454
3455  // TEMP - set gap - better to see if no improvement in last few nodes
3456  model.setAllowableGap(600.0);
3457  // message levels
3458  model.messageHandler()->setLogLevel(2);
3459  model.solver()->messageHandler()->setLogLevel(2);
3460  // Do complete search
3461 
3462  model.branchAndBound();
3463            }
3464            break;
3465          case HELP:
3466            std::cout<<"Coin Solver version "<<CBCVERSION
3467                     <<", build "<<__DATE__<<std::endl;
3468            std::cout<<"Non default values:-"<<std::endl;
3469            std::cout<<"Perturbation "<<lpSolver->perturbation()<<" (default 100)"
3470                     <<std::endl;
3471            CoinReadPrintit(
3472                    "Presolve being done with 5 passes\n\
3473Dual steepest edge steep/partial on matrix shape and factorization density\n\
3474Clpnnnn taken out of messages\n\
3475If Factorization frequency default then done on size of matrix\n\n\
3476(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
3477You can switch to interactive mode at any time so\n\
3478clp watson.mps -scaling off -primalsimplex\nis the same as\n\
3479clp watson.mps -\nscaling off\nprimalsimplex"
3480                    );
3481            break;
3482          case SOLUTION:
3483            if (goodModel) {
3484              // get next field
3485              field = CoinReadGetString(argc,argv);
3486              if (field=="$") {
3487                field = parameters[iParam].stringValue();
3488              } else if (field=="EOL") {
3489                parameters[iParam].printString();
3490                break;
3491              } else {
3492                parameters[iParam].setStringValue(field);
3493              }
3494              std::string fileName;
3495              FILE *fp=NULL;
3496              if (field=="-"||field=="EOL"||field=="stdout") {
3497                // stdout
3498                fp=stdout;
3499              } else if (field=="stderr") {
3500                // stderr
3501                fp=stderr;
3502              } else {
3503                if (field[0]=='/'||field[0]=='\\') {
3504                  fileName = field;
3505                } else if (field[0]=='~') {
3506                  char * environVar = getenv("HOME");
3507                  if (environVar) {
3508                    std::string home(environVar);
3509                    field=field.erase(0,1);
3510                    fileName = home+field;
3511                  } else {
3512                    fileName=field;
3513                  }
3514                } else {
3515                  fileName = directory+field;
3516                }
3517                fp=fopen(fileName.c_str(),"w");
3518              }
3519              if (fp) {
3520                // make fancy later on
3521                int iRow;
3522                int numberRows=lpSolver->numberRows();
3523                double * dualRowSolution = lpSolver->dualRowSolution();
3524                double * primalRowSolution = 
3525                  lpSolver->primalRowSolution();
3526                double * rowLower = lpSolver->rowLower();
3527                double * rowUpper = lpSolver->rowUpper();
3528                double primalTolerance = lpSolver->primalTolerance();
3529                char format[6];
3530                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
3531                bool doMask = (printMask!=""&&lengthName);
3532                int * maskStarts=NULL;
3533                int maxMasks=0;
3534                char ** masks =NULL;
3535                if (doMask) {
3536                  int nAst =0;
3537                  const char * pMask2 = printMask.c_str();
3538                  char pMask[100];
3539                  int iChar;
3540                  int lengthMask = strlen(pMask2);
3541                  assert (lengthMask<100);
3542                  if (*pMask2=='"') {
3543                    if (pMask2[lengthMask-1]!='"') {
3544                      printf("mismatched \" in mask %s\n",pMask2);
3545                      break;
3546                    } else {
3547                      strcpy(pMask,pMask2+1);
3548                      *strchr(pMask,'"')='\0';
3549                    }
3550                  } else if (*pMask2=='\'') {
3551                    if (pMask2[lengthMask-1]!='\'') {
3552                      printf("mismatched ' in mask %s\n",pMask2);
3553                      break;
3554                    } else {
3555                      strcpy(pMask,pMask2+1);
3556                      *strchr(pMask,'\'')='\0';
3557                    }
3558                  } else {
3559                    strcpy(pMask,pMask2);
3560                  }
3561                  if (lengthMask>lengthName) {
3562                    printf("mask %s too long - skipping\n",pMask);
3563                    break;
3564                  }
3565                  maxMasks = 1;
3566                  for (iChar=0;iChar<lengthMask;iChar++) {
3567                    if (pMask[iChar]=='*') {
3568                      nAst++;
3569                      maxMasks *= (lengthName+1);
3570                    }
3571                  }
3572                  int nEntries = 1;
3573                  maskStarts = new int[lengthName+2];
3574                  masks = new char * [maxMasks];
3575                  char ** newMasks = new char * [maxMasks];
3576                  int i;
3577                  for (i=0;i<maxMasks;i++) {
3578                    masks[i] = new char[lengthName+1];
3579                    newMasks[i] = new char[lengthName+1];
3580                  }
3581                  strcpy(masks[0],pMask);
3582                  for (int iAst=0;iAst<nAst;iAst++) {
3583                    int nOldEntries = nEntries;
3584                    nEntries=0;
3585                    for (int iEntry = 0;iEntry<nOldEntries;iEntry++) {
3586                      char * oldMask = masks[iEntry];
3587                      char * ast = strchr(oldMask,'*');
3588                      assert (ast);
3589                      int length = strlen(oldMask)-1;
3590                      int nBefore = ast-oldMask;
3591                      int nAfter = length-nBefore;
3592                      // and add null
3593                      nAfter++;
3594                      for (int i=0;i<=lengthName-length;i++) {
3595                        char * maskOut = newMasks[nEntries];
3596                        memcpy(maskOut,oldMask,nBefore);
3597                        for (int k=0;k<i;k++) 
3598                          maskOut[k+nBefore]='?';
3599                        memcpy(maskOut+nBefore+i,ast+1,nAfter);
3600                        nEntries++;
3601                        assert (nEntries<=maxMasks);
3602                      }
3603                    }
3604                    char ** temp = masks;
3605                    masks = newMasks;
3606                    newMasks = temp;
3607                  }
3608                  // Now extend and sort
3609                  int * sort = new int[nEntries];
3610                  for (i=0;i<nEntries;i++) {
3611                    char * maskThis = masks[i];
3612                    int length = strlen(maskThis);
3613                    while (maskThis[length-1]==' ')
3614                      length--;
3615                    maskThis[length]='\0';
3616                    sort[i]=length;
3617                  }
3618                  CoinSort_2(sort,sort+nEntries,masks);
3619                  int lastLength=-1;
3620                  for (i=0;i<nEntries;i++) {
3621                    int length = sort[i];
3622                    while (length>lastLength) 
3623                      maskStarts[++lastLength] = i;
3624                  }
3625                  maskStarts[++lastLength]=nEntries;
3626                  delete [] sort;
3627                  for (i=0;i<maxMasks;i++)
3628                    delete [] newMasks[i];
3629                  delete [] newMasks;
3630                }
3631                if (printMode>2) {
3632                  for (iRow=0;iRow<numberRows;iRow++) {
3633                    int type=printMode-3;
3634                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
3635                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
3636                      fprintf(fp,"** ");
3637                      type=2;
3638                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
3639                      type=1;
3640                    } else if (numberRows<50) {
3641                      type=3;
3642                    }
3643                    if (doMask&&!maskMatches(maskStarts,masks,rowNames[iRow]))
3644                      type =0;
3645                    if (type) {
3646                      fprintf(fp,"%7d ",iRow);
3647                      if (lengthName)
3648                        fprintf(fp,format,rowNames[iRow].c_str());
3649                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
3650                              dualRowSolution[iRow]);
3651                    }
3652                  }
3653                }
3654                int iColumn;
3655                int numberColumns=lpSolver->numberColumns();
3656                double * dualColumnSolution = 
3657                  lpSolver->dualColumnSolution();
3658                double * primalColumnSolution = 
3659                  lpSolver->primalColumnSolution();
3660                double * columnLower = lpSolver->columnLower();
3661                double * columnUpper = lpSolver->columnUpper();
3662                if (printMode!=2) {
3663                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3664                    int type=(printMode>3) ? 1 :0;
3665                    if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
3666                        primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
3667                      fprintf(fp,"** ");
3668                      type=2;
3669                    } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
3670                      type=1;
3671                    } else if (numberColumns<50) {
3672                      type=3;
3673                    }
3674                    // see if integer
3675                    if ((!lpSolver->isInteger(iColumn)||fabs(primalColumnSolution[iColumn])<1.0e-8)
3676                         &&printMode==1)
3677                      type=0;
3678                    if (doMask&&!maskMatches(maskStarts,masks,
3679                                             columnNames[iColumn]))
3680                      type =0;
3681                    if (type) {
3682                      fprintf(fp,"%7d ",iColumn);
3683                      if (lengthName)
3684                        fprintf(fp,format,columnNames[iColumn].c_str());
3685                      fprintf(fp,"%15.8g        %15.8g\n",
3686                              primalColumnSolution[iColumn],
3687                              dualColumnSolution[iColumn]);
3688                    }
3689                  }
3690                } else {
3691                  // special format suitable for OsiRowCutDebugger
3692                  int n=0;
3693                  bool comma=false;
3694                  bool newLine=false;
3695                  fprintf(fp,"\tint intIndicesV[]={\n");
3696                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3697                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
3698                      if (comma)
3699                        fprintf(fp,",");
3700                      if (newLine)
3701                        fprintf(fp,"\n");
3702                      fprintf(fp,"%d ",iColumn);
3703                      comma=true;
3704                      newLine=false;
3705                      n++;
3706                      if (n==10) {
3707                        n=0;
3708                        newLine=true;
3709                      }
3710                    }
3711                  }
3712                  fprintf(fp,"};\n");
3713                  n=0;
3714                  comma=false;
3715                  newLine=false;
3716                  fprintf(fp,"\tdouble intSolnV[]={\n");
3717                  for ( iColumn=0;iColumn<numberColumns;iColumn++) {
3718                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
3719                      if (comma)
3720                        fprintf(fp,",");
3721                      if (newLine)
3722                        fprintf(fp,"\n");
3723                      int value = (int) (primalColumnSolution[iColumn]+0.5);
3724                      fprintf(fp,"%d. ",value);
3725                      comma=true;
3726                      newLine=false;
3727                      n++;
3728                      if (n==10) {
3729                        n=0;
3730                        newLine=true;
3731                      }
3732                    }
3733                  }
3734                  fprintf(fp,"};\n");
3735                }
3736                if (fp!=stdout)
3737                  fclose(fp);
3738                if (masks) {
3739                  delete [] maskStarts;
3740                  for (int i=0;i<maxMasks;i++)
3741                    delete [] masks[i];
3742                  delete [] masks;
3743                }
3744              } else {
3745                std::cout<<"Unable to open file "<<fileName<<std::endl;
3746              }
3747            } else {
3748              std::cout<<"** Current model not valid"<<std::endl;
3749             
3750            }
3751            break;
3752          case SAVESOL:
3753            if (goodModel) {
3754              // get next field
3755              field = CoinReadGetString(argc,argv);
3756              if (field=="$") {
3757                field = parameters[iParam].stringValue();
3758              } else if (field=="EOL") {
3759                parameters[iParam].printString();
3760                break;
3761              } else {
3762                parameters[iParam].setStringValue(field);
3763              }
3764              std::string fileName;
3765              if (field[0]=='/'||field[0]=='\\') {
3766                fileName = field;
3767              } else if (field[0]=='~') {
3768                char * environVar = getenv("HOME");
3769                if (environVar) {
3770                  std::string home(environVar);
3771                  field=field.erase(0,1);
3772                  fileName = home+field;
3773                } else {
3774                  fileName=field;
3775                }
3776              } else {
3777                fileName = directory+field;
3778              }
3779              saveSolution(lpSolver,fileName);
3780            } else {
3781              std::cout<<"** Current model not valid"<<std::endl;
3782             
3783            }
3784            break;
3785          case DUMMY:
3786            break;
3787          default:
3788            abort();
3789          }
3790        } 
3791      } else if (!numberMatches) {
3792        std::cout<<"No match for "<<field<<" - ? for list of commands"
3793                 <<std::endl;
3794      } else if (numberMatches==1) {
3795        if (!numberQuery) {
3796          std::cout<<"Short match for "<<field<<" - completion: ";
3797          std::cout<<parameters[firstMatch].matchName()<<std::endl;
3798        } else if (numberQuery) {
3799          std::cout<<parameters[firstMatch].matchName()<<" : ";
3800          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
3801          if (numberQuery>=2) 
3802            parameters[firstMatch].printLongHelp();
3803        }
3804      } else {
3805        if (!numberQuery) 
3806          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
3807                   <<std::endl;
3808        else
3809          std::cout<<"Completions of "<<field<<":"<<std::endl;
3810        for ( iParam=0; iParam<numberParameters; iParam++ ) {
3811          int match = parameters[iParam].matches(field);
3812          if (match&&parameters[iParam].displayThis()) {
3813            std::cout<<parameters[iParam].matchName();
3814            if (numberQuery>=2) 
3815              std::cout<<" : "<<parameters[iParam].shortHelp();
3816            std::cout<<std::endl;
3817          }
3818        }
3819      }
3820    }
3821  }
3822  // By now all memory should be freed
3823#ifdef DMALLOC
3824  dmalloc_log_unfreed();
3825  dmalloc_shutdown();
3826#endif
3827  return 0;
3828}   
3829static void breakdown(const char * name, int numberLook, const double * region)
3830{
3831  double range[] = {
3832    -COIN_DBL_MAX,
3833    -1.0e15,-1.0e11,-1.0e8,-1.0e5,-1.0e4,-1.0e3,-1.0e2,-1.0e1,
3834    -1.0,
3835    -1.0e-1,-1.0e-2,-1.0e-3,-1.0e-4,-1.0e-5,-1.0e-8,-1.0e-11,-1.0e-15,
3836    0.0,
3837    1.0e-15,1.0e-11,1.0e-8,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,
3838    1.0,
3839    1.0e1,1.0e2,1.0e3,1.0e4,1.0e5,1.0e8,1.0e11,1.0e15,
3840    COIN_DBL_MAX};
3841  int nRanges = (int) (sizeof(range)/sizeof(double));
3842  int * number = new int[nRanges];
3843  memset(number,0,nRanges*sizeof(int));
3844  int * numberExact = new int[nRanges];
3845  memset(numberExact,0,nRanges*sizeof(int));
3846  int i;
3847  for ( i=0;i<numberLook;i++) {
3848    double value = region[i];
3849    for (int j=0;j<nRanges;j++) {
3850      if (value==range[j]) {
3851        numberExact[j]++;
3852        break;
3853      } else if (value<range[j]) {
3854        number[j]++;
3855        break;
3856      }
3857    }
3858  }
3859  printf("\n%s has %d entries\n",name,numberLook);
3860  for (i=0;i<nRanges;i++) {
3861    if (number[i]) 
3862      printf("%d between %g and %g",number[i],range[i-1],range[i]);
3863    if (numberExact[i]) {
3864      if (number[i])
3865        printf(", ");
3866      printf("%d exactly at %g",numberExact[i],range[i]);
3867    }
3868    if (number[i]+numberExact[i])
3869      printf("\n");
3870  }
3871  delete [] number;
3872  delete [] numberExact;
3873}
3874static void statistics(ClpSimplex * originalModel, ClpSimplex * model)
3875{
3876  int numberColumns = originalModel->numberColumns();
3877  const char * integerInformation  = originalModel->integerInformation(); 
3878  const double * columnLower = originalModel->columnLower();
3879  const double * columnUpper = originalModel->columnUpper();
3880  int numberIntegers=0;
3881  int numberBinary=0;
3882  int iRow,iColumn;
3883  if (integerInformation) {
3884    for (iColumn=0;iColumn<numberColumns;iColumn++) {
3885      if (integerInformation[iColumn]) {
3886        if (columnUpper[iColumn]>columnLower[iColumn]) {
3887          numberIntegers++;
3888          if (columnUpper[iColumn]==0.0&&columnLower[iColumn]==1) 
3889            numberBinary++;
3890        }
3891      }
3892    }
3893  }
3894  numberColumns = model->numberColumns();
3895  int numberRows = model->numberRows();
3896  columnLower = model->columnLower();
3897  columnUpper = model->columnUpper();
3898  const double * rowLower = model->rowLower();
3899  const double * rowUpper = model->rowUpper();
3900  const double * objective = model->objective();
3901  CoinPackedMatrix * matrix = model->matrix();
3902  CoinBigIndex numberElements = matrix->getNumElements();
3903  const int * columnLength = matrix->getVectorLengths();
3904  //const CoinBigIndex * columnStart = matrix->getVectorStarts();
3905  const double * elementByColumn = matrix->getElements();
3906  int * number = new int[numberRows+1];
3907  memset(number,0,(numberRows+1)*sizeof(int));
3908  int numberObjSingletons=0;
3909  /* cType
3910     0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up,
3911     8 0/1
3912  */ 
3913  int cType[9];
3914  std::string cName[]={"0.0->inf,","0.0->up,","lo->inf,","lo->up,","free,","fixed,","-inf->0.0,",
3915                       "-inf->up,","0.0->1.0"};
3916  int nObjective=0;
3917  memset(cType,0,sizeof(cType));
3918  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3919    int length=columnLength[iColumn];
3920    if (length==1&&objective[iColumn])
3921      numberObjSingletons++;
3922    number[length]++;
3923    if (objective[iColumn])
3924      nObjective++;
3925    if (columnLower[iColumn]>-1.0e20) {
3926      if (columnLower[iColumn]==0.0) {
3927        if (columnUpper[iColumn]>1.0e20)
3928          cType[0]++;
3929        else if (columnUpper[iColumn]==1.0)
3930          cType[8]++;
3931        else if (columnUpper[iColumn]==0.0)
3932          cType[5]++;
3933        else
3934          cType[1]++;
3935      } else {
3936        if (columnUpper[iColumn]>1.0e20) 
3937          cType[2]++;
3938        else if (columnUpper[iColumn]==columnLower[iColumn])
3939          cType[5]++;
3940        else
3941          cType[3]++;
3942      }
3943    } else {
3944      if (columnUpper[iColumn]>1.0e20) 
3945        cType[4]++;
3946      else if (columnUpper[iColumn]==0.0) 
3947        cType[6]++;
3948      else
3949        cType[7]++;
3950    }
3951  }
3952  /* rType
3953     0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other,
3954     7 L 0,  8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free
3955  */ 
3956  int rType[13];
3957  std::string rName[]={"E 0.0,","E 1.0,","E -1.0,","E other,","G 0.0,","G 1.0,","G other,",
3958                       "L 0.0,","L 1.0,","L other,","Range 0.0->1.0,","Range other,","Free"};
3959  memset(rType,0,sizeof(rType));
3960  for (iRow=0;iRow<numberRows;iRow++) {
3961    if (rowLower[iRow]>-1.0e20) {
3962      if (rowLower[iRow]==0.0) {
3963        if (rowUpper[iRow]>1.0e20)
3964          rType[4]++;
3965        else if (rowUpper[iRow]==1.0)
3966          rType[10]++;
3967        else if (rowUpper[iRow]==0.0)
3968          rType[0]++;
3969        else
3970          rType[11]++;
3971      } else if (rowLower[iRow]==1.0) {
3972        if (rowUpper[iRow]>1.0e20) 
3973          rType[5]++;
3974        else if (rowUpper[iRow]==rowLower[iRow])
3975          rType[1]++;
3976        else
3977          rType[11]++;
3978      } else if (rowLower[iRow]==-1.0) {
3979        if (rowUpper[iRow]>1.0e20) 
3980          rType[6]++;
3981        else if (rowUpper[iRow]==rowLower[iRow])
3982          rType[2]++;
3983        else
3984          rType[11]++;
3985      } else {
3986        if (rowUpper[iRow]>1.0e20) 
3987          rType[6]++;
3988        else if (rowUpper[iRow]==rowLower[iRow])
3989          rType[3]++;
3990        else
3991          rType[11]++;
3992      }
3993    } else {
3994      if (rowUpper[iRow]>1.0e20) 
3995        rType[12]++;
3996      else if (rowUpper[iRow]==0.0) 
3997        rType[7]++;
3998      else if (rowUpper[iRow]==1.0) 
3999        rType[8]++;
4000      else
4001        rType[9]++;
4002    }
4003  }
4004  // Basic statistics
4005  printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n",
4006         numberRows,numberColumns,nObjective,numberElements);
4007  if (number[0]+number[1]) {
4008    printf("There are ");
4009    if (numberObjSingletons)
4010      printf("%d singletons with objective ",numberObjSingletons);
4011    int numberNoObj = number[1]-numberObjSingletons;
4012    if (numberNoObj)
4013      printf("%d singletons with no objective ",numberNoObj);
4014    if (number[0])
4015      printf("** %d columns have no entries",number[0]);
4016    printf("\n");
4017  }
4018  printf("Column breakdown:\n");
4019  int k;
4020  for (k=0;k<(int) (sizeof(cType)/sizeof(int));k++) {
4021    printf("%d of type %s ",cType[k],cName[k].c_str());
4022    if (((k+1)%3)==0)
4023      printf("\n");
4024  }
4025  if ((k%3)!=0)
4026    printf("\n");
4027  printf("Row breakdown:\n");
4028  for (k=0;k<(int) (sizeof(rType)/sizeof(int));k++) {
4029    printf("%d of type %s ",rType[k],rName[k].c_str());
4030    if (((k+1)%3)==0)
4031      printf("\n");
4032  }
4033  if ((k%3)!=0)
4034    printf("\n");
4035  if (model->logLevel()<2)
4036    return ;
4037  int kMax = model->logLevel()>3 ? 1000000 : 10;
4038  k=0;
4039  for (iRow=1;iRow<=numberRows;iRow++) {
4040    if (number[iRow]) {
4041      k++;
4042      printf("%d columns have %d entries\n",number[iRow],iRow);
4043      if (k==kMax)
4044        break;
4045    }
4046  }
4047  if (k<numberRows) {
4048    int kk=k;
4049    k=0;
4050    for (iRow=numberRows;iRow>=1;iRow--) {
4051      if (number[iRow]) {
4052        k++;
4053        if (k==kMax)
4054          break;
4055      }
4056    }
4057    if (k>kk) {
4058      printf("\n    .........\n\n");
4059      iRow=k;
4060      k=0;
4061      for (;iRow<numberRows;iRow++) {
4062        if (number[iRow]) {
4063          k++;
4064          printf("%d columns have %d entries\n",number[iRow],iRow);
4065          if (k==kMax)
4066            break;
4067        }
4068      }
4069    }
4070  }
4071  delete [] number;
4072  printf("\n\n");
4073  // get row copy
4074  CoinPackedMatrix rowCopy = *matrix;
4075  rowCopy.reverseOrdering();
4076  //const int * column = rowCopy.getIndices();
4077  const int * rowLength = rowCopy.getVectorLengths();
4078  //const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
4079  //const double * element = rowCopy.getElements();
4080  number = new int[numberColumns+1];
4081  memset(number,0,(numberColumns+1)*sizeof(int));
4082  for (iRow=0;iRow<numberRows;iRow++) {
4083    int length=rowLength[iRow];
4084    number[length]++;
4085  }
4086  if (number[0])
4087    printf("** %d rows have no entries\n",number[0]);
4088  k=0;
4089  for (iColumn=1;iColumn<=numberColumns;iColumn++) {
4090    if (number[iColumn]) {
4091      k++;
4092      printf("%d rows have %d entries\n",number[iColumn],iColumn);
4093      if (k==kMax)
4094        break;
4095    }
4096  }
4097  if (k<numberColumns) {
4098    int kk=k;
4099    k=0;
4100    for (iColumn=numberColumns;iColumn>=1;iColumn--) {
4101      if (number[iColumn]) {
4102        k++;
4103        if (k==kMax)
4104          break;
4105      }
4106    }
4107    if (k>kk) {
4108      printf("\n    .........\n\n");
4109      iColumn=k;
4110      k=0;
4111      for (;iColumn<numberColumns;iColumn++) {
4112        if (number[iColumn]) {
4113          k++;
4114          printf("%d rows have %d entries\n",number[iColumn],iColumn);
4115          if (k==kMax)
4116            break;
4117        }
4118      }
4119    }
4120  }
4121  delete [] number;
4122  // Now do breakdown of ranges
4123  breakdown("Elements",numberElements,elementByColumn);
4124  breakdown("RowLower",numberRows,rowLower);
4125  breakdown("RowUpper",numberRows,rowUpper);
4126  breakdown("ColumnLower",numberColumns,columnLower);
4127  breakdown("ColumnUpper",numberColumns,columnUpper);
4128  breakdown("Objective",numberColumns,objective);
4129}
4130static bool maskMatches(const int * starts, char ** masks,
4131                        std::string & check)
4132{
4133  // back to char as I am old fashioned
4134  const char * checkC = check.c_str();
4135  int length = strlen(checkC);
4136  while (checkC[length-1]==' ')
4137    length--;
4138  for (int i=starts[length];i<starts[length+1];i++) {
4139    char * thisMask = masks[i];
4140    int k;
4141    for ( k=0;k<length;k++) {
4142      if (thisMask[k]!='?'&&thisMask[k]!=checkC[k]) 
4143        break;
4144    }
4145    if (k==length)
4146      return true;
4147  }
4148  return false;
4149}
4150static void clean(char * temp)
4151{
4152  char * put = temp;
4153  while (*put>=' ')
4154    put++;
4155  *put='\0';
4156}
4157static void generateCode(const char * fileName,int type,int preProcess)
4158{
4159  // options on code generation
4160  bool sizecode = (type&4)!=0;
4161  type &= 3;
4162  FILE * fp = fopen(fileName,"r");
4163  assert (fp);
4164  int numberLines=0;
4165#define MAXLINES 5000
4166#define MAXONELINE 200
4167  char line[MAXLINES][MAXONELINE];
4168  strcpy(line[numberLines++],"0#if defined(_MSC_VER)");
4169  strcpy(line[numberLines++],"0// Turn off compiler warning about long names");
4170  strcpy(line[numberLines++],"0#  pragma warning(disable:4786)");
4171  strcpy(line[numberLines++],"0#endif\n");
4172  strcpy(line[numberLines++],"0#include <cassert>");
4173  strcpy(line[numberLines++],"0#include <iomanip>");
4174  strcpy(line[numberLines++],"0#include \"OsiClpSolverInterface.hpp\"");
4175  strcpy(line[numberLines++],"0#include \"CbcModel.hpp\"");
4176  strcpy(line[numberLines++],"0#include \"CbcCutGenerator.hpp\"");
4177  strcpy(line[numberLines++],"0#include \"CbcStrategy.hpp\"");
4178  strcpy(line[numberLines++],"0#include \"CglPreProcess.hpp\"");
4179  strcpy(line[numberLines++],"0#include \"CoinTime.hpp\"");
4180  while (fgets(line[numberLines],MAXONELINE,fp)) {
4181    assert (numberLines<MAXLINES);
4182    clean(line[numberLines]);
4183    numberLines++;
4184  }
4185  fclose(fp);
4186  strcpy(line[numberLines++],"0\nint main (int argc, const char *argv[])\n{");
4187  strcpy(line[numberLines++],"0  OsiClpSolverInterface solver1;");
4188  strcpy(line[numberLines++],"0  int status=1;");
4189  strcpy(line[numberLines++],"0  if (argc<2)");
4190  strcpy(line[numberLines++],"0    std::cout<<\"Please give file name\"<<std::endl;");
4191  strcpy(line[numberLines++],"0  else");
4192  strcpy(line[numberLines++],"0    status=solver1.readMps(argv[1],\"\");");
4193  strcpy(line[numberLines++],"0  if (status) {");
4194  strcpy(line[numberLines++],"0    std::cout<<\"Bad readMps \"<<argv[1]<<std::endl;");
4195  strcpy(line[numberLines++],"0    exit(1);");
4196  strcpy(line[numberLines++],"0  }\n");
4197  strcpy(line[numberLines++],"0  double time1 = CoinCpuTime();");
4198  strcpy(line[numberLines++],"0  CbcModel model(solver1);");
4199  strcpy(line[numberLines++],"0  // Now do requested saves and modifications");
4200  strcpy(line[numberLines++],"0  CbcModel * cbcModel = & model;");
4201  strcpy(line[numberLines++],"0  OsiSolverInterface * osiModel = model.solver();");
4202  strcpy(line[numberLines++],"0  OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);");
4203  strcpy(line[numberLines++],"0  ClpSimplex * clpModel = osiclpModel->getModelPtr();");
4204  // add in comments about messages
4205  strcpy(line[numberLines++],"3  // You can save some time by switching off message building");
4206  strcpy(line[numberLines++],"3  // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);");
4207  strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4208  strcpy(line[numberLines++],"5  if (clpModel->tightenPrimalBounds()!=0) {");
4209  strcpy(line[numberLines++],"5    std::cout<<\"Problem is infeasible - tightenPrimalBounds!\"<<std::endl;");
4210  strcpy(line[numberLines++],"5    exit(1);");
4211  strcpy(line[numberLines++],"5  }");
4212  strcpy(line[numberLines++],"5  clpModel->dual();  // clean up");
4213  if (sizecode) {
4214    // override some settings
4215    strcpy(line[numberLines++],"5  // compute some things using problem size");
4216    strcpy(line[numberLines++],"5  cbcModel->setMinimumDrop(min(5.0e-2,");
4217    strcpy(line[numberLines++],"5       fabs(cbcModel->getMinimizationObjValue())*1.0e-3+1.0e-4));");
4218    strcpy(line[numberLines++],"5  if (cbcModel->getNumCols()<500)");
4219    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible");
4220    strcpy(line[numberLines++],"5  else if (cbcModel->getNumCols()<5000)");
4221    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(100); // use minimum drop");
4222    strcpy(line[numberLines++],"5  else");
4223    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(20);");
4224    strcpy(line[numberLines++],"5  cbcModel->setMaximumCutPasses(1);");
4225  }
4226  if (preProcess<=0) {
4227    // no preprocessing or strategy
4228    if (preProcess) {
4229      strcpy(line[numberLines++],"5  // Preprocessing using CbcStrategy");
4230      strcpy(line[numberLines++],"5  CbcStrategyDefault strategy(true,5,5);");
4231      strcpy(line[numberLines++],"5  strategy.setupPreProcessing(1);");
4232      strcpy(line[numberLines++],"5  cbcModel->setStrategy(strategy);");
4233    }
4234  } else {
4235    int translate[]={9999,0,0,-1,2,3};
4236    strcpy(line[numberLines++],"5  // Hand coded preprocessing");
4237    strcpy(line[numberLines++],"5  CglPreProcess process;");
4238    strcpy(line[numberLines++],"5  OsiSolverInterface * saveSolver=cbcModel->solver()->clone();");
4239    strcpy(line[numberLines++],"5  // Tell solver we are in Branch and Cut");
4240    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;");
4241    strcpy(line[numberLines++],"5  // Default set of cut generators");
4242    strcpy(line[numberLines++],"5  CglProbing generator1;");
4243    strcpy(line[numberLines++],"5  generator1.setUsingObjective(true);");
4244    strcpy(line[numberLines++],"5  generator1.setMaxPass(3);");
4245    strcpy(line[numberLines++],"5  generator1.setMaxProbeRoot(saveSolver->getNumCols());");
4246    strcpy(line[numberLines++],"5  generator1.setMaxElements(100);");
4247    strcpy(line[numberLines++],"5  generator1.setMaxLookRoot(50);");
4248    strcpy(line[numberLines++],"5  generator1.setRowCuts(3);");
4249    strcpy(line[numberLines++],"5  // Add in generators");
4250    strcpy(line[numberLines++],"5  process.addCutGenerator(&generator1);");
4251    strcpy(line[numberLines++],"5  process.messageHandler()->setLogLevel(cbcModel->logLevel());");
4252    strcpy(line[numberLines++],"5  OsiSolverInterface * solver2 = ");
4253    sprintf(line[numberLines++],"5    process.preProcessNonDefault(*saveSolver,%d,10);",translate[preProcess]);
4254    strcpy(line[numberLines++],"5  // Tell solver we are not in Branch and Cut");
4255    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4256    strcpy(line[numberLines++],"5  if (solver2)");
4257    strcpy(line[numberLines++],"5    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4258    strcpy(line[numberLines++],"5  if (!solver2) {");
4259    strcpy(line[numberLines++],"5    std::cout<<\"Pre-processing says infeasible!\"<<std::endl;");
4260    strcpy(line[numberLines++],"5    exit(1);");
4261    strcpy(line[numberLines++],"5  } else {");
4262    strcpy(line[numberLines++],"5    std::cout<<\"processed model has \"<<solver2->getNumRows()");
4263    strcpy(line[numberLines++],"5            <<\" rows, \"<<solver2->getNumCols()");
4264    strcpy(line[numberLines++],"5            <<\" and \"<<solver2->getNumElements()<<std::endl;");
4265    strcpy(line[numberLines++],"5  }");
4266    strcpy(line[numberLines++],"5  // we have to keep solver2 so pass clone");
4267    strcpy(line[numberLines++],"5  solver2 = solver2->clone();");
4268    strcpy(line[numberLines++],"5  cbcModel->assignSolver(solver2);");
4269    strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4270  }
4271  // add in actual solve
4272  strcpy(line[numberLines++],"5  cbcModel->branchAndBound();");
4273  strcpy(line[numberLines++],"8  std::cout<<argv[1]<<\" took \"<<CoinCpuTime()-time1<<\" seconds, \"");
4274  strcpy(line[numberLines++],"8    <<cbcModel->getNodeCount()<<\" nodes with objective \"");
4275  strcpy(line[numberLines++],"8    <<cbcModel->getObjValue()");
4276  strcpy(line[numberLines++],"8    <<(!cbcModel->status() ? \" Finished\" : \" Not finished\")");
4277  strcpy(line[numberLines++],"8    <<std::endl;");
4278  strcpy(line[numberLines++],"5  // For best solution");
4279  strcpy(line[numberLines++],"5  int numberColumns = solver1.getNumCols();");
4280  strcpy(line[numberLines++],"5  if (cbcModel->getMinimizationObjValue()<1.0e50) {");
4281  if (preProcess>0) {
4282    strcpy(line[numberLines++],"5    // post process");
4283    strcpy(line[numberLines++],"5    process.postProcess(*cbcModel->solver());");
4284    strcpy(line[numberLines++],"5    // Solution now back in saveSolver");
4285    strcpy(line[numberLines++],"5    cbcModel->assignSolver(saveSolver);");
4286    strcpy(line[numberLines++],"5    memcpy(cbcModel->bestSolution(),cbcModel->solver()->getColSolution(),");
4287    strcpy(line[numberLines++],"5          numberColumns*sizeof(double));");
4288  }
4289  strcpy(line[numberLines++],"5    // put back in original solver");
4290  strcpy(line[numberLines++],"5    solver1.setColSolution(cbcModel->bestSolution());");
4291  strcpy(line[numberLines++],"5    const double * solution = solver1.getColSolution();");
4292  strcpy(line[numberLines++],"8  \n  // Now you would use solution etc etc\n");
4293  strcpy(line[numberLines++],"5");
4294  strcpy(line[numberLines++],"5    // Get names from solver1 (as OsiSolverInterface may lose)");
4295  strcpy(line[numberLines++],"5    std::vector<std::string> columnNames = *solver1.getModelPtr()->columnNames();");
4296  strcpy(line[numberLines++],"5    ");
4297  strcpy(line[numberLines++],"5    int iColumn;");
4298  strcpy(line[numberLines++],"5    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);");
4299  strcpy(line[numberLines++],"5    ");
4300  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4301  strcpy(line[numberLines++],"5    for (iColumn=0;iColumn<numberColumns;iColumn++) {");
4302  strcpy(line[numberLines++],"5      double value=solution[iColumn];");
4303  strcpy(line[numberLines++],"5      if (fabs(value)>1.0e-7&&solver1.isInteger(iColumn)) ");
4304  strcpy(line[numberLines++],"5 std::cout<<std::setw(6)<<iColumn<<\" \"");
4305  strcpy(line[numberLines++],"5                 <<columnNames[iColumn]<<\" \"");
4306  strcpy(line[numberLines++],"5                 <<value<<std::endl;");
4307  strcpy(line[numberLines++],"5    }");
4308  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4309  strcpy(line[numberLines++],"5  ");
4310  strcpy(line[numberLines++],"5    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);");
4311  strcpy(line[numberLines++],"5  }");
4312  strcpy(line[numberLines++],"8  return 0;\n}");
4313  fp = fopen(fileName,"w");
4314  assert (fp);
4315
4316  int wanted[9];
4317  memset(wanted,0,sizeof(wanted));
4318  wanted[0]=wanted[3]=wanted[5]=wanted[8]=1;
4319  if (type>0) 
4320    wanted[1]=wanted[6]=1;
4321  if (type>1) 
4322    wanted[2]=wanted[4]=wanted[7]=1;
4323  std::string header[9]=
4324  { "","Save values","Redundant save of default values","Set changed values",
4325    "Redundant set default values","Solve","Restore values","Redundant restore values","Add to model"};
4326  for (int iType=0;iType<9;iType++) {
4327    if (!wanted[iType])
4328      continue;
4329    int n=0;
4330    int iLine;
4331    for (iLine=0;iLine<numberLines;iLine++) {
4332      if (line[iLine][0]=='0'+iType) {
4333        if (!n&&header[iType]!="")
4334          fprintf(fp,"\n  // %s\n\n",header[iType].c_str());
4335        n++;
4336        // skip save and clp as cloned
4337        if (!strstr(line[iLine],"save")||(!strstr(line[iLine],"clpMo")&&
4338                                          !strstr(line[iLine],"_Osi")))
4339          fprintf(fp,"%s\n",line[iLine]+1);
4340      }
4341    }
4342  }
4343  fclose(fp);
4344  printf("C++ file written to %s\n",fileName);
4345}
4346/*
4347  Version 1.00.00 November 16 2005.
4348  This is to stop me (JJF) messing about too much.
4349  Tuning changes should be noted here.
4350  The testing next version may be activated by CBC_NEXT_VERSION
4351  This applies to OsiClp, Clp etc
4352  Version 1.00.01 November 24 2005
4353  Added several classes for advanced users.  This can't affect code (if you don't use it)
4354  Made some tiny changes (for N way branching) which should not change anything.
4355  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
4356  CbcBranchAllDifferent object class - for branching on general integer variables
4357  to stop them having same value so branches are x >= y+1 and x <= y-1.
4358  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
4359  and CglStored which just has a list of cuts which can be activated.
4360  Modified preprocess option to SOS
4361  Version 1.00.02 December 9 2005
4362  Added use of CbcStrategy to do clean preprocessing
4363  Added use of referenceSolver for cleaner repetition of Cbc
4364  Version 1.01.00 February 2 2006
4365  Added first try at Ampl interface
4366*/
Note: See TracBrowser for help on using the repository browser.