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

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

out memory printing

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