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

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

for nonlinear and start moving to OsiTree?
afor n

  • 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+2 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                  */
2082                  double value = babModel->solver()->getObjSense()*babModel->solver()->getObjValue();
2083                  int w = pumpTune/10;
2084                  int c = w % 10;
2085                  w /= 10;
2086                  int i = w % 10;
2087                  w /= 10;
2088                  int r = w;
2089                  int accumulate = r/1000;
2090                  r -= 1000*accumulate;
2091                  if (accumulate>=10) {
2092                    int which = accumulate/10;
2093                    accumulate -= 10*which;
2094                    which--;
2095                    // weights and factors
2096                    double weight[]={0.1,0.1,0.5,0.5,1.0,1.0,5.0,5.0};
2097                    double factor[] = {0.1,0.5,0.1,0.5,0.1,0.5,0.1,0.5};
2098                    heuristic4.setInitialWeight(weight[which]);
2099                    heuristic4.setWeightFactor(factor[which]);
2100                  }
2101                  // fake cutoff
2102                  printf("Setting ");
2103                  if (c) {
2104                    double cutoff;
2105                    babModel->solver()->getDblParam(OsiDualObjectiveLimit,cutoff);
2106                    cutoff = CoinMin(cutoff,value + 0.1*fabs(value)*c);
2107                    heuristic4.setFakeCutoff(cutoff);
2108                    printf("fake cutoff of %g ",cutoff);
2109                  }
2110                  if (i||r) {
2111                    // also set increment
2112                    heuristic4.setAbsoluteIncrement((0.01*i+0.005)*(fabs(value)+1.0e-12));
2113                    heuristic4.setAccumulate(accumulate);
2114                    heuristic4.setMaximumRetries(r+2);
2115                    if (i)
2116                      printf("increment of %g ",heuristic4.absoluteIncrement());
2117                    if (accumulate)
2118                      printf("accumulate of %d ",accumulate);
2119                    printf("%d retries ",r+2);
2120                  }
2121                  pumpTune = pumpTune%100;
2122                  printf("and setting when to %d\n",pumpTune+10);
2123                  heuristic4.setWhen(pumpTune+10);
2124                }
2125                babModel->addHeuristic(&heuristic4);
2126              }
2127              if (!miplib) {
2128                CbcRounding heuristic1(*babModel);
2129                if (useRounding)
2130                  babModel->addHeuristic(&heuristic1) ;
2131                CbcHeuristicLocal heuristic2(*babModel);
2132                heuristic2.setSearchType(1);
2133                if (useCombine)
2134                  babModel->addHeuristic(&heuristic2);
2135                CbcHeuristicGreedyCover heuristic3(*babModel);
2136                CbcHeuristicGreedyEquality heuristic3a(*babModel);
2137                if (useGreedy) {
2138                  babModel->addHeuristic(&heuristic3);
2139                  babModel->addHeuristic(&heuristic3a);
2140                }
2141                if (useLocalTree) {
2142                  CbcTreeLocal localTree(babModel,NULL,10,0,0,10000,2000);
2143                  babModel->passInTreeHandler(localTree);
2144                }
2145              }
2146              if (type==MIPLIB) {
2147                if (babModel->numberStrong()==5&&babModel->numberBeforeTrust()==5) 
2148                  babModel->setNumberBeforeTrust(50);
2149              }
2150              // add cut generators if wanted
2151              int switches[20];
2152              int numberGenerators=0;
2153              int translate[]={-100,-1,-99,-98,1,1,1,1};
2154              if (probingAction) {
2155                if (probingAction==5||probingAction==7)
2156                  probingGen.setRowCuts(-3); // strengthening etc just at root
2157                if (probingAction==6||probingAction==7) {
2158                  // Number of unsatisfied variables to look at
2159                  probingGen.setMaxProbe(1000);
2160                  probingGen.setMaxProbeRoot(1000);
2161                  // How far to follow the consequences
2162                  probingGen.setMaxLook(50);
2163                  probingGen.setMaxLookRoot(50);
2164                }
2165                babModel->addCutGenerator(&probingGen,translate[probingAction],"Probing");
2166                switches[numberGenerators++]=0;
2167              }
2168              if (gomoryAction) {
2169                babModel->addCutGenerator(&gomoryGen,translate[gomoryAction],"Gomory");
2170                switches[numberGenerators++]=-1;
2171              }
2172              if (knapsackAction) {
2173                babModel->addCutGenerator(&knapsackGen,translate[knapsackAction],"Knapsack");
2174                switches[numberGenerators++]=0;
2175              }
2176              if (redsplitAction) {
2177                babModel->addCutGenerator(&redsplitGen,translate[redsplitAction],"Reduce-and-split");
2178                switches[numberGenerators++]=1;
2179              }
2180              if (cliqueAction) {
2181                babModel->addCutGenerator(&cliqueGen,translate[cliqueAction],"Clique");
2182                switches[numberGenerators++]=0;
2183              }
2184              if (mixedAction) {
2185                babModel->addCutGenerator(&mixedGen,translate[mixedAction],"MixedIntegerRounding2");
2186                switches[numberGenerators++]=-1;
2187              }
2188              if (flowAction) {
2189                babModel->addCutGenerator(&flowGen,translate[flowAction],"FlowCover");
2190                switches[numberGenerators++]=1;
2191              }
2192              if (twomirAction) {
2193                babModel->addCutGenerator(&twomirGen,translate[twomirAction],"TwoMirCuts");
2194                switches[numberGenerators++]=1;
2195              }
2196              if (landpAction) {
2197                babModel->addCutGenerator(&landpGen,translate[landpAction],"LiftAndProject");
2198                switches[numberGenerators++]=1;
2199              }
2200              if (storedCuts) 
2201                babModel->setSpecialOptions(babModel->specialOptions()|64);
2202              // Say we want timings
2203              numberGenerators = babModel->numberCutGenerators();
2204              int iGenerator;
2205              int cutDepth=
2206                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
2207              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
2208                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
2209                int howOften = generator->howOften();
2210                if (howOften==-98||howOften==-99) 
2211                  generator->setSwitchOffIfLessThan(switches[iGenerator]);
2212                generator->setTiming(true);
2213                if (cutDepth>=0)
2214                  generator->setWhatDepth(cutDepth) ;
2215              }
2216              // Could tune more
2217              if (!miplib) {
2218                babModel->setMinimumDrop(min(5.0e-2,
2219                                             fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
2220                if (cutPass==-1234567) {
2221                  if (babModel->getNumCols()<500)
2222                    babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
2223                  else if (babModel->getNumCols()<5000)
2224                    babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
2225                  else
2226                    babModel->setMaximumCutPassesAtRoot(20);
2227                } else {
2228                  babModel->setMaximumCutPassesAtRoot(cutPass);
2229                }
2230                babModel->setMaximumCutPasses(1);
2231              }
2232              // Do more strong branching if small
2233              //if (babModel->getNumCols()<5000)
2234              //babModel->setNumberStrong(20);
2235              // Switch off strong branching if wanted
2236              //if (babModel->getNumCols()>10*babModel->getNumRows())
2237              //babModel->setNumberStrong(0);
2238              if (!noPrinting) {
2239                int iLevel = parameters[log].intValue();
2240                if (iLevel<0) {
2241                  babModel->setPrintingMode(1);
2242                  iLevel = -iLevel;
2243                }
2244                babModel->messageHandler()->setLogLevel(iLevel);
2245                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
2246                    babModel->messageHandler()->logLevel()>1)
2247                  babModel->setPrintFrequency(100);
2248              }
2249             
2250              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,
2251                    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].intValue());
2252              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2253              // go faster stripes
2254              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
2255                osiclp->setupForRepeatedUse(2,parameters[slog].intValue());
2256              } else {
2257                osiclp->setupForRepeatedUse(0,parameters[slog].intValue());
2258              }
2259              double increment=babModel->getCutoffIncrement();;
2260              int * changed = NULL;
2261              if (!miplib)
2262                changed=analyze( osiclp,numberChanged,increment,false);
2263              if (debugValues) {
2264                if (numberDebugValues==babModel->getNumCols()) {
2265                  // for debug
2266                  babModel->solver()->activateRowCutDebugger(debugValues) ;
2267                } else {
2268                  printf("debug file has incorrect number of columns\n");
2269                }
2270              }
2271              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
2272              // Turn this off if you get problems
2273              // Used to be automatically set
2274              int mipOptions = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue();
2275              if (mipOptions!=(128|64|1))
2276                printf("mip options %d\n",mipOptions);
2277              osiclp->setSpecialOptions(mipOptions);
2278              if (gapRatio < 1.0e100) {
2279                double value = babModel->solver()->getObjValue() ;
2280                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
2281                babModel->setAllowableGap(value2) ;
2282                std::cout << "Continuous " << value
2283                          << ", so allowable gap set to "
2284                          << value2 << std::endl ;
2285              }
2286              // probably faster to use a basis to get integer solutions
2287              babModel->setSpecialOptions(babModel->specialOptions()|2);
2288              currentBranchModel = babModel;
2289              OsiSolverInterface * strengthenedModel=NULL;
2290              if (type==BAB||type==MIPLIB) {
2291                int moreMipOptions = parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].intValue();
2292                if (moreMipOptions>=0) {
2293                  printf("more mip options %d\n",moreMipOptions);
2294                  if (((moreMipOptions+1)%1000000)!=0)
2295                    babModel->setSearchStrategy(moreMipOptions%1000000);
2296                  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2297                  // go faster stripes
2298                  if( moreMipOptions >=999999) {
2299                    if (osiclp) {
2300                      int save = osiclp->specialOptions();
2301                      osiclp->setupForRepeatedUse(2,0);
2302                      osiclp->setSpecialOptions(save|osiclp->specialOptions());
2303                    }
2304                  } 
2305                }
2306              }
2307              if (type==BAB) {
2308#ifdef COIN_HAS_ASL
2309                if (usingAmpl) {
2310                  priorities=info.priorities;
2311                  branchDirection=info.branchDirection;
2312                  pseudoDown=info.pseudoDown;
2313                  pseudoUp=info.pseudoUp;
2314                  solutionIn=info.primalSolution;
2315                  prioritiesIn = info.priorities;
2316                  if (info.numberSos&&doSOS) {
2317                    // SOS
2318                    numberSOS = info.numberSos;
2319                    sosStart = info.sosStart;
2320                    sosIndices = info.sosIndices;
2321                    sosType = info.sosType;
2322                    sosReference = info.sosReference;
2323                    sosPriority = info.sosPriority;
2324                  }
2325                }
2326#endif               
2327                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
2328                if (solutionIn&&useSolution) {
2329                  if (preProcess) {
2330                    int numberColumns = babModel->getNumCols();
2331                    // extend arrays in case SOS
2332                    int n = originalColumns[numberColumns-1]+1;
2333                    int nSmaller = CoinMin(n,numberOriginalColumns);
2334                    double * solutionIn2 = new double [n];
2335                    int * prioritiesIn2 = new int[n];
2336                    int i;
2337                    for (i=0;i<nSmaller;i++) {
2338                      solutionIn2[i]=solutionIn[i];
2339                      prioritiesIn2[i]=prioritiesIn[i];
2340                    }
2341                    for (;i<n;i++) {
2342                      solutionIn2[i]=0.0;
2343                      prioritiesIn2[i]=1000000;
2344                    }
2345                    int iLast=-1;
2346                    for (i=0;i<numberColumns;i++) {
2347                      int iColumn = originalColumns[i];
2348                      assert (iColumn>iLast);
2349                      iLast=iColumn;
2350                      solutionIn2[i]=solutionIn2[iColumn];
2351                      if (prioritiesIn)
2352                        prioritiesIn2[i]=prioritiesIn2[iColumn];
2353                    }
2354                    babModel->setHotstartSolution(solutionIn2,prioritiesIn2);
2355                    delete [] solutionIn2;
2356                    delete [] prioritiesIn2;
2357                  } else {
2358                    babModel->setHotstartSolution(solutionIn,prioritiesIn);
2359                  }
2360                }
2361                int testOsiOptions = parameters[whichParam(TESTOSI,numberParameters,parameters)].intValue();
2362                OsiSolverInterface * testOsiSolver= (testOsiOptions>=0) ? babModel->solver() : NULL;
2363                if (!testOsiSolver) {
2364                  // *************************************************************
2365                  // CbcObjects
2366                  if (preProcess&&process.numberSOS()) {
2367                    int numberSOS = process.numberSOS();
2368                    int numberIntegers = babModel->numberIntegers();
2369                    /* model may not have created objects
2370                       If none then create
2371                    */
2372                    if (!numberIntegers||!babModel->numberObjects()) {
2373                      int type = (pseudoUp) ? 1 : 0;
2374                      babModel->findIntegers(true,type);
2375                      numberIntegers = babModel->numberIntegers();
2376                    }
2377                    OsiObject ** oldObjects = babModel->objects();
2378                    // Do sets and priorities
2379                    OsiObject ** objects = new OsiObject * [numberSOS];
2380                    // set old objects to have low priority
2381                    int numberOldObjects = babModel->numberObjects();
2382                    int numberColumns = babModel->getNumCols();
2383                    for (int iObj = 0;iObj<numberOldObjects;iObj++) {
2384                      oldObjects[iObj]->setPriority(numberColumns+1);
2385                      int iColumn = oldObjects[iObj]->columnNumber();
2386                      assert (iColumn>=0);
2387                      if (iColumn>=numberOriginalColumns)
2388                        continue;
2389                      if (originalColumns)
2390                        iColumn = originalColumns[iColumn];
2391                      if (branchDirection) {
2392                        CbcSimpleInteger * obj =
2393                          dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
2394                        if (obj) { 
2395                          obj->setPreferredWay(branchDirection[iColumn]);
2396                        } else {
2397                          CbcObject * obj =
2398                            dynamic_cast <CbcObject *>(oldObjects[iObj]) ;
2399                          assert (obj);
2400                          obj->setPreferredWay(branchDirection[iColumn]);
2401                        }
2402                      }
2403                      if (pseudoUp) {
2404                        CbcSimpleIntegerPseudoCost * obj1a =
2405                          dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
2406                        assert (obj1a);
2407                        if (pseudoDown[iColumn]>0.0)
2408                          obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2409                        if (pseudoUp[iColumn]>0.0)
2410                          obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2411                      }
2412                    }
2413                    const int * starts = process.startSOS();
2414                    const int * which = process.whichSOS();
2415                    const int * type = process.typeSOS();
2416                    const double * weight = process.weightSOS();
2417                    int iSOS;
2418                    for (iSOS =0;iSOS<numberSOS;iSOS++) {
2419                      int iStart = starts[iSOS];
2420                      int n=starts[iSOS+1]-iStart;
2421                      objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
2422                                                 iSOS,type[iSOS]);
2423                      // branch on long sets first
2424                      objects[iSOS]->setPriority(numberColumns-n);
2425                    }
2426                    babModel->addObjects(numberSOS,objects);
2427                    for (iSOS=0;iSOS<numberSOS;iSOS++)
2428                      delete objects[iSOS];
2429                    delete [] objects;
2430                  } else if (priorities||branchDirection||pseudoDown||pseudoUp||numberSOS) {
2431                    // do anyway for priorities etc
2432                    int numberIntegers = babModel->numberIntegers();
2433                    /* model may not have created objects
2434                       If none then create
2435                    */
2436                    if (!numberIntegers||!babModel->numberObjects()) {
2437                      int type = (pseudoUp) ? 1 : 0;
2438                      babModel->findIntegers(true,type);
2439                    }
2440                    if (numberSOS) {
2441                      // Do sets and priorities
2442                      OsiObject ** objects = new OsiObject * [numberSOS];
2443                      int iSOS;
2444                      if (originalColumns) {
2445                        // redo sequence numbers
2446                        int numberColumns = babModel->getNumCols();
2447                        int nOld = originalColumns[numberColumns-1]+1;
2448                        int * back = new int[nOld];
2449                        int i;
2450                        for (i=0;i<nOld;i++)
2451                          back[i]=-1;
2452                        for (i=0;i<numberColumns;i++)
2453                          back[originalColumns[i]]=i;
2454                        // Really need better checks
2455                        int nMissing=0;
2456                        int n=sosStart[numberSOS];
2457                        for (i=0;i<n;i++) {
2458                          int iColumn = sosIndices[i];
2459                          int jColumn = back[iColumn];
2460                          if (jColumn>=0) 
2461                            sosIndices[i] = jColumn;
2462                          else 
2463                            nMissing++;
2464                        }
2465                        delete [] back;
2466                        if (nMissing)
2467                          printf("%d SOS variables vanished due to pre processing? - check validity?\n",nMissing);
2468                      }
2469                      for (iSOS =0;iSOS<numberSOS;iSOS++) {
2470                        int iStart = sosStart[iSOS];
2471                        int n=sosStart[iSOS+1]-iStart;
2472                        objects[iSOS] = new CbcSOS(babModel,n,sosIndices+iStart,sosReference+iStart,
2473                                                   iSOS,sosType[iSOS]);
2474                        if (sosPriority)
2475                          objects[iSOS]->setPriority(sosPriority[iSOS]);
2476                        else if (!prioritiesIn)
2477                          objects[iSOS]->setPriority(10);  // rather than 1000
2478                      }
2479                      // delete any existing SOS objects
2480                      int numberObjects=babModel->numberObjects();
2481                      OsiObject ** oldObjects=babModel->objects();
2482                      int nNew=0;
2483                      for (int i=0;i<numberObjects;i++) {
2484                        OsiObject * objThis = oldObjects[i];
2485                        CbcSOS * obj1 =
2486                          dynamic_cast <CbcSOS *>(objThis) ;
2487                        OsiSOS * obj2 =
2488                          dynamic_cast <OsiSOS *>(objThis) ;
2489                        if (!obj1&&!obj2) {
2490                          oldObjects[nNew++]=objThis;
2491                        } else {
2492                          delete objThis;
2493                        }
2494                      }
2495                      babModel->setNumberObjects(nNew);
2496                      babModel->addObjects(numberSOS,objects);
2497                      for (iSOS=0;iSOS<numberSOS;iSOS++)
2498                        delete objects[iSOS];
2499                      delete [] objects;
2500                    }
2501                  }
2502                  OsiObject ** objects = babModel->objects();
2503                  int numberObjects = babModel->numberObjects();
2504                  for (int iObj = 0;iObj<numberObjects;iObj++) {
2505                    // skip sos
2506                    CbcSOS * objSOS =
2507                      dynamic_cast <CbcSOS *>(objects[iObj]) ;
2508                    if (objSOS)
2509                      continue;
2510                    int iColumn = objects[iObj]->columnNumber();
2511                    assert (iColumn>=0);
2512                    if (originalColumns)
2513                      iColumn = originalColumns[iColumn];
2514                    if (branchDirection) {
2515                      CbcSimpleInteger * obj =
2516                        dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
2517                      if (obj) { 
2518                        obj->setPreferredWay(branchDirection[iColumn]);
2519                      } else {
2520                        CbcObject * obj =
2521                          dynamic_cast <CbcObject *>(objects[iObj]) ;
2522                        assert (obj);
2523                        obj->setPreferredWay(branchDirection[iColumn]);
2524                      }
2525                    }
2526                    if (priorities) {
2527                      int iPriority = priorities[iColumn];
2528                      if (iPriority>0)
2529                        objects[iObj]->setPriority(iPriority);
2530                    }
2531                    if (pseudoUp&&pseudoUp[iColumn]) {
2532                      CbcSimpleIntegerPseudoCost * obj1a =
2533                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
2534                      assert (obj1a);
2535                      if (pseudoDown[iColumn]>0.0)
2536                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
2537                      if (pseudoUp[iColumn]>0.0)
2538                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
2539                    }
2540                  }
2541                  // *************************************************************
2542                } else {
2543                  // *************************************************************
2544                  // OsiObjects
2545                  if (preProcess&&process.numberSOS()) {
2546                    int numberSOS = process.numberSOS();
2547                    int numberIntegers = testOsiSolver->getNumIntegers();
2548                    /* model may not have created objects
2549                       If none then create
2550                    */
2551                    if (!numberIntegers||!testOsiSolver->numberObjects()) {
2552                      //int type = (pseudoUp) ? 1 : 0;
2553                      testOsiSolver->findIntegers(false);
2554                      numberIntegers = testOsiSolver->getNumIntegers();
2555                    }
2556                    OsiObject ** oldObjects = testOsiSolver->objects();
2557                    // Do sets and priorities
2558                    OsiObject ** objects = new OsiObject * [numberSOS];
2559                    // set old objects to have low priority
2560                    int numberOldObjects = testOsiSolver->numberObjects();
2561                    int numberColumns = testOsiSolver->getNumCols();
2562                    for (int iObj = 0;iObj<numberOldObjects;iObj++) {
2563                      oldObjects[iObj]->setPriority(numberColumns+1);
2564                      int iColumn = oldObjects[iObj]->columnNumber();
2565                      assert (iColumn>=0);
2566                      if (iColumn>=numberOriginalColumns)
2567                        continue;
2568                      if (originalColumns)
2569                        iColumn = originalColumns[iColumn];
2570                      if (branchDirection) {
2571                        OsiSimpleInteger * obj =
2572                          dynamic_cast <OsiSimpleInteger *>(oldObjects[iObj]) ;
2573                        if (obj) { 
2574                          obj->setPreferredWay(branchDirection[iColumn]);
2575                        } else {
2576                          OsiObject2 * obj =
2577                            dynamic_cast <OsiObject2 *>(oldObjects[iObj]) ;
2578                          if (obj)
2579                            obj->setPreferredWay(branchDirection[iColumn]);
2580                        }
2581                      }
2582                      if (pseudoUp) {
2583                        abort();
2584                      }
2585                    }
2586                    const int * starts = process.startSOS();
2587                    const int * which = process.whichSOS();
2588                    const int * type = process.typeSOS();
2589                    const double * weight = process.weightSOS();
2590                    int iSOS;
2591                    for (iSOS =0;iSOS<numberSOS;iSOS++) {
2592                      int iStart = starts[iSOS];
2593                      int n=starts[iSOS+1]-iStart;
2594                      objects[iSOS] = new OsiSOS(testOsiSolver,n,which+iStart,weight+iStart,
2595                                                 type[iSOS]);
2596                      // branch on long sets first
2597                      objects[iSOS]->setPriority(numberColumns-n);
2598                    }
2599                    testOsiSolver->addObjects(numberSOS,objects);
2600                    for (iSOS=0;iSOS<numberSOS;iSOS++)
2601                      delete objects[iSOS];
2602                    delete [] objects;
2603                  } else if (priorities||branchDirection||pseudoDown||pseudoUp||numberSOS) {
2604                    // do anyway for priorities etc
2605                    int numberIntegers = testOsiSolver->getNumIntegers();
2606                    /* model may not have created objects
2607                       If none then create
2608                    */
2609                    if (!numberIntegers||!testOsiSolver->numberObjects()) {
2610                      //int type = (pseudoUp) ? 1 : 0;
2611                      testOsiSolver->findIntegers(false);
2612                    }
2613                    if (numberSOS) {
2614                      // Do sets and priorities
2615                      OsiObject ** objects = new OsiObject * [numberSOS];
2616                      int iSOS;
2617                      if (originalColumns) {
2618                        // redo sequence numbers
2619                        int numberColumns = testOsiSolver->getNumCols();
2620                        int nOld = originalColumns[numberColumns-1]+1;
2621                        int * back = new int[nOld];
2622                        int i;
2623                        for (i=0;i<nOld;i++)
2624                          back[i]=-1;
2625                        for (i=0;i<numberColumns;i++)
2626                          back[originalColumns[i]]=i;
2627                        // Really need better checks
2628                        int nMissing=0;
2629                        int n=sosStart[numberSOS];
2630                        for (i=0;i<n;i++) {
2631                          int iColumn = sosIndices[i];
2632                          int jColumn = back[iColumn];
2633                          if (jColumn>=0) 
2634                            sosIndices[i] = jColumn;
2635                          else 
2636                            nMissing++;
2637                        }
2638                        delete [] back;
2639                        if (nMissing)
2640                          printf("%d SOS variables vanished due to pre processing? - check validity?\n",nMissing);
2641                      }
2642                      for (iSOS =0;iSOS<numberSOS;iSOS++) {
2643                        int iStart = sosStart[iSOS];
2644                        int n=sosStart[iSOS+1]-iStart;
2645                        objects[iSOS] = new OsiSOS(testOsiSolver,n,sosIndices+iStart,sosReference+iStart,
2646                                                   sosType[iSOS]);
2647                        if (sosPriority)
2648                          objects[iSOS]->setPriority(sosPriority[iSOS]);
2649                        else if (!prioritiesIn)
2650                          objects[iSOS]->setPriority(10);  // rather than 1000
2651                      }
2652                      // delete any existing SOS objects
2653                      int numberObjects=testOsiSolver->numberObjects();
2654                      OsiObject ** oldObjects=testOsiSolver->objects();
2655                      int nNew=0;
2656                      for (int i=0;i<numberObjects;i++) {
2657                        OsiObject * objThis = oldObjects[i];
2658                        OsiSOS * obj1 =
2659                          dynamic_cast <OsiSOS *>(objThis) ;
2660                        OsiSOS * obj2 =
2661                          dynamic_cast <OsiSOS *>(objThis) ;
2662                        if (!obj1&&!obj2) {
2663                          oldObjects[nNew++]=objThis;
2664                        } else {
2665                          delete objThis;
2666                        }
2667                      }
2668                      testOsiSolver->setNumberObjects(nNew);
2669                      testOsiSolver->addObjects(numberSOS,objects);
2670                      for (iSOS=0;iSOS<numberSOS;iSOS++)
2671                        delete objects[iSOS];
2672                      delete [] objects;
2673                    }
2674                  }
2675                  OsiObject ** objects = testOsiSolver->objects();
2676                  int numberObjects = testOsiSolver->numberObjects();
2677                  for (int iObj = 0;iObj<numberObjects;iObj++) {
2678                    // skip sos
2679                    OsiSOS * objSOS =
2680                      dynamic_cast <OsiSOS *>(objects[iObj]) ;
2681                    if (objSOS)
2682                      continue;
2683                    int iColumn = objects[iObj]->columnNumber();
2684                    assert (iColumn>=0);
2685                    if (originalColumns)
2686                      iColumn = originalColumns[iColumn];
2687                    if (branchDirection) {
2688                      OsiSimpleInteger * obj =
2689                        dynamic_cast <OsiSimpleInteger *>(objects[iObj]) ;
2690                      if (obj) { 
2691                        obj->setPreferredWay(branchDirection[iColumn]);
2692                      } else {
2693                        OsiObject2 * obj =
2694                          dynamic_cast <OsiObject2 *>(objects[iObj]) ;
2695                        if (obj)
2696                          obj->setPreferredWay(branchDirection[iColumn]);
2697                      }
2698                    }
2699                    if (priorities) {
2700                      int iPriority = priorities[iColumn];
2701                      if (iPriority>0)
2702                        objects[iObj]->setPriority(iPriority);
2703                    }
2704                    if (pseudoUp&&pseudoUp[iColumn]) {
2705                      abort();
2706                    }
2707                  }
2708                  // *************************************************************
2709                }
2710                int statistics = (printOptions>0) ? printOptions: 0;
2711#ifdef COIN_HAS_ASL
2712                if (!usingAmpl) {
2713#endif
2714                  free(priorities);
2715                  priorities=NULL;
2716                  free(branchDirection);
2717                  branchDirection=NULL;
2718                  free(pseudoDown);
2719                  pseudoDown=NULL;
2720                  free(pseudoUp);
2721                  pseudoUp=NULL;
2722                  free(solutionIn);
2723                  solutionIn=NULL;
2724                  free(prioritiesIn);
2725                  prioritiesIn=NULL;
2726                  free(sosStart);
2727                  sosStart=NULL;
2728                  free(sosIndices);
2729                  sosIndices=NULL;
2730                  free(sosType);
2731                  sosType=NULL;
2732                  free(sosReference);
2733                  sosReference=NULL;
2734                  free(sosPriority);
2735                  sosPriority=NULL;
2736#ifdef COIN_HAS_ASL
2737                }
2738#endif               
2739                if (nodeStrategy) {
2740                  // change default
2741                  if (nodeStrategy>1) {
2742                    // up or down
2743                    int way = ((nodeStrategy%1)==1) ? -1 : +1;
2744                    babModel->setPreferredWay(way);
2745#if 0
2746                    OsiObject ** objects = babModel->objects();
2747                    int numberObjects = babModel->numberObjects();
2748                    for (int iObj = 0;iObj<numberObjects;iObj++) {
2749                      CbcObject * obj =
2750                        dynamic_cast <CbcObject *>(objects[iObj]) ;
2751                      assert (obj);
2752                      obj->setPreferredWay(way);
2753                    }
2754#endif
2755                  }
2756                  if (nodeStrategy==1||nodeStrategy>3) {
2757                    // depth
2758                    CbcCompareDefault compare;
2759                    compare.setWeight(-3.0);
2760                    babModel->setNodeComparison(compare);
2761                  }
2762                }
2763                if (cppValue>=0) {
2764                  int prepro = useStrategy ? -1 : preProcess;
2765                  // generate code
2766                  FILE * fp = fopen("user_driver.cpp","w");
2767                  if (fp) {
2768                    // generate enough to do BAB
2769                    babModel->generateCpp(fp,1);
2770                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2771                    // Make general so do factorization
2772                    int factor = osiclp->getModelPtr()->factorizationFrequency();
2773                    osiclp->getModelPtr()->setFactorizationFrequency(200);
2774                    osiclp->generateCpp(fp);
2775                    osiclp->getModelPtr()->setFactorizationFrequency(factor);
2776                    //solveOptions.generateCpp(fp);
2777                    fclose(fp);
2778                    // now call generate code
2779                    generateCode(babModel,"user_driver.cpp",cppValue,prepro);
2780                  } else {
2781                    std::cout<<"Unable to open file user_driver.cpp"<<std::endl;
2782                  }
2783                }
2784                if (useStrategy) {
2785                  CbcStrategyDefault strategy(true,babModel->numberStrong(),babModel->numberBeforeTrust());
2786                  strategy.setupPreProcessing(1);
2787                  babModel->setStrategy(strategy);
2788                }
2789                if (testOsiOptions>=0) {
2790                  printf("Testing OsiObject options %d\n",testOsiOptions);
2791                  CbcBranchDefaultDecision decision;
2792                  if (!numberSOS) {
2793                    babModel->solver()->findIntegersAndSOS(false);
2794                  } else {
2795                    // move across
2796                    babModel->deleteObjects(false);
2797                    //babModel->addObjects(babModel->solver()->numberObjects(),babModel->solver()->objects());
2798                  }
2799                  //OsiChooseVariable choose(babModel->solver());
2800                  OsiChooseStrong choose(babModel->solver());
2801                  choose.setNumberBeforeTrusted(babModel->numberBeforeTrust());
2802                  choose.setNumberStrong(babModel->numberStrong());
2803                  choose.setShadowPriceMode(testOsiOptions);
2804                  decision.setChooseMethod(choose);
2805                  babModel->setBranchingMethod(decision);
2806                }
2807                checkSOS(babModel, babModel->solver());
2808                if (doSprint>0) {
2809                  // Sprint for primal solves
2810                  ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
2811                  ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
2812                  int numberPasses = 5;
2813                  int options[] = {0,3,0,0,0,0};
2814                  int extraInfo[] = {-1,20,-1,-1,-1,-1};
2815                  extraInfo[1]=doSprint;
2816                  int independentOptions[] = {0,0,3};
2817                  ClpSolve clpSolve(method,presolveType,numberPasses,
2818                                    options,extraInfo,independentOptions);
2819                  // say use in OsiClp
2820                  clpSolve.setSpecialOption(6,1);
2821                  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2822                  osiclp->setSolveOptions(clpSolve);
2823                  osiclp->setHintParam(OsiDoDualInResolve,false);
2824                }
2825                babModel->branchAndBound(statistics);
2826                checkSOS(babModel, babModel->solver());
2827              } else if (type==MIPLIB) {
2828                CbcStrategyDefault strategy(true,babModel->numberStrong(),babModel->numberBeforeTrust());
2829                // Set up pre-processing
2830                int translate2[]={9999,1,1,3,2,4,5};
2831                if (preProcess)
2832                  strategy.setupPreProcessing(translate2[preProcess]);
2833                babModel->setStrategy(strategy);
2834                CbcClpUnitTest(*babModel);
2835                goodModel=false;
2836                break;
2837              } else {
2838                strengthenedModel = babModel->strengthenedModel();
2839              }
2840              currentBranchModel = NULL;
2841              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
2842              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
2843                lpSolver = osiclp->getModelPtr();
2844                //move best solution (should be there -- but ..)
2845                int n = lpSolver->getNumCols();
2846                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
2847                saveSolution(osiclp->getModelPtr(),"debug.file");
2848              }
2849              if (!noPrinting) {
2850                // Print more statistics
2851                std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
2852                         <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
2853               
2854                numberGenerators = babModel->numberCutGenerators();
2855                for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
2856                  CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
2857                  std::cout<<generator->cutGeneratorName()<<" was tried "
2858                           <<generator->numberTimesEntered()<<" times and created "
2859                           <<generator->numberCutsInTotal()<<" cuts of which "
2860                           <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
2861                  if (generator->timing())
2862                    std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
2863                  else
2864                    std::cout<<std::endl;
2865                }
2866              }
2867              time2 = CoinCpuTime();
2868              totalTime += time2-time1;
2869              // For best solution
2870              double * bestSolution = NULL;
2871              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
2872                // post process
2873                if (preProcess) {
2874                  int n = saveSolver->getNumCols();
2875                  bestSolution = new double [n];
2876                  process.postProcess(*babModel->solver());
2877                  // Solution now back in saveSolver
2878                  babModel->assignSolver(saveSolver);
2879                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2880                } else {
2881                  int n = babModel->solver()->getNumCols();
2882                  bestSolution = new double [n];
2883                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
2884                }
2885                checkSOS(babModel, babModel->solver());
2886              }
2887              if (type==STRENGTHEN&&strengthenedModel)
2888                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
2889              lpSolver = clpSolver->getModelPtr();
2890              if (numberChanged) {
2891                for (int i=0;i<numberChanged;i++) {
2892                  int iColumn=changed[i];
2893                  clpSolver->setContinuous(iColumn);
2894                }
2895                delete [] changed;
2896              }
2897              if (type==BAB) {
2898                //move best solution (should be there -- but ..)
2899                int n = lpSolver->getNumCols();
2900                if (bestSolution)
2901                  memcpy(lpSolver->primalColumnSolution(),bestSolution,n*sizeof(double));
2902                if (debugFile=="create"&&bestSolution) {
2903                  saveSolution(lpSolver,"debug.file");
2904                }
2905                delete [] bestSolution;
2906                std::string statusName[]={"Finished","Stopped on ","Difficulties",
2907                                          "","","User ctrl-c"};
2908                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
2909                int iStat = babModel->status();
2910                int iStat2 = babModel->secondaryStatus();
2911                if (!noPrinting)
2912                  std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
2913                           <<" objective "<<babModel->getObjValue()<<
2914                    " after "<<babModel->getNodeCount()<<" nodes and "
2915                           <<babModel->getIterationCount()<<
2916                    " iterations - took "<<time2-time1<<" seconds"<<std::endl;
2917#ifdef COIN_HAS_ASL
2918                if (usingAmpl) {
2919                  double value = babModel->getObjValue()*lpSolver->getObjSense();
2920                  char buf[300];
2921                  int pos=0;
2922                  if (iStat==0) {
2923                    if (babModel->getObjValue()<1.0e40) {
2924                      pos += sprintf(buf+pos,"optimal," );
2925                    } else {
2926                      // infeasible
2927                      iStat=1;
2928                      pos += sprintf(buf+pos,"infeasible,");
2929                    }
2930                  } else if (iStat==1) {
2931                    if (iStat2!=6)
2932                      iStat=3;
2933                    else
2934                      iStat=4;
2935                    pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
2936                  } else if (iStat==2) {
2937                    iStat = 7;
2938                    pos += sprintf(buf+pos,"stopped on difficulties,");
2939                  } else if (iStat==5) {
2940                    iStat = 3;
2941                    pos += sprintf(buf+pos,"stopped on ctrl-c,");
2942                  } else {
2943                    pos += sprintf(buf+pos,"status unknown,");
2944                    iStat=6;
2945                  }
2946                  info.problemStatus=iStat;
2947                  info.objValue = value;
2948                  if (babModel->getObjValue()<1.0e40) 
2949                    pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
2950                                   value);
2951                  sprintf(buf+pos,"\n%d nodes, %d iterations",
2952                          babModel->getNodeCount(),
2953                          babModel->getIterationCount());
2954                  if (bestSolution) {
2955                    free(info.primalSolution);
2956                    info.primalSolution = (double *) malloc(n*sizeof(double));
2957                    CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
2958                    int numberRows = lpSolver->numberRows();
2959                    free(info.dualSolution);
2960                    info.dualSolution = (double *) malloc(numberRows*sizeof(double));
2961                    CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
2962                  } else {
2963                    info.primalSolution=NULL;
2964                    info.dualSolution=NULL;
2965                  }
2966                  // put buffer into info
2967                  strcpy(info.buffer,buf);
2968                }
2969#endif
2970              } else {
2971                std::cout<<"Model strengthened - now has "<<clpSolver->getNumRows()
2972                         <<" rows"<<std::endl;
2973              }
2974              time1 = time2;
2975              delete babModel;
2976              babModel=NULL;
2977            } else {
2978              std::cout << "** Current model not valid" << std::endl ; 
2979            }
2980            break ;
2981          case IMPORT:
2982            {
2983#ifdef COIN_HAS_ASL
2984              if (!usingAmpl) {
2985#endif
2986                free(priorities);
2987                priorities=NULL;
2988                free(branchDirection);
2989                branchDirection=NULL;
2990                free(pseudoDown);
2991                pseudoDown=NULL;
2992                free(pseudoUp);
2993                pseudoUp=NULL;
2994                free(solutionIn);
2995                solutionIn=NULL;
2996                free(prioritiesIn);
2997                prioritiesIn=NULL;
2998                free(sosStart);
2999                sosStart=NULL;
3000                free(sosIndices);
3001                sosIndices=NULL;
3002                free(sosType);
3003                sosType=NULL;
3004                free(sosReference);
3005                sosReference=NULL;
3006                free(sosPriority);
3007                sosPriority=NULL;
3008#ifdef COIN_HAS_ASL
3009              }
3010#endif               
3011              delete babModel;
3012              babModel=NULL;
3013              // get next field
3014              field = CoinReadGetString(argc,argv);
3015              if (field=="$") {
3016                field = parameters[iParam].stringValue();
3017              } else if (field=="EOL") {
3018                parameters[iParam].printString();
3019                break;
3020              } else {
3021                parameters[iParam].setStringValue(field);
3022              }
3023              std::string fileName;
3024              bool canOpen=false;
3025              if (field=="-") {
3026                // stdin
3027                canOpen=true;
3028                fileName = "-";
3029              } else {
3030                bool absolutePath;
3031                if (dirsep=='/') {
3032                  // non Windows (or cygwin)
3033                  absolutePath=(field[0]=='/');
3034                } else {
3035                  //Windows (non cycgwin)
3036                  absolutePath=(field[0]=='\\');
3037                  // but allow for :
3038                  if (strchr(field.c_str(),':'))
3039                    absolutePath=true;
3040                }
3041                if (absolutePath) {
3042                  fileName = field;
3043                } else if (field[0]=='~') {
3044                  char * environVar = getenv("HOME");
3045                  if (environVar) {
3046                    std::string home(environVar);
3047                    field=field.erase(0,1);
3048                    fileName = home+field;
3049                  } else {
3050                    fileName=field;
3051                  }
3052                } else {
3053                  fileName = directory+field;
3054                }
3055                FILE *fp=fopen(fileName.c_str(),"r");
3056                if (fp) {
3057                  // can open - lets go for it
3058                  fclose(fp);
3059                  canOpen=true;
3060                } else {
3061                  std::cout<<"Unable to open file "<<fileName<<std::endl;
3062                }
3063              }
3064              if (canOpen) {
3065                int status =clpSolver->readMps(fileName.c_str(),
3066                                                   keepImportNames!=0,
3067                                                   allowImportErrors!=0);
3068                if (!status||(status>0&&allowImportErrors)) {
3069                  if (keepImportNames) {
3070                    lengthName = lpSolver->lengthNames();
3071                    rowNames = *(lpSolver->rowNames());
3072                    columnNames = *(lpSolver->columnNames());
3073                  } else {
3074                    lengthName=0;
3075                  }
3076                  goodModel=true;
3077                  //Set integers in clpsolver
3078                  const char * info = lpSolver->integerInformation();
3079                  if (info) {
3080                    int numberColumns = lpSolver->numberColumns();
3081                    int i;
3082                    for (i=0;i<numberColumns;i++) {
3083                      if (info[i]) 
3084                        clpSolver->setInteger(i);
3085                    }
3086                  }
3087                  // sets to all slack (not necessary?)
3088                  lpSolver->createStatus();
3089                  time2 = CoinCpuTime();
3090                  totalTime += time2-time1;
3091                  time1=time2;
3092                  // Go to canned file if just input file
3093                  if (CbcOrClpRead_mode==2&&argc==2) {
3094                    // only if ends .mps
3095                    std::string::size_type loc = fileName.find(".mps") ;
3096                    if (loc != std::string::npos &&
3097                        fileName.length() == loc+3)
3098                    { fileName.replace(loc+1,3,"par") ;
3099                      FILE *fp=fopen(fileName.c_str(),"r");
3100                      if (fp) {
3101                        CbcOrClpReadCommand=fp; // Read from that file
3102                        CbcOrClpRead_mode=-1;
3103                      }
3104                    }
3105                  }
3106                } else {
3107                  // errors
3108                  std::cout<<"There were "<<status<<
3109                    " errors on input"<<std::endl;
3110                }
3111              }
3112            }
3113            break;
3114          case EXPORT:
3115            if (goodModel) {
3116              // get next field
3117              field = CoinReadGetString(argc,argv);
3118              if (field=="$") {
3119                field = parameters[iParam].stringValue();
3120              } else if (field=="EOL") {
3121                parameters[iParam].printString();
3122                break;
3123              } else {
3124                parameters[iParam].setStringValue(field);
3125              }
3126              std::string fileName;
3127              bool canOpen=false;
3128              if (field[0]=='/'||field[0]=='\\') {
3129                fileName = field;
3130              } else if (field[0]=='~') {
3131                char * environVar = getenv("HOME");
3132                if (environVar) {
3133                  std::string home(environVar);
3134                  field=field.erase(0,1);
3135                  fileName = home+field;
3136                } else {
3137                  fileName=field;
3138                }
3139              } else {
3140                fileName = directory+field;
3141              }
3142              FILE *fp=fopen(fileName.c_str(),"w");
3143              if (fp) {
3144                // can open - lets go for it
3145                fclose(fp);
3146                canOpen=true;
3147              } else {
3148                std::cout<<"Unable to open file "<<fileName<<std::endl;
3149              }
3150              if (canOpen) {
3151                // If presolve on then save presolved
3152                bool deleteModel2=false;
3153                ClpSimplex * model2 = lpSolver;
3154#ifdef COIN_HAS_ASL
3155                if (info.numberSos&&doSOS&&usingAmpl) {
3156                  // SOS
3157                  numberSOS = info.numberSos;
3158                  sosStart = info.sosStart;
3159                  sosIndices = info.sosIndices;
3160                  sosReference = info.sosReference;
3161                  preSolve=false;
3162                  clpSolver->setSOSData(numberSOS,info.sosType,sosStart,sosIndices,sosReference);
3163                }
3164#endif
3165                if (preSolve) {
3166                  ClpPresolve pinfo;
3167                  int presolveOptions2 = presolveOptions&~0x40000000;
3168                  if ((presolveOptions2&0xffff)!=0)
3169                    pinfo.setPresolveActions(presolveOptions2);
3170                  if ((printOptions&1)!=0)
3171                    pinfo.statistics();
3172                  double presolveTolerance = 
3173                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
3174                  model2 = 
3175                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
3176                                         true,preSolve);
3177                  if (model2) {
3178                    printf("Saving presolved model on %s\n",
3179                           fileName.c_str());
3180                    deleteModel2=true;
3181                  } else {
3182                    printf("Presolved model looks infeasible - saving original on %s\n",
3183                           fileName.c_str());
3184                    deleteModel2=false;
3185                    model2 = lpSolver;
3186
3187                  }
3188                  model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
3189                  if (deleteModel2)
3190                    delete model2;
3191                } else {
3192                  printf("Saving model on %s\n",
3193                           fileName.c_str());
3194                  if (numberSOS) {
3195                    // Convert names
3196                    int iRow;
3197                    int numberRows=model2->numberRows();
3198                    int iColumn;
3199                    int numberColumns=model2->numberColumns();
3200                   
3201                    char ** rowNames = NULL;
3202                    char ** columnNames = NULL;
3203                    if (model2->lengthNames()) {
3204                      rowNames = new char * [numberRows];
3205                      for (iRow=0;iRow<numberRows;iRow++) {
3206                        rowNames[iRow] = 
3207                          strdup(model2->rowName(iRow).c_str());
3208                      }
3209                     
3210                      columnNames = new char * [numberColumns];
3211                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
3212                        columnNames[iColumn] = 
3213                          strdup(model2->columnName(iColumn).c_str());
3214                      }
3215                    }
3216                    clpSolver->writeMpsNative(fileName.c_str(),(const char **) rowNames,(const char **) columnNames,
3217                                              (outputFormat-1)/2,1+((outputFormat-1)&1));
3218                    if (rowNames) {
3219                      for (iRow=0;iRow<numberRows;iRow++) {
3220                        free(rowNames[iRow]);
3221                      }
3222                      delete [] rowNames;
3223                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
3224                        free(columnNames[iColumn]);
3225                      }
3226                      delete [] columnNames;
3227                    }
3228                  } else {
3229                    model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
3230                  }
3231                }
3232                time2 = CoinCpuTime();
3233                totalTime += time2-time1;
3234                time1=time2;
3235              }
3236            } else {
3237              std::cout<<"** Current model not valid"<<std::endl;
3238            }
3239            break;
3240          case BASISIN:
3241            if (goodModel) {
3242              // get next field
3243              field = CoinReadGetString(argc,argv);
3244              if (field=="$") {
3245                field = parameters[iParam].stringValue();
3246              } else if (field=="EOL") {
3247                parameters[iParam].printString();
3248                break;
3249              } else {
3250                parameters[iParam].setStringValue(field);
3251              }
3252              std::string fileName;
3253              bool canOpen=false;
3254              if (field=="-") {
3255                // stdin
3256                canOpen=true;
3257                fileName = "-";
3258              } else {
3259                if (field[0]=='/'||field[0]=='\\') {
3260                  fileName = field;
3261                } else if (field[0]=='~') {
3262                  char * environVar = getenv("HOME");
3263                  if (environVar) {
3264                    std::string home(environVar);
3265                    field=field.erase(0,1);
3266                    fileName = home+field;
3267                  } else {
3268                    fileName=field;
3269                  }
3270                } else {
3271                  fileName = directory+field;
3272                }
3273                FILE *fp=fopen(fileName.c_str(),"r");
3274                if (fp) {
3275                  // can open - lets go for it
3276                  fclose(fp);
3277                  canOpen=true;
3278                } else {
3279                  std::cout<<"Unable to open file "<<fileName<<std::endl;
3280                }
3281              }
3282              if (canOpen) {
3283                int values = lpSolver->readBasis(fileName.c_str());
3284                if (values==0)
3285                  basisHasValues=-1;
3286                else
3287                  basisHasValues=1;
3288              }
3289            } else {
3290              std::cout<<"** Current model not valid"<<std::endl;
3291            }
3292            break;
3293          case PRIORITYIN:
3294            if (goodModel) {
3295              // get next field
3296              field = CoinReadGetString(argc,argv);
3297              if (field=="$") {
3298                field = parameters[iParam].stringValue();
3299              } else if (field=="EOL") {
3300                parameters[iParam].printString();
3301                break;
3302              } else {
3303                parameters[iParam].setStringValue(field);
3304              }
3305              std::string fileName;
3306              if (field[0]=='/'||field[0]=='\\') {
3307                fileName = field;
3308              } else if (field[0]=='~') {
3309                char * environVar = getenv("HOME");
3310                if (environVar) {
3311                  std::string home(environVar);
3312                  field=field.erase(0,1);
3313                  fileName = home+field;
3314                } else {
3315                  fileName=field;
3316                }
3317              } else {
3318                fileName = directory+field;
3319              }
3320              FILE *fp=fopen(fileName.c_str(),"r");
3321              if (fp) {
3322                // can open - lets go for it
3323                std::string headings[]={"name","number","direction","priority","up","down",
3324                                        "solution","priin"};
3325                int got[]={-1,-1,-1,-1,-1,-1,-1,-1};
3326                int order[8];
3327                assert(sizeof(got)==sizeof(order));
3328                int nAcross=0;
3329                char line[1000];
3330                int numberColumns = lpSolver->numberColumns();
3331                if (!fgets(line,1000,fp)) {
3332                  std::cout<<"Odd file "<<fileName<<std::endl;
3333                } else {
3334                  char * pos = line;
3335                  char * put = line;
3336                  while (*pos>=' '&&*pos!='\n') {
3337                    if (*pos!=' '&&*pos!='\t') {
3338                      *put=tolower(*pos);
3339                      put++;
3340                    }
3341                    pos++;
3342                  }
3343                  *put='\0';
3344                  pos=line;
3345                  int i;
3346                  bool good=true;
3347                  while (pos) {
3348                    char * comma = strchr(pos,',');
3349                    if (comma)
3350                      *comma='\0';
3351                    for (i=0;i<(int) (sizeof(got)/sizeof(int));i++) {
3352                      if (headings[i]==pos) {
3353                        if (got[i]<0) {
3354                          order[nAcross]=i;
3355                          got[i]=nAcross++;
3356                        } else {
3357                          // duplicate
3358                          good=false;
3359                        }
3360                        break;
3361                      }
3362                    }
3363                    if (i==(int) (sizeof(got)/sizeof(int)))
3364                      good=false;
3365                    if (comma) {
3366                      *comma=',';
3367                      pos=comma+1;
3368                    } else {
3369                      break;
3370                    }
3371                  }
3372                  if (got[0]<0&&got[1]<0)
3373                    good=false;
3374                  if (got[0]>=0&&got[1]>=0)
3375                    good=false;
3376                  if (got[0]>=0&&!lpSolver->lengthNames())
3377                    good=false;
3378                  if (good) {
3379                    char ** columnNames = columnNames = new char * [numberColumns];
3380                    pseudoDown= (double *) malloc(numberColumns*sizeof(double));
3381                    pseudoUp = (double *) malloc(numberColumns*sizeof(double));
3382                    branchDirection = (int *) malloc(numberColumns*sizeof(int));
3383                    priorities= (int *) malloc(numberColumns*sizeof(int));
3384                    free(solutionIn);
3385                    solutionIn=NULL;
3386                    free(prioritiesIn);
3387                    prioritiesIn=NULL;
3388                    int iColumn;
3389                    if (got[6]>=0) {
3390                      solutionIn = (double *) malloc(numberColumns*sizeof(double));
3391                      CoinZeroN(solutionIn,numberColumns);
3392                    }
3393                    if (got[7]>=0) {
3394                      prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
3395                      for (iColumn=0;iColumn<numberColumns;iColumn++) 
3396                        prioritiesIn[iColumn]=10000;
3397                    }
3398                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
3399                      columnNames[iColumn] = 
3400                        strdup(lpSolver->columnName(iColumn).c_str());
3401                      pseudoDown[iColumn]=0.0;
3402                      pseudoUp[iColumn]=0.0;
3403                      branchDirection[iColumn]=0;
3404                      priorities[iColumn]=0;
3405                    }
3406                    int nBadPseudo=0;
3407                    int nBadDir=0;
3408                    int nBadPri=0;
3409                    int nBadName=0;
3410                    int nBadLine=0;
3411                    int nLine=0;
3412                    while (fgets(line,1000,fp)) {
3413                      nLine++;
3414                      iColumn = -1;
3415                      double up =0.0;
3416                      double down=0.0;
3417                      int pri=0;
3418                      int dir=0;
3419                      double solValue=COIN_DBL_MAX;
3420                      int priValue=1000000;
3421                      char * pos = line;
3422                      char * put = line;
3423                      while (*pos>=' '&&*pos!='\n') {
3424                        if (*pos!=' '&&*pos!='\t') {
3425                          *put=tolower(*pos);
3426                          put++;
3427                        }
3428                        pos++;
3429                      }
3430                      *put='\0';
3431                      pos=line;
3432                      for (int i=0;i<nAcross;i++) {
3433                        char * comma = strchr(pos,',');
3434                        if (comma) {
3435                          *comma='\0';
3436                        } else if (i<nAcross-1) {
3437                          nBadLine++;
3438                          break;
3439                        }
3440                        switch (order[i]) {
3441                          // name
3442                        case 0:
3443                          for (iColumn=0;iColumn<numberColumns;iColumn++) {
3444                            if (!strcmp(columnNames[iColumn],pos))
3445                              break;
3446                          }
3447                          if (iColumn==numberColumns)
3448                            iColumn=-1;
3449                          break;
3450                          // number
3451                        case 1:
3452                          iColumn = atoi(pos);
3453                          if (iColumn<0||iColumn>=numberColumns)
3454                            iColumn=-1;
3455                          break;
3456                          // direction
3457                        case 2:
3458                          if (*pos=='D')
3459                            dir=-1;
3460                          else if (*pos=='U')
3461                            dir=1;
3462                          else if (*pos=='N')
3463                            dir=0;
3464                          else if (*pos=='1'&&*(pos+1)=='\0')
3465                            dir=1;
3466                          else if (*pos=='0'&&*(pos+1)=='\0')
3467                            dir=0;
3468                          else if (*pos=='1'&&*(pos+1)=='1'&&*(pos+2)=='\0')
3469                            dir=-1;
3470                          else
3471                            dir=-2; // bad
3472                          break;
3473                          // priority
3474                        case 3:
3475                          pri=atoi(pos);
3476                          break;
3477                          // up
3478                        case 4:
3479                          up = atof(pos);
3480                          break;
3481                          // down
3482                        case 5:
3483                          down = atof(pos);
3484                          break;
3485                          // sol value
3486                        case 6:
3487                          solValue = atof(pos);
3488                          break;
3489                          // priority in value
3490                        case 7:
3491                          priValue = atoi(pos);
3492                          break;
3493                        }
3494                        if (comma) {
3495                          *comma=',';
3496                          pos=comma+1;
3497                        }
3498                      }
3499                      if (iColumn>=0) {
3500                        if (down<0.0) {
3501                          nBadPseudo++;
3502                          down=0.0;
3503                        }
3504                        if (up<0.0) {
3505                          nBadPseudo++;
3506                          up=0.0;
3507                        }
3508                        if (!up)
3509                          up=down;
3510                        if (!down)
3511                          down=up;
3512                        if (dir<-1||dir>1) {
3513                          nBadDir++;
3514                          dir=0;
3515                        }
3516                        if (pri<0) {
3517                          nBadPri++;
3518                          pri=0;
3519                        }
3520                        pseudoDown[iColumn]=down;
3521                        pseudoUp[iColumn]=up;
3522                        branchDirection[iColumn]=dir;
3523                        priorities[iColumn]=pri;
3524                        if (solValue!=COIN_DBL_MAX) {
3525                          assert (solutionIn);
3526                          solutionIn[iColumn]=solValue;
3527                        }
3528                        if (priValue!=1000000) {
3529                          assert (prioritiesIn);
3530                          prioritiesIn[iColumn]=priValue;
3531                        }
3532                      } else {
3533                        nBadName++;
3534                      }
3535                    }
3536                    if (!noPrinting) {
3537                      printf("%d fields and %d records",nAcross,nLine);
3538                      if (nBadPseudo)
3539                        printf(" %d bad pseudo costs",nBadPseudo);
3540                      if (nBadDir)
3541                        printf(" %d bad directions",nBadDir);
3542                      if (nBadPri)
3543                        printf(" %d bad priorities",nBadPri);
3544                      if (nBadName)
3545                        printf(" ** %d records did not match on name/sequence",nBadName);
3546                      printf("\n");
3547                    }
3548                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
3549                      free(columnNames[iColumn]);
3550                    }
3551                    delete [] columnNames;
3552                  } else {
3553                    std::cout<<"Duplicate or unknown keyword - or name/number fields wrong"<<line<<std::endl;
3554                  }
3555                }
3556                fclose(fp);
3557              } else {
3558                std::cout<<"Unable to open file "<<fileName<<std::endl;
3559              }
3560            } else {
3561              std::cout<<"** Current model not valid"<<std::endl;
3562            }
3563            break;
3564          case DEBUG:
3565            if (goodModel) {
3566              delete [] debugValues;
3567              debugValues=NULL;
3568              // get next field
3569              field = CoinReadGetString(argc,argv);
3570              if (field=="$") {
3571                field = parameters[iParam].stringValue();
3572              } else if (field=="EOL") {
3573                parameters[iParam].printString();
3574                break;
3575              } else {
3576                parameters[iParam].setStringValue(field);
3577                debugFile=field;
3578                if (debugFile=="create"||
3579                    debugFile=="createAfterPre") {
3580                  printf("Will create a debug file so this run should be a good one\n");
3581                  break;
3582                }
3583              }
3584              std::string fileName;
3585              if (field[0]=='/'||field[0]=='\\') {
3586                fileName = field;
3587              } else if (field[0]=='~') {
3588                char * environVar = getenv("HOME");
3589                if (environVar) {
3590                  std::string home(environVar);
3591                  field=field.erase(0,1);
3592                  fileName = home+field;
3593                } else {
3594                  fileName=field;
3595                }
3596              } else {
3597                fileName = directory+field;
3598              }
3599              FILE *fp=fopen(fileName.c_str(),"rb");
3600              if (fp) {
3601                // can open - lets go for it
3602                int numRows;
3603                double obj;
3604                fread(&numRows,sizeof(int),1,fp);
3605                fread(&numberDebugValues,sizeof(int),1,fp);
3606                fread(&obj,sizeof(double),1,fp);
3607                debugValues = new double[numberDebugValues+numRows];
3608                fread(debugValues,sizeof(double),numRows,fp);
3609                fread(debugValues,sizeof(double),numRows,fp);
3610                fread(debugValues,sizeof(double),numberDebugValues,fp);
3611                printf("%d doubles read into debugValues\n",numberDebugValues);
3612                fclose(fp);
3613              } else {
3614                std::cout<<"Unable to open file "<<fileName<<std::endl;
3615              }
3616            } else {
3617              std::cout<<"** Current model not valid"<<std::endl;
3618            }
3619            break;
3620          case PRINTMASK:
3621            // get next field
3622            {
3623              std::string name = CoinReadGetString(argc,argv);
3624              if (name!="EOL") {
3625                parameters[iParam].setStringValue(name);
3626                printMask = name;
3627              } else {
3628                parameters[iParam].printString();
3629              }
3630            }
3631            break;
3632          case BASISOUT:
3633            if (goodModel) {
3634              // get next field
3635              field = CoinReadGetString(argc,argv);
3636              if (field=="$") {
3637                field = parameters[iParam].stringValue();
3638              } else if (field=="EOL") {
3639                parameters[iParam].printString();
3640                break;
3641              } else {
3642                parameters[iParam].setStringValue(field);
3643              }
3644              std::string fileName;
3645              bool canOpen=false;
3646              if (field[0]=='/'||field[0]=='\\') {
3647                fileName = field;
3648              } else if (field[0]=='~') {
3649                char * environVar = getenv("HOME");
3650                if (environVar) {
3651                  std::string home(environVar);
3652                  field=field.erase(0,1);
3653                  fileName = home+field;
3654                } else {
3655                  fileName=field;
3656                }
3657              } else {
3658                fileName = directory+field;
3659              }
3660              FILE *fp=fopen(fileName.c_str(),"w");
3661              if (fp) {
3662                // can open - lets go for it
3663                fclose(fp);
3664                canOpen=true;
3665              } else {
3666                std::cout<<"Unable to open file "<<fileName<<std::endl;
3667              }
3668              if (canOpen) {
3669                ClpSimplex * model2 = lpSolver;
3670                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
3671                time2 = CoinCpuTime();
3672                totalTime += time2-time1;
3673                time1=time2;
3674              }
3675            } else {
3676              std::cout<<"** Current model not valid"<<std::endl;
3677            }
3678            break;
3679          case SAVE:
3680            {
3681              // get next field
3682              field = CoinReadGetString(argc,argv);
3683              if (field=="$") {
3684                field = parameters[iParam].stringValue();
3685              } else if (field=="EOL") {
3686                parameters[iParam].printString();
3687                break;
3688              } else {
3689                parameters[iParam].setStringValue(field);
3690              }
3691              std::string fileName;
3692              bool canOpen=false;
3693              if (field[0]=='/'||field[0]=='\\') {
3694                fileName = field;
3695              } else if (field[0]=='~') {
3696                char * environVar = getenv("HOME");
3697                if (environVar) {
3698                  std::string home(environVar);
3699                  field=field.erase(0,1);
3700                  fileName = home+field;
3701                } else {
3702                  fileName=field;
3703                }
3704              } else {
3705                fileName = directory+field;
3706              }
3707              FILE *fp=fopen(fileName.c_str(),"wb");
3708              if (fp) {
3709                // can open - lets go for it
3710                fclose(fp);
3711                canOpen=true;
3712              } else {
3713                std::cout<<"Unable to open file "<<fileName<<std::endl;
3714              }
3715              if (canOpen) {
3716                int status;
3717                // If presolve on then save presolved
3718                bool deleteModel2=false;
3719                ClpSimplex * model2 = lpSolver;
3720                if (preSolve) {
3721                  ClpPresolve pinfo;
3722                  double presolveTolerance = 
3723                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
3724                  model2 = 
3725                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
3726                                         false,preSolve);
3727                  if (model2) {
3728                    printf("Saving presolved model on %s\n",
3729                           fileName.c_str());
3730                    deleteModel2=true;
3731                  } else {
3732                    printf("Presolved model looks infeasible - saving original on %s\n",
3733                           fileName.c_str());
3734                    deleteModel2=false;
3735                    model2 = lpSolver;
3736
3737                  }
3738                } else {
3739                  printf("Saving model on %s\n",
3740                           fileName.c_str());
3741                }
3742                status =model2->saveModel(fileName.c_str());
3743                if (deleteModel2)
3744                  delete model2;
3745                if (!status) {
3746                  goodModel=true;
3747                  time2 = CoinCpuTime();
3748                  totalTime += time2-time1;
3749                  time1=time2;
3750                } else {
3751                  // errors
3752                  std::cout<<"There were errors on output"<<std::endl;
3753                }
3754              }
3755            }
3756            break;
3757          case RESTORE:
3758            {
3759              // get next field
3760              field = CoinReadGetString(argc,argv);
3761              if (field=="$") {
3762                field = parameters[iParam].stringValue();
3763              } else if (field=="EOL") {
3764                parameters[iParam].printString();
3765                break;
3766              } else {
3767                parameters[iParam].setStringValue(field);
3768              }
3769              std::string fileName;
3770              bool canOpen=false;
3771              if (field[0]=='/'||field[0]=='\\') {
3772                fileName = field;
3773              } else if (field[0]=='~') {
3774                char * environVar = getenv("HOME");
3775                if (environVar) {
3776                  std::string home(environVar);
3777                  field=field.erase(0,1);
3778                  fileName = home+field;
3779                } else {
3780                  fileName=field;
3781                }
3782              } else {
3783                fileName = directory+field;
3784              }
3785              FILE *fp=fopen(fileName.c_str(),"rb");
3786              if (fp) {
3787                // can open - lets go for it
3788                fclose(fp);
3789                canOpen=true;
3790              } else {
3791                std::cout<<"Unable to open file "<<fileName<<std::endl;
3792              }
3793              if (canOpen) {
3794                int status =lpSolver->restoreModel(fileName.c_str());
3795                if (!status) {
3796                  goodModel=true;
3797                  time2 = CoinCpuTime();
3798                  totalTime += time2-time1;
3799                  time1=time2;
3800                } else {
3801                  // errors
3802                  std::cout<<"There were errors on input"<<std::endl;
3803                }
3804              }
3805            }
3806            break;
3807          case MAXIMIZE:
3808            lpSolver->setOptimizationDirection(-1);
3809            break;
3810          case MINIMIZE:
3811            lpSolver->setOptimizationDirection(1);
3812            break;
3813          case ALLSLACK:
3814            lpSolver->allSlackBasis(true);
3815            break;
3816          case REVERSE:
3817            if (goodModel) {
3818              int iColumn;
3819              int numberColumns=lpSolver->numberColumns();
3820              double * dualColumnSolution = 
3821                lpSolver->dualColumnSolution();
3822              ClpObjective * obj = lpSolver->objectiveAsObject();
3823              assert(dynamic_cast<ClpLinearObjective *> (obj));
3824              double offset;
3825              double * objective = obj->gradient(NULL,NULL,offset,true);
3826              for (iColumn=0;iColumn<numberColumns;iColumn++) {
3827                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
3828                objective[iColumn] = -objective[iColumn];
3829              }
3830              int iRow;
3831              int numberRows=lpSolver->numberRows();
3832              double * dualRowSolution = 
3833                lpSolver->dualRowSolution();
3834              for (iRow=0;iRow<numberRows;iRow++) 
3835                dualRowSolution[iRow] = dualRowSolution[iRow];
3836            }
3837            break;
3838          case DIRECTORY:
3839            {
3840              std::string name = CoinReadGetString(argc,argv);
3841              if (name!="EOL") {
3842                int length=name.length();
3843                if (name[length-1]=='/'||name[length-1]=='\\')
3844                  directory=name;
3845                else
3846                  directory = name+"/";
3847                parameters[iParam].setStringValue(directory);
3848              } else {
3849                parameters[iParam].printString();
3850              }
3851            }
3852            break;
3853          case STDIN:
3854            CbcOrClpRead_mode=-1;
3855            break;
3856          case NETLIB_DUAL:
3857          case NETLIB_EITHER:
3858          case NETLIB_BARRIER:
3859          case NETLIB_PRIMAL:
3860          case NETLIB_TUNE:
3861            {
3862              // create fields for unitTest
3863              const char * fields[4];
3864              int nFields=2;
3865              fields[0]="fake main from unitTest";
3866              fields[1]="-netlib";
3867              if (directory!=defaultDirectory) {
3868                fields[2]="-netlibDir";
3869                fields[3]=directory.c_str();
3870                nFields=4;
3871              }
3872              int algorithm;
3873              if (type==NETLIB_DUAL) {
3874                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
3875                algorithm =0;
3876              } else if (type==NETLIB_BARRIER) {
3877                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
3878                algorithm =2;
3879              } else if (type==NETLIB_EITHER) {
3880                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
3881                algorithm =3;
3882              } else if (type==NETLIB_TUNE) {
3883                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
3884                algorithm =5;
3885                // uncomment next to get active tuning
3886                // algorithm=6;
3887              } else {
3888                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
3889                algorithm=1;
3890              }
3891              int specialOptions = lpSolver->specialOptions();
3892              lpSolver->setSpecialOptions(0);
3893              mainTest(nFields,fields,algorithm,*lpSolver,
3894                       (preSolve!=0),specialOptions,doVector!=0);
3895            }
3896            break;
3897          case UNITTEST:
3898            {
3899              // create fields for unitTest
3900              const char * fields[3];
3901              int nFields=1;
3902              fields[0]="fake main from unitTest";
3903              if (directory!=defaultDirectory) {
3904                fields[1]="-mpsDir";
3905                fields[2]=directory.c_str();
3906                nFields=3;
3907              }
3908              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
3909                       false,doVector!=0);
3910            }
3911            break;
3912          case FAKEBOUND:
3913            if (goodModel) {
3914              // get bound
3915              double value = CoinReadGetDoubleField(argc,argv,&valid);
3916              if (!valid) {
3917                std::cout<<"Setting "<<parameters[iParam].name()<<
3918                  " to DEBUG "<<value<<std::endl;
3919                int iRow;
3920                int numberRows=lpSolver->numberRows();
3921                double * rowLower = lpSolver->rowLower();
3922                double * rowUpper = lpSolver->rowUpper();
3923                for (iRow=0;iRow<numberRows;iRow++) {
3924                  // leave free ones for now
3925                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
3926                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
3927                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
3928                  }
3929                }
3930                int iColumn;
3931                int numberColumns=lpSolver->numberColumns();
3932                double * columnLower = lpSolver->columnLower();
3933                double * columnUpper = lpSolver->columnUpper();
3934                for (iColumn=0;iColumn<numberColumns;iColumn++) {
3935                  // leave free ones for now
3936                  if (columnLower[iColumn]>-1.0e20||
3937                      columnUpper[iColumn]<1.0e20) {
3938                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
3939                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
3940                  }
3941                }
3942              } else if (valid==1) {
3943                abort();
3944              } else {
3945                std::cout<<"enter value for "<<parameters[iParam].name()<<
3946                  std::endl;
3947              }
3948            }
3949            break;
3950          case REALLY_SCALE:
3951            if (goodModel) {
3952              ClpSimplex newModel(*lpSolver,
3953                                  lpSolver->scalingFlag());
3954              printf("model really really scaled\n");
3955              *lpSolver=newModel;
3956            }
3957            break;
3958          case USERCLP:
3959            // Replace the sample code by whatever you want
3960            if (goodModel) {
3961              printf("Dummy user clp code - model has %d rows and %d columns\n",
3962                     lpSolver->numberRows(),lpSolver->numberColumns());
3963            }
3964            break;
3965          case USERCBC:
3966            // Replace the sample code by whatever you want
3967            if (goodModel) {
3968#ifndef USER_HAS_FAKE_MAIN
3969              printf("Dummy user cbc code - model has %d rows and %d columns\n",
3970                     model.getNumRows(),model.getNumCols());
3971              // Reduce printout
3972              model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
3973              // Do complete search
3974              model.branchAndBound();
3975#ifdef COIN_HAS_ASL
3976              double objectiveValue=model.getMinimizationObjValue();
3977              int iStat = model.status();
3978              int iStat2 = model.secondaryStatus();
3979#endif
3980#else
3981              // Way of using an existing piece of code
3982              OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
3983              ClpSimplex * lpSolver = clpSolver->getModelPtr();
3984              // set time from integer model
3985              double timeToGo = model.getMaximumSeconds();
3986              lpSolver->setMaximumSeconds(timeToGo);
3987              fakeMain(*lpSolver,*clpSolver,model);
3988#ifdef COIN_HAS_ASL
3989              // My actual usage has objective only in clpSolver
3990              double objectiveValue=clpSolver->getObjValue();
3991              int iStat = lpSolver->status();
3992              int iStat2 = lpSolver->secondaryStatus();
3993#endif
3994#endif
3995              // make sure solution back in correct place
3996              clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
3997              lpSolver = clpSolver->getModelPtr();
3998#ifdef COIN_HAS_ASL
3999              if (usingAmpl) {
4000                int n = clpSolver->getNumCols();
4001                double value = objectiveValue*lpSolver->getObjSense();
4002                char buf[300];
4003                int pos=0;
4004                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
4005                if (iStat==0) {
4006                  if (objectiveValue<1.0e40) {
4007                    pos += sprintf(buf+pos,"optimal," );
4008                  } else {
4009                    // infeasible
4010                    iStat=1;
4011                    pos += sprintf(buf+pos,"infeasible,");
4012                  }
4013                } else if (iStat==1) {
4014                  if (iStat2!=6)
4015                    iStat=3;
4016                  else
4017                    iStat=4;
4018                  pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
4019                } else if (iStat==2) {
4020                  iStat = 7;
4021                  pos += sprintf(buf+pos,"stopped on difficulties,");
4022                } else if (iStat==5) {
4023                  iStat = 3;
4024                  pos += sprintf(buf+pos,"stopped on ctrl-c,");
4025                } else {
4026                  pos += sprintf(buf+pos,"status unknown,");
4027                  iStat=6;
4028                }
4029                info.problemStatus=iStat;
4030                info.objValue = value;
4031                if (objectiveValue<1.0e40) 
4032                  pos += sprintf(buf+pos," objective %.*g",ampl_obj_prec(),
4033                                 value);
4034                sprintf(buf+pos,"\n%d nodes, %d iterations",
4035                        model.getNodeCount(),
4036                        model.getIterationCount());
4037                if (objectiveValue<1.0e50) {
4038                  free(info.primalSolution);
4039                  info.primalSolution = (double *) malloc(n*sizeof(double));
4040                  CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
4041                  int numberRows = lpSolver->numberRows();
4042                  free(info.dualSolution);
4043                  info.dualSolution = (double *) malloc(numberRows*sizeof(double));
4044                  CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
4045                } else {
4046                  info.primalSolution=NULL;
4047                  info.dualSolution=NULL;
4048                }
4049                // put buffer into info
4050                strcpy(info.buffer,buf);
4051              }
4052#endif
4053            }
4054            break;
4055          case HELP:
4056            std::cout<<"Coin Solver version "<<CBCVERSION
4057                     <<", build "<<__DATE__<<std::endl;
4058            std::cout<<"Non default values:-"<<std::endl;
4059            std::cout<<"Perturbation "<<lpSolver->perturbation()<<" (default 100)"
4060                     <<std::endl;
4061            CoinReadPrintit(
4062                    "Presolve being done with 5 passes\n\
4063Dual steepest edge steep/partial on matrix shape and factorization density\n\
4064Clpnnnn taken out of messages\n\
4065If Factorization frequency default then done on size of matrix\n\n\
4066(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
4067You can switch to interactive mode at any time so\n\
4068clp watson.mps -scaling off -primalsimplex\nis the same as\n\
4069clp watson.mps -\nscaling off\nprimalsimplex"
4070                    );
4071            break;
4072          case SOLUTION:
4073            if (goodModel) {
4074              // get next field
4075              field = CoinReadGetString(argc,argv);
4076              if (field=="$") {
4077                field = parameters[iParam].stringValue();
4078              } else if (field=="EOL") {
4079                parameters[iParam].printString();
4080                break;
4081              } else {
4082                parameters[iParam].setStringValue(field);
4083              }
4084              std::string fileName;
4085              FILE *fp=NULL;
4086              if (field=="-"||field=="EOL"||field=="stdout") {
4087                // stdout
4088                fp=stdout;
4089              } else if (field=="stderr") {
4090                // stderr
4091                fp=stderr;
4092              } else {
4093                if (field[0]=='/'||field[0]=='\\') {
4094                  fileName = field;
4095                } else if (field[0]=='~') {
4096                  char * environVar = getenv("HOME");
4097                  if (environVar) {
4098                    std::string home(environVar);
4099                    field=field.erase(0,1);
4100                    fileName = home+field;
4101                  } else {
4102                    fileName=field;
4103                  }
4104                } else {
4105                  fileName = directory+field;
4106                }
4107                fp=fopen(fileName.c_str(),"w");
4108              }
4109              if (fp) {
4110                // make fancy later on
4111                int iRow;
4112                int numberRows=lpSolver->numberRows();
4113                double * dualRowSolution = lpSolver->dualRowSolution();
4114                double * primalRowSolution = 
4115                  lpSolver->primalRowSolution();
4116                double * rowLower = lpSolver->rowLower();
4117                double * rowUpper = lpSolver->rowUpper();
4118                double primalTolerance = lpSolver->primalTolerance();
4119                char format[6];
4120                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
4121                bool doMask = (printMask!=""&&lengthName);
4122                int * maskStarts=NULL;
4123                int maxMasks=0;
4124                char ** masks =NULL;
4125                if (doMask) {
4126                  int nAst =0;
4127                  const char * pMask2 = printMask.c_str();
4128                  char pMask[100];
4129                  int iChar;
4130                  int lengthMask = strlen(pMask2);
4131                  assert (lengthMask<100);
4132                  if (*pMask2=='"') {
4133                    if (pMask2[lengthMask-1]!='"') {
4134                      printf("mismatched \" in mask %s\n",pMask2);
4135                      break;
4136                    } else {
4137                      strcpy(pMask,pMask2+1);
4138                      *strchr(pMask,'"')='\0';
4139                    }
4140                  } else if (*pMask2=='\'') {
4141                    if (pMask2[lengthMask-1]!='\'') {
4142                      printf("mismatched ' in mask %s\n",pMask2);
4143                      break;
4144                    } else {
4145                      strcpy(pMask,pMask2+1);
4146                      *strchr(pMask,'\'')='\0';
4147                    }
4148                  } else {
4149                    strcpy(pMask,pMask2);
4150                  }
4151                  if (lengthMask>lengthName) {
4152                    printf("mask %s too long - skipping\n",pMask);
4153                    break;
4154                  }
4155                  maxMasks = 1;
4156                  for (iChar=0;iChar<lengthMask;iChar++) {
4157                    if (pMask[iChar]=='*') {
4158                      nAst++;
4159                      maxMasks *= (lengthName+1);
4160                    }
4161                  }
4162                  int nEntries = 1;
4163                  maskStarts = new int[lengthName+2];
4164                  masks = new char * [maxMasks];
4165                  char ** newMasks = new char * [maxMasks];
4166                  int i;
4167                  for (i=0;i<maxMasks;i++) {
4168                    masks[i] = new char[lengthName+1];
4169                    newMasks[i] = new char[lengthName+1];
4170                  }
4171                  strcpy(masks[0],pMask);
4172                  for (int iAst=0;iAst<nAst;iAst++) {
4173                    int nOldEntries = nEntries;
4174                    nEntries=0;
4175                    for (int iEntry = 0;iEntry<nOldEntries;iEntry++) {
4176                      char * oldMask = masks[iEntry];
4177                      char * ast = strchr(oldMask,'*');
4178                      assert (ast);
4179                      int length = strlen(oldMask)-1;
4180                      int nBefore = ast-oldMask;
4181                      int nAfter = length-nBefore;
4182                      // and add null
4183                      nAfter++;
4184                      for (int i=0;i<=lengthName-length;i++) {
4185                        char * maskOut = newMasks[nEntries];
4186                        memcpy(maskOut,oldMask,nBefore);
4187                        for (int k=0;k<i;k++) 
4188                          maskOut[k+nBefore]='?';
4189                        memcpy(maskOut+nBefore+i,ast+1,nAfter);
4190                        nEntries++;
4191                        assert (nEntries<=maxMasks);
4192                      }
4193                    }
4194                    char ** temp = masks;
4195                    masks = newMasks;
4196                    newMasks = temp;
4197                  }
4198                  // Now extend and sort
4199                  int * sort = new int[nEntries];
4200                  for (i=0;i<nEntries;i++) {
4201                    char * maskThis = masks[i];
4202                    int length = strlen(maskThis);
4203                    while (maskThis[length-1]==' ')
4204                      length--;
4205                    maskThis[length]='\0';
4206                    sort[i]=length;
4207                  }
4208                  CoinSort_2(sort,sort+nEntries,masks);
4209                  int lastLength=-1;
4210                  for (i=0;i<nEntries;i++) {
4211                    int length = sort[i];
4212                    while (length>lastLength) 
4213                      maskStarts[++lastLength] = i;
4214                  }
4215                  maskStarts[++lastLength]=nEntries;
4216                  delete [] sort;
4217                  for (i=0;i<maxMasks;i++)
4218                    delete [] newMasks[i];
4219                  delete [] newMasks;
4220                }
4221                if (printMode>2) {
4222                  for (iRow=0;iRow<numberRows;iRow++) {
4223                    int type=printMode-3;
4224                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
4225                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
4226                      fprintf(fp,"** ");
4227                      type=2;
4228                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
4229                      type=1;
4230                    } else if (numberRows<50) {
4231                      type=3;
4232                    }
4233                    if (doMask&&!maskMatches(maskStarts,masks,rowNames[iRow]))
4234                      type =0;
4235                    if (type) {
4236                      fprintf(fp,"%7d ",iRow);
4237                      if (lengthName)
4238                        fprintf(fp,format,rowNames[iRow].c_str());
4239                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
4240                              dualRowSolution[iRow]);
4241                    }
4242                  }
4243                }
4244                int iColumn;
4245                int numberColumns=lpSolver->numberColumns();
4246                double * dualColumnSolution = 
4247                  lpSolver->dualColumnSolution();
4248                double * primalColumnSolution = 
4249                  lpSolver->primalColumnSolution();
4250                double * columnLower = lpSolver->columnLower();
4251                double * columnUpper = lpSolver->columnUpper();
4252                if (printMode!=2) {
4253                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
4254                    int type=(printMode>3) ? 1 :0;
4255                    if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
4256                        primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
4257                      fprintf(fp,"** ");
4258                      type=2;
4259                    } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
4260                      type=1;
4261                    } else if (numberColumns<50) {
4262                      type=3;
4263                    }
4264                    // see if integer
4265                    if ((!lpSolver->isInteger(iColumn)||fabs(primalColumnSolution[iColumn])<1.0e-8)
4266                         &&printMode==1)
4267                      type=0;
4268                    if (doMask&&!maskMatches(maskStarts,masks,
4269                                             columnNames[iColumn]))
4270                      type =0;
4271                    if (type) {
4272                      fprintf(fp,"%7d ",iColumn);
4273                      if (lengthName)
4274                        fprintf(fp,format,columnNames[iColumn].c_str());
4275                      fprintf(fp,"%15.8g        %15.8g\n",
4276                              primalColumnSolution[iColumn],
4277                              dualColumnSolution[iColumn]);
4278                    }
4279                  }
4280                } else {
4281                  // special format suitable for OsiRowCutDebugger
4282                  int n=0;
4283                  bool comma=false;
4284                  bool newLine=false;
4285                  fprintf(fp,"\tint intIndicesV[]={\n");
4286                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
4287                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
4288                      if (comma)
4289                        fprintf(fp,",");
4290                      if (newLine)
4291                        fprintf(fp,"\n");
4292                      fprintf(fp,"%d ",iColumn);
4293                      comma=true;
4294                      newLine=false;
4295                      n++;
4296                      if (n==10) {
4297                        n=0;
4298                        newLine=true;
4299                      }
4300                    }
4301                  }
4302                  fprintf(fp,"};\n");
4303                  n=0;
4304                  comma=false;
4305                  newLine=false;
4306                  fprintf(fp,"\tdouble intSolnV[]={\n");
4307                  for ( iColumn=0;iColumn<numberColumns;iColumn++) {
4308                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
4309                      if (comma)
4310                        fprintf(fp,",");
4311                      if (newLine)
4312                        fprintf(fp,"\n");
4313                      int value = (int) (primalColumnSolution[iColumn]+0.5);
4314                      fprintf(fp,"%d. ",value);
4315                      comma=true;
4316                      newLine=false;
4317                      n++;
4318                      if (n==10) {
4319                        n=0;
4320                        newLine=true;
4321                      }
4322                    }
4323                  }
4324                  fprintf(fp,"};\n");
4325                }
4326                if (fp!=stdout)
4327                  fclose(fp);
4328                if (masks) {
4329                  delete [] maskStarts;
4330                  for (int i=0;i<maxMasks;i++)
4331                    delete [] masks[i];
4332                  delete [] masks;
4333                }
4334              } else {
4335                std::cout<<"Unable to open file "<<fileName<<std::endl;
4336              }
4337            } else {
4338              std::cout<<"** Current model not valid"<<std::endl;
4339             
4340            }
4341            break;
4342          case SAVESOL:
4343            if (goodModel) {
4344              // get next field
4345              field = CoinReadGetString(argc,argv);
4346              if (field=="$") {
4347                field = parameters[iParam].stringValue();
4348              } else if (field=="EOL") {
4349                parameters[iParam].printString();
4350                break;
4351              } else {
4352                parameters[iParam].setStringValue(field);
4353              }
4354              std::string fileName;
4355              if (field[0]=='/'||field[0]=='\\') {
4356                fileName = field;
4357              } else if (field[0]=='~') {
4358                char * environVar = getenv("HOME");
4359                if (environVar) {
4360                  std::string home(environVar);
4361                  field=field.erase(0,1);
4362                  fileName = home+field;
4363                } else {
4364                  fileName=field;
4365                }
4366              } else {
4367                fileName = directory+field;
4368              }
4369              saveSolution(lpSolver,fileName);
4370            } else {
4371              std::cout<<"** Current model not valid"<<std::endl;
4372             
4373            }
4374            break;
4375          case DUMMY:
4376            break;
4377          default:
4378            abort();
4379          }
4380        } 
4381      } else if (!numberMatches) {
4382        std::cout<<"No match for "<<field<<" - ? for list of commands"
4383                 <<std::endl;
4384      } else if (numberMatches==1) {
4385        if (!numberQuery) {
4386          std::cout<<"Short match for "<<field<<" - completion: ";
4387          std::cout<<parameters[firstMatch].matchName()<<std::endl;
4388        } else if (numberQuery) {
4389          std::cout<<parameters[firstMatch].matchName()<<" : ";
4390          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
4391          if (numberQuery>=2) 
4392            parameters[firstMatch].printLongHelp();
4393        }
4394      } else {
4395        if (!numberQuery) 
4396          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
4397                   <<std::endl;
4398        else
4399          std::cout<<"Completions of "<<field<<":"<<std::endl;
4400        for ( iParam=0; iParam<numberParameters; iParam++ ) {
4401          int match = parameters[iParam].matches(field);
4402          if (match&&parameters[iParam].displayThis()) {
4403            std::cout<<parameters[iParam].matchName();
4404            if (numberQuery>=2) 
4405              std::cout<<" : "<<parameters[iParam].shortHelp();
4406            std::cout<<std::endl;
4407          }
4408        }
4409      }
4410    }
4411  }
4412  // By now all memory should be freed
4413#ifdef DMALLOC
4414  dmalloc_log_unfreed();
4415  dmalloc_shutdown();
4416#endif
4417  return 0;
4418}   
4419static void breakdown(const char * name, int numberLook, const double * region)
4420{
4421  double range[] = {
4422    -COIN_DBL_MAX,
4423    -1.0e15,-1.0e11,-1.0e8,-1.0e5,-1.0e4,-1.0e3,-1.0e2,-1.0e1,
4424    -1.0,
4425    -1.0e-1,-1.0e-2,-1.0e-3,-1.0e-4,-1.0e-5,-1.0e-8,-1.0e-11,-1.0e-15,
4426    0.0,
4427    1.0e-15,1.0e-11,1.0e-8,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,
4428    1.0,
4429    1.0e1,1.0e2,1.0e3,1.0e4,1.0e5,1.0e8,1.0e11,1.0e15,
4430    COIN_DBL_MAX};
4431  int nRanges = (int) (sizeof(range)/sizeof(double));
4432  int * number = new int[nRanges];
4433  memset(number,0,nRanges*sizeof(int));
4434  int * numberExact = new int[nRanges];
4435  memset(numberExact,0,nRanges*sizeof(int));
4436  int i;
4437  for ( i=0;i<numberLook;i++) {
4438    double value = region[i];
4439    for (int j=0;j<nRanges;j++) {
4440      if (value==range[j]) {
4441        numberExact[j]++;
4442        break;
4443      } else if (value<range[j]) {
4444        number[j]++;
4445        break;
4446      }
4447    }
4448  }
4449  printf("\n%s has %d entries\n",name,numberLook);
4450  for (i=0;i<nRanges;i++) {
4451    if (number[i]) 
4452      printf("%d between %g and %g",number[i],range[i-1],range[i]);
4453    if (numberExact[i]) {
4454      if (number[i])
4455        printf(", ");
4456      printf("%d exactly at %g",numberExact[i],range[i]);
4457    }
4458    if (number[i]+numberExact[i])
4459      printf("\n");
4460  }
4461  delete [] number;
4462  delete [] numberExact;
4463}
4464static void statistics(ClpSimplex * originalModel, ClpSimplex * model)
4465{
4466  int numberColumns = originalModel->numberColumns();
4467  const char * integerInformation  = originalModel->integerInformation(); 
4468  const double * columnLower = originalModel->columnLower();
4469  const double * columnUpper = originalModel->columnUpper();
4470  int numberIntegers=0;
4471  int numberBinary=0;
4472  int iRow,iColumn;
4473  if (integerInformation) {
4474    for (iColumn=0;iColumn<numberColumns;iColumn++) {
4475      if (integerInformation[iColumn]) {
4476        if (columnUpper[iColumn]>columnLower[iColumn]) {
4477          numberIntegers++;
4478          if (columnUpper[iColumn]==0.0&&columnLower[iColumn]==1) 
4479            numberBinary++;
4480        }
4481      }
4482    }
4483  }
4484  numberColumns = model->numberColumns();
4485  int numberRows = model->numberRows();
4486  columnLower = model->columnLower();
4487  columnUpper = model->columnUpper();
4488  const double * rowLower = model->rowLower();
4489  const double * rowUpper = model->rowUpper();
4490  const double * objective = model->objective();
4491  CoinPackedMatrix * matrix = model->matrix();
4492  CoinBigIndex numberElements = matrix->getNumElements();
4493  const int * columnLength = matrix->getVectorLengths();
4494  //const CoinBigIndex * columnStart = matrix->getVectorStarts();
4495  const double * elementByColumn = matrix->getElements();
4496  int * number = new int[numberRows+1];
4497  memset(number,0,(numberRows+1)*sizeof(int));
4498  int numberObjSingletons=0;
4499  /* cType
4500     0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up,
4501     8 0/1
4502  */ 
4503  int cType[9];
4504  std::string cName[]={"0.0->inf,","0.0->up,","lo->inf,","lo->up,","free,","fixed,","-inf->0.0,",
4505                       "-inf->up,","0.0->1.0"};
4506  int nObjective=0;
4507  memset(cType,0,sizeof(cType));
4508  for (iColumn=0;iColumn<numberColumns;iColumn++) {
4509    int length=columnLength[iColumn];
4510    if (length==1&&objective[iColumn])
4511      numberObjSingletons++;
4512    number[length]++;
4513    if (objective[iColumn])
4514      nObjective++;
4515    if (columnLower[iColumn]>-1.0e20) {
4516      if (columnLower[iColumn]==0.0) {
4517        if (columnUpper[iColumn]>1.0e20)
4518          cType[0]++;
4519        else if (columnUpper[iColumn]==1.0)
4520          cType[8]++;
4521        else if (columnUpper[iColumn]==0.0)
4522          cType[5]++;
4523        else
4524          cType[1]++;
4525      } else {
4526        if (columnUpper[iColumn]>1.0e20) 
4527          cType[2]++;
4528        else if (columnUpper[iColumn]==columnLower[iColumn])
4529          cType[5]++;
4530        else
4531          cType[3]++;
4532      }
4533    } else {
4534      if (columnUpper[iColumn]>1.0e20) 
4535        cType[4]++;
4536      else if (columnUpper[iColumn]==0.0) 
4537        cType[6]++;
4538      else
4539        cType[7]++;
4540    }
4541  }
4542  /* rType
4543     0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other,
4544     7 L 0,  8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free
4545  */ 
4546  int rType[13];
4547  std::string rName[]={"E 0.0,","E 1.0,","E -1.0,","E other,","G 0.0,","G 1.0,","G other,",
4548                       "L 0.0,","L 1.0,","L other,","Range 0.0->1.0,","Range other,","Free"};
4549  memset(rType,0,sizeof(rType));
4550  for (iRow=0;iRow<numberRows;iRow++) {
4551    if (rowLower[iRow]>-1.0e20) {
4552      if (rowLower[iRow]==0.0) {
4553        if (rowUpper[iRow]>1.0e20)
4554          rType[4]++;
4555        else if (rowUpper[iRow]==1.0)
4556          rType[10]++;
4557        else if (rowUpper[iRow]==0.0)
4558          rType[0]++;
4559        else
4560          rType[11]++;
4561      } else if (rowLower[iRow]==1.0) {
4562        if (rowUpper[iRow]>1.0e20) 
4563          rType[5]++;
4564        else if (rowUpper[iRow]==rowLower[iRow])
4565          rType[1]++;
4566        else
4567          rType[11]++;
4568      } else if (rowLower[iRow]==-1.0) {
4569        if (rowUpper[iRow]>1.0e20) 
4570          rType[6]++;
4571        else if (rowUpper[iRow]==rowLower[iRow])
4572          rType[2]++;
4573        else
4574          rType[11]++;
4575      } else {
4576        if (rowUpper[iRow]>1.0e20) 
4577          rType[6]++;
4578        else if (rowUpper[iRow]==rowLower[iRow])
4579          rType[3]++;
4580        else
4581          rType[11]++;
4582      }
4583    } else {
4584      if (rowUpper[iRow]>1.0e20) 
4585        rType[12]++;
4586      else if (rowUpper[iRow]==0.0) 
4587        rType[7]++;
4588      else if (rowUpper[iRow]==1.0) 
4589        rType[8]++;
4590      else
4591        rType[9]++;
4592    }
4593  }
4594  // Basic statistics
4595  printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n",
4596         numberRows,numberColumns,nObjective,numberElements);
4597  if (number[0]+number[1]) {
4598    printf("There are ");
4599    if (numberObjSingletons)
4600      printf("%d singletons with objective ",numberObjSingletons);
4601    int numberNoObj = number[1]-numberObjSingletons;
4602    if (numberNoObj)
4603      printf("%d singletons with no objective ",numberNoObj);
4604    if (number[0])
4605      printf("** %d columns have no entries",number[0]);
4606    printf("\n");
4607  }
4608  printf("Column breakdown:\n");
4609  int k;
4610  for (k=0;k<(int) (sizeof(cType)/sizeof(int));k++) {
4611    printf("%d of type %s ",cType[k],cName[k].c_str());
4612    if (((k+1)%3)==0)
4613      printf("\n");
4614  }
4615  if ((k%3)!=0)
4616    printf("\n");
4617  printf("Row breakdown:\n");
4618  for (k=0;k<(int) (sizeof(rType)/sizeof(int));k++) {
4619    printf("%d of type %s ",rType[k],rName[k].c_str());
4620    if (((k+1)%3)==0)
4621      printf("\n");
4622  }
4623  if ((k%3)!=0)
4624    printf("\n");
4625  if (model->logLevel()<2)
4626    return ;
4627  int kMax = model->logLevel()>3 ? 1000000 : 10;
4628  k=0;
4629  for (iRow=1;iRow<=numberRows;iRow++) {
4630    if (number[iRow]) {
4631      k++;
4632      printf("%d columns have %d entries\n",number[iRow],iRow);
4633      if (k==kMax)
4634        break;
4635    }
4636  }
4637  if (k<numberRows) {
4638    int kk=k;
4639    k=0;
4640    for (iRow=numberRows;iRow>=1;iRow--) {
4641      if (number[iRow]) {
4642        k++;
4643        if (k==kMax)
4644          break;
4645      }
4646    }
4647    if (k>kk) {
4648      printf("\n    .........\n\n");
4649      iRow=k;
4650      k=0;
4651      for (;iRow<numberRows;iRow++) {
4652        if (number[iRow]) {
4653          k++;
4654          printf("%d columns have %d entries\n",number[iRow],iRow);
4655          if (k==kMax)
4656            break;
4657        }
4658      }
4659    }
4660  }
4661  delete [] number;
4662  printf("\n\n");
4663  // get row copy
4664  CoinPackedMatrix rowCopy = *matrix;
4665  rowCopy.reverseOrdering();
4666  //const int * column = rowCopy.getIndices();
4667  const int * rowLength = rowCopy.getVectorLengths();
4668  //const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
4669  //const double * element = rowCopy.getElements();
4670  number = new int[numberColumns+1];
4671  memset(number,0,(numberColumns+1)*sizeof(int));
4672  for (iRow=0;iRow<numberRows;iRow++) {
4673    int length=rowLength[iRow];
4674    number[length]++;
4675  }
4676  if (number[0])
4677    printf("** %d rows have no entries\n",number[0]);
4678  k=0;
4679  for (iColumn=1;iColumn<=numberColumns;iColumn++) {
4680    if (number[iColumn]) {
4681      k++;
4682      printf("%d rows have %d entries\n",number[iColumn],iColumn);
4683      if (k==kMax)
4684        break;
4685    }
4686  }
4687  if (k<numberColumns) {
4688    int kk=k;
4689    k=0;
4690    for (iColumn=numberColumns;iColumn>=1;iColumn--) {
4691      if (number[iColumn]) {
4692        k++;
4693        if (k==kMax)
4694          break;
4695      }
4696    }
4697    if (k>kk) {
4698      printf("\n    .........\n\n");
4699      iColumn=k;
4700      k=0;
4701      for (;iColumn<numberColumns;iColumn++) {
4702        if (number[iColumn]) {
4703          k++;
4704          printf("%d rows have %d entries\n",number[iColumn],iColumn);
4705          if (k==kMax)
4706            break;
4707        }
4708      }
4709    }
4710  }
4711  delete [] number;
4712  // Now do breakdown of ranges
4713  breakdown("Elements",numberElements,elementByColumn);
4714  breakdown("RowLower",numberRows,rowLower);
4715  breakdown("RowUpper",numberRows,rowUpper);
4716  breakdown("ColumnLower",numberColumns,columnLower);
4717  breakdown("ColumnUpper",numberColumns,columnUpper);
4718  breakdown("Objective",numberColumns,objective);
4719}
4720static bool maskMatches(const int * starts, char ** masks,
4721                        std::string & check)
4722{
4723  // back to char as I am old fashioned
4724  const char * checkC = check.c_str();
4725  int length = strlen(checkC);
4726  while (checkC[length-1]==' ')
4727    length--;
4728  for (int i=starts[length];i<starts[length+1];i++) {
4729    char * thisMask = masks[i];
4730    int k;
4731    for ( k=0;k<length;k++) {
4732      if (thisMask[k]!='?'&&thisMask[k]!=checkC[k]) 
4733        break;
4734    }
4735    if (k==length)
4736      return true;
4737  }
4738  return false;
4739}
4740static void clean(char * temp)
4741{
4742  char * put = temp;
4743  while (*put>=' ')
4744    put++;
4745  *put='\0';
4746}
4747static void generateCode(CbcModel * model, const char * fileName,int type,int preProcess)
4748{
4749  // options on code generation
4750  bool sizecode = (type&4)!=0;
4751  type &= 3;
4752  FILE * fp = fopen(fileName,"r");
4753  assert (fp);
4754  int numberLines=0;
4755#define MAXLINES 5000
4756#define MAXONELINE 200
4757  char line[MAXLINES][MAXONELINE];
4758  strcpy(line[numberLines++],"0#if defined(_MSC_VER)");
4759  strcpy(line[numberLines++],"0// Turn off compiler warning about long names");
4760  strcpy(line[numberLines++],"0#  pragma warning(disable:4786)");
4761  strcpy(line[numberLines++],"0#endif\n");
4762  strcpy(line[numberLines++],"0#include <cassert>");
4763  strcpy(line[numberLines++],"0#include <iomanip>");
4764  strcpy(line[numberLines++],"0#include \"OsiClpSolverInterface.hpp\"");
4765  strcpy(line[numberLines++],"0#include \"CbcModel.hpp\"");
4766  strcpy(line[numberLines++],"0#include \"CbcCutGenerator.hpp\"");
4767  strcpy(line[numberLines++],"0#include \"CbcStrategy.hpp\"");
4768  strcpy(line[numberLines++],"0#include \"CglPreProcess.hpp\"");
4769  strcpy(line[numberLines++],"0#include \"CoinTime.hpp\"");
4770  if (preProcess>0) 
4771    strcpy(line[numberLines++],"0#include \"CglProbing.hpp\""); // possibly redundant
4772  // To allow generated 5's to be just before branchAndBound - do rest here
4773  strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4774  strcpy(line[numberLines++],"5  if (clpModel->tightenPrimalBounds()!=0) {");
4775  strcpy(line[numberLines++],"5    std::cout<<\"Problem is infeasible - tightenPrimalBounds!\"<<std::endl;");
4776  strcpy(line[numberLines++],"5    exit(1);");
4777  strcpy(line[numberLines++],"5  }");
4778  strcpy(line[numberLines++],"5  clpModel->dual();  // clean up");
4779  if (sizecode) {
4780    // override some settings
4781    strcpy(line[numberLines++],"5  // compute some things using problem size");
4782    strcpy(line[numberLines++],"5  cbcModel->setMinimumDrop(min(5.0e-2,");
4783    strcpy(line[numberLines++],"5       fabs(cbcModel->getMinimizationObjValue())*1.0e-3+1.0e-4));");
4784    strcpy(line[numberLines++],"5  if (cbcModel->getNumCols()<500)");
4785    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible");
4786    strcpy(line[numberLines++],"5  else if (cbcModel->getNumCols()<5000)");
4787    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(100); // use minimum drop");
4788    strcpy(line[numberLines++],"5  else");
4789    strcpy(line[numberLines++],"5    cbcModel->setMaximumCutPassesAtRoot(20);");
4790    strcpy(line[numberLines++],"5  cbcModel->setMaximumCutPasses(1);");
4791  }
4792  if (preProcess<=0) {
4793    // no preprocessing or strategy
4794    if (preProcess) {
4795      strcpy(line[numberLines++],"5  // Preprocessing using CbcStrategy");
4796      strcpy(line[numberLines++],"5  CbcStrategyDefault strategy(true,5,5);");
4797      strcpy(line[numberLines++],"5  strategy.setupPreProcessing(1);");
4798      strcpy(line[numberLines++],"5  cbcModel->setStrategy(strategy);");
4799    }
4800  } else {
4801    int translate[]={9999,0,0,-1,2,3,-2};
4802    strcpy(line[numberLines++],"5  // Hand coded preprocessing");
4803    strcpy(line[numberLines++],"5  CglPreProcess process;");
4804    strcpy(line[numberLines++],"5  OsiSolverInterface * saveSolver=cbcModel->solver()->clone();");
4805    strcpy(line[numberLines++],"5  // Tell solver we are in Branch and Cut");
4806    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;");
4807    strcpy(line[numberLines++],"5  // Default set of cut generators");
4808    strcpy(line[numberLines++],"5  CglProbing generator1;");
4809    strcpy(line[numberLines++],"5  generator1.setUsingObjective(true);");
4810    strcpy(line[numberLines++],"5  generator1.setMaxPass(3);");
4811    strcpy(line[numberLines++],"5  generator1.setMaxProbeRoot(saveSolver->getNumCols());");
4812    strcpy(line[numberLines++],"5  generator1.setMaxElements(100);");
4813    strcpy(line[numberLines++],"5  generator1.setMaxLookRoot(50);");
4814    strcpy(line[numberLines++],"5  generator1.setRowCuts(3);");
4815    strcpy(line[numberLines++],"5  // Add in generators");
4816    strcpy(line[numberLines++],"5  process.addCutGenerator(&generator1);");
4817    strcpy(line[numberLines++],"5  process.messageHandler()->setLogLevel(cbcModel->logLevel());");
4818    strcpy(line[numberLines++],"5  OsiSolverInterface * solver2 = ");
4819    sprintf(line[numberLines++],"5    process.preProcessNonDefault(*saveSolver,%d,10);",translate[preProcess]);
4820    strcpy(line[numberLines++],"5  // Tell solver we are not in Branch and Cut");
4821    strcpy(line[numberLines++],"5  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4822    strcpy(line[numberLines++],"5  if (solver2)");
4823    strcpy(line[numberLines++],"5    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;");
4824    strcpy(line[numberLines++],"5  if (!solver2) {");
4825    strcpy(line[numberLines++],"5    std::cout<<\"Pre-processing says infeasible!\"<<std::endl;");
4826    strcpy(line[numberLines++],"5    exit(1);");
4827    strcpy(line[numberLines++],"5  } else {");
4828    strcpy(line[numberLines++],"5    std::cout<<\"processed model has \"<<solver2->getNumRows()");
4829    strcpy(line[numberLines++],"5            <<\" rows, \"<<solver2->getNumCols()");
4830    strcpy(line[numberLines++],"5            <<\" columns and \"<<solver2->getNumElements()");
4831    strcpy(line[numberLines++],"5            <<\" elements\"<<solver2->getNumElements()<<std::endl;");
4832    strcpy(line[numberLines++],"5  }");
4833    strcpy(line[numberLines++],"5  // we have to keep solver2 so pass clone");
4834    strcpy(line[numberLines++],"5  solver2 = solver2->clone();");
4835    strcpy(line[numberLines++],"5  cbcModel->assignSolver(solver2);");
4836    strcpy(line[numberLines++],"5  cbcModel->initialSolve();");
4837  }
4838  while (fgets(line[numberLines],MAXONELINE,fp)) {
4839    assert (numberLines<MAXLINES);
4840    clean(line[numberLines]);
4841    numberLines++;
4842  }
4843  fclose(fp);
4844  strcpy(line[numberLines++],"0\nint main (int argc, const char *argv[])\n{");
4845  strcpy(line[numberLines++],"0  OsiClpSolverInterface solver1;");
4846  strcpy(line[numberLines++],"0  int status=1;");
4847  strcpy(line[numberLines++],"0  if (argc<2)");
4848  strcpy(line[numberLines++],"0    std::cout<<\"Please give file name\"<<std::endl;");
4849  strcpy(line[numberLines++],"0  else");
4850  strcpy(line[numberLines++],"0    status=solver1.readMps(argv[1],\"\");");
4851  strcpy(line[numberLines++],"0  if (status) {");
4852  strcpy(line[numberLines++],"0    std::cout<<\"Bad readMps \"<<argv[1]<<std::endl;");
4853  strcpy(line[numberLines++],"0    exit(1);");
4854  strcpy(line[numberLines++],"0  }\n");
4855  strcpy(line[numberLines++],"0  double time1 = CoinCpuTime();");
4856  strcpy(line[numberLines++],"0  CbcModel model(solver1);");
4857  strcpy(line[numberLines++],"0  // Now do requested saves and modifications");
4858  strcpy(line[numberLines++],"0  CbcModel * cbcModel = & model;");
4859  strcpy(line[numberLines++],"0  OsiSolverInterface * osiModel = model.solver();");
4860  strcpy(line[numberLines++],"0  OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);");
4861  strcpy(line[numberLines++],"0  ClpSimplex * clpModel = osiclpModel->getModelPtr();");
4862  // add in comments about messages
4863  strcpy(line[numberLines++],"3  // You can save some time by switching off message building");
4864  strcpy(line[numberLines++],"3  // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);");
4865  // add in actual solve
4866  strcpy(line[numberLines++],"5  cbcModel->branchAndBound();");
4867  strcpy(line[numberLines++],"8  std::cout<<argv[1]<<\" took \"<<CoinCpuTime()-time1<<\" seconds, \"");
4868  strcpy(line[numberLines++],"8    <<cbcModel->getNodeCount()<<\" nodes with objective \"");
4869  strcpy(line[numberLines++],"8    <<cbcModel->getObjValue()");
4870  strcpy(line[numberLines++],"8    <<(!cbcModel->status() ? \" Finished\" : \" Not finished\")");
4871  strcpy(line[numberLines++],"8    <<std::endl;");
4872  strcpy(line[numberLines++],"5  // For best solution");
4873  strcpy(line[numberLines++],"5  int numberColumns = solver1.getNumCols();");
4874  strcpy(line[numberLines++],"5  if (cbcModel->getMinimizationObjValue()<1.0e50) {");
4875  if (preProcess>0) {
4876    strcpy(line[numberLines++],"5    // post process");
4877    strcpy(line[numberLines++],"5    process.postProcess(*cbcModel->solver());");
4878    strcpy(line[numberLines++],"5    // Solution now back in saveSolver");
4879    strcpy(line[numberLines++],"5    cbcModel->assignSolver(saveSolver);");
4880    strcpy(line[numberLines++],"5    memcpy(cbcModel->bestSolution(),cbcModel->solver()->getColSolution(),");
4881    strcpy(line[numberLines++],"5          numberColumns*sizeof(double));");
4882  }
4883  strcpy(line[numberLines++],"5    // put back in original solver");
4884  strcpy(line[numberLines++],"5    solver1.setColSolution(cbcModel->bestSolution());");
4885  strcpy(line[numberLines++],"5    const double * solution = solver1.getColSolution();");
4886  strcpy(line[numberLines++],"8  \n  // Now you would use solution etc etc\n");
4887  strcpy(line[numberLines++],"5");
4888  strcpy(line[numberLines++],"5    // Get names from solver1 (as OsiSolverInterface may lose)");
4889  strcpy(line[numberLines++],"5    std::vector<std::string> columnNames = *solver1.getModelPtr()->columnNames();");
4890  strcpy(line[numberLines++],"5    ");
4891  strcpy(line[numberLines++],"5    int iColumn;");
4892  strcpy(line[numberLines++],"5    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);");
4893  strcpy(line[numberLines++],"5    ");
4894  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4895  strcpy(line[numberLines++],"5    for (iColumn=0;iColumn<numberColumns;iColumn++) {");
4896  strcpy(line[numberLines++],"5      double value=solution[iColumn];");
4897  strcpy(line[numberLines++],"5      if (fabs(value)>1.0e-7&&solver1.isInteger(iColumn)) ");
4898  strcpy(line[numberLines++],"5 std::cout<<std::setw(6)<<iColumn<<\" \"");
4899  strcpy(line[numberLines++],"5                 <<columnNames[iColumn]<<\" \"");
4900  strcpy(line[numberLines++],"5                 <<value<<std::endl;");
4901  strcpy(line[numberLines++],"5    }");
4902  strcpy(line[numberLines++],"5    std::cout<<\"--------------------------------------\"<<std::endl;");
4903  strcpy(line[numberLines++],"5  ");
4904  strcpy(line[numberLines++],"5    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);");
4905  strcpy(line[numberLines++],"5  }");
4906  strcpy(line[numberLines++],"8  return 0;\n}");
4907  fp = fopen(fileName,"w");
4908  assert (fp);
4909
4910  int wanted[9];
4911  memset(wanted,0,sizeof(wanted));
4912  wanted[0]=wanted[3]=wanted[5]=wanted[8]=1;
4913  if (type>0) 
4914    wanted[1]=wanted[6]=1;
4915  if (type>1) 
4916    wanted[2]=wanted[4]=wanted[7]=1;
4917  std::string header[9]=
4918  { "","Save values","Redundant save of default values","Set changed values",
4919    "Redundant set default values","Solve","Restore values","Redundant restore values","Finish up"};
4920  for (int iType=0;iType<9;iType++) {
4921    if (!wanted[iType])
4922      continue;
4923    int n=0;
4924    int iLine;
4925    for (iLine=0;iLine<numberLines;iLine++) {
4926      if (line[iLine][0]=='0'+iType) {
4927        if (!n&&header[iType]!="")
4928          fprintf(fp,"\n  // %s\n\n",header[iType].c_str());
4929        n++;
4930        // skip save and clp as cloned
4931        if (!strstr(line[iLine],"save")||(!strstr(line[iLine],"clpMo")&&
4932                                          !strstr(line[iLine],"_Osi")))
4933          fprintf(fp,"%s\n",line[iLine]+1);
4934      }
4935    }
4936  }
4937  fclose(fp);
4938  printf("C++ file written to %s\n",fileName);
4939}
4940/*
4941  Version 1.00.00 November 16 2005.
4942  This is to stop me (JJF) messing about too much.
4943  Tuning changes should be noted here.
4944  The testing next version may be activated by CBC_NEXT_VERSION
4945  This applies to OsiClp, Clp etc
4946  Version 1.00.01 November 24 2005
4947  Added several classes for advanced users.  This can't affect code (if you don't use it)
4948  Made some tiny changes (for N way branching) which should not change anything.
4949  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
4950  CbcBranchAllDifferent object class - for branching on general integer variables
4951  to stop them having same value so branches are x >= y+1 and x <= y-1.
4952  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
4953  and CglStored which just has a list of cuts which can be activated.
4954  Modified preprocess option to SOS
4955  Version 1.00.02 December 9 2005
4956  Added use of CbcStrategy to do clean preprocessing
4957  Added use of referenceSolver for cleaner repetition of Cbc
4958  Version 1.01.00 February 2 2006
4959  Added first try at Ampl interface
4960*/
Note: See TracBrowser for help on using the repository browser.