source: trunk/Test/CoinSolve.cpp @ 183

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

renaming

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