source: trunk/Clp/src/ClpMain.cpp @ 1090

Last change on this file since 1090 was 1090, checked in by ladanyi, 13 years ago

fixed trailing backslash in directory specifications for Windows

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 71.0 KB
Line 
1// Copyright (C) 2002, 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#include "CoinSort.hpp"
17// History since 1.0 at end
18#define CLPVERSION "1.05.00"
19
20#include "CoinMpsIO.hpp"
21#include "CoinFileIO.hpp"
22
23#include "ClpFactorization.hpp"
24#include "CoinTime.hpp"
25#include "ClpSimplex.hpp"
26#include "ClpSimplexOther.hpp"
27#include "ClpSolve.hpp"
28#include "ClpPackedMatrix.hpp"
29#include "ClpPlusMinusOneMatrix.hpp"
30#include "ClpNetworkMatrix.hpp"
31#include "ClpDualRowSteepest.hpp"
32#include "ClpDualRowDantzig.hpp"
33#include "ClpLinearObjective.hpp"
34#include "ClpPrimalColumnSteepest.hpp"
35#include "ClpPrimalColumnDantzig.hpp"
36#include "ClpPresolve.hpp"
37#include "CbcOrClpParam.hpp"
38#ifdef DMALLOC
39#include "dmalloc.h"
40#endif
41#ifdef WSSMP_BARRIER
42#define FOREIGN_BARRIER
43#endif
44#ifdef UFL_BARRIER
45#define FOREIGN_BARRIER
46#endif
47#ifdef TAUCS_BARRIER
48#define FOREIGN_BARRIER
49#endif
50
51static double totalTime=0.0;
52static bool maskMatches(const int * starts, char ** masks,
53                        std::string & check);
54
55//#############################################################################
56
57#ifdef NDEBUG
58#undef NDEBUG
59#endif
60
61int mainTest (int argc, const char *argv[],int algorithm,
62              ClpSimplex empty, bool doPresolve,int switchOff,bool doVector);
63static void statistics(ClpSimplex * originalModel, ClpSimplex * model);
64static void generateCode(const char * fileName,int type);
65// Returns next valid field
66int CbcOrClpRead_mode=1;
67FILE * CbcOrClpReadCommand=stdin;
68int main (int argc, const char *argv[])
69{
70  // next {} is just to make sure all memory should be freed - for debug
71  {
72    double time1 = CoinCpuTime(),time2;
73    // Set up all non-standard stuff
74    //int numberModels=1;
75    ClpSimplex * models = new ClpSimplex[1];
76   
77    // default action on import
78    int allowImportErrors=0;
79    int keepImportNames=1;
80    int doIdiot=-1;
81    int outputFormat=2;
82    int slpValue=-1;
83    int cppValue=-1;
84    int printOptions=0;
85    int printMode=0;
86    int presolveOptions=0;
87    int doCrash=0;
88    int doVector=0;
89    int doSprint=-1;
90    // set reasonable defaults
91    int preSolve=5;
92    bool preSolveFile=false;
93    models->setPerturbation(50);
94    models->messageHandler()->setPrefix(false);
95    const char dirsep =  CoinFindDirSeparator();
96    std::string directory;
97    std::string dirSample;
98    std::string dirNetlib;
99    std::string dirMiplib;
100    if (dirsep == '/') {
101      directory = "./";
102      dirSample = "../../Data/Sample/";
103      dirNetlib = "../../Data/Netlib/";
104      dirMiplib = "../../Data/miplib3/";
105    } else {
106      directory = ".\\";
107      dirSample = "..\\..\\Data\\Sample\\";
108      dirNetlib = "..\\..\\Data\\Netlib\\";
109      dirMiplib = "..\\..\\Data\\miplib3\\";
110    }
111    std::string defaultDirectory = directory;
112    std::string importFile ="";
113    std::string exportFile ="default.mps";
114    std::string importBasisFile ="";
115    int basisHasValues=0;
116    int substitution=3;
117    int dualize=0;
118    std::string exportBasisFile ="default.bas";
119    std::string saveFile ="default.prob";
120    std::string restoreFile ="default.prob";
121    std::string solutionFile ="stdout";
122    std::string solutionSaveFile ="solution.file";
123    std::string printMask="";
124    CbcOrClpParam parameters[CBCMAXPARAMETERS];
125    int numberParameters ;
126    establishParams(numberParameters,parameters) ;
127    parameters[whichParam(BASISIN,numberParameters,parameters)].setStringValue(importBasisFile);
128    parameters[whichParam(BASISOUT,numberParameters,parameters)].setStringValue(exportBasisFile);
129    parameters[whichParam(PRINTMASK,numberParameters,parameters)].setStringValue(printMask);
130    parameters[whichParam(DIRECTORY,numberParameters,parameters)].setStringValue(directory);
131    parameters[whichParam(DIRSAMPLE,numberParameters,parameters)].setStringValue(dirSample);
132    parameters[whichParam(DIRNETLIB,numberParameters,parameters)].setStringValue(dirNetlib);
133    parameters[whichParam(DIRMIPLIB,numberParameters,parameters)].setStringValue(dirMiplib);
134    parameters[whichParam(DUALBOUND,numberParameters,parameters)].setDoubleValue(models->dualBound());
135    parameters[whichParam(DUALTOLERANCE,numberParameters,parameters)].setDoubleValue(models->dualTolerance());
136    parameters[whichParam(EXPORT,numberParameters,parameters)].setStringValue(exportFile);
137    parameters[whichParam(IDIOT,numberParameters,parameters)].setIntValue(doIdiot);
138    parameters[whichParam(IMPORT,numberParameters,parameters)].setStringValue(importFile);
139    parameters[whichParam(SOLVERLOGLEVEL,numberParameters,parameters)].setIntValue(models->logLevel());
140    parameters[whichParam(MAXFACTOR,numberParameters,parameters)].setIntValue(models->factorizationFrequency());
141    parameters[whichParam(MAXITERATION,numberParameters,parameters)].setIntValue(models->maximumIterations());
142    parameters[whichParam(OUTPUTFORMAT,numberParameters,parameters)].setIntValue(outputFormat);
143    parameters[whichParam(PRESOLVEPASS,numberParameters,parameters)].setIntValue(preSolve);
144    parameters[whichParam(PERTVALUE,numberParameters,parameters)].setIntValue(models->perturbation());
145    parameters[whichParam(PRIMALTOLERANCE,numberParameters,parameters)].setDoubleValue(models->primalTolerance());
146    parameters[whichParam(PRIMALWEIGHT,numberParameters,parameters)].setDoubleValue(models->infeasibilityCost());
147    parameters[whichParam(RESTORE,numberParameters,parameters)].setStringValue(restoreFile);
148    parameters[whichParam(SAVE,numberParameters,parameters)].setStringValue(saveFile);
149    parameters[whichParam(TIMELIMIT,numberParameters,parameters)].setDoubleValue(models->maximumSeconds());
150    parameters[whichParam(SOLUTION,numberParameters,parameters)].setStringValue(solutionFile);
151    parameters[whichParam(SAVESOL,numberParameters,parameters)].setStringValue(solutionSaveFile);
152    parameters[whichParam(SPRINT,numberParameters,parameters)].setIntValue(doSprint);
153    parameters[whichParam(SUBSTITUTION,numberParameters,parameters)].setIntValue(substitution);
154    parameters[whichParam(DUALIZE,numberParameters,parameters)].setIntValue(dualize);
155    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].setDoubleValue(1.0e-8);
156    int verbose=0;
157   
158    // total number of commands read
159    int numberGoodCommands=0;
160    bool * goodModels = new bool[1];
161
162    // Hidden stuff for barrier
163    int choleskyType = 0;
164    int gamma=0;
165    int scaleBarrier=0;
166    int doKKT=0;
167    int crossover=2; // do crossover unless quadratic
168   
169    int iModel=0;
170    goodModels[0]=false;
171    //models[0].scaling(1);
172    //models[0].setDualBound(1.0e6);
173    //models[0].setDualTolerance(1.0e-7);
174    //ClpDualRowSteepest steep;
175    //models[0].setDualRowPivotAlgorithm(steep);
176    //models[0].setPrimalTolerance(1.0e-7);
177    //ClpPrimalColumnSteepest steepP;
178    //models[0].setPrimalColumnPivotAlgorithm(steepP);
179    std::string field;
180    std::cout<<"Coin LP version "<<CLPVERSION
181             <<", build "<<__DATE__<<std::endl;
182    // Print command line
183    if (argc>1) {
184      printf("command line - ");
185      for (int i=0;i<argc;i++)
186        printf("%s ",argv[i]);
187      printf("\n");
188    }
189   
190    while (1) {
191      // next command
192      field=CoinReadGetCommand(argc,argv);
193     
194      // exit if null or similar
195      if (!field.length()) {
196        if (numberGoodCommands==1&&goodModels[0]) {
197          // we just had file name - do dual or primal
198          field="either";
199        } else if (!numberGoodCommands) {
200          // let's give the sucker a hint
201          std::cout
202            <<"Clp takes input from arguments ( - switches to stdin)"
203            <<std::endl
204            <<"Enter ? for list of commands or help"<<std::endl;
205          field="-";
206        } else {
207          break;
208        }
209      }
210     
211      // see if ? at end
212      int numberQuery=0;
213      if (field!="?"&&field!="???") {
214        int length = field.length();
215        int i;
216        for (i=length-1;i>0;i--) {
217          if (field[i]=='?') 
218            numberQuery++;
219          else
220            break;
221        }
222        field=field.substr(0,length-numberQuery);
223      }
224      // find out if valid command
225      int iParam;
226      int numberMatches=0;
227      int firstMatch=-1;
228      for ( iParam=0; iParam<numberParameters; iParam++ ) {
229        int match = parameters[iParam].matches(field);
230        if (match==1) {
231          numberMatches = 1;
232          firstMatch=iParam;
233          break;
234        } else {
235          if (match&&firstMatch<0)
236            firstMatch=iParam;
237          numberMatches += match>>1;
238        }
239      }
240      if (iParam<numberParameters&&!numberQuery) {
241        // found
242        CbcOrClpParam found = parameters[iParam];
243        CbcOrClpParameterType type = found.type();
244        int valid;
245        numberGoodCommands++;
246        if (type==GENERALQUERY) {
247          std::cout<<"In argument list keywords have leading - "
248            ", -stdin or just - switches to stdin"<<std::endl;
249          std::cout<<"One command per line (and no -)"<<std::endl;
250          std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
251          std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
252          std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
253          std::cout<<"abcd value sets value"<<std::endl;
254          std::cout<<"Commands are:"<<std::endl;
255          int maxAcross=5;
256          bool evenHidden=false;
257          if ((verbose&8)!=0) {
258            // even hidden
259            evenHidden = true;
260            verbose &= ~8;
261          }
262          if (verbose)
263            maxAcross=1;
264          int limits[]={1,101,201,301,401};
265          std::vector<std::string> types;
266          types.push_back("Double parameters:");
267          types.push_back("Int parameters:");
268          types.push_back("Keyword parameters:");
269          types.push_back("Actions or string parameters:");
270          int iType;
271          for (iType=0;iType<4;iType++) {
272            int across=0;
273            if ((verbose%4)!=0)
274              std::cout<<std::endl;
275            std::cout<<types[iType]<<std::endl;
276            if ((verbose&2)!=0)
277              std::cout<<std::endl;
278            for ( iParam=0; iParam<numberParameters; iParam++ ) {
279              int type = parameters[iParam].type();
280              if ((parameters[iParam].displayThis()||evenHidden)&&
281                  type>=limits[iType]
282                  &&type<limits[iType+1]) {
283                if (!across) {
284                  if ((verbose&2)==0) 
285                    std::cout<<"  ";
286                  else
287                    std::cout<<"Command ";
288                }
289                std::cout<<parameters[iParam].matchName()<<"  ";
290                across++;
291                if (across==maxAcross) {
292                  across=0;
293                  if (verbose) {
294                    // put out description as well
295                    if ((verbose&1)!=0) 
296                      std::cout<<parameters[iParam].shortHelp();
297                    std::cout<<std::endl;
298                    if ((verbose&2)!=0) {
299                      std::cout<<"---- description"<<std::endl;
300                      parameters[iParam].printLongHelp();
301                      std::cout<<"----"<<std::endl<<std::endl;
302                    }
303                  } else {
304                    std::cout<<std::endl;
305                  }
306                }
307              }
308            }
309            if (across)
310              std::cout<<std::endl;
311          }
312        } else if (type==FULLGENERALQUERY) {
313          std::cout<<"Full list of commands is:"<<std::endl;
314          int maxAcross=5;
315          int limits[]={1,101,201,301,401};
316          std::vector<std::string> types;
317          types.push_back("Double parameters:");
318          types.push_back("Int parameters:");
319          types.push_back("Keyword parameters and others:");
320          types.push_back("Actions:");
321          int iType;
322          for (iType=0;iType<4;iType++) {
323            int across=0;
324            std::cout<<types[iType]<<std::endl;
325            for ( iParam=0; iParam<numberParameters; iParam++ ) {
326              int type = parameters[iParam].type();
327              if (type>=limits[iType]
328                  &&type<limits[iType+1]) {
329                if (!across)
330                  std::cout<<"  ";
331                std::cout<<parameters[iParam].matchName()<<"  ";
332                across++;
333                if (across==maxAcross) {
334                  std::cout<<std::endl;
335                  across=0;
336                }
337              }
338            }
339            if (across)
340              std::cout<<std::endl;
341          }
342        } else if (type<101) {
343          // get next field as double
344          double value = CoinReadGetDoubleField(argc,argv,&valid);
345          if (!valid) {
346            parameters[iParam].setDoubleParameter(models+iModel,value);
347          } else if (valid==1) {
348            std::cout<<" is illegal for double parameter "<<parameters[iParam].name()<<" value remains "<<
349              parameters[iParam].doubleValue()<<std::endl;
350          } else {
351            std::cout<<parameters[iParam].name()<<" has value "<<
352              parameters[iParam].doubleValue()<<std::endl;
353          }
354        } else if (type<201) {
355          // get next field as int
356          int value = CoinReadGetIntField(argc,argv,&valid);
357          if (!valid) {
358            if (parameters[iParam].type()==PRESOLVEPASS)
359              preSolve = value;
360            else if (parameters[iParam].type()==IDIOT)
361              doIdiot = value;
362            else if (parameters[iParam].type()==SPRINT)
363              doSprint = value;
364            else if (parameters[iParam].type()==OUTPUTFORMAT)
365              outputFormat = value;
366            else if (parameters[iParam].type()==SLPVALUE)
367              slpValue = value;
368            else if (parameters[iParam].type()==CPP)
369              cppValue = value;
370            else if (parameters[iParam].type()==PRESOLVEOPTIONS)
371              presolveOptions = value;
372            else if (parameters[iParam].type()==PRINTOPTIONS)
373              printOptions = value;
374            else if (parameters[iParam].type()==SUBSTITUTION)
375              substitution = value;
376            else if (parameters[iParam].type()==DUALIZE)
377              dualize = value;
378            else if (parameters[iParam].type()==VERBOSE)
379              verbose = value;
380            parameters[iParam].setIntParameter(models+iModel,value);
381          } else if (valid==1) {
382            std::cout<<" is illegal for integer parameter "<<parameters[iParam].name()<<" value remains "<<
383              parameters[iParam].intValue()<<std::endl;
384          } else {
385            std::cout<<parameters[iParam].name()<<" has value "<<
386              parameters[iParam].intValue()<<std::endl;
387          }
388        } else if (type<301) {
389          // one of several strings
390          std::string value = CoinReadGetString(argc,argv);
391          int action = parameters[iParam].parameterOption(value);
392          if (action<0) {
393            if (value!="EOL") {
394              // no match
395              parameters[iParam].printOptions();
396            } else {
397              // print current value
398              std::cout<<parameters[iParam].name()<<" has value "<<
399                parameters[iParam].currentOption()<<std::endl;
400            }
401          } else {
402            parameters[iParam].setCurrentOption(action);
403            // for now hard wired
404            switch (type) {
405            case DIRECTION:
406              if (action==0)
407                models[iModel].setOptimizationDirection(1);
408              else if (action==1)
409                models[iModel].setOptimizationDirection(-1);
410              else
411                models[iModel].setOptimizationDirection(0);
412              break;
413            case DUALPIVOT:
414              if (action==0) {
415                ClpDualRowSteepest steep(3);
416                models[iModel].setDualRowPivotAlgorithm(steep);
417              } else if (action==1) {
418                //ClpDualRowDantzig dantzig;
419                ClpDualRowSteepest dantzig(5);
420                models[iModel].setDualRowPivotAlgorithm(dantzig);
421              } else if (action==2) {
422                // partial steep
423                ClpDualRowSteepest steep(2);
424                models[iModel].setDualRowPivotAlgorithm(steep);
425              } else {
426                ClpDualRowSteepest steep;
427                models[iModel].setDualRowPivotAlgorithm(steep);
428              }
429              break;
430            case PRIMALPIVOT:
431              if (action==0) {
432                ClpPrimalColumnSteepest steep(3);
433                models[iModel].setPrimalColumnPivotAlgorithm(steep);
434              } else if (action==1) {
435                ClpPrimalColumnSteepest steep(0);
436                models[iModel].setPrimalColumnPivotAlgorithm(steep);
437              } else if (action==2) {
438                ClpPrimalColumnDantzig dantzig;
439                models[iModel].setPrimalColumnPivotAlgorithm(dantzig);
440              } else if (action==3) {
441                ClpPrimalColumnSteepest steep(2);
442                models[iModel].setPrimalColumnPivotAlgorithm(steep);
443              } else if (action==4) {
444                ClpPrimalColumnSteepest steep(1);
445                models[iModel].setPrimalColumnPivotAlgorithm(steep);
446              } else if (action==5) {
447                ClpPrimalColumnSteepest steep(4);
448                models[iModel].setPrimalColumnPivotAlgorithm(steep);
449              } else if (action==6) {
450                ClpPrimalColumnSteepest steep(10);
451                models[iModel].setPrimalColumnPivotAlgorithm(steep);
452              }
453              break;
454            case SCALING:
455              models[iModel].scaling(action);
456              break;
457            case AUTOSCALE:
458              models[iModel].setAutomaticScaling(action!=0);
459              break;
460            case SPARSEFACTOR:
461              models[iModel].setSparseFactorization((1-action)!=0);
462              break;
463            case BIASLU:
464              models[iModel].factorization()->setBiasLU(action);
465              break;
466            case PERTURBATION:
467              if (action==0)
468                models[iModel].setPerturbation(50);
469              else
470                models[iModel].setPerturbation(100);
471              break;
472            case ERRORSALLOWED:
473              allowImportErrors = action;
474              break;
475            case INTPRINT:
476              printMode=action;
477              break;
478            case KEEPNAMES:
479              keepImportNames = 1-action;
480              break;
481            case PRESOLVE:
482              if (action==0)
483                preSolve = 5;
484              else if (action==1)
485                preSolve=0;
486              else if (action==2)
487                preSolve=10;
488              else
489                preSolveFile=true;
490              break;
491            case PFI:
492              models[iModel].factorization()->setForrestTomlin(action==0);
493              break;
494            case CRASH:
495              doCrash=action;
496              break;
497            case VECTOR:
498              doVector=action;
499              break;
500            case MESSAGES:
501              models[iModel].messageHandler()->setPrefix(action!=0);
502              break;
503            case CHOLESKY:
504              choleskyType = action;
505              break;
506            case GAMMA:
507              gamma=action;
508              break;
509            case BARRIERSCALE:
510              scaleBarrier=action;
511              break;
512            case KKT:
513              doKKT=action;
514              break;
515            case CROSSOVER:
516              crossover=action;
517              break;
518            default:
519              abort();
520            }
521          }
522        } else {
523          // action
524          if (type==EXIT)
525            break; // stop all
526          switch (type) {
527          case DUALSIMPLEX:
528          case PRIMALSIMPLEX:
529          case EITHERSIMPLEX:
530          case BARRIER:
531            // synonym for dual
532          case BAB:
533            if (goodModels[iModel]) {
534              double objScale = 
535                parameters[whichParam(OBJSCALE2,numberParameters,parameters)].doubleValue();
536              if (objScale!=1.0) {
537                int iColumn;
538                int numberColumns=models[iModel].numberColumns();
539                double * dualColumnSolution = 
540                  models[iModel].dualColumnSolution();
541                ClpObjective * obj = models[iModel].objectiveAsObject();
542                assert(dynamic_cast<ClpLinearObjective *> (obj));
543                double offset;
544                double * objective = obj->gradient(NULL,NULL,offset,true);
545                for (iColumn=0;iColumn<numberColumns;iColumn++) {
546                  dualColumnSolution[iColumn] *= objScale;
547                  objective[iColumn] *= objScale;;
548                }
549                int iRow;
550                int numberRows=models[iModel].numberRows();
551                double * dualRowSolution = 
552                  models[iModel].dualRowSolution();
553                for (iRow=0;iRow<numberRows;iRow++) 
554                  dualRowSolution[iRow] *= objScale;
555                models[iModel].setObjectiveOffset(objScale*models[iModel].objectiveOffset());
556              }
557              ClpSolve::SolveType method;
558              ClpSolve::PresolveType presolveType;
559              ClpSimplex * model2 = models+iModel;
560              if (dualize) {
561                model2 = ((ClpSimplexOther *) model2)->dualOfModel();
562                printf("Dual of model has %d rows and %d columns\n",
563                       model2->numberRows(),model2->numberColumns());
564                model2->setOptimizationDirection(1.0);
565              }
566              ClpSolve solveOptions;
567              solveOptions.setPresolveActions(presolveOptions);
568              solveOptions.setSubstitution(substitution);
569              if (preSolve!=5&&preSolve) {
570                presolveType=ClpSolve::presolveNumber;
571                if (preSolve<0) {
572                  preSolve = - preSolve;
573                  if (preSolve<=100) {
574                    presolveType=ClpSolve::presolveNumber;
575                    printf("Doing %d presolve passes - picking up non-costed slacks\n",
576                           preSolve);
577                    solveOptions.setDoSingletonColumn(true);
578                  } else {
579                    preSolve -=100;
580                    presolveType=ClpSolve::presolveNumberCost;
581                    printf("Doing %d presolve passes - picking up costed slacks\n",
582                           preSolve);
583                  }
584                } 
585              } else if (preSolve) {
586                presolveType=ClpSolve::presolveOn;
587              } else {
588                presolveType=ClpSolve::presolveOff;
589              }
590              solveOptions.setPresolveType(presolveType,preSolve);
591              if (type==DUALSIMPLEX||type==BAB) {
592                method=ClpSolve::useDual;
593              } else if (type==PRIMALSIMPLEX) {
594                method=ClpSolve::usePrimalorSprint;
595              } else if (type==EITHERSIMPLEX) {
596                method=ClpSolve::automatic;
597              } else {
598                method = ClpSolve::useBarrier;
599                if (crossover==1) {
600                  method=ClpSolve::useBarrierNoCross;
601                } else if (crossover==2) {
602                  ClpObjective * obj = models[iModel].objectiveAsObject();
603                  if (obj->type()>1) {
604                    method=ClpSolve::useBarrierNoCross;
605                    presolveType=ClpSolve::presolveOff;
606                    solveOptions.setPresolveType(presolveType,preSolve);
607                  } 
608                }
609              }
610              solveOptions.setSolveType(method);
611              if(preSolveFile)
612                presolveOptions |= 0x40000000;
613              solveOptions.setSpecialOption(4,presolveOptions);
614              solveOptions.setSpecialOption(5,printOptions&1);
615              if (doVector) {
616                ClpMatrixBase * matrix = models[iModel].clpMatrix();
617                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
618                  ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
619                  clpMatrix->makeSpecialColumnCopy();
620                }
621              }
622              if (method==ClpSolve::useDual) {
623                // dual
624                if (doCrash)
625                  solveOptions.setSpecialOption(0,1,doCrash); // crash
626                else if (doIdiot)
627                  solveOptions.setSpecialOption(0,2,doIdiot); // possible idiot
628              } else if (method==ClpSolve::usePrimalorSprint) {
629                // primal
630                // if slp turn everything off
631                if (slpValue>0) {
632                  doCrash=false;
633                  doSprint=0;
634                  doIdiot=-1;
635                  solveOptions.setSpecialOption(1,10,slpValue); // slp
636                  method=ClpSolve::usePrimal;
637                }
638                if (doCrash) {
639                  solveOptions.setSpecialOption(1,1,doCrash); // crash
640                } else if (doSprint>0) {
641                  // sprint overrides idiot
642                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
643                } else if (doIdiot>0) {
644                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
645                } else if (slpValue<=0) {
646                  if (doIdiot==0) {
647                    if (doSprint==0)
648                      solveOptions.setSpecialOption(1,4); // all slack
649                    else
650                      solveOptions.setSpecialOption(1,9); // all slack or sprint
651                  } else {
652                    if (doSprint==0)
653                      solveOptions.setSpecialOption(1,8); // all slack or idiot
654                    else
655                      solveOptions.setSpecialOption(1,7); // initiative
656                  }
657                }
658                if (basisHasValues==-1)
659                  solveOptions.setSpecialOption(1,11); // switch off values
660              } else if (method==ClpSolve::useBarrier||method==ClpSolve::useBarrierNoCross) {
661                int barrierOptions = choleskyType;
662                if (scaleBarrier)
663                  barrierOptions |= 8;
664                if (doKKT)
665                  barrierOptions |= 16;
666                if (gamma)
667                  barrierOptions |= 32*gamma;
668                if (crossover==3) 
669                  barrierOptions |= 256; // try presolve in crossover
670                solveOptions.setSpecialOption(4,barrierOptions);
671              }
672              int status;
673              if (cppValue>=0) {
674                // generate code
675                FILE * fp = fopen("user_driver.cpp","w");
676                if (fp) {
677                  // generate enough to do solveOptions
678                  model2->generateCpp(fp);
679                  solveOptions.generateCpp(fp);
680                  fclose(fp);
681                  // now call generate code
682                  generateCode("user_driver.cpp",cppValue);
683                } else {
684                  std::cout<<"Unable to open file user_driver.cpp"<<std::endl;
685                }
686              }
687              try {
688                status=model2->initialSolve(solveOptions);
689              }
690              catch (CoinError e) {
691                e.print();
692                status=-1;
693              }
694              if (dualize) {
695                int returnCode=((ClpSimplexOther *) models+iModel)->restoreFromDual(model2);
696                delete model2;
697                if (returnCode&&dualize!=2)
698                  models[iModel].primal(1);
699              }
700              if (status>=0)
701                basisHasValues=1;
702            } else {
703              std::cout<<"** Current model not valid"<<std::endl;
704            }
705            break;
706          case STATISTICS:
707            if (goodModels[iModel]) {
708              // If presolve on look at presolved
709              bool deleteModel2=false;
710              ClpSimplex * model2 = models+iModel;
711              if (preSolve) {
712                ClpPresolve pinfo;
713                int presolveOptions2 = presolveOptions&~0x40000000;
714                if ((presolveOptions2&0xffff)!=0)
715                  pinfo.setPresolveActions(presolveOptions2);
716                pinfo.setSubstitution(substitution);
717                if ((printOptions&1)!=0)
718                  pinfo.statistics();
719                double presolveTolerance = 
720                  parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
721                model2 = 
722                  pinfo.presolvedModel(models[iModel],presolveTolerance,
723                                       true,preSolve);
724                if (model2) {
725                  printf("Statistics for presolved model\n");
726                  deleteModel2=true;
727                } else {
728                  printf("Presolved model looks infeasible - will use unpresolved\n");
729                  model2 = models+iModel;
730                }
731              } else {
732                printf("Statistics for unpresolved model\n");
733                model2 =  models+iModel;
734              }
735              statistics(models+iModel,model2);
736              if (deleteModel2)
737                delete model2;
738            } else {
739              std::cout<<"** Current model not valid"<<std::endl;
740            }
741            break;
742          case TIGHTEN:
743            if (goodModels[iModel]) {
744              int numberInfeasibilities = models[iModel].tightenPrimalBounds();
745              if (numberInfeasibilities)
746                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
747            } else {
748              std::cout<<"** Current model not valid"<<std::endl;
749            }
750            break;
751          case PLUSMINUS:
752            if (goodModels[iModel]) {
753              ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
754              ClpPackedMatrix* clpMatrix =
755                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
756              if (clpMatrix) {
757                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
758                if (newMatrix->getIndices()) {
759                  models[iModel].replaceMatrix(newMatrix);
760                  delete saveMatrix;
761                  std::cout<<"Matrix converted to +- one matrix"<<std::endl;
762                } else {
763                  std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
764                }
765              } else {
766                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
767              }
768            } else {
769              std::cout<<"** Current model not valid"<<std::endl;
770            }
771            break;
772          case NETWORK:
773            if (goodModels[iModel]) {
774              ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
775              ClpPackedMatrix* clpMatrix =
776                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
777              if (clpMatrix) {
778                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
779                if (newMatrix->getIndices()) {
780                  models[iModel].replaceMatrix(newMatrix);
781                  delete saveMatrix;
782                  std::cout<<"Matrix converted to network matrix"<<std::endl;
783                } else {
784                  std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
785                }
786              } else {
787                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
788              }
789            } else {
790              std::cout<<"** Current model not valid"<<std::endl;
791            }
792            break;
793          case IMPORT:
794            {
795              // get next field
796              field = CoinReadGetString(argc,argv);
797              if (field=="$") {
798                field = parameters[iParam].stringValue();
799              } else if (field=="EOL") {
800                parameters[iParam].printString();
801                break;
802              } else {
803                parameters[iParam].setStringValue(field);
804              }
805              std::string fileName;
806              bool canOpen=false;
807              // See if gmpl file
808              int gmpl=0;
809              std::string gmplData;
810              if (field=="-") {
811                // stdin
812                canOpen=true;
813                fileName = "-";
814              } else {
815                // See if .lp
816                {
817                  const char * c_name = field.c_str();
818                  int length = strlen(c_name);
819                  if (length>3&&!strncmp(c_name+length-3,".lp",3))
820                    gmpl=-1; // .lp
821                }
822                bool absolutePath;
823                if (dirsep=='/') {
824                  // non Windows (or cygwin)
825                  absolutePath=(field[0]=='/');
826                } else {
827                  //Windows (non cycgwin)
828                  absolutePath=(field[0]=='\\');
829                  // but allow for :
830                  if (strchr(field.c_str(),':'))
831                    absolutePath=true;
832                }
833                if (absolutePath) {
834                  fileName = field;
835                } else if (field[0]=='~') {
836                  char * environVar = getenv("HOME");
837                  if (environVar) {
838                    std::string home(environVar);
839                    field=field.erase(0,1);
840                    fileName = home+field;
841                  } else {
842                    fileName=field;
843                  }
844                } else {
845                  fileName = directory+field;
846                  // See if gmpl (model & data) - or even lp file
847                  int length = field.size();
848                  int percent = field.find('%');
849                  if (percent<length&&percent>0) {
850                    gmpl=1;
851                    fileName = directory+field.substr(0,percent);
852                    gmplData = directory+field.substr(percent+1);
853                    if (percent<length-1)
854                      gmpl=2; // two files
855                    printf("GMPL model file %s and data file %s\n",
856                           fileName.c_str(),gmplData.c_str());
857                  }
858                }
859                std::string name=fileName;
860                if (fileCoinReadable(name)) {
861                  // can open - lets go for it
862                  canOpen=true;
863                  if (gmpl==2) {
864                    FILE *fp;
865                    fp=fopen(gmplData.c_str(),"r");
866                    if (fp) {
867                      fclose(fp);
868                    } else {
869                      canOpen=false;
870                      std::cout<<"Unable to open file "<<gmplData<<std::endl;
871                    }
872                  }
873                } else {
874                  std::cout<<"Unable to open file "<<fileName<<std::endl;
875                }
876              }
877              if (canOpen) {
878                int status;
879                if (!gmpl)
880                  status =models[iModel].readMps(fileName.c_str(),
881                                                 keepImportNames!=0,
882                                                 allowImportErrors!=0);
883                else if (gmpl>0)
884                  status= models[iModel].readGMPL(fileName.c_str(),
885                                                  (gmpl==2) ? gmplData.c_str() : NULL,
886                                                  keepImportNames!=0);
887                else
888                  status= models[iModel].readLp(fileName.c_str(),1.0e-12);
889                if (!status||(status>0&&allowImportErrors)) {
890                  goodModels[iModel]=true;
891                  // sets to all slack (not necessary?)
892                  models[iModel].createStatus();
893                  time2 = CoinCpuTime();
894                  totalTime += time2-time1;
895                  time1=time2;
896                  // Go to canned file if just input file
897                  if (CbcOrClpRead_mode==2&&argc==2) {
898                    // only if ends .mps
899                    char * find = (char *)strstr(fileName.c_str(),".mps");
900                    if (find&&find[4]=='\0') {
901                      find[1]='p'; find[2]='a';find[3]='r';
902                      FILE *fp=fopen(fileName.c_str(),"r");
903                      if (fp) {
904                        CbcOrClpReadCommand=fp; // Read from that file
905                        CbcOrClpRead_mode=-1;
906                      }
907                    }
908                  }
909                } else {
910                  // errors
911                  std::cout<<"There were "<<status<<
912                    " errors on input"<<std::endl;
913                }
914              }
915            }
916            break;
917          case EXPORT:
918            if (goodModels[iModel]) {
919              double objScale = 
920                parameters[whichParam(OBJSCALE2,numberParameters,parameters)].doubleValue();
921              if (objScale!=1.0) {
922                int iColumn;
923                int numberColumns=models[iModel].numberColumns();
924                double * dualColumnSolution = 
925                  models[iModel].dualColumnSolution();
926                ClpObjective * obj = models[iModel].objectiveAsObject();
927                assert(dynamic_cast<ClpLinearObjective *> (obj));
928                double offset;
929                double * objective = obj->gradient(NULL,NULL,offset,true);
930                for (iColumn=0;iColumn<numberColumns;iColumn++) {
931                  dualColumnSolution[iColumn] *= objScale;
932                  objective[iColumn] *= objScale;;
933                }
934                int iRow;
935                int numberRows=models[iModel].numberRows();
936                double * dualRowSolution = 
937                  models[iModel].dualRowSolution();
938                for (iRow=0;iRow<numberRows;iRow++) 
939                  dualRowSolution[iRow] *= objScale;
940                models[iModel].setObjectiveOffset(objScale*models[iModel].objectiveOffset());
941              }
942              // get next field
943              field = CoinReadGetString(argc,argv);
944              if (field=="$") {
945                field = parameters[iParam].stringValue();
946              } else if (field=="EOL") {
947                parameters[iParam].printString();
948                break;
949              } else {
950                parameters[iParam].setStringValue(field);
951              }
952              std::string fileName;
953              bool canOpen=false;
954              if (field[0]=='/'||field[0]=='\\') {
955                fileName = field;
956              } else if (field[0]=='~') {
957                char * environVar = getenv("HOME");
958                if (environVar) {
959                  std::string home(environVar);
960                  field=field.erase(0,1);
961                  fileName = home+field;
962                } else {
963                  fileName=field;
964                }
965              } else {
966                fileName = directory+field;
967              }
968              FILE *fp=fopen(fileName.c_str(),"w");
969              if (fp) {
970                // can open - lets go for it
971                fclose(fp);
972                canOpen=true;
973              } else {
974                std::cout<<"Unable to open file "<<fileName<<std::endl;
975              }
976              if (canOpen) {
977                // If presolve on then save presolved
978                bool deleteModel2=false;
979                ClpSimplex * model2 = models+iModel;
980                if (dualize) {
981                  model2 = ((ClpSimplexOther *) model2)->dualOfModel();
982                  printf("Dual of model has %d rows and %d columns\n",
983                         model2->numberRows(),model2->numberColumns());
984                  model2->setOptimizationDirection(1.0);
985                  preSolve=0; // as picks up from model
986                }
987                if (preSolve) {
988                  ClpPresolve pinfo;
989                  int presolveOptions2 = presolveOptions&~0x40000000;
990                  if ((presolveOptions2&0xffff)!=0)
991                    pinfo.setPresolveActions(presolveOptions2);
992                  pinfo.setSubstitution(substitution);
993                  if ((printOptions&1)!=0)
994                    pinfo.statistics();
995                  double presolveTolerance = 
996                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
997                  model2 = 
998                    pinfo.presolvedModel(models[iModel],presolveTolerance,
999                                         true,preSolve,false,false);
1000                  if (model2) {
1001                    printf("Saving presolved model on %s\n",
1002                           fileName.c_str());
1003                    deleteModel2=true;
1004                  } else {
1005                    printf("Presolved model looks infeasible - saving original on %s\n",
1006                           fileName.c_str());
1007                    deleteModel2=false;
1008                    model2 = models+iModel;
1009
1010                  }
1011                } else {
1012                  printf("Saving model on %s\n",
1013                           fileName.c_str());
1014                }
1015#if 0
1016                // Convert names
1017                int iRow;
1018                int numberRows=model2->numberRows();
1019                int iColumn;
1020                int numberColumns=model2->numberColumns();
1021
1022                char ** rowNames = NULL;
1023                char ** columnNames = NULL;
1024                if (model2->lengthNames()) {
1025                  rowNames = new char * [numberRows];
1026                  for (iRow=0;iRow<numberRows;iRow++) {
1027                    rowNames[iRow] =
1028                      strdup(model2->rowName(iRow).c_str());
1029#ifdef STRIPBLANKS
1030                    char * xx = rowNames[iRow];
1031                    int i;
1032                    int length = strlen(xx);
1033                    int n=0;
1034                    for (i=0;i<length;i++) {
1035                      if (xx[i]!=' ')
1036                        xx[n++]=xx[i];
1037                    }
1038                    xx[n]='\0';
1039#endif
1040                  }
1041                 
1042                  columnNames = new char * [numberColumns];
1043                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1044                    columnNames[iColumn] =
1045                      strdup(model2->columnName(iColumn).c_str());
1046#ifdef STRIPBLANKS
1047                    char * xx = columnNames[iColumn];
1048                    int i;
1049                    int length = strlen(xx);
1050                    int n=0;
1051                    for (i=0;i<length;i++) {
1052                      if (xx[i]!=' ')
1053                        xx[n++]=xx[i];
1054                    }
1055                    xx[n]='\0';
1056#endif
1057                  }
1058                }
1059                CoinMpsIO writer;
1060                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
1061                                  model2->getColLower(), model2->getColUpper(),
1062                                  model2->getObjCoefficients(),
1063                                  (const char*) 0 /*integrality*/,
1064                                  model2->getRowLower(), model2->getRowUpper(),
1065                                  columnNames, rowNames);
1066                // Pass in array saying if each variable integer
1067                writer.copyInIntegerInformation(model2->integerInformation());
1068                writer.setObjectiveOffset(model2->objectiveOffset());
1069                writer.writeMps(fileName.c_str(),0,1,1);
1070                if (rowNames) {
1071                  for (iRow=0;iRow<numberRows;iRow++) {
1072                    free(rowNames[iRow]);
1073                  }
1074                  delete [] rowNames;
1075                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1076                    free(columnNames[iColumn]);
1077                  }
1078                  delete [] columnNames;
1079                }
1080#else
1081                model2->writeMps(fileName.c_str(),(outputFormat-1)/2,1+((outputFormat-1)&1));
1082#endif
1083                if (deleteModel2)
1084                  delete model2;
1085                time2 = CoinCpuTime();
1086                totalTime += time2-time1;
1087                time1=time2;
1088              }
1089            } else {
1090              std::cout<<"** Current model not valid"<<std::endl;
1091            }
1092            break;
1093          case BASISIN:
1094            if (goodModels[iModel]) {
1095              // get next field
1096              field = CoinReadGetString(argc,argv);
1097              if (field=="$") {
1098                field = parameters[iParam].stringValue();
1099              } else if (field=="EOL") {
1100                parameters[iParam].printString();
1101                break;
1102              } else {
1103                parameters[iParam].setStringValue(field);
1104              }
1105              std::string fileName;
1106              bool canOpen=false;
1107              if (field=="-") {
1108                // stdin
1109                canOpen=true;
1110                fileName = "-";
1111              } else {
1112                if (field[0]=='/'||field[0]=='\\') {
1113                  fileName = field;
1114                } else if (field[0]=='~') {
1115                  char * environVar = getenv("HOME");
1116                  if (environVar) {
1117                    std::string home(environVar);
1118                    field=field.erase(0,1);
1119                    fileName = home+field;
1120                  } else {
1121                    fileName=field;
1122                  }
1123                } else {
1124                  fileName = directory+field;
1125                }
1126                FILE *fp=fopen(fileName.c_str(),"r");
1127                if (fp) {
1128                  // can open - lets go for it
1129                  fclose(fp);
1130                  canOpen=true;
1131                } else {
1132                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1133                }
1134              }
1135              if (canOpen) {
1136                int values = models[iModel].readBasis(fileName.c_str());
1137                if (values==0)
1138                  basisHasValues=-1;
1139                else
1140                  basisHasValues=1;
1141              }
1142            } else {
1143              std::cout<<"** Current model not valid"<<std::endl;
1144            }
1145            break;
1146          case PRINTMASK:
1147            // get next field
1148            {
1149              std::string name = CoinReadGetString(argc,argv);
1150              if (name!="EOL") {
1151                parameters[iParam].setStringValue(name);
1152                printMask = name;
1153              } else {
1154                parameters[iParam].printString();
1155              }
1156            }
1157            break;
1158          case BASISOUT:
1159            if (goodModels[iModel]) {
1160              // get next field
1161              field = CoinReadGetString(argc,argv);
1162              if (field=="$") {
1163                field = parameters[iParam].stringValue();
1164              } else if (field=="EOL") {
1165                parameters[iParam].printString();
1166                break;
1167              } else {
1168                parameters[iParam].setStringValue(field);
1169              }
1170              std::string fileName;
1171              bool canOpen=false;
1172              if (field[0]=='/'||field[0]=='\\') {
1173                fileName = field;
1174              } else if (field[0]=='~') {
1175                char * environVar = getenv("HOME");
1176                if (environVar) {
1177                  std::string home(environVar);
1178                  field=field.erase(0,1);
1179                  fileName = home+field;
1180                } else {
1181                  fileName=field;
1182                }
1183              } else {
1184                fileName = directory+field;
1185              }
1186              FILE *fp=fopen(fileName.c_str(),"w");
1187              if (fp) {
1188                // can open - lets go for it
1189                fclose(fp);
1190                canOpen=true;
1191              } else {
1192                std::cout<<"Unable to open file "<<fileName<<std::endl;
1193              }
1194              if (canOpen) {
1195                ClpSimplex * model2 = models+iModel;
1196                model2->writeBasis(fileName.c_str(),outputFormat>1,outputFormat-2);
1197                time2 = CoinCpuTime();
1198                totalTime += time2-time1;
1199                time1=time2;
1200              }
1201            } else {
1202              std::cout<<"** Current model not valid"<<std::endl;
1203            }
1204            break;
1205          case SAVE:
1206            {
1207              // get next field
1208              field = CoinReadGetString(argc,argv);
1209              if (field=="$") {
1210                field = parameters[iParam].stringValue();
1211              } else if (field=="EOL") {
1212                parameters[iParam].printString();
1213                break;
1214              } else {
1215                parameters[iParam].setStringValue(field);
1216              }
1217              std::string fileName;
1218              bool canOpen=false;
1219              if (field[0]=='/'||field[0]=='\\') {
1220                fileName = field;
1221              } else if (field[0]=='~') {
1222                char * environVar = getenv("HOME");
1223                if (environVar) {
1224                  std::string home(environVar);
1225                  field=field.erase(0,1);
1226                  fileName = home+field;
1227                } else {
1228                  fileName=field;
1229                }
1230              } else {
1231                fileName = directory+field;
1232              }
1233              FILE *fp=fopen(fileName.c_str(),"wb");
1234              if (fp) {
1235                // can open - lets go for it
1236                fclose(fp);
1237                canOpen=true;
1238              } else {
1239                std::cout<<"Unable to open file "<<fileName<<std::endl;
1240              }
1241              if (canOpen) {
1242                int status;
1243                // If presolve on then save presolved
1244                bool deleteModel2=false;
1245                ClpSimplex * model2 = models+iModel;
1246                if (preSolve) {
1247                  ClpPresolve pinfo;
1248                  double presolveTolerance = 
1249                    parameters[whichParam(PRESOLVETOLERANCE,numberParameters,parameters)].doubleValue();
1250                  model2 = 
1251                    pinfo.presolvedModel(models[iModel],presolveTolerance,
1252                                         false,preSolve);
1253                  if (model2) {
1254                    printf("Saving presolved model on %s\n",
1255                           fileName.c_str());
1256                    deleteModel2=true;
1257                  } else {
1258                    printf("Presolved model looks infeasible - saving original on %s\n",
1259                           fileName.c_str());
1260                    deleteModel2=false;
1261                    model2 = models+iModel;
1262
1263                  }
1264                } else {
1265                  printf("Saving model on %s\n",
1266                           fileName.c_str());
1267                }
1268                status =model2->saveModel(fileName.c_str());
1269                if (deleteModel2)
1270                  delete model2;
1271                if (!status) {
1272                  goodModels[iModel]=true;
1273                  time2 = CoinCpuTime();
1274                  totalTime += time2-time1;
1275                  time1=time2;
1276                } else {
1277                  // errors
1278                  std::cout<<"There were errors on output"<<std::endl;
1279                }
1280              }
1281            }
1282            break;
1283          case RESTORE:
1284            {
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 * environVar = getenv("HOME");
1301                if (environVar) {
1302                  std::string home(environVar);
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(),"rb");
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                int status =models[iModel].restoreModel(fileName.c_str());
1321                if (!status) {
1322                  goodModels[iModel]=true;
1323                  time2 = CoinCpuTime();
1324                  totalTime += time2-time1;
1325                  time1=time2;
1326                } else {
1327                  // errors
1328                  std::cout<<"There were errors on input"<<std::endl;
1329                }
1330              }
1331            }
1332            break;
1333          case MAXIMIZE:
1334            models[iModel].setOptimizationDirection(-1);
1335            break;
1336          case MINIMIZE:
1337            models[iModel].setOptimizationDirection(1);
1338            break;
1339          case ALLSLACK:
1340            models[iModel].allSlackBasis(true);
1341            break;
1342          case REVERSE:
1343            if (goodModels[iModel]) {
1344              int iColumn;
1345              int numberColumns=models[iModel].numberColumns();
1346              double * dualColumnSolution = 
1347                models[iModel].dualColumnSolution();
1348              ClpObjective * obj = models[iModel].objectiveAsObject();
1349              assert(dynamic_cast<ClpLinearObjective *> (obj));
1350              double offset;
1351              double * objective = obj->gradient(NULL,NULL,offset,true);
1352              for (iColumn=0;iColumn<numberColumns;iColumn++) {
1353                dualColumnSolution[iColumn] = -dualColumnSolution[iColumn];
1354                objective[iColumn] = -objective[iColumn];
1355              }
1356              int iRow;
1357              int numberRows=models[iModel].numberRows();
1358              double * dualRowSolution = 
1359                models[iModel].dualRowSolution();
1360              for (iRow=0;iRow<numberRows;iRow++) 
1361                dualRowSolution[iRow] = -dualRowSolution[iRow];
1362              models[iModel].setObjectiveOffset(-models[iModel].objectiveOffset());
1363            }
1364            break;
1365          case DIRECTORY:
1366            {
1367              std::string name = CoinReadGetString(argc,argv);
1368              if (name!="EOL") {
1369                int length=name.length();
1370                if (name[length-1]==dirsep)
1371                  directory = name;
1372                else
1373                  directory = name+dirsep;
1374                parameters[iParam].setStringValue(directory);
1375              } else {
1376                parameters[iParam].printString();
1377              }
1378            }
1379            break;
1380          case DIRSAMPLE:
1381            {
1382              std::string name = CoinReadGetString(argc,argv);
1383              if (name!="EOL") {
1384                int length=name.length();
1385                if (name[length-1]==dirsep)
1386                  dirSample = name;
1387                else
1388                  dirSample = name+dirsep;
1389                parameters[iParam].setStringValue(dirSample);
1390              } else {
1391                parameters[iParam].printString();
1392              }
1393            }
1394            break;
1395          case DIRNETLIB:
1396            {
1397              std::string name = CoinReadGetString(argc,argv);
1398              if (name!="EOL") {
1399                int length=name.length();
1400                if (name[length-1]==dirsep)
1401                  dirNetlib = name;
1402                else
1403                  dirNetlib = name+dirsep;
1404                parameters[iParam].setStringValue(dirNetlib);
1405              } else {
1406                parameters[iParam].printString();
1407              }
1408            }
1409            break;
1410          case DIRMIPLIB:
1411            {
1412              std::string name = CoinReadGetString(argc,argv);
1413              if (name!="EOL") {
1414                int length=name.length();
1415                if (name[length-1]==dirsep)
1416                  dirMiplib = name;
1417                else
1418                  dirMiplib = name+dirsep;
1419                parameters[iParam].setStringValue(dirMiplib);
1420              } else {
1421                parameters[iParam].printString();
1422              }
1423            }
1424            break;
1425          case STDIN:
1426            CbcOrClpRead_mode=-1;
1427            break;
1428          case NETLIB_DUAL:
1429          case NETLIB_EITHER:
1430          case NETLIB_BARRIER:
1431          case NETLIB_PRIMAL:
1432          case NETLIB_TUNE:
1433            {
1434              // create fields for unitTest
1435              const char * fields[4];
1436              int nFields=4;
1437              fields[0]="fake main from unitTest";
1438              std::string mpsfield = "-dirSample=";
1439              mpsfield += dirSample.c_str();
1440              fields[1]=mpsfield.c_str();
1441              std::string netfield = "-dirNetlib=";
1442              netfield += dirNetlib.c_str();
1443              fields[2]=netfield.c_str();
1444              fields[3]="-netlib";
1445              int algorithm;
1446              if (type==NETLIB_DUAL) {
1447                std::cerr<<"Doing netlib with dual algorithm"<<std::endl;
1448                algorithm =0;
1449              } else if (type==NETLIB_BARRIER) {
1450                std::cerr<<"Doing netlib with barrier algorithm"<<std::endl;
1451                algorithm =2;
1452              } else if (type==NETLIB_EITHER) {
1453                std::cerr<<"Doing netlib with dual or primal algorithm"<<std::endl;
1454                algorithm =3;
1455              } else if (type==NETLIB_TUNE) {
1456                std::cerr<<"Doing netlib with best algorithm!"<<std::endl;
1457                algorithm =5;
1458                // uncomment next to get active tuning
1459                // algorithm=6;
1460              } else {
1461                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
1462                algorithm=1;
1463              }
1464              int specialOptions = models[iModel].specialOptions();
1465              models[iModel].setSpecialOptions(0);
1466              mainTest(nFields,fields,algorithm,models[iModel],
1467                       (preSolve!=0),specialOptions,doVector!=0);
1468            }
1469            break;
1470          case UNITTEST:
1471            {
1472              // create fields for unitTest
1473              const char * fields[2];
1474              int nFields=2;
1475              fields[0]="fake main from unitTest";
1476              std::string dirfield = "-dirSample=";
1477              dirfield += dirSample.c_str();
1478              fields[1]=dirfield.c_str();
1479              int specialOptions = models[iModel].specialOptions();
1480              models[iModel].setSpecialOptions(0);
1481              int algorithm=-1;
1482              if (models[iModel].numberRows())
1483                algorithm=7;
1484              mainTest(nFields,fields,algorithm,models[iModel],(preSolve!=0),specialOptions,doVector!=0);
1485            }
1486            break;
1487          case FAKEBOUND:
1488            if (goodModels[iModel]) {
1489              // get bound
1490              double value = CoinReadGetDoubleField(argc,argv,&valid);
1491              if (!valid) {
1492                std::cout<<"Setting "<<parameters[iParam].name()<<
1493                  " to DEBUG "<<value<<std::endl;
1494                int iRow;
1495                int numberRows=models[iModel].numberRows();
1496                double * rowLower = models[iModel].rowLower();
1497                double * rowUpper = models[iModel].rowUpper();
1498                for (iRow=0;iRow<numberRows;iRow++) {
1499                  // leave free ones for now
1500                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
1501                    rowLower[iRow]=CoinMax(rowLower[iRow],-value);
1502                    rowUpper[iRow]=CoinMin(rowUpper[iRow],value);
1503                  }
1504                }
1505                int iColumn;
1506                int numberColumns=models[iModel].numberColumns();
1507                double * columnLower = models[iModel].columnLower();
1508                double * columnUpper = models[iModel].columnUpper();
1509                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1510                  // leave free ones for now
1511                  if (columnLower[iColumn]>-1.0e20||
1512                      columnUpper[iColumn]<1.0e20) {
1513                    columnLower[iColumn]=CoinMax(columnLower[iColumn],-value);
1514                    columnUpper[iColumn]=CoinMin(columnUpper[iColumn],value);
1515                  }
1516                }
1517              } else if (valid==1) {
1518                abort();
1519              } else {
1520                std::cout<<"enter value for "<<parameters[iParam].name()<<
1521                  std::endl;
1522              }
1523            }
1524            break;
1525          case REALLY_SCALE:
1526            if (goodModels[iModel]) {
1527              ClpSimplex newModel(models[iModel],
1528                                  models[iModel].scalingFlag());
1529              printf("model really really scaled\n");
1530              models[iModel]=newModel;
1531            }
1532            break;
1533          case USERCLP:
1534            // Replace the sample code by whatever you want
1535            if (goodModels[iModel]) {
1536              ClpSimplex * thisModel = &models[iModel];
1537              printf("Dummy user code - model has %d rows and %d columns\n",
1538                     thisModel->numberRows(),thisModel->numberColumns());
1539            }
1540            break;
1541          case HELP:
1542            std::cout<<"Coin LP version "<<CLPVERSION
1543                     <<", build "<<__DATE__<<std::endl;
1544            std::cout<<"Non default values:-"<<std::endl;
1545            std::cout<<"Perturbation "<<models[0].perturbation()<<" (default 100)"
1546                     <<std::endl;
1547            CoinReadPrintit(
1548                    "Presolve being done with 5 passes\n\
1549Dual steepest edge steep/partial on matrix shape and factorization density\n\
1550Clpnnnn taken out of messages\n\
1551If Factorization frequency default then done on size of matrix\n\n\
1552(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
1553You can switch to interactive mode at any time so\n\
1554clp watson.mps -scaling off -primalsimplex\nis the same as\n\
1555clp watson.mps -\nscaling off\nprimalsimplex"
1556                    );
1557            break;
1558          case SOLUTION:
1559            if (goodModels[iModel]) {
1560              // get next field
1561              field = CoinReadGetString(argc,argv);
1562              if (field=="$") {
1563                field = parameters[iParam].stringValue();
1564              } else if (field=="EOL") {
1565                parameters[iParam].printString();
1566                break;
1567              } else {
1568                parameters[iParam].setStringValue(field);
1569              }
1570              std::string fileName;
1571              FILE *fp=NULL;
1572              if (field=="-"||field=="EOL"||field=="stdout") {
1573                // stdout
1574                fp=stdout;
1575                fprintf(fp,"\n");
1576              } else if (field=="stderr") {
1577                // stderr
1578                fp=stderr;
1579                fprintf(fp,"\n");
1580              } else {
1581                if (field[0]=='/'||field[0]=='\\') {
1582                  fileName = field;
1583                } else if (field[0]=='~') {
1584                  char * environVar = getenv("HOME");
1585                  if (environVar) {
1586                    std::string home(environVar);
1587                    field=field.erase(0,1);
1588                    fileName = home+field;
1589                  } else {
1590                    fileName=field;
1591                  }
1592                } else {
1593                  fileName = directory+field;
1594                }
1595                fp=fopen(fileName.c_str(),"w");
1596              }
1597              if (fp) {
1598                // make fancy later on
1599                int iRow;
1600                int numberRows=models[iModel].numberRows();
1601                int lengthName = models[iModel].lengthNames(); // 0 if no names
1602                // in general I don't want to pass around massive
1603                // amounts of data but seems simpler here
1604                std::vector<std::string> rowNames =
1605                  *(models[iModel].rowNames());
1606                std::vector<std::string> columnNames =
1607                  *(models[iModel].columnNames());
1608
1609                double * dualRowSolution = models[iModel].dualRowSolution();
1610                double * primalRowSolution = 
1611                  models[iModel].primalRowSolution();
1612                double * rowLower = models[iModel].rowLower();
1613                double * rowUpper = models[iModel].rowUpper();
1614                double primalTolerance = models[iModel].primalTolerance();
1615                char format[6];
1616                sprintf(format,"%%-%ds",CoinMax(lengthName,8));
1617                bool doMask = (printMask!=""&&lengthName);
1618                int * maskStarts=NULL;
1619                int maxMasks=0;
1620                char ** masks =NULL;
1621                if (doMask) {
1622                  int nAst =0;
1623                  const char * pMask2 = printMask.c_str();
1624                  char pMask[100];
1625                  int iChar;
1626                  int lengthMask = strlen(pMask2);
1627                  assert (lengthMask<100);
1628                  if (*pMask2=='"') {
1629                    if (pMask2[lengthMask-1]!='"') {
1630                      printf("mismatched \" in mask %s\n",pMask2);
1631                      break;
1632                    } else {
1633                      strcpy(pMask,pMask2+1);
1634                      *strchr(pMask,'"')='\0';
1635                    }
1636                  } else if (*pMask2=='\'') {
1637                    if (pMask2[lengthMask-1]!='\'') {
1638                      printf("mismatched ' in mask %s\n",pMask2);
1639                      break;
1640                    } else {
1641                      strcpy(pMask,pMask2+1);
1642                      *strchr(pMask,'\'')='\0';
1643                    }
1644                  } else {
1645                    strcpy(pMask,pMask2);
1646                  }
1647                  if (lengthMask>lengthName) {
1648                    printf("mask %s too long - skipping\n",pMask);
1649                    break;
1650                  }
1651                  maxMasks = 1;
1652                  for (iChar=0;iChar<lengthMask;iChar++) {
1653                    if (pMask[iChar]=='*') {
1654                      nAst++;
1655                      maxMasks *= (lengthName+1);
1656                    }
1657                  }
1658                  int nEntries = 1;
1659                  maskStarts = new int[lengthName+2];
1660                  masks = new char * [maxMasks];
1661                  char ** newMasks = new char * [maxMasks];
1662                  int i;
1663                  for (i=0;i<maxMasks;i++) {
1664                    masks[i] = new char[lengthName+1];
1665                    newMasks[i] = new char[lengthName+1];
1666                  }
1667                  strcpy(masks[0],pMask);
1668                  for (int iAst=0;iAst<nAst;iAst++) {
1669                    int nOldEntries = nEntries;
1670                    nEntries=0;
1671                    for (int iEntry = 0;iEntry<nOldEntries;iEntry++) {
1672                      char * oldMask = masks[iEntry];
1673                      char * ast = strchr(oldMask,'*');
1674                      assert (ast);
1675                      int length = strlen(oldMask)-1;
1676                      int nBefore = ast-oldMask;
1677                      int nAfter = length-nBefore;
1678                      // and add null
1679                      nAfter++;
1680                      for (int i=0;i<=lengthName-length;i++) {
1681                        char * maskOut = newMasks[nEntries];
1682                        memcpy(maskOut,oldMask,nBefore);
1683                        for (int k=0;k<i;k++) 
1684                          maskOut[k+nBefore]='?';
1685                        memcpy(maskOut+nBefore+i,ast+1,nAfter);
1686                        nEntries++;
1687                        assert (nEntries<=maxMasks);
1688                      }
1689                    }
1690                    char ** temp = masks;
1691                    masks = newMasks;
1692                    newMasks = temp;
1693                  }
1694                  // Now extend and sort
1695                  int * sort = new int[nEntries];
1696                  for (i=0;i<nEntries;i++) {
1697                    char * maskThis = masks[i];
1698                    int length = strlen(maskThis);
1699                    while (maskThis[length-1]==' ')
1700                      length--;
1701                    maskThis[length]='\0';
1702                    sort[i]=length;
1703                  }
1704                  CoinSort_2(sort,sort+nEntries,masks);
1705                  int lastLength=-1;
1706                  for (i=0;i<nEntries;i++) {
1707                    int length = sort[i];
1708                    while (length>lastLength) 
1709                      maskStarts[++lastLength] = i;
1710                  }
1711                  maskStarts[++lastLength]=nEntries;
1712                  delete [] sort;
1713                  for (i=0;i<maxMasks;i++)
1714                    delete [] newMasks[i];
1715                  delete [] newMasks;
1716                }
1717                if (printMode>2) {
1718                  for (iRow=0;iRow<numberRows;iRow++) {
1719                    int type=printMode-3;
1720                    if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
1721                        primalRowSolution[iRow]<rowLower[iRow]-primalTolerance) {
1722                      fprintf(fp,"** ");
1723                      type=2;
1724                    } else if (fabs(primalRowSolution[iRow])>1.0e-8) {
1725                      type=1;
1726                    } else if (numberRows<50) {
1727                      type=3;
1728                    } 
1729                    if (doMask&&!maskMatches(maskStarts,masks,rowNames[iRow]))
1730                      type=0;
1731                    if (type) {
1732                      fprintf(fp,"%7d ",iRow);
1733                      if (lengthName)
1734                        fprintf(fp,format,rowNames[iRow].c_str());
1735                      fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
1736                              dualRowSolution[iRow]);
1737                    }
1738                  }
1739                }
1740                int iColumn;
1741                int numberColumns=models[iModel].numberColumns();
1742                double * dualColumnSolution = 
1743  models[iModel].dualColumnSolution();
1744                double * primalColumnSolution = 
1745  models[iModel].primalColumnSolution();
1746                double * columnLower = models[iModel].columnLower();
1747                double * columnUpper = models[iModel].columnUpper();
1748                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1749                  int type=(printMode>3) ? 1 : 0;
1750                  if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
1751                      primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance) {
1752                    fprintf(fp,"** ");
1753                    type=2;
1754                  } else if (fabs(primalColumnSolution[iColumn])>1.0e-8) {
1755                    type=1;
1756                  } else if (numberColumns<50) {
1757                    type=3;
1758                  }
1759                  if (doMask&&!maskMatches(maskStarts,masks,
1760                                           columnNames[iColumn]))
1761                    type =0;
1762                  if (type) {
1763                    fprintf(fp,"%7d ",iColumn);
1764                    if (lengthName)
1765                      fprintf(fp,format,columnNames[iColumn].c_str());
1766                    fprintf(fp,"%15.8g        %15.8g\n",
1767                            primalColumnSolution[iColumn],
1768                            dualColumnSolution[iColumn]);
1769                  }
1770                }
1771                if (fp!=stdout)
1772                  fclose(fp);
1773                if (masks) {
1774                  delete [] maskStarts;
1775                  for (int i=0;i<maxMasks;i++)
1776                    delete [] masks[i];
1777                  delete [] masks;
1778                }
1779              } else {
1780                std::cout<<"Unable to open file "<<fileName<<std::endl;
1781              }
1782            } else {
1783              std::cout<<"** Current model not valid"<<std::endl;
1784             
1785            }
1786         
1787            break;
1788          case SAVESOL:
1789            if (goodModels[iModel]) {
1790              // get next field
1791              field = CoinReadGetString(argc,argv);
1792              if (field=="$") {
1793                field = parameters[iParam].stringValue();
1794              } else if (field=="EOL") {
1795                parameters[iParam].printString();
1796                break;
1797              } else {
1798                parameters[iParam].setStringValue(field);
1799              }
1800              std::string fileName;
1801              if (field[0]=='/'||field[0]=='\\') {
1802                fileName = field;
1803              } else if (field[0]=='~') {
1804                char * environVar = getenv("HOME");
1805                if (environVar) {
1806                  std::string home(environVar);
1807                  field=field.erase(0,1);
1808                  fileName = home+field;
1809                } else {
1810                  fileName=field;
1811                }
1812              } else {
1813                fileName = directory+field;
1814              }
1815              saveSolution(models+iModel,fileName);
1816            } else {
1817              std::cout<<"** Current model not valid"<<std::endl;
1818             
1819            }
1820            break;
1821          default:
1822            abort();
1823          }
1824        } 
1825      } else if (!numberMatches) {
1826        std::cout<<"No match for "<<field<<" - ? for list of commands"
1827                 <<std::endl;
1828      } else if (numberMatches==1) {
1829        if (!numberQuery) {
1830          std::cout<<"Short match for "<<field<<" - completion: ";
1831          std::cout<<parameters[firstMatch].matchName()<<std::endl;
1832        } else if (numberQuery) {
1833          std::cout<<parameters[firstMatch].matchName()<<" : ";
1834          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
1835          if (numberQuery>=2) 
1836            parameters[firstMatch].printLongHelp();
1837        }
1838      } else {
1839        if (!numberQuery) 
1840          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
1841                   <<std::endl;
1842        else
1843          std::cout<<"Completions of "<<field<<":"<<std::endl;
1844        for ( iParam=0; iParam<numberParameters; iParam++ ) {
1845          int match = parameters[iParam].matches(field);
1846          if (match&&parameters[iParam].displayThis()) {
1847            std::cout<<parameters[iParam].matchName();
1848            if (numberQuery>=2) 
1849              std::cout<<" : "<<parameters[iParam].shortHelp();
1850            std::cout<<std::endl;
1851          }
1852        }
1853      }
1854    }
1855    delete [] models;
1856    delete [] goodModels;
1857  }
1858  // By now all memory should be freed
1859#ifdef DMALLOC
1860  dmalloc_log_unfreed();
1861  dmalloc_shutdown();
1862#endif
1863  return 0;
1864}   
1865static void breakdown(const char * name, int numberLook, const double * region)
1866{
1867  double range[] = {
1868    -COIN_DBL_MAX,
1869    -1.0e15,-1.0e11,-1.0e8,-1.0e5,-1.0e4,-1.0e3,-1.0e2,-1.0e1,
1870    -1.0,
1871    -1.0e-1,-1.0e-2,-1.0e-3,-1.0e-4,-1.0e-5,-1.0e-8,-1.0e-11,-1.0e-15,
1872    0.0,
1873    1.0e-15,1.0e-11,1.0e-8,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,
1874    1.0,
1875    1.0e1,1.0e2,1.0e3,1.0e4,1.0e5,1.0e8,1.0e11,1.0e15,
1876    COIN_DBL_MAX};
1877  int nRanges = (int) (sizeof(range)/sizeof(double));
1878  int * number = new int[nRanges];
1879  memset(number,0,nRanges*sizeof(int));
1880  int * numberExact = new int[nRanges];
1881  memset(numberExact,0,nRanges*sizeof(int));
1882  int i;
1883  for ( i=0;i<numberLook;i++) {
1884    double value = region[i];
1885    for (int j=0;j<nRanges;j++) {
1886      if (value==range[j]) {
1887        numberExact[j]++;
1888        break;
1889      } else if (value<range[j]) {
1890        number[j]++;
1891        break;
1892      }
1893    }
1894  }
1895  printf("\n%s has %d entries\n",name,numberLook);
1896  for (i=0;i<nRanges;i++) {
1897    if (number[i]) 
1898      printf("%d between %g and %g",number[i],range[i-1],range[i]);
1899    if (numberExact[i]) {
1900      if (number[i])
1901        printf(", ");
1902      printf("%d exactly at %g",numberExact[i],range[i]);
1903    }
1904    if (number[i]+numberExact[i])
1905      printf("\n");
1906  }
1907  delete [] number;
1908  delete [] numberExact;
1909}
1910static void statistics(ClpSimplex * originalModel, ClpSimplex * model)
1911{
1912  int numberColumns = originalModel->numberColumns();
1913  const char * integerInformation  = originalModel->integerInformation(); 
1914  const double * columnLower = originalModel->columnLower();
1915  const double * columnUpper = originalModel->columnUpper();
1916  int numberIntegers=0;
1917  int numberBinary=0;
1918  int iRow,iColumn;
1919  if (integerInformation) {
1920    for (iColumn=0;iColumn<numberColumns;iColumn++) {
1921      if (integerInformation[iColumn]) {
1922        if (columnUpper[iColumn]>columnLower[iColumn]) {
1923          numberIntegers++;
1924          if (columnUpper[iColumn]==0.0&&columnLower[iColumn]==1) 
1925            numberBinary++;
1926        }
1927      }
1928    }
1929  }
1930  numberColumns = model->numberColumns();
1931  int numberRows = model->numberRows();
1932  columnLower = model->columnLower();
1933  columnUpper = model->columnUpper();
1934  const double * rowLower = model->rowLower();
1935  const double * rowUpper = model->rowUpper();
1936  const double * objective = model->objective();
1937  CoinPackedMatrix * matrix = model->matrix();
1938  CoinBigIndex numberElements = matrix->getNumElements();
1939  const int * columnLength = matrix->getVectorLengths();
1940  //const CoinBigIndex * columnStart = matrix->getVectorStarts();
1941  const double * elementByColumn = matrix->getElements();
1942  int * number = new int[numberRows+1];
1943  memset(number,0,(numberRows+1)*sizeof(int));
1944  int numberObjSingletons=0;
1945  /* cType
1946     0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up,
1947     8 0/1
1948  */ 
1949  int cType[9];
1950  std::string cName[]={"0.0->inf,","0.0->up,","lo->inf,","lo->up,","free,","fixed,","-inf->0.0,",
1951                       "-inf->up,","0.0->1.0"};
1952  int nObjective=0;
1953  memset(cType,0,sizeof(cType));
1954  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1955    int length=columnLength[iColumn];
1956    if (length==1&&objective[iColumn])
1957      numberObjSingletons++;
1958    number[length]++;
1959    if (objective[iColumn])
1960      nObjective++;
1961    if (columnLower[iColumn]>-1.0e20) {
1962      if (columnLower[iColumn]==0.0) {
1963        if (columnUpper[iColumn]>1.0e20)
1964          cType[0]++;
1965        else if (columnUpper[iColumn]==1.0)
1966          cType[8]++;
1967        else if (columnUpper[iColumn]==0.0)
1968          cType[5]++;
1969        else
1970          cType[1]++;
1971      } else {
1972        if (columnUpper[iColumn]>1.0e20) 
1973          cType[2]++;
1974        else if (columnUpper[iColumn]==columnLower[iColumn])
1975          cType[5]++;
1976        else
1977          cType[3]++;
1978      }
1979    } else {
1980      if (columnUpper[iColumn]>1.0e20) 
1981        cType[4]++;
1982      else if (columnUpper[iColumn]==0.0) 
1983        cType[6]++;
1984      else
1985        cType[7]++;
1986    }
1987  }
1988  /* rType
1989     0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other,
1990     7 L 0,  8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free
1991  */ 
1992  int rType[13];
1993  std::string rName[]={"E 0.0,","E 1.0,","E -1.0,","E other,","G 0.0,","G 1.0,","G other,",
1994                       "L 0.0,","L 1.0,","L other,","Range 0.0->1.0,","Range other,","Free"};
1995  memset(rType,0,sizeof(rType));
1996  for (iRow=0;iRow<numberRows;iRow++) {
1997    if (rowLower[iRow]>-1.0e20) {
1998      if (rowLower[iRow]==0.0) {
1999        if (rowUpper[iRow]>1.0e20)
2000          rType[4]++;
2001        else if (rowUpper[iRow]==1.0)
2002          rType[10]++;
2003        else if (rowUpper[iRow]==0.0)
2004          rType[0]++;
2005        else
2006          rType[11]++;
2007      } else if (rowLower[iRow]==1.0) {
2008        if (rowUpper[iRow]>1.0e20) 
2009          rType[5]++;
2010        else if (rowUpper[iRow]==rowLower[iRow])
2011          rType[1]++;
2012        else
2013          rType[11]++;
2014      } else if (rowLower[iRow]==-1.0) {
2015        if (rowUpper[iRow]>1.0e20) 
2016          rType[6]++;
2017        else if (rowUpper[iRow]==rowLower[iRow])
2018          rType[2]++;
2019        else
2020          rType[11]++;
2021      } else {
2022        if (rowUpper[iRow]>1.0e20) 
2023          rType[6]++;
2024        else if (rowUpper[iRow]==rowLower[iRow])
2025          rType[3]++;
2026        else
2027          rType[11]++;
2028      }
2029    } else {
2030      if (rowUpper[iRow]>1.0e20) 
2031        rType[12]++;
2032      else if (rowUpper[iRow]==0.0) 
2033        rType[7]++;
2034      else if (rowUpper[iRow]==1.0) 
2035        rType[8]++;
2036      else
2037        rType[9]++;
2038    }
2039  }
2040  // Basic statistics
2041  printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n",
2042         numberRows,numberColumns,nObjective,numberElements);
2043  if (number[0]+number[1]) {
2044    printf("There are ");
2045    if (numberObjSingletons)
2046      printf("%d singletons with objective ",numberObjSingletons);
2047    int numberNoObj = number[1]-numberObjSingletons;
2048    if (numberNoObj)
2049      printf("%d singletons with no objective ",numberNoObj);
2050    if (number[0])
2051      printf("** %d columns have no entries",number[0]);
2052    printf("\n");
2053  }
2054  printf("Column breakdown:\n");
2055  int k;
2056  for (k=0;k<(int) (sizeof(cType)/sizeof(int));k++) {
2057    printf("%d of type %s ",cType[k],cName[k].c_str());
2058    if (((k+1)%3)==0)
2059      printf("\n");
2060  }
2061  if ((k%3)!=0)
2062    printf("\n");
2063  printf("Row breakdown:\n");
2064  for (k=0;k<(int) (sizeof(rType)/sizeof(int));k++) {
2065    printf("%d of type %s ",rType[k],rName[k].c_str());
2066    if (((k+1)%3)==0)
2067      printf("\n");
2068  }
2069  if ((k%3)!=0)
2070    printf("\n");
2071  if (model->logLevel()<2)
2072    return ;
2073  int kMax = model->logLevel()>3 ? 1000000 : 10;
2074  k=0;
2075  for (iRow=1;iRow<=numberRows;iRow++) {
2076    if (number[iRow]) {
2077      k++;
2078      printf("%d columns have %d entries\n",number[iRow],iRow);
2079      if (k==kMax)
2080        break;
2081    }
2082  }
2083  if (k<numberRows) {
2084    int kk=k;
2085    k=0;
2086    for (iRow=numberRows;iRow>=1;iRow--) {
2087      if (number[iRow]) {
2088        k++;
2089        if (k==kMax)
2090          break;
2091      }
2092    }
2093    if (k>kk) {
2094      printf("\n    .........\n\n");
2095      iRow=k;
2096      k=0;
2097      for (;iRow<numberRows;iRow++) {
2098        if (number[iRow]) {
2099          k++;
2100          printf("%d columns have %d entries\n",number[iRow],iRow);
2101          if (k==kMax)
2102            break;
2103        }
2104      }
2105    }
2106  }
2107  delete [] number;
2108  printf("\n\n");
2109  // get row copy
2110  CoinPackedMatrix rowCopy = *matrix;
2111  rowCopy.reverseOrdering();
2112  //const int * column = rowCopy.getIndices();
2113  const int * rowLength = rowCopy.getVectorLengths();
2114  //const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
2115  //const double * element = rowCopy.getElements();
2116  number = new int[numberColumns+1];
2117  memset(number,0,(numberColumns+1)*sizeof(int));
2118  for (iRow=0;iRow<numberRows;iRow++) {
2119    int length=rowLength[iRow];
2120    number[length]++;
2121  }
2122  if (number[0])
2123    printf("** %d rows have no entries\n",number[0]);
2124  k=0;
2125  for (iColumn=1;iColumn<=numberColumns;iColumn++) {
2126    if (number[iColumn]) {
2127      k++;
2128      printf("%d rows have %d entries\n",number[iColumn],iColumn);
2129      if (k==kMax)
2130        break;
2131    }
2132  }
2133  if (k<numberColumns) {
2134    int kk=k;
2135    k=0;
2136    for (iColumn=numberColumns;iColumn>=1;iColumn--) {
2137      if (number[iColumn]) {
2138        k++;
2139        if (k==kMax)
2140          break;
2141      }
2142    }
2143    if (k>kk) {
2144      printf("\n    .........\n\n");
2145      iColumn=k;
2146      k=0;
2147      for (;iColumn<numberColumns;iColumn++) {
2148        if (number[iColumn]) {
2149          k++;
2150          printf("%d rows have %d entries\n",number[iColumn],iColumn);
2151          if (k==kMax)
2152            break;
2153        }
2154      }
2155    }
2156  }
2157  delete [] number;
2158  // Now do breakdown of ranges
2159  breakdown("Elements",numberElements,elementByColumn);
2160  breakdown("RowLower",numberRows,rowLower);
2161  breakdown("RowUpper",numberRows,rowUpper);
2162  breakdown("ColumnLower",numberColumns,columnLower);
2163  breakdown("ColumnUpper",numberColumns,columnUpper);
2164  breakdown("Objective",numberColumns,objective);
2165}
2166static bool maskMatches(const int * starts, char ** masks,
2167                        std::string & check)
2168{
2169  // back to char as I am old fashioned
2170  const char * checkC = check.c_str();
2171  int length = strlen(checkC);
2172  while (checkC[length-1]==' ')
2173    length--;
2174  for (int i=starts[length];i<starts[length+1];i++) {
2175    char * thisMask = masks[i];
2176    int k;
2177    for ( k=0;k<length;k++) {
2178      if (thisMask[k]!='?'&&thisMask[k]!=checkC[k]) 
2179        break;
2180    }
2181    if (k==length)
2182      return true;
2183  }
2184  return false;
2185}
2186static void clean(char * temp)
2187{
2188  char * put = temp;
2189  while (*put>=' ')
2190    put++;
2191  *put='\0';
2192}
2193static void generateCode(const char * fileName,int type)
2194{
2195  FILE * fp = fopen(fileName,"r");
2196  assert (fp);
2197  int numberLines=0;
2198#define MAXLINES 500
2199#define MAXONELINE 200
2200  char line[MAXLINES][MAXONELINE];
2201  while (fgets(line[numberLines],MAXONELINE,fp)) {
2202    assert (numberLines<MAXLINES);
2203    clean(line[numberLines]);
2204    numberLines++;
2205  }
2206  fclose(fp);
2207  // add in actual solve
2208  strcpy(line[numberLines],"5  clpModel->initialSolve(clpSolve);");
2209  numberLines++;
2210  fp = fopen(fileName,"w");
2211  assert (fp);
2212  char apo='"';   
2213  char backslash = '\\';
2214
2215  fprintf(fp,"#include %cClpSimplex.hpp%c\n",apo,apo);
2216  fprintf(fp,"#include %cClpSolve.hpp%c\n",apo,apo);
2217
2218  fprintf(fp,"\nint main (int argc, const char *argv[])\n{\n");
2219  fprintf(fp,"  ClpSimplex  model;\n");
2220  fprintf(fp,"  int status=1;\n");
2221  fprintf(fp,"  if (argc<2)\n");
2222  fprintf(fp,"    fprintf(stderr,%cPlease give file name%cn%c);\n",
2223          apo,backslash,apo);
2224  fprintf(fp,"  else\n");
2225  fprintf(fp,"    status=model.readMps(argv[1],true);\n");
2226  fprintf(fp,"  if (status) {\n");
2227  fprintf(fp,"    fprintf(stderr,%cBad readMps %%s%cn%c,argv[1]);\n",
2228                apo,backslash,apo);
2229  fprintf(fp,"    exit(1);\n");
2230  fprintf(fp,"  }\n\n");
2231  fprintf(fp,"  // Now do requested saves and modifications\n");
2232  fprintf(fp,"  ClpSimplex * clpModel = & model;\n");
2233  int wanted[9];
2234  memset(wanted,0,sizeof(wanted));
2235  wanted[0]=wanted[3]=wanted[5]=wanted[8]=1;
2236  if (type>0) 
2237    wanted[1]=wanted[6]=1;
2238  if (type>1) 
2239    wanted[2]=wanted[4]=wanted[7]=1;
2240  std::string header[9]=
2241  { "","Save values","Redundant save of default values","Set changed values",
2242    "Redundant set default values","Solve","Restore values","Redundant restore values","Add to model"};
2243  for (int iType=0;iType<9;iType++) {
2244    if (!wanted[iType])
2245      continue;
2246    int n=0;
2247    int iLine;
2248    for (iLine=0;iLine<numberLines;iLine++) {
2249      if (line[iLine][0]=='0'+iType) {
2250        if (!n)
2251          fprintf(fp,"\n  // %s\n\n",header[iType].c_str());
2252        n++;
2253        fprintf(fp,"%s\n",line[iLine]+1);
2254      }
2255    }
2256  }
2257  fprintf(fp,"\n  // Now you would use solution etc etc\n\n");
2258  fprintf(fp,"  return 0;\n}\n");
2259  fclose(fp);
2260  printf("C++ file written to %s\n",fileName);
2261}
2262/*
2263  Version 1.00.00 October 13 2004.
2264  1.00.01 October 18.  Added basis handling helped/prodded by Thorsten Koch.
2265  Also modifications to make faster with sbb (I hope I haven't broken anything).
2266  1.00.02 March 21 2005.  Redid ClpNonLinearCost to save memory also redid
2267  createRim to try and improve cache characteristics.
2268  1.00.03 April 8 2005.  Added Volume algorithm as crash and made code more
2269  robust on testing.  Also added "either" and "tune" algorithm.
2270  1.01.01 April 12 2005.  Decided to go to different numbering.  Backups will
2271  be last 2 digits while middle 2 are for improvements.  Still take a long
2272  time to get to 2.00.01
2273  1.01.02 May 4 2005.  Will be putting in many changes - so saving stable version
2274  1.02.01 May 6 2005.  Lots of changes to try and make faster and more stable in
2275  branch and cut.
2276  1.02.02 May 19 2005.  Stuff for strong branching and some improvements to simplex
2277  1.03.01 May 24 2006.  Lots done but I can't remember what!
2278  1.03.03 June 13 2006.  For clean up after dual perturbation
2279  1.04.01 June 26 2007.  Lots of changes but I got lazy
2280  1.05.00 June 27 2007.  This is trunk so when gets to stable will be 1.5
2281 */
Note: See TracBrowser for help on using the repository browser.