source: branches/BSP/trunk/Clp/src/ClpMain.cpp @ 1087

Last change on this file since 1087 was 1087, checked in by ladanyi, 12 years ago

committing merging w/ trunk of Clp, Osi, Cbc

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