source: trunk/Test/CoinSolve.cpp @ 41

Last change on this file since 41 was 41, checked in by forrest, 17 years ago

refresh lpsolver

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