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

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

for osibranching

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