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

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

correct row solution

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 214.3 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                  if (doSprint>0) {
2695                    // Sprint for primal solves
2696                    ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
2697                    ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
2698                    int numberPasses = 5;
2699                    int options[] = {0,3,0,0,0,0};
2700                    int extraInfo[] = {-1,20,-1,-1,-1,-1};
2701                    extraInfo[1]=doSprint;
2702                    int independentOptions[] = {0,0,3};
2703                    ClpSolve clpSolve(method,presolveType,numberPasses,
2704                                      options,extraInfo,independentOptions);
2705                    // say use in OsiClp
2706                    clpSolve.setSpecialOption(6,1);
2707                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
2708                    osiclp->setSolveOptions(clpSolve);
2709                    osiclp->setHintParam(OsiDoDualInResolve,false);
2710                    // switch off row copy
2711                    osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions()|256);
2712                    osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
2713                  }
2714                  solver2 = process.preProcessNonDefault(*saveSolver,translate[preProcess],numberPasses,
2715                                                         tunePreProcess);
2716                  // Tell solver we are not in Branch and Cut
2717                  saveSolver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
2718                  if (solver2)
2719                    solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
2720                }
2721#ifdef COIN_HAS_ASL
2722                if (!solver2&&usingAmpl) {
2723                  // infeasible
2724                  info.problemStatus=1;
2725                  info.objValue = 1.0e100;
2726                  sprintf(info.buffer,"infeasible/unbounded by pre-processing");
2727                  info.primalSolution=NULL;
2728                  info.dualSolution=NULL;
2729                  break;
2730                }
2731#endif
2732                if (!noPrinting) {
2733                  if (!solver2) {
2734                    printf("Pre-processing says infeasible or unbounded\n");
2735                    break;
2736                  } else {
2737                    printf("processed model has %d rows, %d columns and %d elements\n",
2738                           solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
2739                  }
2740                }
2741                //solver2->resolve();
2742                if (preProcess==2) {
2743                  OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
2744                  ClpSimplex * lpSolver = clpSolver2->getModelPtr();
2745                  lpSolver->writeMps("presolved.mps",0,1,lpSolver->optimizationDirection());
2746                  printf("Preprocessed model (minimization) on presolved.mps\n");
2747                }
2748                // we have to keep solver2 so pass clone
2749                solver2 = solver2->clone();
2750                babModel->assignSolver(solver2);
2751                babModel->initialSolve();
2752                babModel->setMaximumSeconds(timeLeft-(CoinCpuTime()-time1));
2753              }
2754              // now tighten bounds
2755              if (!miplib) {
2756                OsiClpSolverInterface * si =
2757                  dynamic_cast<OsiClpSolverInterface *>(babModel->solver()) ;
2758                assert (si != NULL);
2759                // get clp itself
2760                ClpSimplex * modelC = si->getModelPtr();
2761                if (noPrinting)
2762                  modelC->setLogLevel(0);
2763                if (!complicatedInteger&&modelC->tightenPrimalBounds()!=0) {
2764                  std::cout<<"Problem is infeasible!"<<std::endl;
2765                  break;
2766                }
2767                modelC->dual();
2768              }
2769#if 0
2770              numberDebugValues=599;
2771              debugValues = new double[numberDebugValues];
2772              CoinZeroN(debugValues,numberDebugValues);
2773              debugValues[3]=1.0;
2774              debugValues[6]=25.0;
2775              debugValues[9]=4.0;
2776              debugValues[26]=4.0;
2777              debugValues[27]=6.0;
2778              debugValues[35]=8.0;
2779              debugValues[53]=21.0;
2780              debugValues[56]=4.0;
2781#endif
2782              if (debugValues) {
2783                // for debug
2784                std::string problemName ;
2785                babModel->solver()->getStrParam(OsiProbName,problemName) ;
2786                babModel->solver()->activateRowCutDebugger(problemName.c_str()) ;
2787                twomirGen.probname_=strdup(problemName.c_str());
2788                // checking seems odd
2789                //redsplitGen.set_given_optsol(babModel->solver()->getRowCutDebuggerAlways()->optimalSolution(),
2790                //                         babModel->getNumCols());
2791              }
2792              int testOsiOptions = parameters[whichParam(TESTOSI,numberParameters,parameters)].intValue();
2793#ifdef COIN_HAS_LINK
2794              // If linked then see if expansion wanted
2795              {
2796                OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel->solver());
2797                if (solver3) {
2798                  int options = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue()/10000;
2799                  if (options) {
2800                    /*
2801                      1 - force mini branch and bound
2802                      2 - set priorities high on continuous
2803                      4 - try adding OA cuts
2804                      8 - try doing quadratic linearization
2805                      16 - try expanding knapsacks
2806                    */
2807                    if ((options&16)) {
2808                      int numberColumns = saveCoinModel.numberColumns();
2809                      int numberRows = saveCoinModel.numberRows();
2810                      whichColumn = new int[numberColumns];
2811                      knapsackStart=new int[numberRows+1];
2812                      knapsackRow=new int[numberRows];
2813                      numberKnapsack=10000;
2814                      int extra1 = parameters[whichParam(EXTRA1,numberParameters,parameters)].intValue();
2815                      int extra2 = parameters[whichParam(EXTRA2,numberParameters,parameters)].intValue();
2816                      int logLevel = parameters[log].intValue();
2817                      OsiSolverInterface * solver = expandKnapsack(saveCoinModel,whichColumn,knapsackStart,
2818                                                                   knapsackRow,numberKnapsack,
2819                                                                   storedAmpl,logLevel,extra1,extra2);
2820                      if (solver) {
2821                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
2822                        assert (clpSolver);
2823                        lpSolver = clpSolver->getModelPtr();
2824                        babModel->assignSolver(solver);
2825                        testOsiOptions=0;
2826                        // Priorities already done
2827                        free(info.priorities);
2828                        info.priorities=NULL;
2829                      } else {
2830                        numberKnapsack=0;
2831                        delete [] whichColumn;
2832                        delete [] knapsackStart;
2833                        delete [] knapsackRow;
2834                        whichColumn=NULL;
2835                        knapsackStart=NULL;
2836                        knapsackRow=NULL;
2837                      }
2838                    }
2839                  }
2840                }
2841              }
2842#endif
2843              if (useCosts&&testOsiOptions<0) {
2844                int numberColumns = babModel->getNumCols();
2845                int * sort = new int[numberColumns];
2846                double * dsort = new double[numberColumns];
2847                int * priority = new int [numberColumns];
2848                const double * objective = babModel->getObjCoefficients();
2849                const double * lower = babModel->getColLower() ;
2850                const double * upper = babModel->getColUpper() ;
2851                const CoinPackedMatrix * matrix = babModel->solver()->getMatrixByCol();
2852                const int * columnLength = matrix->getVectorLengths();
2853                int iColumn;
2854                int n=0;
2855                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2856                  if (babModel->isInteger(iColumn)) {
2857                    sort[n]=n;
2858                    if (useCosts==1)
2859                      dsort[n++]=-fabs(objective[iColumn]);
2860                    else if (useCosts==2)
2861                      dsort[n++]=iColumn;
2862                    else if (useCosts==3)
2863                      dsort[n++]=upper[iColumn]-lower[iColumn];
2864                    else if (useCosts==4)
2865                      dsort[n++]=-(upper[iColumn]-lower[iColumn]);
2866                    else if (useCosts==5)
2867                      dsort[n++]=-columnLength[iColumn];
2868                  }
2869                }
2870                CoinSort_2(dsort,dsort+n,sort);
2871                int level=0;
2872                double last = -1.0e100;
2873                for (int i=0;i<n;i++) {
2874                  int iPut=sort[i];
2875                  if (dsort[i]!=last) {
2876                    level++;
2877                    last=dsort[i];
2878                  }
2879                  priority[iPut]=level;
2880                }
2881                babModel->passInPriorities( priority,false);
2882                delete [] priority;
2883                delete [] sort;
2884                delete [] dsort;
2885              }
2886              // FPump done first as it only works if no solution
2887              CbcHeuristicFPump heuristic4(*babModel);
2888              if (useFpump) {
2889                heuristic4.setMaximumPasses(parameters[whichParam(FPUMPITS,numberParameters,parameters)].intValue());
2890                int pumpTune=parameters[whichParam(FPUMPTUNE,numberParameters,parameters)].intValue();
2891                if (pumpTune>0) {
2892                  /*
2893                    >=10000000 for using obj
2894                    >=1000000 use as accumulate switch
2895                    >=1000 use index+1 as number of large loops
2896                    >=100 use 0.05 objvalue as increment
2897                    >=10 use +0.1 objvalue for cutoff (add)
2898                    1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
2899                    4 and static continuous, 5 as 3 but no internal integers
2900                    6 as 3 but all slack basis!
2901                  */
2902                  double value = babModel->solver()->getObjSense()*babModel->solver()->getObjValue();
2903                  int w = pumpTune/10;
2904                  int c = w % 10;
2905                  w /= 10;
2906                  int i = w % 10;
2907                  w /= 10;
2908                  int r = w;
2909                  int accumulate = r/1000;
2910                  r -= 1000*accumulate;
2911                  if (accumulate>=10) {
2912                    int which = accumulate/10;
2913                    accumulate -= 10*which;
2914                    which--;
2915                    // weights and factors
2916                    double weight[]={0.1,0.1,0.5,0.5,1.0,1.0,5.0,5.0};
2917                    double factor[] = {0.1,0.5,0.1,0.5,0.1,0.5,0.1,0.5};
2918                    heuristic4.setInitialWeight(weight[which]);
2919                    heuristic4.setWeightFactor(factor[which]);
2920                  }
2921                  // fake cutoff
2922                  printf("Setting ");
2923                  if (c) {
2924                    double cutoff;
2925                    babModel->solver()->getDblParam(OsiDualObjectiveLimit,cutoff);
2926                    cutoff = CoinMin(cutoff,value + 0.1*fabs(value)*c);
2927                    heuristic4.setFakeCutoff(cutoff);
2928                    printf("fake cutoff of %g ",cutoff);
2929                  }
2930                  if (i||r) {
2931                    // also set increment
2932                    heuristic4.setAbsoluteIncrement((0.01*i+0.005)*(fabs(value)+1.0e-12));
2933                    heuristic4.setAccumulate(accumulate);
2934                    heuristic4.setMaximumRetries(r+1);
2935                    if (i)
2936                      printf("increment of %g ",heuristic4.absoluteIncrement());
2937                    if (accumulate)
2938                      printf("accumulate of %d ",accumulate);
2939                    printf("%d retries ",r+2);
2940                  }
2941                  pumpTune = pumpTune%100;
2942                  printf("and setting when to %d\n",pumpTune+10);
2943                  if (pumpTune==6)
2944                    pumpTune =13;
2945                  heuristic4.setWhen(pumpTune+10);
2946                }
2947                babModel->addHeuristic(&heuristic4);
2948              }
2949              if (!miplib) {
2950                CbcRounding heuristic1(*babModel);
2951                if (useRounding)
2952                  babModel->addHeuristic(&heuristic1) ;
2953                CbcHeuristicLocal heuristic2(*babModel);
2954                heuristic2.setSearchType(1);
2955                if (useCombine)
2956                  babModel->addHeuristic(&heuristic2);
2957                CbcHeuristicGreedyCover heuristic3(*babModel);
2958                CbcHeuristicGreedyEquality heuristic3a(*babModel);
2959                if (useGreedy) {
2960                  babModel->addHeuristic(&heuristic3);
2961                  babModel->addHeuristic(&heuristic3a);
2962                }
2963                if (useLocalTree) {
2964                  CbcTreeLocal localTree(babModel,NULL,10,0,0,10000,2000);
2965                  babModel->passInTreeHandler(localTree);
2966                }
2967              }
2968              CbcHeuristicRINS heuristic5(*babModel);
2969              if (useRINS)
2970                babModel->addHeuristic(&heuristic5) ;
2971              if (type==MIPLIB) {
2972                if (babModel->numberStrong()==5&&babModel->numberBeforeTrust()==5) 
2973                  babModel->setNumberBeforeTrust(50);
2974              }
2975              // add cut generators if wanted
2976              int switches[20];
2977              int numberGenerators=0;
2978              int translate[]={-100,-1,-99,-98,1,1,1,1};
2979              if (probingAction) {
2980                if (probingAction==5||probingAction==7)
2981                  probingGen.setRowCuts(-3); // strengthening etc just at root
2982                if (probingAction==6||probingAction==7) {
2983                  // Number of unsatisfied variables to look at
2984                  probingGen.setMaxProbe(1000);
2985                  probingGen.setMaxProbeRoot(1000);
2986                  // How far to follow the consequences
2987                  probingGen.setMaxLook(50);
2988                  probingGen.setMaxLookRoot(50);
2989                }
2990                babModel->addCutGenerator(&probingGen,translate[probingAction],"Probing");
2991                switches[numberGenerators++]=0;
2992              }
2993              if (gomoryAction&&(!complicatedInteger||gomoryAction==1)) {
2994                babModel->addCutGenerator(&gomoryGen,translate[gomoryAction],"Gomory");
2995                switches[numberGenerators++]=-1;
2996              }
2997              if (knapsackAction) {
2998                babModel->addCutGenerator(&knapsackGen,translate[knapsackAction],"Knapsack");
2999                switches[numberGenerators++]=0;
3000              }
3001              if (redsplitAction&&!complicatedInteger) {
3002                babModel->addCutGenerator(&redsplitGen,translate[redsplitAction],"Reduce-and-split");
3003                switches[numberGenerators++]=1;
3004              }
3005              if (cliqueAction) {
3006                babModel->addCutGenerator(&cliqueGen,translate[cliqueAction],"Clique");
3007                switches[numberGenerators++]=0;
3008              }
3009              if (mixedAction) {
3010                babModel->addCutGenerator(&mixedGen,translate[mixedAction],"MixedIntegerRounding2");
3011                switches[numberGenerators++]=-1;
3012              }
3013              if (flowAction) {
3014                babModel->addCutGenerator(&flowGen,translate[flowAction],"FlowCover");
3015                switches[numberGenerators++]=1;
3016              }
3017              if (twomirAction&&!complicatedInteger) {
3018                babModel->addCutGenerator(&twomirGen,translate[twomirAction],"TwoMirCuts");
3019                switches[numberGenerators++]=1;
3020              }
3021              if (landpAction) {
3022                babModel->addCutGenerator(&landpGen,translate[landpAction],"LiftAndProject");
3023                switches[numberGenerators++]=1;
3024              }
3025              if (storedCuts) 
3026                babModel->setSpecialOptions(babModel->specialOptions()|64);
3027              // Say we want timings
3028              numberGenerators = babModel->numberCutGenerators();
3029              int iGenerator;
3030              int cutDepth=
3031                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
3032              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
3033                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
3034                int howOften = generator->howOften();
3035                if (howOften==-98||howOften==-99) 
3036                  generator->setSwitchOffIfLessThan(switches[iGenerator]);
3037                generator->setTiming(true);
3038                if (cutDepth>=0)
3039                  generator->setWhatDepth(cutDepth) ;
3040              }
3041              // Could tune more
3042              if (!miplib) {
3043                babModel->setMinimumDrop(min(5.0e-2,
3044                                             fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
3045                if (cutPass==-1234567) {
3046                  if (babModel->getNumCols()<500)
3047                    babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
3048                  else if (babModel->getNumCols()<5000)
3049                    babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
3050                  else
3051                    babModel->setMaximumCutPassesAtRoot(20);
3052                } else {
3053                  babModel->setMaximumCutPassesAtRoot(cutPass);
3054                }
3055                babModel->setMaximumCutPasses(1);
3056              }
3057              // Do more strong branching if small
3058              //if (babModel->getNumCols()<5000)
3059              //babModel->setNumberStrong(20);
3060              // Switch off strong branching if wanted
3061              //if (babModel->getNumCols()>10*babModel->getNumRows())
3062              //babModel->setNumberStrong(0);
3063              if (!noPrinting) {
3064                int iLevel = parameters[log].intValue();
3065                if (iLevel<0) {
3066                  babModel->setPrintingMode(1);
3067                  iLevel = -iLevel;
3068                }
3069                babModel->messageHandler()->setLogLevel(iLevel);
3070                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
3071                    babModel->messageHandler()->logLevel()>1)
3072                  babModel->setPrintFrequency(100);
3073              }
3074             
3075              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,
3076                    parameters[whichParam(MAXHOTITS,numberParameters,parameters)].intValue());
3077              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3078              // go faster stripes
3079              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
3080                osiclp->setupForRepeatedUse(2,parameters[slog].intValue());
3081              } else {
3082                osiclp->setupForRepeatedUse(0,parameters[slog].intValue());
3083              }
3084              double increment=babModel->getCutoffIncrement();;
3085              int * changed = NULL;
3086              if (!miplib)
3087                changed=analyze( osiclp,numberChanged,increment,false);
3088              if (debugValues) {
3089                if (numberDebugValues==babModel->getNumCols()) {
3090                  // for debug
3091                  babModel->solver()->activateRowCutDebugger(debugValues) ;
3092                } else {
3093                  printf("debug file has incorrect number of columns\n");
3094                }
3095              }
3096              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
3097              // Turn this off if you get problems
3098              // Used to be automatically set
3099              int mipOptions = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue()%10000;
3100              if (mipOptions!=(128|64|1))
3101                printf("mip options %d\n",mipOptions);
3102              osiclp->setSpecialOptions(mipOptions);
3103              if (gapRatio < 1.0e100) {
3104                double value = babModel->solver()->getObjValue() ;
3105                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
3106                babModel->setAllowableGap(value2) ;
3107                std::cout << "Continuous " << value
3108                          << ", so allowable gap set to "
3109                          << value2 << std::endl ;
3110              }
3111              // probably faster to use a basis to get integer solutions
3112              babModel->setSpecialOptions(babModel->specialOptions()|2);
3113              currentBranchModel = babModel;
3114              OsiSolverInterface * strengthenedModel=NULL;
3115              if (type==BAB||type==MIPLIB) {
3116                int moreMipOptions = parameters[whichParam(MOREMIPOPTIONS,numberParameters,parameters)].intValue();
3117                if (moreMipOptions>=0) {
3118                  printf("more mip options %d\n",moreMipOptions);
3119                  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3120                  if (moreMipOptions==10000) {
3121                    // test memory saving
3122                    moreMipOptions -= 10000;
3123                    ClpSimplex * lpSolver = osiclp->getModelPtr();
3124                    lpSolver->setPersistenceFlag(1);
3125                    // switch off row copy if few rows
3126                    if (lpSolver->numberRows()<150)
3127                      lpSolver->setSpecialOptions(lpSolver->specialOptions()|256);
3128                  }
3129                  if (((moreMipOptions+1)%1000000)!=0)
3130                    babModel->setSearchStrategy(moreMipOptions%1000000);
3131                  // go faster stripes
3132                  if( moreMipOptions >=999999) {
3133                    if (osiclp) {
3134                      int save = osiclp->specialOptions();
3135                      osiclp->setupForRepeatedUse(2,0);
3136                      osiclp->setSpecialOptions(save|osiclp->specialOptions());
3137                    }
3138                  } 
3139                }
3140              }
3141              if (type==BAB) {
3142#ifdef COIN_HAS_ASL
3143                if (usingAmpl) {
3144                  priorities=info.priorities;
3145                  branchDirection=info.branchDirection;
3146                  pseudoDown=info.pseudoDown;
3147                  pseudoUp=info.pseudoUp;
3148                  solutionIn=info.primalSolution;
3149                  prioritiesIn = info.priorities;
3150                  if (info.numberSos&&doSOS) {
3151                    // SOS
3152                    numberSOS = info.numberSos;
3153                    sosStart = info.sosStart;
3154                    sosIndices = info.sosIndices;
3155                    sosType = info.sosType;
3156                    sosReference = info.sosReference;
3157                    sosPriority = info.sosPriority;
3158                  }
3159                }
3160#endif               
3161                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
3162                if (solutionIn&&useSolution) {
3163                  if (preProcess) {
3164                    int numberColumns = babModel->getNumCols();
3165                    // extend arrays in case SOS
3166                    int n = originalColumns[numberColumns-1]+1;
3167                    int nSmaller = CoinMin(n,numberOriginalColumns);
3168                    double * solutionIn2 = new double [n];
3169                    int * prioritiesIn2 = new int[n];
3170                    int i;
3171                    for (i=0;i<nSmaller;i++) {
3172                      solutionIn2[i]=solutionIn[i];
3173                      prioritiesIn2[i]=prioritiesIn[i];
3174                    }
3175                    for (;i<n;i++) {
3176                      solutionIn2[i]=0.0;
3177                      prioritiesIn2[i]=1000000;
3178                    }
3179                    int iLast=-1;
3180                    for (i=0;i<numberColumns;i++) {
3181                      int iColumn = originalColumns[i];
3182                      assert (iColumn>iLast);
3183                      iLast=iColumn;
3184                      solutionIn2[i]=solutionIn2[iColumn];
3185                      if (prioritiesIn)
3186                        prioritiesIn2[i]=prioritiesIn2[iColumn];
3187                    }
3188                    babModel->setHotstartSolution(solutionIn2,prioritiesIn2);
3189                    delete [] solutionIn2;
3190                    delete [] prioritiesIn2;
3191                  } else {
3192                    babModel->setHotstartSolution(solutionIn,prioritiesIn);
3193                  }
3194                }
3195                OsiSolverInterface * testOsiSolver= (testOsiOptions>=0) ? babModel->solver() : NULL;
3196                if (!testOsiSolver) {
3197                  // *************************************************************
3198                  // CbcObjects
3199                  if (preProcess&&process.numberSOS()) {
3200                    int numberSOS = process.numberSOS();
3201                    int numberIntegers = babModel->numberIntegers();
3202                    /* model may not have created objects
3203                       If none then create
3204                    */
3205                    if (!numberIntegers||!babModel->numberObjects()) {
3206                      int type = (pseudoUp) ? 1 : 0;
3207                      babModel->findIntegers(true,type);
3208                      numberIntegers = babModel->numberIntegers();
3209                    }
3210                    OsiObject ** oldObjects = babModel->objects();
3211                    // Do sets and priorities
3212                    OsiObject ** objects = new OsiObject * [numberSOS];
3213                    // set old objects to have low priority
3214                    int numberOldObjects = babModel->numberObjects();
3215                    int numberColumns = babModel->getNumCols();
3216                    for (int iObj = 0;iObj<numberOldObjects;iObj++) {
3217                      oldObjects[iObj]->setPriority(numberColumns+1);
3218                      int iColumn = oldObjects[iObj]->columnNumber();
3219                      assert (iColumn>=0);
3220                      if (iColumn>=numberOriginalColumns)
3221                        continue;
3222                      if (originalColumns)
3223                        iColumn = originalColumns[iColumn];
3224                      if (branchDirection) {
3225                        CbcSimpleInteger * obj =
3226                          dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
3227                        if (obj) { 
3228                          obj->setPreferredWay(branchDirection[iColumn]);
3229                        } else {
3230                          CbcObject * obj =
3231                            dynamic_cast <CbcObject *>(oldObjects[iObj]) ;
3232                          assert (obj);
3233                          obj->setPreferredWay(branchDirection[iColumn]);
3234                        }
3235                      }
3236                      if (pseudoUp) {
3237                        CbcSimpleIntegerPseudoCost * obj1a =
3238                          dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
3239                        assert (obj1a);
3240                        if (pseudoDown[iColumn]>0.0)
3241                          obj1a->setDownPseudoCost(pseudoDown[iColumn]);
3242                        if (pseudoUp[iColumn]>0.0)
3243                          obj1a->setUpPseudoCost(pseudoUp[iColumn]);
3244                      }
3245                    }
3246                    const int * starts = process.startSOS();
3247                    const int * which = process.whichSOS();
3248                    const int * type = process.typeSOS();
3249                    const double * weight = process.weightSOS();
3250                    int iSOS;
3251                    for (iSOS =0;iSOS<numberSOS;iSOS++) {
3252                      int iStart = starts[iSOS];
3253                      int n=starts[iSOS+1]-iStart;
3254                      objects[iSOS] = new CbcSOS(babModel,n,which+iStart,weight+iStart,
3255                                                 iSOS,type[iSOS]);
3256                      // branch on long sets first
3257                      objects[iSOS]->setPriority(numberColumns-n);
3258                    }
3259                    babModel->addObjects(numberSOS,objects);
3260                    for (iSOS=0;iSOS<numberSOS;iSOS++)
3261                      delete objects[iSOS];
3262                    delete [] objects;
3263                  } else if (priorities||branchDirection||pseudoDown||pseudoUp||numberSOS) {
3264                    // do anyway for priorities etc
3265                    int numberIntegers = babModel->numberIntegers();
3266                    /* model may not have created objects
3267                       If none then create
3268                    */
3269                    if (!numberIntegers||!babModel->numberObjects()) {
3270                      int type = (pseudoUp) ? 1 : 0;
3271                      babModel->findIntegers(true,type);
3272                    }
3273                    if (numberSOS) {
3274                      // Do sets and priorities
3275                      OsiObject ** objects = new OsiObject * [numberSOS];
3276                      int iSOS;
3277                      if (originalColumns) {
3278                        // redo sequence numbers
3279                        int numberColumns = babModel->getNumCols();
3280                        int nOld = originalColumns[numberColumns-1]+1;
3281                        int * back = new int[nOld];
3282                        int i;
3283                        for (i=0;i<nOld;i++)
3284                          back[i]=-1;
3285                        for (i=0;i<numberColumns;i++)
3286                          back[originalColumns[i]]=i;
3287                        // Really need better checks
3288                        int nMissing=0;
3289                        int n=sosStart[numberSOS];
3290                        for (i=0;i<n;i++) {
3291                          int iColumn = sosIndices[i];
3292                          int jColumn = back[iColumn];
3293                          if (jColumn>=0) 
3294                            sosIndices[i] = jColumn;
3295                          else 
3296                            nMissing++;
3297                        }
3298                        delete [] back;
3299                        if (nMissing)
3300                          printf("%d SOS variables vanished due to pre processing? - check validity?\n",nMissing);
3301                      }
3302                      for (iSOS =0;iSOS<numberSOS;iSOS++) {
3303                        int iStart = sosStart[iSOS];
3304                        int n=sosStart[iSOS+1]-iStart;
3305                        objects[iSOS] = new CbcSOS(babModel,n,sosIndices+iStart,sosReference+iStart,
3306                                                   iSOS,sosType[iSOS]);
3307                        if (sosPriority)
3308                          objects[iSOS]->setPriority(sosPriority[iSOS]);
3309                        else if (!prioritiesIn)
3310                          objects[iSOS]->setPriority(10);  // rather than 1000
3311                      }
3312                      // delete any existing SOS objects
3313                      int numberObjects=babModel->numberObjects();
3314                      OsiObject ** oldObjects=babModel->objects();
3315                      int nNew=0;
3316                      for (int i=0;i<numberObjects;i++) {
3317                        OsiObject * objThis = oldObjects[i];
3318                        CbcSOS * obj1 =
3319                          dynamic_cast <CbcSOS *>(objThis) ;
3320                        OsiSOS * obj2 =
3321                          dynamic_cast <OsiSOS *>(objThis) ;
3322                        if (!obj1&&!obj2) {
3323                          oldObjects[nNew++]=objThis;
3324                        } else {
3325                          delete objThis;
3326                        }
3327                      }
3328                      babModel->setNumberObjects(nNew);
3329                      babModel->addObjects(numberSOS,objects);
3330                      for (iSOS=0;iSOS<numberSOS;iSOS++)
3331                        delete objects[iSOS];
3332                      delete [] objects;
3333                    }
3334                  }
3335                  OsiObject ** objects = babModel->objects();
3336                  int numberObjects = babModel->numberObjects();
3337                  for (int iObj = 0;iObj<numberObjects;iObj++) {
3338                    // skip sos
3339                    CbcSOS * objSOS =
3340                      dynamic_cast <CbcSOS *>(objects[iObj]) ;
3341                    if (objSOS)
3342                      continue;
3343                    int iColumn = objects[iObj]->columnNumber();
3344                    assert (iColumn>=0);
3345                    if (originalColumns)
3346                      iColumn = originalColumns[iColumn];
3347                    if (branchDirection) {
3348                      CbcSimpleInteger * obj =
3349                        dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3350                      if (obj) { 
3351                        obj->setPreferredWay(branchDirection[iColumn]);
3352                      } else {
3353                        CbcObject * obj =
3354                          dynamic_cast <CbcObject *>(objects[iObj]) ;
3355                        assert (obj);
3356                        obj->setPreferredWay(branchDirection[iColumn]);
3357                      }
3358                    }
3359                    if (priorities) {
3360                      int iPriority = priorities[iColumn];
3361                      if (iPriority>0)
3362                        objects[iObj]->setPriority(iPriority);
3363                    }
3364                    if (pseudoUp&&pseudoUp[iColumn]) {
3365                      CbcSimpleIntegerPseudoCost * obj1a =
3366                        dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
3367                      assert (obj1a);
3368                      if (pseudoDown[iColumn]>0.0)
3369                        obj1a->setDownPseudoCost(pseudoDown[iColumn]);
3370                      if (pseudoUp[iColumn]>0.0)
3371                        obj1a->setUpPseudoCost(pseudoUp[iColumn]);
3372                    }
3373                  }
3374                  // *************************************************************
3375                } else {
3376                  // *************************************************************
3377                  // OsiObjects
3378                  // Find if none
3379                  int numberIntegers = testOsiSolver->getNumIntegers();
3380                  /* model may not have created objects
3381                     If none then create
3382                  */
3383                  if (!numberIntegers||!testOsiSolver->numberObjects()) {
3384                    //int type = (pseudoUp) ? 1 : 0;
3385                    testOsiSolver->findIntegers(false);
3386                    numberIntegers = testOsiSolver->getNumIntegers();
3387                  }
3388                  if (preProcess&&process.numberSOS()) {
3389                    int numberSOS = process.numberSOS();
3390                    OsiObject ** oldObjects = testOsiSolver->objects();
3391                    // Do sets and priorities
3392                    OsiObject ** objects = new OsiObject * [numberSOS];
3393                    // set old objects to have low priority
3394                    int numberOldObjects = testOsiSolver->numberObjects();
3395                    int numberColumns = testOsiSolver->getNumCols();
3396                    for (int iObj = 0;iObj<numberOldObjects;iObj++) {
3397                      oldObjects[iObj]->setPriority(numberColumns+1);
3398                      int iColumn = oldObjects[iObj]->columnNumber();
3399                      assert (iColumn>=0);
3400                      if (iColumn>=numberOriginalColumns)
3401                        continue;
3402                      if (originalColumns)
3403                        iColumn = originalColumns[iColumn];
3404                      if (branchDirection) {
3405                        OsiSimpleInteger * obj =
3406                          dynamic_cast <OsiSimpleInteger *>(oldObjects[iObj]) ;
3407                        if (obj) { 
3408                          obj->setPreferredWay(branchDirection[iColumn]);
3409                        } else {
3410                          OsiObject2 * obj =
3411                            dynamic_cast <OsiObject2 *>(oldObjects[iObj]) ;
3412                          if (obj)
3413                            obj->setPreferredWay(branchDirection[iColumn]);
3414                        }
3415                      }
3416                      if (pseudoUp) {
3417                        abort();
3418                      }
3419                    }
3420                    const int * starts = process.startSOS();
3421                    const int * which = process.whichSOS();
3422                    const int * type = process.typeSOS();
3423                    const double * weight = process.weightSOS();
3424                    int iSOS;
3425                    for (iSOS =0;iSOS<numberSOS;iSOS++) {
3426                      int iStart = starts[iSOS];
3427                      int n=starts[iSOS+1]-iStart;
3428                      objects[iSOS] = new OsiSOS(testOsiSolver,n,which+iStart,weight+iStart,
3429                                                 type[iSOS]);
3430                      // branch on long sets first
3431                      objects[iSOS]->setPriority(numberColumns-n);
3432                    }
3433                    testOsiSolver->addObjects(numberSOS,objects);
3434                    for (iSOS=0;iSOS<numberSOS;iSOS++)
3435                      delete objects[iSOS];
3436                    delete [] objects;
3437                  } else if (priorities||branchDirection||pseudoDown||pseudoUp||numberSOS) {
3438                    if (numberSOS) {
3439                      // Do sets and priorities
3440                      OsiObject ** objects = new OsiObject * [numberSOS];
3441                      int iSOS;
3442                      if (originalColumns) {
3443                        // redo sequence numbers
3444                        int numberColumns = testOsiSolver->getNumCols();
3445                        int nOld = originalColumns[numberColumns-1]+1;
3446                        int * back = new int[nOld];
3447                        int i;
3448                        for (i=0;i<nOld;i++)
3449                          back[i]=-1;
3450                        for (i=0;i<numberColumns;i++)
3451                          back[originalColumns[i]]=i;
3452                        // Really need better checks
3453                        int nMissing=0;
3454                        int n=sosStart[numberSOS];
3455                        for (i=0;i<n;i++) {
3456                          int iColumn = sosIndices[i];
3457                          int jColumn = back[iColumn];
3458                          if (jColumn>=0) 
3459                            sosIndices[i] = jColumn;
3460                          else 
3461                            nMissing++;
3462                        }
3463                        delete [] back;
3464                        if (nMissing)
3465                          printf("%d SOS variables vanished due to pre processing? - check validity?\n",nMissing);
3466                      }
3467                      for (iSOS =0;iSOS<numberSOS;iSOS++) {
3468                        int iStart = sosStart[iSOS];
3469                        int n=sosStart[iSOS+1]-iStart;
3470                        objects[iSOS] = new OsiSOS(testOsiSolver,n,sosIndices+iStart,sosReference+iStart,
3471                                                   sosType[iSOS]);
3472                        if (sosPriority)
3473                          objects[iSOS]->setPriority(sosPriority[iSOS]);
3474                        else if (!prioritiesIn)
3475                          objects[iSOS]->setPriority(10);  // rather than 1000
3476                      }
3477                      // delete any existing SOS objects
3478                      int numberObjects=testOsiSolver->numberObjects();
3479                      OsiObject ** oldObjects=testOsiSolver->objects();
3480                      int nNew=0;
3481                      for (int i=0;i<numberObjects;i++) {
3482                        OsiObject * objThis = oldObjects[i];
3483                        OsiSOS * obj1 =
3484                          dynamic_cast <OsiSOS *>(objThis) ;
3485                        OsiSOS * obj2 =
3486                          dynamic_cast <OsiSOS *>(objThis) ;
3487                        if (!obj1&&!obj2) {
3488                          oldObjects[nNew++]=objThis;
3489                        } else {
3490                          delete objThis;
3491                        }
3492                      }
3493                      testOsiSolver->setNumberObjects(nNew);
3494                      testOsiSolver->addObjects(numberSOS,objects);
3495                      for (iSOS=0;iSOS<numberSOS;iSOS++)
3496                        delete objects[iSOS];
3497                      delete [] objects;
3498                    }
3499                  }
3500                  OsiObject ** objects = testOsiSolver->objects();
3501                  int numberObjects = testOsiSolver->numberObjects();
3502                  int logLevel = parameters[log].intValue();
3503                  for (int iObj = 0;iObj<numberObjects;iObj++) {
3504                    // skip sos
3505                    OsiSOS * objSOS =
3506                      dynamic_cast <OsiSOS *>(objects[iObj]) ;
3507                    if (objSOS) {
3508                      if (logLevel>2)
3509                        printf("Set %d is SOS - priority %d\n",iObj,objSOS->priority());
3510                      continue;
3511                    }
3512                    int iColumn = objects[iObj]->columnNumber();
3513                    if (iColumn>=0) {
3514                      if (originalColumns)
3515                        iColumn = originalColumns[iColumn];
3516                      if (branchDirection) {
3517                        OsiSimpleInteger * obj =
3518                          dynamic_cast <OsiSimpleInteger *>(objects[iObj]) ;
3519                        if (obj) { 
3520                          obj->setPreferredWay(branchDirection[iColumn]);
3521                        } else {
3522                          OsiObject2 * obj =
3523                            dynamic_cast <OsiObject2 *>(objects[iObj]) ;
3524                          if (obj)
3525                            obj->setPreferredWay(branchDirection[iColumn]);
3526                        }
3527                      }
3528                    }
3529                    if (priorities) {
3530                      int iPriority = priorities[iColumn];
3531                      if (iPriority>0)
3532                        objects[iObj]->setPriority(iPriority);
3533                    }
3534                    if (logLevel>2)
3535                      printf("Obj %d is int? - priority %d\n",iObj,objects[iObj]->priority());
3536                    if (pseudoUp&&pseudoUp[iColumn]) {
3537                      abort();
3538                    }
3539                  }
3540                  // *************************************************************
3541                }
3542                int statistics = (printOptions>0) ? printOptions: 0;
3543#ifdef COIN_HAS_ASL
3544                if (!usingAmpl) {
3545#endif
3546                  free(priorities);
3547                  priorities=NULL;
3548                  free(branchDirection);
3549                  branchDirection=NULL;
3550                  free(pseudoDown);
3551                  pseudoDown=NULL;
3552                  free(pseudoUp);
3553                  pseudoUp=NULL;
3554                  free(solutionIn);
3555                  solutionIn=NULL;
3556                  free(prioritiesIn);
3557                  prioritiesIn=NULL;
3558                  free(sosStart);
3559                  sosStart=NULL;
3560                  free(sosIndices);
3561                  sosIndices=NULL;
3562                  free(sosType);
3563                  sosType=NULL;
3564                  free(sosReference);
3565                  sosReference=NULL;
3566                  free(cut);
3567                  cut=NULL;
3568                  free(sosPriority);
3569                  sosPriority=NULL;
3570#ifdef COIN_HAS_ASL
3571                }
3572#endif               
3573                if (nodeStrategy) {
3574                  // change default
3575                  if (nodeStrategy>1) {
3576                    // up or down
3577                    int way = ((nodeStrategy%1)==1) ? -1 : +1;
3578                    babModel->setPreferredWay(way);
3579#if 0
3580                    OsiObject ** objects = babModel->objects();
3581                    int numberObjects = babModel->numberObjects();
3582                    for (int iObj = 0;iObj<numberObjects;iObj++) {
3583                      CbcObject * obj =
3584                        dynamic_cast <CbcObject *>(objects[iObj]) ;
3585                      assert (obj);
3586                      obj->setPreferredWay(way);
3587                    }
3588#endif
3589                  }
3590                  if (nodeStrategy==1||nodeStrategy>3) {
3591                    // depth
3592                    CbcCompareDefault compare;
3593                    compare.setWeight(-3.0);
3594                    babModel->setNodeComparison(compare);
3595                  }
3596                }
3597                if (cppValue>=0) {
3598                  int prepro = useStrategy ? -1 : preProcess;
3599                  // generate code
3600                  FILE * fp = fopen("user_driver.cpp","w");
3601                  if (fp) {
3602                    // generate enough to do BAB
3603                    babModel->generateCpp(fp,1);
3604                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3605                    // Make general so do factorization
3606                    int factor = osiclp->getModelPtr()->factorizationFrequency();
3607                    osiclp->getModelPtr()->setFactorizationFrequency(200);
3608                    osiclp->generateCpp(fp);
3609                    osiclp->getModelPtr()->setFactorizationFrequency(factor);
3610                    //solveOptions.generateCpp(fp);
3611                    fclose(fp);
3612                    // now call generate code
3613                    generateCode(babModel,"user_driver.cpp",cppValue,prepro);
3614                  } else {
3615                    std::cout<<"Unable to open file user_driver.cpp"<<std::endl;
3616                  }
3617                }
3618                if (!babModel->numberStrong())
3619                  babModel->setNumberBeforeTrust(0);
3620                if (useStrategy) {
3621                  CbcStrategyDefault strategy(true,babModel->numberStrong(),babModel->numberBeforeTrust());
3622                  strategy.setupPreProcessing(1);
3623                  babModel->setStrategy(strategy);
3624                }
3625                if (testOsiOptions>=0) {
3626                  printf("Testing OsiObject options %d\n",testOsiOptions);
3627                  CbcBranchDefaultDecision decision;
3628                  OsiChooseStrong choose(babModel->solver());
3629                  choose.setNumberBeforeTrusted(babModel->numberBeforeTrust());
3630                  choose.setNumberStrong(babModel->numberStrong());
3631                  choose.setShadowPriceMode(testOsiOptions);
3632                  if (!numberSOS) {
3633                    babModel->solver()->findIntegersAndSOS(false);
3634#ifdef COIN_HAS_LINK
3635                    // If linked then pass in model
3636                    OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel->solver());
3637                    if (solver3) {
3638                      if (tightenFactor>0.0) {
3639                        // set grid size for all continuous bi-linear
3640                        solver3->setMeshSizes(tightenFactor);
3641                      }
3642                      int options = parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].intValue()/10000;
3643                      CglStored stored;
3644                      if (options) {
3645                        printf("nlp options %d\n",options);
3646                        /*
3647                          1 - force mini branch and bound
3648                          2 - set priorities high on continuous
3649                          4 - try adding OA cuts
3650                          8 - try doing quadratic linearization
3651                          16 - try expanding knapsacks
3652                        */
3653                        if ((options&2))
3654                          solver3->setBiLinearPriorities(10);
3655                        if ((options&4))
3656                          solver3->setSpecialOptions2(solver3->specialOptions2()|(8+4));
3657                        if ((options&1)!=0&&slpValue>0)
3658                          solver3->setFixedPriority(slpValue);
3659                        double cutoff=COIN_DBL_MAX;
3660                        if ((options&4))
3661                          cutoff=solver3->linearizedBAB(&stored);
3662                        if (cutoff<babModel->getCutoff())
3663                          babModel->setCutoff(cutoff);
3664                      }
3665                      solver3->setCbcModel(babModel);
3666                      babModel->addCutGenerator(&stored,1,"Stored");
3667                      CglTemporary temp;
3668                      babModel->addCutGenerator(&temp,1,"OnceOnly");
3669                      choose.setNumberBeforeTrusted(2000);
3670                      choose.setNumberStrong(20);
3671                    }
3672#endif
3673                  } else {
3674                    // move across
3675                    babModel->deleteObjects(false);
3676                    //babModel->addObjects(babModel->solver()->numberObjects(),babModel->solver()->objects());
3677                  }
3678                  decision.setChooseMethod(choose);
3679                  babModel->setBranchingMethod(decision);
3680                  if (useCosts&&testOsiOptions>=0) {
3681                    int numberColumns = babModel->getNumCols();
3682                    int * sort = new int[numberColumns];
3683                    double * dsort = new double[numberColumns];
3684                    int * priority = new int [numberColumns];
3685                    const double * objective = babModel->getObjCoefficients();
3686                    const double * lower = babModel->getColLower() ;
3687                    const double * upper = babModel->getColUpper() ;
3688                    const CoinPackedMatrix * matrix = babModel->solver()->getMatrixByCol();
3689                    const int * columnLength = matrix->getVectorLengths();
3690                    int iColumn;
3691                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
3692                      sort[iColumn]=iColumn;
3693                      if (useCosts==1)
3694                        dsort[iColumn]=-fabs(objective[iColumn]);
3695                      else if (useCosts==2)
3696                        dsort[iColumn]=iColumn;
3697                      else if (useCosts==3)
3698                        dsort[iColumn]=upper[iColumn]-lower[iColumn];
3699                      else if (useCosts==4)
3700                        dsort[iColumn]=-(upper[iColumn]-lower[iColumn]);
3701                      else if (useCosts==5)
3702                        dsort[iColumn]=-columnLength[iColumn];
3703                    }
3704                    CoinSort_2(dsort,dsort+numberColumns,sort);
3705                    int level=0;
3706                    double last = -1.0e100;
3707                    for (int i=0;i<numberColumns;i++) {
3708                      int iPut=sort[i];
3709                      if (dsort[i]!=last) {
3710                        level++;
3711                        last=dsort[i];
3712                      }
3713                      priority[iPut]=level;
3714                    }
3715                    OsiObject ** objects = babModel->objects();
3716                    int numberObjects = babModel->numberObjects();
3717                    for (int iObj = 0;iObj<numberObjects;iObj++) {
3718                      OsiObject * obj = objects[iObj] ;
3719                      int iColumn = obj->columnNumber();
3720                      if (iColumn>=0)
3721                        obj->setPriority(priority[iColumn]);
3722                    }
3723                    delete [] priority;
3724                    delete [] sort;
3725                    delete [] dsort;
3726                  }
3727                }
3728                checkSOS(babModel, babModel->solver());
3729                if (doSprint>0) {
3730                  // Sprint for primal solves
3731                  ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
3732                  ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
3733                  int numberPasses = 5;
3734                  int options[] = {0,3,0,0,0,0};
3735                  int extraInfo[] = {-1,20,-1,-1,-1,-1};
3736                  extraInfo[1]=doSprint;
3737                  int independentOptions[] = {0,0,3};
3738                  ClpSolve clpSolve(method,presolveType,numberPasses,
3739                                    options,extraInfo,independentOptions);
3740                  // say use in OsiClp
3741                  clpSolve.setSpecialOption(6,1);
3742                  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3743                  osiclp->setSolveOptions(clpSolve);
3744                  osiclp->setHintParam(OsiDoDualInResolve,false);
3745                  // switch off row copy
3746                  osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions()|256);
3747                  osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
3748                }
3749#ifdef COIN_HAS_LINK
3750                if (storedAmpl.sizeRowCuts()) {
3751                  if (preProcess) {
3752                    const int * originalColumns = process.originalColumns();
3753                    int numberColumns = babModel->getNumCols();
3754                    int * newColumn = new int[numberOriginalColumns];
3755                    int i;
3756                    for (i=0;i<numberOriginalColumns;i++) 
3757                      newColumn[i]=-1;
3758                    for (i=0;i<numberColumns;i++) {
3759                      int iColumn = originalColumns[i];
3760                      newColumn[iColumn]=i;
3761                    }
3762                    int * buildColumn = new int[numberColumns];
3763                    // Build up valid cuts
3764                    int nBad=0;
3765                    int nCuts = storedAmpl.sizeRowCuts();
3766                    CglStored newCuts;
3767                    for (i=0;i<nCuts;i++) {
3768                      const OsiRowCut * cut = storedAmpl.rowCutPointer(i);
3769                      double lb = cut->lb();
3770                      double ub = cut->ub();
3771                      int n=cut->row().getNumElements();
3772                      const int * column = cut->row().getIndices();
3773                      const double * element = cut->row().getElements();
3774                      bool bad=false;
3775                      for (int i=0;i<n;i++) {
3776                        int iColumn = column[i];
3777                        iColumn = newColumn[iColumn];
3778                        if (iColumn>=0) {
3779                          buildColumn[i]=iColumn;
3780                        } else {
3781                          bad=true;
3782                          break;
3783                        }
3784                      }
3785                      if (!bad) {
3786                        newCuts.addCut(lb,ub,n,buildColumn,element);
3787                      } else {
3788                        nBad++;
3789                      }
3790                    }
3791                    storedAmpl=newCuts;
3792                    if (nBad)
3793                      printf("%d cuts dropped\n",nBad);
3794                    delete [] newColumn;
3795                    delete [] buildColumn;
3796                  }
3797                  if (storedAmpl.sizeRowCuts()) {
3798                    //babModel->addCutGenerator(&storedAmpl,1,"AmplStored");
3799                    int numberRowCuts = storedAmpl.sizeRowCuts();
3800                    for (int i=0;i<numberRowCuts;i++) {
3801                      const OsiRowCut * rowCutPointer = storedAmpl.rowCutPointer(i);
3802                      babModel->makeGlobalCut(rowCutPointer);
3803                    }
3804                  }
3805                }
3806#endif
3807#ifdef CLP_MALLOC_STATISTICS
3808                malloc_stats();
3809                malloc_stats2();
3810#endif
3811                if (outputFormat==5) {
3812                  osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3813                  lpSolver = osiclp->getModelPtr();
3814                  lpSolver->setPersistenceFlag(1);
3815                }
3816                babModel->branchAndBound(statistics);
3817#ifdef CLP_MALLOC_STATISTICS
3818                malloc_stats();
3819                malloc_stats2();
3820#endif
3821                checkSOS(babModel, babModel->solver());
3822              } else if (type==MIPLIB) {
3823                CbcStrategyDefault strategy(true,babModel->numberStrong(),babModel->numberBeforeTrust());
3824                // Set up pre-processing
3825                int translate2[]={9999,1,1,3,2,4,5};
3826                if (preProcess)
3827                  strategy.setupPreProcessing(translate2[preProcess]);
3828                babModel->setStrategy(strategy);
3829                if (outputFormat==5) {
3830                  osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3831                  lpSolver = osiclp->getModelPtr();
3832                  lpSolver->setPersistenceFlag(1);
3833                }
3834                if (testOsiOptions>=0) {
3835                  printf("Testing OsiObject options %d\n",testOsiOptions);
3836                  CbcBranchDefaultDecision decision;
3837                  OsiChooseStrong choose(babModel->solver());
3838                  choose.setNumberBeforeTrusted(babModel->numberBeforeTrust());
3839                  choose.setNumberStrong(babModel->numberStrong());
3840                  choose.setShadowPriceMode(testOsiOptions);
3841                  //babModel->deleteObjects(false);
3842                  decision.setChooseMethod(choose);
3843                  babModel->setBranchingMethod(decision);
3844                }
3845                CbcClpUnitTest(*babModel);
3846                goodModel=false;
3847                break;
3848              } else {
3849                strengthenedModel = babModel->strengthenedModel();
3850              }
3851              currentBranchModel = NULL;
3852              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3853              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
3854                lpSolver = osiclp->getModelPtr();
3855                //move best solution (should be there -- but ..)
3856                int n = lpSolver->getNumCols();
3857                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
3858                saveSolution(osiclp->getModelPtr(),"debug.file");
3859              }
3860              if (!noPrinting) {
3861                // Print more statistics
3862                std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
3863                         <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
3864               
3865                numberGenerators = babModel->numberCutGenerators();
3866                for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
3867                  CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
3868                  std::cout<<generator->cutGeneratorName()<<" was tried "
3869                           <<generator->numberTimesEntered()<<" times and created "
3870                           <<generator->numberCutsInTotal()<<" cuts of which "
3871                           <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
3872                  if (generator->timing())
3873                    std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
3874                  else
3875                    std::cout<<std::endl;
3876                }
3877              }
3878              time2 = CoinCpuTime();
3879              totalTime += time2-time1;
3880              // For best solution
3881              double * bestSolution = NULL;
3882              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
3883                // post process
3884                if (preProcess) {
3885                  int n = saveSolver->getNumCols();
3886                  bestSolution = new double [n];
3887                  process.postProcess(*babModel->solver());
3888                  // Solution now back in saveSolver
3889                  babModel->assignSolver(saveSolver);
3890                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
3891                } else {
3892                  int n = babModel->solver()->getNumCols();
3893                  bestSolution = new double [n];
3894                  memcpy(bestSolution,babModel->solver()->getColSolution(),n*sizeof(double));
3895                }
3896                checkSOS(babModel, babModel->solver());
3897              }
3898              if (type==STRENGTHEN&&strengthenedModel)
3899                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
3900#ifdef COIN_HAS_ASL
3901              else if (usingAmpl) 
3902                clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3903#endif
3904              lpSolver = clpSolver->getModelPtr();
3905              if (numberChanged) {
3906                for (int i=0;i<numberChanged;i++) {
3907                  int iColumn=changed[i];
3908                  clpSolver->setContinuous(iColumn);
3909                }
3910                delete [] changed;
3911              }
3912              if (type==BAB) {
3913                //move best solution (should be there -- but ..)
3914                int n = lpSolver->getNumCols();
3915                if (bestSolution) {
3916                  memcpy(lpSolver->primalColumnSolution(),bestSolution,n*sizeof(double));
3917                  // now see what that does to row solution
3918                  int numberRows=lpSolver->numberRows();
3919                  double * rowSolution = lpSolver->primalRowSolution();
3920                  memset (rowSolution,0,numberRows*sizeof(double));
3921                  lpSolver->clpMatrix()->times(1.0,bestSolution,rowSolution);
3922                }
3923                if (debugFile=="create"&&bestSolution) {
3924                  saveSolution(lpSolver,"debug.file");
3925                }
3926                delete [] bestSolution;
3927                std::string statusName[]={"Finished","Stopped on ","Difficulties",
3928                                          "","","User ctrl-c"};
3929                std::string minor[]={"","","gap","nodes","time","","solutions","user ctrl-c"};
3930                int iStat = babModel->status();
3931                int iStat2 = babModel->secondaryStatus();
3932                if (!noPrinting)
3933                  std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
3934                           <<" objective "<<babModel->getObjValue()<<
3935                    " after "<<babModel->getNodeCount()<<" nodes and "
3936                           <<babModel->getIterationCount()<<
3937                    " iterations - took "<<time2-time1<<" seconds"<<std::endl;
3938#ifdef COIN_HAS_ASL
3939                if (usingAmpl) {
3940                  clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
3941                  lpSolver = clpSolver->getModelPtr();
3942                  double value = babModel->getObjValue()*lpSolver->getObjSense();
3943                  char buf[300];
3944                  int pos=0;
3945                  if (iStat==0) {
3946                    if (babModel->getObjValue()<1.0e40) {
3947                      pos += sprintf(buf+pos,"optimal," );
3948                    } else {
3949                      // infeasible
3950                      iStat=1;
3951                      pos += sprintf(buf+pos,"infeasible,");
3952                    }
3953                  } else if (iStat==1) {
3954                    if (iStat2!=6)
3955                      iStat=3;
3956                    else
3957                      iStat=4;
3958                    pos += sprintf(buf+pos,"stopped on %s,",minor[iStat2].c_str());
3959                  } else if (iStat==2) {
3960                    iStat = 7;
3961                    pos += sprintf(buf+pos,"stopped on difficulties,");
3962                  } else if (iStat==5) {
3963                    iStat = 3;
3964                    pos += sprintf(buf+pos,"stopped on ctrl-c,");
3965                  } else {
3966                    pos += sprintf(buf+pos,"status unknown,");
3967                    iStat=6;
3968                  }
3969                  info.problemStatus=iStat;
3970                  info.objValue = value;
3971                  if (babModel->getObjValue()<1.0e40) {
3972                    int precision = ampl_obj_prec();
3973                    if (precision>0)
3974                      pos += sprintf(buf+pos," objective %.*g",precision,
3975                                     value);
3976                    else
3977                      pos += sprintf(buf+pos," objective %g",value);
3978                  }
3979                  sprintf(buf+pos,"\n%d nodes, %d iterations",
3980                          babModel->getNodeCount(),
3981                          babModel->getIterationCount());
3982                  if (bestSolution) {
3983                    free(info.primalSolution);
3984                    if (!numberKnapsack) {
3985                      info.primalSolution = (double *) malloc(n*sizeof(double));
3986                      CoinCopyN(lpSolver->primalColumnSolution(),n,info.primalSolution);
3987                      int numberRows = lpSolver->numberRows();
3988                      free(info.dualSolution);
3989                      info.dualSolution = (double *) malloc(numberRows*sizeof(double));
3990                      CoinCopyN(lpSolver->dualRowSolution(),numberRows,info.dualSolution);
3991                    } else {
3992                      // expanded knapsack
3993                      info.dualSolution=NULL;
3994                      int numberColumns = saveCoinModel.numberColumns();
3995                      info.primalSolution = (double *) malloc(numberColumns*sizeof(double));
3996                      // Fills in original solution (coinModel length)
3997                      afterKnapsack(saveCoinModel,  whichColumn,  knapsackStart, 
3998                                    knapsackRow,  numberKnapsack,
3999                                    lpSolver->primalColumnSolution(), info.primalSolution,1);
4000                    }
4001                  } else {
4002                    info.primalSolution=NULL;
4003                    info.dualSolution=NULL;
4004                  }
4005                  // put buffer into info
4006                  strcpy(info.buffer,buf);
4007                }
4008#endif
4009              } else {
4010                std::cout<<"Model strengthened - now has "<<clpSolver->getNumRows()
4011                         <<" rows"<<std::endl;
4012              }
4013              time1 = time2;
4014              delete babModel;
4015              babModel=NULL;
4016            } else {
4017              std::cout << "** Current model not valid" << std::endl ; 
4018            }
4019            break ;
4020          case IMPORT:
4021            {
4022#ifdef COIN_HAS_ASL
4023              if (!usingAmpl) {
4024#endif
4025                free(priorities);
4026                priorities=NULL;
4027                free(branchDirection);
4028                branchDirection=NULL;
4029                free(pseudoDown);
4030                pseudoDown=NULL;
4031                free(pseudoUp);
4032                pseudoUp=NULL;
4033                free(solutionIn);
4034                solutionIn=NULL;
4035                free(prioritiesIn);
4036                prioritiesIn=NULL;
4037                free(sosStart);
4038                sosStart=NULL;
4039                free(sosIndices);
4040                sosIndices=NULL;
4041                free(sosType);
4042                sosType=NULL;
4043                free(sosReference);
4044                sosReference=NULL;
4045                free(cut);
4046                cut=NULL;
4047                free(sosPriority);
4048                sosPriority=NULL;
4049#ifdef COIN_HAS_ASL
4050              }
4051#endif               
4052              delete babModel;
4053              babModel=NULL;
4054              // get next field
4055              field = CoinReadGetString(argc,argv);
4056              if (field=="$") {
4057                field = parameters[iParam].stringValue();
4058              } else if (field=="EOL") {
4059                parameters[iParam].printString();
4060                break;
4061              } else {
4062                parameters[iParam].setStringValue(field);
4063              }
4064              std::string fileName;
4065              bool canOpen=false;
4066              if (field=="-") {
4067                // stdin
4068                canOpen=true;
4069                fileName = "-";
4070              } else {
4071                bool absolutePath;
4072                if (dirsep=='/') {
4073                  // non Windows (or cygwin)
4074                  absolutePath=(field[0]=='/');
4075                } else {
4076                  //Windows (non cycgwin)
4077                  absolutePath=(field[0]=='\\');
4078                  // but allow for :
4079                  if (strchr(field.c_str(),':'))
4080                    absolutePath=true;
4081                }
4082                if (absolutePath) {
4083                  fileName = field;
4084                } else if (field[0]=='~') {
4085                  char * environVar = getenv("HOME");
4086                  if (environVar) {
4087                    std::string home(environVar);
4088                    field=field.erase(0,1);
4089                    fileName = home+field;
4090                  } else {
4091                    fileName=field;
4092                  }
4093                } else {
4094                  fileName = directory+field;
4095                }
4096                FILE *fp=fopen(fileName.c_str(),"r");
4097                if (fp) {
4098                  // can open - lets go for it
4099                  fclose(fp);
4100                  canOpen=true;
4101                } else {
4102                  std::cout<<"Unable to open file "<<fileName<<std::endl;
4103                }
4104              }
4105              if (canOpen) {
4106                int status =clpSolver->readMps(fileName.c_str(),
4107                                                   keepImportNames!=0,
4108                                                   allowImportErrors!=0);
4109                if (!status||(status>0&&allowImportErrors)) {
4110                  if (keepImportNames) {
4111                    lengthName = lpSolver->lengthNames();
4112                    rowNames = *(lpSolver->rowNames());
4113                    columnNames = *(lpSolver->columnNames());
4114                  } else {
4115                    lengthName=0;
4116                  }
4117                  goodModel=true;
4118                  //Set integers in clpsolver
4119                  const char * info = lpSolver->integerInformation();
4120                  if (info) {
4121                    int numberColumns = lpSolver->numberColumns();
4122                    int i;
4123                    for (i=0;i<numberColumns;i++) {
4124                      if (info[i]) 
4125                        clpSolver->setInteger(i);
4126                    }
4127                  }
4128                  // sets to all slack (not necessary?)
4129                  lpSolver->createStatus();
4130                  time2 = CoinCpuTime();
4131                  totalTime += time2-time1;
4132                  time1=time2;
4133                  // Go to canned file if just input file
4134                  if (CbcOrClpRead_mode==2&&argc==2) {
4135                    // only if ends .mps
4136                    std::string::size_type loc = fileName.find(".mps") ;
4137                    if (loc != std::string::npos &&
4138                        fileName.length() == loc+3)
4139                    { fileName.replace(loc+1,3,"par") ;
4140                      FILE *fp=fopen(fileName.c_str(),"r");
4141                      if (fp) {
4142                        CbcOrClpReadCommand=fp; // Read from that file
4143                        CbcOrClpRead_mode=-1;
4144                      }
4145                    }
4146                  }
4147                } else {
4148                  // errors
4149                  std::cout<<"There were "<<status<<
4150                    " errors on input"<<std::endl;
4151                }
4152              }
4153            }
4154            break;
4155          case MODELIN:
4156#ifdef COIN_HAS_LINK
4157            {
4158              // get next field
4159              field = CoinReadGetString(argc,argv);
4160              if (field=="$") {
4161                field = parameters[iParam].stringValue();
4162              } else if (field=="EOL") {
4163                parameters[iParam].printString();
4164                break;
4165              } else {
4166                parameters[iParam].setStringValue(field);
4167              }
4168              std::string fileName;
4169              bool canOpen=false;
4170              if (field=="-") {
4171                // stdin
4172                canOpen=true;
4173                fileName = "-";
4174              } else {
4175                bool absolutePath;
4176                if (dirsep=='/') {
4177                  // non Windows (or cygwin)
4178                  absolutePath=(field[0]=='/');
4179                } else {
4180                  //Windows (non cycgwin)
4181                  absolutePath=(field[0]=='\\');
4182                  // but allow for :
4183                  if (strchr(field.c_str(),':'))
4184                    absolutePath=true;
4185                }
4186                if (absolutePath) {
4187                  fileName = field;
4188                } else if (field[0]=='~') {
4189                  char * environVar = getenv("HOME");
4190                  if (environVar) {
4191                    std::string home(environVar);
4192                    field=field.erase(0,1);
4193                    fileName = home+field;
4194                  } else {
4195                    fileName=field;
4196                  }
4197                } else {
4198                  fileName = directory+field;
4199                }
4200                FILE *fp=fopen(fileName.c_str(),"r");
4201                if (fp) {
4202                  // can open - lets go for it
4203                  fclose(fp);
4204                  canOpen=true;
4205                } else {
4206                  std::cout<<"Unable to open file "<<fileName<<std::endl;
4207                }
4208              }
4209              if (canOpen) {
4210                CoinModel coinModel(fileName.c_str(),2);
4211                // load from coin model
4212                OsiSolverLink solver1;
4213                OsiSolverInterface * solver2 = solver1.clone();
4214                model.assignSolver(solver2,true);
4215                OsiSolverLink * si =
4216                  dynamic_cast<OsiSolverLink *>(model.solver()) ;
4217                assert (si != NULL);
4218                si->setDefaultMeshSize(0.001);
4219                // need some relative granularity
4220                si->setDefaultBound(100.0);
4221                si->setDefaultMeshSize(0.01);
4222                si->setDefaultBound(100.0);
4223                si->setIntegerPriority(1000);
4224                si->setBiLinearPriority(10000);
4225                CoinModel * model2 = (CoinModel *) &coinModel;
4226                si->load(*model2);
4227                // redo
4228                solver = model.solver();
4229                clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
4230                lpSolver = clpSolver->getModelPtr();
4231                clpSolver->messageHandler()->setLogLevel(0) ;
4232                testOsiParameters=0;
4233                complicatedInteger=2;
4234              }
4235            }
4236#endif
4237            break;
4238          case EXPORT:
4239            if (goodModel) {
4240              // get next field
4241              field = CoinReadGetString(argc,argv);
4242              if (field=="$") {
4243                field = parameters[iParam].stringValue();
4244              } else if (field=="EOL") {
4245                parameters[iParam].printString();
4246                break;
4247              } else {
4248                parameters[iParam].setStringValue(field);
4249              }
4250              std::string fileName;
4251              bool canOpen=false;
4252              if (field[0]=='/'||field[0]=='\\') {
4253                fileName = field;
4254              } else if (field[0]=='~') {
4255                char * environVar = getenv("HOME");
4256                if (environVar) {
4257                  std::string home(environVar);
4258                  field=field.erase(0,1);
4259                  fileName = home+field;
4260                } else {
4261                  fileName=field;
4262                }
4263              } else {
4264                fileName = directory+field;
4265              }
4266              FILE *fp=fopen(fileName.c_str(),"w");
4267              if (fp) {
4268                // can open - lets go for it
4269                fclose(fp);
4270                canOpen=true;
4271              } else {
4272                std::cout<<"Unable to open file "<<fileName<<std::endl;
4273              }
4274              if (canOpen) {
4275                // If presolve on then save presolved
4276                bool deleteModel2=false;
4277                ClpSimplex * model2 = lpSolver;
4278#ifdef COIN_HAS_ASL
4279                if (info.numberSos&&doSOS&&usingAmpl) {
4280                  // SOS
4281                  numberSOS = info.numberSos;
4282                  sosStart = info.sosStart;
4283                  sosIndices = info.sosIndices;
4284                  sosReference = info.sosReference;
4285                  preSolve=false;
4286                  clpSolver->setSOSData(numberSOS,info.sosType,sosStart,sosIndices,sosReference);
4287                }
4288#endif
4289                if (preSolve) {
4290                  ClpPresolve pinfo;
4291                  int presolveOptions2 = presolveOptions&~0x40000000;
4292                  if ((presolveOptions2&0xffff)!=0)
4293                    pinfo.setPresolveActions(presolveOptions2);
4294                  if ((printOptions&1)!=0)
4295                    pinfo.statistics();
4296                  double presolveTolerance = 
4297                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
4298                  model2 = 
4299                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
4300                                         true,preSolve);
4301                  if (model2) {
4302                    printf("Saving presolved model on %s\n",
4303                           fileName.c_str());
4304                    deleteModel2=true;
4305                  } else {
4306                    printf("Presolved model looks infeasible - saving original on %s\n",
4307                           fileName.c_str());
4308                    deleteModel2=false;
4309                    model2 = lpSolver;
4310
4311                  }
4312                  model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
4313                  if (deleteModel2)
4314                    delete model2;
4315                } else {
4316                  printf("Saving model on %s\n",
4317                           fileName.c_str());
4318                  if (numberSOS) {
4319                    // Convert names
4320                    int iRow;
4321                    int numberRows=model2->numberRows();
4322                    int iColumn;
4323                    int numberColumns=model2->numberColumns();
4324                   
4325                    char ** rowNames = NULL;
4326                    char ** columnNames = NULL;
4327                    if (model2->lengthNames()) {
4328                      rowNames = new char * [numberRows];
4329                      for (iRow=0;iRow<numberRows;iRow++) {
4330                        rowNames[iRow] = 
4331                          strdup(model2->rowName(iRow).c_str());
4332                      }
4333                     
4334                      columnNames = new char * [numberColumns];
4335                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
4336                        columnNames[iColumn] = 
4337                          strdup(model2->columnName(iColumn).c_str());
4338                      }
4339                    }
4340                    clpSolver->writeMpsNative(fileName.c_str(),(const char **) rowNames,(const char **) columnNames,
4341                                              (outputFormat-1)/2,1+((outputFormat-1)&1));
4342                    if (rowNames) {
4343                      for (iRow=0;iRow<numberRows;iRow++) {
4344                        free(rowNames[iRow]);
4345                      }
4346                      delete [] rowNames;
4347                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
4348                        free(columnNames[iColumn]);
4349                      }
4350                      delete [] columnNames;
4351                    }
4352                  } else {
4353                    model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
4354                  }
4355                }
4356                time2 = CoinCpuTime();
4357                totalTime += time2-time1;
4358                time1=time2;
4359              }
4360            } else {
4361              std::cout<<"** Current model not valid"<<std::endl;
4362            }
4363            break;
4364          case BASISIN:
4365            if (goodModel) {
4366              // get next field
4367              field = CoinReadGetString(argc,argv);
4368              if (field=="$") {
4369                field = parameters[iParam].stringValue();
4370              } else if (field=="EOL") {
4371                parameters[iParam].printString();
4372                break;
4373              } else {
4374                parameters[iParam].setStringValue(field);
4375              }
4376              std::string fileName;
4377              bool canOpen=false;
4378              if (field=="-") {
4379                // stdin
4380                canOpen=true;
4381                fileName = "-";
4382              } else {
4383                if (field[0]=='/'||field[0]=='\\') {
4384                  fileName = field;
4385                } else if (field[0]=='~') {
4386                  char * environVar = getenv("HOME");
4387                  if (environVar) {
4388                    std::string home(environVar);
4389                    field=field.erase(0,1);
4390                    fileName = home+field;
4391                  } else {
4392                    fileName=field;
4393                  }
4394                } else {
4395                  fileName = directory+field;
4396                }
4397                FILE *fp=fopen(fileName.c_str(),"r");
4398                if (fp) {
4399                  // can open - lets go for it
4400                  fclose(fp);
4401                  canOpen=true;
4402                } else {
4403                  std::cout<<"Unable to open file "<<fileName<<std::endl;
4404                }
4405              }
4406              if (canOpen) {
4407                int values = lpSolver->readBasis(fileName.c_str());
4408                if (values==0)
4409                  basisHasValues=-1;
4410                else
4411                  basisHasValues=1;
4412              }
4413            } else {
4414              std::cout<<"** Current model not valid"<<std::endl;
4415            }
4416            break;
4417          case PRIORITYIN:
4418            if (goodModel) {
4419              // get next field
4420              field = CoinReadGetString(argc,argv);
4421              if (field=="$") {
4422                field = parameters[iParam].stringValue();
4423              } else if (field=="EOL") {
4424                parameters[iParam].printString();
4425                break;
4426              } else {
4427                parameters[iParam].setStringValue(field);
4428              }
4429              std::string fileName;
4430              if (field[0]=='/'||field[0]=='\\') {
4431                fileName = field;
4432              } else if (field[0]=='~') {
4433                char * environVar = getenv("HOME");
4434                if (environVar) {
4435                  std::string home(environVar);
4436                  field=field.erase(0,1);
4437                  fileName = home+field;
4438                } else {
4439                  fileName=field;
4440                }
4441              } else {
4442                fileName = directory+field;
4443              }
4444              FILE *fp=fopen(fileName.c_str(),"r");
4445              if (fp) {
4446                // can open - lets go for it
4447                std::string headings[]={"name","number","direction","priority","up","down",
4448                                        "solution","priin"};
4449                int got[]={-1,-1,-1,-1,-1,-1,-1,-1};
4450                int order[8];
4451                assert(sizeof(got)==sizeof(order));
4452                int nAcross=0;
4453                char line[1000];
4454                int numberColumns = lpSolver->numberColumns();
4455                if (!fgets(line,1000,fp)) {
4456                  std::cout<<"Odd file "<<fileName<<std::endl;
4457                } else {
4458                  char * pos = line;
4459                  char * put = line;
4460                  while (*pos>=' '&&*pos!='\n') {
4461                    if (*pos!=' '&&*pos!='\t') {
4462                      *put=tolower(*pos);
4463                      put++;
4464                    }
4465                    pos++;
4466                  }
4467                  *put='\0';
4468                  pos=line;
4469                  int i;
4470                  bool good=true;
4471                  while (pos) {
4472                    char * comma = strchr(pos,',');
4473                    if (comma)
4474                      *comma='\0';
4475                    for (i=0;i<(int) (sizeof(got)/sizeof(int));i++) {
4476                      if (headings[i]==pos) {
4477                        if (got[i]<0) {
4478                          order[nAcross]=i;
4479                          got[i]=nAcross++;
4480                        } else {
4481                          // duplicate
4482                          good=false;
4483                        }
4484                        break;
4485                      }
4486                    }
4487                    if (i==(int) (sizeof(got)/sizeof(int)))
4488                      good=false;
4489                    if (comma) {
4490                      *comma=',';
4491                      pos=comma+1;
4492                    } else {
4493                      break;
4494                    }
4495                  }
4496                  if (got[0]<0&&got[1]<0)
4497                    good=false;
4498                  if (got[0]>=0&&got[1]>=0)
4499                    good=false;
4500                  if (got[0]>=0&&!lpSolver->lengthNames())
4501                    good=false;
4502                  if (good) {
4503                    char ** columnNames = columnNames = new char * [numberColumns];
4504                    pseudoDown= (double *) malloc(numberColumns*sizeof(double));
4505                    pseudoUp = (double *) malloc(numberColumns*sizeof(double));
4506                    branchDirection = (int *) malloc(numberColumns*sizeof(int));
4507                    priorities= (int *) malloc(numberColumns*sizeof(int));
4508                    free(solutionIn);
4509                    solutionIn=NULL;
4510                    free(prioritiesIn);
4511                    prioritiesIn=NULL;
4512                    int iColumn;
4513                    if (got[6]>=0) {
4514                      solutionIn = (double *) malloc(numberColumns*sizeof(double));
4515                      CoinZeroN(solutionIn,numberColumns);
4516                    }
4517                    if (got[7]>=0) {
4518                      prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
4519                      for (iColumn=0;iColumn<numberColumns;iColumn++) 
4520                        prioritiesIn[iColumn]=10000;
4521                    }
4522                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
4523                      columnNames[iColumn] = 
4524                        strdup(lpSolver->columnName(iColumn).c_str());
4525                      pseudoDown[iColumn]=0.0;
4526                      pseudoUp[iColumn]=0.0;
4527                      branchDirection[iColumn]=0;
4528                      priorities[iColumn]=0;
4529                    }
4530                    int nBadPseudo=0;
4531                    int nBadDir=0;
4532                    int nBadPri=0;
4533                    int nBadName=0;
4534                    int nBadLine=0;
4535                    int nLine=0;
4536                    while (fgets(line,1000,fp)) {
4537                      nLine++;
4538                      iColumn = -1;
4539                      double up =0.0;
4540                      double down=0.0;
4541                      int pri=0;
4542                      int dir=0;
4543                      double solValue=COIN_DBL_MAX;
4544                      int priValue=1000000;
4545                      char * pos = line;
4546                      char * put = line;
4547                      while (*pos>=' '&&*pos!='\n') {
4548                        if (*pos!=' '&&*pos!='\t') {
4549                          *put=tolower(*pos);
4550                          put++;
4551                        }
4552                        pos++;
4553                      }
4554                      *put='\0';
4555                      pos=line;
4556                      for (int i=0;i<nAcross;i++) {
4557                        char * comma = strchr(pos,',');
4558                        if (comma) {
4559                          *comma='\0';
4560                        } else if (i<nAcross-1) {
4561                          nBadLine++;
4562                          break;
4563                        }
4564                        switch (order[i]) {
4565                          // name
4566                        case 0:
4567                          for (iColumn=0;iColumn<numberColumns;iColumn++) {
4568                            if (!strcmp(columnNames[iColumn],pos))
4569                              break;
4570                          }
4571                          if (iColumn==numberColumns)
4572                            iColumn=-1;
4573                          break;
4574                          // number
4575                        case 1:
4576                          iColumn = atoi(pos);
4577                          if (iColumn<0||iColumn>=numberColumns)
4578                            iColumn=-1;
4579                          break;
4580                          // direction
4581                        case 2:
4582                          if (*pos=='D')
4583                            dir=-1;
4584                          else if (*pos=='U')
4585                            dir=1;
4586                          else if (*pos=='N')
4587                            dir=0;
4588                          else if (*pos=='1'&&*(pos+1)=='\0')
4589                            dir=1;
4590                          else if (*pos=='0'&&*(pos+1)=='\0')
4591                            dir=0;
4592                          else if (*pos=='1'&&*(pos+1)=='1'&&*(pos+2)=='\0')
4593                            dir=-1;
4594                          else
4595                            dir=-2; // bad
4596                          break;
4597                          // priority
4598                        case 3:
4599                          pri=atoi(pos);
4600                          break;
4601                          // up
4602                        case 4:
4603                          up = atof(pos);
4604                          break;
4605                          // down
4606                        case 5:
4607                          down = atof(pos);
4608                          break;
4609                          // sol value
4610                        case 6:
4611                          solValue = atof(pos);
4612                          break;
4613                          // priority in value
4614                        case 7:
4615                          priValue = atoi(pos);
4616                          break;
4617                        }
4618                        if (comma) {
4619                          *comma=',';
4620                          pos=comma+1;
4621                        }
4622                      }
4623                      if (iColumn>=0) {
4624                        if (down<0.0) {
4625                          nBadPseudo++;
4626                          down=0.0;
4627                        }
4628                        if (up<0.0) {
4629                          nBadPseudo++;
4630                          up=0.0;
4631                        }
4632                        if (!up)
4633                          up=down;
4634                        if (!down)
4635                          down=up;
4636                        if (dir<-1||dir>1) {
4637                          nBadDir++;
4638                          dir=0;
4639                        }
4640                        if (pri<0) {
4641                          nBadPri++;
4642                          pri=0;
4643                        }
4644                        pseudoDown[iColumn]=down;
4645                        pseudoUp[iColumn]=up;
4646                        branchDirection[iColumn]=dir;
4647                        priorities[iColumn]=pri;
4648                        if (solValue!=COIN_DBL_MAX) {
4649                          assert (solutionIn);
4650                          solutionIn[iColumn]=solValue;
4651                        }
4652                        if (priValue!=1000000) {
4653                          assert (prioritiesIn);
4654                          prioritiesIn[iColumn]=priValue;
4655                        }
4656                      } else {
4657                        nBadName++;
4658                      }
4659                    }
4660                    if (!noPrinting) {
4661                      printf("%d fields and %d records",nAcross,nLine);
4662                      if (nBadPseudo)
4663                        printf(" %d bad pseudo costs",nBadPseudo);
4664                      if (nBadDir)
4665                        printf(" %d bad directions",nBadDir);
4666                      if (nBadPri)
4667                        printf(" %d bad priorities",nBadPri);
4668                      if (nBadName)
4669                        printf(" ** %d records did not match on name/sequence",nBadName);
4670                      printf("\n");
4671                    }
4672                    for (iColumn=0;iColumn<numberColumns;iColumn++) {
4673                      free(columnNames[iColumn]);
4674                    }
4675                    delete [] columnNames;
4676                  } else {
4677                    std::cout<<"Duplicate or unknown keyword - or name/number fields wrong"<<line<<std::endl;
4678                  }
4679                }
4680                fclose(fp);
4681              } else {
4682                std::cout<<"Unable to open file "<<fileName<<std::endl;
4683              }
4684            } else {
4685              std::cout<<"** Current model not valid"<<std::endl;
4686            }
4687            break;
4688          case DEBUG:
4689            if (goodModel) {
4690              delete [] debugValues;
4691              debugValues=NULL;
4692              // get next field
4693              field = CoinReadGetString(argc,argv);
4694              if (field=="$") {
4695                field = parameters[iParam].stringValue();
4696              } else if (field=="EOL") {
4697                parameters[iParam].printString();
4698                break;
4699              } else {
4700                parameters[iParam].setStringValue(field);
4701                debugFile=field;
4702                if (debugFile=="create"||
4703                    debugFile=="createAfterPre") {
4704                  printf("Will create a debug file so this run should be a good one\n");
4705                  break;
4706                }
4707              }
4708              std::string fileName;
4709              if (field[0]=='/'||field[0]=='\\') {
4710                fileName = field;
4711              } else if (field[0]=='~') {
4712                char * environVar = getenv("HOME");
4713                if (environVar) {
4714                  std::string home(environVar);
4715                  field=field.erase(0,1);
4716                  fileName = home+field;
4717                } else {
4718                  fileName=field;
4719                }
4720              } else {
4721                fileName = directory+field;
4722              }
4723              FILE *fp=fopen(fileName.c_str(),"rb");
4724              if (fp) {
4725                // can open - lets go for it
4726                int numRows;
4727                double obj;
4728                fread(&numRows,sizeof(int),1,fp);
4729                fread(&numberDebugValues,sizeof(int),1,fp);
4730                fread(&obj,sizeof(double),1,fp);
4731                debugValues = new double[numberDebugValues+numRows];
4732                fread(debugValues,sizeof(double),numRows,fp);
4733                fread(debugValues,sizeof(double),numRows,fp);
4734                fread(debugValues,sizeof(double),numberDebugValues,fp);
4735                printf("%d doubles read into debugValues\n",numberDebugValues);
4736                fclose(fp);
4737              } else {
4738                std::cout<<"Unable to open file "<<fileName<<std::endl;
4739              }
4740            } else {
4741              std::cout<<"** Current model not valid"<<std::endl;
4742            }
4743            break;
4744          case PRINTMASK:
4745            // get next field
4746            {
4747              std::string name = CoinReadGetString(argc,argv);
4748              if (name!="EOL") {
4749                parameters[iParam].setStringValue(name);
4750                printMask = name;
4751              } else {
4752                parameters[iParam].printString();
4753              }
4754            }
4755            break;
4756          case BASISOUT:
4757            if (goodModel) {
4758              // get next field
4759              field = CoinReadGetString(argc,argv);
4760              if (field=="$") {
4761                field = parameters[iParam].stringValue();
4762              } else if (field=="EOL") {
4763                parameters[iParam].printString();
4764                break;
4765              } else {
4766                parameters[iParam].setStringValue(field);
4767              }
4768              std::string fileName;
4769              bool canOpen=false;
4770              if (field[0]=='/'||field[0]=='\\') {
4771                fileName = field;
4772              } else if (field[0]=='~') {
4773                char * environVar = getenv("HOME");
4774                if (environVar) {
4775                  std::string home(environVar);
4776                  field=field.erase(0,1);
4777                  fileName = home+field;
4778                } else {
4779                  fileName=field;
4780                }
4781              } else {
4782                fileName = directory+field;
4783              }
4784              FILE *fp=fopen(fileName.c_str(),"w");
4785              if (fp) {
4786                // can open - lets go for it
4787                fclose(fp);
4788                canOpen=true;
4789              } else {
4790                std::cout<<"Unable to open file "<<fileName<<std::endl;
4791              }
4792              if (canOpen) {
4793                ClpSimplex * model2 = lpSolver;
4794                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
4795                time2 = CoinCpuTime();
4796                totalTime += time2-time1;
4797                time1=time2;
4798              }
4799            } else {
4800              std::cout<<"** Current model not valid"<<std::endl;
4801            }
4802            break;
4803          case SAVE:
4804            {
4805              // get next field
4806              field = CoinReadGetString(argc,argv);
4807              if (field=="$") {
4808                field = parameters[iParam].stringValue();
4809              } else if (field=="EOL") {
4810                parameters[iParam].printString();
4811                break;
4812              } else {
4813                parameters[iParam].setStringValue(field);
4814              }
4815              std::string fileName;
4816              bool canOpen=false;
4817              if (field[0]=='/'||field[0]=='\\') {
4818                fileName = field;
4819              } else if (field[0]=='~') {
4820                char * environVar = getenv("HOME");
4821                if (environVar) {
4822                  std::string home(environVar);
4823                  field=field.erase(0,1);
4824                  fileName = home+field;
4825                } else {
4826                  fileName=field;
4827                }
4828              } else {
4829                fileName = directory+field;
4830              }
4831              FILE *fp=fopen(fileName.c_str(),"wb");
4832              if (fp) {
4833                // can open - lets go for it
4834                fclose(fp);
4835                canOpen=true;
4836              } else {
4837                std::cout<<"Unable to open file "<<fileName<<std::endl;
4838              }
4839              if (canOpen) {
4840                int status;
4841                // If presolve on then save presolved
4842                bool deleteModel2=false;
4843                ClpSimplex * model2 = lpSolver;
4844                if (preSolve) {
4845                  ClpPresolve pinfo;
4846                  double presolveTolerance = 
4847                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
4848                  model2 = 
4849                    pinfo.presolvedModel(*lpSolver,presolveTolerance,
4850                                         false,preSolve);
4851                  if (model2) {
4852                    printf("Saving presolved model on %s\n",
4853                           fileName.c_str());
4854                    deleteModel2=true;
4855                  } else {
4856                    printf("Presolved model looks infeasible - saving original on %s\n",
4857                           fileName.c_str());
4858                    deleteModel2=false;
4859                    model2 = lpSolver;
4860
4861                  }
4862                } else {
4863                  printf("Saving model on %s\n",
4864                           fileName.c_str());
4865                }
4866                status =model2->saveModel(fileName.c_str());
4867                if (deleteModel2)
4868                  delete model2;
4869                if (!status) {
4870                  goodModel=true;
4871                  time2 = CoinCpuTime();
4872                  totalTime += time2-time1;
4873                  time1=time2;
4874                } else {
4875                  // errors
4876                  std::cout<<"There were errors on output"<<std::endl;
4877                }
4878              }
4879            }
4880            break;
4881          case RESTORE:
4882            {
4883              // get next field
4884              field = CoinReadGetString(argc,argv);
4885              if (field=="$") {
4886                field = parameters[iParam].stringValue();
4887              } else if (field=="EOL") {
4888                parameters[iParam].printString();
4889                break;
4890              } else {
4891                parameters[iParam].setStringValue(field);
4892              }
4893              std::string fileName;
4894              bool canOpen=false;
4895              if (field[0]=='/'||field[0]=='\\') {
4896                fileName = field;
4897              } else if (field[0]=='~') {
4898                char * environVar = getenv("HOME");
4899                if (environVar) {
4900                  std::string home(environVar);
4901                  field=field.erase(0,1);
4902                  fileName = home+field;
4903                } else {
4904                  fileName=field;
4905                }
4906              } else {
4907                fileName = directory+field;
4908              }
4909              FILE *fp=fopen(fileName.c_str(),"rb");
4910              if (fp) {
4911                // can open - lets go for it
4912                fclose(fp);
4913                canOpen=true;
4914              } else {
4915                std::cout<<"Unable to open file "<<fileName<<std::endl;
4916              }
4917              if (canOpen) {
4918                int status =lpSolver->restoreModel(fileName.c_str());
4919                if (!status) {
4920                  goodModel=true;
4921                  time2 = CoinCpuTime();
4922                  totalTime += time2-time1;
4923                  time1=time2;
4924                } else {
4925                  // errors
4926                  std::cout<<"There were errors on input"<<std::endl;
4927                }
4928              }
4929            }
4930            break;
4931          case MAXIMIZE:
4932            lpSolver->setOptimizationDirection(-1);
4933            break;
4934          case MINIMIZE:
4935            lpSolver->setOptimizationDirection(1);
4936            break;
4937          case ALLSLACK:
4938            lpSolver->allSlackBasis(true);
4939            break;
4940          case REVERSE:
4941            if (goodModel) {
4942              int iColumn;
4943              int numberColumns=lpSolver->numberColumns();
4944              double * dualColumnSolution = 
4945                lpSolver->dualColumnSolution();
4946              ClpObjective * obj = lpSolver->objectiveAsObject();
4947              assert(dynamic_cast<ClpLinearObjective *> (obj));
4948              double offset;
4949              double * objective = obj->gradient(NULL,NULL,offset,true);
4950              for (iColumn=0;iColumn<numberColumns;iColumn++) {
4951                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
4952                objective[iColumn] = -objective[iColumn];
4953              }
4954              int iRow;
4955              int numberRows=lpSolver->numberRows();
4956              double * dualRowSolution = 
4957                lpSolver->dualRowSolution();
4958              for (iRow=0;iRow<numberRows;iRow++) 
4959                dualRowSolution[iRow] = dualRowSolution[iRow];
4960            }
4961            break;
4962          case DIRECTORY:
4963            {
4964              std::string name = CoinReadGetString(argc,argv);
4965              if (name!="EOL") {
4966                int length=name.length();
4967                if (name[length-1]=='/'||name[length-1]=='\\')
4968                  directory=name;
4969                else
4970                  directory = name+"/";
4971                parameters[iParam].setStringValue(directory);
4972              } else {
4973                parameters[iParam].printString();
4974              }
4975            }
4976            break;
4977          case STDIN:
4978            CbcOrClpRead_mode=-1;
4979            break;
4980          case NETLIB_DUAL:
4981          case NETLIB_EITHER:
4982          case NETLIB_BARRIER:
4983          case NETLIB_PRIMAL:
4984          case NETLIB_TUNE:
4985            {
4986              // create fields for unitTest
4987              const char * fields[4];
4988              int nFields=2;
4989              fields[0]="fake main from unitTest";
4990              fields[1]="-netlib";
4991              if (directory!=defaultDirectory) {
4992                fields[2]="-netlibDir";
4993                fields[3]=directory.c_str();
4994                nFields=4;
4995              }
4996              int algorithm;
4997              if (type==NETLIB_DUAL) {
4998                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
4999                algorithm =0;
5000              } else if (type==NETLIB_BARRIER) {
5001                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
5002                algorithm =2;
5003              } else if (type==NETLIB_EITHER) {
5004                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
5005                algorithm =3;
5006              } else if (type==NETLIB_TUNE) {
5007                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
5008                algorithm =5;
5009                // uncomment next to get active tuning
5010                // algorithm=6;
5011              } else {
5012                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
5013                algorithm=1;
5014              }
5015              int specialOptions = lpSolver->specialOptions();
5016              lpSolver->setSpecialOptions(0);
5017              mainTest(nFields,fields,algorithm,*lpSolver,
5018                       (preSolve!=0),specialOptions,doVector!=0);
5019            }
5020            break;
5021          case UNITTEST:
5022            {
5023              // create fields for unitTest
5024              const char * fields[3];
5025              int nFields=1;
5026              fields[0]="fake main from unitTest";
5027              if (directory!=defaultDirectory) {
5028                fields[1]="-mpsDir";
5029                fields[2]=directory.c_str();
5030                nFields=3;
5031              }
5032              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
5033                       false,doVector!=0);
5034            }
5035            break;
5036          case FAKEBOUND:
5037            if (goodModel) {
5038              // get bound
5039              double value = CoinReadGetDoubleField(argc,argv,&valid);
5040              if (!valid) {
5041                std::cout<<"Setting "<<parameters[iParam].name()<<
5042                  " to DEBUG "<<value<<std::endl;
5043                int iRow;
5044                int numberRows=lpSolver->numberRows();
5045                double * rowLower = lpSolver->rowLower();
5046                double * rowUpper = lpSolver->rowUpper();
5047                for (iRow=0;iRow<numberRows;iRow++) {
5048                  // leave free ones for now
5049                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
5050                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
5051                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
5052                  }
5053