source: trunk/Test/CoinSolve.cpp @ 199

Last change on this file since 199 was 199, checked in by forrest, 16 years ago

more stuff

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 77.5 KB
Line 
1// Copyright (C) 2004, International Business Machines
2// Corporation and others.  All Rights Reserved.
3   
4#include "CoinPragma.hpp"
5
6#include <cassert>
7#include <cstdio>
8#include <cmath>
9#include <cfloat>
10#include <string>
11#include <iostream>
12
13
14#include "CoinPragma.hpp"
15#include "CoinHelperFunctions.hpp"
16// Same version as CBC
17#define CBCVERSION "0.99"
18
19#include "CoinMpsIO.hpp"
20
21#include "ClpFactorization.hpp"
22#include "CoinTime.hpp"
23#include "ClpSimplex.hpp"
24#include "ClpSolve.hpp"
25#include "ClpPackedMatrix.hpp"
26#include "ClpPlusMinusOneMatrix.hpp"
27#include "ClpNetworkMatrix.hpp"
28#include "ClpDualRowSteepest.hpp"
29#include "ClpDualRowDantzig.hpp"
30#include "ClpLinearObjective.hpp"
31#include "ClpPrimalColumnSteepest.hpp"
32#include "ClpPrimalColumnDantzig.hpp"
33#include "ClpPresolve.hpp"
34#include "CbcOrClpParam.hpp"
35#include "OsiRowCutDebugger.hpp"
36#ifdef DMALLOC
37#include "dmalloc.h"
38#endif
39#ifdef WSSMP_BARRIER
40#define FOREIGN_BARRIER
41#endif
42#ifdef UFL_BARRIER
43#define FOREIGN_BARRIER
44#endif
45#ifdef TAUCS_BARRIER
46#define FOREIGN_BARRIER
47#endif
48#include "CoinWarmStartBasis.hpp"
49
50#include "OsiSolverInterface.hpp"
51#include "OsiCuts.hpp"
52#include "OsiRowCut.hpp"
53#include "OsiColCut.hpp"
54
55#include "CglPreProcess.hpp"
56#include "CglCutGenerator.hpp"
57#include "CglGomory.hpp"
58#include "CglProbing.hpp"
59#include "CglKnapsackCover.hpp"
60#include "CglRedSplit.hpp"
61#include "CglClique.hpp"
62#include "CglFlowCover.hpp"
63#include "CglMixedIntegerRounding2.hpp"
64#include "CglTwomir.hpp"
65
66#include "CbcModel.hpp"
67#include "CbcHeuristic.hpp"
68#include "CbcHeuristicLocal.hpp"
69#include "CbcHeuristicGreedy.hpp"
70#include "CbcHeuristicFPump.hpp"
71#include "CbcTreeLocal.hpp"
72#include "CbcCompareActual.hpp"
73#include  "CbcOrClpParam.hpp"
74#include  "CbcCutGenerator.hpp"
75
76#include "OsiClpSolverInterface.hpp"
77
78static double totalTime=0.0;
79
80//#############################################################################
81
82#ifdef NDEBUG
83#undef NDEBUG
84#endif
85// Allow for interrupts
86// But is this threadsafe ? (so switched off by option)
87
88#include "CoinSignal.hpp"
89static CbcModel * currentBranchModel = NULL;
90
91extern "C" {
92   static void signal_handler(int whichSignal)
93   {
94      if (currentBranchModel!=NULL) 
95         currentBranchModel->setMaximumNodes(0); // stop at next node
96      return;
97   }
98}
99
100int mainTest (int argc, const char *argv[],int algorithm,
101              ClpSimplex empty, bool doPresolve,int doIdiot);
102// Returns next valid field
103int CbcOrClpRead_mode=1;
104FILE * CbcOrClpReadCommand=stdin;
105static int * analyze(OsiClpSolverInterface * solver, int & numberChanged)
106{
107  //const double *objective = solver->getObjCoefficients() ;
108  const double *lower = solver->getColLower() ;
109  const double *upper = solver->getColUpper() ;
110  int numberColumns = solver->getNumCols() ;
111  int numberRows = solver->getNumRows();
112  //double direction = solver->getObjSense();
113  int iRow,iColumn;
114
115  // Row copy
116  CoinPackedMatrix matrixByRow(*solver->getMatrixByRow());
117  const double * elementByRow = matrixByRow.getElements();
118  const int * column = matrixByRow.getIndices();
119  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
120  const int * rowLength = matrixByRow.getVectorLengths();
121
122  // Column copy
123  CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
124  //const double * element = matrixByCol.getElements();
125  const int * row = matrixByCol.getIndices();
126  const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
127  const int * columnLength = matrixByCol.getVectorLengths();
128
129  const double * rowLower = solver->getRowLower();
130  const double * rowUpper = solver->getRowUpper();
131
132  char * ignore = new char [numberRows];
133  int * changed = new int[numberColumns];
134  memset(ignore,0,numberRows);
135  numberChanged=0;
136  int numberInteger=0;
137  for (iColumn=0;iColumn<numberColumns;iColumn++) {
138    if (upper[iColumn] > lower[iColumn]+1.0e-8&&solver->isInteger(iColumn)) 
139      numberInteger++;
140  }
141  for (iRow=0;iRow<numberRows;iRow++) {
142    int numberContinuous=0;
143    double value1=0.0,value2=0.0;
144    bool allIntegerCoeff=true;
145    double sumFixed=0.0;
146    int jColumn1=-1,jColumn2=-1;
147    for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
148      int jColumn = column[j];
149      double value = elementByRow[j];
150      if (upper[jColumn] > lower[jColumn]+1.0e-8) {
151        if (!solver->isInteger(jColumn)) {
152          if (numberContinuous==0) {
153            jColumn1=jColumn;
154            value1=value;
155          } else {
156            jColumn2=jColumn;
157            value2=value;
158          }
159          numberContinuous++;
160        } else {
161          if (fabs(value-floor(value+0.5))>1.0e-12)
162            allIntegerCoeff=false;
163        }
164      } else {
165        sumFixed += lower[jColumn]*value;
166      }
167    }
168    double low = rowLower[iRow];
169    if (low>-1.0e20) {
170      low -= sumFixed;
171      if (fabs(low-floor(low+0.5))>1.0e-12)
172        allIntegerCoeff=false;
173    }
174    double up = rowUpper[iRow];
175    if (up<1.0e20) {
176      up -= sumFixed;
177      if (fabs(up-floor(up+0.5))>1.0e-12)
178        allIntegerCoeff=false;
179    }
180    if (numberContinuous==1) {
181      // see if really integer
182      // This does not allow for complicated cases
183      if (low==up) {
184        if (fabs(value1)>1.0e-3) {
185          value1 = 1.0/value1;
186          if (fabs(value1-floor(value1+0.5))<1.0e-12) {
187            // integer
188            changed[numberChanged++]=jColumn1;
189            solver->setInteger(jColumn1);
190            if (upper[jColumn1]>1.0e20)
191              solver->setColUpper(jColumn1,1.0e20);
192            if (lower[jColumn1]<-1.0e20)
193              solver->setColLower(jColumn1,-1.0e20);
194          }
195        }
196      } else {
197        if (fabs(value1)>1.0e-3) {
198          value1 = 1.0/value1;
199          if (fabs(value1-floor(value1+0.5))<1.0e-12) {
200            // This constraint will not stop it being integer
201            ignore[iRow]=1;
202          }
203        }
204      }
205    } else if (numberContinuous==2) {
206      if (low==up) {
207      }
208    }
209  }
210  for (iColumn=0;iColumn<numberColumns;iColumn++) {
211    if (upper[iColumn] > lower[iColumn]+1.0e-8&&!solver->isInteger(iColumn)) {
212      double value;
213      value = upper[iColumn];
214      if (value<1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
215        continue;
216      value = lower[iColumn];
217      if (value>-1.0e20&&fabs(value-floor(value+0.5))>1.0e-12) 
218        continue;
219      bool integer=true;
220      for (CoinBigIndex j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn];j++) {
221        int iRow = row[j];
222        if (!ignore[iRow]) {
223          integer=false;
224          break;
225        }
226      }
227      if (integer) {
228        // integer
229        changed[numberChanged++]=iColumn;
230        solver->setInteger(iColumn);
231        if (upper[iColumn]>1.0e20)
232          solver->setColUpper(iColumn,1.0e20);
233        if (lower[iColumn]<-1.0e20)
234          solver->setColLower(iColumn,-1.0e20);
235      }
236    }
237  }
238  if (numberInteger)
239    printf("%d integer variables",numberInteger);
240  if (numberChanged)
241    printf(" and %d variables made integer\n",numberChanged);
242  else
243    printf("\n");
244  delete [] ignore;
245  if (!numberChanged) {
246    delete [] changed;
247    return NULL;
248  } else {
249    return changed;
250  }
251}
252int main (int argc, const char *argv[])
253{
254  /* Note
255     This is meant as a stand-alone executable to do as much of coin as possible.
256     It should only have one solver known to it.
257  */
258  {
259    double time1 = CoinCpuTime(),time2;
260    CoinSighandler_t saveSignal=SIG_DFL;
261    // register signal handler
262    saveSignal = signal(SIGINT,signal_handler);
263    // Set up all non-standard stuff
264    OsiClpSolverInterface solver1;
265    CbcModel model(solver1);
266    CbcModel * babModel = NULL;
267    model.setNumberBeforeTrust(5);
268    int cutPass=-1234567;
269    OsiSolverInterface * solver = model.solver();
270    OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
271    ClpSimplex * lpSolver = clpSolver->getModelPtr();
272    clpSolver->messageHandler()->setLogLevel(0) ;
273    model.messageHandler()->setLogLevel(1);
274   
275   
276    // default action on import
277    int allowImportErrors=0;
278    int keepImportNames=1;
279    int doIdiot=-1;
280    int outputFormat=2;
281    int slpValue=-1;
282    int printOptions=0;
283    int printMode=0;
284    int presolveOptions=0;
285    int doCrash=0;
286    int doSprint=-1;
287    int doScaling=1;
288    // set reasonable defaults
289    int preSolve=5;
290    int preProcess=1;
291    bool preSolveFile=false;
292   
293    double djFix=1.0e100;
294    double gapRatio=1.0e100;
295    double tightenFactor=0.0;
296    lpSolver->setPerturbation(50);
297    lpSolver->messageHandler()->setPrefix(false);
298    const char dirsep =  CoinFindDirSeparator();
299    std::string directory = (dirsep == '/' ? "./" : ".\\");
300    std::string defaultDirectory = directory;
301    std::string importFile ="";
302    std::string exportFile ="default.mps";
303    std::string importBasisFile ="";
304    std::string debugFile="";
305    double * debugValues = NULL;
306    int numberDebugValues = -1;
307    int basisHasValues=0;
308    std::string exportBasisFile ="default.bas";
309    std::string saveFile ="default.prob";
310    std::string restoreFile ="default.prob";
311    std::string solutionFile ="stdout";
312    std::string solutionSaveFile ="solution.file";
313#define CBCMAXPARAMETERS 200
314    CbcOrClpParam parameters[CBCMAXPARAMETERS];
315    int numberParameters ;
316    establishParams(numberParameters,parameters) ;
317    parameters[whichParam(BASISIN,numberParameters,parameters)].setStringValue(importBasisFile);
318    parameters[whichParam(BASISOUT,numberParameters,parameters)].setStringValue(exportBasisFile);
319    parameters[whichParam(DEBUG,numberParameters,parameters)].setStringValue(debugFile);
320    parameters[whichParam(DIRECTORY,numberParameters,parameters)].setStringValue(directory);
321    parameters[whichParam(DUALBOUND,numberParameters,parameters)].setDoubleValue(lpSolver->dualBound());
322    parameters[whichParam(DUALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->dualTolerance());
323    parameters[whichParam(EXPORT,numberParameters,parameters)].setStringValue(exportFile);
324    parameters[whichParam(IDIOT,numberParameters,parameters)].setIntValue(doIdiot);
325    parameters[whichParam(IMPORT,numberParameters,parameters)].setStringValue(importFile);
326    int slog = whichParam(SOLVERLOGLEVEL,numberParameters,parameters);
327    int log = whichParam(LOGLEVEL,numberParameters,parameters);
328    parameters[slog].setIntValue(0);
329    parameters[log].setIntValue(1);
330    parameters[whichParam(MAXFACTOR,numberParameters,parameters)].setIntValue(lpSolver->factorizationFrequency());
331    parameters[whichParam(MAXITERATION,numberParameters,parameters)].setIntValue(lpSolver->maximumIterations());
332    parameters[whichParam(OUTPUTFORMAT,numberParameters,parameters)].setIntValue(outputFormat);
333    parameters[whichParam(PRESOLVEPASS,numberParameters,parameters)].setIntValue(preSolve);
334    parameters[whichParam(PERTVALUE,numberParameters,parameters)].setIntValue(lpSolver->perturbation());
335    parameters[whichParam(PRIMALTOLERANCE,numberParameters,parameters)].setDoubleValue(lpSolver->primalTolerance());
336    parameters[whichParam(PRIMALWEIGHT,numberParameters,parameters)].setDoubleValue(lpSolver->infeasibilityCost());
337    parameters[whichParam(RESTORE,numberParameters,parameters)].setStringValue(restoreFile);
338    parameters[whichParam(SAVE,numberParameters,parameters)].setStringValue(saveFile);
339    //parameters[whichParam(TIMELIMIT,numberParameters,parameters)].setDoubleValue(1.0e8);
340    parameters[whichParam(TIMELIMIT_BAB,numberParameters,parameters)].setDoubleValue(1.0e8);
341    parameters[whichParam(SOLUTION,numberParameters,parameters)].setStringValue(solutionFile);
342    parameters[whichParam(SAVESOL,numberParameters,parameters)].setStringValue(solutionSaveFile);
343    parameters[whichParam(SPRINT,numberParameters,parameters)].setIntValue(doSprint);
344    model.setNumberBeforeTrust(5);
345    parameters[whichParam(NUMBERBEFORE,numberParameters,parameters)].setIntValue(5);
346    parameters[whichParam(MAXNODES,numberParameters,parameters)].setIntValue(model.getMaximumNodes());
347    model.setNumberStrong(10);
348    parameters[whichParam(STRONGBRANCHING,numberParameters,parameters)].setIntValue(model.numberStrong());
349    parameters[whichParam(INFEASIBILITYWEIGHT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcInfeasibilityWeight));
350    parameters[whichParam(INTEGERTOLERANCE,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcIntegerTolerance));
351    parameters[whichParam(INCREMENT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcCutoffIncrement));
352    // Set up likely cut generators and defaults
353    parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("on");
354
355    CglGomory gomoryGen;
356    // try larger limit
357    gomoryGen.setLimitAtRoot(500);
358    gomoryGen.setLimit(100);
359    // set default action (0=off,1=on,2=root)
360    int gomoryAction=3;
361    parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
362
363    CglProbing probingGen;
364    probingGen.setUsingObjective(true);
365    probingGen.setMaxPass(3);
366    probingGen.setMaxPassRoot(3);
367    // Number of unsatisfied variables to look at
368    probingGen.setMaxProbe(10);
369    probingGen.setMaxProbeRoot(50);
370    // How far to follow the consequences
371    probingGen.setMaxLook(10);
372    probingGen.setMaxLookRoot(50);
373    probingGen.setMaxLookRoot(10);
374    // Only look at rows with fewer than this number of elements
375    probingGen.setMaxElements(200);
376    probingGen.setRowCuts(3);
377    // set default action (0=off,1=on,2=root)
378    int probingAction=3;
379    parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
380
381    CglKnapsackCover knapsackGen;
382    // set default action (0=off,1=on,2=root)
383    int knapsackAction=3;
384    parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
385
386    CglRedSplit redsplitGen;
387    redsplitGen.setLimit(100);
388    // set default action (0=off,1=on,2=root)
389    // Off as seems to give some bad cuts
390    int redsplitAction=2;
391    parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption("root");
392
393    CglClique cliqueGen(false,true);
394    cliqueGen.setStarCliqueReport(false);
395    cliqueGen.setRowCliqueReport(false);
396    cliqueGen.setMinViolation(0.1);
397    // set default action (0=off,1=on,2=root)
398    int cliqueAction=3;
399    parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption("ifmove");
400
401    CglMixedIntegerRounding2 mixedGen;
402    // set default action (0=off,1=on,2=root)
403    int mixedAction=3;
404    parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
405
406    CglFlowCover flowGen;
407    // set default action (0=off,1=on,2=root)
408    int flowAction=3;
409    parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
410
411    CglTwomir twomirGen;
412    // set default action (0=off,1=on,2=root)
413    int twomirAction=2;
414    parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption("root");
415
416    bool useRounding=true;
417    parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption("on");
418    bool useFpump=true;
419    bool useGreedy=true;
420    parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption("on");
421    bool useCombine=true;
422    parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption("on");
423    bool useLocalTree=false;
424   
425    // total number of commands read
426    int numberGoodCommands=0;
427    bool goodModel=false;
428    // Set false if user does anything advanced
429    bool defaultSettings=true;
430
431    // Hidden stuff for barrier
432    int choleskyType = 0;
433    int gamma=0;
434    int scaleBarrier=0;
435    int doKKT=0;
436    int crossover=2; // do crossover unless quadratic
437    // For names
438    int lengthName = 0;
439    std::vector<std::string> rowNames;
440    std::vector<std::string> columnNames;
441   
442    std::string field;
443    std::cout<<"Coin Cbc and Clp Solver version "<<CBCVERSION
444             <<", build "<<__DATE__<<std::endl;
445   
446    while (1) {
447      // next command
448      field=CoinReadGetCommand(argc,argv);
449     
450      // exit if null or similar
451      if (!field.length()) {
452        if (numberGoodCommands==1&&goodModel) {
453          // we just had file name - do branch and bound
454          field="branch";
455        } else if (!numberGoodCommands) {
456          // let's give the sucker a hint
457          std::cout
458            <<"CoinSolver takes input from arguments ( - switches to stdin)"
459            <<std::endl
460            <<"Enter ? for list of commands or help"<<std::endl;
461          field="-";
462        } else {
463          break;
464        }
465      }
466     
467      // see if ? at end
468      int numberQuery=0;
469      if (field!="?"&&field!="???") {
470        int length = field.length();
471        int i;
472        for (i=length-1;i>0;i--) {
473          if (field[i]=='?') 
474            numberQuery++;
475          else
476            break;
477        }
478        field=field.substr(0,length-numberQuery);
479      }
480      // find out if valid command
481      int iParam;
482      int numberMatches=0;
483      int firstMatch=-1;
484      for ( iParam=0; iParam<numberParameters; iParam++ ) {
485        int match = parameters[iParam].matches(field);
486        if (match==1) {
487          numberMatches = 1;
488          firstMatch=iParam;
489          break;
490        } else {
491          if (match&&firstMatch<0)
492            firstMatch=iParam;
493          numberMatches += match>>1;
494        }
495      }
496      if (iParam<numberParameters&&!numberQuery) {
497        // found
498        CbcOrClpParam found = parameters[iParam];
499        CbcOrClpParameterType type = found.type();
500        int valid;
501        numberGoodCommands++;
502        if (type==BAB&&goodModel) {
503          // check if any integers
504          if (!lpSolver->integerInformation())
505            type=DUALSIMPLEX;
506        }
507        if (type==GENERALQUERY) {
508          std::cout<<"In argument list keywords have leading - "
509            ", -stdin or just - switches to stdin"<<std::endl;
510          std::cout<<"One command per line (and no -)"<<std::endl;
511          std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
512          std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
513          std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
514          std::cout<<"abcd value sets value"<<std::endl;
515          std::cout<<"Commands are:"<<std::endl;
516          int maxAcross=5;
517          int limits[]={1,51,101,151,201,251,301,351,401};
518          std::vector<std::string> types;
519          types.push_back("Double parameters:");
520          types.push_back("Branch and Cut double parameters:");
521          types.push_back("Integer parameters:");
522          types.push_back("Branch and Cut integer parameters:");
523          types.push_back("Keyword parameters and others:");
524          types.push_back("Branch and Cut keyword parameters and others:");
525          types.push_back("Actions:");
526          types.push_back("Branch and Cut actions:");
527          int iType;
528          for (iType=0;iType<8;iType++) {
529            int across=0;
530            std::cout<<types[iType]<<"   ";
531            for ( iParam=0; iParam<numberParameters; iParam++ ) {
532              int type = parameters[iParam].type();
533              if (parameters[iParam].displayThis()&&type>=limits[iType]
534                  &&type<limits[iType+1]) {
535                if (!across)
536                  std::cout<<"  ";
537                std::cout<<parameters[iParam].matchName()<<"  ";
538                across++;
539                if (across==maxAcross) {
540                  std::cout<<std::endl;
541                  across=0;
542                }
543              }
544            }
545            if (across)
546              std::cout<<std::endl;
547          }
548        } else if (type==FULLGENERALQUERY) {
549          std::cout<<"Full list of commands is:"<<std::endl;
550          int maxAcross=5;
551          int limits[]={1,51,101,151,201,251,301,351,401};
552          std::vector<std::string> types;
553          types.push_back("Double parameters:");
554          types.push_back("Branch and Cut double parameters:");
555          types.push_back("Integer parameters:");
556          types.push_back("Branch and Cut integer parameters:");
557          types.push_back("Keyword parameters and others:");
558          types.push_back("Branch and Cut keyword parameters and others:");
559          types.push_back("Actions:");
560          types.push_back("Branch and Cut actions:");
561          int iType;
562          for (iType=0;iType<8;iType++) {
563            int across=0;
564            std::cout<<types[iType]<<"  ";
565            for ( iParam=0; iParam<numberParameters; iParam++ ) {
566              int type = parameters[iParam].type();
567              if (type>=limits[iType]
568                  &&type<limits[iType+1]) {
569                if (!across)
570                  std::cout<<"  ";
571                std::cout<<parameters[iParam].matchName()<<"  ";
572                across++;
573                if (across==maxAcross) {
574                  std::cout<<std::endl;
575                  across=0;
576                }
577              }
578            }
579            if (across)
580              std::cout<<std::endl;
581          }
582        } else if (type<101) {
583          // get next field as double
584          double value = CoinReadGetDoubleField(argc,argv,&valid);
585          if (!valid) {
586            parameters[iParam].setDoubleValue(value);
587            if (type<51) {
588              parameters[iParam].setDoubleParameter(lpSolver,value);
589            } else if (type<81) {
590              parameters[iParam].setDoubleParameter(model,value);
591            } else {
592              switch(type) {
593              case DJFIX:
594                djFix=value;
595                preSolve=5;
596                defaultSettings=false; // user knows what she is doing
597                break;
598              case GAPRATIO:
599                gapRatio=value;
600                break;
601              case TIGHTENFACTOR:
602                tightenFactor=value;
603                defaultSettings=false; // user knows what she is doing
604                break;
605              default:
606                abort();
607              }
608            }
609          } else if (valid==1) {
610            abort();
611          } else {
612            std::cout<<parameters[iParam].name()<<" has value "<<
613              parameters[iParam].doubleValue()<<std::endl;
614          }
615        } else if (type<201) {
616          // get next field as int
617          int value = CoinReadGetIntField(argc,argv,&valid);
618          if (!valid) {
619            parameters[iParam].setIntValue(value);
620            if (type<151) {
621              if (parameters[iParam].type()==PRESOLVEPASS)
622                preSolve = value;
623              else if (parameters[iParam].type()==IDIOT)
624                doIdiot = value;
625              else if (parameters[iParam].type()==SPRINT)
626                doSprint = value;
627              else if (parameters[iParam].type()==OUTPUTFORMAT)
628                outputFormat = value;
629              else if (parameters[iParam].type()==SLPVALUE)
630                slpValue = value;
631              else if (parameters[iParam].type()==PRESOLVEOPTIONS)
632                presolveOptions = value;
633              else if (parameters[iParam].type()==PRINTOPTIONS)
634                printOptions = value;
635              else if (parameters[iParam].type()==CUTPASS)
636                cutPass = value;
637              else if (parameters[iParam].type()==FPUMPITS)
638                { useFpump = true;parameters[iParam].setIntValue(value);}
639              else
640                parameters[iParam].setIntParameter(lpSolver,value);
641            } else {
642              parameters[iParam].setIntParameter(model,value);
643            }
644          } else if (valid==1) {
645            abort();
646          } else {
647            std::cout<<parameters[iParam].name()<<" has value "<<
648              parameters[iParam].intValue()<<std::endl;
649          }
650        } else if (type<301) {
651          // one of several strings
652          std::string value = CoinReadGetString(argc,argv);
653          int action = parameters[iParam].parameterOption(value);
654          if (action<0) {
655            if (value!="EOL") {
656              // no match
657              parameters[iParam].printOptions();
658            } else {
659              // print current value
660              std::cout<<parameters[iParam].name()<<" has value "<<
661                parameters[iParam].currentOption()<<std::endl;
662            }
663          } else {
664            parameters[iParam].setCurrentOption(action);
665            // for now hard wired
666            switch (type) {
667            case DIRECTION:
668              if (action==0)
669                lpSolver->setOptimizationDirection(1);
670              else if (action==1)
671                lpSolver->setOptimizationDirection(-1);
672              else
673                lpSolver->setOptimizationDirection(0);
674              break;
675            case DUALPIVOT:
676              if (action==0) {
677                ClpDualRowSteepest steep(3);
678                lpSolver->setDualRowPivotAlgorithm(steep);
679              } else if (action==1) {
680                //ClpDualRowDantzig dantzig;
681                ClpDualRowSteepest dantzig(5);
682                lpSolver->setDualRowPivotAlgorithm(dantzig);
683              } else if (action==2) {
684                // partial steep
685                ClpDualRowSteepest steep(2);
686                lpSolver->setDualRowPivotAlgorithm(steep);
687              } else {
688                ClpDualRowSteepest steep;
689                lpSolver->setDualRowPivotAlgorithm(steep);
690              }
691              break;
692            case PRIMALPIVOT:
693              if (action==0) {
694                ClpPrimalColumnSteepest steep(3);
695                lpSolver->setPrimalColumnPivotAlgorithm(steep);
696              } else if (action==1) {
697                ClpPrimalColumnSteepest steep(0);
698                lpSolver->setPrimalColumnPivotAlgorithm(steep);
699              } else if (action==2) {
700                ClpPrimalColumnDantzig dantzig;
701                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
702              } else if (action==3) {
703                ClpPrimalColumnSteepest steep(2);
704                lpSolver->setPrimalColumnPivotAlgorithm(steep);
705              } else if (action==4) {
706                ClpPrimalColumnSteepest steep(1);
707                lpSolver->setPrimalColumnPivotAlgorithm(steep);
708              } else if (action==5) {
709                ClpPrimalColumnSteepest steep(4);
710                lpSolver->setPrimalColumnPivotAlgorithm(steep);
711              } else if (action==6) {
712                ClpPrimalColumnSteepest steep(10);
713                lpSolver->setPrimalColumnPivotAlgorithm(steep);
714              }
715              break;
716            case SCALING:
717              lpSolver->scaling(action);
718              solver->setHintParam(OsiDoScale,action!=0,OsiHintTry);
719              doScaling = 1-action;
720              break;
721            case AUTOSCALE:
722              lpSolver->setAutomaticScaling(action!=0);
723              break;
724            case SPARSEFACTOR:
725              lpSolver->setSparseFactorization((1-action)!=0);
726              break;
727            case BIASLU:
728              lpSolver->factorization()->setBiasLU(action);
729              break;
730            case PERTURBATION:
731              if (action==0)
732                lpSolver->setPerturbation(50);
733              else
734                lpSolver->setPerturbation(100);
735              break;
736            case ERRORSALLOWED:
737              allowImportErrors = action;
738              break;
739            case INTPRINT:
740              printMode=action;
741              break;
742              //case ALGORITHM:
743              //algorithm  = action;
744              //defaultSettings=false; // user knows what she is doing
745              //abort();
746              //break;
747            case KEEPNAMES:
748              keepImportNames = 1-action;
749              break;
750            case PRESOLVE:
751              if (action==0)
752                preSolve = 5;
753              else if (action==1)
754                preSolve=0;
755              else if (action==2)
756                preSolve=10;
757              else
758                preSolveFile=true;
759              break;
760            case PFI:
761              lpSolver->factorization()->setForrestTomlin(action==0);
762              break;
763            case CRASH:
764              doCrash=action;
765              break;
766            case MESSAGES:
767              lpSolver->messageHandler()->setPrefix(action!=0);
768              break;
769            case CHOLESKY:
770              choleskyType = action;
771              break;
772            case GAMMA:
773              gamma=action;
774              break;
775            case BARRIERSCALE:
776              scaleBarrier=action;
777              break;
778            case KKT:
779              doKKT=action;
780              break;
781            case CROSSOVER:
782              crossover=action;
783              break;
784            case GOMORYCUTS:
785              defaultSettings=false; // user knows what she is doing
786              gomoryAction = action;
787              break;
788            case PROBINGCUTS:
789              defaultSettings=false; // user knows what she is doing
790              probingAction = action;
791              break;
792            case KNAPSACKCUTS:
793              defaultSettings=false; // user knows what she is doing
794              knapsackAction = action;
795              break;
796            case REDSPLITCUTS:
797              defaultSettings=false; // user knows what she is doing
798              redsplitAction = action;
799              break;
800            case CLIQUECUTS:
801              defaultSettings=false; // user knows what she is doing
802              cliqueAction = action;
803              break;
804            case FLOWCUTS:
805              defaultSettings=false; // user knows what she is doing
806              flowAction = action;
807              break;
808            case MIXEDCUTS:
809              defaultSettings=false; // user knows what she is doing
810              mixedAction = action;
811              break;
812            case TWOMIRCUTS:
813              defaultSettings=false; // user knows what she is doing
814              twomirAction = action;
815              break;
816            case ROUNDING:
817              defaultSettings=false; // user knows what she is doing
818              useRounding = action;
819              break;
820            case FPUMP:
821              defaultSettings=false; // user knows what she is doing
822              useFpump=action;
823              break;
824            case CUTSSTRATEGY:
825              gomoryAction = action;
826              probingAction = action;
827              knapsackAction = action;
828              //redsplitAction = action;
829              cliqueAction = action;
830              flowAction = action;
831              mixedAction = action;
832              twomirAction = action;
833              parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption(action);
834              parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption(action);
835              parameters[whichParam(KNAPSACKCUTS,numberParameters,parameters)].setCurrentOption(action);
836              //parameters[whichParam(REDSPLITCUTS,numberParameters,parameters)].setCurrentOption(action);
837              parameters[whichParam(CLIQUECUTS,numberParameters,parameters)].setCurrentOption(action);
838              parameters[whichParam(FLOWCUTS,numberParameters,parameters)].setCurrentOption(action);
839              parameters[whichParam(MIXEDCUTS,numberParameters,parameters)].setCurrentOption(action);
840              parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption(action);
841              break;
842            case HEURISTICSTRATEGY:
843              useRounding = action;
844              useGreedy = action;
845              useCombine = action;
846              //useLocalTree = action;
847              useFpump=action;
848              parameters[whichParam(ROUNDING,numberParameters,parameters)].setCurrentOption(action);
849              parameters[whichParam(GREEDY,numberParameters,parameters)].setCurrentOption(action);
850              parameters[whichParam(COMBINE,numberParameters,parameters)].setCurrentOption(action);
851              //parameters[whichParam(LOCALTREE,numberParameters,parameters)].setCurrentOption(action);
852              parameters[whichParam(FPUMP,numberParameters,parameters)].setCurrentOption(action);
853              break;
854            case GREEDY:
855              defaultSettings=false; // user knows what she is doing
856              useGreedy = action;
857              break;
858            case COMBINE:
859              defaultSettings=false; // user knows what she is doing
860              useCombine = action;
861              break;
862            case LOCALTREE:
863              defaultSettings=false; // user knows what she is doing
864              useLocalTree = action;
865              break;
866            case COSTSTRATEGY:
867              if (action!=1) {
868                printf("Pseudo costs not implemented yet\n");
869              } else {
870                int numberColumns = model.getNumCols();
871                int * sort = new int[numberColumns];
872                double * dsort = new double[numberColumns];
873                int * priority = new int [numberColumns];
874                const double * objective = model.getObjCoefficients();
875                int iColumn;
876                int n=0;
877                for (iColumn=0;iColumn<numberColumns;iColumn++) {
878                  if (model.isInteger(iColumn)) {
879                    sort[n]=n;
880                    dsort[n++]=-objective[iColumn];
881                  }
882                }
883                CoinSort_2(dsort,dsort+n,sort);
884                int level=0;
885                double last = -1.0e100;
886                for (int i=0;i<n;i++) {
887                  int iPut=sort[i];
888                  if (dsort[i]!=last) {
889                    level++;
890                    last=dsort[i];
891                  }
892                  priority[iPut]=level;
893                }
894                model.passInPriorities( priority,false);
895                delete [] priority;
896                delete [] sort;
897                delete [] dsort;
898              }
899              break;
900            case PREPROCESS:
901              preProcess = action;
902              break;
903            default:
904              abort();
905            }
906          }
907        } else {
908          // action
909          if (type==EXIT)
910            break; // stop all
911          switch (type) {
912          case DUALSIMPLEX:
913          case PRIMALSIMPLEX:
914          case SOLVECONTINUOUS:
915          case BARRIER:
916            if (goodModel) {
917              ClpSolve::SolveType method;
918              ClpSolve::PresolveType presolveType;
919              ClpSimplex * model2 = lpSolver;
920              ClpSolve solveOptions;
921              if (preSolve!=5&&preSolve)
922                presolveType=ClpSolve::presolveNumber;
923              else if (preSolve)
924                presolveType=ClpSolve::presolveOn;
925              else
926                presolveType=ClpSolve::presolveOff;
927              solveOptions.setPresolveType(presolveType,preSolve);
928              if (type==DUALSIMPLEX||SOLVECONTINUOUS) {
929                method=ClpSolve::useDual;
930              } else if (type==PRIMALSIMPLEX) {
931                method=ClpSolve::usePrimalorSprint;
932              } else {
933                method = ClpSolve::useBarrier;
934                if (crossover==1) {
935                  method=ClpSolve::useBarrierNoCross;
936                } else if (crossover==2) {
937                  ClpObjective * obj = lpSolver->objectiveAsObject();
938                  if (obj->type()>1) {
939                    method=ClpSolve::useBarrierNoCross;
940                    presolveType=ClpSolve::presolveOff;
941                    solveOptions.setPresolveType(presolveType,preSolve);
942                  } 
943                }
944              }
945              solveOptions.setSolveType(method);
946              if(preSolveFile)
947                presolveOptions |= 0x40000000;
948              solveOptions.setSpecialOption(4,presolveOptions);
949              solveOptions.setSpecialOption(5,printOptions);
950              if (method==ClpSolve::useDual) {
951                // dual
952                if (doCrash)
953                  solveOptions.setSpecialOption(0,1,doCrash); // crash
954                else if (doIdiot)
955                  solveOptions.setSpecialOption(0,2,doIdiot); // possible idiot
956              } else if (method==ClpSolve::usePrimalorSprint) {
957                // primal
958                // if slp turn everything off
959                if (slpValue>0) {
960                  doCrash=false;
961                  doSprint=0;
962                  doIdiot=-1;
963                  solveOptions.setSpecialOption(1,10,slpValue); // slp
964                  method=ClpSolve::usePrimal;
965                }
966                if (doCrash) {
967                  solveOptions.setSpecialOption(1,1,doCrash); // crash
968                } else if (doSprint>0) {
969                  // sprint overrides idiot
970                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
971                } else if (doIdiot>0) {
972                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
973                } else if (slpValue<=0) {
974                  if (doIdiot==0) {
975                    if (doSprint==0)
976                      solveOptions.setSpecialOption(1,4); // all slack
977                    else
978                      solveOptions.setSpecialOption(1,9); // all slack or sprint
979                  } else {
980                    if (doSprint==0)
981                      solveOptions.setSpecialOption(1,8); // all slack or idiot
982                    else
983                      solveOptions.setSpecialOption(1,7); // initiative
984                  }
985                }
986                if (basisHasValues==-1)
987                  solveOptions.setSpecialOption(1,11); // switch off values
988              } else if (method==ClpSolve::useBarrier||method==ClpSolve::useBarrierNoCross) {
989                int barrierOptions = choleskyType;
990                if (scaleBarrier)
991                  barrierOptions |= 8;
992                if (gamma)
993                  barrierOptions |= 16;
994                if (doKKT)
995                  barrierOptions |= 32;
996                solveOptions.setSpecialOption(4,barrierOptions);
997              }
998              model2->initialSolve(solveOptions);
999              basisHasValues=1;
1000            } else {
1001              std::cout<<"** Current model not valid"<<std::endl;
1002            }
1003            break;
1004          case TIGHTEN:
1005            if (goodModel) {
1006              int numberInfeasibilities = lpSolver->tightenPrimalBounds();
1007              if (numberInfeasibilities)
1008                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
1009            } else {
1010              std::cout<<"** Current model not valid"<<std::endl;
1011            }
1012            break;
1013          case PLUSMINUS:
1014            if (goodModel) {
1015              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1016              ClpPackedMatrix* clpMatrix =
1017                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1018              if (clpMatrix) {
1019                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
1020                if (newMatrix->getIndices()) {
1021                  lpSolver->replaceMatrix(newMatrix);
1022                  delete saveMatrix;
1023                  std::cout<<"Matrix converted to +- one matrix"<<std::endl;
1024                } else {
1025                  std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
1026                }
1027              } else {
1028                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1029              }
1030            } else {
1031              std::cout<<"** Current model not valid"<<std::endl;
1032            }
1033            break;
1034          case NETWORK:
1035            if (goodModel) {
1036              ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
1037              ClpPackedMatrix* clpMatrix =
1038                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1039              if (clpMatrix) {
1040                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
1041                if (newMatrix->getIndices()) {
1042                  lpSolver->replaceMatrix(newMatrix);
1043                  delete saveMatrix;
1044                  std::cout<<"Matrix converted to network matrix"<<std::endl;
1045                } else {
1046                  std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
1047                }
1048              } else {
1049                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1050              }
1051            } else {
1052              std::cout<<"** Current model not valid"<<std::endl;
1053            }
1054            break;
1055/*
1056  Run branch-and-cut. First set a few options -- node comparison, scaling. If
1057  the solver is Clp, consider running some presolve code (not yet converted
1058  this to generic OSI) with branch-and-cut. If presolve is disabled, or the
1059  solver is not Clp, simply run branch-and-cut. Print elapsed time at the end.
1060*/
1061          case BAB: // branchAndBound
1062            if (goodModel) {
1063              // If user made settings then use them
1064              if (!defaultSettings) {
1065                OsiSolverInterface * solver = model.solver();
1066                if (!doScaling)
1067                  solver->setHintParam(OsiDoScale,false,OsiHintTry);
1068                OsiClpSolverInterface * si =
1069                  dynamic_cast<OsiClpSolverInterface *>(solver) ;
1070                assert (si != NULL);
1071                // get clp itself
1072                ClpSimplex * modelC = si->getModelPtr();
1073                if (modelC->tightenPrimalBounds()!=0) {
1074                  std::cout<<"Problem is infeasible!"<<std::endl;
1075                  break;
1076                }
1077                model.initialSolve();
1078                // bounds based on continuous
1079                if (tightenFactor) {
1080                  if (modelC->tightenPrimalBounds(tightenFactor)!=0) {
1081                    std::cout<<"Problem is infeasible!"<<std::endl;
1082                    break;
1083                  }
1084                }
1085                if (djFix<1.0e20) {
1086                  // do some fixing
1087                  int numberColumns = modelC->numberColumns();
1088                  int i;
1089                  const char * type = modelC->integerInformation();
1090                  double * lower = modelC->columnLower();
1091                  double * upper = modelC->columnUpper();
1092                  double * solution = modelC->primalColumnSolution();
1093                  double * dj = modelC->dualColumnSolution();
1094                  int numberFixed=0;
1095                  for (i=0;i<numberColumns;i++) {
1096                    if (type[i]) {
1097                      double value = solution[i];
1098                      if (value<lower[i]+1.0e-5&&dj[i]>djFix) {
1099                        solution[i]=lower[i];
1100                        upper[i]=lower[i];
1101                        numberFixed++;
1102                      } else if (value>upper[i]-1.0e-5&&dj[i]<-djFix) {
1103                        solution[i]=upper[i];
1104                        lower[i]=upper[i];
1105                        numberFixed++;
1106                      }
1107                    }
1108                  }
1109                  printf("%d columns fixed\n",numberFixed);
1110                }
1111              }
1112              // See if we want preprocessing
1113              OsiSolverInterface * saveSolver=NULL;
1114              CglPreProcess process;
1115              delete babModel;
1116              babModel = new CbcModel(model);
1117              OsiSolverInterface * solver3 = clpSolver->clone();
1118              babModel->assignSolver(solver3);
1119              OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1120              int numberChanged=0;
1121              int * changed = analyze( clpSolver2,numberChanged);
1122              if (clpSolver2->messageHandler()->logLevel())
1123                clpSolver2->messageHandler()->setLogLevel(1);
1124              int logLevel = parameters[slog].intValue();
1125              if (logLevel)
1126                clpSolver2->messageHandler()->setLogLevel(logLevel);
1127              lpSolver = clpSolver2->getModelPtr();
1128              if (lpSolver->factorizationFrequency()==200) {
1129                // User did not touch preset
1130                int numberRows = lpSolver->numberRows();
1131                const int cutoff1=10000;
1132                const int cutoff2=100000;
1133                const int base=75;
1134                const int freq0 = 50;
1135                const int freq1=200;
1136                const int freq2=400;
1137                const int maximum=1000;
1138                int frequency;
1139                if (numberRows<cutoff1)
1140                  frequency=base+numberRows/freq0;
1141                else if (numberRows<cutoff2)
1142                  frequency=base+cutoff1/freq0 + (numberRows-cutoff1)/freq1;
1143                else
1144                  frequency=base+cutoff1/freq0 + (cutoff2-cutoff1)/freq1 + (numberRows-cutoff2)/freq2;
1145                lpSolver->setFactorizationFrequency(CoinMin(maximum,frequency));
1146              }
1147              time2 = CoinCpuTime();
1148              totalTime += time2-time1;
1149              time1 = time2;
1150              double timeLeft = babModel->getMaximumSeconds();
1151              if (preProcess) {
1152                saveSolver=babModel->solver()->clone();
1153                /* Do not try and produce equality cliques and
1154                   do up to 10 passes */
1155                OsiSolverInterface * solver2 = process.preProcess(*saveSolver,false,10);
1156                if (!solver2) {
1157                  printf("Pre-processing says infeasible\n");
1158                  break;
1159                } else {
1160                  printf("processed model has %d rows and %d columns\n",
1161                         solver2->getNumRows(),solver2->getNumCols());
1162                }
1163                //solver2->resolve();
1164                if (preProcess==2) {
1165                  OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
1166                  ClpSimplex * lpSolver = clpSolver2->getModelPtr();
1167                  lpSolver->writeMps("presolved.mps",0,1,lpSolver->optimizationDirection());
1168                  printf("Preprocessed model (minimization) on presolved.mps\n");
1169                }
1170                // we have to keep solver2 so pass clone
1171                solver2 = solver2->clone();
1172                babModel->assignSolver(solver2);
1173                babModel->initialSolve();
1174                babModel->setMaximumSeconds(timeLeft-(CoinCpuTime()-time1));
1175              }
1176              if (0) {
1177                // for debug
1178                std::string problemName ;
1179                babModel->solver()->getStrParam(OsiProbName,problemName) ;
1180                babModel->solver()->activateRowCutDebugger(problemName.c_str()) ;
1181                twomirGen.probname_=strdup(problemName.c_str());
1182                // checking seems odd
1183                //redsplitGen.set_given_optsol(babModel->solver()->getRowCutDebuggerAlways()->optimalSolution(),
1184                //                         babModel->getNumCols());
1185              }
1186              if (debugValues) {
1187                if (numberDebugValues==babModel->getNumCols()) {
1188                  // for debug
1189                  babModel->solver()->activateRowCutDebugger(debugValues) ;
1190                } else {
1191                  printf("debug file has incorrect number of columns\n");
1192                }
1193              }
1194              // FPump done first as it only works if no solution
1195              CbcHeuristicFPump heuristic4(*babModel);
1196              if (useFpump) {
1197                heuristic4.setMaximumPasses(parameters[whichParam(FPUMPITS,numberParameters,parameters)].intValue());
1198                babModel->addHeuristic(&heuristic4);
1199              }
1200              CbcRounding heuristic1(*babModel);
1201              if (useRounding)
1202                babModel->addHeuristic(&heuristic1) ;
1203              CbcHeuristicLocal heuristic2(*babModel);
1204              heuristic2.setSearchType(1);
1205              if (useCombine)
1206                babModel->addHeuristic(&heuristic2);
1207              CbcHeuristicGreedyCover heuristic3(*babModel);
1208              CbcHeuristicGreedyEquality heuristic3a(*babModel);
1209              if (useGreedy) {
1210                babModel->addHeuristic(&heuristic3);
1211                babModel->addHeuristic(&heuristic3a);
1212              }
1213              if (useLocalTree) {
1214                CbcTreeLocal localTree(babModel,NULL,10,0,0,10000,2000);
1215                babModel->passInTreeHandler(localTree);
1216              }
1217              // add cut generators if wanted
1218              if (probingAction==1)
1219                babModel->addCutGenerator(&probingGen,-1,"Probing");
1220              else if (probingAction>=2)
1221                babModel->addCutGenerator(&probingGen,-101+probingAction,"Probing");
1222              if (gomoryAction==1)
1223                babModel->addCutGenerator(&gomoryGen,-1,"Gomory");
1224              else if (gomoryAction>=2)
1225                babModel->addCutGenerator(&gomoryGen,-101+gomoryAction,"Gomory");
1226              if (knapsackAction==1)
1227                babModel->addCutGenerator(&knapsackGen,-1,"Knapsack");
1228              else if (knapsackAction>=2)
1229                babModel->addCutGenerator(&knapsackGen,-101+knapsackAction,"Knapsack");
1230              if (redsplitAction==1)
1231                babModel->addCutGenerator(&redsplitGen,-1,"Reduce-and-split");
1232              else if (redsplitAction>=2)
1233                babModel->addCutGenerator(&redsplitGen,-101+redsplitAction,"Reduce-and-split");
1234              if (cliqueAction==1)
1235                babModel->addCutGenerator(&cliqueGen,-1,"Clique");
1236              else if (cliqueAction>=2)
1237                babModel->addCutGenerator(&cliqueGen,-101+cliqueAction,"Clique");
1238              if (mixedAction==1)
1239                babModel->addCutGenerator(&mixedGen,-1,"MixedIntegerRounding2");
1240              else if (mixedAction>=2)
1241                babModel->addCutGenerator(&mixedGen,-101+mixedAction,"MixedIntegerRounding2");
1242              if (flowAction==1)
1243                babModel->addCutGenerator(&flowGen,-1,"FlowCover");
1244              else if (flowAction>=2)
1245                babModel->addCutGenerator(&flowGen,-101+flowAction,"FlowCover");
1246              if (twomirAction==1)
1247                babModel->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
1248              else if (twomirAction>=2)
1249                babModel->addCutGenerator(&twomirGen,-101+twomirAction,"TwoMirCuts");
1250              // Say we want timings
1251              int numberGenerators = babModel->numberCutGenerators();
1252              int iGenerator;
1253              int cutDepth=
1254                parameters[whichParam(CUTDEPTH,numberParameters,parameters)].intValue();
1255              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1256                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1257                generator->setTiming(true);
1258                if (cutDepth>=0)
1259                  generator->setWhatDepth(cutDepth) ;
1260              }
1261              // Could tune more
1262              babModel->setMinimumDrop(min(5.0e-2,
1263                                        fabs(babModel->getMinimizationObjValue())*1.0e-3+1.0e-4));
1264              if (cutPass==-1234567) {
1265                if (babModel->getNumCols()<500)
1266                  babModel->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
1267                else if (babModel->getNumCols()<5000)
1268                  babModel->setMaximumCutPassesAtRoot(100); // use minimum drop
1269                else
1270                  babModel->setMaximumCutPassesAtRoot(20);
1271              } else {
1272                babModel->setMaximumCutPassesAtRoot(cutPass);
1273              }
1274              babModel->setMaximumCutPasses(1);
1275             
1276              // Do more strong branching if small
1277              //if (babModel->getNumCols()<5000)
1278              //babModel->setNumberStrong(20);
1279              // Switch off strong branching if wanted
1280              //if (babModel->getNumCols()>10*babModel->getNumRows())
1281              //babModel->setNumberStrong(0);
1282              babModel->messageHandler()->setLogLevel(parameters[log].intValue());
1283              if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
1284                  babModel->messageHandler()->logLevel()>1)
1285                babModel->setPrintFrequency(100);
1286             
1287              babModel->solver()->setIntParam(OsiMaxNumIterationHotStart,100);
1288              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1289              // go faster stripes
1290              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
1291                osiclp->setupForRepeatedUse(2,0);
1292              } else {
1293                osiclp->setupForRepeatedUse(0,0);
1294              }
1295              // Turn this off if you get problems
1296              // Used to be automatically set
1297              osiclp->setSpecialOptions(osiclp->specialOptions()|(128+64));
1298              if (gapRatio < 1.0e100) {
1299                double value = babModel->solver()->getObjValue() ;
1300                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
1301                babModel->setAllowableGap(value2) ;
1302                std::cout << "Continuous " << value
1303                          << ", so allowable gap set to "
1304                          << value2 << std::endl ;
1305              }
1306              currentBranchModel = babModel;
1307              babModel->branchAndBound();
1308              currentBranchModel = NULL;
1309              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1310              if (debugFile=="createAfterPre"&&babModel->bestSolution()) {
1311                lpSolver = osiclp->getModelPtr();
1312                //move best solution (should be there -- but ..)
1313                int n = lpSolver->getNumCols();
1314                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
1315                saveSolution(osiclp->getModelPtr(),"debug.file");
1316              }
1317              // Print more statistics
1318              std::cout<<"Cuts at root node changed objective from "<<babModel->getContinuousObjective()
1319                       <<" to "<<babModel->rootObjectiveAfterCuts()<<std::endl;
1320             
1321              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
1322                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
1323                std::cout<<generator->cutGeneratorName()<<" was tried "
1324                         <<generator->numberTimesEntered()<<" times and created "
1325                         <<generator->numberCutsInTotal()<<" cuts of which "
1326                         <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
1327                if (generator->timing())
1328                  std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
1329                else
1330                  std::cout<<std::endl;
1331              }
1332              time2 = CoinCpuTime();
1333              totalTime += time2-time1;
1334              if (babModel->getMinimizationObjValue()<1.0e50) {
1335                // post process
1336                if (preProcess) {
1337                  process.postProcess(*babModel->solver());
1338                  // Solution now back in saveSolver
1339                  babModel->assignSolver(saveSolver);
1340                }
1341              }
1342              // clpSolver still OK clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
1343              lpSolver = clpSolver->getModelPtr();
1344              if (babModel->bestSolution()){
1345                //move best solution (should be there -- but ..)
1346                int n = lpSolver->getNumCols();
1347                memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
1348              }
1349              if (debugFile=="create"&&babModel->bestSolution()) {
1350                saveSolution(lpSolver,"debug.file");
1351              }
1352              if (numberChanged) {
1353                for (int i=0;i<numberChanged;i++) {
1354                  int iColumn=changed[i];
1355                  clpSolver->setContinuous(iColumn);
1356                }
1357                delete [] changed;
1358              }
1359              std::string statusName[]={"Finished","Stopped on ","Difficulties",
1360                                        "","","User ctrl-c"};
1361              std::string minor[]={"","","gap","nodes","time","","solutions"};
1362              int iStat = babModel->status();
1363              int iStat2 = babModel->secondaryStatus();
1364              std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
1365                       <<" objective "<<babModel->getObjValue()<<
1366                " after "<<babModel->getNodeCount()<<" nodes and "
1367                <<babModel->getIterationCount()<<
1368                " iterations - took "<<time2-time1<<" seconds"<<std::endl;
1369              time1 = time2;
1370              delete babModel;
1371              babModel=NULL;
1372            } else {
1373              std::cout << "** Current model not valid" << std::endl ; 
1374            }
1375            break ;
1376          case IMPORT:
1377            {
1378              delete babModel;
1379              babModel=NULL;
1380              // get next field
1381              field = CoinReadGetString(argc,argv);
1382              if (field=="$") {
1383                field = parameters[iParam].stringValue();
1384              } else if (field=="EOL") {
1385                parameters[iParam].printString();
1386                break;
1387              } else {
1388                parameters[iParam].setStringValue(field);
1389              }
1390              std::string fileName;
1391              bool canOpen=false;
1392              if (field=="-") {
1393                // stdin
1394                canOpen=true;
1395                fileName = "-";
1396              } else {
1397                bool absolutePath;
1398                if (dirsep=='/') {
1399                  // non Windows (or cygwin)
1400                  absolutePath=(field[0]=='/');
1401                } else {
1402                  //Windows (non cycgwin)
1403                  absolutePath=(field[0]=='\\');
1404                  // but allow for :
1405                  if (strchr(field.c_str(),':'))
1406                    absolutePath=true;
1407                }
1408                if (absolutePath) {
1409                  fileName = field;
1410                } else if (field[0]=='~') {
1411                  char * environ = getenv("HOME");
1412                  if (environ) {
1413                    std::string home(environ);
1414                    field=field.erase(0,1);
1415                    fileName = home+field;
1416                  } else {
1417                    fileName=field;
1418                  }
1419                } else {
1420                  fileName = directory+field;
1421                }
1422                FILE *fp=fopen(fileName.c_str(),"r");
1423                if (fp) {
1424                  // can open - lets go for it
1425                  fclose(fp);
1426                  canOpen=true;
1427                } else {
1428                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1429                }
1430              }
1431              if (canOpen) {
1432                int status =lpSolver->readMps(fileName.c_str(),
1433                                                   keepImportNames!=0,
1434                                                   allowImportErrors!=0);
1435                if (!status||(status>0&&allowImportErrors)) {
1436                  if (keepImportNames) {
1437                    lengthName = lpSolver->lengthNames();
1438                    rowNames = *(lpSolver->rowNames());
1439                    columnNames = *(lpSolver->columnNames());
1440                  } else {
1441                    lengthName=0;
1442                  }
1443                  goodModel=true;
1444                  //Set integers in clpsolver
1445                  const char * info = lpSolver->integerInformation();
1446                  if (info) {
1447                    int numberColumns = lpSolver->numberColumns();
1448                    int i;
1449                    for (i=0;i<numberColumns;i++) {
1450                      if (info[i]) 
1451                        clpSolver->setInteger(i);
1452                    }
1453                  }
1454                  // sets to all slack (not necessary?)
1455                  lpSolver->createStatus();
1456                  time2 = CoinCpuTime();
1457                  totalTime += time2-time1;
1458                  time1=time2;
1459                  // Go to canned file if just input file
1460                  if (CbcOrClpRead_mode==2&&argc==2) {
1461                    // only if ends .mps
1462                    char * find = strstr(fileName.c_str(),".mps");
1463                    if (find&&find[4]=='\0') {
1464                      find[1]='p'; find[2]='a';find[3]='r';
1465                      FILE *fp=fopen(fileName.c_str(),"r");
1466                      if (fp) {
1467                        CbcOrClpReadCommand=fp; // Read from that file
1468                        CbcOrClpRead_mode=-1;
1469                      }
1470                    }
1471                  }
1472                } else {
1473                  // errors
1474                  std::cout<<"There were "<<status<<
1475                    " errors on input"<<std::endl;
1476                }
1477              }
1478            }
1479            break;
1480          case EXPORT:
1481            if (goodModel) {
1482              // get next field
1483              field = CoinReadGetString(argc,argv);
1484              if (field=="$") {
1485                field = parameters[iParam].stringValue();
1486              } else if (field=="EOL") {
1487                parameters[iParam].printString();
1488                break;
1489              } else {
1490                parameters[iParam].setStringValue(field);
1491              }
1492              std::string fileName;
1493              bool canOpen=false;
1494              if (field[0]=='/'||field[0]=='\\') {
1495                fileName = field;
1496              } else if (field[0]=='~') {
1497                char * environ = getenv("HOME");
1498                if (environ) {
1499                  std::string home(environ);
1500                  field=field.erase(0,1);
1501                  fileName = home+field;
1502                } else {
1503                  fileName=field;
1504                }
1505              } else {
1506                fileName = directory+field;
1507              }
1508              FILE *fp=fopen(fileName.c_str(),"w");
1509              if (fp) {
1510                // can open - lets go for it
1511                fclose(fp);
1512                canOpen=true;
1513              } else {
1514                std::cout<<"Unable to open file "<<fileName<<std::endl;
1515              }
1516              if (canOpen) {
1517                // If presolve on then save presolved
1518                bool deleteModel2=false;
1519                ClpSimplex * model2 = lpSolver;
1520                if (preSolve) {
1521                  ClpPresolve pinfo;
1522                  int presolveOptions2 = presolveOptions&~0x40000000;
1523                  if ((presolveOptions2&0xffff)!=0)
1524                    pinfo.setPresolveActions(presolveOptions2);
1525                  if ((printOptions&1)!=0)
1526                    pinfo.statistics();
1527                  model2 = 
1528                    pinfo.presolvedModel(*lpSolver,1.0e-8,
1529                                         true,preSolve);
1530                  if (model2) {
1531                    printf("Saving presolved model on %s\n",
1532                           fileName.c_str());
1533                    deleteModel2=true;
1534                  } else {
1535                    printf("Presolved model looks infeasible - saving original on %s\n",
1536                           fileName.c_str());
1537                    deleteModel2=false;
1538                    model2 = lpSolver;
1539
1540                  }
1541                } else {
1542                  printf("Saving model on %s\n",
1543                           fileName.c_str());
1544                }
1545#if 0
1546                // Convert names
1547                int iRow;
1548                int numberRows=model2->numberRows();
1549                int iColumn;
1550                int numberColumns=model2->numberColumns();
1551
1552                char ** rowNames = NULL;
1553                char ** columnNames = NULL;
1554                if (model2->lengthNames()) {
1555                  rowNames = new char * [numberRows];
1556                  for (iRow=0;iRow<numberRows;iRow++) {
1557                    rowNames[iRow] =
1558                      strdup(model2->rowName(iRow).c_str());
1559#ifdef STRIPBLANKS
1560                    char * xx = rowNames[iRow];
1561                    int i;
1562                    int length = strlen(xx);
1563                    int n=0;
1564                    for (i=0;i<length;i++) {
1565                      if (xx[i]!=' ')
1566                        xx[n++]=xx[i];
1567                    }
1568                    xx[n]='\0';
1569#endif
1570                  }
1571                 
1572                  columnNames = new char * [numberColumns];
1573                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1574                    columnNames[iColumn] =
1575                      strdup(model2->columnName(iColumn).c_str());
1576#ifdef STRIPBLANKS
1577                    char * xx = columnNames[iColumn];
1578                    int i;
1579                    int length = strlen(xx);
1580                    int n=0;
1581                    for (i=0;i<length;i++) {
1582                      if (xx[i]!=' ')
1583                        xx[n++]=xx[i];
1584                    }
1585                    xx[n]='\0';
1586#endif
1587                  }
1588                }
1589                CoinMpsIO writer;
1590                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
1591                                  model2->getColLower(), model2->getColUpper(),
1592                                  model2->getObjCoefficients(),
1593                                  (const char*) 0 /*integrality*/,
1594                                  model2->getRowLower(), model2->getRowUpper(),
1595                                  columnNames, rowNames);
1596                // Pass in array saying if each variable integer
1597                writer.copyInIntegerInformation(model2->integerInformation());
1598                writer.setObjectiveOffset(model2->objectiveOffset());
1599                writer.writeMps(fileName.c_str(),0,1,1);
1600                if (rowNames) {
1601                  for (iRow=0;iRow<numberRows;iRow++) {
1602                    free(rowNames[iRow]);
1603                  }
1604                  delete [] rowNames;
1605                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1606                    free(columnNames[iColumn]);
1607                  }
1608                  delete [] columnNames;
1609                }
1610#else
1611                model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
1612#endif
1613                if (deleteModel2)
1614                  delete model2;
1615                time2 = CoinCpuTime();
1616                totalTime += time2-time1;
1617                time1=time2;
1618              }
1619            } else {
1620              std::cout<<"** Current model not valid"<<std::endl;
1621            }
1622            break;
1623          case BASISIN:
1624            if (goodModel) {
1625              // get next field
1626              field = CoinReadGetString(argc,argv);
1627              if (field=="$") {
1628                field = parameters[iParam].stringValue();
1629              } else if (field=="EOL") {
1630                parameters[iParam].printString();
1631                break;
1632              } else {
1633                parameters[iParam].setStringValue(field);
1634              }
1635              std::string fileName;
1636              bool canOpen=false;
1637              if (field=="-") {
1638                // stdin
1639                canOpen=true;
1640                fileName = "-";
1641              } else {
1642                if (field[0]=='/'||field[0]=='\\') {
1643                  fileName = field;
1644                } else if (field[0]=='~') {
1645                  char * environ = getenv("HOME");
1646                  if (environ) {
1647                    std::string home(environ);
1648                    field=field.erase(0,1);
1649                    fileName = home+field;
1650                  } else {
1651                    fileName=field;
1652                  }
1653                } else {
1654                  fileName = directory+field;
1655                }
1656                FILE *fp=fopen(fileName.c_str(),"r");
1657                if (fp) {
1658                  // can open - lets go for it
1659                  fclose(fp);
1660                  canOpen=true;
1661                } else {
1662                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1663                }
1664              }
1665              if (canOpen) {
1666                int values = lpSolver->readBasis(fileName.c_str());
1667                if (values==0)
1668                  basisHasValues=-1;
1669                else
1670                  basisHasValues=1;
1671              }
1672            } else {
1673              std::cout<<"** Current model not valid"<<std::endl;
1674            }
1675            break;
1676          case DEBUG:
1677            if (goodModel) {
1678              delete [] debugValues;
1679              debugValues=NULL;
1680              // get next field
1681              field = CoinReadGetString(argc,argv);
1682              if (field=="$") {
1683                field = parameters[iParam].stringValue();
1684              } else if (field=="EOL") {
1685                parameters[iParam].printString();
1686                break;
1687              } else {
1688                parameters[iParam].setStringValue(field);
1689                debugFile=field;
1690                if (debugFile=="create"||
1691                    debugFile=="createAfterPre") {
1692                  printf("Will create a debug file so this run should be a good one\n");
1693                  break;
1694                }
1695              }
1696              std::string fileName;
1697              if (field[0]=='/'||field[0]=='\\') {
1698                fileName = field;
1699              } else if (field[0]=='~') {
1700                char * environ = getenv("HOME");
1701                if (environ) {
1702                  std::string home(environ);
1703                  field=field.erase(0,1);
1704                  fileName = home+field;
1705                } else {
1706                  fileName=field;
1707                }
1708              } else {
1709                fileName = directory+field;
1710              }
1711              FILE *fp=fopen(fileName.c_str(),"rb");
1712              if (fp) {
1713                // can open - lets go for it
1714                int numRows;
1715                double obj;
1716                fread(&numRows,sizeof(int),1,fp);
1717                fread(&numberDebugValues,sizeof(int),1,fp);
1718                fread(&obj,sizeof(double),1,fp);
1719                debugValues = new double[numberDebugValues+numRows];
1720                fread(debugValues,sizeof(double),numRows,fp);
1721                fread(debugValues,sizeof(double),numRows,fp);
1722                fread(debugValues,sizeof(double),numberDebugValues,fp);
1723                printf("%d doubles read into debugValues\n",numberDebugValues);
1724                fclose(fp);
1725              } else {
1726                std::cout<<"Unable to open file "<<fileName<<std::endl;
1727              }
1728            } else {
1729              std::cout<<"** Current model not valid"<<std::endl;
1730            }
1731            break;
1732          case BASISOUT:
1733            if (goodModel) {
1734              // get next field
1735              field = CoinReadGetString(argc,argv);
1736              if (field=="$") {
1737                field = parameters[iParam].stringValue();
1738              } else if (field=="EOL") {
1739                parameters[iParam].printString();
1740                break;
1741              } else {
1742                parameters[iParam].setStringValue(field);
1743              }
1744              std::string fileName;
1745              bool canOpen=false;
1746              if (field[0]=='/'||field[0]=='\\') {
1747                fileName = field;
1748              } else if (field[0]=='~') {
1749                char * environ = getenv("HOME");
1750                if (environ) {
1751                  std::string home(environ);
1752                  field=field.erase(0,1);
1753                  fileName = home+field;
1754                } else {
1755                  fileName=field;
1756                }
1757              } else {
1758                fileName = directory+field;
1759              }
1760              FILE *fp=fopen(fileName.c_str(),"w");
1761              if (fp) {
1762                // can open - lets go for it
1763                fclose(fp);
1764                canOpen=true;
1765              } else {
1766                std::cout<<"Unable to open file "<<fileName<<std::endl;
1767              }
1768              if (canOpen) {
1769                ClpSimplex * model2 = lpSolver;
1770                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
1771                time2 = CoinCpuTime();
1772                totalTime += time2-time1;
1773                time1=time2;
1774              }
1775            } else {
1776              std::cout<<"** Current model not valid"<<std::endl;
1777            }
1778            break;
1779          case SAVE:
1780            {
1781              // get next field
1782              field = CoinReadGetString(argc,argv);
1783              if (field=="$") {
1784                field = parameters[iParam].stringValue();
1785              } else if (field=="EOL") {
1786                parameters[iParam].printString();
1787                break;
1788              } else {
1789                parameters[iParam].setStringValue(field);
1790              }
1791              std::string fileName;
1792              bool canOpen=false;
1793              if (field[0]=='/'||field[0]=='\\') {
1794                fileName = field;
1795              } else if (field[0]=='~') {
1796                char * environ = getenv("HOME");
1797                if (environ) {
1798                  std::string home(environ);
1799                  field=field.erase(0,1);
1800                  fileName = home+field;
1801                } else {
1802                  fileName=field;
1803                }
1804              } else {
1805                fileName = directory+field;
1806              }
1807              FILE *fp=fopen(fileName.c_str(),"wb");
1808              if (fp) {
1809                // can open - lets go for it
1810                fclose(fp);
1811                canOpen=true;
1812              } else {
1813                std::cout<<"Unable to open file "<<fileName<<std::endl;
1814              }
1815              if (canOpen) {
1816                int status;
1817                // If presolve on then save presolved
1818                bool deleteModel2=false;
1819                ClpSimplex * model2 = lpSolver;
1820                if (preSolve) {
1821                  ClpPresolve pinfo;
1822                  model2 = 
1823                    pinfo.presolvedModel(*lpSolver,1.0e-8,
1824                                         false,preSolve);
1825                  if (model2) {
1826                    printf("Saving presolved model on %s\n",
1827                           fileName.c_str());
1828                    deleteModel2=true;
1829                  } else {
1830                    printf("Presolved model looks infeasible - saving original on %s\n",
1831                           fileName.c_str());
1832                    deleteModel2=false;
1833                    model2 = lpSolver;
1834
1835                  }
1836                } else {
1837                  printf("Saving model on %s\n",
1838                           fileName.c_str());
1839                }
1840                status =model2->saveModel(fileName.c_str());
1841                if (deleteModel2)
1842                  delete model2;
1843                if (!status) {
1844                  goodModel=true;
1845                  time2 = CoinCpuTime();
1846                  totalTime += time2-time1;
1847                  time1=time2;
1848                } else {
1849                  // errors
1850                  std::cout<<"There were errors on output"<<std::endl;
1851                }
1852              }
1853            }
1854            break;
1855          case RESTORE:
1856            {
1857              // get next field
1858              field = CoinReadGetString(argc,argv);
1859              if (field=="$") {
1860                field = parameters[iParam].stringValue();
1861              } else if (field=="EOL") {
1862                parameters[iParam].printString();
1863                break;
1864              } else {
1865                parameters[iParam].setStringValue(field);
1866              }
1867              std::string fileName;
1868              bool canOpen=false;
1869              if (field[0]=='/'||field[0]=='\\') {
1870                fileName = field;
1871              } else if (field[0]=='~') {
1872                char * environ = getenv("HOME");
1873                if (environ) {
1874                  std::string home(environ);
1875                  field=field.erase(0,1);
1876                  fileName = home+field;
1877                } else {
1878                  fileName=field;
1879                }
1880              } else {
1881                fileName = directory+field;
1882              }
1883              FILE *fp=fopen(fileName.c_str(),"rb");
1884              if (fp) {
1885                // can open - lets go for it
1886                fclose(fp);
1887                canOpen=true;
1888              } else {
1889                std::cout<<"Unable to open file "<<fileName<<std::endl;
1890              }
1891              if (canOpen) {
1892                int status =lpSolver->restoreModel(fileName.c_str());
1893                if (!status) {
1894                  goodModel=true;
1895                  time2 = CoinCpuTime();
1896                  totalTime += time2-time1;
1897                  time1=time2;
1898                } else {
1899                  // errors
1900                  std::cout<<"There were errors on input"<<std::endl;
1901                }
1902              }
1903            }
1904            break;
1905          case MAXIMIZE:
1906            lpSolver->setOptimizationDirection(-1);
1907            break;
1908          case MINIMIZE:
1909            lpSolver->setOptimizationDirection(1);
1910            break;
1911          case ALLSLACK:
1912            lpSolver->allSlackBasis(true);
1913            break;
1914          case REVERSE:
1915            if (goodModel) {
1916              int iColumn;
1917              int numberColumns=lpSolver->numberColumns();
1918              double * dualColumnSolution = 
1919                lpSolver->dualColumnSolution();
1920              ClpObjective * obj = lpSolver->objectiveAsObject();
1921              assert(dynamic_cast<ClpLinearObjective *> (obj));
1922              double offset;
1923              double * objective = obj->gradient(NULL,NULL,offset,true);
1924              for (iColumn=0;iColumn<numberColumns;iColumn++) {
1925                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
1926                objective[iColumn] = -objective[iColumn];
1927              }
1928              int iRow;
1929              int numberRows=lpSolver->numberRows();
1930              double * dualRowSolution = 
1931                lpSolver->dualRowSolution();
1932              for (iRow=0;iRow<numberRows;iRow++) 
1933                dualRowSolution[iRow] = dualRowSolution[iRow];
1934            }
1935            break;
1936          case DIRECTORY:
1937            {
1938              std::string name = CoinReadGetString(argc,argv);
1939              if (name!="EOL") {
1940                int length=name.length();
1941                if (name[length-1]=='/'||name[length-1]=='\\')
1942                  directory=name;
1943                else
1944                  directory = name+"/";
1945                parameters[iParam].setStringValue(directory);
1946              } else {
1947                parameters[iParam].printString();
1948              }
1949            }
1950            break;
1951          case STDIN:
1952            CbcOrClpRead_mode=-1;
1953            break;
1954          case NETLIB_DUAL:
1955          case NETLIB_EITHER:
1956          case NETLIB_BARRIER:
1957          case NETLIB_PRIMAL:
1958          case NETLIB_TUNE:
1959            {
1960              // create fields for unitTest
1961              const char * fields[4];
1962              int nFields=2;
1963              fields[0]="fake main from unitTest";
1964              fields[1]="-netlib";
1965              if (directory!=defaultDirectory) {
1966                fields[2]="-netlibDir";
1967                fields[3]=directory.c_str();
1968                nFields=4;
1969              }
1970              int algorithm;
1971              if (type==NETLIB_DUAL) {
1972                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
1973                algorithm =0;
1974              } else if (type==NETLIB_BARRIER) {
1975                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
1976                algorithm =2;
1977              } else if (type==NETLIB_EITHER) {
1978                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
1979                algorithm =3;
1980              } else if (type==NETLIB_TUNE) {
1981                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
1982                algorithm =5;
1983                // uncomment next to get active tuning
1984                // algorithm=6;
1985              } else {
1986                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
1987                algorithm=1;
1988              }
1989              int specialOptions = lpSolver->specialOptions();
1990              lpSolver->setSpecialOptions(0);
1991              mainTest(nFields,fields,algorithm,*lpSolver,
1992                       (preSolve!=0),specialOptions);
1993            }
1994            break;
1995          case UNITTEST:
1996            {
1997              // create fields for unitTest
1998              const char * fields[3];
1999              int nFields=1;
2000              fields[0]="fake main from unitTest";
2001              if (directory!=defaultDirectory) {
2002                fields[1]="-mpsDir";
2003                fields[2]=directory.c_str();
2004                nFields=3;
2005              }
2006              mainTest(nFields,fields,false,*lpSolver,(preSolve!=0),
2007                       false);
2008            }
2009            break;
2010          case FAKEBOUND:
2011            if (goodModel) {
2012              // get bound
2013              double value = CoinReadGetDoubleField(argc,argv,&valid);
2014              if (!valid) {
2015                std::cout<<"Setting "<<parameters[iParam].name()<<
2016                  " to DEBUG "<<value<<std::endl;
2017                int iRow;
2018                int numberRows=lpSolver->numberRows();
2019                double * rowLower = lpSolver->rowLower();
2020                double * rowUpper = lpSolver->rowUpper();
2021                for (iRow=0;iRow<numberRows;iRow++) {
2022                  // leave free ones for now
2023                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
2024                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
2025                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
2026                  }
2027                }
2028                int iColumn;
2029                int numberColumns=lpSolver->numberColumns();
2030                double * columnLower = lpSolver->columnLower();
2031                double * columnUpper = lpSolver->columnUpper();
2032                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2033                  // leave free ones for now
2034                  if (columnLower[iColumn]>-1.0e20||
2035                      columnUpper[iColumn]<1.0e20) {
2036                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
2037                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
2038                  }
2039                }
2040              } else if (valid==1) {
2041                abort();
2042              } else {
2043                std::cout<<"enter value for "<<parameters[iParam].name()<<
2044                  std::endl;
2045              }
2046            }
2047            break;
2048          case REALLY_SCALE:
2049            if (goodModel) {
2050              ClpSimplex newModel(*lpSolver,
2051                                  lpSolver->scalingFlag());
2052              printf("model really really scaled\n");
2053              *lpSolver=newModel;
2054            }
2055            break;
2056          case HELP:
2057            std::cout<<"Coin Solver version "<<CBCVERSION
2058                     <<", build "<<__DATE__<<std::endl;
2059            std::cout<<"Non default values:-"<<std::endl;
2060            std::cout<<"Perturbation "<<lpSolver->perturbation()<<" (default 100)"
2061                     <<std::endl;
2062            CoinReadPrintit(
2063                    "Presolve being done with 5 passes\n\
2064Dual steepest edge steep/partial on matrix shape and factorization density\n\
2065Clpnnnn taken out of messages\n\
2066If Factorization frequency default then done on size of matrix\n\n\
2067(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
2068You can switch to interactive mode at any time so\n\
2069clp watson.mps -scaling off -primalsimplex\nis the same as\n\
2070clp watson.mps -\nscaling off\nprimalsimplex"
2071                    );
2072            break;
2073          case SOLUTION:
2074            if (goodModel) {
2075              // get next field
2076              field = CoinReadGetString(argc,argv);
2077              if (field=="$") {
2078                field = parameters[iParam].stringValue();
2079              } else if (field=="EOL") {
2080                parameters[iParam].printString();
2081                break;
2082              } else {
2083                parameters[iParam].setStringValue(field);
2084              }
2085              std::string fileName;
2086              FILE *fp=NULL;
2087              if (field=="-"||field=="EOL"||field=="stdout") {
2088                // stdout
2089                fp=stdout;
2090              } else if (field=="stderr") {
2091                // stderr
2092                fp=stderr;
2093              } else {
2094                if (field[0]=='/'||field[0]=='\\') {
2095                  fileName = field;
2096                } else if (field[0]=='~') {
2097                  char * environ = getenv("HOME");
2098                  if (environ) {
2099                    std::string home(environ);
2100                    field=field.erase(0,1);
2101                    fileName = home+field;
2102                  } else {
2103                    fileName=field;
2104                  }
2105                } else {
2106                  fileName = directory+field;
2107                }
2108                fp=fopen(fileName.c_str(),"w");
2109              }
2110              if (fp) {
2111                // make fancy later on
2112                int iRow;
2113                int numberRows=lpSolver->numberRows();
2114                double * dualRowSolution = lpSolver->dualRowSolution();
2115                double * primalRowSolution = 
2116                  lpSolver->primalRowSolution();
2117                double * rowLower = lpSolver->rowLower();
2118                double * rowUpper = lpSolver->rowUpper();
2119                double primalTolerance = lpSolver->primalTolerance();
2120                char format[6];
2121                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
2122                if (printMode>2) {
2123                  for (iRow=0;iRow<numberRows;iRow++) {
2124                    int type=printMode-3;
2125                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
2126                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
2127                      fprintf(fp,"** ");
2128                      type=2;
2129                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
2130                      type=1;
2131                    } else if (numberRows<50) {
2132                      type=3;
2133                    }
2134                    if (type) {
2135                      fprintf(fp,"%7d ",iRow);
2136                      if (lengthName)
2137                        fprintf(fp,format,rowNames[iRow].c_str());
2138                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
2139                              dualRowSolution[iRow]);
2140                    }
2141                  }
2142                }
2143                int iColumn;
2144                int numberColumns=lpSolver->numberColumns();
2145                double * dualColumnSolution = 
2146                  lpSolver->dualColumnSolution();
2147                double * primalColumnSolution = 
2148                  lpSolver->primalColumnSolution();
2149                double * columnLower = lpSolver->columnLower();
2150                double * columnUpper = lpSolver->columnUpper();
2151                if (printMode!=2) {
2152                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2153                    int type=0;
2154                    if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
2155                        primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
2156                      fprintf(fp,"** ");
2157                      type=2;
2158                    } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
2159                      type=1;
2160                    } else if (numberColumns<50) {
2161                      type=3;
2162                    }
2163                    // see if integer
2164                    if (!lpSolver->isInteger(iColumn)&&printMode==1)
2165                      type=0;
2166                    if (type) {
2167                      fprintf(fp,"%7d ",iColumn);
2168                      if (lengthName)
2169                        fprintf(fp,format,columnNames[iColumn].c_str());
2170                      fprintf(fp,"%15.8g        %15.8g\n",
2171                              primalColumnSolution[iColumn],
2172                              dualColumnSolution[iColumn]);
2173                    }
2174                  }
2175                } else {
2176                  // special format suitable for OsiRowCutDebugger
2177                  int n=0;
2178                  bool comma=false;
2179                  bool newLine=false;
2180                  fprintf(fp,"\tint intIndicesV[]={\n");
2181                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
2182                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
2183                      if (comma)
2184                        fprintf(fp,",");
2185                      if (newLine)
2186                        fprintf(fp,"\n");
2187                      fprintf(fp,"%d ",iColumn);
2188                      comma=true;
2189                      newLine=false;
2190                      n++;
2191                      if (n==10) {
2192                        n=0;
2193                        newLine=true;
2194                      }
2195                    }
2196                  }
2197                  fprintf(fp,"};\n");
2198                  n=0;
2199                  comma=false;
2200                  newLine=false;
2201                  fprintf(fp,"\tdouble intSolnV[]={\n");
2202                  for ( iColumn=0;iColumn<numberColumns;iColumn++) {
2203                    if(primalColumnSolution[iColumn]>0.5&&model.solver()->isInteger(iColumn)) {
2204                      if (comma)
2205                        fprintf(fp,",");
2206                      if (newLine)
2207                        fprintf(fp,"\n");
2208                      int value = (int) (primalColumnSolution[iColumn]+0.5);
2209                      fprintf(fp,"%d. ",value);
2210                      comma=true;
2211                      newLine=false;
2212                      n++;
2213                      if (n==10) {
2214                        n=0;
2215                        newLine=true;
2216                      }
2217                    }
2218                  }
2219                  fprintf(fp,"};\n");
2220                }
2221                if (fp!=stdout)
2222                  fclose(fp);
2223              } else {
2224                std::cout<<"Unable to open file "<<fileName<<std::endl;
2225              }
2226            } else {
2227              std::cout<<"** Current model not valid"<<std::endl;
2228             
2229            }
2230            break;
2231          case SAVESOL:
2232            if (goodModel) {
2233              // get next field
2234              field = CoinReadGetString(argc,argv);
2235              if (field=="$") {
2236                field = parameters[iParam].stringValue();
2237              } else if (field=="EOL") {
2238                parameters[iParam].printString();
2239                break;
2240              } else {
2241                parameters[iParam].setStringValue(field);
2242              }
2243              std::string fileName;
2244              if (field[0]=='/'||field[0]=='\\') {
2245                fileName = field;
2246              } else if (field[0]=='~') {
2247                char * environ = getenv("HOME");
2248                if (environ) {
2249                  std::string home(environ);
2250                  field=field.erase(0,1);
2251                  fileName = home+field;
2252                } else {
2253                  fileName=field;
2254                }
2255              } else {
2256                fileName = directory+field;
2257              }
2258              saveSolution(lpSolver,fileName);
2259            } else {
2260              std::cout<<"** Current model not valid"<<std::endl;
2261             
2262            }
2263            break;
2264          default:
2265            abort();
2266          }
2267        } 
2268      } else if (!numberMatches) {
2269        std::cout<<"No match for "<<field<<" - ? for list of commands"
2270                 <<std::endl;
2271      } else if (numberMatches==1) {
2272        if (!numberQuery) {
2273          std::cout<<"Short match for "<<field<<" - completion: ";
2274          std::cout<<parameters[firstMatch].matchName()<<std::endl;
2275        } else if (numberQuery) {
2276          std::cout<<parameters[firstMatch].matchName()<<" : ";
2277          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
2278          if (numberQuery>=2) 
2279            parameters[firstMatch].printLongHelp();
2280        }
2281      } else {
2282        if (!numberQuery) 
2283          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
2284                   <<std::endl;
2285        else
2286          std::cout<<"Completions of "<<field<<":"<<std::endl;
2287        for ( iParam=0; iParam<numberParameters; iParam++ ) {
2288          int match = parameters[iParam].matches(field);
2289          if (match&&parameters[iParam].displayThis()) {
2290            std::cout<<parameters[iParam].matchName();
2291            if (numberQuery>=2) 
2292              std::cout<<" : "<<parameters[iParam].shortHelp();
2293            std::cout<<std::endl;
2294          }
2295        }
2296      }
2297    }
2298  }
2299  // By now all memory should be freed
2300#ifdef DMALLOC
2301  dmalloc_log_unfreed();
2302  dmalloc_shutdown();
2303#endif
2304  return 0;
2305}   
Note: See TracBrowser for help on using the repository browser.