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

Last change on this file since 1998 was 1998, checked in by forrest, 6 years ago

for threadsafe

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