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

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

include cstdlib before cmath to get things to compile on AIX with xlC

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