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

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

Added new parameters to indicate location of Sample/Netlib?/mplib problems

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