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

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

fix ampl ifdef

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