source: trunk/Test/CoinSolve.cpp @ 169

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

for solve

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