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

Last change on this file since 523 was 523, checked in by forrest, 12 years ago

nonlinear stuff

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