source: stable/1.6/Clp/src/ClpMain.cpp @ 1609

Last change on this file since 1609 was 1111, checked in by forrest, 13 years ago

trying to improve networks

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