source: stable/1.1/Cbc/src/CoinSolve.cpp @ 450

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

modify CoinSolve? so will solve all 44 with -miplib

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 160.3 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              if (type==MIPLIB) {
1858                if (babModel->numberStrong()==5&&babModel->numberBeforeTrust()==5) 
1859                  babModel->setNumberBeforeTrust(50);
1860              }
1861              // add cut generators if wanted
1862              int switches[20];
1863              int numberGenerators=0;
1864              if (probingAction==1) {
1865                babModel->addCutGenerator(&probingGen,-1,"Probing");
1866                switches[numberGenerators++]=0;
1867              } else if (probingAction>=2) {
1868                babModel->addCutGenerator(&probingGen,-101+probingAction,"Probing");
1869                switches[numberGenerators++]=0;
1870              }
1871              if (gomoryAction==1) {
1872                babModel->addCutGenerator(&gomoryGen,-1,"Gomory");
1873                switches[numberGenerators++]=1;
1874              } else if (gomoryAction>=2) {
1875                babModel->addCutGenerator(&gomoryGen,-101+gomoryAction,"Gomory");
1876                switches[numberGenerators++]=-1;
1877              }
1878              if (knapsackAction==1) {
1879                babModel->addCutGenerator(&knapsackGen,-1,"Knapsack");
1880                switches[numberGenerators++]=0;
1881              } else if (knapsackAction>=2) {
1882                babModel->addCutGenerator(&knapsackGen,-101+knapsackAction,"Knapsack");
1883                switches[numberGenerators++]=0;
1884              }
1885              if (redsplitAction==1) {
1886                babModel->addCutGenerator(&redsplitGen,-1,"Reduce-and-split");
1887                switches[numberGenerators++]=1;
1888              } else if (redsplitAction>=2) {
1889                babModel->addCutGenerator(&redsplitGen,-101+redsplitAction,"Reduce-and-split");
1890                switches[numberGenerators++]=1;
1891              }
1892              if (cliqueAction==1) {
1893                babModel->addCutGenerator(&cliqueGen,-1,"Clique");
1894                switches[numberGenerators++]=1;
1895              } else if (cliqueAction>=2) {
1896                babModel->addCutGenerator(&cliqueGen,-101+cliqueAction,"Clique");
1897                switches[numberGenerators++]=-1;
1898              }
1899              if (mixedAction==1) {
1900                babModel->addCutGenerator(&mixedGen,-1,"MixedIntegerRounding2");
1901                switches[numberGenerators++]=1;
1902              } else if (mixedAction>=2) {
1903                babModel->addCutGenerator(&mixedGen,-101+mixedAction,"MixedIntegerRounding2");
1904                switches[numberGenerators++]=-1;
1905              }
1906              if (flowAction==1) {
1907                babModel->addCutGenerator(&flowGen,-1,"FlowCover");
1908                switches[numberGenerators++]=1;
1909              } else if (flowAction>=2) {
1910                babModel->addCutGenerator(&flowGen,-101+flowAction,"FlowCover");
1911                switches[numberGenerators++]=1;
1912              }
1913              if (twomirAction==1) {
1914                babModel->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
1915                switches[numberGenerators++]=1;
1916              } else if (twomirAction>=2) {
1917                babModel->addCutGenerator(&twomirGen,-101+twomirAction,"TwoMirCuts");
1918                switches[numberGenerators++]=1;
1919              }
1920              // Say we want timings
1921              numberGenerators = babModel->numberCutGenerators();
1922              int iGenerator;
1923              int cutDepth=
1924                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
1925              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1926                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1927                int howOften = generator->howOften();
1928                if (howOften==-98||howOften==-99) 
1929                  generator->setSwitchOffIfLessThan(switches[iGenerator]);
1930                generator->setTiming(true);
1931                if (cutDepth>=0)
1932                  generator->setWhatDepth(cutDepth) ;
1933              }
1934              // Could tune more
1935              if (!miplib) {
1936                babModel->setMinimumDrop(min(5.0e-2,
1937                                             fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
1938                if (cutPass==-1234567) {
1939                  if (babModel->getNumCols()<500)
1940                    babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
1941                  else if (babModel->getNumCols()<5000)
1942                    babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
1943                  else
1944                    babModel->setMaximumCutPassesAtRoot(20);
1945                } else {
1946                  babModel->setMaximumCutPassesAtRoot(cutPass);
1947                }
1948                babModel->setMaximumCutPasses(1);
1949              }
1950              // Do more strong branching if small
1951              //if (babModel->getNumCols()<5000)
1952              //babModel->setNumberStrong(20);
1953              // Switch off strong branching if wanted
1954              //if (babModel->getNumCols()>10*babModel->getNumRows())
1955              //babModel->setNumberStrong(0);
1956              if (!noPrinting) {
1957                babModel->messageHandler()->setLogLevel(parameters[log].intValue());
1958                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
1959                    babModel->messageHandler()->logLevel()>1)
1960                  babModel->setPrintFrequency(100);
1961              }
1962             
1963              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,
1964                    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].intValue());
1965              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1966              // go faster stripes
1967              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
1968                osiclp->setupForRepeatedUse(2,parameters[slog].intValue());
1969              } else {
1970                osiclp->setupForRepeatedUse(0,parameters[slog].intValue());
1971              }
1972              double increment=babModel->getCutoffIncrement();;
1973              int * changed = NULL;
1974              if (!miplib)
1975                changed=analyze( osiclp,numberChanged,increment,false);
1976              if (debugValues) {
1977                if (numberDebugValues==babModel->getNumCols()) {
1978                  // for debug
1979                  babModel->solver()->activateRowCutDebugger(debugValues) ;
1980                } else {
1981                  printf("debug file has incorrect number of columns\n");
1982                }
1983              }
1984              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
1985              // Turn this off if you get problems
1986              // Used to be automatically set
1987              int mipOptions = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue();
1988              if (mipOptions!=(128|64|1))
1989                printf("mip options %d\n",mipOptions);
1990              osiclp->setSpecialOptions(mipOptions);
1991              if (gapRatio < 1.0e100) {
1992                double value = babModel->solver()->getObjValue() ;
1993                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
1994                babModel->setAllowableGap(value2) ;
1995                std::cout << "Continuous " << value
1996                          << ", so allowable gap set to "
1997                          << value2 << std::endl ;
1998              }
1999              // probably faster to use a basis to get integer solutions
2000              babModel->setSpecialOptions(2);
2001              currentBranchModel = babModel;
2002              OsiSolverInterface * strengthenedModel=NULL;
2003              if (type==BAB||type==MIPLIB) {
2004                int moreMipOptions = parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].intValue();
2005                if (moreMipOptions>=0) {
2006                  printf("more mip options %d\n",moreMipOptions);
2007                  babModel->setSearchStrategy(moreMipOptions);
2008                }
2009              }
2010              if (type==BAB) {
2011#ifdef COIN_HAS_ASL
2012                if (usingAmpl) {
2013                  priorities=info.priorities;
2014                  branchDirection=info.branchDirection;
2015                  pseudoDown=info.pseudoDown;
2016                  pseudoUp=info.pseudoUp;
2017                  solutionIn=info.primalSolution;
2018                  prioritiesIn = info.priorities;
2019                  if (info.numberSos&&doSOS) {
2020                    // SOS
2021                    numberSOS = info.numberSos;
2022                    sosStart = info.sosStart;
2023                    sosIndices = info.sosIndices;
2024                    sosType = info.sosType;
2025                    sosReference = info.sosReference;
2026                    sosPriority = info.sosPriority;
2027                  }
2028                }
2029#endif               
2030                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
2031                if (solutionIn&&useSolution) {
2032                  if (preProcess) {
2033                    int numberColumns = babModel->getNumCols();
2034                    // extend arrays in case SOS
2035                    int n = originalColumns[numberColumns-1]+1;
2036                    int nSmaller = CoinMin(n,numberOriginalColumns);
2037                    double * solutionIn2 = new double [n];
2038                    int * prioritiesIn2 = new int[n];
2039                    int i;
2040                    for (i=0;i<nSmaller;i++) {
2041                      solutionIn2[i]=solutionIn[i];
2042                      prioritiesIn2[i]=prioritiesIn[i];
2043                    }
2044                    for (;i<n;i++) {
2045                      solutionIn2[i]=0.0;
2046                      prioritiesIn2[i]=1000000;
2047                    }
2048                    int iLast=-1;
2049                    for (i=0;i<numberColumns;i++) {
2050                      int iColumn = originalColumns[i];
2051                      assert (iColumn>iLast);
2052                      iLast=iColumn;
2053                      solutionIn2[i]=solutionIn2[iColumn];
2054                      if (prioritiesIn)
2055                        prioritiesIn2[i]=prioritiesIn2[iColumn];
2056                    }
2057                    babModel->setHotstartSolution(solutionIn2,prioritiesIn2);
2058                    delete [] solutionIn2;
2059                    delete [] prioritiesIn2;
2060                  } else {
2061                    babModel->setHotstartSolution(solutionIn,prioritiesIn);
2062                  }
2063                }
2064                if (preProcess&&process.numberSOS()) {
2065                  int numberSOS = process.numberSOS();
2066                  int numberIntegers = babModel->numberIntegers();
2067                  /* model may not have created objects
2068                     If none then create
2069                  */
2070                  if (!numberIntegers||!babModel->numberObjects()) {
2071                    int type = (pseudoUp) ? 1 : 0;
2072                    babModel->findIntegers(true,type);
2073                    numberIntegers = babModel->numberIntegers();
2074                  }
2075                  CbcObject ** oldObjects = babModel->objects();
2076                  // Do sets and priorities
2077                  CbcObject ** objects = new CbcObject * [numberSOS];
2078                  // set old objects to have low priority
2079                  int numberOldObjects = babModel->numberObjects();
2080                  int numberColumns = babModel->getNumCols();
2081                  for (int iObj = 0;iObj<numberOldObjects;iObj++) {
2082                    oldObjects[iObj]->setPriority(numberColumns+1);
2083                    int iColumn = oldObjects[iObj]->columnNumber();
2084                    assert (iColumn>=0);
2085                    if (iColumn>=numberOriginalColumns)
2086                      continue;
2087                    if (originalColumns)
2088                      iColumn = originalColumns[iColumn];
2089                    if (branchDirection)
2090                      oldObjects[iObj]->setPreferredWay(branchDirection[iColumn]);
2091                    if (pseudoUp) {
2092                      CbcSimpleIntegerPseudoCost * obj1a =
2093                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
2094                      assert (obj1a);
2095                      if (pseudoDown[iColumn]>0.0)
2096                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2097                      if (pseudoUp[iColumn]>0.0)
2098                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2099                    }
2100                  }
2101                  const int * starts = process.startSOS();
2102                  const int * which = process.whichSOS();
2103                  const int * type = process.typeSOS();
2104                  const double * weight = process.weightSOS();
2105                  int iSOS;
2106                  for (iSOS =0;iSOS<numberSOS;iSOS++) {
2107                    int iStart = starts[iSOS];
2108                    int n=starts[iSOS+1]-iStart;
2109                    objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
2110                                               iSOS,type[iSOS]);
2111                    // branch on long sets first
2112                    objects[iSOS]->setPriority(numberColumns-n);
2113                  }
2114                  babModel->addObjects(numberSOS,objects);
2115                  for (iSOS=0;iSOS<numberSOS;iSOS++)
2116                    delete objects[iSOS];
2117                  delete [] objects;
2118                } else if (priorities||branchDirection||pseudoDown||pseudoUp||numberSOS) {
2119                  // do anyway for priorities etc
2120                  int numberIntegers = babModel->numberIntegers();
2121                  /* model may not have created objects
2122                     If none then create
2123                  */
2124                  if (!numberIntegers||!babModel->numberObjects()) {
2125                    int type = (pseudoUp) ? 1 : 0;
2126                    babModel->findIntegers(true,type);
2127                  }
2128                  if (numberSOS) {
2129                    // Do sets and priorities
2130                    CbcObject ** objects = new CbcObject * [numberSOS];
2131                    int iSOS;
2132                    if (originalColumns) {
2133                      // redo sequence numbers
2134                      int numberColumns = babModel->getNumCols();
2135                      int nOld = originalColumns[numberColumns-1]+1;
2136                      int * back = new int[nOld];
2137                      int i;
2138                      for (i=0;i<nOld;i++)
2139                        back[i]=-1;
2140                      for (i=0;i<numberColumns;i++)
2141                        back[originalColumns[i]]=i;
2142                      // Really need better checks
2143                      int nMissing=0;
2144                      int n=sosStart[numberSOS];
2145                      for (i=0;i<n;i++) {
2146                        int iColumn = sosIndices[i];
2147                        int jColumn = back[iColumn];
2148                        if (jColumn>=0) 
2149                          sosIndices[i] = jColumn;
2150                        else 
2151                          nMissing++;
2152                      }
2153                      delete [] back;
2154                      if (nMissing)
2155                        printf("%d SOS variables vanished due to pre processing? - check validity?\n",nMissing);
2156                    }
2157                    for (iSOS =0;iSOS<numberSOS;iSOS++) {
2158                      int iStart = sosStart[iSOS];
2159                      int n=sosStart[iSOS+1]-iStart;
2160                      objects[iSOS] = new CbcSOS(babModel,n,sosIndices+iStart,sosReference+iStart,
2161                                                 iSOS,sosType[iSOS]);
2162                      if (sosPriority)
2163                        objects[iSOS]->setPriority(sosPriority[iSOS]);
2164                      else if (!prioritiesIn)
2165                        objects[iSOS]->setPriority(10);  // rather than 1000
2166                    }
2167                    babModel->addObjects(numberSOS,objects);
2168                    for (iSOS=0;iSOS<numberSOS;iSOS++)
2169                      delete objects[iSOS];
2170                    delete [] objects;
2171                  }
2172                  CbcObject ** objects = babModel->objects();
2173                  int numberObjects = babModel->numberObjects();
2174                  for (int iObj = 0;iObj<numberObjects;iObj++) {
2175                    // skip sos
2176                    CbcSOS * objSOS =
2177                      dynamic_cast <CbcSOS *>(objects[iObj]) ;
2178                    if (objSOS)
2179                      continue;
2180                    int iColumn = objects[iObj]->columnNumber();
2181                    assert (iColumn>=0);
2182                    if (originalColumns)
2183                      iColumn = originalColumns[iColumn];
2184                    if (branchDirection)
2185                      objects[iObj]->setPreferredWay(branchDirection[iColumn]);
2186                    if (priorities) {
2187                      int iPriority = priorities[iColumn];
2188                      if (iPriority>0)
2189                        objects[iObj]->setPriority(iPriority);
2190                    }
2191                    if (pseudoUp&&pseudoUp[iColumn]) {
2192                      CbcSimpleIntegerPseudoCost * obj1a =
2193                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
2194                      assert (obj1a);
2195                      if (pseudoDown[iColumn]>0.0)
2196                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2197                      if (pseudoUp[iColumn]>0.0)
2198                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2199                    }
2200                  }
2201                }
2202                int statistics = (printOptions>0) ? printOptions: 0;
2203#ifdef COIN_HAS_ASL
2204                if (!usingAmpl) {
2205#endif
2206                  free(priorities);
2207                  priorities=NULL;
2208                  free(branchDirection);
2209                  branchDirection=NULL;
2210                  free(pseudoDown);
2211                  pseudoDown=NULL;
2212                  free(pseudoUp);
2213                  pseudoUp=NULL;
2214                  free(solutionIn);
2215                  solutionIn=NULL;
2216                  free(prioritiesIn);
2217                  prioritiesIn=NULL;
2218                  free(sosStart);
2219                  sosStart=NULL;
2220                  free(sosIndices);
2221                  sosIndices=NULL;
2222                  free(sosType);
2223                  sosType=NULL;
2224                  free(sosReference);
2225                  sosReference=NULL;
2226                  free(sosPriority);
2227                  sosPriority=NULL;
2228#ifdef COIN_HAS_ASL
2229                }
2230#endif               
2231                if (cppValue>=0) {
2232                  int prepro = useStrategy ? -1 : preProcess;
2233                  // generate code
2234                  FILE * fp = fopen("user_driver.cpp","w");
2235                  if (fp) {
2236                    // generate enough to do BAB
2237                    babModel->generateCpp(fp,1);
2238                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2239                    // Make general so do factorization
2240                    int factor = osiclp->getModelPtr()->factorizationFrequency();
2241                    osiclp->getModelPtr()->setFactorizationFrequency(200);
2242                    osiclp->generateCpp(fp);
2243                    osiclp->getModelPtr()->setFactorizationFrequency(factor);
2244                    //solveOptions.generateCpp(fp);
2245                    fclose(fp);
2246                    // now call generate code
2247                    generateCode("user_driver.cpp",cppValue,prepro);
2248                  } else {
2249                    std::cout<<"Unable to open file user_driver.cpp"<<std::endl;
2250                  }
2251                }
2252                if (useStrategy) {
2253                  CbcStrategyDefault strategy(true,5,5);
2254                  strategy.setupPreProcessing(1);
2255                  babModel->setStrategy(strategy);
2256                }
2257                babModel->branchAndBound(statistics);
2258              } else if (type==MIPLIB) {
2259                CbcStrategyDefault strategy(true,5,5);
2260                // Set up pre-processing to find sos if wanted
2261                if (preProcess)
2262                  strategy.setupPreProcessing(2);
2263                babModel->setStrategy(strategy);
2264                CbcClpUnitTest(*babModel);
2265                goodModel=false;
2266                break;
2267              } else {
2268                strengthenedModel = babModel->strengthenedModel();
2269              }
2270              currentBranchModel = NULL;
2271              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2272              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
2273                lpSolver = osiclp->getModelPtr();
2274                //move best solution (should be there -- but ..)
2275                int n = lpSolver->getNumCols();
2276                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
2277                saveSolution(osiclp->getModelPtr(),"debug.file");
2278              }
2279              if (!noPrinting) {
2280                // Print more statistics
2281                std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
2282                         <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
2283               
2284                for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
2285                  CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
2286                  std::cout<<generator->cutGeneratorName()<<" was tried "
2287                           <<generator->numberTimesEntered()<<" times and created "
2288                           <<generator->numberCutsInTotal()<<" cuts of which "
2289                           <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
2290                  if (generator->timing())
2291                    std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
2292                  else
2293                    std::cout<<std::endl;
2294                }
2295              }
2296              time2 = CoinCpuTime();
2297              totalTime += time2-time1;
2298              // For best solution
2299              double * bestSolution = NULL;
2300              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
2301                // post process
2302                if (preProcess) {
2303                  int n = saveSolver->getNumCols();
2304                  bestSolution = new double [n];
2305                  process.postProcess(*babModel->solver());
2306                  // Solution now back in saveSolver
2307                  babModel->assignSolver(saveSolver);
2308                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2309                } else {
2310                  int n = babModel->solver()->getNumCols();
2311                  bestSolution = new double [n];
2312                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2313                }
2314              }
2315              if (type==STRENGTHEN&&strengthenedModel)
2316                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
2317              lpSolver = clpSolver->getModelPtr();
2318              if (numberChanged) {
2319                for (int i=0;i<numberChanged;i++) {
2320                  int iColumn=changed[i];
2321                  clpSolver->setContinuous(iColumn);
2322                }
2323                delete [] changed;
2324              }
2325              if (type==BAB) {
2326                //move best solution (should be there -- but ..)
2327                int n = lpSolver->getNumCols();
2328                if (bestSolution)
2329                  memcpy(lpSolver->primalColumnSolution(),bestSolution,n*sizeof(double));
2330                if (debugFile=="create"&&bestSolution) {
2331                  saveSolution(lpSolver,"debug.file");
2332                }
2333                delete [] bestSolution;
2334                std::string statusName[]={"Finished","Stopped on ","Difficulties",
2335                                          "","","User ctrl-c"};
2336                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
2337                int iStat = babModel->status();
2338                int iStat2 = babModel->secondaryStatus();
2339                if (!noPrinting)
2340                  std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
2341                           <<" objective "<<babModel->getObjValue()<<
2342                    " after "<<babModel->getNodeCount()<<" nodes and "
2343                           <<babModel->getIterationCount()<<
2344                    " iterations - took "<<time2-time1<<" seconds"<<std::endl;
2345#ifdef COIN_HAS_ASL
2346                if (usingAmpl) {
2347                  double value = babModel->getObjValue()*lpSolver->getObjSense();
2348                  char buf[300];
2349                  int pos=0;
2350                  if (iStat==0) {
2351                    if (babModel->getObjValue()<1.0e40) {
2352                      pos += sprintf(buf+pos,"optimal," );
2353                    } else {
2354                      // infeasible
2355                      iStat=1;
2356                      pos += sprintf(buf+pos,"infeasible,");
2357                    }
2358                  } else if (iStat==1) {
2359                    if (iStat2!=6)
2360                      iStat=3;
2361                    else
2362                      iStat=4;
2363                    pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
2364                  } else if (iStat==2) {
2365                    iStat = 7;
2366                    pos += sprintf(buf+pos,"stopped on difficulties,");
2367                  } else if (iStat==5) {
2368                    iStat = 3;
2369                    pos += sprintf(buf+pos,"stopped on ctrl-c,");
2370                  } else {
2371                    pos += sprintf(buf+pos,"status unknown,");
2372                    iStat=6;
2373                  }
2374                  info.problemStatus=iStat;
2375                  info.objValue = value;
2376                  if (babModel->getObjValue()<1.0e40) 
2377                    pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
2378                                   value);
2379                  sprintf(buf+pos,"\n%d nodes, %d iterations",
2380                          babModel->getNodeCount(),
2381                          babModel->getIterationCount());
2382                  if (bestSolution) {
2383                    free(info.primalSolution);
2384                    info.primalSolution = (double *) malloc(n*sizeof(double));
2385                    CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
2386                    int numberRows = lpSolver->numberRows();
2387                    free(info.dualSolution);
2388                    info.dualSolution = (double *) malloc(numberRows*sizeof(double));
2389                    CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
2390                  } else {
2391                    info.primalSolution=NULL;
2392                    info.dualSolution=NULL;
2393                  }
2394                  // put buffer into info
2395                  strcpy(info.buffer,buf);
2396                }
2397#endif
2398              } else {
2399                std::cout<<"Model strengthened - now has "<<clpSolver->getNumRows()
2400                         <<" rows"<<std::endl;
2401              }
2402              time1 = time2;
2403              delete babModel;
2404              babModel=NULL;
2405            } else {
2406              std::cout << "** Current model not valid" << std::endl ; 
2407            }
2408            break ;
2409          case IMPORT:
2410            {
2411#ifdef COIN_HAS_ASL
2412              if (!usingAmpl) {
2413#endif
2414                free(priorities);
2415                priorities=NULL;
2416                free(branchDirection);
2417                branchDirection=NULL;
2418                free(pseudoDown);
2419                pseudoDown=NULL;
2420                free(pseudoUp);
2421                pseudoUp=NULL;
2422                free(solutionIn);
2423                solutionIn=NULL;
2424                free(prioritiesIn);
2425                prioritiesIn=NULL;
2426                free(sosStart);
2427                sosStart=NULL;
2428                free(sosIndices);
2429                sosIndices=NULL;
2430                free(sosType);
2431                sosType=NULL;
2432                free(sosReference);
2433                sosReference=NULL;
2434                free(sosPriority);
2435                sosPriority=NULL;
2436#ifdef COIN_HAS_ASL
2437              }
2438#endif               
2439              delete babModel;
2440              babModel=NULL;
2441              // get next field
2442              field = CoinReadGetString(argc,argv);
2443              if (field=="$") {
2444                field = parameters[iParam].stringValue();
2445              } else if (field=="EOL") {
2446                parameters[iParam].printString();
2447                break;
2448              } else {
2449                parameters[iParam].setStringValue(field);
2450              }
2451              std::string fileName;
2452              bool canOpen=false;
2453              if (field=="-") {
2454                // stdin
2455                canOpen=true;
2456                fileName = "-";
2457              } else {
2458                bool absolutePath;
2459                if (dirsep=='/') {
2460                  // non Windows (or cygwin)
2461                  absolutePath=(field[0]=='/');
2462                } else {
2463                  //Windows (non cycgwin)
2464                  absolutePath=(field[0]=='\\');
2465                  // but allow for :
2466                  if (strchr(field.c_str(),':'))
2467                    absolutePath=true;
2468                }
2469                if (absolutePath) {
2470                  fileName = field;
2471                } else if (field[0]=='~') {
2472                  char * environVar = getenv("HOME");
2473                  if (environVar) {
2474                    std::string home(environVar);
2475                    field=field.erase(0,1);
2476                    fileName = home+field;
2477                  } else {
2478                    fileName=field;
2479                  }
2480                } else {
2481                  fileName = directory+field;
2482                }
2483                FILE *fp=fopen(fileName.c_str(),"r");
2484                if (fp) {
2485                  // can open - lets go for it
2486                  fclose(fp);
2487                  canOpen=true;
2488                } else {
2489                  std::cout<<"Unable to open file "<<fileName<<std::endl;
2490                }
2491              }
2492              if (canOpen) {
2493                int status =lpSolver->readMps(fileName.c_str(),
2494                                                   keepImportNames!=0,
2495                                                   allowImportErrors!=0);
2496                if (!status||(status>0&&allowImportErrors)) {
2497                  if (keepImportNames) {
2498                    lengthName = lpSolver->lengthNames();
2499                    rowNames = *(lpSolver->rowNames());
2500                    columnNames = *(lpSolver->columnNames());
2501                  } else {
2502                    lengthName=0;
2503                  }
2504                  goodModel=true;
2505                  //Set integers in clpsolver
2506                  const char * info = lpSolver->integerInformation();
2507                  if (info) {
2508                    int numberColumns = lpSolver->numberColumns();
2509                    int i;
2510                    for (i=0;i<numberColumns;i++) {
2511                      if (info[i]) 
2512                        clpSolver->setInteger(i);
2513                    }
2514                  }
2515                  // sets to all slack (not necessary?)
2516                  lpSolver->createStatus();
2517                  time2 = CoinCpuTime();
2518                  totalTime += time2-time1;
2519                  time1=time2;
2520                  // Go to canned file if just input file
2521                  if (CbcOrClpRead_mode==2&&argc==2) {
2522                    // only if ends .mps
2523                    std::string::size_type loc = fileName.find(".mps") ;
2524                    if (loc != std::string::npos &&
2525                        fileName.length() == loc+3)
2526                    { fileName.replace(loc+1,3,"par") ;
2527                      FILE *fp=fopen(fileName.c_str(),"r");
2528                      if (fp) {
2529                        CbcOrClpReadCommand=fp; // Read from that file
2530                        CbcOrClpRead_mode=-1;
2531                      }
2532                    }
2533                  }
2534                } else {
2535                  // errors
2536                  std::cout<<"There were "<<status<<
2537                    " errors on input"<<std::endl;
2538                }
2539              }
2540            }
2541            break;
2542          case EXPORT:
2543            if (goodModel) {
2544              // get next field
2545              field = CoinReadGetString(argc,argv);
2546              if (field=="$") {
2547                field = parameters[iParam].stringValue();
2548              } else if (field=="EOL") {
2549                parameters[iParam].printString();
2550                break;
2551              } else {
2552                parameters[iParam].setStringValue(field);
2553              }
2554              std::string fileName;
2555              bool canOpen=false;
2556              if (field[0]=='/'||field[0]=='\\') {
2557                fileName = field;
2558              } else if (field[0]=='~') {
2559                char * environVar = getenv("HOME");
2560                if (environVar) {
2561                  std::string home(environVar);
2562                  field=field.erase(0,1);
2563                  fileName = home+field;
2564                } else {
2565                  fileName=field;
2566                }
2567              } else {
2568                fileName = directory+field;
2569              }
2570              FILE *fp=fopen(fileName.c_str(),"w");
2571              if (fp) {
2572                // can open - lets go for it
2573                fclose(fp);
2574                canOpen=true;
2575              } else {
2576                std::cout<<"Unable to open file "<<fileName<<std::endl;
2577              }
2578              if (canOpen) {
2579                // If presolve on then save presolved
2580                bool deleteModel2=false;
2581                ClpSimplex * model2 = lpSolver;
2582                if (preSolve) {
2583                  ClpPresolve pinfo;
2584                  int presolveOptions2 = presolveOptions&~0x40000000;
2585                  if ((presolveOptions2&0xffff)!=0)
2586                    pinfo.setPresolveActions(presolveOptions2);
2587                  if ((printOptions&1)!=0)
2588                    pinfo.statistics();
2589                  double presolveTolerance = 
2590                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
2591                  model2 = 
2592                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
2593                                         true,preSolve);
2594                  if (model2) {
2595                    printf("Saving presolved model on %s\n",
2596                           fileName.c_str());
2597                    deleteModel2=true;
2598                  } else {
2599                    printf("Presolved model looks infeasible - saving original on %s\n",
2600                           fileName.c_str());
2601                    deleteModel2=false;
2602                    model2 = lpSolver;
2603
2604                  }
2605                } else {
2606                  printf("Saving model on %s\n",
2607                           fileName.c_str());
2608                }
2609#if 0
2610                // Convert names
2611                int iRow;
2612                int numberRows=model2->numberRows();
2613                int iColumn;
2614                int numberColumns=model2->numberColumns();
2615
2616                char ** rowNames = NULL;
2617                char ** columnNames = NULL;
2618                if (model2->lengthNames()) {
2619                  rowNames = new char * [numberRows];
2620                  for (iRow=0;iRow<numberRows;iRow++) {
2621                    rowNames[iRow] =
2622                      strdup(model2->rowName(iRow).c_str());
2623#ifdef STRIPBLANKS
2624                    char * xx = rowNames[iRow];
2625                    int i;
2626                    int length = strlen(xx);
2627                    int n=0;
2628                    for (i=0;i<length;i++) {
2629                      if (xx[i]!=' ')
2630                        xx[n++]=xx[i];
2631                    }
2632                    xx[n]='\0';
2633#endif
2634                  }
2635                 
2636                  columnNames = new char * [numberColumns];
2637                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2638                    columnNames[iColumn] =
2639                      strdup(model2->columnName(iColumn).c_str());
2640#ifdef STRIPBLANKS
2641                    char * xx = columnNames[iColumn];
2642                    int i;
2643                    int length = strlen(xx);
2644                    int n=0;
2645                    for (i=0;i<length;i++) {
2646                      if (xx[i]!=' ')
2647                        xx[n++]=xx[i];
2648                    }
2649                    xx[n]='\0';
2650#endif
2651                  }
2652                }
2653                CoinMpsIO writer;
2654                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
2655                                  model2->getColLower(), model2->getColUpper(),
2656                                  model2->getObjCoefficients(),
2657                                  (const char*) 0 /*integrality*/,
2658                                  model2->getRowLower(), model2->getRowUpper(),
2659                                  columnNames, rowNames);
2660                // Pass in array saying if each variable integer
2661                writer.copyInIntegerInformation(model2->integerInformation());
2662                writer.setObjectiveOffset(model2->objectiveOffset());
2663                writer.writeMps(fileName.c_str(),0,1,1);
2664                if (rowNames) {
2665                  for (iRow=0;iRow<numberRows;iRow++) {
2666                    free(rowNames[iRow]);
2667                  }
2668                  delete [] rowNames;
2669                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2670                    free(columnNames[iColumn]);
2671                  }
2672                  delete [] columnNames;
2673                }
2674#else
2675                model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
2676#endif
2677                if (deleteModel2)
2678                  delete model2;
2679                time2 = CoinCpuTime();
2680                totalTime += time2-time1;
2681                time1=time2;
2682              }
2683            } else {
2684              std::cout<<"** Current model not valid"<<std::endl;
2685            }
2686            break;
2687          case BASISIN:
2688            if (goodModel) {
2689              // get next field
2690              field = CoinReadGetString(argc,argv);
2691              if (field=="$") {
2692                field = parameters[iParam].stringValue();
2693              } else if (field=="EOL") {
2694                parameters[iParam].printString();
2695                break;
2696              } else {
2697                parameters[iParam].setStringValue(field);
2698              }
2699              std::string fileName;
2700              bool canOpen=false;
2701              if (field=="-") {
2702                // stdin
2703                canOpen=true;
2704                fileName = "-";
2705              } else {
2706                if (field[0]=='/'||field[0]=='\\') {
2707                  fileName = field;
2708                } else if (field[0]=='~') {
2709                  char * environVar = getenv("HOME");
2710                  if (environVar) {
2711                    std::string home(environVar);
2712                    field=field.erase(0,1);
2713                    fileName = home+field;
2714                  } else {
2715                    fileName=field;
2716                  }
2717                } else {
2718                  fileName = directory+field;
2719                }
2720                FILE *fp=fopen(fileName.c_str(),"r");
2721                if (fp) {
2722                  // can open - lets go for it
2723                  fclose(fp);
2724                  canOpen=true;
2725                } else {
2726                  std::cout<<"Unable to open file "<<fileName<<std::endl;
2727                }
2728              }
2729              if (canOpen) {
2730                int values = lpSolver->readBasis(fileName.c_str());
2731                if (values==0)
2732                  basisHasValues=-1;
2733                else
2734                  basisHasValues=1;
2735              }
2736            } else {
2737              std::cout<<"** Current model not valid"<<std::endl;
2738            }
2739            break;
2740          case PRIORITYIN:
2741            if (goodModel) {
2742              // get next field
2743              field = CoinReadGetString(argc,argv);
2744              if (field=="$") {
2745                field = parameters[iParam].stringValue();
2746              } else if (field=="EOL") {
2747                parameters[iParam].printString();
2748                break;
2749              } else {
2750                parameters[iParam].setStringValue(field);
2751              }
2752              std::string fileName;
2753              if (field[0]=='/'||field[0]=='\\') {
2754                fileName = field;
2755              } else if (field[0]=='~') {
2756                char * environVar = getenv("HOME");
2757                if (environVar) {
2758                  std::string home(environVar);
2759                  field=field.erase(0,1);
2760                  fileName = home+field;
2761                } else {
2762                  fileName=field;
2763                }
2764              } else {
2765                fileName = directory+field;
2766              }
2767              FILE *fp=fopen(fileName.c_str(),"r");
2768              if (fp) {
2769                // can open - lets go for it
2770                std::string headings[]={"name","number","direction","priority","up","down",
2771                                        "solution","priin"};
2772                int got[]={-1,-1,-1,-1,-1,-1,-1,-1};
2773                int order[8];
2774                assert(sizeof(got)==sizeof(order));
2775                int nAcross=0;
2776                char line[1000];
2777                int numberColumns = lpSolver->numberColumns();
2778                if (!fgets(line,1000,fp)) {
2779                  std::cout<<"Odd file "<<fileName<<std::endl;
2780                } else {
2781                  char * pos = line;
2782                  char * put = line;
2783                  while (*pos>=' '&&*pos!='\n') {
2784                    if (*pos!=' '&&*pos!='\t') {
2785                      *put=tolower(*pos);
2786                      put++;
2787                    }
2788                    pos++;
2789                  }
2790                  *put='\0';
2791                  pos=line;
2792                  int i;
2793                  bool good=true;
2794                  while (pos) {
2795                    char * comma = strchr(pos,',');
2796                    if (comma)
2797                      *comma='\0';
2798                    for (i=0;i<(int) (sizeof(got)/sizeof(int));i++) {
2799                      if (headings[i]==pos) {
2800                        if (got[i]<0) {
2801                          order[nAcross]=i;
2802                          got[i]=nAcross++;
2803                        } else {
2804                          // duplicate
2805                          good=false;
2806                        }
2807                        break;
2808                      }
2809                    }
2810                    if (i==(int) (sizeof(got)/sizeof(int)))
2811                      good=false;
2812                    if (comma) {
2813                      *comma=',';
2814                      pos=comma+1;
2815                    } else {
2816                      break;
2817                    }
2818                  }
2819                  if (got[0]<0&&got[1]<0)
2820                    good=false;
2821                  if (got[0]>=0&&got[1]>=0)
2822                    good=false;
2823                  if (got[0]>=0&&!lpSolver->lengthNames())
2824                    good=false;
2825                  if (good) {
2826                    char ** columnNames = columnNames = new char * [numberColumns];
2827                    pseudoDown= (double *) malloc(numberColumns*sizeof(double));
2828                    pseudoUp = (double *) malloc(numberColumns*sizeof(double));
2829                    branchDirection = (int *) malloc(numberColumns*sizeof(int));
2830                    priorities= (int *) malloc(numberColumns*sizeof(int));
2831                    free(solutionIn);
2832                    solutionIn=NULL;
2833                    free(prioritiesIn);
2834                    prioritiesIn=NULL;
2835                    int iColumn;
2836                    if (got[6]>=0) {
2837                      solutionIn = (double *) malloc(numberColumns*sizeof(double));
2838                      CoinZeroN(solutionIn,numberColumns);
2839                    }
2840                    if (got[7]>=0) {
2841                      prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
2842                      for (iColumn=0;iColumn<numberColumns;iColumn++) 
2843                        prioritiesIn[iColumn]=10000;
2844                    }
2845                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
2846                      columnNames[iColumn] = 
2847                        strdup(lpSolver->columnName(iColumn).c_str());
2848                      pseudoDown[iColumn]=0.0;
2849                      pseudoUp[iColumn]=0.0;
2850                      branchDirection[iColumn]=0;
2851                      priorities[iColumn]=0;
2852                    }
2853                    int nBadPseudo=0;
2854                    int nBadDir=0;
2855                    int nBadPri=0;
2856                    int nBadName=0;
2857                    int nBadLine=0;
2858                    int nLine=0;
2859                    while (fgets(line,1000,fp)) {
2860                      nLine++;
2861                      iColumn = -1;
2862                      double up =0.0;
2863                      double down=0.0;
2864                      int pri=0;
2865                      int dir=0;
2866                      double solValue=COIN_DBL_MAX;
2867                      int priValue=1000000;
2868                      char * pos = line;
2869                      char * put = line;
2870                      while (*pos>=' '&&*pos!='\n') {
2871                        if (*pos!=' '&&*pos!='\t') {
2872                          *put=tolower(*pos);
2873                          put++;
2874                        }
2875                        pos++;
2876                      }
2877                      *put='\0';
2878                      pos=line;
2879                      for (int i=0;i<nAcross;i++) {
2880                        char * comma = strchr(pos,',');
2881                        if (comma) {
2882                          *comma='\0';
2883                        } else if (i<nAcross-1) {
2884                          nBadLine++;
2885                          break;
2886                        }
2887                        switch (order[i]) {
2888                          // name
2889                        case 0:
2890                          for (iColumn=0;iColumn<numberColumns;iColumn++) {
2891                            if (!strcmp(columnNames[iColumn],pos))
2892                              break;
2893                          }
2894                          if (iColumn==numberColumns)
2895                            iColumn=-1;
2896                          break;
2897                          // number
2898                        case 1:
2899                          iColumn = atoi(pos);
2900                          if (iColumn<0||iColumn>=numberColumns)
2901                            iColumn=-1;
2902                          break;
2903                          // direction
2904                        case 2:
2905                          if (*pos=='D')
2906                            dir=-1;
2907                          else if (*pos=='U')
2908                            dir=1;
2909                          else if (*pos=='N')
2910                            dir=0;
2911                          else if (*pos=='1'&&*(pos+1)=='\0')
2912                            dir=1;
2913                          else if (*pos=='0'&&*(pos+1)=='\0')
2914                            dir=0;
2915                          else if (*pos=='1'&&*(pos+1)=='1'&&*(pos+2)=='\0')
2916                            dir=-1;
2917                          else
2918                            dir=-2; // bad
2919                          break;
2920                          // priority
2921                        case 3:
2922                          pri=atoi(pos);
2923                          break;
2924                          // up
2925                        case 4:
2926                          up = atof(pos);
2927                          break;
2928                          // down
2929                        case 5:
2930                          down = atof(pos);
2931                          break;
2932                          // sol value
2933                        case 6:
2934                          solValue = atof(pos);
2935                          break;
2936                          // priority in value
2937                        case 7:
2938                          priValue = atoi(pos);
2939                          break;
2940                        }
2941                        if (comma) {
2942                          *comma=',';
2943                          pos=comma+1;
2944                        }
2945                      }
2946                      if (iColumn>=0) {
2947                        if (down<0.0) {
2948                          nBadPseudo++;
2949                          down=0.0;
2950                        }
2951                        if (up<0.0) {
2952                          nBadPseudo++;
2953                          up=0.0;
2954                        }
2955                        if (!up)
2956                          up=down;
2957                        if (!down)
2958                          down=up;
2959                        if (dir<-1||dir>1) {
2960                          nBadDir++;
2961                          dir=0;
2962                        }
2963                        if (pri<0) {
2964                          nBadPri++;
2965                          pri=0;
2966                        }
2967                        pseudoDown[iColumn]=down;
2968                        pseudoUp[iColumn]=up;
2969                        branchDirection[iColumn]=dir;
2970                        priorities[iColumn]=pri;
2971                        if (solValue!=COIN_DBL_MAX) {
2972                          assert (solutionIn);
2973                          solutionIn[iColumn]=solValue;
2974                        }
2975                        if (priValue!=1000000) {
2976                          assert (prioritiesIn);
2977                          prioritiesIn[iColumn]=priValue;
2978                        }
2979                      } else {
2980                        nBadName++;
2981                      }
2982                    }
2983                    if (!noPrinting) {
2984                      printf("%d fields and %d records",nAcross,nLine);
2985                      if (nBadPseudo)
2986                        printf(" %d bad pseudo costs",nBadPseudo);
2987                      if (nBadDir)
2988                        printf(" %d bad directions",nBadDir);
2989                      if (nBadPri)
2990                        printf(" %d bad priorities",nBadPri);
2991                      if (nBadName)
2992                        printf(" ** %d records did not match on name/sequence",nBadName);
2993                      printf("\n");
2994                    }
2995                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
2996                      free(columnNames[iColumn]);
2997                    }
2998                    delete [] columnNames;
2999                  } else {
3000                    std::cout<<"Duplicate or unknown keyword - or name/number fields wrong"<<line<<std::endl;
3001                  }
3002                }
3003                fclose(fp);
3004              } else {
3005                std::cout<<"Unable to open file "<<fileName<<std::endl;
3006              }
3007            } else {
3008              std::cout<<"** Current model not valid"<<std::endl;
3009            }
3010            break;
3011          case DEBUG:
3012            if (goodModel) {
3013              delete [] debugValues;
3014              debugValues=NULL;
3015              // get next field
3016              field = CoinReadGetString(argc,argv);
3017              if (field=="$") {
3018                field = parameters[iParam].stringValue();
3019              } else if (field=="EOL") {
3020                parameters[iParam].printString();
3021                break;
3022              } else {
3023                parameters[iParam].setStringValue(field);
3024                debugFile=field;
3025                if (debugFile=="create"||
3026                    debugFile=="createAfterPre") {
3027                  printf("Will create a debug file so this run should be a good one\n");
3028                  break;
3029                }
3030              }
3031              std::string fileName;
3032              if (field[0]=='/'||field[0]=='\\') {
3033                fileName = field;
3034              } else if (field[0]=='~') {
3035                char * environVar = getenv("HOME");
3036                if (environVar) {
3037                  std::string home(environVar);
3038                  field=field.erase(0,1);
3039                  fileName = home+field;
3040                } else {
3041                  fileName=field;
3042                }
3043              } else {
3044                fileName = directory+field;
3045              }
3046              FILE *fp=fopen(fileName.c_str(),"rb");
3047              if (fp) {
3048                // can open - lets go for it
3049                int numRows;
3050                double obj;
3051                fread(&numRows,sizeof(int),1,fp);
3052                fread(&numberDebugValues,sizeof(int),1,fp);
3053                fread(&obj,sizeof(double),1,fp);
3054                debugValues = new double[numberDebugValues+numRows];
3055                fread(debugValues,sizeof(double),numRows,fp);
3056                fread(debugValues,sizeof(double),numRows,fp);
3057                fread(debugValues,sizeof(double),numberDebugValues,fp);
3058                printf("%d doubles read into debugValues\n",numberDebugValues);
3059                fclose(fp);
3060              } else {
3061                std::cout<<"Unable to open file "<<fileName<<std::endl;
3062              }
3063            } else {
3064              std::cout<<"** Current model not valid"<<std::endl;
3065            }
3066            break;
3067          case PRINTMASK:
3068            // get next field
3069            {
3070              std::string name = CoinReadGetString(argc,argv);
3071              if (name!="EOL") {
3072                parameters[iParam].setStringValue(name);
3073                printMask = name;
3074              } else {
3075                parameters[iParam].printString();
3076              }
3077            }
3078            break;
3079          case BASISOUT:
3080            if (goodModel) {
3081              // get next field
3082              field = CoinReadGetString(argc,argv);
3083              if (field=="$") {
3084                field = parameters[iParam].stringValue();
3085              } else if (field=="EOL") {
3086                parameters[iParam].printString();
3087                break;
3088              } else {
3089                parameters[iParam].setStringValue(field);
3090              }
3091              std::string fileName;
3092              bool canOpen=false;
3093              if (field[0]=='/'||field[0]=='\\') {
3094                fileName = field;
3095              } else if (field[0]=='~') {
3096                char * environVar = getenv("HOME");
3097                if (environVar) {
3098                  std::string home(environVar);
3099                  field=field.erase(0,1);
3100                  fileName = home+field;
3101                } else {
3102                  fileName=field;
3103                }
3104              } else {
3105                fileName = directory+field;
3106              }
3107              FILE *fp=fopen(fileName.c_str(),"w");
3108              if (fp) {
3109                // can open - lets go for it
3110                fclose(fp);
3111                canOpen=true;
3112              } else {
3113                std::cout<<"Unable to open file "<<fileName<<std::endl;
3114              }
3115              if (canOpen) {
3116                ClpSimplex * model2 = lpSolver;
3117                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
3118                time2 = CoinCpuTime();
3119                totalTime += time2-time1;
3120                time1=time2;
3121              }
3122            } else {
3123              std::cout<<"** Current model not valid"<<std::endl;
3124            }
3125            break;
3126          case SAVE:
3127            {
3128              // get next field
3129              field = CoinReadGetString(argc,argv);
3130              if (field=="$") {
3131                field = parameters[iParam].stringValue();
3132              } else if (field=="EOL") {
3133                parameters[iParam].printString();
3134                break;
3135              } else {
3136                parameters[iParam].setStringValue(field);
3137              }
3138              std::string fileName;
3139              bool canOpen=false;
3140              if (field[0]=='/'||field[0]=='\\') {
3141                fileName = field;
3142              } else if (field[0]=='~') {
3143                char * environVar = getenv("HOME");
3144                if (environVar) {
3145                  std::string home(environVar);
3146                  field=field.erase(0,1);
3147                  fileName = home+field;
3148                } else {
3149                  fileName=field;
3150                }
3151              } else {
3152                fileName = directory+field;
3153              }
3154              FILE *fp=fopen(fileName.c_str(),"wb");
3155              if (fp) {
3156                // can open - lets go for it
3157                fclose(fp);
3158                canOpen=true;
3159              } else {
3160                std::cout<<"Unable to open file "<<fileName<<std::endl;
3161              }
3162              if (canOpen) {
3163                int status;
3164                // If presolve on then save presolved
3165                bool deleteModel2=false;
3166                ClpSimplex * model2 = lpSolver;
3167                if (preSolve) {
3168                  ClpPresolve pinfo;
3169                  double presolveTolerance = 
3170                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
3171                  model2 = 
3172                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
3173                                         false,preSolve);
3174                  if (model2) {
3175                    printf("Saving presolved model on %s\n",
3176                           fileName.c_str());
3177                    deleteModel2=true;
3178                  } else {
3179                    printf("Presolved model looks infeasible - saving original on %s\n",
3180                           fileName.c_str());
3181                    deleteModel2=false;
3182                    model2 = lpSolver;
3183
3184                  }
3185                } else {
3186                  printf("Saving model on %s\n",
3187                           fileName.c_str());
3188                }
3189                status =model2->saveModel(fileName.c_str());
3190                if (deleteModel2)
3191                  delete model2;
3192                if (!status) {
3193                  goodModel=true;
3194                  time2 = CoinCpuTime();
3195                  totalTime += time2-time1;
3196                  time1=time2;
3197                } else {
3198                  // errors
3199                  std::cout<<"There were errors on output"<<std::endl;
3200                }
3201              }
3202            }
3203            break;
3204          case RESTORE:
3205            {
3206              // get next field
3207              field = CoinReadGetString(argc,argv);
3208              if (field=="$") {
3209                field = parameters[iParam].stringValue();
3210              } else if (field=="EOL") {
3211                parameters[iParam].printString();
3212                break;
3213              } else {
3214                parameters[iParam].setStringValue(field);
3215              }
3216              std::string fileName;
3217              bool canOpen=false;
3218              if (field[0]=='/'||field[0]=='\\') {
3219                fileName = field;
3220              } else if (field[0]=='~') {
3221                char * environVar = getenv("HOME");
3222                if (environVar) {
3223                  std::string home(environVar);
3224                  field=field.erase(0,1);
3225                  fileName = home+field;
3226                } else {
3227                  fileName=field;
3228                }
3229              } else {
3230                fileName = directory+field;
3231              }
3232              FILE *fp=fopen(fileName.c_str(),"rb");
3233              if (fp) {
3234                // can open - lets go for it
3235                fclose(fp);
3236                canOpen=true;
3237              } else {
3238                std::cout<<"Unable to open file "<<fileName<<std::endl;
3239              }
3240              if (canOpen) {
3241                int status =lpSolver->restoreModel(fileName.c_str());
3242                if (!status) {
3243                  goodModel=true;
3244                  time2 = CoinCpuTime();
3245                  totalTime += time2-time1;
3246                  time1=time2;
3247                } else {
3248                  // errors
3249                  std::cout<<"There were errors on input"<<std::endl;
3250                }
3251              }
3252            }
3253            break;
3254          case MAXIMIZE:
3255            lpSolver->setOptimizationDirection(-1);
3256            break;
3257          case MINIMIZE:
3258            lpSolver->setOptimizationDirection(1);
3259            break;
3260          case ALLSLACK:
3261            lpSolver->allSlackBasis(true);
3262            break;
3263          case REVERSE:
3264            if (goodModel) {
3265              int iColumn;
3266              int numberColumns=lpSolver->numberColumns();
3267              double * dualColumnSolution = 
3268                lpSolver->dualColumnSolution();
3269              ClpObjective * obj = lpSolver->objectiveAsObject();
3270              assert(dynamic_cast<ClpLinearObjective *> (obj));
3271              double offset;
3272              double * objective = obj->gradient(NULL,NULL,offset,true);
3273              for (iColumn=0;iColumn<numberColumns;iColumn++) {
3274                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
3275                objective[iColumn] = -objective[iColumn];
3276              }
3277              int iRow;
3278              int numberRows=lpSolver->numberRows();
3279              double * dualRowSolution = 
3280                lpSolver->dualRowSolution();
3281              for (iRow=0;iRow<numberRows;iRow++) 
3282                dualRowSolution[iRow] = dualRowSolution[iRow];
3283            }
3284            break;
3285          case DIRECTORY:
3286            {
3287              std::string name = CoinReadGetString(argc,argv);
3288              if (name!="EOL") {
3289                int length=name.length();
3290                if (name[length-1]=='/'||name[length-1]=='\\')
3291                  directory=name;
3292                else
3293                  directory = name+"/";
3294                parameters[iParam].setStringValue(directory);
3295              } else {
3296                parameters[iParam].printString();
3297              }
3298            }
3299            break;
3300          case STDIN:
3301            CbcOrClpRead_mode=-1;
3302            break;
3303          case NETLIB_DUAL:
3304          case NETLIB_EITHER:
3305          case NETLIB_BARRIER:
3306          case NETLIB_PRIMAL:
3307          case NETLIB_TUNE:
3308            {
3309              // create fields for unitTest
3310              const char * fields[4];
3311              int nFields=2;
3312              fields[0]="fake main from unitTest";
3313              fields[1]="-netlib";
3314              if (directory!=defaultDirectory) {
3315                fields[2]="-netlibDir";
3316                fields[3]=directory.c_str();
3317                nFields=4;
3318              }
3319              int algorithm;
3320              if (type==NETLIB_DUAL) {
3321                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
3322                algorithm =0;
3323              } else if (type==NETLIB_BARRIER) {
3324                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
3325                algorithm =2;
3326              } else if (type==NETLIB_EITHER) {
3327                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
3328                algorithm =3;
3329              } else if (type==NETLIB_TUNE) {
3330                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
3331                algorithm =5;
3332                // uncomment next to get active tuning
3333                // algorithm=6;
3334              } else {
3335                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
3336                algorithm=1;
3337              }
3338              int specialOptions = lpSolver->specialOptions();
3339              lpSolver->setSpecialOptions(0);
3340              mainTest(nFields,fields,algorithm,*lpSolver,
3341                       (preSolve!=0),specialOptions);
3342            }
3343            break;
3344          case UNITTEST:
3345            {
3346              // create fields for unitTest
3347              const char * fields[3];
3348              int nFields=1;
3349              fields[0]="fake main from unitTest";
3350              if (directory!=defaultDirectory) {
3351                fields[1]="-mpsDir";
3352                fields[2]=directory.c_str();
3353                nFields=3;
3354              }
3355              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
3356                       false);
3357            }
3358            break;
3359          case FAKEBOUND:
3360            if (goodModel) {
3361              // get bound
3362              double value = CoinReadGetDoubleField(argc,argv,&valid);
3363              if (!valid) {
3364                std::cout<<"Setting "<<parameters[iParam].name()<<
3365                  " to DEBUG "<<value<<std::endl;
3366                int iRow;
3367                int numberRows=lpSolver->numberRows();
3368                double * rowLower = lpSolver->rowLower();
3369                double * rowUpper = lpSolver->rowUpper();
3370                for (iRow=0;iRow<numberRows;iRow++) {
3371                  // leave free ones for now
3372                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
3373                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
3374                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
3375                  }
3376                }
3377                int iColumn;
3378                int numberColumns=lpSolver->numberColumns();
3379                double * columnLower = lpSolver->columnLower();
3380                double * columnUpper = lpSolver->columnUpper();
3381                for (iColumn=0;iColumn<numberColumns;iColumn++) {
3382                  // leave free ones for now
3383                  if (columnLower[iColumn]>-1.0e20||
3384                      columnUpper[iColumn]<1.0e20) {
3385                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
3386                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
3387                  }
3388                }
3389              } else if (valid==1) {
3390                abort();
3391              } else {
3392                std::cout<<"enter value for "<<parameters[iParam].name()<<
3393                  std::endl;
3394              }
3395            }
3396            break;
3397          case REALLY_SCALE:
3398            if (goodModel) {
3399              ClpSimplex newModel(*lpSolver,
3400                                  lpSolver->scalingFlag());
3401              printf("model really really scaled\n");
3402              *lpSolver=newModel;
3403            }
3404            break;
3405          case USERCLP:
3406            // Replace the sample code by whatever you want
3407            if (goodModel) {
3408              printf("Dummy user clp code - model has %d rows and %d columns\n",
3409                     lpSolver->numberRows(),lpSolver->numberColumns());
3410            }
3411            break;
3412          case USERCBC:
3413            // Replace the sample code by whatever you want
3414            if (goodModel) {
3415              printf("Dummy user cbc code - model has %d rows and %d columns\n",
3416                     model.getNumRows(),model.getNumCols());
3417  // Reduce printout
3418  //solver1.setHintParam(OsiDoReducePrint,true,OsiHintTry);
3419  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (model.solver());
3420  // go faster stripes
3421  if (osiclp&&0) {
3422    // Turn this off if you get problems
3423    // Used to be automatically set
3424    osiclp->setSpecialOptions(128);
3425    if(osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
3426      //osiclp->setupForRepeatedUse(2,0);
3427      osiclp->setupForRepeatedUse(0,0);
3428    }
3429  } 
3430  // Allow rounding heuristic
3431
3432  CbcRounding heuristic1(model);
3433  model.addHeuristic(&heuristic1);
3434
3435  // Do initial solve to continuous
3436  ClpPrimalColumnSteepest steepest(5);
3437  osiclp->getModelPtr()->setPrimalColumnPivotAlgorithm(steepest);
3438  osiclp->getModelPtr()->setPerturbation(50);
3439  osiclp->getModelPtr()->setInfeasibilityCost(1.0e9);
3440  osiclp->setHintParam(OsiDoPresolveInInitial,false,OsiHintTry);
3441  osiclp->setHintParam(OsiDoDualInInitial,false,OsiHintTry);
3442  //osiclp->setHintParam(OsiDoDualInResolve,false,OsiHintTry);
3443  model.setSpecialOptions(model.specialOptions()|4);
3444  osiclp->getModelPtr()->defaultFactorizationFrequency();
3445  {
3446    ClpSimplex * clp = osiclp->getModelPtr();
3447    // fix integers to 1
3448    int numberColumns = clp->numberColumns();
3449    double * lower = clp->columnLower();
3450    int i;
3451    for (i=0;i<numberColumns;i++) {
3452      if (osiclp->isInteger(i))
3453        lower[i]=1.0;
3454    }
3455    clp->primal();
3456    double objValue = clp->objectiveValue();
3457    osiclp->setDblParam(OsiDualObjectiveLimit,objValue+1.0e-4);
3458    // unfix integers
3459    for (i=0;i<numberColumns;i++) {
3460      if (osiclp->isInteger(i))
3461        lower[i]=0.0;
3462    }
3463    clp->primal();
3464    //clp->dual();
3465    int nArt=0;
3466    int nFixed0=0,nFixed1=0;
3467    double gap=objValue-clp->objectiveValue();
3468    // for those at one fix anyway
3469    double gap2=1.0;
3470    const double * solution = clp->primalColumnSolution();
3471    const double * dj = clp->dualColumnSolution();
3472    const double * objective = clp->objective();
3473    double * upper = clp->columnUpper();
3474    for (i=0;i<numberColumns;i++) {
3475      if (objective[i]>1.0e5&&solution[i]>1.0e-8)
3476        nArt++;
3477      if (osiclp->isInteger(i)) {
3478        if(dj[i]>gap+1.0e-4) {
3479          nFixed0++;
3480          upper[i]=0.0;
3481        }
3482        if(-dj[i]>gap2+1.0e-4) {
3483          nFixed1++;
3484        lower[i]=1.0;
3485        }
3486      }
3487    }
3488    printf("%d artificials, %d fixed to 0, %d fixed to 1\n",nArt,nFixed0,nFixed1);
3489    //osiclp->getModelPtr()->setPerturbation(100);
3490    osiclp->setWarmStart(NULL); // set basis in osiclp
3491  }
3492  osiclp->initialSolve();
3493
3494  // Switch off strong branching if wanted
3495  // model.setNumberStrong(0);
3496  // Do more strong branching if small
3497  model.setNumberStrong(0);
3498  model.setNumberBeforeTrust(0);
3499
3500  // TEMP - set gap - better to see if no improvement in last few nodes
3501  model.setAllowableGap(600.0);
3502  // message levels
3503  model.messageHandler()->setLogLevel(2);
3504  model.solver()->messageHandler()->setLogLevel(2);
3505  // Do complete search
3506 
3507  model.branchAndBound();
3508            }
3509            break;
3510          case HELP:
3511            std::cout<<"Coin Solver version "<<CBCVERSION
3512                     <<", build "<<__DATE__<<std::endl;
3513            std::cout<<"Non default values:-"<<std::endl;
3514            std::cout<<"Perturbation "<<lpSolver->perturbation()<<" (default 100)"
3515                     <<std::endl;
3516            CoinReadPrintit(
3517                    "Presolve being done with 5 passes\n\
3518Dual steepest edge steep/partial on matrix shape and factorization density\n\
3519Clpnnnn taken out of messages\n\
3520If Factorization frequency default then done on size of matrix\n\n\
3521(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
3522You can switch to interactive mode at any time so\n\
3523clp watson.mps -scaling off -primalsimplex\nis the same as\n\
3524clp watson.mps -\nscaling off\nprimalsimplex"
3525                    );
3526            break;
3527          case SOLUTION:
3528            if (goodModel) {
3529              // get next field
3530              field = CoinReadGetString(argc,argv);
3531              if (field=="$") {
3532                field = parameters[iParam].stringValue();
3533              } else if (field=="EOL") {
3534                parameters[iParam].printString();
3535                break;
3536              } else {
3537                parameters[iParam].setStringValue(field);
3538              }
3539              std::string fileName;
3540              FILE *fp=NULL;
3541              if (field=="-"||field=="EOL"||field=="stdout") {
3542                // stdout
3543                fp=stdout;
3544              } else if (field=="stderr") {
3545                // stderr
3546                fp=stderr;
3547              } else {
3548                if (field[0]=='/'||field[0]=='\\') {
3549                  fileName = field;
3550                } else if (field[0]=='~') {
3551                  char * environVar = getenv("HOME");
3552                  if (environVar) {
3553                    std::string home(environVar);
3554                    field=field.erase(0,1);
3555                    fileName = home+field;
3556                  } else {
3557                    fileName=field;
3558                  }
3559                } else {
3560                  fileName = directory+field;
3561                }
3562                fp=fopen(fileName.c_str(),"w");
3563              }
3564              if (fp) {
3565                // make fancy later on
3566                int iRow;
3567                int numberRows=lpSolver->numberRows();
3568                double * dualRowSolution = lpSolver->dualRowSolution();
3569                double * primalRowSolution = 
3570                  lpSolver->primalRowSolution();
3571                double * rowLower = lpSolver->rowLower();
3572                double * rowUpper = lpSolver->rowUpper();
3573                double primalTolerance = lpSolver->primalTolerance();
3574                char format[6];
3575                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
3576                bool doMask = (printMask!=""&&lengthName);
3577                int * maskStarts=NULL;
3578                int maxMasks=0;
3579                char ** masks =NULL;
3580                if (doMask) {
3581                  int nAst =0;
3582                  const char * pMask2 = printMask.c_str();
3583                  char pMask[100];
3584                  int iChar;
3585                  int lengthMask = strlen(pMask2);
3586                  assert (lengthMask<100);
3587                  if (*pMask2=='"') {
3588                    if (pMask2[lengthMask-1]!='"') {
3589                      printf("mismatched \" in mask %s\n",pMask2);
3590                      break;
3591                    } else {
3592                      strcpy(pMask,pMask2+1);
3593                      *strchr(pMask,'"')='\0';
3594                    }
3595                  } else if (*pMask2=='\'') {
3596                    if (pMask2[lengthMask-1]!='\'') {
3597                      printf("mismatched ' in mask %s\n",pMask2);
3598                      break;
3599                    } else {
3600                      strcpy(pMask,pMask2+1);
3601                      *strchr(pMask,'\'')='\0';
3602                    }
3603                  } else {
3604                    strcpy(pMask,pMask2);
3605                  }
3606                  if (lengthMask>lengthName) {
3607                    printf("mask %s too long - skipping\n",pMask);
3608                    break;
3609                  }
3610                  maxMasks = 1;
3611                  for (iChar=0;iChar<lengthMask;iChar++) {
3612                    if (pMask[iChar]=='*') {
3613                      nAst++;
3614                      maxMasks *= (lengthName+1);
3615                    }
3616                  }
3617                  int nEntries = 1;
3618                  maskStarts = new int[lengthName+2];
3619                  masks = new char * [maxMasks];
3620                  char ** newMasks = new char * [maxMasks];
3621                  int i;
3622                  for (i=0;i<maxMasks;i++) {
3623                    masks[i] = new char[lengthName+1];
3624                    newMasks[i] = new char[lengthName+1];
3625                  }
3626                  strcpy(masks[0],pMask);
3627                  for (int iAst=0;iAst<nAst;iAst++) {
3628                    int nOldEntries = nEntries;
3629                    nEntries=0;
3630                    for (int iEntry = 0;iEntry<nOldEntries;iEntry++) {
3631                      char * oldMask = masks[iEntry];
3632                      char * ast = strchr(oldMask,'*');
3633                      assert (ast);
3634                      int length = strlen(oldMask)-1;
3635                      int nBefore = ast-oldMask;
3636                      int nAfter = length-nBefore;
3637                      // and add null
3638                      nAfter++;
3639                      for (int i=0;i<=lengthName-length;i++) {
3640                        char * maskOut = newMasks[nEntries];
3641                        memcpy(maskOut,oldMask,nBefore);
3642                        for (int k=0;k<i;k++) 
3643                          maskOut[k+nBefore]='?';
3644                        memcpy(maskOut+nBefore+i,ast+1,nAfter);
3645                        nEntries++;
3646                        assert (nEntries<=maxMasks);
3647                      }
3648                    }
3649                    char ** temp = masks;
3650                    masks = newMasks;
3651                    newMasks = temp;
3652                  }
3653                  // Now extend and sort
3654                  int * sort = new int[nEntries];
3655                  for (i=0;i<nEntries;i++) {
3656                    char * maskThis = masks[i];
3657                    int length = strlen(maskThis);
3658                    while (maskThis[length-1]==' ')
3659                      length--;
3660                    maskThis[length]='\0';
3661                    sort[i]=length;
3662                  }
3663                  CoinSort_2(sort,sort+nEntries,masks);
3664                  int lastLength=-1;
3665                  for (i=0;i<nEntries;i++) {
3666                    int length = sort[i];
3667                    while (length>lastLength) 
3668                      maskStarts[++lastLength] = i;
3669                  }
3670                  maskStarts[++lastLength]=nEntries;
3671                  delete [] sort;
3672                  for (i=0;i<maxMasks;i++)
3673                    delete [] newMasks[i];
3674                  delete [] newMasks;
3675                }
3676                if (printMode>2) {
3677                  for (iRow=0;iRow<numberRows;iRow++) {
3678                    int type=printMode-3;
3679                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
3680                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
3681                      fprintf(fp,"** ");
3682                      type=2;
3683                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
3684                      type=1;
3685                    } else if (numberRows<50) {
3686                      type=3;
3687                    }
3688                    if (doMask&&!maskMatches(maskStarts,masks,rowNames[iRow]))
3689                      type =0;
3690                    if (type) {
3691                      fprintf(fp,"%7d ",iRow);
3692                      if (lengthName)
3693                        fprintf(fp,format,rowNames[iRow].c_str());
3694                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
3695                              dualRowSolution[iRow]);
3696                    }
3697                  }
3698                }
3699                int iColumn;
3700                int numberColumns=lpSolver->numberColumns();
3701                double * dualColumnSolution = 
3702                  lpSolver->dualColumnSolution();
3703                double * primalColumnSolution = 
3704                  lpSolver->primalColumnSolution();
3705                double * columnLower = lpSolver->columnLower();
3706                double * columnUpper = lpSolver->columnUpper();
3707                if (printMode!=2) {
3708                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3709                    int type=(printMode>3) ? 1 :0;
3710                    if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
3711                        primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
3712                      fprintf(fp,"** ");
3713                      type=2;
3714                    } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
3715                      type=1;
3716                    } else if (numberColumns<50) {
3717                      type=3;
3718                    }
3719                    // see if integer
3720                    if ((!lpSolver->isInteger(iColumn)||fabs(primalColumnSolution[iColumn])<1.0e-8)
3721                         &&printMode==1)
3722                      type=0;
3723                    if (doMask&&!maskMatches(maskStarts,masks,
3724                                             columnNames[iColumn]))
3725                      type =0;
3726                    if (type) {
3727                      fprintf(fp,"%7d ",iColumn);
3728                      if (lengthName)
3729                        fprintf(fp,format,columnNames[iColumn].c_str());
3730                      fprintf(fp,"%15.8g        %15.8g\n",
3731                              primalColumnSolution[iColumn],
3732                              dualColumnSolution[iColumn]);
3733                    }
3734                  }
3735                } else {
3736                  // special format suitable for OsiRowCutDebugger
3737                  int n=0;
3738                  bool comma=false;
3739                  bool newLine=false;
3740                  fprintf(fp,"\tint intIndicesV[]={\n");
3741                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3742                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
3743                      if (comma)
3744                        fprintf(fp,",");
3745                      if (newLine)
3746                        fprintf(fp,"\n");
3747                      fprintf(fp,"%d ",iColumn);
3748                      comma=true;
3749                      newLine=false;
3750                      n++;
3751                      if (n==10) {
3752                        n=0;
3753                        newLine=true;
3754                      }
3755                    }
3756                  }
3757                  fprintf(fp,"};\n");
3758                  n=0;
3759                  comma=false;
3760                  newLine=false;
3761                  fprintf(fp,"\tdouble intSolnV[]={\n");
3762                  for ( iColumn=0;iColumn<numberColumns;iColumn++) {
3763                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
3764                      if (comma)
3765                        fprintf(fp,",");
3766                      if (newLine)
3767                        fprintf(fp,"\n");
3768                      int value = (int) (primalColumnSolution[iColumn]+0.5);
3769                      fprintf(fp,"%d. ",value);
3770                      comma=true;
3771                      newLine=false;
3772                      n++;
3773                      if (n==10) {
3774                        n=0;
3775                        newLine=true;
3776                      }
3777                    }
3778                  }
3779                  fprintf(fp,"};\n");
3780                }
3781                if (fp!=stdout)
3782                  fclose(fp);
3783                if (masks) {
3784                  delete [] maskStarts;
3785                  for (int i=0;i<maxMasks;i++)
3786                    delete [] masks[i];
3787                  delete [] masks;
3788                }
3789              } else {
3790                std::cout<<"Unable to open file "<<fileName<<std::endl;
3791              }
3792            } else {
3793              std::cout<<"** Current model not valid"<<std::endl;
3794             
3795            }
3796            break;
3797          case SAVESOL:
3798            if (goodModel) {
3799              // get next field
3800              field = CoinReadGetString(argc,argv);
3801              if (field=="$") {
3802                field = parameters[iParam].stringValue();
3803              } else if (field=="EOL") {
3804                parameters[iParam].printString();
3805                break;
3806              } else {
3807                parameters[iParam].setStringValue(field);
3808              }
3809              std::string fileName;
3810              if (field[0]=='/'||field[0]=='\\') {
3811                fileName = field;
3812              } else if (field[0]=='~') {
3813                char * environVar = getenv("HOME");
3814                if (environVar) {
3815                  std::string home(environVar);
3816                  field=field.erase(0,1);
3817                  fileName = home+field;
3818                } else {
3819                  fileName=field;
3820                }
3821              } else {
3822                fileName = directory+field;
3823              }
3824              saveSolution(lpSolver,fileName);
3825            } else {
3826              std::cout<<"** Current model not valid"<<std::endl;
3827             
3828            }
3829            break;
3830          case DUMMY:
3831            break;
3832          default:
3833            abort();
3834          }
3835        } 
3836      } else if (!numberMatches) {
3837        std::cout<<"No match for "<<field<<" - ? for list of commands"
3838                 <<std::endl;
3839      } else if (numberMatches==1) {
3840        if (!numberQuery) {
3841          std::cout<<"Short match for "<<field<<" - completion: ";
3842          std::cout<<parameters[firstMatch].matchName()<<std::endl;
3843        } else if (numberQuery) {
3844          std::cout<<parameters[firstMatch].matchName()<<" : ";
3845          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
3846          if (numberQuery>=2) 
3847            parameters[firstMatch].printLongHelp();
3848        }
3849      } else {
3850        if (!numberQuery) 
3851          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
3852                   <<std::endl;
3853        else
3854          std::cout<<"Completions of "<<field<<":"<<std::endl;
3855        for ( iParam=0; iParam<numberParameters; iParam++ ) {
3856          int match = parameters[iParam].matches(field);
3857          if (match&&parameters[iParam].displayThis()) {
3858            std::cout<<parameters[iParam].matchName();
3859            if (numberQuery>=2) 
3860              std::cout<<" : "<<parameters[iParam].shortHelp();
3861            std::cout<<std::endl;
3862          }
3863        }
3864      }
3865    }
3866  }
3867  // By now all memory should be freed
3868#ifdef DMALLOC
3869  dmalloc_log_unfreed();
3870  dmalloc_shutdown();
3871#endif
3872  return 0;
3873}   
3874static void breakdown(const char * name, int numberLook, const double * region)
3875{
3876  double range[] = {
3877    -COIN_DBL_MAX,
3878    -1.0e15,-1.0e11,-1.0e8,-1.0e5,-1.0e4,-1.0e3,-1.0e2,-1.0e1,
3879    -1.0,
3880    -1.0e-1,-1.0e-2,-1.0e-3,-1.0e-4,-1.0e-5,-1.0e-8,-1.0e-11,-1.0e-15,
3881    0.0,
3882    1.0e-15,1.0e-11,1.0e-8,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,
3883    1.0,
3884    1.0e1,1.0e2,1.0e3,1.0e4,1.0e5,1.0e8,1.0e11,1.0e15,
3885    COIN_DBL_MAX};
3886  int nRanges = (int) (sizeof(range)/sizeof(double));
3887  int * number = new int[nRanges];
3888  memset(number,0,nRanges*sizeof(int));
3889  int * numberExact = new int[nRanges];
3890  memset(numberExact,0,nRanges*sizeof(int));
3891  int i;
3892  for ( i=0;i<numberLook;i++) {
3893    double value = region[i];
3894    for (int j=0;j<nRanges;j++) {
3895      if (value==range[j]) {
3896        numberExact[j]++;
3897        break;
3898      } else if (value<range[j]) {
3899        number[j]++;
3900        break;
3901      }
3902    }
3903  }
3904  printf("\n%s has %d entries\n",name,numberLook);
3905  for (i=0;i<nRanges;i++) {
3906    if (number[i]) 
3907      printf("%d between %g and %g",number[i],range[i-1],range[i]);
3908    if (numberExact[i]) {
3909      if (number[i])
3910        printf(", ");
3911      printf("%d exactly at %g",numberExact[i],range[i]);
3912    }
3913    if (number[i]+numberExact[i])
3914      printf("\n");
3915  }
3916  delete [] number;
3917  delete [] numberExact;
3918}
3919static void statistics(ClpSimplex * originalModel, ClpSimplex * model)
3920{
3921  int numberColumns = originalModel->numberColumns();
3922  const char * integerInformation  = originalModel->integerInformation(); 
3923  const double * columnLower = originalModel->columnLower();
3924  const double * columnUpper = originalModel->columnUpper();
3925  int numberIntegers=0;
3926  int numberBinary=0;
3927  int iRow,iColumn;
3928  if (integerInformation) {
3929    for (iColumn=0;iColumn<numberColumns;iColumn++) {
3930      if (integerInformation[iColumn]) {
3931        if (columnUpper[iColumn]>columnLower[iColumn]) {
3932          numberIntegers++;
3933          if (columnUpper[iColumn]==0.0&&columnLower[iColumn]==1) 
3934            numberBinary++;
3935        }
3936      }
3937    }
3938  }
3939  numberColumns = model->numberColumns();
3940  int numberRows = model->numberRows();
3941  columnLower = model->columnLower();
3942  columnUpper = model->columnUpper();
3943  const double * rowLower = model->rowLower();
3944  const double * rowUpper = model->rowUpper();
3945  const double * objective = model->objective();
3946  CoinPackedMatrix * matrix = model->matrix();
3947  CoinBigIndex numberElements = matrix->getNumElements();
3948  const int * columnLength = matrix->getVectorLengths();
3949  //const CoinBigIndex * columnStart = matrix->getVectorStarts();
3950  const double * elementByColumn = matrix->getElements();
3951  int * number = new int[numberRows+1];
3952  memset(number,0,(numberRows+1)*sizeof(int));
3953  int numberObjSingletons=0;
3954  /* cType
3955     0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up,
3956     8 0/1
3957  */ 
3958  int cType[9];
3959  std::string cName[]={"0.0->inf,","0.0->up,","lo->inf,","lo->up,","free,","fixed,","-inf->0.0,",
3960                       "-inf->up,","0.0->1.0"};
3961  int nObjective=0;
3962  memset(cType,0,sizeof(cType));
3963  for (iColumn=0;iColumn<numberColumns;iColumn++) {
3964    int length=columnLength[iColumn];
3965    if (length==1&&objective[iColumn])
3966      numberObjSingletons++;
3967    number[length]++;
3968    if (objective[iColumn])
3969      nObjective++;
3970    if (columnLower[iColumn]>-1.0e20) {
3971      if (columnLower[iColumn]==0.0) {
3972        if (columnUpper[iColumn]>1.0e20)
3973          cType[0]++;
3974        else if (columnUpper[iColumn]==1.0)
3975          cType[8]++;
3976        else if (columnUpper[iColumn]==0.0)
3977          cType[5]++;
3978        else
3979          cType[1]++;
3980      } else {
3981        if (columnUpper[iColumn]>1.0e20) 
3982          cType[2]++;
3983        else if (columnUpper[iColumn]==columnLower[iColumn])
3984          cType[5]++;
3985        else
3986          cType[3]++;
3987      }
3988    } else {
3989      if (columnUpper[iColumn]>1.0e20) 
3990        cType[4]++;
3991      else if (columnUpper[iColumn]==0.0) 
3992        cType[6]++;
3993      else
3994        cType[7]++;
3995    }
3996  }
3997  /* rType
3998     0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other,
3999     7 L 0,  8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free
4000  */ 
4001  int rType[13];
4002  std::string rName[]={"E 0.0,","E 1.0,","E -1.0,","E other,","G 0.0,","G 1.0,","G other,",
4003                       "L 0.0,","L 1.0,","L other,","Range 0.0->1.0,","Range other,","Free"};
4004  memset(rType,0,sizeof(rType));
4005  for (iRow=0;iRow<numberRows;iRow++) {
4006    if (rowLower[iRow]>-1.0e20) {
4007      if (rowLower[iRow]==0.0) {
4008        if (rowUpper[iRow]>1.0e20)
4009          rType[4]++;
4010        else if (rowUpper[iRow]==1.0)
4011          rType[10]++;
4012        else if (rowUpper[iRow]==0.0)
4013          rType[0]++;
4014        else
4015          rType[11]++;
4016      } else if (rowLower[iRow]==1.0) {
4017        if (rowUpper[iRow]>1.0e20) 
4018          rType[5]++;
4019        else if (rowUpper[iRow]==rowLower[iRow])
4020          rType[1]++;
4021        else
4022          rType[11]++;
4023      } else if (rowLower[iRow]==-1.0) {
4024        if (rowUpper[iRow]>1.0e20) 
4025          rType[6]++;
4026        else if (rowUpper[iRow]==rowLower[iRow])
4027          rType[2]++;
4028        else
4029          rType[11]++;
4030      } else {
4031        if (rowUpper[iRow]>1.0e20) 
4032          rType[6]++;
4033        else if (rowUpper[iRow]==rowLower[iRow])
4034          rType[3]++;
4035        else
4036          rType[11]++;
4037      }
4038    } else {
4039      if (rowUpper[iRow]>1.0e20) 
4040        rType[12]++;
4041      else if (rowUpper[iRow]==0.0) 
4042        rType[7]++;
4043      else if (rowUpper[iRow]==1.0) 
4044        rType[8]++;
4045      else
4046        rType[9]++;
4047    }
4048  }
4049  // Basic statistics
4050  printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n",
4051         numberRows,numberColumns,nObjective,numberElements);
4052  if (number[0]+number[1]) {
4053    printf("There are ");
4054    if (numberObjSingletons)
4055      printf("%d singletons with objective ",numberObjSingletons);
4056    int numberNoObj = number[1]-numberObjSingletons;
4057    if (numberNoObj)
4058      printf("%d singletons with no objective ",numberNoObj);
4059    if (number[0])
4060      printf("** %d columns have no entries",number[0]);
4061    printf("\n");
4062  }
4063  printf("Column breakdown:\n");
4064  int k;
4065  for (k=0;k<(int) (sizeof(cType)/sizeof(int));k++) {
4066    printf("%d of type %s ",cType[k],cName[k].c_str());
4067    if (((k+1)%3)==0)
4068      printf("\n");
4069  }
4070  if ((k%3)!=0)
4071    printf("\n");
4072  printf("Row breakdown:\n");
4073  for (k=0;k<(int) (sizeof(rType)/sizeof(int));k++) {
4074    printf("%d of type %s ",rType[k],rName[k].c_str());
4075    if (((k+1)%3)==0)
4076      printf("\n");
4077  }
4078  if ((k%3)!=0)
4079    printf("\n");
4080  if (model->logLevel()<2)
4081    return ;
4082  int kMax = model->logLevel()>3 ? 1000000 : 10;
4083  k=0;
4084  for (iRow=1;iRow<=numberRows;iRow++) {
4085    if (number[iRow]) {
4086      k++;
4087      printf("%d columns have %d entries\n",number[iRow],iRow);
4088      if (k==kMax)
4089        break;
4090    }
4091  }
4092  if (k<numberRows) {
4093    int kk=k;
4094    k=0;
4095    for (iRow=numberRows;iRow>=1;iRow--) {
4096      if (number[iRow]) {
4097        k++;
4098        if (k==kMax)
4099          break;
4100      }
4101    }
4102    if (k>kk) {
4103      printf("\n    .........\n\n");
4104      iRow=k;
4105      k=0;
4106      for (;iRow<numberRows;iRow++) {
4107        if (number[iRow]) {
4108          k++;
4109          printf("%d columns have %d entries\n",number[iRow],iRow);
4110          if (k==kMax)
4111            break;
4112        }
4113      }
4114    }
4115  }
4116  delete [] number;
4117  printf("\n\n");
4118  // get row copy
4119  CoinPackedMatrix rowCopy = *matrix;
4120  rowCopy.reverseOrdering();
4121  //const int * column = rowCopy.getIndices();
4122  const int * rowLength = rowCopy.getVectorLengths();
4123  //const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
4124  //const double * element = rowCopy.getElements();
4125  number = new int[numberColumns+1];
4126  memset(number,0,(numberColumns+1)*sizeof(int));
4127  for (iRow=0;iRow<numberRows;iRow++) {
4128    int length=rowLength[iRow];
4129    number[length]++;
4130  }
4131  if (number[0])
4132    printf("** %d rows have no entries\n",number[0]);
4133  k=0;
4134  for (iColumn=1;iColumn<=numberColumns;iColumn++) {
4135    if (number[iColumn]) {
4136      k++;
4137      printf("%d rows have %d entries\n",number[iColumn],iColumn);
4138      if (k==kMax)
4139        break;
4140    }
4141  }
4142  if (k<numberColumns) {
4143    int kk=k;
4144    k=0;
4145    for (iColumn=numberColumns;iColumn>=1;iColumn--) {
4146      if (number[iColumn]) {
4147        k++;
4148        if (k==kMax)
4149          break;
4150      }
4151    }
4152    if (k>kk) {
4153      printf("\n    .........\n\n");
4154      iColumn=k;
4155      k=0;
4156      for (;iColumn<numberColumns;iColumn++) {
4157        if (number[iColumn]) {
4158          k++;
4159          printf("%d rows have %d entries\n",number[iColumn],iColumn);
4160          if (k==kMax)
4161            break;
4162        }
4163      }
4164    }
4165  }
4166  delete [] number;
4167  // Now do breakdown of ranges
4168  breakdown("Elements",numberElements,elementByColumn);
4169  breakdown("RowLower",numberRows,rowLower);
4170  breakdown("RowUpper",numberRows,rowUpper);
4171  breakdown("ColumnLower",numberColumns,columnLower);
4172  breakdown("ColumnUpper",numberColumns,columnUpper);
4173  breakdown("Objective",numberColumns,objective);
4174}
4175static bool maskMatches(const int * starts, char ** masks,
4176                        std::string & check)
4177{
4178  // back to char as I am old fashioned
4179  const char * checkC = check.c_str();
4180  int length = strlen(checkC);
4181  while (checkC[length-1]==' ')
4182    length--;
4183  for (int i=starts[length];i<starts[length+1];i++) {
4184    char * thisMask = masks[i];
4185    int k;
4186    for ( k=0;k<length;k++) {
4187      if (thisMask[k]!='?'&&thisMask[k]!=checkC[k]) 
4188        break;
4189    }
4190    if (k==length)
4191      return true;
4192  }
4193  return false;
4194}
4195static void clean(char * temp)
4196{
4197  char * put = temp;
4198  while (*put>=' ')
4199    put++;
4200  *put='\0';
4201}
4202static void generateCode(const char * fileName,int type,int preProcess)
4203{
4204  // options on code generation
4205  bool sizecode = (type&4)!=0;
4206  type &= 3;
4207  FILE * fp = fopen(fileName,"r");
4208  assert (fp);
4209  int numberLines=0;
4210#define MAXLINES 5000
4211#define MAXONELINE 200
4212  char line[MAXLINES][MAXONELINE];
4213  strcpy(line[numberLines++],"0#if defined(_MSC_VER)");
4214  strcpy(line[numberLines++],"0// Turn off compiler warning about long names");
4215  strcpy(line[numberLines++],"0#  pragma warning(disable:4786)");
4216  strcpy(line[numberLines++],"0#endif\n");
4217  strcpy(line[numberLines++],"0#include <cassert>");
4218  strcpy(line[numberLines++],"0#include <iomanip>");
4219  strcpy(line[numberLines++],"0#include \"OsiClpSolverInterface.hpp\"");
4220  strcpy(line[numberLines++],"0#include \"CbcModel.hpp\"");
4221  strcpy(line[numberLines++],"0#include \"CbcCutGenerator.hpp\"");
4222  strcpy(line[numberLines++],"0#include \"CbcStrategy.hpp\"");
4223  strcpy(line[numberLines++],"0#include \"CglPreProcess.hpp\"");
4224  strcpy(line[numberLines++],"0#include \"CoinTime.hpp\"");
4225  while (fgets(line[numberLines],MAXONELINE,fp)) {
4226    assert (numberLines<MAXLINES);
4227    clean(line[numberLines]);
4228    numberLines++;
4229  }
4230  fclose(fp);
4231  strcpy(line[numberLines++],"0\nint main (int argc, const char *argv[])\n{");
4232  strcpy(line[numberLines++],"0  OsiClpSolverInterface solver1;");
4233  strcpy(line[numberLines++],"0  int status=1;");
4234  strcpy(line[numberLines++],"0  if (argc<2)");
4235  strcpy(line[numberLines++],"0    std::cout<<\"Please give file name\"<<std::endl;");
4236  strcpy(line[numberLines++],"0  else");
4237  strcpy(line[numberLines++],"0    status=solver1.readMps(argv[1],\"\");");
4238  strcpy(line[numberLines++],"0  if (status) {");
4239  strcpy(line[numberLines++],"0    std::cout<<\"Bad readMps \"<<argv[1]<<std::endl;");
4240  strcpy(line[numberLines++],"0    exit(1);");
4241  strcpy(line[numberLines++],"0  }\n");
4242  strcpy(line[numberLines++],"0  double time1 = CoinCpuTime();");
4243  strcpy(line[numberLines++],"0  CbcModel model(solver1);");
4244  strcpy(line[numberLines++],"0  // Now do requested saves and modifications");
4245  strcpy(line[numberLines++],"0  CbcModel * cbcModel = & model;");
4246  strcpy(line[numberLines++],"0  OsiSolverInterface * osiModel = model.solver();");
4247  strcpy(line[numberLines++],"0  OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);");
4248  strcpy(line[numberLines++],"0  ClpSimplex * clpModel = osiclpModel->getModelPtr();");
4249  // add in comments about messages
4250  strcpy(line[numberLines++],"3  // You can save some time by switching off message building");
4251  strcpy(line[numberLines++],"3  // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);");
4252  strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4253  strcpy(line[numberLines++],"5  if (clpModel->tightenPrimalBounds()!=0) {");
4254  strcpy(line[numberLines++],"5    std::cout<<\"Problem is infeasible - tightenPrimalBounds!\"<<std::endl;");
4255  strcpy(line[numberLines++],"5    exit(1);");
4256  strcpy(line[numberLines++],"5  }");
4257  strcpy(line[numberLines++],"5  clpModel->dual();  // clean up");
4258  if (sizecode) {
4259    // override some settings
4260    strcpy(line[numberLines++],"5  // compute some things using problem size");
4261    strcpy(line[numberLines++],"5  cbcModel->setMinimumDrop(min(5.0e-2,");
4262    strcpy(line[numberLines++],"5       fabs(cbcModel->getMinimizationObjValue())*1.0e-3+1.0e-4));");
4263    strcpy(line[numberLines++],"5  if (cbcModel->getNumCols()<500)");
4264    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible");
4265    strcpy(line[numberLines++],"5  else if (cbcModel->getNumCols()<5000)");
4266    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(100); // use minimum drop");
4267    strcpy(line[numberLines++],"5  else");
4268    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(20);");
4269    strcpy(line[numberLines++],"5  cbcModel->setMaximumCutPasses(1);");
4270  }
4271  if (preProcess<=0) {
4272    // no preprocessing or strategy
4273    if (preProcess) {
4274      strcpy(line[numberLines++],"5  // Preprocessing using CbcStrategy");
4275      strcpy(line[numberLines++],"5  CbcStrategyDefault strategy(true,5,5);");
4276      strcpy(line[numberLines++],"5  strategy.setupPreProcessing(1);");
4277      strcpy(line[numberLines++],"5  cbcModel->setStrategy(strategy);");
4278    }
4279  } else {
4280    int translate[]={9999,0,0,-1,2,3};
4281    strcpy(line[numberLines++],"5  // Hand coded preprocessing");
4282    strcpy(line[numberLines++],"5  CglPreProcess process;");
4283    strcpy(line[numberLines++],"5  OsiSolverInterface * saveSolver=cbcModel->solver()->clone();");
4284    strcpy(line[numberLines++],"5  // Tell solver we are in Branch and Cut");
4285    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;");
4286    strcpy(line[numberLines++],"5  // Default set of cut generators");
4287    strcpy(line[numberLines++],"5  CglProbing generator1;");
4288    strcpy(line[numberLines++],"5  generator1.setUsingObjective(true);");
4289    strcpy(line[numberLines++],"5  generator1.setMaxPass(3);");
4290    strcpy(line[numberLines++],"5  generator1.setMaxProbeRoot(saveSolver->getNumCols());");
4291    strcpy(line[numberLines++],"5  generator1.setMaxElements(100);");
4292    strcpy(line[numberLines++],"5  generator1.setMaxLookRoot(50);");
4293    strcpy(line[numberLines++],"5  generator1.setRowCuts(3);");
4294    strcpy(line[numberLines++],"5  // Add in generators");
4295    strcpy(line[numberLines++],"5  process.addCutGenerator(&generator1);");
4296    strcpy(line[numberLines++],"5  process.messageHandler()->setLogLevel(cbcModel->logLevel());");
4297    strcpy(line[numberLines++],"5  OsiSolverInterface * solver2 = ");
4298    sprintf(line[numberLines++],"5    process.preProcessNonDefault(*saveSolver,%d,10);",translate[preProcess]);
4299    strcpy(line[numberLines++],"5  // Tell solver we are not in Branch and Cut");
4300    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4301    strcpy(line[numberLines++],"5  if (solver2)");
4302    strcpy(line[numberLines++],"5    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4303    strcpy(line[numberLines++],"5  if (!solver2) {");
4304    strcpy(line[numberLines++],"5    std::cout<<\"Pre-processing says infeasible!\"<<std::endl;");
4305    strcpy(line[numberLines++],"5    exit(1);");
4306    strcpy(line[numberLines++],"5  } else {");
4307    strcpy(line[numberLines++],"5    std::cout<<\"processed model has \"<<solver2->getNumRows()");
4308    strcpy(line[numberLines++],"5            <<\" rows, \"<<solver2->getNumCols()");
4309    strcpy(line[numberLines++],"5            <<\" and \"<<solver2->getNumElements()<<std::endl;");
4310    strcpy(line[numberLines++],"5  }");
4311    strcpy(line[numberLines++],"5  // we have to keep solver2 so pass clone");
4312    strcpy(line[numberLines++],"5  solver2 = solver2->clone();");
4313    strcpy(line[numberLines++],"5  cbcModel->assignSolver(solver2);");
4314    strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4315  }
4316  // add in actual solve
4317  strcpy(line[numberLines++],"5  cbcModel->branchAndBound();");
4318  strcpy(line[numberLines++],"8  std::cout<<argv[1]<<\" took \"<<CoinCpuTime()-time1<<\" seconds, \"");
4319  strcpy(line[numberLines++],"8    <<cbcModel->getNodeCount()<<\" nodes with objective \"");
4320  strcpy(line[numberLines++],"8    <<cbcModel->getObjValue()");
4321  strcpy(line[numberLines++],"8    <<(!cbcModel->status() ? \" Finished\" : \" Not finished\")");
4322  strcpy(line[numberLines++],"8    <<std::endl;");
4323  strcpy(line[numberLines++],"5  // For best solution");
4324  strcpy(line[numberLines++],"5  int numberColumns = solver1.getNumCols();");
4325  strcpy(line[numberLines++],"5  if (cbcModel->getMinimizationObjValue()<1.0e50) {");
4326  if (preProcess>0) {
4327    strcpy(line[numberLines++],"5    // post process");
4328    strcpy(line[numberLines++],"5    process.postProcess(*cbcModel->solver());");
4329    strcpy(line[numberLines++],"5    // Solution now back in saveSolver");
4330    strcpy(line[numberLines++],"5    cbcModel->assignSolver(saveSolver);");
4331    strcpy(line[numberLines++],"5    memcpy(cbcModel->bestSolution(),cbcModel->solver()->getColSolution(),");
4332    strcpy(line[numberLines++],"5          numberColumns*sizeof(double));");
4333  }
4334  strcpy(line[numberLines++],"5    // put back in original solver");
4335  strcpy(line[numberLines++],"5    solver1.setColSolution(cbcModel->bestSolution());");
4336  strcpy(line[numberLines++],"5    const double * solution = solver1.getColSolution();");
4337  strcpy(line[numberLines++],"8  \n  // Now you would use solution etc etc\n");
4338  strcpy(line[numberLines++],"5");
4339  strcpy(line[numberLines++],"5    // Get names from solver1 (as OsiSolverInterface may lose)");
4340  strcpy(line[numberLines++],"5    std::vector<std::string> columnNames = *solver1.getModelPtr()->columnNames();");
4341  strcpy(line[numberLines++],"5    ");
4342  strcpy(line[numberLines++],"5    int iColumn;");
4343  strcpy(line[numberLines++],"5    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);");
4344  strcpy(line[numberLines++],"5    ");
4345  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4346  strcpy(line[numberLines++],"5    for (iColumn=0;iColumn<numberColumns;iColumn++) {");
4347  strcpy(line[numberLines++],"5      double value=solution[iColumn];");
4348  strcpy(line[numberLines++],"5      if (fabs(value)>1.0e-7&&solver1.isInteger(iColumn)) ");
4349  strcpy(line[numberLines++],"5 std::cout<<std::setw(6)<<iColumn<<\" \"");
4350  strcpy(line[numberLines++],"5                 <<columnNames[iColumn]<<\" \"");
4351  strcpy(line[numberLines++],"5                 <<value<<std::endl;");
4352  strcpy(line[numberLines++],"5    }");
4353  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4354  strcpy(line[numberLines++],"5  ");
4355  strcpy(line[numberLines++],"5    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);");
4356  strcpy(line[numberLines++],"5  }");
4357  strcpy(line[numberLines++],"8  return 0;\n}");
4358  fp = fopen(fileName,"w");
4359  assert (fp);
4360
4361  int wanted[9];
4362  memset(wanted,0,sizeof(wanted));
4363  wanted[0]=wanted[3]=wanted[5]=wanted[8]=1;
4364  if (type>0) 
4365    wanted[1]=wanted[6]=1;
4366  if (type>1) 
4367    wanted[2]=wanted[4]=wanted[7]=1;
4368  std::string header[9]=
4369  { "","Save values","Redundant save of default values","Set changed values",
4370    "Redundant set default values","Solve","Restore values","Redundant restore values","Add to model"};
4371  for (int iType=0;iType<9;iType++) {
4372    if (!wanted[iType])
4373      continue;
4374    int n=0;
4375    int iLine;
4376    for (iLine=0;iLine<numberLines;iLine++) {
4377      if (line[iLine][0]=='0'+iType) {
4378        if (!n&&header[iType]!="")
4379          fprintf(fp,"\n  // %s\n\n",header[iType].c_str());
4380        n++;
4381        // skip save and clp as cloned
4382        if (!strstr(line[iLine],"save")||(!strstr(line[iLine],"clpMo")&&
4383                                          !strstr(line[iLine],"_Osi")))
4384          fprintf(fp,"%s\n",line[iLine]+1);
4385      }
4386    }
4387  }
4388  fclose(fp);
4389  printf("C++ file written to %s\n",fileName);
4390}
4391/*
4392  Version 1.00.00 November 16 2005.
4393  This is to stop me (JJF) messing about too much.
4394  Tuning changes should be noted here.
4395  The testing next version may be activated by CBC_NEXT_VERSION
4396  This applies to OsiClp, Clp etc
4397  Version 1.00.01 November 24 2005
4398  Added several classes for advanced users.  This can't affect code (if you don't use it)
4399  Made some tiny changes (for N way branching) which should not change anything.
4400  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
4401  CbcBranchAllDifferent object class - for branching on general integer variables
4402  to stop them having same value so branches are x >= y+1 and x <= y-1.
4403  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
4404  and CglStored which just has a list of cuts which can be activated.
4405  Modified preprocess option to SOS
4406  Version 1.00.02 December 9 2005
4407  Added use of CbcStrategy to do clean preprocessing
4408  Added use of referenceSolver for cleaner repetition of Cbc
4409  Version 1.01.00 February 2 2006
4410  Added first try at Ampl interface
4411*/
Note: See TracBrowser for help on using the repository browser.