source: trunk/Test/CoinSolve.cpp @ 186

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

heuristics

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