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

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

hopefully fix compare

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