source: trunk/Cbc/src/CbcSolver.cpp @ 2332

Last change on this file since 2332 was 2332, checked in by forrest, 22 months ago

fix SOS2

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 622.7 KB
Line 
1/* $Id: CbcSolver.cpp 2332 2017-05-25 15:37:09Z forrest $ */
2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6/*! \file CbcSolver.cpp
7    \brief Second level routines for the cbc stand-alone solver.
8*/
9
10#include "CbcConfig.h"
11#include "CoinPragma.hpp"
12
13#include <cassert>
14#include <cstdio>
15#include <cstdlib>
16#include <cmath>
17#include <cfloat>
18#include <cstring>
19#include <iostream>
20
21#include "CoinPragma.hpp"
22#include "CoinHelperFunctions.hpp"
23
24#include "CoinMpsIO.hpp"
25#include "CoinModel.hpp"
26
27#include "ClpFactorization.hpp"
28#include "ClpQuadraticObjective.hpp"
29#include "CoinTime.hpp"
30#include "ClpSimplex.hpp"
31#include "ClpSimplexOther.hpp"
32#include "ClpSolve.hpp"
33#include "ClpMessage.hpp"
34#include "ClpPackedMatrix.hpp"
35#include "ClpPlusMinusOneMatrix.hpp"
36#include "ClpNetworkMatrix.hpp"
37#include "ClpDualRowSteepest.hpp"
38#include "ClpDualRowDantzig.hpp"
39#include "ClpPEDualRowSteepest.hpp"
40#include "ClpPEDualRowDantzig.hpp"
41#include "ClpPEPrimalColumnSteepest.hpp"
42#include "ClpPEPrimalColumnDantzig.hpp"
43#include "ClpLinearObjective.hpp"
44#include "ClpPrimalColumnSteepest.hpp"
45#include "ClpPrimalColumnDantzig.hpp"
46
47#include "ClpPresolve.hpp"
48#ifndef COIN_HAS_CBC
49#define COIN_HAS_CBC
50#endif
51#include "CbcOrClpParam.hpp"
52#include "OsiRowCutDebugger.hpp"
53#include "OsiChooseVariable.hpp"
54#include "OsiAuxInfo.hpp"
55#include "CbcMipStartIO.hpp"
56// for printing
57#ifndef CLP_OUTPUT_FORMAT
58#define CLP_OUTPUT_FORMAT %15.8g
59#endif
60#define CLP_QUOTE(s) CLP_STRING(s)
61#define CLP_STRING(s) #s
62
63#include "CbcSolverHeuristics.hpp"
64#ifdef COIN_HAS_GLPK
65#include "glpk.h"
66extern glp_tran* cbc_glp_tran;
67extern glp_prob* cbc_glp_prob;
68#else
69#define GLP_UNDEF 1
70#define GLP_FEAS 2
71#define GLP_INFEAS 3
72#define GLP_NOFEAS 4
73#define GLP_OPT 5
74#endif
75
76#ifndef CBC_QUIET
77#define CBC_QUIET 0
78#endif
79
80//#define USER_HAS_FAKE_CLP
81//#define USER_HAS_FAKE_CBC
82
83//#define CLP_MALLOC_STATISTICS
84
85#ifdef CLP_MALLOC_STATISTICS
86#include <malloc.h>
87#include <exception>
88#include <new>
89#include "stolen_from_ekk_malloc.cpp"
90static double malloc_times = 0.0;
91static double malloc_total = 0.0;
92static int malloc_amount[] = {0, 32, 128, 256, 1024, 4096, 16384, 65536, 262144, INT_MAX};
93static int malloc_n = 10;
94double malloc_counts[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
95bool malloc_counts_on = true;
96void * operator new (size_t size) throw (std::bad_alloc)
97{
98    malloc_times ++;
99    malloc_total += size;
100    int i;
101    for (i = 0; i < malloc_n; i++) {
102        if ((int) size <= malloc_amount[i]) {
103            malloc_counts[i]++;
104            break;
105        }
106    }
107# ifdef DEBUG_MALLOC
108    void *p;
109    if (malloc_counts_on)
110        p = stolen_from_ekk_mallocBase(size);
111    else
112        p = malloc(size);
113# else
114    void * p = malloc(size);
115# endif
116    //char * xx = (char *) p;
117    //memset(xx,0,size);
118    // Initialize random seed
119    //CoinSeedRandom(987654321);
120    return p;
121}
122void operator delete (void *p) throw()
123{
124# ifdef DEBUG_MALLOC
125    if (malloc_counts_on)
126        stolen_from_ekk_freeBase(p);
127    else
128        free(p);
129# else
130    free(p);
131# endif
132}
133static void malloc_stats2()
134{
135    double average = malloc_total / malloc_times;
136    printf("count %g bytes %g - average %g\n", malloc_times, malloc_total, average);
137    for (int i = 0; i < malloc_n; i++)
138        printf("%g ", malloc_counts[i]);
139    printf("\n");
140    malloc_times = 0.0;
141    malloc_total = 0.0;
142    memset(malloc_counts, 0, sizeof(malloc_counts));
143    // print results
144}
145#else   //CLP_MALLOC_STATISTICS
146//void stolen_from_ekk_memory(void * dummy,int type)
147//{
148//}
149//bool malloc_counts_on=false;
150#endif  //CLP_MALLOC_STATISTICS
151
152//#define DMALLOC
153#ifdef DMALLOC
154#include "dmalloc.h"
155#endif
156
157#ifdef WSSMP_BARRIER
158#define FOREIGN_BARRIER
159#endif
160
161#ifdef UFL_BARRIER
162#define FOREIGN_BARRIER
163#endif
164
165#ifdef TAUCS_BARRIER
166#define FOREIGN_BARRIER
167#endif
168
169static int initialPumpTune = -1;
170#include "CoinWarmStartBasis.hpp"
171
172#include "OsiSolverInterface.hpp"
173#include "OsiCuts.hpp"
174#include "OsiRowCut.hpp"
175#include "OsiColCut.hpp"
176
177#ifndef COIN_HAS_LINK
178#define COIN_HAS_LINK
179#endif
180#ifdef COIN_HAS_LINK
181#include "CbcLinked.hpp"
182#endif
183
184#include "CglPreProcess.hpp"
185#include "CglCutGenerator.hpp"
186#include "CglGomory.hpp"
187#include "CglProbing.hpp"
188#include "CglKnapsackCover.hpp"
189#include "CglRedSplit.hpp"
190#include "CglRedSplit2.hpp"
191#include "CglGMI.hpp"
192#include "CglClique.hpp"
193#include "CglFlowCover.hpp"
194#include "CglMixedIntegerRounding2.hpp"
195#include "CglTwomir.hpp"
196#include "CglDuplicateRow.hpp"
197#include "CglStored.hpp"
198#include "CglLandP.hpp"
199#include "CglResidualCapacity.hpp"
200#include "CglZeroHalf.hpp"
201//#define CGL_WRITEMPS
202#ifdef CGL_WRITEMPS
203extern double * debugSolution;
204extern int debugNumberColumns;
205#endif
206#include "CbcModel.hpp"
207#include "CbcHeuristic.hpp"
208#include "CbcHeuristicLocal.hpp"
209#include "CbcHeuristicPivotAndFix.hpp"
210//#include "CbcHeuristicPivotAndComplement.hpp"
211#include "CbcHeuristicRandRound.hpp"
212#include "CbcHeuristicGreedy.hpp"
213#include "CbcHeuristicFPump.hpp"
214#include "CbcHeuristicRINS.hpp"
215#include "CbcHeuristicDiveCoefficient.hpp"
216#include "CbcHeuristicDiveFractional.hpp"
217#include "CbcHeuristicDiveGuided.hpp"
218#include "CbcHeuristicDiveVectorLength.hpp"
219#include "CbcHeuristicDivePseudoCost.hpp"
220#include "CbcHeuristicDiveLineSearch.hpp"
221#include "CbcTreeLocal.hpp"
222#include "CbcCompareActual.hpp"
223#include "CbcCompareObjective.hpp"
224#include "CbcBranchActual.hpp"
225#include "CbcBranchLotsize.hpp"
226#include  "CbcOrClpParam.hpp"
227#include  "CbcCutGenerator.hpp"
228#include  "CbcStrategy.hpp"
229#include "CbcBranchCut.hpp"
230
231#include "OsiClpSolverInterface.hpp"
232
233#include "CbcSolverAnalyze.hpp"
234#include "CbcSolverExpandKnapsack.hpp"
235
236#include "CbcSolver.hpp"
237
238//#define IN_BRANCH_AND_BOUND (0x01000000|262144)
239#define IN_BRANCH_AND_BOUND (0x01000000|262144|128|1024|2048)
240//#define IN_BRANCH_AND_BOUND (0x01000000|262144|128)
241
242/*
243  CbcStopNow class definitions.
244*/
245
246CbcStopNow::CbcStopNow()
247{
248}
249CbcStopNow::~CbcStopNow()
250{
251}
252// Copy constructor
253CbcStopNow::CbcStopNow ( const CbcStopNow & )
254{
255}
256// Assignment operator
257CbcStopNow &
258CbcStopNow::operator=(const CbcStopNow & rhs)
259{
260    if (this != &rhs) {
261    }
262    return *this;
263}
264// Clone
265CbcStopNow *
266CbcStopNow::clone() const
267{
268    return new CbcStopNow(*this);
269}
270
271/*
272  CbcUser class definitions.
273*/
274
275// User stuff (base class)
276CbcUser::CbcUser()
277        : coinModel_(NULL),
278        userName_("null")
279{
280}
281CbcUser::~CbcUser()
282{
283    delete coinModel_;
284}
285// Copy constructor
286CbcUser::CbcUser ( const CbcUser & rhs)
287{
288    if (rhs.coinModel_)
289        coinModel_ = new CoinModel(*rhs.coinModel_);
290    else
291        coinModel_ = NULL;
292    userName_ = rhs.userName_;
293}
294// Assignment operator
295CbcUser &
296CbcUser::operator=(const CbcUser & rhs)
297{
298    if (this != &rhs) {
299        if (rhs.coinModel_)
300            coinModel_ = new CoinModel(*rhs.coinModel_);
301        else
302            coinModel_ = NULL;
303        userName_ = rhs.userName_;
304    }
305    return *this;
306}
307
308static void putBackOtherSolutions(CbcModel * presolvedModel, CbcModel * model,
309                           CglPreProcess * preProcess)
310{
311  int numberSolutions=presolvedModel->numberSavedSolutions();
312  int numberColumns=presolvedModel->getNumCols();
313  if (numberSolutions>1) {
314    model->deleteSolutions();
315    double * bestSolution = CoinCopyOfArray(presolvedModel->bestSolution(),numberColumns);
316    //double cutoff = presolvedModel->getCutoff();
317    double objectiveValue=presolvedModel->getObjValue();
318    //model->createSpaceForSavedSolutions(numberSolutions-1);
319    for (int iSolution=numberSolutions-1;iSolution>=0;iSolution--) {
320      presolvedModel->setCutoff(COIN_DBL_MAX);
321      presolvedModel->solver()->setColSolution(presolvedModel->savedSolution(iSolution));
322      //presolvedModel->savedSolutionObjective(iSolution));
323      preProcess->postProcess(*presolvedModel->solver(),false);
324      model->setBestSolution(preProcess->originalModel()->getColSolution(),model->solver()->getNumCols(),
325                             presolvedModel->savedSolutionObjective(iSolution));
326    }
327    presolvedModel->setBestObjectiveValue(objectiveValue);
328    presolvedModel->solver()->setColSolution(bestSolution);
329    //presolvedModel->setBestSolution(bestSolution,numberColumns,objectiveValue);
330  }
331}
332
333/*
334  CbcSolver class definitions
335*/
336
337CbcSolver::CbcSolver()
338        : babModel_(NULL),
339        userFunction_(NULL),
340        statusUserFunction_(NULL),
341        originalSolver_(NULL),
342        originalCoinModel_(NULL),
343        cutGenerator_(NULL),
344        numberUserFunctions_(0),
345        numberCutGenerators_(0),
346        startTime_(CoinCpuTime()),
347        parameters_(NULL),
348        numberParameters_(0),
349        doMiplib_(false),
350        noPrinting_(false),
351        readMode_(1)
352{
353    callBack_ = new CbcStopNow();
354    fillParameters();
355}
356CbcSolver::CbcSolver(const OsiClpSolverInterface & solver)
357        : babModel_(NULL),
358        userFunction_(NULL),
359        statusUserFunction_(NULL),
360        originalSolver_(NULL),
361        originalCoinModel_(NULL),
362        cutGenerator_(NULL),
363        numberUserFunctions_(0),
364        numberCutGenerators_(0),
365        startTime_(CoinCpuTime()),
366        parameters_(NULL),
367        numberParameters_(0),
368        doMiplib_(false),
369        noPrinting_(false),
370        readMode_(1)
371{
372    callBack_ = new CbcStopNow();
373    model_ = CbcModel(solver);
374    fillParameters();
375}
376CbcSolver::CbcSolver(const CbcModel & solver)
377        : babModel_(NULL),
378        userFunction_(NULL),
379        statusUserFunction_(NULL),
380        originalSolver_(NULL),
381        originalCoinModel_(NULL),
382        cutGenerator_(NULL),
383        numberUserFunctions_(0),
384        numberCutGenerators_(0),
385        startTime_(CoinCpuTime()),
386        parameters_(NULL),
387        numberParameters_(0),
388        doMiplib_(false),
389        noPrinting_(false),
390        readMode_(1)
391{
392    callBack_ = new CbcStopNow();
393    model_ = solver;
394    fillParameters();
395}
396CbcSolver::~CbcSolver()
397{
398    int i;
399    for (i = 0; i < numberUserFunctions_; i++)
400        delete userFunction_[i];
401    delete [] userFunction_;
402    for (i = 0; i < numberCutGenerators_; i++)
403        delete cutGenerator_[i];
404    delete [] cutGenerator_;
405    delete [] statusUserFunction_;
406    delete originalSolver_;
407    delete originalCoinModel_;
408    delete babModel_;
409    delete [] parameters_;
410    delete callBack_;
411}
412// Copy constructor
413CbcSolver::CbcSolver ( const CbcSolver & rhs)
414        : model_(rhs.model_),
415        babModel_(NULL),
416        userFunction_(NULL),
417        statusUserFunction_(NULL),
418        numberUserFunctions_(rhs.numberUserFunctions_),
419        startTime_(CoinCpuTime()),
420        parameters_(NULL),
421        numberParameters_(rhs.numberParameters_),
422        doMiplib_(rhs.doMiplib_),
423        noPrinting_(rhs.noPrinting_),
424        readMode_(rhs.readMode_)
425{
426    fillParameters();
427    if (rhs.babModel_)
428        babModel_ = new CbcModel(*rhs.babModel_);
429    userFunction_ = new CbcUser * [numberUserFunctions_];
430    int i;
431    for (i = 0; i < numberUserFunctions_; i++)
432        userFunction_[i] = rhs.userFunction_[i]->clone();
433    for (i = 0; i < numberParameters_; i++)
434        parameters_[i] = rhs.parameters_[i];
435    for (i = 0; i < numberCutGenerators_; i++)
436        cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
437    callBack_ = rhs.callBack_->clone();
438    originalSolver_ = NULL;
439    if (rhs.originalSolver_) {
440        OsiSolverInterface * temp = rhs.originalSolver_->clone();
441        originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
442        assert (originalSolver_);
443    }
444    originalCoinModel_ = NULL;
445    if (rhs.originalCoinModel_)
446        originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
447}
448// Assignment operator
449CbcSolver &
450CbcSolver::operator=(const CbcSolver & rhs)
451{
452    if (this != &rhs) {
453        int i;
454        for (i = 0; i < numberUserFunctions_; i++)
455            delete userFunction_[i];
456        delete [] userFunction_;
457        for (i = 0; i < numberCutGenerators_; i++)
458            delete cutGenerator_[i];
459        delete [] statusUserFunction_;
460        delete originalSolver_;
461        delete originalCoinModel_;
462        statusUserFunction_ = NULL;
463        delete babModel_;
464        delete callBack_;
465        numberUserFunctions_ = rhs.numberUserFunctions_;
466        startTime_ = rhs.startTime_;
467        numberParameters_ = rhs.numberParameters_;
468        for (i = 0; i < numberParameters_; i++)
469            parameters_[i] = rhs.parameters_[i];
470        for (i = 0; i < numberCutGenerators_; i++)
471            cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
472        noPrinting_ = rhs.noPrinting_;
473        readMode_ = rhs.readMode_;
474        doMiplib_ = rhs.doMiplib_;
475        model_ = rhs.model_;
476        if (rhs.babModel_)
477            babModel_ = new CbcModel(*rhs.babModel_);
478        else
479            babModel_ = NULL;
480        userFunction_ = new CbcUser * [numberUserFunctions_];
481        for (i = 0; i < numberUserFunctions_; i++)
482            userFunction_[i] = rhs.userFunction_[i]->clone();
483        callBack_ = rhs.callBack_->clone();
484        originalSolver_ = NULL;
485        if (rhs.originalSolver_) {
486            OsiSolverInterface * temp = rhs.originalSolver_->clone();
487            originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
488            assert (originalSolver_);
489        }
490        originalCoinModel_ = NULL;
491        if (rhs.originalCoinModel_)
492            originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
493    }
494    return *this;
495}
496// Get int value
497int CbcSolver::intValue(CbcOrClpParameterType type) const
498{
499    return parameters_[whichParam(type, numberParameters_, parameters_)].intValue();
500}
501// Set int value
502void CbcSolver::setIntValue(CbcOrClpParameterType type, int value)
503{
504    parameters_[whichParam(type, numberParameters_, parameters_)].setIntValue(value);
505}
506// Get double value
507double CbcSolver::doubleValue(CbcOrClpParameterType type) const
508{
509    return parameters_[whichParam(type, numberParameters_, parameters_)].doubleValue();
510}
511// Set double value
512void CbcSolver::setDoubleValue(CbcOrClpParameterType type, double value)
513{
514    parameters_[whichParam(type, numberParameters_, parameters_)].setDoubleValue(value);
515}
516// User function (NULL if no match)
517CbcUser * CbcSolver::userFunction(const char * name) const
518{
519    int i;
520    for (i = 0; i < numberUserFunctions_; i++) {
521        if (!strcmp(name, userFunction_[i]->name().c_str()))
522            break;
523    }
524    if (i < numberUserFunctions_)
525        return userFunction_[i];
526    else
527        return NULL;
528}
529void CbcSolver::fillParameters()
530{
531    int maxParam = 200;
532    CbcOrClpParam * parameters = new CbcOrClpParam [maxParam];
533    numberParameters_ = 0 ;
534    establishParams(numberParameters_, parameters) ;
535    assert (numberParameters_ <= maxParam);
536    parameters_ = new CbcOrClpParam [numberParameters_];
537    int i;
538    for (i = 0; i < numberParameters_; i++)
539        parameters_[i] = parameters[i];
540    delete [] parameters;
541    const char dirsep =  CoinFindDirSeparator();
542    std::string directory;
543    std::string dirSample;
544    std::string dirNetlib;
545    std::string dirMiplib;
546    if (dirsep == '/') {
547        directory = "./";
548        dirSample = "../../Data/Sample/";
549        dirNetlib = "../../Data/Netlib/";
550        dirMiplib = "../../Data/miplib3/";
551    } else {
552        directory = ".\\";
553        dirSample = "..\\..\\..\\..\\Data\\Sample\\";
554        dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
555        dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
556    }
557    std::string defaultDirectory = directory;
558    std::string importFile = "";
559    std::string exportFile = "default.mps";
560    std::string importBasisFile = "";
561    std::string importPriorityFile = "";
562    std::string mipStartFile = "";
563    std::string debugFile = "";
564    std::string printMask = "";
565    std::string exportBasisFile = "default.bas";
566    std::string saveFile = "default.prob";
567    std::string restoreFile = "default.prob";
568    std::string solutionFile = "stdout";
569    std::string solutionSaveFile = "solution.file";
570    int doIdiot = -1;
571    int outputFormat = 2;
572    int substitution = 3;
573    int dualize = 3;
574    int preSolve = 5;
575    int doSprint = -1;
576    int testOsiParameters = -1;
577    int createSolver = 0;
578    ClpSimplex * lpSolver;
579    OsiClpSolverInterface * clpSolver;
580    if (model_.solver()) {
581        clpSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
582        assert (clpSolver);
583        lpSolver = clpSolver->getModelPtr();
584        assert (lpSolver);
585    } else {
586        lpSolver = new ClpSimplex();
587        clpSolver = new OsiClpSolverInterface(lpSolver, true);
588        createSolver = 1 ;
589    }
590    parameters_[whichParam(CLP_PARAM_ACTION_BASISIN, numberParameters_, parameters_)].setStringValue(importBasisFile);
591    parameters_[whichParam(CBC_PARAM_ACTION_PRIORITYIN, numberParameters_, parameters_)].setStringValue(importPriorityFile);
592    parameters_[whichParam(CBC_PARAM_ACTION_MIPSTART, numberParameters_, parameters_)].setStringValue(mipStartFile);
593    parameters_[whichParam(CLP_PARAM_ACTION_BASISOUT, numberParameters_, parameters_)].setStringValue(exportBasisFile);
594    parameters_[whichParam(CLP_PARAM_ACTION_DEBUG, numberParameters_, parameters_)].setStringValue(debugFile);
595    parameters_[whichParam(CLP_PARAM_ACTION_PRINTMASK, numberParameters_, parameters_)].setStringValue(printMask);
596    parameters_[whichParam(CLP_PARAM_ACTION_DIRECTORY, numberParameters_, parameters_)].setStringValue(directory);
597    parameters_[whichParam(CLP_PARAM_ACTION_DIRSAMPLE, numberParameters_, parameters_)].setStringValue(dirSample);
598    parameters_[whichParam(CLP_PARAM_ACTION_DIRNETLIB, numberParameters_, parameters_)].setStringValue(dirNetlib);
599    parameters_[whichParam(CBC_PARAM_ACTION_DIRMIPLIB, numberParameters_, parameters_)].setStringValue(dirMiplib);
600    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
601    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
602    parameters_[whichParam(CLP_PARAM_ACTION_EXPORT, numberParameters_, parameters_)].setStringValue(exportFile);
603    parameters_[whichParam(CLP_PARAM_INT_IDIOT, numberParameters_, parameters_)].setIntValue(doIdiot);
604    parameters_[whichParam(CLP_PARAM_ACTION_IMPORT, numberParameters_, parameters_)].setStringValue(importFile);
605    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].setDoubleValue(1.0e-8);
606    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
607    int value = 1;
608    clpSolver->messageHandler()->setLogLevel(1) ;
609    lpSolver->setLogLevel(1);
610    parameters_[iParam].setIntValue(value);
611    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
612    model_.messageHandler()->setLogLevel(value);
613    parameters_[iParam].setIntValue(value);
614    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
615    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
616    parameters_[whichParam(CLP_PARAM_INT_OUTPUTFORMAT, numberParameters_, parameters_)].setIntValue(outputFormat);
617    parameters_[whichParam(CLP_PARAM_INT_PRESOLVEPASS, numberParameters_, parameters_)].setIntValue(preSolve);
618    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
619    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
620    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
621    parameters_[whichParam(CLP_PARAM_ACTION_RESTORE, numberParameters_, parameters_)].setStringValue(restoreFile);
622    parameters_[whichParam(CLP_PARAM_ACTION_SAVE, numberParameters_, parameters_)].setStringValue(saveFile);
623    //parameters_[whichParam(CLP_PARAM_DBL_TIMELIMIT,numberParameters_,parameters_)].setDoubleValue(1.0e8);
624    parameters_[whichParam(CBC_PARAM_DBL_TIMELIMIT_BAB, numberParameters_, parameters_)].setDoubleValue(1.0e8);
625    parameters_[whichParam(CLP_PARAM_ACTION_SOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
626    parameters_[whichParam(CLP_PARAM_ACTION_NEXTBESTSOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
627    parameters_[whichParam(CLP_PARAM_ACTION_SAVESOL, numberParameters_, parameters_)].setStringValue(solutionSaveFile);
628    parameters_[whichParam(CLP_PARAM_INT_SPRINT, numberParameters_, parameters_)].setIntValue(doSprint);
629    parameters_[whichParam(CLP_PARAM_INT_SUBSTITUTION, numberParameters_, parameters_)].setIntValue(substitution);
630    parameters_[whichParam(CLP_PARAM_INT_DUALIZE, numberParameters_, parameters_)].setIntValue(dualize);
631    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
632    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
633    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
634    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
635    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
636    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
637    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(testOsiParameters);
638    parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_)].setIntValue(1003);
639    initialPumpTune = 1003;
640#ifdef CBC_THREAD
641    parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].setIntValue(0);
642#endif
643    // Set up likely cut generators and defaults
644    parameters_[whichParam(CBC_PARAM_STR_PREPROCESS, numberParameters_, parameters_)].setCurrentOption("sos");
645    parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValue(1057);
646    parameters_[whichParam(CBC_PARAM_INT_CUTPASSINTREE, numberParameters_, parameters_)].setIntValue(1);
647    parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].setIntValue(-1);
648    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
649    parameters_[whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
650    parameters_[whichParam(CBC_PARAM_STR_HEURISTICSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
651    parameters_[whichParam(CBC_PARAM_STR_NODESTRATEGY, numberParameters_, parameters_)].setCurrentOption("fewest");
652    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
653    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
654    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
655    parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
656    parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption("off");
657    parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption("off");
658    parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption("off");
659    parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
660    parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
661    parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
662    parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
663    parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption("off");
664    parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption("off");
665    parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption("on");
666    parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption("on");
667    parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption("on");
668    parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption("on");
669    parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters_, parameters_)].setCurrentOption("off");
670    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters_, parameters_)].setCurrentOption("off");
671    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters_, parameters_)].setCurrentOption("off");
672    parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].setCurrentOption("off");
673    parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].setCurrentOption("off");
674    parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption("off");
675    parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].setCurrentOption("off");
676    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("off");
677    parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].setCurrentOption("off");
678    parameters_[whichParam(CBC_PARAM_STR_COSTSTRATEGY, numberParameters_, parameters_)].setCurrentOption("off");
679    if (createSolver)
680        delete clpSolver;
681}
682
683/*
684  Initialise a subset of the parameters prior to processing any input from
685  the user.
686
687  Why this choice of subset?
688*/
689/*!
690  \todo Guard/replace clp-specific code
691*/
692void CbcSolver::fillValuesInSolver()
693{
694    OsiSolverInterface * solver = model_.solver();
695    OsiClpSolverInterface * clpSolver =
696        dynamic_cast< OsiClpSolverInterface*> (solver);
697    assert (clpSolver);
698    ClpSimplex * lpSolver = clpSolver->getModelPtr();
699
700    /*
701      Why are we reaching into the underlying solver(s) for these settings?
702      Shouldn't CbcSolver have its own defaults, which are then imposed on the
703      underlying solver?
704
705      Coming at if from the other side, if CbcSolver had the capability to use
706      multiple solvers then it definitely makes sense to acquire the defaults from
707      the solver (on the assumption that we haven't processed command line
708      parameters yet, which can then override the defaults). But then it's more of
709      a challenge to avoid solver-specific coding here.
710    */
711    noPrinting_ = (lpSolver->logLevel() == 0);
712    CoinMessageHandler * generalMessageHandler = clpSolver->messageHandler();
713    generalMessageHandler->setPrefix(true);
714
715    lpSolver->setPerturbation(50);
716    lpSolver->messageHandler()->setPrefix(false);
717
718    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
719    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
720    /*
721      Why are we doing this? We read the log level from parameters_, set it into
722      the message handlers for cbc and the underlying solver. Then we read the
723      log level back from the handlers and use it to set the values in
724      parameters_!
725    */
726    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
727    int value = parameters_[iParam].intValue();
728    clpSolver->messageHandler()->setLogLevel(value) ;
729    lpSolver->setLogLevel(value);
730    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
731    value = parameters_[iParam].intValue();
732    model_.messageHandler()->setLogLevel(value);
733    parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].setIntValue(model_.logLevel());
734    parameters_[whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_)].setIntValue(lpSolver->logLevel());
735    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
736    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
737    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
738    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
739    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
740    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
741    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
742    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
743    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
744    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
745    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
746}
747// Add user function
748void
749CbcSolver::addUserFunction(CbcUser * function)
750{
751    CbcUser ** temp = new CbcUser * [numberUserFunctions_+1];
752    int i;
753    for (i = 0; i < numberUserFunctions_; i++)
754        temp[i] = userFunction_[i];
755    delete [] userFunction_;
756    userFunction_ = temp;
757    userFunction_[numberUserFunctions_++] = function->clone();
758    delete [] statusUserFunction_;
759    statusUserFunction_ = NULL;
760}
761// Set user call back
762void
763CbcSolver::setUserCallBack(CbcStopNow * function)
764{
765    delete callBack_;
766    callBack_ = function->clone();
767}
768// Copy of model on initial load (will contain output solutions)
769void
770CbcSolver::setOriginalSolver(OsiClpSolverInterface * originalSolver)
771{
772    delete originalSolver_;
773    OsiSolverInterface * temp = originalSolver->clone();
774    originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
775    assert (originalSolver_);
776
777}
778// Copy of model on initial load
779void
780CbcSolver::setOriginalCoinModel(CoinModel * originalCoinModel)
781{
782    delete originalCoinModel_;
783    originalCoinModel_ = new CoinModel(*originalCoinModel);
784}
785// Add cut generator
786void
787CbcSolver::addCutGenerator(CglCutGenerator * generator)
788{
789    CglCutGenerator ** temp = new CglCutGenerator * [numberCutGenerators_+1];
790    int i;
791    for (i = 0; i < numberCutGenerators_; i++)
792        temp[i] = cutGenerator_[i];
793    delete [] cutGenerator_;
794    cutGenerator_ = temp;
795    cutGenerator_[numberCutGenerators_++] = generator->clone();
796}
797
798/*
799  The only other solver that's ever been used is cplex, and the use is
800  limited -- do the root with clp and all the cbc smarts, then give the
801  problem over to cplex to finish. Although the defines can be read in some
802  places to allow other options, nothing's been tested and success is
803  unlikely.
804
805  CBC_OTHER_SOLVER == 1 is cplex.
806*/
807
808#if CBC_OTHER_SOLVER==1
809#  ifndef COIN_HAS_CPX
810#    error "Configuration did not detect cplex installation."
811#  else
812#    include "OsiCpxSolverInterface.hpp"
813#  endif
814#endif
815
816#ifdef COIN_HAS_ASL
817#include "Cbc_ampl.h"
818#endif
819
820static void statistics(ClpSimplex * originalModel, ClpSimplex * model);
821static bool maskMatches(const int * starts, char ** masks,
822                        std::string & check);
823static void generateCode(CbcModel * model, const char * fileName, int type, int preProcess);
824
825// dummy fake main programs for UserClp and UserCbc
826void fakeMain (ClpSimplex & model, OsiSolverInterface & osiSolver, CbcModel & babSolver);
827void fakeMain2 (ClpSimplex & model, OsiClpSolverInterface & osiSolver, int options);
828
829// Allow for interrupts
830// But is this threadsafe? (so switched off by option)
831
832#include "CoinSignal.hpp"
833static CbcModel * currentBranchModel = NULL;
834
835extern "C" {
836    static void signal_handler(int whichSignal) {
837      if (currentBranchModel != NULL) {
838        currentBranchModel->sayEventHappened(); // say why stopped
839        if (currentBranchModel->heuristicModel())
840          currentBranchModel->heuristicModel()->sayEventHappened();
841      }
842        return;
843    }
844}
845
846//#define CBC_SIG_TRAP
847#ifdef CBC_SIG_TRAP
848#include <setjmp.h>
849static sigjmp_buf cbc_seg_buffer;
850extern "C" {
851    static void signal_handler_error(int whichSignal) {
852        siglongjmp(cbc_seg_buffer, 1);
853    }
854}
855#endif
856
857
858/*
859  Debug checks on special ordered sets.
860
861  This is active only for debugging. The entire body of the routine becomes
862  a noop when COIN_DEVELOP is not defined. To avoid compiler warnings, the
863  formal parameters also need to go away.
864*/
865#ifdef COIN_DEVELOP
866void checkSOS(CbcModel * babModel, const OsiSolverInterface * solver)
867#else
868void checkSOS(CbcModel * /*babModel*/, const OsiSolverInterface * /*solver*/)
869#endif
870{
871#ifdef COIN_DEVELOP
872    if (!babModel->ownObjects())
873        return;
874#if COIN_DEVELOP>2
875    //const double *objective = solver->getObjCoefficients() ;
876    const double *columnLower = solver->getColLower() ;
877    const double * columnUpper = solver->getColUpper() ;
878    const double * solution = solver->getColSolution();
879    //int numberRows = solver->getNumRows();
880    //double direction = solver->getObjSense();
881    //int iRow,iColumn;
882#endif
883
884    // Row copy
885    CoinPackedMatrix matrixByRow(*solver->getMatrixByRow());
886    //const double * elementByRow = matrixByRow.getElements();
887    //const int * column = matrixByRow.getIndices();
888    //const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
889    const int * rowLength = matrixByRow.getVectorLengths();
890
891    // Column copy
892    CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
893    const double * element = matrixByCol.getElements();
894    const int * row = matrixByCol.getIndices();
895    const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
896    const int * columnLength = matrixByCol.getVectorLengths();
897
898    const double * rowLower = solver->getRowLower();
899    const double * rowUpper = solver->getRowUpper();
900    OsiObject ** objects = babModel->objects();
901    int numberObjects = babModel->numberObjects();
902    int numberColumns = solver->getNumCols() ;
903    for (int iObj = 0; iObj < numberObjects; iObj++) {
904        CbcSOS * objSOS =
905            dynamic_cast <CbcSOS *>(objects[iObj]) ;
906        if (objSOS) {
907            int n = objSOS->numberMembers();
908            const int * which = objSOS->members();
909#if COIN_DEVELOP>2
910            const double * weight = objSOS->weights();
911#endif
912            int type = objSOS->sosType();
913            // convexity row?
914            int iColumn;
915            iColumn = which[0];
916            int j;
917            int convex = -1;
918            for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {
919                int iRow = row[j];
920                double value = element[j];
921                if (rowLower[iRow] == 1.0 && rowUpper[iRow] == 1.0 &&
922                        value == 1.0) {
923                    // possible
924                    if (rowLength[iRow] == n) {
925                        if (convex == -1)
926                            convex = iRow;
927                        else
928                            convex = -2;
929                    }
930                }
931            }
932            printf ("set %d of type %d has %d members - possible convexity row %d\n",
933                    iObj, type, n, convex);
934            for (int i = 0; i < n; i++) {
935                iColumn = which[i];
936                // Column may have been added
937                if (iColumn < numberColumns) {
938                    int convex2 = -1;
939                    for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {
940                        int iRow = row[j];
941                        if (iRow == convex) {
942                            double value = element[j];
943                            if (value == 1.0) {
944                                convex2 = iRow;
945                            }
946                        }
947                    }
948                    if (convex2<0 && convex >= 0) {
949                        printf("odd convexity row\n");
950                        convex = -2;
951                    }
952#if COIN_DEVELOP>2
953                    printf("col %d has weight %g and value %g, bounds %g %g\n",
954                           iColumn, weight[i], solution[iColumn], columnLower[iColumn],
955                           columnUpper[iColumn]);
956#endif
957                }
958            }
959        }
960    }
961#endif  // COIN_DEVELOP
962}
963
964static int dummyCallBack(CbcModel * /*model*/, int /*whereFrom*/)
965{
966    return 0;
967}
968
969
970/*
971  Global parameters for command processing.
972
973  These will need to be moved into an object of some sort in order to make
974  this set of calls thread-safe.
975*/
976
977int CbcOrClpRead_mode = 1;
978FILE * CbcOrClpReadCommand = stdin;
979extern int CbcOrClpEnvironmentIndex;
980
981int callCbc1(const char * input2, CbcModel & model,
982             int callBack(CbcModel * currentSolver, int whereFrom),
983             CbcSolverUsefulData & parameterData);
984
985/*
986  Wrappers for CbcMain0, CbcMain1. The various forms of callCbc will eventually
987  resolve to a call to CbcMain0 followed by a call to callCbc1.
988*/
989/*
990  Simplest calling form: supply just a string with the command options. The
991  wrapper creates an OsiClpSolverInterface and calls the next wrapper.
992*/
993int callCbc(const std::string input2)
994{
995    char * input3 = CoinStrdup(input2.c_str());
996    OsiClpSolverInterface solver1;
997    int returnCode = callCbc(input3, solver1);
998    free(input3);
999    return returnCode;
1000}
1001
1002int callCbc(const char * input2)
1003{
1004    {
1005        OsiClpSolverInterface solver1;
1006        return callCbc(input2, solver1);
1007    }
1008}
1009
1010/*
1011  Second calling form: supply the command line and an OsiClpSolverInterface.
1012  the wrapper will create a CbcModel and call the next wrapper.
1013*/
1014
1015int callCbc(const std::string input2, OsiClpSolverInterface& solver1)
1016{
1017    char * input3 = CoinStrdup(input2.c_str());
1018    int returnCode = callCbc(input3, solver1);
1019    free(input3);
1020    return returnCode;
1021}
1022
1023int callCbc(const char * input2, OsiClpSolverInterface& solver1)
1024{
1025    CbcModel model(solver1);
1026    return callCbc(input2, model);
1027}
1028
1029/*
1030  Third calling form: supply the command line and a CbcModel. This wrapper will
1031  actually call CbcMain0 and then call the next set of wrappers (callCbc1) to
1032  handle the call to CbcMain1.
1033*/
1034int callCbc(const char * input2, CbcModel & babSolver)
1035{
1036  CbcSolverUsefulData data;
1037#ifndef CBC_NO_INTERRUPT
1038    data.useSignalHandler_=true;
1039#endif
1040#ifndef CBC_NO_PRINTING
1041    data.noPrinting_ = false;
1042#endif
1043  CbcMain0(babSolver, data);
1044  return callCbc1(input2, babSolver, dummyCallBack, data);
1045}
1046
1047int callCbc(const std::string input2, CbcModel & babSolver)
1048{
1049    char * input3 = CoinStrdup(input2.c_str());
1050    CbcMain0(babSolver);
1051    int returnCode = callCbc1(input3, babSolver);
1052    free(input3);
1053    return returnCode;
1054}
1055
1056
1057/*
1058  Various overloads of callCbc1. The first pair accepts just a CbcModel and
1059  supplements it with a dummy callback routine. The second pair allows the
1060  user to supply a callback. See CbcMain1 for further explanation of the
1061  callback. The various overloads of callCbc1 resolve to the final version,
1062  which breaks the string into individual parameter strings (i.e., creates
1063  something that looks like a standard argv vector).
1064*/
1065
1066int callCbc1(const std::string input2, CbcModel & babSolver)
1067{
1068    char * input3 = CoinStrdup(input2.c_str());
1069    int returnCode = callCbc1(input3, babSolver);
1070    free(input3);
1071    return returnCode;
1072}
1073
1074int callCbc1(const char * input2, CbcModel & model)
1075{
1076    return callCbc1(input2, model, dummyCallBack);
1077}
1078
1079int callCbc1(const std::string input2, CbcModel & babSolver,
1080             int callBack(CbcModel * currentSolver, int whereFrom))
1081{
1082    char * input3 = CoinStrdup(input2.c_str());
1083    int returnCode = callCbc1(input3, babSolver, callBack);
1084    free(input3);
1085    return returnCode;
1086}
1087int callCbc1(const char * input2, CbcModel & model,
1088             int callBack(CbcModel * currentSolver, int whereFrom),
1089             CbcSolverUsefulData & parameterData)
1090{
1091    char * input = CoinStrdup(input2 ? input2 : "") ;
1092    size_t length = strlen(input);
1093    bool blank = input[0] == ' ';
1094    int n = blank ? 0 : 1;
1095    for (size_t i = 0; i < length; i++) {
1096        if (blank) {
1097            // look for next non blank
1098            if (input[i] == ' ') {
1099                continue;
1100            } else {
1101                n++;
1102                blank = false;
1103            }
1104        } else {
1105            // look for next blank
1106            if (input[i] != ' ') {
1107                continue;
1108            } else {
1109                blank = true;
1110            }
1111        }
1112    }
1113    char ** argv = new char * [n+2];
1114    argv[0] = CoinStrdup("cbc");
1115    size_t i = 0;
1116    while (input[i] == ' ')
1117        i++;
1118    for (int j = 0; j < n; j++) {
1119        size_t saveI = i;
1120        for (; i < length; i++) {
1121            // look for next blank
1122            if (input[i] != ' ') {
1123                continue;
1124            } else {
1125                break;
1126            }
1127        }
1128        input[i++] = '\0';
1129        argv[j+1] = CoinStrdup(input + saveI);
1130        while (input[i] == ' ')
1131            i++;
1132    }
1133    argv[n+1] = CoinStrdup("-quit");
1134    free(input);
1135    currentBranchModel = NULL;
1136    CbcOrClpRead_mode = 1;
1137    CbcOrClpReadCommand = stdin;
1138    int returnCode = CbcMain1(n + 2, const_cast<const char **>(argv),
1139                              model, callBack,parameterData);
1140    for (int k = 0; k < n + 2; k++)
1141        free(argv[k]);
1142    delete [] argv;
1143    return returnCode;
1144}
1145static CbcSolverUsefulData staticParameterData;
1146int callCbc1(const char * input2, CbcModel & model,
1147             int callBack(CbcModel * currentSolver, int whereFrom))
1148{
1149  // allow interrupts and printing
1150#ifndef CBC_NO_INTERRUPT
1151  staticParameterData.useSignalHandler_=true;
1152#endif
1153#ifndef CBC_NO_PRINTING
1154  staticParameterData.noPrinting_ = false;
1155#endif
1156  return callCbc1(input2,model,callBack,staticParameterData);
1157}
1158
1159CglPreProcess * cbcPreProcessPointer=NULL;
1160
1161int CbcClpUnitTest (const CbcModel & saveModel,
1162                    const std::string& dirMiplib, int testSwitch,
1163                    const double * stuff);
1164
1165int CbcMain1 (int argc, const char *argv[],
1166              CbcModel  & model)
1167{
1168    return CbcMain1(argc, argv, model, dummyCallBack);
1169}
1170
1171#ifdef CBC_THREAD_SAFE
1172// Copies of some input decoding
1173
1174static std::string
1175CoinReadGetCommand(int &whichArgument, int argc, const char *argv[])
1176{
1177  std::string field;
1178  if (whichArgument < argc) 
1179    field = argv[whichArgument++];
1180  else
1181    field = "quit";
1182  if (field[0] == '-') 
1183    field = field.substr(1);
1184  return field;
1185}
1186static std::string
1187CoinReadGetString(int &whichArgument, int argc, const char *argv[])
1188{
1189  std::string field;
1190  if (whichArgument < argc) 
1191    field = argv[whichArgument++];
1192  else
1193    field = "";
1194  return field;
1195}
1196// valid 0 - okay, 1 bad, 2 not there
1197static int
1198CoinReadGetIntField(int &whichArgument, int argc, const char *argv[], int * valid)
1199{
1200  std::string field;
1201  if (whichArgument < argc) 
1202    field = argv[whichArgument++];
1203  else
1204    field = "0";
1205  long int value = 0;
1206  const char * start = field.c_str();
1207  char * endPointer = NULL;
1208  // check valid
1209  value =  strtol(start, &endPointer, 10);
1210  if (*endPointer == '\0') {
1211    *valid = 0;
1212  } else {
1213    *valid = 1;
1214    std::cout << "String of " << field;
1215  }
1216  return static_cast<int>(value);
1217}
1218static double
1219CoinReadGetDoubleField(int &whichArgument, int argc, const char *argv[], int * valid)
1220{
1221  std::string field;
1222  if (whichArgument < argc) 
1223    field = argv[whichArgument++];
1224  else
1225    field = "0.0";
1226  double value = 0.0;
1227  const char * start = field.c_str();
1228  char * endPointer = NULL;
1229  // check valid
1230  value =  strtod(start, &endPointer);
1231  if (*endPointer == '\0') {
1232    *valid = 0;
1233  } else {
1234    *valid = 1;
1235    std::cout << "String of " << field;
1236  }
1237  return value;
1238}
1239// Redefine all
1240#define CoinReadGetCommand(x,y) CoinReadGetCommand(whichArgument,x,y)
1241#define CoinReadGetString(x,y) CoinReadGetString(whichArgument,x,y)
1242#define CoinReadGetIntField(x,y,z) CoinReadGetIntField(whichArgument,x,y,z)
1243#define CoinReadGetDoubleField(x,y,z) CoinReadGetDoubleField(whichArgument,x,y,z)
1244#endif
1245// Default Constructor
1246CbcSolverUsefulData::CbcSolverUsefulData()
1247{
1248  totalTime_ = 0.0;
1249  noPrinting_ = true;
1250  useSignalHandler_ = false;
1251  establishParams(numberParameters_,parameters_);
1252}
1253
1254/* Copy constructor .
1255 */
1256CbcSolverUsefulData::CbcSolverUsefulData(const CbcSolverUsefulData & rhs)
1257{
1258  totalTime_ = rhs.totalTime_;
1259  noPrinting_ = rhs.noPrinting_;
1260  useSignalHandler_ = rhs.useSignalHandler_;
1261  numberParameters_ = rhs.numberParameters_;
1262  memcpy(parameters_,rhs.parameters_,sizeof(parameters_));
1263}
1264
1265// Assignment operator
1266CbcSolverUsefulData & CbcSolverUsefulData::operator=(const CbcSolverUsefulData& rhs)
1267{
1268  if (this != &rhs) {
1269    totalTime_ = rhs.totalTime_;
1270    noPrinting_ = rhs.noPrinting_;
1271    useSignalHandler_ = rhs.useSignalHandler_;
1272    numberParameters_ = rhs.numberParameters_;
1273    memcpy(parameters_,rhs.parameters_,sizeof(parameters_));
1274  }
1275  return *this;
1276}
1277
1278// Destructor
1279CbcSolverUsefulData::~CbcSolverUsefulData ()
1280{
1281}
1282
1283/*
1284  Meaning of whereFrom:
1285    1 after initial solve by dualsimplex etc
1286    2 after preprocessing
1287    3 just before branchAndBound (so user can override)
1288    4 just after branchAndBound (before postprocessing)
1289    5 after postprocessing
1290    6 after a user called heuristic phase
1291*/
1292
1293int CbcMain1 (int argc, const char *argv[],
1294              CbcModel  & model,
1295              int callBack(CbcModel * currentSolver, int whereFrom))
1296{
1297  // allow interrupts and printing
1298  staticParameterData.noPrinting_ = false;
1299  staticParameterData.useSignalHandler_=true;
1300  return CbcMain1(argc,argv,model,callBack,staticParameterData);
1301}
1302static void printGeneralMessage(CbcModel &model,const char * message);
1303/*
1304  Meaning of whereFrom:
1305    1 after initial solve by dualsimplex etc
1306    2 after preprocessing
1307    3 just before branchAndBound (so user can override)
1308    4 just after branchAndBound (before postprocessing)
1309    5 after postprocessing
1310    6 after a user called heuristic phase
1311*/
1312int CbcMain1 (int argc, const char *argv[],
1313              CbcModel  & model,
1314              int callBack(CbcModel * currentSolver, int whereFrom),
1315              CbcSolverUsefulData & parameterData)
1316{
1317    CbcOrClpParam * parameters_ = parameterData.parameters_;
1318    int numberParameters_ = parameterData.numberParameters_;
1319    double totalTime = parameterData.totalTime_;
1320    bool noPrinting = parameterData.noPrinting_;
1321    bool useSignalHandler = parameterData.useSignalHandler_;
1322    CbcModel & model_ = model;
1323#ifdef CBC_THREAD_SAFE
1324    // Initialize argument
1325    int whichArgument=1;
1326#endif
1327#ifdef CBC_USE_INITIAL_TIME
1328    if (model_.useElapsedTime())
1329      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1330    else
1331      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1332#endif
1333    CbcModel * babModel_ = NULL;
1334    int returnMode = 1;
1335    CbcOrClpRead_mode = 1;
1336    int statusUserFunction_[1];
1337    int numberUserFunctions_ = 1; // to allow for ampl
1338    // Statistics
1339    double statistics_seconds = 0.0, statistics_obj = 0.0;
1340    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1341    CoinWallclockTime();
1342    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1343    double statistics_cut_time = 0.0;
1344    int statistics_nodes = 0, statistics_iterations = 0;
1345    int statistics_nrows = 0, statistics_ncols = 0;
1346    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1347    std::string statistics_result;
1348    int * statistics_number_cuts = NULL;
1349    const char ** statistics_name_generators = NULL;
1350    int statistics_number_generators = 0;
1351    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1352    /* Note
1353       This is meant as a stand-alone executable to do as much of coin as possible.
1354       It should only have one solver known to it.
1355    */
1356    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1357    generalMessageHandler->setPrefix(false);
1358#ifndef CBC_OTHER_SOLVER
1359    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1360    assert (originalSolver);
1361    // Move handler across if not default
1362    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1363        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1364    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1365    char generalPrint[10000];
1366    if (originalSolver->getModelPtr()->logLevel() == 0)
1367        noPrinting = true;
1368#elif CBC_OTHER_SOLVER==1
1369    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1370    assert (originalSolver);
1371    OsiClpSolverInterface dummySolver;
1372    OsiCpxSolverInterface * clpSolver = originalSolver;
1373    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1374    char generalPrint[10000];
1375    noPrinting = true;
1376#endif
1377    bool noPrinting_ = noPrinting;
1378    // Say not in integer
1379    int integerStatus = -1;
1380    // Say no resolve after cuts
1381    model_.setResolveAfterTakeOffCuts(false);
1382    // see if log in list
1383    for (int i = 1; i < argc; i++) {
1384        if (!strncmp(argv[i], "log", 3)) {
1385            const char * equals = strchr(argv[i], '=');
1386            if (equals && atoi(equals + 1) != 0)
1387                noPrinting_ = false;
1388            else
1389                noPrinting_ = true;
1390            break;
1391        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1392            if (atoi(argv[i+1]) != 0)
1393                noPrinting_ = false;
1394            else
1395                noPrinting_ = true;
1396            break;
1397        }
1398    }
1399    double time0;
1400    double time0Elapsed = CoinGetTimeOfDay();
1401    {
1402        double time1 = CoinCpuTime(), time2;
1403        time0 = time1;
1404        double time1Elapsed = time0Elapsed;
1405        bool goodModel = (originalSolver->getNumCols()) ? true : false;
1406
1407        // register signal handler
1408        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
1409#if CBC_QUIET < 2
1410        if (useSignalHandler)
1411          signal(SIGINT, signal_handler);
1412#endif
1413        // Set up all non-standard stuff
1414        int cutPass = -1234567;
1415        int cutPassInTree = -1234567;
1416        int tunePreProcess = 0;
1417        int testOsiParameters = -1;
1418        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1419        int complicatedInteger = 0;
1420        OsiSolverInterface * solver = model_.solver();
1421        if (noPrinting_)
1422            setCbcOrClpPrinting(false);
1423#ifndef CBC_OTHER_SOLVER
1424        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1425        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1426        if (noPrinting_) {
1427            lpSolver->setLogLevel(0);
1428        }
1429#else
1430        ClpSimplex * lpSolver = NULL;
1431#endif
1432        // For priorities etc
1433        int * priorities = NULL;
1434        int * branchDirection = NULL;
1435        double * pseudoDown = NULL;
1436        double * pseudoUp = NULL;
1437        double * solutionIn = NULL;
1438        int * prioritiesIn = NULL;
1439        std::vector< std::pair< std::string, double > > mipStart;
1440        std::vector< std::pair< std::string, double > > mipStartBefore;
1441        int numberSOS = 0;
1442        int * sosStart = NULL;
1443        int * sosIndices = NULL;
1444        char * sosType = NULL;
1445        double * sosReference = NULL;
1446        int * cut = NULL;
1447        int * sosPriority = NULL;
1448        CglStored storedAmpl;
1449        CoinModel * coinModel = NULL;
1450        CoinModel saveCoinModel;
1451        CoinModel saveTightenedModel;
1452        int * whichColumn = NULL;
1453        int * knapsackStart = NULL;
1454        int * knapsackRow = NULL;
1455        int numberKnapsack = 0;
1456#ifdef COIN_HAS_ASL
1457        ampl_info info;
1458        {
1459            memset(&info, 0, sizeof(info));
1460            if (argc > 2 && !strcmp(argv[2], "-AMPL")) {
1461                statusUserFunction_[0] = 1;
1462                // see if log in list
1463                noPrinting_ = true;
1464                for (int i = 1; i < argc; i++) {
1465                    if (!strncmp(argv[i], "log", 3)) {
1466                        const char * equals = strchr(argv[i], '=');
1467                        if (equals && atoi(equals + 1) > 0) {
1468                            noPrinting_ = false;
1469                            info.logLevel = atoi(equals + 1);
1470                            int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1471                            parameters_[log].setIntValue(info.logLevel);
1472                            // mark so won't be overWritten
1473                            info.numberRows = -1234567;
1474                            break;
1475                        }
1476                    }
1477                }
1478
1479                union {
1480                    void * voidModel;
1481                    CoinModel * model;
1482                } coinModelStart;
1483                coinModelStart.model = NULL;
1484                int returnCode = readAmpl(&info, argc, const_cast<char **>(argv), & coinModelStart.voidModel);
1485                coinModel = coinModelStart.model;
1486                if (returnCode)
1487                    return returnCode;
1488                CbcOrClpRead_mode = 2; // so will start with parameters
1489                // see if log in list (including environment)
1490                for (int i = 1; i < info.numberArguments; i++) {
1491                    if (!strcmp(info.arguments[i], "log")) {
1492                        if (i < info.numberArguments - 1 && atoi(info.arguments[i+1]) > 0)
1493                            noPrinting_ = false;
1494                        break;
1495                    }
1496                }
1497                if (noPrinting_) {
1498                    model_.messageHandler()->setLogLevel(0);
1499                    setCbcOrClpPrinting(false);
1500                }
1501                if (!noPrinting_)
1502                    printf("%d rows, %d columns and %d elements\n",
1503                           info.numberRows, info.numberColumns, info.numberElements);
1504#ifdef COIN_HAS_LINK
1505                if (!coinModel) {
1506#endif
1507                    solver->loadProblem(info.numberColumns, info.numberRows, info.starts,
1508                                        info.rows, info.elements,
1509                                        info.columnLower, info.columnUpper, info.objective,
1510                                        info.rowLower, info.rowUpper);
1511                    // take off cuts if ampl wants that
1512                    if (info.cut && 0) {
1513                        printf("AMPL CUTS OFF until global cuts fixed\n");
1514                        info.cut = NULL;
1515                    }
1516                    if (info.cut) {
1517                        int numberRows = info.numberRows;
1518                        int * whichRow = new int [numberRows];
1519                        // Row copy
1520                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1521                        const double * elementByRow = matrixByRow->getElements();
1522                        const int * column = matrixByRow->getIndices();
1523                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1524                        const int * rowLength = matrixByRow->getVectorLengths();
1525
1526                        const double * rowLower = solver->getRowLower();
1527                        const double * rowUpper = solver->getRowUpper();
1528                        int nDelete = 0;
1529                        for (int iRow = 0; iRow < numberRows; iRow++) {
1530                            if (info.cut[iRow]) {
1531                                whichRow[nDelete++] = iRow;
1532                                int start = rowStart[iRow];
1533                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1534                                                  rowLength[iRow], column + start, elementByRow + start);
1535                            }
1536                        }
1537                        solver->deleteRows(nDelete, whichRow);
1538                        delete [] whichRow;
1539                    }
1540#ifdef COIN_HAS_LINK
1541                } else {
1542#ifndef CBC_OTHER_SOLVER
1543                    // save
1544                    saveCoinModel = *coinModel;
1545                    // load from coin model
1546                    OsiSolverLink solver1;
1547                    OsiSolverInterface * solver2 = solver1.clone();
1548                    model_.assignSolver(solver2, false);
1549                    OsiSolverLink * si =
1550                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1551                    assert (si != NULL);
1552                    si->setDefaultMeshSize(0.001);
1553                    // need some relative granularity
1554                    si->setDefaultBound(100.0);
1555                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
1556                    if (dextra3)
1557                        si->setDefaultMeshSize(dextra3);
1558                    si->setDefaultBound(100000.0);
1559                    si->setIntegerPriority(1000);
1560                    si->setBiLinearPriority(10000);
1561                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
1562                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1563                    si->load(*model2, true, logLevel);
1564                    // redo
1565                    solver = model_.solver();
1566                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1567                    lpSolver = clpSolver->getModelPtr();
1568                    clpSolver->messageHandler()->setLogLevel(0) ;
1569                    testOsiParameters = 0;
1570                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
1571                    complicatedInteger = 1;
1572                    if (info.cut) {
1573                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1574                        abort();
1575                        int numberRows = info.numberRows;
1576                        int * whichRow = new int [numberRows];
1577                        // Row copy
1578                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1579                        const double * elementByRow = matrixByRow->getElements();
1580                        const int * column = matrixByRow->getIndices();
1581                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1582                        const int * rowLength = matrixByRow->getVectorLengths();
1583
1584                        const double * rowLower = solver->getRowLower();
1585                        const double * rowUpper = solver->getRowUpper();
1586                        int nDelete = 0;
1587                        for (int iRow = 0; iRow < numberRows; iRow++) {
1588                            if (info.cut[iRow]) {
1589                                whichRow[nDelete++] = iRow;
1590                                int start = rowStart[iRow];
1591                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1592                                                  rowLength[iRow], column + start, elementByRow + start);
1593                            }
1594                        }
1595                        solver->deleteRows(nDelete, whichRow);
1596                        // and special matrix
1597                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1598                        delete [] whichRow;
1599                    }
1600#endif
1601                }
1602#endif
1603                // If we had a solution use it
1604                if (info.primalSolution) {
1605                    solver->setColSolution(info.primalSolution);
1606                }
1607                // status
1608                if (info.rowStatus) {
1609                    unsigned char * statusArray = lpSolver->statusArray();
1610                    int i;
1611                    for (i = 0; i < info.numberColumns; i++)
1612                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1613                    statusArray += info.numberColumns;
1614                    for (i = 0; i < info.numberRows; i++)
1615                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1616                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1617                    solver->setWarmStart(basis);
1618                    delete basis;
1619                }
1620                freeArrays1(&info);
1621                // modify objective if necessary
1622                solver->setObjSense(info.direction);
1623                solver->setDblParam(OsiObjOffset, -info.offset);
1624                if (info.offset) {
1625                    sprintf(generalPrint, "Ampl objective offset is %g",
1626                            info.offset);
1627                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1628                    << generalPrint
1629                    << CoinMessageEol;
1630                }
1631                // Set integer variables (unless nonlinear when set)
1632                if (!info.nonLinear) {
1633                    for (int i = info.numberColumns - info.numberIntegers;
1634                            i < info.numberColumns; i++)
1635                        solver->setInteger(i);
1636                }
1637                goodModel = true;
1638                // change argc etc
1639                argc = info.numberArguments;
1640                argv = const_cast<const char **>(info.arguments);
1641            }
1642        }
1643#endif
1644        // default action on import
1645        int allowImportErrors = 0;
1646        int keepImportNames = 1;
1647        int doIdiot = -1;
1648        int outputFormat = 2;
1649        int slpValue = -1;
1650        int cppValue = -1;
1651        int printOptions = 0;
1652        int printMode = 0;
1653        int presolveOptions = 0;
1654        int substitution = 3;
1655        int dualize = 3;
1656        int doCrash = 0;
1657        int doVector = 0;
1658        int doSprint = -1;
1659        int doScaling = 4;
1660        // set reasonable defaults
1661        int preSolve = 5;
1662        int preProcess = 4;
1663        bool useStrategy = false;
1664        bool preSolveFile = false;
1665        bool strongChanged = false;
1666        bool pumpChanged = false;
1667
1668        double djFix = 1.0e100;
1669        double tightenFactor = 0.0;
1670        const char dirsep =  CoinFindDirSeparator();
1671        std::string directory;
1672        std::string dirSample;
1673        std::string dirNetlib;
1674        std::string dirMiplib;
1675        if (dirsep == '/') {
1676            directory = "./";
1677            dirSample = "../../Data/Sample/";
1678            dirNetlib = "../../Data/Netlib/";
1679            dirMiplib = "../../Data/miplib3/";
1680        } else {
1681            directory = ".\\";
1682            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1683            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1684            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
1685        }
1686        std::string defaultDirectory = directory;
1687        std::string importFile = "";
1688        std::string exportFile = "default.mps";
1689        std::string importBasisFile = "";
1690        std::string importPriorityFile = "";
1691        std::string debugFile = "";
1692        std::string printMask = "";
1693        double * debugValues = NULL;
1694        int numberDebugValues = -1;
1695        int basisHasValues = 0;
1696        std::string exportBasisFile = "default.bas";
1697        std::string saveFile = "default.prob";
1698        std::string restoreFile = "default.prob";
1699        std::string solutionFile = "stdout";
1700        std::string solutionSaveFile = "solution.file";
1701        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1702        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1703#ifndef CBC_OTHER_SOLVER
1704        double normalIncrement = model_.getCutoffIncrement();;
1705#endif
1706        if (testOsiParameters >= 0) {
1707            // trying nonlinear - switch off some stuff
1708            preProcess = 0;
1709        }
1710        // Set up likely cut generators and defaults
1711        int nodeStrategy = 0;
1712        bool dominatedCuts = false;
1713        int doSOS = 1;
1714        int verbose = 0;
1715        CglGomory gomoryGen;
1716        // try larger limit
1717        gomoryGen.setLimitAtRoot(1000);
1718        gomoryGen.setLimit(50);
1719        // set default action (0=off,1=on,2=root)
1720        int gomoryAction = 3;
1721
1722        CglProbing probingGen;
1723        probingGen.setUsingObjective(1);
1724        probingGen.setMaxPass(1);
1725        probingGen.setMaxPassRoot(1);
1726        // Number of unsatisfied variables to look at
1727        probingGen.setMaxProbe(10);
1728        probingGen.setMaxProbeRoot(50);
1729        // How far to follow the consequences
1730        probingGen.setMaxLook(10);
1731        probingGen.setMaxLookRoot(50);
1732        probingGen.setMaxLookRoot(10);
1733        // Only look at rows with fewer than this number of elements
1734        probingGen.setMaxElements(200);
1735        probingGen.setMaxElementsRoot(300);
1736        probingGen.setRowCuts(3);
1737        // set default action (0=off,1=on,2=root)
1738        int probingAction = 1;
1739
1740        CglKnapsackCover knapsackGen;
1741        //knapsackGen.switchOnExpensive();
1742        //knapsackGen.setMaxInKnapsack(100);
1743        // set default action (0=off,1=on,2=root)
1744        int knapsackAction = 3;
1745
1746        CglRedSplit redsplitGen;
1747        //redsplitGen.setLimit(100);
1748        // set default action (0=off,1=on,2=root)
1749        // Off as seems to give some bad cuts
1750        int redsplitAction = 0;
1751
1752        CglRedSplit2 redsplit2Gen;
1753        //redsplit2Gen.setLimit(100);
1754        // set default action (0=off,1=on,2=root)
1755        // Off
1756        int redsplit2Action = 0;
1757
1758        CglGMI GMIGen;
1759        //GMIGen.setLimit(100);
1760        // set default action (0=off,1=on,2=root)
1761        // Off
1762        int GMIAction = 0;
1763
1764        CglFakeClique cliqueGen(NULL, false);
1765        //CglClique cliqueGen(false,true);
1766        cliqueGen.setStarCliqueReport(false);
1767        cliqueGen.setRowCliqueReport(false);
1768        cliqueGen.setMinViolation(0.1);
1769        // set default action (0=off,1=on,2=root)
1770        int cliqueAction = 3;
1771
1772        // maxaggr,multiply,criterion(1-3)
1773        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1774        // set default action (0=off,1=on,2=root)
1775        int mixedAction = 3;
1776        mixedGen.setDoPreproc(1); // safer (and better)
1777
1778        CglFlowCover flowGen;
1779        // set default action (0=off,1=on,2=root)
1780        int flowAction = 3;
1781
1782        CglTwomir twomirGen;
1783        twomirGen.setMaxElements(250);
1784        // set default action (0=off,1=on,2=root)
1785        int twomirAction = 3;
1786#ifndef DEBUG_MALLOC
1787        CglLandP landpGen;
1788        landpGen.validator().setMinViolation(1.0e-4);
1789#endif
1790        // set default action (0=off,1=on,2=root)
1791        int landpAction = 0;
1792        CglResidualCapacity residualCapacityGen;
1793        residualCapacityGen.setDoPreproc(1); // always preprocess
1794        // set default action (0=off,1=on,2=root)
1795        int residualCapacityAction = 0;
1796
1797        CglZeroHalf zerohalfGen;
1798        //zerohalfGen.switchOnExpensive();
1799        // set default action (0=off,1=on,2=root)
1800        int zerohalfAction = 0;
1801
1802        // Stored cuts
1803        //bool storedCuts = false;
1804
1805        int useCosts = 0;
1806        // don't use input solution
1807        int useSolution = -1;
1808
1809        // total number of commands read
1810        int numberGoodCommands = 0;
1811        // Set false if user does anything advanced
1812        bool defaultSettings = true;
1813
1814        // Hidden stuff for barrier
1815        int choleskyType = 0;
1816        int gamma = 0;
1817        int scaleBarrier = 0;
1818        int doKKT = 0;
1819        int crossover = 2; // do crossover unless quadratic
1820        bool biLinearProblem=false;
1821        // For names
1822        int lengthName = 0;
1823        std::vector<std::string> rowNames;
1824        std::vector<std::string> columnNames;
1825        // Default strategy stuff
1826        {
1827            // try changing tolerance at root
1828#define MORE_CUTS
1829#ifdef MORE_CUTS
1830            gomoryGen.setAwayAtRoot(0.005);
1831            twomirGen.setAwayAtRoot(0.005);
1832            twomirGen.setAway(0.01);
1833            //twomirGen.setMirScale(1,1);
1834            //twomirGen.setTwomirScale(1,1);
1835            //twomirGen.setAMax(2);
1836#else
1837            gomoryGen.setAwayAtRoot(0.01);
1838            twomirGen.setAwayAtRoot(0.01);
1839            twomirGen.setAway(0.01);
1840#endif
1841            int iParam;
1842            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
1843            parameters_[iParam].setIntValue(2);
1844            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
1845            parameters_[iParam].setIntValue(30);
1846            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
1847            parameters_[iParam].setIntValue(1005043);
1848            initialPumpTune = 1005043;
1849            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
1850            parameters_[iParam].setIntValue(6);
1851            tunePreProcess = 6;
1852            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
1853            parameters_[iParam].setCurrentOption("on");
1854            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
1855            parameters_[iParam].setCurrentOption("on");
1856            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
1857            parameters_[iParam].setCurrentOption("on");
1858            probingAction = 3;
1859            //parameters_[iParam].setCurrentOption("forceOnStrong");
1860            //probingAction = 8;
1861        }
1862        std::string field;
1863#if CBC_QUIET == 0
1864        if (!noPrinting_) {
1865           sprintf(generalPrint,
1866                   "Welcome to the CBC MILP Solver \n");
1867            if (strcmp(CBC_VERSION, "trunk")){
1868               sprintf(generalPrint + strlen(generalPrint),
1869                       "Version: %s \n", CBC_VERSION);
1870            }else{
1871               sprintf(generalPrint + strlen(generalPrint),
1872                       "Version: Trunk (unstable) \n");
1873            }
1874            sprintf(generalPrint + strlen(generalPrint),
1875                    "Build Date: %s \n", __DATE__);
1876#ifdef CBC_SVN_REV
1877            sprintf(generalPrint + strlen(generalPrint),
1878                    "Revision Number: %d \n", CBC_SVN_REV);
1879#endif
1880            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1881            << generalPrint
1882            << CoinMessageEol;
1883            // Print command line
1884            if (argc > 1) {
1885                bool foundStrategy = false;
1886                sprintf(generalPrint, "command line - ");
1887                for (int i = 0; i < argc; i++) {
1888                    if (!argv[i])
1889                        break;
1890                    if (strstr(argv[i], "strat"))
1891                        foundStrategy = true;
1892                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1893                }
1894                if (!foundStrategy)
1895                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1896                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1897                << generalPrint
1898                << CoinMessageEol;
1899            }
1900        }
1901#endif
1902        while (1) {
1903            // next command
1904            field = CoinReadGetCommand(argc, argv);
1905            // Reset time
1906            time1 = CoinCpuTime();
1907            time1Elapsed = CoinGetTimeOfDay();
1908            // adjust field if has odd trailing characters
1909            char temp [200];
1910            strcpy(temp, field.c_str());
1911            int length = static_cast<int>(strlen(temp));
1912            for (int k = length - 1; k >= 0; k--) {
1913                if (temp[k] < ' ')
1914                    length--;
1915                else
1916                    break;
1917            }
1918            temp[length] = '\0';
1919            field = temp;
1920            // exit if null or similar
1921            if (!field.length()) {
1922                if (numberGoodCommands == 1 && goodModel) {
1923                    // we just had file name - do branch and bound
1924                    field = "branch";
1925                } else if (!numberGoodCommands) {
1926                    // let's give the sucker a hint
1927                    std::cout
1928                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1929                        << std::endl
1930                        << "Enter ? for list of commands or help" << std::endl;
1931                    field = "-";
1932                } else {
1933                    break;
1934                }
1935            }
1936
1937            // see if ? at end
1938            size_t numberQuery = 0;
1939            if (field != "?" && field != "???") {
1940                size_t length = field.length();
1941                size_t i;
1942                for (i = length - 1; i > 0; i--) {
1943                    if (field[i] == '?')
1944                        numberQuery++;
1945                    else
1946                        break;
1947                }
1948                field = field.substr(0, length - numberQuery);
1949            }
1950            // find out if valid command
1951            int iParam;
1952            int numberMatches = 0;
1953            int firstMatch = -1;
1954            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1955                int match = parameters_[iParam].matches(field);
1956                if (match == 1) {
1957                    numberMatches = 1;
1958                    firstMatch = iParam;
1959                    break;
1960                } else {
1961                    if (match && firstMatch < 0)
1962                        firstMatch = iParam;
1963                    numberMatches += match >> 1;
1964                }
1965            }
1966            if (iParam < numberParameters_ && !numberQuery) {
1967                // found
1968                CbcOrClpParam found = parameters_[iParam];
1969                CbcOrClpParameterType type = found.type();
1970                int valid;
1971                numberGoodCommands++;
1972                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
1973#ifndef CBC_USE_INITIAL_TIME
1974                  if (model_.useElapsedTime())
1975                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1976                  else
1977                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1978#endif
1979                  biLinearProblem=false;
1980                    // check if any integers
1981#ifndef CBC_OTHER_SOLVER
1982#ifdef COIN_HAS_ASL
1983                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1984                        // SOS
1985                        numberSOS = info.numberSos;
1986                    }
1987#endif
1988                    lpSolver = clpSolver->getModelPtr();
1989                    if (!lpSolver->integerInformation() && !numberSOS &&
1990                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
1991                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
1992#endif
1993                }
1994                if (type == CBC_PARAM_GENERALQUERY) {
1995                    bool evenHidden = false;
1996                    int printLevel =
1997                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
1998                                               numberParameters_, parameters_)].currentOptionAsInteger();
1999                    int convertP[] = {2, 1, 0};
2000                    printLevel = convertP[printLevel];
2001                    if ((verbose&8) != 0) {
2002                        // even hidden
2003                        evenHidden = true;
2004                        verbose &= ~8;
2005                    }
2006#ifdef COIN_HAS_ASL
2007                    if (verbose < 4 && statusUserFunction_[0])
2008                        verbose += 4;
2009#endif
2010                    if (verbose < 4) {
2011                        std::cout << "In argument list keywords have leading - "
2012                                  ", -stdin or just - switches to stdin" << std::endl;
2013                        std::cout << "One command per line (and no -)" << std::endl;
2014                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
2015                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
2016                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
2017                        std::cout << "abcd value sets value" << std::endl;
2018                        std::cout << "Commands are:" << std::endl;
2019                    } else {
2020                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
2021                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
2022                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
2023                    }
2024                    int maxAcross = 10;
2025                    if ((verbose % 4) != 0)
2026                        maxAcross = 1;
2027                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2028                    std::vector<std::string> types;
2029                    types.push_back("Double parameters:");
2030                    types.push_back("Branch and Cut double parameters:");
2031                    types.push_back("Integer parameters:");
2032                    types.push_back("Branch and Cut integer parameters:");
2033                    types.push_back("Keyword parameters:");
2034                    types.push_back("Branch and Cut keyword parameters:");
2035                    types.push_back("Actions or string parameters:");
2036                    types.push_back("Branch and Cut actions:");
2037                    int iType;
2038                    for (iType = 0; iType < 8; iType++) {
2039                        int across = 0;
2040                        int lengthLine = 0;
2041                        if ((verbose % 4) != 0)
2042                            std::cout << std::endl;
2043                        std::cout << types[iType] << std::endl;
2044                        if ((verbose&2) != 0)
2045                            std::cout << std::endl;
2046                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2047                            int type = parameters_[iParam].type();
2048                            //printf("%d type %d limits %d %d display %d\n",iParam,
2049                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
2050                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
2051                                    type >= limits[iType]
2052                                    && type < limits[iType+1]) {
2053                                // but skip if not useful for ampl (and in ampl mode)
2054                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
2055                                    continue;
2056                                if (!across) {
2057                                    if ((verbose&2) != 0)
2058                                        std::cout << "Command ";
2059                                }
2060                                int length = parameters_[iParam].lengthMatchName() + 1;
2061                                if (lengthLine + length > 80) {
2062                                    std::cout << std::endl;
2063                                    across = 0;
2064                                    lengthLine = 0;
2065                                }
2066                                std::cout << " " << parameters_[iParam].matchName();
2067                                lengthLine += length;
2068                                across++;
2069                                if (across == maxAcross) {
2070                                    across = 0;
2071                                    if ((verbose % 4) != 0) {
2072                                        // put out description as well
2073                                        if ((verbose&1) != 0)
2074                                            std::cout << " " << parameters_[iParam].shortHelp();
2075                                        std::cout << std::endl;
2076                                        if ((verbose&2) != 0) {
2077                                            std::cout << "---- description" << std::endl;
2078                                            parameters_[iParam].printLongHelp();
2079                                            std::cout << "----" << std::endl << std::endl;
2080                                        }
2081                                    } else {
2082                                        std::cout << std::endl;
2083                                    }
2084                                }
2085                            }
2086                        }
2087                        if (across)
2088                            std::cout << std::endl;
2089                    }
2090                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
2091                    std::cout << "Full list of commands is:" << std::endl;
2092                    int maxAcross = 5;
2093                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2094                    std::vector<std::string> types;
2095                    types.push_back("Double parameters:");
2096                    types.push_back("Branch and Cut double parameters:");
2097                    types.push_back("Integer parameters:");
2098                    types.push_back("Branch and Cut integer parameters:");
2099                    types.push_back("Keyword parameters:");
2100                    types.push_back("Branch and Cut keyword parameters:");
2101                    types.push_back("Actions or string parameters:");
2102                    types.push_back("Branch and Cut actions:");
2103                    int iType;
2104                    for (iType = 0; iType < 8; iType++) {
2105                        int across = 0;
2106                        std::cout << types[iType] << "  ";
2107                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2108                            int type = parameters_[iParam].type();
2109                            if (type >= limits[iType]
2110                                    && type < limits[iType+1]) {
2111                                if (!across)
2112                                    std::cout << "  ";
2113                                std::cout << parameters_[iParam].matchName() << "  ";
2114                                across++;
2115                                if (across == maxAcross) {
2116                                    std::cout << std::endl;
2117                                    across = 0;
2118                                }
2119                            }
2120                        }
2121                        if (across)
2122                            std::cout << std::endl;
2123                    }
2124                } else if (type < 101) {
2125                    // get next field as double
2126                    double value = CoinReadGetDoubleField(argc, argv, &valid);
2127                    if (!valid) {
2128                        if (type < 51) {
2129                            int returnCode;
2130                            const char * message =
2131                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2132                            if (!noPrinting_ && strlen(message)) {
2133                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2134                                << message
2135                                << CoinMessageEol;
2136                            }
2137                        } else if (type < 81) {
2138                            int returnCode;
2139                            const char * message =
2140                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
2141                            if (!noPrinting_ && strlen(message)) {
2142                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2143                                << message
2144                                << CoinMessageEol;
2145                            }
2146                        } else {
2147                            int returnCode;
2148                            const char * message =
2149                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2150                            if (!noPrinting_ && strlen(message)) {
2151                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2152                                << message
2153                                << CoinMessageEol;
2154                            }
2155                            switch (type) {
2156                            case CBC_PARAM_DBL_DJFIX:
2157                                djFix = value;
2158#ifndef CBC_OTHER_SOLVER
2159                                if (goodModel && djFix < 1.0e20) {
2160                                    // do some fixing
2161                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
2162                                    clpSolver->initialSolve();
2163                                    lpSolver = clpSolver->getModelPtr();
2164                                    int numberColumns = lpSolver->numberColumns();
2165                                    int i;
2166                                    const char * type = lpSolver->integerInformation();
2167                                    double * lower = lpSolver->columnLower();
2168                                    double * upper = lpSolver->columnUpper();
2169                                    double * solution = lpSolver->primalColumnSolution();
2170                                    double * dj = lpSolver->dualColumnSolution();
2171                                    int numberFixed = 0;
2172                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
2173                                    if (dextra4)
2174                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
2175                                    for (i = 0; i < numberColumns; i++) {
2176                                        double djValue = dj[i];
2177                                        if (!type[i])
2178                                            djValue *= dextra4;
2179                                        if (type[i] || dextra4) {
2180                                            double value = solution[i];
2181                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
2182                                                solution[i] = lower[i];
2183                                                upper[i] = lower[i];
2184                                                numberFixed++;
2185                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
2186                                                solution[i] = upper[i];
2187                                                lower[i] = upper[i];
2188                                                numberFixed++;
2189                                            }
2190                                        }
2191                                    }
2192                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
2193                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2194                                    << generalPrint
2195                                    << CoinMessageEol;
2196                                }
2197#endif
2198                                break;
2199                            case CBC_PARAM_DBL_TIGHTENFACTOR:
2200                                tightenFactor = value;
2201                                if (!complicatedInteger)
2202                                    defaultSettings = false; // user knows what she is doing
2203                                break;
2204                            default:
2205                                break;
2206                            }
2207                        }
2208                    } else if (valid == 1) {
2209                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2210                                  parameters_[iParam].doubleValue() << std::endl;
2211                    } else {
2212                        std::cout << parameters_[iParam].name() << " has value " <<
2213                                  parameters_[iParam].doubleValue() << std::endl;
2214                    }
2215                } else if (type < 201) {
2216                    // get next field as int
2217                    int value = CoinReadGetIntField(argc, argv, &valid);
2218                    if (!valid) {
2219                        if (type < 151) {
2220                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
2221                                preSolve = value;
2222                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
2223                                doIdiot = value;
2224                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
2225                                doSprint = value;
2226                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
2227                                outputFormat = value;
2228                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
2229                                slpValue = value;
2230                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
2231                                cppValue = value;
2232                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
2233                                presolveOptions = value;
2234                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
2235                                printOptions = value;
2236                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
2237                                substitution = value;
2238                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
2239                                dualize = value;
2240                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
2241                                tunePreProcess = value;
2242                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
2243                                useSolution = value;
2244                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
2245                                verbose = value;
2246                            int returnCode;
2247                            const char * message =
2248                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2249                            if (!noPrinting_ && strlen(message)) {
2250                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2251                                << message
2252                                << CoinMessageEol;
2253                            }
2254                        } else {
2255                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
2256                                cutPass = value;
2257                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
2258                                cutPassInTree = value;
2259                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2260                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
2261                                strongChanged = true;
2262                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2263                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2264                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
2265                                pumpChanged = true;
2266                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
2267                                int addFlags=0;
2268                                // switch on some later features if >999
2269                                if (value>999) {
2270                                  int switchValue=value/1000;
2271                                  const char * message = NULL;
2272                                  value -= 1000*switchValue;
2273                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(0/*value*/);
2274                                  switch (switchValue) {
2275                                  default:
2276                                  case 4:
2277                                    // hotstart 500, -200 cut passes
2278                                    message=parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValueWithMessage(500);
2279                                    if (!noPrinting_&&message) 
2280                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2281                                        << message << CoinMessageEol;
2282                                    message=parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValueWithMessage(-200);
2283                                    if (!noPrinting_&&message) 
2284                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2285                                        << message << CoinMessageEol;
2286                                  case 3:
2287                                    // multiple 4
2288                                    message=parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValueWithMessage(4);
2289                                    if (!noPrinting_&&message) 
2290                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2291                                        << message << CoinMessageEol;
2292                                  case 2:
2293                                    // rens plus all diving at root
2294                                    message=parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].setIntValueWithMessage(16);
2295                                    if (!noPrinting_&&message) 
2296                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2297                                        << message << CoinMessageEol;
2298                                    model_.setNumberAnalyzeIterations(-value);
2299                                    // -tune 7 zero,lagomory,gmi at root - probing on
2300                                  case 1:
2301                                    tunePreProcess=7;
2302                                    message=parameters_[whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_)].setIntValueWithMessage(7);
2303                                    if (!noPrinting_&&message) 
2304                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2305                                        << message << CoinMessageEol;
2306                                    //message = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValueWithMessage(1025);
2307                                    //if (!noPrinting_&&message)
2308                                    //    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2309                                    //  << message << CoinMessageEol;
2310                                    message=parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("on");
2311                                    probingAction = 1;
2312                                    if (!noPrinting_&&message) 
2313                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2314                                        << message << CoinMessageEol;
2315                                    message=parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2316                                    if (!noPrinting_&&message) 
2317                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2318                                        << message << CoinMessageEol;
2319                                    message=parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2320                                    if (!noPrinting_&&message) 
2321                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2322                                        << message << CoinMessageEol;
2323                                    GMIAction = 2;
2324                                    message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2325                                    if (!noPrinting_&&message) 
2326                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2327                                        << message << CoinMessageEol;
2328                                  }
2329                                  value = 0;
2330                                }
2331                                if (value>=10) {
2332                                  addFlags = 1048576*(value/10);
2333                                  value = value % 10;
2334                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(value);
2335                                }
2336                                if (value >= 1) {
2337                                    int values[]={24003,280003,792003,24003,24003};
2338                                    if (value>=2&&value<=3) {
2339                                      // swap default diving
2340                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2341                                      parameters_[iParam].setCurrentOption("off");
2342                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2343                                      parameters_[iParam].setCurrentOption("on");
2344                                    }
2345                                    int extra4 = values[value-1]+addFlags;
2346                                    parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].setIntValue(extra4);
2347                                    if (!noPrinting_) {
2348                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2349                                        << "switching on global root cuts for gomory and knapsack"
2350                                        << CoinMessageEol;
2351                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2352                                        << "using OSL factorization"
2353                                        << CoinMessageEol;
2354                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2355                                        << "extra options - -rens on -extra4 "
2356                                        <<extra4<<" -passc 1000!"
2357                                        << CoinMessageEol;
2358                                    }
2359                                    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("forceOnStrong");
2360                                    probingAction = 8;
2361                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2362                                    gomoryAction = 5;
2363                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2364                                    knapsackAction = 5;
2365                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
2366                                    lpSolver->factorization()->forceOtherFactorization(3);
2367                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
2368                                    parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValue(1000);
2369                                    cutPass = 1000;
2370                                    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("on");
2371                                }
2372                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
2373                                if (value == 0) {
2374                                    gomoryGen.setAwayAtRoot(0.05);
2375                                    int iParam;
2376                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
2377                                    parameters_[iParam].setIntValue(-1);
2378                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
2379                                    parameters_[iParam].setIntValue(20);
2380                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
2381                                    parameters_[iParam].setIntValue(1003);
2382                                    initialPumpTune = 1003;
2383                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
2384                                    parameters_[iParam].setIntValue(0);
2385                                    tunePreProcess = 0;
2386                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2387                                    parameters_[iParam].setCurrentOption("off");
2388                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
2389                                    parameters_[iParam].setCurrentOption("off");
2390                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
2391                                    // but not if cuts off
2392                                    int jParam = whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_);
2393                                   
2394                                    jParam = parameters_[jParam].currentOptionAsInteger();
2395                                    if (jParam) {
2396                                      parameters_[iParam].setCurrentOption("on");
2397                                      probingAction = 1;
2398                                    } else {
2399                                      parameters_[iParam].setCurrentOption("off");
2400                                      probingAction = 0;
2401                                    }
2402                                }
2403                            }
2404                            int returnCode;
2405                            const char * message =
2406                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2407                            if (!noPrinting_ && strlen(message)) {
2408                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2409                                << message
2410                                << CoinMessageEol;
2411                            }
2412                        }
2413                    } else if (valid == 1) {
2414                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2415                                  parameters_[iParam].intValue() << std::endl;
2416                    } else {
2417                        std::cout << parameters_[iParam].name() << " has value " <<
2418                                  parameters_[iParam].intValue() << std::endl;
2419                    }
2420                } else if (type < 301) {
2421                    // one of several strings
2422                    std::string value = CoinReadGetString(argc, argv);
2423                    int action = parameters_[iParam].parameterOption(value);
2424                    if (action < 0) {
2425                        if (value != "EOL") {
2426                            // no match
2427                            parameters_[iParam].printOptions();
2428                        } else {
2429                            // print current value
2430                            std::cout << parameters_[iParam].name() << " has value " <<
2431                                      parameters_[iParam].currentOption() << std::endl;
2432                        }
2433                    } else {
2434                        const char * message =
2435                            parameters_[iParam].setCurrentOptionWithMessage(action);
2436                        if (!noPrinting_ && strlen(message)) {
2437                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2438                            << message
2439                            << CoinMessageEol;
2440                        }
2441                        // for now hard wired
2442                        switch (type) {
2443                        case CLP_PARAM_STR_DIRECTION:
2444                            if (action == 0)
2445                                lpSolver->setOptimizationDirection(1);
2446                            else if (action == 1)
2447                                lpSolver->setOptimizationDirection(-1);
2448                            else
2449                                lpSolver->setOptimizationDirection(0);
2450                            break;
2451                        case CLP_PARAM_STR_DUALPIVOT:
2452                            if (action == 0) {
2453                                ClpDualRowSteepest steep(3);
2454                                lpSolver->setDualRowPivotAlgorithm(steep);
2455                            } else if (action == 1) {
2456                                ClpDualRowDantzig dantzig;
2457                                //ClpDualRowSteepest dantzig(5);
2458                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2459                            } else if (action == 2) {
2460                                // partial steep
2461                                ClpDualRowSteepest steep(2);
2462                                lpSolver->setDualRowPivotAlgorithm(steep);
2463                            } else if (action == 3) {
2464                                ClpDualRowSteepest steep;
2465                                lpSolver->setDualRowPivotAlgorithm(steep);
2466                            } else if (action == 4) {
2467                              // Positive edge steepest
2468                              ClpPEDualRowSteepest p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2469                              lpSolver->setDualRowPivotAlgorithm(p);
2470                            } else if (action == 5) {
2471                              // Positive edge Dantzig
2472                              ClpPEDualRowDantzig p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2473                              lpSolver->setDualRowPivotAlgorithm(p);
2474                            }
2475                            break;
2476                        case CLP_PARAM_STR_PRIMALPIVOT:
2477                            if (action == 0) {
2478                                ClpPrimalColumnSteepest steep(3);
2479                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2480                            } else if (action == 1) {
2481                                ClpPrimalColumnSteepest steep(0);
2482                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2483                            } else if (action == 2) {
2484                                ClpPrimalColumnDantzig dantzig;
2485                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2486                            } else if (action == 3) {
2487                                ClpPrimalColumnSteepest steep(4);
2488                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2489                            } else if (action == 4) {
2490                                ClpPrimalColumnSteepest steep(1);
2491                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2492                            } else if (action == 5) {
2493                                ClpPrimalColumnSteepest steep(2);
2494                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2495                            } else if (action == 6) {
2496                                ClpPrimalColumnSteepest steep(10);
2497                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2498                            } else if (action == 7) {
2499                              // Positive edge steepest
2500                              ClpPEPrimalColumnSteepest p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2501                              lpSolver->setPrimalColumnPivotAlgorithm(p);
2502                            } else if (action == 8) {
2503                              // Positive edge Dantzig
2504                              ClpPEPrimalColumnDantzig p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2505                              lpSolver->setPrimalColumnPivotAlgorithm(p);
2506                            }
2507                            break;
2508                        case CLP_PARAM_STR_SCALING:
2509                            lpSolver->scaling(action);
2510                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2511                            doScaling = action;
2512                            break;
2513                        case CLP_PARAM_STR_AUTOSCALE:
2514                            lpSolver->setAutomaticScaling(action != 0);
2515                            break;
2516                        case CLP_PARAM_STR_SPARSEFACTOR:
2517                            lpSolver->setSparseFactorization((1 - action) != 0);
2518                            break;
2519                        case CLP_PARAM_STR_BIASLU:
2520                            lpSolver->factorization()->setBiasLU(action);
2521                            break;
2522                        case CLP_PARAM_STR_PERTURBATION:
2523                            if (action == 0)
2524                                lpSolver->setPerturbation(50);
2525                            else
2526                                lpSolver->setPerturbation(100);
2527                            break;
2528                        case CLP_PARAM_STR_ERRORSALLOWED:
2529                            allowImportErrors = action;
2530                            break;
2531                        case CLP_PARAM_STR_INTPRINT:
2532                            printMode = action;
2533                            break;
2534                            //case CLP_PARAM_NOTUSED_ALGORITHM:
2535                            //algorithm  = action;
2536                            //defaultSettings=false; // user knows what she is doing
2537                            //abort();
2538                            //break;
2539                        case CLP_PARAM_STR_KEEPNAMES:
2540                            keepImportNames = 1 - action;
2541                            break;
2542                        case CLP_PARAM_STR_PRESOLVE:
2543                            if (action == 0)
2544                                preSolve = 5;
2545                            else if (action == 1)
2546                                preSolve = 0;
2547                            else if (action == 2)
2548                                preSolve = 10;
2549                            else
2550                                preSolveFile = true;
2551                            break;
2552                        case CLP_PARAM_STR_PFI:
2553                            lpSolver->factorization()->setForrestTomlin(action == 0);
2554                            break;
2555                        case CLP_PARAM_STR_FACTORIZATION:
2556                            lpSolver->factorization()->forceOtherFactorization(action);
2557                            break;
2558                        case CLP_PARAM_STR_CRASH:
2559                            doCrash = action;
2560                            break;
2561                        case CLP_PARAM_STR_VECTOR:
2562                            doVector = action;
2563                            break;
2564                        case CLP_PARAM_STR_MESSAGES:
2565                            lpSolver->messageHandler()->setPrefix(action != 0);
2566                            break;
2567                        case CLP_PARAM_STR_CHOLESKY:
2568                            choleskyType = action;
2569                            break;
2570                        case CLP_PARAM_STR_GAMMA:
2571                            gamma = action;
2572                            break;
2573                        case CLP_PARAM_STR_BARRIERSCALE:
2574                            scaleBarrier = action;
2575                            break;
2576                        case CLP_PARAM_STR_KKT:
2577                            doKKT = action;
2578                            break;
2579                        case CLP_PARAM_STR_CROSSOVER:
2580                            crossover = action;
2581                            break;
2582                        case CLP_PARAM_STR_TIME_MODE:
2583                            model_.setUseElapsedTime(action!=0);
2584                            break;
2585                        case CBC_PARAM_STR_SOS:
2586                            doSOS = action;
2587                            break;
2588                        case CBC_PARAM_STR_GOMORYCUTS:
2589                            defaultSettings = false; // user knows what she is doing
2590                            gomoryAction = action;
2591                            break;
2592                        case CBC_PARAM_STR_PROBINGCUTS:
2593                            defaultSettings = false; // user knows what she is doing
2594                            probingAction = action;
2595                            break;
2596                        case CBC_PARAM_STR_KNAPSACKCUTS:
2597                            defaultSettings = false; // user knows what she is doing
2598                            knapsackAction = action;
2599                            break;
2600                        case CBC_PARAM_STR_REDSPLITCUTS:
2601                            defaultSettings = false; // user knows what she is doing
2602                            redsplitAction = action;
2603                            break;
2604                        case CBC_PARAM_STR_REDSPLIT2CUTS:
2605                            defaultSettings = false; // user knows what she is doing
2606                            redsplit2Action = action;
2607                            break;
2608                        case CBC_PARAM_STR_GMICUTS:
2609                            defaultSettings = false; // user knows what she is doing
2610                            GMIAction = action;
2611                            break;
2612                        case CBC_PARAM_STR_CLIQUECUTS:
2613                            defaultSettings = false; // user knows what she is doing
2614                            cliqueAction = action;
2615                            break;
2616                        case CBC_PARAM_STR_FLOWCUTS:
2617                            defaultSettings = false; // user knows what she is doing
2618                            flowAction = action;
2619                            break;
2620                        case CBC_PARAM_STR_MIXEDCUTS:
2621                            defaultSettings = false; // user knows what she is doing
2622                            mixedAction = action;
2623                            break;
2624                        case CBC_PARAM_STR_TWOMIRCUTS:
2625                            defaultSettings = false; // user knows what she is doing
2626                            twomirAction = action;
2627                            break;
2628                        case CBC_PARAM_STR_LANDPCUTS:
2629                            defaultSettings = false; // user knows what she is doing
2630                            landpAction = action;
2631                            break;
2632                        case CBC_PARAM_STR_RESIDCUTS:
2633                            defaultSettings = false; // user knows what she is doing
2634                            residualCapacityAction = action;
2635                            break;
2636                        case CBC_PARAM_STR_ZEROHALFCUTS:
2637                            defaultSettings = false; // user knows what she is doing
2638                            zerohalfAction = action;
2639                            break;
2640                        case CBC_PARAM_STR_ROUNDING:
2641                            defaultSettings = false; // user knows what she is doing
2642                            break;
2643                        case CBC_PARAM_STR_FPUMP:
2644                            defaultSettings = false; // user knows what she is doing
2645                            break;
2646                        case CBC_PARAM_STR_RINS:
2647                            break;
2648                        case CBC_PARAM_STR_DINS:
2649                            break;
2650                        case CBC_PARAM_STR_RENS:
2651                            break;
2652                        case CBC_PARAM_STR_CUTSSTRATEGY:
2653                            gomoryAction = action;
2654                            probingAction = action;
2655                            knapsackAction = action;
2656                            cliqueAction = action;
2657                            flowAction = action;
2658                            mixedAction = action;
2659                            twomirAction = action;
2660                            //landpAction = action;
2661                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2662                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2663                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2664                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2665                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2666                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2667                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2668                            if (!action) {
2669                                zerohalfAction = action;
2670                                parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2671                                redsplitAction = action;
2672                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2673                                redsplit2Action = action;
2674                                parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption(action);
2675                                GMIAction = action;
2676                                parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption(action);
2677                                landpAction = action;
2678                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2679                                residualCapacityAction = action;
2680                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2681                            }
2682                            break;
2683                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2684                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2685                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2686                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2687                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2688                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2689                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2690                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
2691                            break;
2692                        case CBC_PARAM_STR_GREEDY:
2693                        case CBC_PARAM_STR_DIVINGS:
2694                        case CBC_PARAM_STR_DIVINGC:
2695                        case CBC_PARAM_STR_DIVINGF:
2696                        case CBC_PARAM_STR_DIVINGG:
2697                        case CBC_PARAM_STR_DIVINGL:
2698                        case CBC_PARAM_STR_DIVINGP:
2699                        case CBC_PARAM_STR_DIVINGV:
2700                        case CBC_PARAM_STR_COMBINE:
2701                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2702                        case CBC_PARAM_STR_PIVOTANDFIX:
2703                        case CBC_PARAM_STR_RANDROUND:
2704                        case CBC_PARAM_STR_LOCALTREE:
2705                        case CBC_PARAM_STR_NAIVE:
2706                        case CBC_PARAM_STR_CPX:
2707                            defaultSettings = false; // user knows what she is doing
2708                            break;
2709                        case CBC_PARAM_STR_COSTSTRATEGY:
2710                            useCosts = action;
2711                            break;
2712                        case CBC_PARAM_STR_NODESTRATEGY:
2713                            nodeStrategy = action;
2714                            break;
2715                        case CBC_PARAM_STR_PREPROCESS:
2716                            preProcess = action;
2717                            break;
2718                        default:
2719                            //abort();
2720                            break;
2721                        }
2722                    }
2723                } else {
2724                    // action
2725                    if (type == CLP_PARAM_ACTION_EXIT) {
2726#ifdef COIN_HAS_ASL
2727                        if (statusUserFunction_[0]) {
2728                            if (info.numberIntegers || info.numberBinary) {
2729                                // integer
2730                            } else {
2731                                // linear
2732                            }
2733                            writeAmpl(&info);
2734                            freeArrays2(&info);
2735                            freeArgs(&info);
2736                        }
2737#endif
2738                        break; // stop all
2739                    }
2740                    switch (type) {
2741                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2742                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2743                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2744                    case CLP_PARAM_ACTION_BARRIER:
2745                        if (goodModel) {
2746                            // Say not in integer
2747                            integerStatus = -1;
2748                            double objScale =
2749                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
2750                            // deal with positive edge
2751                            double psi = parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue();
2752                            if (psi>0.0) {
2753                              ClpDualRowPivot * dualp = lpSolver->dualRowPivot();
2754                              ClpDualRowSteepest * d1 = dynamic_cast<ClpDualRowSteepest *>(dualp);
2755                              ClpDualRowDantzig * d2 = dynamic_cast<ClpDualRowDantzig *>(dualp);
2756                              if (d1) {
2757                                ClpPEDualRowSteepest p(psi,d1->mode());
2758                                lpSolver->setDualRowPivotAlgorithm(p);
2759                              } else if (d2) {
2760                                ClpPEDualRowDantzig p(psi);
2761                                lpSolver->setDualRowPivotAlgorithm(p);
2762                              }
2763                              ClpPrimalColumnPivot * primalp = lpSolver->primalColumnPivot();
2764                              ClpPrimalColumnSteepest * p1 = dynamic_cast<ClpPrimalColumnSteepest *>(primalp);
2765                              ClpPrimalColumnDantzig * p2 = dynamic_cast<ClpPrimalColumnDantzig *>(primalp);
2766                              if (p1) {
2767                                ClpPEPrimalColumnSteepest p(psi,p1->mode());
2768                                lpSolver->setPrimalColumnPivotAlgorithm(p);
2769                              } else if (p2) {
2770                                ClpPEPrimalColumnDantzig p(psi);
2771                                lpSolver->setPrimalColumnPivotAlgorithm(p);
2772                              }
2773                            }
2774                            if (objScale != 1.0) {
2775                                int iColumn;
2776                                int numberColumns = lpSolver->numberColumns();
2777                                double * dualColumnSolution =
2778                                    lpSolver->dualColumnSolution();
2779                                ClpObjective * obj = lpSolver->objectiveAsObject();
2780                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2781                                double offset;
2782                                double * objective = obj->gradient(NULL, NULL, offset, true);
2783                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2784                                    dualColumnSolution[iColumn] *= objScale;
2785                                    objective[iColumn] *= objScale;;
2786                                }
2787                                int iRow;
2788                                int numberRows = lpSolver->numberRows();
2789                                double * dualRowSolution =
2790                                    lpSolver->dualRowSolution();
2791                                for (iRow = 0; iRow < numberRows; iRow++)
2792                                    dualRowSolution[iRow] *= objScale;
2793                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2794                            }
2795                            ClpSolve::SolveType method;
2796                            ClpSolve::PresolveType presolveType;
2797                            ClpSimplex * model2 = lpSolver;
2798                            if (dualize) {
2799                                bool tryIt = true;
2800                                double fractionColumn = 1.0;
2801                                double fractionRow = 1.0;
2802                                if (dualize == 3) {
2803                                    dualize = 1;
2804                                    int numberColumns = lpSolver->numberColumns();
2805                                    int numberRows = lpSolver->numberRows();
2806                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2807                                        tryIt = false;
2808                                    } else {
2809                                        fractionColumn = 0.1;
2810                                        fractionRow = 0.1;
2811                                    }
2812                                }
2813                                if (tryIt) {
2814                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2815                                    if (model2) {
2816                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2817                                                model2->numberRows(), model2->numberColumns());
2818                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2819                                        << generalPrint
2820                                        << CoinMessageEol;
2821                                        model2->setOptimizationDirection(1.0);
2822                                    } else {
2823                                        model2 = lpSolver;
2824                                        dualize = 0;
2825                                    }
2826                                } else {
2827                                    dualize = 0;
2828                                }
2829                            }
2830                            if (noPrinting_)
2831                                lpSolver->setLogLevel(0);
2832                            ClpSolve solveOptions;
2833                            solveOptions.setPresolveActions(presolveOptions);
2834                            solveOptions.setSubstitution(substitution);
2835                            if (preSolve != 5 && preSolve) {
2836                                presolveType = ClpSolve::presolveNumber;
2837                                if (preSolve < 0) {
2838                                    preSolve = - preSolve;
2839                                    if (preSolve <= 100) {
2840                                        presolveType = ClpSolve::presolveNumber;
2841                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2842                                                preSolve);
2843                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2844                                        << generalPrint
2845                                        << CoinMessageEol;
2846                                        solveOptions.setDoSingletonColumn(true);
2847                                    } else {
2848                                        preSolve -= 100;
2849                                        presolveType = ClpSolve::presolveNumberCost;
2850                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2851                                                preSolve);
2852                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2853                                        << generalPrint
2854                                        << CoinMessageEol;
2855                                    }
2856                                }
2857                            } else if (preSolve) {
2858                                presolveType = ClpSolve::presolveOn;
2859                            } else {
2860                                presolveType = ClpSolve::presolveOff;
2861                            }
2862                            solveOptions.setPresolveType(presolveType, preSolve);
2863                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2864                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
2865                                method = ClpSolve::useDual;
2866                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
2867                                method = ClpSolve::usePrimalorSprint;
2868                            } else {
2869                                method = ClpSolve::useBarrier;
2870                                if (crossover == 1) {
2871                                    method = ClpSolve::useBarrierNoCross;
2872                                } else if (crossover == 2) {
2873                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2874                                    if (obj->type() > 1) {
2875                                        method = ClpSolve::useBarrierNoCross;
2876                                        presolveType = ClpSolve::presolveOff;
2877                                        solveOptions.setPresolveType(presolveType, preSolve);
2878                                    }
2879                                }
2880                            }
2881                            solveOptions.setSolveType(method);
2882                            if (preSolveFile)
2883                                presolveOptions |= 0x40000000;
2884                            solveOptions.setSpecialOption(4, presolveOptions);
2885                            solveOptions.setSpecialOption(5, printOptions);
2886                            if (doVector) {
2887                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2888                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2889                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2890                                    clpMatrix->makeSpecialColumnCopy();
2891                                }
2892                            }
2893                            if (method == ClpSolve::useDual) {
2894                                // dual
2895                                if (doCrash)
2896                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2897                                else if (doIdiot)
2898                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2899                            } else if (method == ClpSolve::usePrimalorSprint) {
2900                                // primal
2901                                // if slp turn everything off
2902                                if (slpValue > 0) {
2903                                    doCrash = false;
2904                                    doSprint = 0;
2905                                    doIdiot = -1;
2906                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2907                                    method = ClpSolve::usePrimal;
2908                                }
2909                                if (doCrash) {
2910                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2911                                } else if (doSprint > 0) {
2912                                    // sprint overrides idiot
2913                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2914                                } else if (doIdiot > 0) {
2915                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2916                                } else if (slpValue <= 0) {
2917                                    if (doIdiot == 0) {
2918                                        if (doSprint == 0)
2919                                            solveOptions.setSpecialOption(1, 4); // all slack
2920                                        else
2921                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2922                                    } else {
2923                                        if (doSprint == 0)
2924                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2925                                        else
2926                                            solveOptions.setSpecialOption(1, 7); // initiative
2927                                    }
2928                                }
2929                                if (basisHasValues == -1)
2930                                    solveOptions.setSpecialOption(1, 11); // switch off values
2931                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2932                                int barrierOptions = choleskyType;
2933                                if (scaleBarrier)
2934                                    barrierOptions |= 8;
2935                                if (doKKT)
2936                                    barrierOptions |= 16;
2937                                if (gamma)
2938                                    barrierOptions |= 32 * gamma;
2939                                if (crossover == 3)
2940                                    barrierOptions |= 256; // try presolve in crossover
2941                                solveOptions.setSpecialOption(4, barrierOptions);
2942                            }
2943                            model2->setMaximumSeconds(model_.getMaximumSeconds());
2944#ifdef COIN_HAS_LINK
2945                            OsiSolverInterface * coinSolver = model_.solver();
2946                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2947                            if (!linkSolver) {
2948                                model2->initialSolve(solveOptions);
2949                            } else {
2950                                // special solver
2951                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
2952                                double * solution = NULL;
2953                                if (testOsiOptions < 10) {
2954                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2955                                } else if (testOsiOptions >= 10) {
2956                                    CoinModel coinModel = *linkSolver->coinModel();
2957                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2958                                    assert (tempModel);
2959                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2960                                    model2->setObjectiveValue(tempModel->objectiveValue());
2961                                    model2->setProblemStatus(tempModel->problemStatus());
2962                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2963                                    delete tempModel;
2964                                }
2965                                if (solution) {
2966                                    memcpy(model2->primalColumnSolution(), solution,
2967                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2968                                    delete [] solution;
2969                                } else {
2970                                    printf("No nonlinear solution\n");
2971                                }
2972                            }
2973#else
2974                            model2->initialSolve(solveOptions);
2975#endif
2976                            {
2977                                // map states
2978                                /* clp status
2979                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2980                                   0 - optimal
2981                                   1 - primal infeasible
2982                                   2 - dual infeasible
2983                                   3 - stopped on iterations or time
2984                                   4 - stopped due to errors
2985                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2986                                /* cbc status
2987                                   -1 before branchAndBound
2988                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2989                                   (or check value of best solution)
2990                                   1 stopped - on maxnodes, maxsols, maxtime
2991                                   2 difficulties so run was abandoned
2992                                   (5 event user programmed event occurred) */
2993                                /* clp secondary status of problem - may get extended
2994                                   0 - none
2995                                   1 - primal infeasible because dual limit reached OR probably primal
2996                                   infeasible but can't prove it (main status 4)
2997                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2998                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
2999                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
3000                                   5 - giving up in primal with flagged variables
3001                                   6 - failed due to empty problem check
3002                                   7 - postSolve says not optimal
3003                                   8 - failed due to bad element check
3004                                   9 - status was 3 and stopped on time
3005                                   100 up - translation of enum from ClpEventHandler
3006                                */
3007                                /* cbc secondary status of problem
3008                                   -1 unset (status_ will also be -1)
3009                                   0 search completed with solution
3010                                   1 linear relaxation not feasible (or worse than cutoff)
3011                                   2 stopped on gap
3012                                   3 stopped on nodes
3013                                   4 stopped on time
3014                                   5 stopped on user event
3015                                   6 stopped on solutions
3016                                   7 linear relaxation unbounded
3017                                   8 stopped on iterations limit
3018                                */
3019                                int iStatus = model2->status();
3020                                int iStatus2 = model2->secondaryStatus();
3021                                if (iStatus == 0) {
3022                                    iStatus2 = 0;
3023                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
3024                                        // set best solution in model as no integers
3025                                        model_.setBestSolution(model2->primalColumnSolution(),
3026                                                               model2->numberColumns(),
3027                                                               model2->getObjValue()*
3028                                                               model2->getObjSense());
3029                                    }
3030                                } else if (iStatus == 1) {
3031                                    iStatus = 0;
3032                                    iStatus2 = 1; // say infeasible
3033                                } else if (iStatus == 2) {
3034                                    iStatus = 0;
3035                                    iStatus2 = 7; // say unbounded
3036                                } else if (iStatus == 3) {
3037                                    iStatus = 1;
3038                                    if (iStatus2 == 9)  // what does 9 mean ?????????????
3039                                        iStatus2 = 4;
3040                                    else
3041                                        iStatus2 = 3; // Use nodes - as closer than solutions
3042                                } else if (iStatus == 4) {
3043                                    iStatus = 2; // difficulties
3044                                    iStatus2 = 0;
3045                                }
3046                                model_.setProblemStatus(iStatus);
3047                                model_.setSecondaryStatus(iStatus2);
3048                                if ((iStatus == 2 || iStatus2 > 0) &&
3049                                    !noPrinting_) {
3050                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
3051                                   std::string minor[] = {"Optimal solution found", "Linear relaxation infeasible", "Optimal solution found (within gap tolerance)", "node limit", "time limit", "user ctrl-c", "solution limit", "Linear relaxation unbounded", "iterations limit", "Problem proven infeasible"};
3052                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
3053                                           statusName[iStatus].c_str(), 
3054                                           minor[iStatus2].c_str());
3055                                   sprintf(generalPrint + strlen(generalPrint),
3056                                           "Enumerated nodes:           0\n");
3057                                   sprintf(generalPrint + strlen(generalPrint), 
3058                                           "Total iterations:           0\n");
3059#if CBC_QUIET == 0
3060                                   sprintf(generalPrint + strlen(generalPrint),
3061                                           "Time (CPU seconds):         %.2f\n", 
3062                                           CoinCpuTime() - time0);
3063                                   sprintf(generalPrint + strlen(generalPrint),
3064                                           "Time (Wallclock Seconds):   %.2f\n", 
3065                                           CoinGetTimeOfDay()-time0Elapsed);
3066#endif
3067                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
3068                                      << generalPrint
3069                                      << CoinMessageEol;
3070                                }
3071                                //assert (lpSolver==clpSolver->getModelPtr());
3072                                assert (clpSolver == model_.solver());
3073                                clpSolver->setWarmStart(NULL);
3074                                // and in babModel if exists
3075                                if (babModel_) {
3076                                    babModel_->setProblemStatus(iStatus);
3077                                    babModel_->setSecondaryStatus(iStatus2);
3078                                }
3079                                int returnCode = callBack(&model, 1);
3080                                if (returnCode) {
3081                                    // exit if user wants
3082                                    delete babModel_;
3083                                    babModel_ = NULL;
3084                                    return returnCode;
3085                                }
3086                            }
3087                            basisHasValues = 1;
3088                            if (dualize) {
3089                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
3090                                if (model2->status() == 3)
3091                                    returnCode = 0;
3092                                delete model2;
3093                                if (returnCode && dualize != 2)
3094                                    lpSolver->primal(1);
3095                                model2 = lpSolver;
3096                            }
3097#ifdef COIN_HAS_ASL
3098                            if (statusUserFunction_[0]) {
3099                                double value = model2->getObjValue();
3100                                char buf[300];
3101                                int pos = 0;
3102                                int iStat = model2->status();
3103                                if (iStat == 0) {
3104                                    pos += sprintf(buf + pos, "optimal," );
3105                                } else if (iStat == 1) {
3106                                    // infeasible
3107                                    pos += sprintf(buf + pos, "infeasible,");
3108                                } else if (iStat == 2) {
3109                                    // unbounded
3110                                    pos += sprintf(buf + pos, "unbounded,");
3111                                } else if (iStat == 3) {
3112                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
3113                                } else if (iStat == 4) {
3114                                    iStat = 7;
3115                                    pos += sprintf(buf + pos, "stopped on difficulties,");
3116                                } else if (iStat == 5) {
3117                                    iStat = 3;
3118                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
3119                                } else if (iStat == 6) {
3120                                    // bab infeasible
3121                                    pos += sprintf(buf + pos, "integer infeasible,");
3122                                    iStat = 1;
3123                                } else {
3124                                    pos += sprintf(buf + pos, "status unknown,");
3125                                    iStat = 6;
3126                                }
3127                                info.problemStatus = iStat;
3128                                info.objValue = value;
3129                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3130                                               value);
3131                                sprintf(buf + pos, "\n%d iterations",
3132                                        model2->getIterationCount());
3133                                free(info.primalSolution);
3134                                int numberColumns = model2->numberColumns();
3135                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3136                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
3137                                int numberRows = model2->numberRows();
3138                                free(info.dualSolution);
3139                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3140                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
3141                                CoinWarmStartBasis * basis = model2->getBasis();
3142                                free(info.rowStatus);
3143                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3144                                free(info.columnStatus);
3145                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3146                                // Put basis in
3147                                int i;
3148                                // free,basic,ub,lb are 0,1,2,3
3149                                for (i = 0; i < numberRows; i++) {
3150                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3151                                    info.rowStatus[i] = status;
3152                                }
3153                                for (i = 0; i < numberColumns; i++) {
3154                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3155                                    info.columnStatus[i] = status;
3156                                }
3157                                // put buffer into info
3158                                strcpy(info.buffer, buf);
3159                                delete basis;
3160                            }
3161#endif
3162                        } else {
3163                          sprintf(generalPrint, "** Current model not valid");
3164                          printGeneralMessage(model_,generalPrint);
3165                        }
3166                        break;
3167                    case CLP_PARAM_ACTION_STATISTICS:
3168                        if (goodModel) {
3169                            // If presolve on look at presolved
3170                            bool deleteModel2 = false;
3171                            ClpSimplex * model2 = lpSolver;
3172                            if (preSolve) {
3173                                ClpPresolve pinfo;
3174                                int presolveOptions2 = presolveOptions&~0x40000000;
3175                                if ((presolveOptions2&0xffff) != 0)
3176                                    pinfo.setPresolveActions(presolveOptions2);
3177                                pinfo.setSubstitution(substitution);
3178                                if ((printOptions&1) != 0)
3179                                    pinfo.statistics();
3180                                double presolveTolerance =
3181                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
3182                                model2 =
3183                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
3184                                                         true, preSolve);
3185                                if (model2) {
3186                                    printf("Statistics for presolved model\n");
3187                                    deleteModel2 = true;
3188                                } else {
3189                                    printf("Presolved model looks infeasible - will use unpresolved\n");
3190                                    model2 = lpSolver;
3191                                }
3192                            } else {
3193                                printf("Statistics for unpresolved model\n");
3194                                model2 =  lpSolver;
3195                            }
3196                            statistics(lpSolver, model2);
3197                            if (deleteModel2)
3198                                delete model2;
3199                        } else {
3200                          sprintf(generalPrint, "** Current model not valid");
3201                          printGeneralMessage(model_,generalPrint);
3202                        }
3203                        break;
3204                    case CLP_PARAM_ACTION_TIGHTEN:
3205                        if (goodModel) {
3206                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
3207                            if (numberInfeasibilities) {
3208                              sprintf(generalPrint,"** Analysis indicates model infeasible");
3209                              printGeneralMessage(model_,generalPrint);
3210                            }
3211                        } else {
3212                          sprintf(generalPrint, "** Current model not valid");
3213                          printGeneralMessage(model_,generalPrint);
3214                        }
3215                        break;
3216                    case CLP_PARAM_ACTION_PLUSMINUS:
3217                        if (goodModel) {
3218                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3219                            ClpPackedMatrix* clpMatrix =
3220                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3221                            if (clpMatrix) {
3222                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
3223                                if (newMatrix->getIndices()) {
3224                                    lpSolver->replaceMatrix(newMatrix);
3225                                    delete saveMatrix;
3226                                    sprintf(generalPrint, "Matrix converted to +- one matrix");
3227                                    printGeneralMessage(model_,generalPrint);
3228                                } else {
3229                                  sprintf(generalPrint, "Matrix can not be converted to +- 1 matrix");
3230                                  printGeneralMessage(model_,generalPrint);
3231                                }
3232                            } else {
3233                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3234                              printGeneralMessage(model_,generalPrint);
3235                            }
3236                        } else {
3237                          sprintf(generalPrint, "** Current model not valid");
3238                          printGeneralMessage(model_,generalPrint);
3239                        }
3240                        break;
3241                    case CLP_PARAM_ACTION_OUTDUPROWS:
3242                        dominatedCuts = true;
3243#ifdef JJF_ZERO
3244                        if (goodModel) {
3245                            int numberRows = clpSolver->getNumRows();
3246                            //int nOut = outDupRow(clpSolver);
3247                            CglDuplicateRow dupcuts(clpSolver);
3248                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
3249                            int nOut = numberRows - clpSolver->getNumRows();
3250                            if (nOut && !noPrinting_)
3251                                sprintf(generalPrint, "%d rows eliminated", nOut);
3252                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
3253                            << generalPrint
3254                            << CoinMessageEol;
3255                        } else {
3256                          sprintf(generalPrint, "** Current model not valid");
3257                          printGeneralMessage(model_,generalPrint);
3258                        }
3259#endif
3260                        break;
3261                    case CLP_PARAM_ACTION_NETWORK:
3262                        if (goodModel) {
3263                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3264                            ClpPackedMatrix* clpMatrix =
3265                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3266                            if (clpMatrix) {
3267                                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
3268                                if (newMatrix->getIndices()) {
3269                                    lpSolver->replaceMatrix(newMatrix);
3270                                    delete saveMatrix;
3271                                    sprintf(generalPrint, "Matrix converted to network matrix");
3272                                    printGeneralMessage(model_,generalPrint);
3273                                } else {
3274                                  sprintf(generalPrint, "Matrix can not be converted to network matrix");
3275                                  printGeneralMessage(model_,generalPrint);
3276                                }
3277                            } else {
3278                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3279                              printGeneralMessage(model_,generalPrint);
3280                            }
3281                        } else {
3282                          sprintf(generalPrint, "** Current model not valid");
3283                          printGeneralMessage(model_,generalPrint);
3284                        }
3285                        break;
3286                    case CBC_PARAM_ACTION_DOHEURISTIC:
3287                        if (goodModel) {
3288#ifndef CBC_USE_INITIAL_TIME
3289                          if (model_.useElapsedTime())
3290                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
3291                          else
3292                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
3293#endif
3294                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
3295                            if (vubAction != -1) {
3296                                // look at vubs
3297                                // extra1 is number of ints to leave free
3298                                // Just ones which affect >= extra3
3299                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
3300                                /* 2 is cost above which to fix if feasible
3301                                   3 is fraction of integer variables fixed if relaxing (0.97)
3302                                   4 is fraction of all variables fixed if relaxing (0.0)
3303                                */
3304                                double dextra[6];
3305                                int extra[5];
3306                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3307                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
3308                                                                  parameters_)].intValue();
3309                                if (exp1 == 4 && extra[1] == -1)
3310                                    extra[1] = 999998;
3311                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
3312                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
3313                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3314                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
3315                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
3316                                if (!dextra[3])
3317                                    dextra[3] = 0.97;
3318                                //OsiClpSolverInterface * newSolver =
3319                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
3320                                        debugValues, dextra, extra);
3321                                //assert (!newSolver);
3322                            }
3323                            // Actually do heuristics
3324                            // may need to flip objective
3325                            bool needFlip = model_.solver()->getObjSense()<0.0;
3326                            if (needFlip)
3327                              model_.flipModel(); 
3328                            //if we do then - fix priorities in clonebutmodel_.convertToDynamic();
3329                            bool objectsExist = model_.objects() != NULL;
3330                            if (!objectsExist) {
3331                              model_.findIntegers(false);
3332                              model_.convertToDynamic();
3333                            }
3334                            // set priorities etc
3335                            if (priorities) {
3336                              OsiObject ** objects = model_.objects();
3337                              int numberObjects = model_.numberObjects();
3338                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3339                                CbcSimpleInteger * obj =
3340                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3341                                if (!obj)
3342                                  continue;
3343                                int iColumn = obj->columnNumber();
3344                                if (branchDirection) {
3345                                  obj->setPreferredWay(branchDirection[iColumn]);
3346                                }
3347                                if (priorities) {
3348                                  int iPriority = priorities[iColumn];
3349                                  if (iPriority > 0)
3350                                    obj->setPriority(iPriority);
3351                                }
3352                                if (pseudoUp && pseudoUp[iColumn]) {
3353                                  CbcSimpleIntegerPseudoCost * obj1a =
3354                                    dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
3355                                  assert (obj1a);
3356                                  if (pseudoDown[iColumn] > 0.0)
3357                                    obj1a->setDownPseudoCost(pseudoDown[iColumn]);
3358                                  if (pseudoUp[iColumn] > 0.0)
3359                                    obj1a->setUpPseudoCost(pseudoUp[iColumn]);
3360                                }
3361                              }
3362                            }
3363                            doHeuristics(&model_, 2, parameters_,
3364                                         numberParameters_, noPrinting_, initialPumpTune);
3365                            if (!objectsExist) {
3366                              model_.deleteObjects(false);
3367                            }
3368                            if (needFlip)
3369                              model_.flipModel();
3370                            if (model_.bestSolution()) {
3371                                model_.setProblemStatus(1);
3372                                model_.setSecondaryStatus(6);
3373#ifdef COIN_HAS_ASL
3374                                if (statusUserFunction_[0]) {
3375                                    double value = model_.getObjValue();
3376                                    char buf[300];
3377                                    int pos = 0;
3378                                    pos += sprintf(buf + pos, "feasible,");
3379                                    info.problemStatus = 0;
3380                                    info.objValue = value;
3381                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3382                                                   value);
3383                                    sprintf(buf + pos, "\n0 iterations");
3384                                    free(info.primalSolution);
3385                                    int numberColumns = lpSolver->numberColumns();
3386                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3387                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3388                                    int numberRows = lpSolver->numberRows();
3389                                    free(info.dualSolution);
3390                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3391                                    CoinZeroN(info.dualSolution, numberRows);
3392                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3393                                    free(info.rowStatus);
3394                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3395                                    free(info.columnStatus);
3396                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3397                                    // Put basis in
3398                                    int i;
3399                                    // free,basic,ub,lb are 0,1,2,3
3400                                    for (i = 0; i < numberRows; i++) {
3401                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3402                                        info.rowStatus[i] = status;
3403                                    }
3404                                    for (i = 0; i < numberColumns; i++) {
3405                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3406                                        info.columnStatus[i] = status;
3407                                    }
3408                                    // put buffer into info
3409                                    strcpy(info.buffer, buf);
3410                                    delete basis;
3411                                }
3412#endif
3413                            }
3414                            int returnCode = callBack(&model, 6);
3415                            if (returnCode) {
3416                                // exit if user wants
3417                                delete babModel_;
3418                                babModel_ = NULL;
3419                                return returnCode;
3420                            }
3421                        }
3422                        break;
3423                    case CBC_PARAM_ACTION_MIPLIB:
3424                        // User can set options - main difference is lack of model and CglPreProcess
3425                        goodModel = true;
3426                        parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValue(0);
3427                        /*
3428                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3429                          Print elapsed time at the end.
3430                        */
3431                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3432                        // obsolete case STRENGTHEN:
3433                        if (goodModel) {
3434                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3435                            int logLevel = parameters_[slog].intValue();
3436                            int truncateColumns=COIN_INT_MAX;
3437                            int truncateRows=-1;
3438                            double * truncatedRhsLower=NULL;
3439                            double * truncatedRhsUpper=NULL;
3440                            int * newPriorities=NULL;
3441                            // Reduce printout
3442                            if (logLevel <= 1) {
3443                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3444                            } else {
3445                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3446                            }
3447                            {
3448                                OsiSolverInterface * solver = model_.solver();
3449#ifndef CBC_OTHER_SOLVER
3450                                OsiClpSolverInterface * si =
3451                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3452                                assert (si != NULL);
3453                                si->getModelPtr()->scaling(doScaling);
3454                                ClpSimplex * lpSolver = si->getModelPtr();
3455                                // deal with positive edge
3456                                double psi = parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue();
3457                                if (psi>0.0) {
3458                                  ClpDualRowPivot * dualp = lpSolver->dualRowPivot();
3459                                  ClpDualRowSteepest * d1 = dynamic_cast<ClpDualRowSteepest *>(dualp);
3460                                  ClpDualRowDantzig * d2 = dynamic_cast<ClpDualRowDantzig *>(dualp);
3461                                  if (d1) {
3462                                    ClpPEDualRowSteepest p(psi,d1->mode());
3463                                    lpSolver->setDualRowPivotAlgorithm(p);
3464                                  } else if (d2) {
3465                                    ClpPEDualRowDantzig p(psi);
3466                                    lpSolver->setDualRowPivotAlgorithm(p);
3467                                  }
3468                                  ClpPrimalColumnPivot * primalp = lpSolver->primalColumnPivot();
3469                                  ClpPrimalColumnSteepest * p1 = dynamic_cast<ClpPrimalColumnSteepest *>(primalp);
3470                                  ClpPrimalColumnDantzig * p2 = dynamic_cast<ClpPrimalColumnDantzig *>(primalp);
3471                                  if (p1) {
3472                                    ClpPEPrimalColumnSteepest p(psi,p1->mode());
3473                                    lpSolver->setPrimalColumnPivotAlgorithm(p);
3474                                  } else if (p2) {
3475                                    ClpPEPrimalColumnDantzig p(psi);
3476                                    lpSolver->setPrimalColumnPivotAlgorithm(p);
3477                                  }
3478                                }
3479                                if (doVector) {
3480                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3481                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3482                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3483                                        clpMatrix->makeSpecialColumnCopy();
3484                                    }
3485                                }
3486#elif CBC_OTHER_SOLVER==1
3487                                OsiCpxSolverInterface * si =
3488                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3489                                assert (si != NULL);
3490#endif
3491                                statistics_nrows = si->getNumRows();
3492                                statistics_ncols = si->getNumCols();
3493                                statistics_nprocessedrows = si->getNumRows();
3494                                statistics_nprocessedcols = si->getNumCols();
3495                                // See if quadratic
3496#ifndef CBC_OTHER_SOLVER
3497#ifdef COIN_HAS_LINK
3498                                if (!complicatedInteger) {
3499                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3500                                    if (obj) {
3501                                        preProcess = 0;
3502                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3503                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3504                                        // create coin model
3505                                        coinModel = lpSolver->createCoinModel();
3506                                        assert (coinModel);
3507                                        // load from coin model
3508                                        OsiSolverLink solver1;
3509                                        OsiSolverInterface * solver2 = solver1.clone();
3510                                        model_.assignSolver(solver2, false);
3511                                        OsiSolverLink * si =
3512                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3513                                        assert (si != NULL);
3514                                        si->setDefaultMeshSize(0.001);
3515                                        // need some relative granularity
3516                                        si->setDefaultBound(100.0);
3517                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3518                                        if (dextra3)
3519                                            si->setDefaultMeshSize(dextra3);
3520                                        si->setDefaultBound(1000.0);
3521                                        si->setIntegerPriority(1000);
3522                                        si->setBiLinearPriority(10000);
3523                                        biLinearProblem=true;
3524                                        si->setSpecialOptions2(2 + 4 + 8);
3525                                        CoinModel * model2 = coinModel;
3526                                        si->load(*model2, true, parameters_[log].intValue());
3527                                        // redo
3528                                        solver = model_.solver();
3529                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3530                                        lpSolver = clpSolver->getModelPtr();
3531                                        clpSolver->messageHandler()->setLogLevel(0) ;
3532                                        testOsiParameters = 0;
3533                                        complicatedInteger = 2;  // allow cuts
3534                                        OsiSolverInterface * coinSolver = model_.solver();
3535                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3536                                        if (linkSolver->quadraticModel()) {
3537                                            ClpSimplex * qp = linkSolver->quadraticModel();
3538                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3539                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3540                                            qp->primal(1);
3541                                            OsiSolverLinearizedQuadratic solver2(qp);
3542                                            const double * solution = NULL;
3543                                            // Reduce printout
3544                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3545                                            CbcModel model2(solver2);
3546                                            // Now do requested saves and modifications
3547                                            CbcModel * cbcModel = & model2;
3548                                            OsiSolverInterface * osiModel = model2.solver();
3549                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3550                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3551
3552                                            // Set changed values
3553
3554                                            CglProbing probing;
3555                                            probing.setMaxProbe(10);
3556                                            probing.setMaxLook(10);
3557                                            probing.setMaxElements(200);
3558                                            probing.setMaxProbeRoot(50);
3559                                            probing.setMaxLookRoot(10);
3560                                            probing.setRowCuts(3);
3561                                            probing.setUsingObjective(true);
3562                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3563                                            cbcModel->cutGenerator(0)->setTiming(true);
3564
3565                                            CglGomory gomory;
3566                                            gomory.setLimitAtRoot(512);
3567                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3568                                            cbcModel->cutGenerator(1)->setTiming(true);
3569
3570                                            CglKnapsackCover knapsackCover;
3571                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3572                                            cbcModel->cutGenerator(2)->setTiming(true);
3573
3574                                            CglRedSplit redSplit;
3575                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3576                                            cbcModel->cutGenerator(3)->setTiming(true);
3577
3578                                            CglClique clique;
3579                                            clique.setStarCliqueReport(false);
3580                                            clique.setRowCliqueReport(false);
3581                                            clique.setMinViolation(0.1);
3582                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3583                                            cbcModel->cutGenerator(4)->setTiming(true);
3584
3585                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3586                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3587                                            cbcModel->cutGenerator(5)->setTiming(true);
3588
3589                                            CglFlowCover flowCover;
3590                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3591                                            cbcModel->cutGenerator(6)->setTiming(true);
3592
3593                                            CglTwomir twomir;
3594                                            twomir.setMaxElements(250);
3595                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3596                                            cbcModel->cutGenerator(7)->setTiming(true);
3597
3598                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3599                                            heuristicFPump.setWhen(13);
3600                                            heuristicFPump.setMaximumPasses(20);
3601                                            heuristicFPump.setMaximumRetries(7);
3602                                            heuristicFPump.setHeuristicName("feasibility pump");
3603                                            heuristicFPump.setInitialWeight(1);
3604                                            heuristicFPump.setFractionSmall(0.6);
3605                                            cbcModel->addHeuristic(&heuristicFPump);
3606
3607                                            CbcRounding rounding(*cbcModel);
3608                                            rounding.setHeuristicName("rounding");
3609                                            cbcModel->addHeuristic(&rounding);
3610
3611                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3612                                            heuristicLocal.setHeuristicName("combine solutions");
3613                                            heuristicLocal.setSearchType(1);
3614                                            heuristicLocal.setFractionSmall(0.6);
3615                                            cbcModel->addHeuristic(&heuristicLocal);
3616
3617                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3618                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3619                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3620
3621                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3622                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3623                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3624
3625                                            CbcCompareDefault compare;
3626                                            cbcModel->setNodeComparison(compare);
3627                                            cbcModel->setNumberBeforeTrust(5);
3628                                            cbcModel->setSpecialOptions(2);
3629                                            cbcModel->messageHandler()->setLogLevel(1);
3630                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3631                                            cbcModel->setMaximumCutPasses(1);
3632                                            cbcModel->setMinimumDrop(0.05);
3633                                            // For branchAndBound this may help
3634                                            clpModel->defaultFactorizationFrequency();
3635                                            clpModel->setDualBound(1.0001e+08);
3636                                            clpModel->setPerturbation(50);
3637                                            osiclpModel->setSpecialOptions(193);
3638                                            osiclpModel->messageHandler()->setLogLevel(0);
3639                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3640                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3641                                            // You can save some time by switching off message building
3642                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3643
3644                                            // Solve
3645
3646                                            cbcModel->initialSolve();
3647                                            if (clpModel->tightenPrimalBounds() != 0) {
3648                                              sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3649                                              printGeneralMessage(model_,generalPrint);
3650                                                break;
3651                                            }
3652                                            clpModel->dual();  // clean up
3653                                            cbcModel->initialSolve();
3654#ifdef CBC_THREAD
3655                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3656                                            cbcModel->setNumberThreads(numberThreads % 100);
3657                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3658#endif
3659                                            //setCutAndHeuristicOptions(*cbcModel);
3660                                            cbcModel->branchAndBound();
3661                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3662                                            assert (solver3);
3663                                            solution = solver3->bestSolution();
3664                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3665                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3666                                            if (solution) {
3667                                              linkSolver->setBestSolution(solution, solver3->getNumCols());
3668                                            }
3669                                            CbcHeuristicDynamic3 dynamic(model_);
3670                                            dynamic.setHeuristicName("dynamic pass thru");
3671                                            model_.addHeuristic(&dynamic);
3672                                            // if convex
3673                                            if ((linkSolver->specialOptions2()&4) != 0 && solution) {
3674                                                int numberColumns = coinModel->numberColumns();
3675                                                assert (linkSolver->objectiveVariable() == numberColumns);
3676                                                // add OA cut
3677                                                double offset;
3678                                                double * gradient = new double [numberColumns+1];
3679                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3680                                                       numberColumns*sizeof(double));
3681                                                double rhs = 0.0;
3682                                                int * column = new int[numberColumns+1];
3683                                                int n = 0;
3684                                                for (int i = 0; i < numberColumns; i++) {
3685                                                    double value = gradient[i];
3686                                                    if (fabs(value) > 1.0e-12) {
3687                                                        gradient[n] = value;
3688                                                        rhs += value * solution[i];
3689                                                        column[n++] = i;
3690                                                    }
3691                                                }
3692                                                gradient[n] = -1.0;
3693                                                column[n++] = numberColumns;
3694                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3695                                                delete [] gradient;
3696                                                delete [] column;
3697                                            }
3698                                            // could do three way branching round a) continuous b) best solution
3699                                            printf("obj %g\n", bestObjectiveValue);
3700                                            linkSolver->initialSolve();
3701                                        }
3702                                    }
3703                                }
3704#endif
3705#endif
3706                                if (logLevel <= 1)
3707                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3708#ifndef CBC_OTHER_SOLVER
3709                                si->setSpecialOptions(0x40000000);
3710#endif
3711                            }
3712                            if (!miplib) {
3713                                if (!preSolve) {
3714                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3715                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3716                                }
3717                                double time1a = CoinCpuTime();
3718                                OsiSolverInterface * solver = model_.solver();
3719#ifndef CBC_OTHER_SOLVER
3720                                OsiClpSolverInterface * si =
3721                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3722                                if (si)
3723                                    si->setSpecialOptions(si->specialOptions() | 1024);
3724#endif
3725                                model_.initialSolve();
3726#ifndef CBC_OTHER_SOLVER
3727                                ClpSimplex * clpSolver = si->getModelPtr();
3728                                int iStatus = clpSolver->status();
3729                                int iStatus2 = clpSolver->secondaryStatus();
3730                                if (iStatus == 0) {
3731                                    iStatus2 = 0;
3732                                } else if (iStatus == 1) {
3733                                    iStatus = 0;
3734                                    iStatus2 = 1; // say infeasible
3735                                } else if (iStatus == 2) {
3736                                    iStatus = 0;
3737                                    iStatus2 = 7; // say unbounded
3738                                } else if (iStatus == 3) {
3739                                    iStatus = 1;
3740                                    if (iStatus2 == 9)
3741                                        iStatus2 = 4;
3742                                    else
3743                                        iStatus2 = 3; // Use nodes - as closer than solutions
3744                                } else if (iStatus == 4) {
3745                                    iStatus = 2; // difficulties
3746                                    iStatus2 = 0;
3747                                }
3748                                model_.setProblemStatus(iStatus);
3749                                model_.setSecondaryStatus(iStatus2);
3750                                si->setWarmStart(NULL);
3751                                int returnCode = callBack(&model_, 1);
3752                                if (returnCode) {
3753                                    // exit if user wants
3754                                    delete babModel_;
3755                                    babModel_ = NULL;
3756                                    return returnCode;
3757                                }
3758                                if (clpSolver->status() > 0) {
3759                                    // and in babModel if exists
3760                                    if (babModel_) {
3761                                        babModel_->setProblemStatus(iStatus);
3762                                        babModel_->setSecondaryStatus(iStatus2);
3763                                    }
3764                                    if (!noPrinting_) {
3765                                        iStatus = clpSolver->status();
3766                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3767                                                              "difficulties", "other"
3768                                                             };
3769                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3770                                                msg[iStatus-1], CoinCpuTime() - time1a);
3771                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3772                                        << generalPrint
3773                                        << CoinMessageEol;
3774                                    }
3775                                    break;
3776                                }
3777                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3778#elif CBC_OTHER_SOLVER==1
3779#endif
3780                                if (!noPrinting_) {
3781                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3782                                            solver->getObjValue(), CoinCpuTime() - time1a);
3783                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3784                                    << generalPrint
3785                                    << CoinMessageEol;
3786                                }
3787                                if (model_.getMaximumNodes() == -987654321) {
3788                                    // See if No objective!
3789                                    int numberColumns = clpSolver->getNumCols();
3790                                    const double * obj = clpSolver->getObjCoefficients();
3791                                    const double * lower = clpSolver->getColLower();
3792                                    const double * upper = clpSolver->getColUpper();
3793                                    int nObj = 0;
3794                                    for (int i = 0; i < numberColumns; i++) {
3795                                        if (upper[i] > lower[i] && obj[i])
3796                                            nObj++;
3797                                    }
3798                                    if (!nObj) {
3799                                        printf("************No objective!!\n");
3800                                        model_.setMaximumSolutions(1);
3801                                        // Column copy
3802                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3803                                        //const double * element = matrixByCol.getElements();
3804                                        //const int * row = matrixByCol.getIndices();
3805                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3806                                        const int * columnLength = matrixByCol.getVectorLengths();
3807                                        for (int i = 0; i < numberColumns; i++) {
3808                                            double value = (CoinDrand48() + 0.5) * 10000;
3809                                            value = 10;
3810                                            value *= columnLength[i];
3811                                            int iValue = static_cast<int> (value) / 10;
3812                                            //iValue=1;
3813                                            clpSolver->setObjCoeff(i, iValue);
3814                                        }
3815                                    }
3816                                }
3817#ifndef CBC_OTHER_SOLVER
3818                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3819                                  sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3820                                  printGeneralMessage(model_,generalPrint);
3821                                    model_.setProblemStatus(0);
3822                                    model_.setSecondaryStatus(1);
3823                                    // say infeasible for solution
3824                                    integerStatus = 6;
3825                                    // and in babModel if exists
3826                                    if (babModel_) {
3827                                        babModel_->setProblemStatus(0);
3828                                        babModel_->setSecondaryStatus(1);
3829                                    }
3830                                    break;
3831                                }
3832                                if (clpSolver->dualBound() == 1.0e10) {
3833                                    ClpSimplex temp = *clpSolver;
3834                                    temp.setLogLevel(0);
3835                                    temp.dual(0, 7);
3836                                    // user did not set - so modify
3837                                    // get largest scaled away from bound
3838                                    double largest = 1.0e-12;
3839                                    double largestScaled = 1.0e-12;
3840                                    int numberRows = temp.numberRows();
3841                                    const double * rowPrimal = temp.primalRowSolution();
3842                                    const double * rowLower = temp.rowLower();
3843                                    const double * rowUpper = temp.rowUpper();
3844                                    const double * rowScale = temp.rowScale();
3845                                    int iRow;
3846                                    for (iRow = 0; iRow < numberRows; iRow++) {
3847                                        double value = rowPrimal[iRow];
3848                                        double above = value - rowLower[iRow];
3849                                        double below = rowUpper[iRow] - value;
3850                                        if (above < 1.0e12) {
3851                                            largest = CoinMax(largest, above);
3852                                        }
3853                                        if (below < 1.0e12) {
3854                                            largest = CoinMax(largest, below);
3855                                        }
3856                                        if (rowScale) {
3857                                            double multiplier = rowScale[iRow];
3858                                            above *= multiplier;
3859                                            below *= multiplier;
3860                                        }
3861                                        if (above < 1.0e12) {
3862                                            largestScaled = CoinMax(largestScaled, above);
3863                                        }
3864                                        if (below < 1.0e12) {
3865                                            largestScaled = CoinMax(largestScaled, below);
3866                                        }
3867                                    }
3868
3869                                    int numberColumns = temp.numberColumns();
3870                                    const double * columnPrimal = temp.primalColumnSolution();
3871                                    const double * columnLower = temp.columnLower();
3872                                    const double * columnUpper = temp.columnUpper();
3873                                    const double * columnScale = temp.columnScale();
3874                                    int iColumn;
3875                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3876                                        double value = columnPrimal[iColumn];
3877                                        double above = value - columnLower[iColumn];
3878                                        double below = columnUpper[iColumn] - value;
3879                                        if (above < 1.0e12) {
3880                                            largest = CoinMax(largest, above);
3881                                        }
3882                                        if (below < 1.0e12) {
3883                                            largest = CoinMax(largest, below);
3884                                        }
3885                                        if (columnScale) {
3886                                            double multiplier = 1.0 / columnScale[iColumn];
3887                                            above *= multiplier;
3888                                            below *= multiplier;
3889                                        }
3890                                        if (above < 1.0e12) {
3891                                            largestScaled = CoinMax(largestScaled, above);
3892                                        }
3893                                        if (below < 1.0e12) {
3894                                            largestScaled = CoinMax(largestScaled, below);
3895                                        }
3896                                    }
3897#ifdef COIN_DEVELOP
3898                                    if (!noPrinting_)
3899                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3900                                                  << " unscaled " << largest << std::endl;
3901#endif
3902                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3903                                }
3904                                si->resolve();  // clean up
3905#endif
3906                            }
3907                            // If user made settings then use them
3908                            if (!defaultSettings) {
3909                                OsiSolverInterface * solver = model_.solver();
3910                                if (!doScaling)
3911                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3912#ifndef CBC_OTHER_SOLVER
3913                                OsiClpSolverInterface * si =
3914                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3915                                assert (si != NULL);
3916                                // get clp itself
3917                                ClpSimplex * modelC = si->getModelPtr();
3918                                //if (modelC->tightenPrimalBounds()!=0) {
3919                                //std::cout<<"Problem is infeasible!"<<std::endl;
3920                                //break;
3921                                //}
3922                                // bounds based on continuous
3923                                if (tightenFactor && !complicatedInteger) {
3924                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3925                                      sprintf(generalPrint, "Problem is infeasible!");
3926                                      printGeneralMessage(model_,generalPrint);
3927                                        model_.setProblemStatus(0);
3928                                        model_.setSecondaryStatus(1);
3929                                        // and in babModel if exists
3930                                        if (babModel_) {
3931                                            babModel_->setProblemStatus(0);
3932                                            babModel_->setSecondaryStatus(1);
3933                                        }
3934                                        break;
3935                                    }
3936                                }
3937#endif
3938                            }
3939                            // See if we want preprocessing
3940                            OsiSolverInterface * saveSolver = NULL;
3941                            CglPreProcess process;
3942                            // Say integers in sync
3943                            bool integersOK = true;
3944                            delete babModel_;
3945                            babModel_ = new CbcModel(model_);
3946#ifndef CBC_OTHER_SOLVER
3947                            int numberChanged = 0;
3948                            OsiSolverInterface * solver3 = clpSolver->clone();
3949                            babModel_->assignSolver(solver3);
3950                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3951                            if (clpSolver2->messageHandler()->logLevel())
3952                                clpSolver2->messageHandler()->setLogLevel(1);
3953                            if (logLevel > -1)
3954                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3955                            lpSolver = clpSolver2->getModelPtr();
3956                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3957                                // User did not touch preset
3958                                int numberRows = lpSolver->numberRows();
3959                                const int cutoff1 = 10000;
3960                                const int cutoff2 = 100000;
3961                                const int base = 75;
3962                                const int freq0 = 50;
3963                                const int freq1 = 200;
3964                                const int freq2 = 400;
3965                                const int maximum = 1000;
3966                                int frequency;
3967                                if (numberRows < cutoff1)
3968                                    frequency = base + numberRows / freq0;
3969                                else if (numberRows < cutoff2)
3970                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3971                                else
3972                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3973                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3974                            }
3975#elif CBC_OTHER_SOLVER==1
3976                            OsiSolverInterface * solver3 = model_.solver()->clone();
3977                            babModel_->assignSolver(solver3);
3978#endif
3979                            time2 = CoinCpuTime();
3980                            totalTime += time2 - time1;
3981                            //time1 = time2;
3982                            double timeLeft = babModel_->getMaximumSeconds();
3983                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3984                            if (preProcess == 7) {
3985                                // use strategy instead
3986                                preProcess = 0;
3987                                useStrategy = true;
3988#ifdef COIN_HAS_LINK
3989                                // empty out any cuts
3990                                if (storedAmpl.sizeRowCuts()) {
3991                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3992                                    CglStored temp;
3993                                    storedAmpl = temp;
3994                                }
3995#endif
3996                            }
3997                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3998                              // see whether to switch off preprocessing
3999                              // only allow SOS and integer
4000                              OsiObject ** objects = babModel_->objects();
4001                              int numberObjects = babModel_->numberObjects();
4002                              for (int iObj = 0; iObj < numberObjects; iObj++) {
4003                                CbcSOS * objSOS =
4004                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
4005                                CbcSimpleInteger * objSimpleInteger =
4006                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
4007                                if (!objSimpleInteger&&!objSOS) {
4008                                  // find all integers anyway
4009                                  babModel_->findIntegers(true);
4010                                  preProcess=0;
4011                                  break;
4012                                }
4013                              }
4014                            }
4015                            if (type == CBC_PARAM_ACTION_BAB) {
4016                                double limit;
4017                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
4018                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
4019                                        limit*clpSolver->getObjSense())
4020                                    preProcess = 0;
4021                            }
4022                            if (mipStartBefore.size())
4023                              {
4024                                CbcModel tempModel=*babModel_;
4025                                assert (babModel_->getNumCols()==model_.getNumCols());
4026                                std::vector< std::string > colNames;
4027                                for ( int i=0 ; (i<model_.solver()->getNumCols()) ; ++i )
4028                                  colNames.push_back( model_.solver()->getColName(i) );
4029                                std::vector< double > x( model_.getNumCols(), 0.0 );
4030                                double obj;
4031                                int status = computeCompleteSolution( &tempModel, colNames, mipStartBefore, &x[0], obj );
4032                                // set cutoff ( a trifle high)
4033                                if (!status) {
4034                                  double newCutoff = CoinMin(babModel_->getCutoff(),obj+1.0e-4);
4035                                  babModel_->setBestSolution( &x[0], static_cast<int>(x.size()), obj, false );
4036                                  babModel_->setCutoff(newCutoff);
4037                                  babModel_->setSolutionCount(1);
4038                                  model_.setBestSolution( &x[0], static_cast<int>(x.size()), obj, false );
4039                                  model_.setCutoff(newCutoff);
4040                                  model_.setSolutionCount(1);
4041                                }
4042                              }
4043                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
4044#ifndef CBC_OTHER_SOLVER
4045                                // See if sos from mps file
4046                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
4047                                    // SOS
4048                                    numberSOS = clpSolver->numberSOS();
4049                                    const CoinSet * setInfo = clpSolver->setInfo();
4050                                    sosStart = new int [numberSOS+1];
4051                                    sosType = new char [numberSOS];
4052                                    int i;
4053                                    int nTotal = 0;
4054                                    sosStart[0] = 0;
4055                                    for ( i = 0; i < numberSOS; i++) {
4056                                        int type = setInfo[i].setType();
4057                                        int n = setInfo[i].numberEntries();
4058                                        sosType[i] = static_cast<char>(type);
4059                                        nTotal += n;
4060                                        sosStart[i+1] = nTotal;
4061                                    }
4062                                    sosIndices = new int[nTotal];
4063                                    sosReference = new double [nTotal];
4064                                    for (i = 0; i < numberSOS; i++) {
4065                                        int n = setInfo[i].numberEntries();
4066                                        const int * which = setInfo[i].which();
4067                                        const double * weights = setInfo[i].weights();
4068                                        int base = sosStart[i];
4069                                        for (int j = 0; j < n; j++) {
4070                                            int k = which[j];
4071                                            sosIndices[j+base] = k;
4072                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
4073                                        }
4074                                    }
4075                                }
4076#endif
4077                                saveSolver = babModel_->solver()->clone();
4078                                /* Do not try and produce equality cliques and
4079                                   do up to 10 passes */
4080                                OsiSolverInterface * solver2;
4081                                {
4082                                    // Tell solver we are in Branch and Cut
4083                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
4084                                    // Default set of cut generators
4085                                    CglProbing generator1;
4086                                    generator1.setUsingObjective(1);
4087                                    generator1.setMaxPass(1);
4088                                    generator1.setMaxPassRoot(1);
4089                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
4090                                    generator1.setMaxElements(100);
4091                                    generator1.setMaxElementsRoot(200);
4092                                    generator1.setMaxLookRoot(50);
4093                                    if (saveSolver->getNumCols() > 3000)
4094                                        generator1.setMaxProbeRoot(123);
4095                                    generator1.setRowCuts(3);
4096                                    // switch off duplicate columns if we have a solution
4097                                    if (model_.bestSolution()/*||debugValues*/)
4098                                      tunePreProcess |= 4096;
4099                                    if ((tunePreProcess&1) != 0) {
4100                                        // heavy probing
4101                                        generator1.setMaxPassRoot(2);
4102                                        generator1.setMaxElements(1000);
4103                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
4104                                        generator1.setMaxLookRoot(saveSolver->getNumCols());
4105                                    }
4106                                    if ((babModel_->specialOptions()&65536) != 0)
4107                                        process.setOptions(1);
4108                                    // Add in generators
4109                                    if ((model_.moreSpecialOptions()&65536)==0)
4110                                      process.addCutGenerator(&generator1);
4111                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
4112                                    process.passInMessageHandler(babModel_->messageHandler());
4113                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
4114#ifdef COIN_HAS_ASL
4115                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
4116                                        // SOS
4117                                        numberSOS = info.numberSos;
4118                                        sosStart = info.sosStart;
4119                                        sosIndices = info.sosIndices;
4120                                    }
4121#endif
4122                                    if (numberSOS && doSOS) {
4123                                        // SOS
4124                                        int numberColumns = saveSolver->getNumCols();
4125                                        char * prohibited = new char[numberColumns];
4126                                        memset(prohibited, 0, numberColumns);
4127                                        int n = sosStart[numberSOS];
4128                                        for (int i = 0; i < n; i++) {
4129                                            int iColumn = sosIndices[i];
4130                                            prohibited[iColumn] = 1;
4131                                        }
4132                                        process.passInProhibited(prohibited, numberColumns);
4133                                        delete [] prohibited;
4134                                    }
4135                                    if (0) {
4136                                     
4137                                      // Special integers
4138                                      int numberColumns = saveSolver->getNumCols();
4139                                      char * prohibited = new char[numberColumns];
4140                                      memset(prohibited, 0, numberColumns);
4141                                      const CoinPackedMatrix * matrix = saveSolver->getMatrixByCol();
4142                                      const int * columnLength = matrix->getVectorLengths();
4143                                      int numberProhibited=0;
4144                                      for (int iColumn = numberColumns-1; iColumn >=0; iColumn--) {
4145                                        if (!saveSolver->isInteger(iColumn)||
4146                                            columnLength[iColumn]>1)
4147                                          break;
4148                                        numberProhibited++;
4149                                        prohibited[iColumn] = 1;
4150                                      }
4151                                      if (numberProhibited) {
4152                                        process.passInProhibited(prohibited, numberColumns);
4153                                        printf("**** Treating last %d integers as special - give high priority?\n",numberProhibited);
4154                                      }
4155                                      delete [] prohibited;
4156                                    }
4157                                    if (!model_.numberObjects() && true) {
4158                                        /* model may not have created objects
4159                                           If none then create
4160                                        */
4161                                        model_.findIntegers(true);
4162                                    }
4163                                    if (model_.numberObjects()) {
4164                                        OsiObject ** oldObjects = babModel_->objects();
4165                                        int numberOldObjects = babModel_->numberObjects();
4166                                        if (!numberOldObjects) {
4167                                          oldObjects = model_.objects();
4168                                          numberOldObjects = model_.numberObjects();
4169                                        }
4170                                        // SOS
4171                                        int numberColumns = saveSolver->getNumCols();
4172                                        char * prohibited = new char[numberColumns];
4173                                        memset(prohibited, 0, numberColumns);
4174                                        int numberProhibited = 0;
4175                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4176                                            CbcSOS * obj =
4177                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
4178                                            if (obj) {
4179                                                int n = obj->numberMembers();
4180                                                const int * which = obj->members();
4181                                                for (int i = 0; i < n; i++) {
4182                                                    int iColumn = which[i];
4183                                                    prohibited[iColumn] = 1;
4184                                                    numberProhibited++;
4185                                                }
4186                                            }
4187                                            CbcLotsize * obj2 =
4188                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
4189                                            if (obj2) {
4190                                                int iColumn = obj2->columnNumber();
4191                                                prohibited[iColumn] = 1;
4192                                                numberProhibited++;
4193                                            }
4194                                        }
4195                                        if (numberProhibited)
4196                                            process.passInProhibited(prohibited, numberColumns);
4197                                        delete [] prohibited;
4198                                    }
4199                                    int numberPasses = 10;
4200#ifndef CBC_OTHER_SOLVER
4201                                    if (doSprint > 0) {
4202                                        // Sprint for primal solves
4203                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
4204                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
4205                                        int numberPasses = 5;
4206                                        int options[] = {0, 3, 0, 0, 0, 0};
4207                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
4208                                        extraInfo[1] = doSprint;
4209                                        int independentOptions[] = {0, 0, 3};
4210                                        ClpSolve clpSolve(method, presolveType, numberPasses,
4211                                                          options, extraInfo, independentOptions);
4212                                        // say use in OsiClp
4213                                        clpSolve.setSpecialOption(6, 1);
4214                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4215                                        osiclp->setSolveOptions(clpSolve);
4216                                        osiclp->setHintParam(OsiDoDualInResolve, false);
4217                                        // switch off row copy
4218                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
4219                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
4220                                    }
4221#endif
4222#ifndef CBC_OTHER_SOLVER
4223                                    {
4224                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4225                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
4226                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
4227                                        //#define CBC_TEMP1
4228#ifdef CBC_TEMP1
4229                                        if (savePerturbation == 50)
4230                                            osiclp->getModelPtr()->setPerturbation(52); // try less
4231#endif
4232                                        if ((model_.moreSpecialOptions()&65536)!=0)
4233                                          process.setOptions(2+4+8); // no cuts
4234                                        cbcPreProcessPointer = & process;
4235                                        int saveOptions = osiclp->getModelPtr()->moreSpecialOptions();
4236                                        if ((model_.specialOptions()&16777216)!=0&&
4237                                            model_.getCutoff()>1.0e30) {
4238                                          osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions|262144);
4239                                        }
4240#ifdef CGL_WRITEMPS
4241                                        if (debugValues) {
4242                                          process.setApplicationData(const_cast<double *>(debugValues));
4243                                        }
4244#endif
4245                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4246                                                                               tunePreProcess);
4247                                        if (solver2) {
4248                                          model_.setOriginalColumns( process.originalColumns(), solver2->getNumCols() );
4249                                         
4250                                          osiclp->getModelPtr()->setPerturbation(savePerturbation);
4251                                          osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions);
4252                                        }
4253                                    }
4254#elif CBC_OTHER_SOLVER==1
4255                                    cbcPreProcessPointer = & process;
4256                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4257                                                                           tunePreProcess);
4258#endif
4259                                    integersOK = false; // We need to redo if CbcObjects exist
4260                                    // Tell solver we are not in Branch and Cut
4261                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4262                                    if (solver2)
4263                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4264                                }
4265#ifdef COIN_HAS_ASL
4266                                if (!solver2 && statusUserFunction_[0]) {
4267                                    // infeasible
4268                                    info.problemStatus = 1;
4269                                    info.objValue = 1.0e100;
4270                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
4271                                    info.primalSolution = NULL;
4272                                    info.dualSolution = NULL;
4273                                    break;
4274                                }
4275#endif
4276                                if (!noPrinting_) {
4277                                    if (!solver2) {
4278                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
4279                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4280                                        << generalPrint
4281                                        << CoinMessageEol;
4282                                    } else {
4283                                        //printf("processed model has %d rows, %d columns and %d elements\n",
4284                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
4285                                    }
4286                                }
4287                                if (!solver2) {
4288                                    // say infeasible for solution
4289                                    integerStatus = 6;
4290                                    delete saveSolver;
4291                                    saveSolver=NULL;
4292                                    model_.setProblemStatus(0);
4293                                    model_.setSecondaryStatus(1);
4294                                    babModel_->setProblemStatus(0);
4295                                    babModel_->setSecondaryStatus(1);
4296                                } else {
4297                                    statistics_nprocessedrows = solver2->getNumRows();
4298                                    statistics_nprocessedcols = solver2->getNumCols();
4299                                    model_.setProblemStatus(-1);
4300                                    babModel_->setProblemStatus(-1);
4301                                }
4302                                int returnCode = callBack(babModel_, 2);
4303                                if (returnCode) {
4304                                    // exit if user wants
4305                                    delete babModel_;
4306                                    babModel_ = NULL;
4307                                    return returnCode;
4308                                }
4309                                if (!solver2)
4310                                    break;
4311                                if (model_.bestSolution()) {
4312                                    // need to redo - in case no better found in BAB
4313                                    // just get integer part right
4314                                    const int * originalColumns = process.originalColumns();
4315                                    int numberColumns = solver2->getNumCols();
4316                                    double * bestSolution = babModel_->bestSolution();
4317                                    const double * oldBestSolution = model_.bestSolution();
4318                                    for (int i = 0; i < numberColumns; i++) {
4319                                        int jColumn = originalColumns[i];
4320                                        bestSolution[i] = oldBestSolution[jColumn];
4321                                    }
4322                                }
4323                                //solver2->resolve();
4324                                if (preProcess == 2) {
4325                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4326                                    ClpSimplex * lpSolver = clpSolver2->getModelPtr();
4327                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
4328                                    printf("Preprocessed model (minimization) on presolved.mps\n");
4329                                }
4330                                {
4331                                    // look at new integers
4332                                    int numberOriginalColumns =
4333                                        process.originalModel()->getNumCols();
4334                                    const int * originalColumns = process.originalColumns();
4335                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4336                                    int numberColumns = osiclp2->getNumCols();
4337                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4338                                    for (int i = 0; i < numberColumns; i++) {
4339                                        int iColumn = originalColumns[i];
4340                                        if (iColumn < numberOriginalColumns) {
4341                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
4342                                                osiclp2->setOptionalInteger(i); // say optional
4343                                        }
4344                                    }
4345                                    // redo existing SOS
4346                                    if (osiclp->numberSOS()) {
4347                                      int * back = new int[numberOriginalColumns];
4348                                      for (int i = 0; i < numberOriginalColumns; i++)
4349                                        back[i]=-1;
4350                                      for (int i = 0; i < numberColumns; i++) {
4351                                        int iColumn = originalColumns[i];
4352                                        back[iColumn]=i;
4353                                      }
4354                                      int numberSOSOld=osiclp->numberSOS();
4355                                      int numberSOS=osiclp2->numberSOS();
4356                                      assert (numberSOS==numberSOSOld);
4357                                      CoinSet * setInfo = const_cast<CoinSet *>(osiclp2->setInfo());
4358                                      for (int i = 0; i < numberSOS; i++) {
4359                                        //int type = setInfo[i].setType();
4360                                        int n = setInfo[i].numberEntries();
4361                                        int * which = const_cast<int *>(setInfo[i].which());
4362                                        for (int j=0;j<n;j++) {
4363                                          int iColumn = which[j];
4364                                          iColumn=back[iColumn];
4365                                          assert(iColumn>=0);
4366                                          which[j]=iColumn;
4367                                        }
4368                                      }
4369                                      delete [] back;
4370                                    }
4371                                }
4372                                // we have to keep solver2 so pass clone
4373                                solver2 = solver2->clone();
4374                                // see if extra variables wanted
4375                                int threshold = 
4376                                  parameters_[whichParam(CBC_PARAM_INT_EXTRA_VARIABLES, numberParameters_, parameters_)].intValue();
4377                                int more2 = parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].intValue();
4378                                if (threshold || (more2&(512|1024)) != 0) {
4379                                  int numberColumns = solver2->getNumCols();
4380                                  truncateRows = solver2->getNumRows();
4381                                  bool modifiedModel=false;
4382                                  int highPriority=0;
4383                                  /*
4384                                    normal - no priorities
4385                                    >10000 equal high priority
4386                                    >20000 higher priority for higher cost
4387                                  */
4388                                  if (threshold>10000) {
4389                                    highPriority=threshold/10000;
4390                                    threshold -= 10000*highPriority;
4391                                  }
4392                                  // If 1000 set then don't put obj on ne variables
4393                                  bool moveObjective=true;
4394                                  if (threshold>1000) {
4395                                    moveObjective=false;
4396                                    threshold -= 1000;
4397                                  }
4398                                  const double * columnLower = solver2->getColLower();
4399                                  const double * columnUpper = solver2->getColUpper();
4400                                  const double * objective = solver2->getObjCoefficients();
4401                                  int numberIntegers = 0;
4402                                  int numberBinary = 0;
4403                                  int numberTotalIntegers=0;
4404                                  double * obj = new double [numberColumns];
4405                                  int * which = new int [numberColumns];
4406                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4407                                    if (solver2->isInteger(iColumn)) {
4408                                      numberTotalIntegers++;
4409                                      if (columnUpper[iColumn] > columnLower[iColumn]) {
4410                                        numberIntegers++;
4411                                        if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1)
4412                                          numberBinary++;
4413                                      }
4414                                    }
4415                                  }
4416                                  int numberSort=0;
4417                                  int numberZero=0;
4418                                  int numberZeroContinuous=0;
4419                                  int numberDifferentObj=0;
4420                                  int numberContinuous=0;
4421                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4422                                    if (columnUpper[iColumn] > columnLower[iColumn]) {
4423                                      if (solver2->isInteger(iColumn)) {
4424                                        if (!objective[iColumn]) {
4425                                          numberZero++;
4426                                        } else {
4427                                          obj[numberSort]= fabs(objective[iColumn]);
4428                                          which[numberSort++]=iColumn;
4429                                        }
4430                                      } else if (objective[iColumn]) {
4431                                        numberContinuous++;
4432                                      } else {
4433                                        numberZeroContinuous++;
4434                                      }
4435                                    }
4436                                  }
4437                                  CoinSort_2(obj,obj+numberSort,which);
4438                                  double last=obj[0];
4439                                  for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4440                                    if (fabs(obj[jColumn]-last)>1.0e-12) {
4441                                      numberDifferentObj++;
4442                                      last=obj[jColumn];
4443                                    }
4444                                  }
4445                                  numberDifferentObj++;
4446                                  sprintf(generalPrint,"Problem has %d integers (%d of which binary) and %d continuous",
4447                                         numberIntegers,numberBinary,numberColumns-numberIntegers);
4448                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4449                                    << generalPrint
4450                                    << CoinMessageEol;
4451                                  if (numberColumns>numberIntegers) {
4452                                    sprintf(generalPrint,"%d continuous have nonzero objective, %d have zero objective",
4453                                            numberContinuous,numberZeroContinuous);
4454                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4455                                      << generalPrint
4456                                      << CoinMessageEol;
4457                                  }
4458                                  sprintf(generalPrint,"%d integer have nonzero objective, %d have zero objective, %d different nonzero (taking abs)",
4459                                          numberSort,numberZero,numberDifferentObj);
4460                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4461                                    << generalPrint
4462                                    << CoinMessageEol;
4463                                  if (numberDifferentObj<=threshold + (numberZero) ? 1 : 0 && numberDifferentObj) {
4464                                    int * backward=NULL;
4465                                    if (highPriority) {
4466                                      newPriorities = new int [numberTotalIntegers+numberDifferentObj+numberColumns];
4467                                      backward=newPriorities+numberTotalIntegers+numberDifferentObj;
4468                                      numberTotalIntegers=0;
4469                                      for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4470                                        if (solver2->isInteger(iColumn)) {
4471                                          backward[iColumn]=numberTotalIntegers;
4472                                          newPriorities[numberTotalIntegers++]=10000;
4473                                        }
4474                                      }
4475                                    }
4476                                    int iLast=0;
4477                                    double last=obj[0];
4478                                    for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4479                                      if (fabs(obj[jColumn]-last)>1.0e-12) {
4480                                        sprintf(generalPrint,"%d variables have objective of %g",
4481                                               jColumn-iLast,last);
4482                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4483                                          << generalPrint
4484                                          << CoinMessageEol;
4485                                        iLast=jColumn;
4486                                        last=obj[jColumn];
4487                                      }
4488                                    }
4489                                    sprintf(generalPrint,"%d variables have objective of %g",
4490                                           numberSort-iLast,last);
4491                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4492                                      << generalPrint
4493                                      << CoinMessageEol;
4494                                    int spaceNeeded=numberSort+numberDifferentObj;
4495                                    int * columnAdd = new int[spaceNeeded+numberDifferentObj+1];
4496                                    double * elementAdd = new double[spaceNeeded];
4497                                    int * rowAdd = new int[numberDifferentObj+1];
4498                                    double * objectiveNew = new double[3*numberDifferentObj];
4499                                    double * lowerNew = objectiveNew+numberDifferentObj;
4500                                    double * upperNew = lowerNew+numberDifferentObj;
4501                                    memset(columnAdd+spaceNeeded,0,
4502                                           (numberDifferentObj+1)*sizeof(int));
4503                                    iLast=0;
4504                                    last=obj[0];
4505                                    numberDifferentObj=0;
4506                                    int priorityLevel=9999;
4507                                    int numberElements=0;
4508                                    rowAdd[0]=0;
4509                                    for (int jColumn = 1; jColumn < numberSort+1; jColumn++) {
4510                                      if (jColumn==numberSort||fabs(obj[jColumn]-last)>1.0e-12) {
4511                                        // not if just one
4512                                        if (jColumn-iLast>1) {
4513                                          // do priority
4514                                          if (highPriority==1) {
4515                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4516                                              = 500;
4517                                          } else if (highPriority==2) {
4518                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4519                                              = priorityLevel;
4520                                            priorityLevel--;
4521                                          }
4522                                          int iColumn=which[iLast];
4523                                          objectiveNew[numberDifferentObj]=objective[iColumn];
4524                                          double lower=0.0;
4525                                          double upper=0.0;
4526                                          for (int kColumn=iLast;kColumn<jColumn;kColumn++) {
4527                                            iColumn=which[kColumn];
4528                                            if (moveObjective)
4529                                              solver2->setObjCoeff(iColumn,0.0);
4530                                            double lowerValue=columnLower[iColumn];
4531                                            double upperValue=columnUpper[iColumn];
4532                                            double elementValue=-1.0;
4533                                            if (objectiveNew[numberDifferentObj]*objective[iColumn]<0.0) {
4534                                              lowerValue=-columnUpper[iColumn];
4535                                              upperValue=-columnLower[iColumn];
4536                                              elementValue=1.0;
4537                                            }
4538                                            if (!moveObjective)
4539                                              objectiveNew[numberDifferentObj]=0.0;
4540                                            columnAdd[numberElements]=iColumn;
4541                                            elementAdd[numberElements++]=elementValue;
4542                                            if (lower!=-COIN_DBL_MAX) {
4543                                              if (lowerValue!=-COIN_DBL_MAX)
4544                                                lower += lowerValue;
4545                                              else
4546                                                lower=-COIN_DBL_MAX;
4547                                            }
4548                                            if (upper!=COIN_DBL_MAX) {
4549                                              if (upperValue!=COIN_DBL_MAX)
4550                                                upper += upperValue;
4551                                              else
4552                                                upper=COIN_DBL_MAX;
4553                                            }
4554                                          }
4555                                          columnAdd[numberElements]=numberColumns+numberDifferentObj;
4556                                          elementAdd[numberElements++]=1.0;
4557                                          lowerNew[numberDifferentObj]=lower;
4558                                          upperNew[numberDifferentObj]=upper;
4559                                          numberDifferentObj++;
4560                                          rowAdd[numberDifferentObj]=numberElements;
4561                                        } else if (highPriority) {
4562                                          // just one
4563                                          // do priority
4564                                          int iColumn=which[iLast];
4565                                          int iInt=backward[iColumn];
4566                                          if (highPriority==1) {
4567                                            newPriorities[iInt] = 500;
4568                                          } else {
4569                                            newPriorities[iInt] = priorityLevel;
4570                                            priorityLevel--;
4571                                          }
4572                                        }
4573                                        if (jColumn<numberSort) {
4574                                          iLast=jColumn;
4575                                          last=obj[jColumn];
4576                                        }
4577                                      }
4578                                    }
4579                                    if (numberDifferentObj) {
4580                                      // add columns
4581                                      solver2->addCols(numberDifferentObj, 
4582                                                       columnAdd+spaceNeeded, NULL, NULL,
4583                                                       lowerNew, upperNew,objectiveNew);
4584                                      // add constraints and make integer if all integer in group
4585#ifdef COIN_HAS_CLP
4586                                      OsiClpSolverInterface * clpSolver2
4587                                        = dynamic_cast<OsiClpSolverInterface *> (solver2);
4588#endif
4589                                      for (int iObj=0; iObj < numberDifferentObj; iObj++) {
4590                                        lowerNew[iObj]=0.0;
4591                                        upperNew[iObj]=0.0;
4592                                        solver2->setInteger(numberColumns+iObj);
4593#ifdef COIN_HAS_CLP
4594                                        if (clpSolver2)
4595                                          clpSolver2->setOptionalInteger(numberColumns+iObj);
4596#endif
4597                                      }
4598                                      solver2->addRows(numberDifferentObj, 
4599                                                       rowAdd,columnAdd,elementAdd,
4600                                                       lowerNew, upperNew);
4601                                      sprintf(generalPrint,"Replacing model - %d new variables",numberDifferentObj);
4602                                      modifiedModel=true;
4603                                    }
4604                                    delete [] columnAdd;
4605                                    delete [] elementAdd;
4606                                    delete [] rowAdd;
4607                                    delete [] objectiveNew;
4608                                  }
4609                                  delete [] which;
4610                                  delete [] obj;
4611                                  if ((more2&(512|1024)) != 0) {
4612                                    // try for row slacks etc
4613                                    // later do row branching
4614                                    int iRow, iColumn;
4615                                    int numberColumns = solver2->getNumCols();
4616                                    int numberRows = solver2->getNumRows();
4617                                    int fudgeObjective = more2&512;
4618                                    int addSlacks = more2&1024;
4619                                    if (fudgeObjective) {
4620                                      bool moveObj = false;
4621                                      fudgeObjective = 0;
4622                                      const double * objective = solver2->getObjCoefficients();
4623                                      const double * columnLower = solver2->getColLower();
4624                                      const double * columnUpper = solver2->getColUpper();
4625                                      double * newValues = new double [numberColumns+1];
4626                                      int * newColumn = new int [numberColumns+1];
4627                                      bool allInteger=true;
4628                                      int n=0;
4629                                      double newLower = 0.0;
4630                                      double newUpper = 0.0;
4631                                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
4632                                        if (objective[iColumn]) {
4633                                          if (!solver2->isInteger(iColumn)) {
4634                                            allInteger=false;
4635                                            break;
4636                                          } else {
4637                                            double value = objective[iColumn];
4638                                            double nearest = floor(value+0.5);
4639                                            if (fabs(value-nearest)>1.0e-8) {
4640                                              allInteger=false;
4641                                              break;
4642                                            } else {
4643                                              newValues[n]=nearest;
4644                                              newColumn[n++]=iColumn;
4645                                              if (nearest>0.0) {
4646                                                newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4647                                                newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4648                                              } else {
4649                                                newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4650                                                newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4651                                              }
4652                                            }
4653                                          }
4654                                        }
4655                                      }
4656                                      if (allInteger && n) {
4657                                        fudgeObjective = n;
4658                                        solver2->addCol(0,NULL,NULL,newLower,newUpper,0.0,"obj_col");
4659                                        solver2->setInteger(numberColumns);
4660                                        newValues[n]=-1.0;
4661                                        newColumn[n++]=numberColumns;
4662                                        solver2->addRow(n,newColumn,newValues,0.0,0.0);
4663                                        if (moveObj) {
4664                                          memset(newValues,0,numberColumns*sizeof(double));
4665                                          newValues[numberColumns]=1.0;
4666                                          solver2->setObjective(newValues);
4667                                        }
4668                                        numberRows++;
4669                                        numberColumns++;
4670                                      }
4671                                      delete [] newValues;
4672                                      delete [] newColumn;
4673                                    }
4674                                    if (addSlacks) {
4675                                      bool moveObj = false;
4676                                      addSlacks=0;
4677                                      // get row copy
4678                                      const CoinPackedMatrix * matrix = solver2->getMatrixByRow();
4679                                      const double * element = matrix->getElements();
4680                                      const int * column = matrix->getIndices();
4681                                      const CoinBigIndex * rowStart = matrix->getVectorStarts();
4682                                      const int * rowLength = matrix->getVectorLengths();
4683                                      const double * rowLower = solver2->getRowLower();
4684                                      const double * rowUpper = solver2->getRowUpper();
4685                                      const double * columnLower = solver2->getColLower();
4686                                      const double * columnUpper = solver2->getColUpper();
4687                                     
4688                                      // maximum space for additional columns
4689                                      CoinBigIndex * newColumnStart = new CoinBigIndex[numberRows+1];
4690                                      newColumnStart[0]=0;
4691                                      int * newRow = new int [numberRows];
4692                                      double * newElement = new double [numberRows]; 
4693                                      double * newObjective = new double [numberRows]; 
4694                                      double * newColumnLower = new double [numberRows]; 
4695                                      double * newColumnUpper = new double [numberRows];
4696                                      double * oldObjective = CoinCopyOfArray(solver2->getObjCoefficients(),
4697                                                                              numberColumns);
4698                                      for (iRow=0;iRow<numberRows;iRow++) {
4699                                        if (rowLower[iRow]!=rowUpper[iRow]) {
4700                                          bool allInteger=true;
4701                                          double newLower = 0.0;
4702                                          double newUpper = 0.0;
4703                                          double constantObjective=0.0;
4704                                          for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
4705                                            int iColumn = column[j];
4706                                            if (!solver2->isInteger(iColumn)) {
4707                                              allInteger=false;
4708                                              break;
4709                                            } else {
4710                                              double value = element[j];
4711                                              double nearest = floor(value+0.5);
4712                                              if (fabs(value-nearest)>1.0e-8) {
4713                                                allInteger=false;
4714                                                break;
4715                                              } else {
4716                                                if (!oldObjective[iColumn])
4717                                                  constantObjective=COIN_DBL_MAX;
4718                                                if (!constantObjective) {
4719                                                  constantObjective=oldObjective[iColumn]/nearest;
4720                                                } else if (constantObjective!=COIN_DBL_MAX) {
4721                                                  double newConstant=oldObjective[iColumn]/nearest;
4722                                                  if (constantObjective>0.0) {
4723                                                    if (newConstant<=0.0)
4724                                                      constantObjective=COIN_DBL_MAX;
4725                                                    else
4726                                                      constantObjective=CoinMin(constantObjective,newConstant);
4727                                                  } else {
4728                                                    if (newConstant>=0.0)
4729                                                      constantObjective=COIN_DBL_MAX;
4730                                                    else
4731                                                      constantObjective=CoinMax(constantObjective,newConstant);
4732                                                  }
4733                                                }
4734                                                if (nearest>0.0) {
4735                                                  newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4736                                                  newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4737                                                } else {
4738                                                  newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4739                                                  newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4740                                                }
4741                                              }
4742                                            }
4743                                          }
4744                                          if (allInteger) {
4745                                            newColumnStart[addSlacks+1]=addSlacks+1;
4746                                            newRow[addSlacks]=iRow;
4747                                            newElement[addSlacks]=-1.0;
4748                                            newObjective[addSlacks] = 0.0;
4749                                            if (moveObj && constantObjective != COIN_DBL_MAX) {
4750                                              // move some of objective here if looks constant
4751                                              newObjective[addSlacks]=constantObjective;
4752                                              for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
4753                                                int iColumn = column[j];
4754                                                double value = element[j];
4755                                                double nearest = floor(value+0.5);
4756                                                oldObjective[iColumn] -= nearest*constantObjective;
4757                                              }
4758                                            }
4759                                            newColumnLower[addSlacks] = CoinMax(newLower,ceil(rowLower[iRow]));;
4760                                            newColumnUpper[addSlacks] = CoinMin(newUpper,floor(rowUpper[iRow]));
4761                                            addSlacks++;
4762                                          }
4763                                        }
4764                                      }
4765                                      if (addSlacks) {
4766                                        solver2->setObjective(oldObjective);
4767                                        solver2->addCols(addSlacks,newColumnStart,newRow,newElement,
4768                                                         newColumnLower,newColumnUpper,newObjective);
4769                                        truncatedRhsLower = CoinCopyOfArray(solver2->getRowLower(),numberRows);
4770                                        truncatedRhsUpper = CoinCopyOfArray(solver2->getRowUpper(),numberRows);
4771                                        for (int j=0;j<addSlacks;j++) {
4772                                          int iRow = newRow[j];
4773                                          solver2->setRowLower(iRow,0.0);
4774                                          solver2->setRowUpper(iRow,0.0);
4775                                          int iColumn = j+numberColumns;
4776                                          solver2->setInteger(iColumn);
4777                                          std::string name = solver2->getRowName(iRow);
4778                                          name += "_int";
4779                                          solver2->setColName(iColumn,name);
4780                                        }
4781                                      }
4782                                    }
4783                                    if (fudgeObjective||addSlacks) {
4784                                      modifiedModel=true;
4785