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

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

nonlinear

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