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

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

quadratic

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