source: branches/devel/Cbc/src/CoinSolve.cpp @ 400

Last change on this file since 400 was 391, checked in by forrest, 13 years ago

for ampl and version

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