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

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

for nonlinear

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