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

Last change on this file since 1886 was 1886, checked in by stefan, 7 years ago

fix compiler (gcc 4.6.2) warnings in optimized mode, mainly about unused variables

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