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

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

adding a dubious heuristic

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 586.5 KB
Line 
1/* $Id: CbcSolver.cpp 1945 2013-07-29 08:56:04Z forrest $ */
2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6/*! \file CbcSolver.cpp
7    \brief Second level routines for the cbc stand-alone solver.
8*/
9
10#include "CbcConfig.h"
11#include "CoinPragma.hpp"
12
13#include <cassert>
14#include <cstdio>
15#include <cstdlib>
16#include <cmath>
17#include <cfloat>
18#include <cstring>
19#include <iostream>
20
21#include "CoinPragma.hpp"
22#include "CoinHelperFunctions.hpp"
23
24#include "CoinMpsIO.hpp"
25#include "CoinModel.hpp"
26
27#include "ClpFactorization.hpp"
28#include "ClpQuadraticObjective.hpp"
29#include "CoinTime.hpp"
30#include "ClpSimplex.hpp"
31#include "ClpSimplexOther.hpp"
32#include "ClpSolve.hpp"
33#include "ClpMessage.hpp"
34#include "ClpPackedMatrix.hpp"
35#include "ClpPlusMinusOneMatrix.hpp"
36#include "ClpNetworkMatrix.hpp"
37#include "ClpDualRowSteepest.hpp"
38#include "ClpDualRowDantzig.hpp"
39#include "ClpLinearObjective.hpp"
40#include "ClpPrimalColumnSteepest.hpp"
41#include "ClpPrimalColumnDantzig.hpp"
42
43#include "ClpPresolve.hpp"
44#ifndef COIN_HAS_CBC
45#define COIN_HAS_CBC
46#endif
47#include "CbcOrClpParam.hpp"
48#include "OsiRowCutDebugger.hpp"
49#include "OsiChooseVariable.hpp"
50#include "OsiAuxInfo.hpp"
51#include "CbcMipStartIO.hpp"
52
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#ifndef CBC_USE_INITIAL_TIME
3020                          if (model_.useElapsedTime())
3021                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
3022                          else
3023                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
3024#endif
3025                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
3026                            if (vubAction != -1) {
3027                                // look at vubs
3028                                // extra1 is number of ints to leave free
3029                                // Just ones which affect >= extra3
3030                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
3031                                /* 2 is cost above which to fix if feasible
3032                                   3 is fraction of integer variables fixed if relaxing (0.97)
3033                                   4 is fraction of all variables fixed if relaxing (0.0)
3034                                */
3035                                double dextra[6];
3036                                int extra[5];
3037                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3038                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
3039                                                                  parameters_)].intValue();
3040                                if (exp1 == 4 && extra[1] == -1)
3041                                    extra[1] = 999998;
3042                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
3043                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
3044                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3045                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
3046                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
3047                                if (!dextra[3])
3048                                    dextra[3] = 0.97;
3049                                //OsiClpSolverInterface * newSolver =
3050                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
3051                                        debugValues, dextra, extra);
3052                                //assert (!newSolver);
3053                            }
3054                            // Actually do heuristics
3055                            // may need to flip objective
3056                            bool needFlip = model_.solver()->getObjSense()<0.0;
3057                            if (needFlip)
3058                              model_.flipModel(); 
3059                            //if we do then - fix priorities in clonebutmodel_.convertToDynamic();
3060                            doHeuristics(&model_, 2, parameters_,
3061                                         numberParameters_, noPrinting_, initialPumpTune);
3062                            if (needFlip)
3063                              model_.flipModel();
3064                            if (model_.bestSolution()) {
3065                                model_.setProblemStatus(1);
3066                                model_.setSecondaryStatus(6);
3067#ifdef COIN_HAS_ASL
3068                                if (statusUserFunction_[0]) {
3069                                    double value = model_.getObjValue();
3070                                    char buf[300];
3071                                    int pos = 0;
3072                                    pos += sprintf(buf + pos, "feasible,");
3073                                    info.problemStatus = 0;
3074                                    info.objValue = value;
3075                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3076                                                   value);
3077                                    sprintf(buf + pos, "\n0 iterations");
3078                                    free(info.primalSolution);
3079                                    int numberColumns = lpSolver->numberColumns();
3080                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3081                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3082                                    int numberRows = lpSolver->numberRows();
3083                                    free(info.dualSolution);
3084                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3085                                    CoinZeroN(info.dualSolution, numberRows);
3086                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3087                                    free(info.rowStatus);
3088                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3089                                    free(info.columnStatus);
3090                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3091                                    // Put basis in
3092                                    int i;
3093                                    // free,basic,ub,lb are 0,1,2,3
3094                                    for (i = 0; i < numberRows; i++) {
3095                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3096                                        info.rowStatus[i] = status;
3097                                    }
3098                                    for (i = 0; i < numberColumns; i++) {
3099                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3100                                        info.columnStatus[i] = status;
3101                                    }
3102                                    // put buffer into info
3103                                    strcpy(info.buffer, buf);
3104                                    delete basis;
3105                                }
3106#endif
3107                            }
3108                            int returnCode = callBack(&model, 6);
3109                            if (returnCode) {
3110                                // exit if user wants
3111                                delete babModel_;
3112                                babModel_ = NULL;
3113                                return returnCode;
3114                            }
3115                        }
3116                        break;
3117                    case CBC_PARAM_ACTION_MIPLIB:
3118                        // User can set options - main difference is lack of model and CglPreProcess
3119                        goodModel = true;
3120                        /*
3121                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3122                          Print elapsed time at the end.
3123                        */
3124                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3125                        // obsolete case STRENGTHEN:
3126                        if (goodModel) {
3127                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3128                            int logLevel = parameters_[slog].intValue();
3129                            int truncateColumns=COIN_INT_MAX;
3130                            int * newPriorities=NULL;
3131                            // Reduce printout
3132                            if (logLevel <= 1) {
3133                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3134                            } else {
3135                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3136                            }
3137                            {
3138                                OsiSolverInterface * solver = model_.solver();
3139#ifndef CBC_OTHER_SOLVER
3140                                OsiClpSolverInterface * si =
3141                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3142                                assert (si != NULL);
3143                                si->getModelPtr()->scaling(doScaling);
3144                                ClpSimplex * lpSolver = si->getModelPtr();
3145                                if (doVector) {
3146                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3147                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3148                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3149                                        clpMatrix->makeSpecialColumnCopy();
3150                                    }
3151                                }
3152#elif CBC_OTHER_SOLVER==1
3153                                OsiCpxSolverInterface * si =
3154                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3155                                assert (si != NULL);
3156#endif
3157                                statistics_nrows = si->getNumRows();
3158                                statistics_ncols = si->getNumCols();
3159                                statistics_nprocessedrows = si->getNumRows();
3160                                statistics_nprocessedcols = si->getNumCols();
3161                                // See if quadratic
3162#ifndef CBC_OTHER_SOLVER
3163#ifdef COIN_HAS_LINK
3164                                if (!complicatedInteger) {
3165                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3166                                    if (obj) {
3167                                        preProcess = 0;
3168                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3169                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3170                                        // create coin model
3171                                        coinModel = lpSolver->createCoinModel();
3172                                        assert (coinModel);
3173                                        // load from coin model
3174                                        OsiSolverLink solver1;
3175                                        OsiSolverInterface * solver2 = solver1.clone();
3176                                        model_.assignSolver(solver2, false);
3177                                        OsiSolverLink * si =
3178                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3179                                        assert (si != NULL);
3180                                        si->setDefaultMeshSize(0.001);
3181                                        // need some relative granularity
3182                                        si->setDefaultBound(100.0);
3183                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3184                                        if (dextra3)
3185                                            si->setDefaultMeshSize(dextra3);
3186                                        si->setDefaultBound(1000.0);
3187                                        si->setIntegerPriority(1000);
3188                                        si->setBiLinearPriority(10000);
3189                                        biLinearProblem=true;
3190                                        si->setSpecialOptions2(2 + 4 + 8);
3191                                        CoinModel * model2 = coinModel;
3192                                        si->load(*model2, true, parameters_[log].intValue());
3193                                        // redo
3194                                        solver = model_.solver();
3195                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3196                                        lpSolver = clpSolver->getModelPtr();
3197                                        clpSolver->messageHandler()->setLogLevel(0) ;
3198                                        testOsiParameters = 0;
3199                                        complicatedInteger = 2;  // allow cuts
3200                                        OsiSolverInterface * coinSolver = model_.solver();
3201                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3202                                        if (linkSolver->quadraticModel()) {
3203                                            ClpSimplex * qp = linkSolver->quadraticModel();
3204                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3205                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3206                                            qp->primal(1);
3207                                            OsiSolverLinearizedQuadratic solver2(qp);
3208                                            const double * solution = NULL;
3209                                            // Reduce printout
3210                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3211                                            CbcModel model2(solver2);
3212                                            // Now do requested saves and modifications
3213                                            CbcModel * cbcModel = & model2;
3214                                            OsiSolverInterface * osiModel = model2.solver();
3215                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3216                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3217
3218                                            // Set changed values
3219
3220                                            CglProbing probing;
3221                                            probing.setMaxProbe(10);
3222                                            probing.setMaxLook(10);
3223                                            probing.setMaxElements(200);
3224                                            probing.setMaxProbeRoot(50);
3225                                            probing.setMaxLookRoot(10);
3226                                            probing.setRowCuts(3);
3227                                            probing.setUsingObjective(true);
3228                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3229                                            cbcModel->cutGenerator(0)->setTiming(true);
3230
3231                                            CglGomory gomory;
3232                                            gomory.setLimitAtRoot(512);
3233                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3234                                            cbcModel->cutGenerator(1)->setTiming(true);
3235
3236                                            CglKnapsackCover knapsackCover;
3237                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3238                                            cbcModel->cutGenerator(2)->setTiming(true);
3239
3240                                            CglRedSplit redSplit;
3241                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3242                                            cbcModel->cutGenerator(3)->setTiming(true);
3243
3244                                            CglClique clique;
3245                                            clique.setStarCliqueReport(false);
3246                                            clique.setRowCliqueReport(false);
3247                                            clique.setMinViolation(0.1);
3248                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3249                                            cbcModel->cutGenerator(4)->setTiming(true);
3250
3251                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3252                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3253                                            cbcModel->cutGenerator(5)->setTiming(true);
3254
3255                                            CglFlowCover flowCover;
3256                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3257                                            cbcModel->cutGenerator(6)->setTiming(true);
3258
3259                                            CglTwomir twomir;
3260                                            twomir.setMaxElements(250);
3261                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3262                                            cbcModel->cutGenerator(7)->setTiming(true);
3263
3264                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3265                                            heuristicFPump.setWhen(13);
3266                                            heuristicFPump.setMaximumPasses(20);
3267                                            heuristicFPump.setMaximumRetries(7);
3268                                            heuristicFPump.setHeuristicName("feasibility pump");
3269                                            heuristicFPump.setInitialWeight(1);
3270                                            heuristicFPump.setFractionSmall(0.6);
3271                                            cbcModel->addHeuristic(&heuristicFPump);
3272
3273                                            CbcRounding rounding(*cbcModel);
3274                                            rounding.setHeuristicName("rounding");
3275                                            cbcModel->addHeuristic(&rounding);
3276
3277                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3278                                            heuristicLocal.setHeuristicName("combine solutions");
3279                                            heuristicLocal.setSearchType(1);
3280                                            heuristicLocal.setFractionSmall(0.6);
3281                                            cbcModel->addHeuristic(&heuristicLocal);
3282
3283                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3284                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3285                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3286
3287                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3288                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3289                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3290
3291                                            CbcCompareDefault compare;
3292                                            cbcModel->setNodeComparison(compare);
3293                                            cbcModel->setNumberBeforeTrust(5);
3294                                            cbcModel->setSpecialOptions(2);
3295                                            cbcModel->messageHandler()->setLogLevel(1);
3296                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3297                                            cbcModel->setMaximumCutPasses(1);
3298                                            cbcModel->setMinimumDrop(0.05);
3299                                            // For branchAndBound this may help
3300                                            clpModel->defaultFactorizationFrequency();
3301                                            clpModel->setDualBound(1.0001e+08);
3302                                            clpModel->setPerturbation(50);
3303                                            osiclpModel->setSpecialOptions(193);
3304                                            osiclpModel->messageHandler()->setLogLevel(0);
3305                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3306                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3307                                            // You can save some time by switching off message building
3308                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3309
3310                                            // Solve
3311
3312                                            cbcModel->initialSolve();
3313                                            if (clpModel->tightenPrimalBounds() != 0) {
3314#ifndef DISALLOW_PRINTING
3315                                                std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3316#endif
3317                                                break;
3318                                            }
3319                                            clpModel->dual();  // clean up
3320                                            cbcModel->initialSolve();
3321#ifdef CBC_THREAD
3322                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3323                                            cbcModel->setNumberThreads(numberThreads % 100);
3324                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3325#endif
3326                                            //setCutAndHeuristicOptions(*cbcModel);
3327                                            cbcModel->branchAndBound();
3328                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3329                                            assert (solver3);
3330                                            solution = solver3->bestSolution();
3331                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3332                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3333                                            if (solution) {
3334                                              linkSolver->setBestSolution(solution, solver3->getNumCols());
3335                                            }
3336                                            CbcHeuristicDynamic3 dynamic(model_);
3337                                            dynamic.setHeuristicName("dynamic pass thru");
3338                                            model_.addHeuristic(&dynamic);
3339                                            // if convex
3340                                            if ((linkSolver->specialOptions2()&4) != 0 && solution) {
3341                                                int numberColumns = coinModel->numberColumns();
3342                                                assert (linkSolver->objectiveVariable() == numberColumns);
3343                                                // add OA cut
3344                                                double offset;
3345                                                double * gradient = new double [numberColumns+1];
3346                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3347                                                       numberColumns*sizeof(double));
3348                                                double rhs = 0.0;
3349                                                int * column = new int[numberColumns+1];
3350                                                int n = 0;
3351                                                for (int i = 0; i < numberColumns; i++) {
3352                                                    double value = gradient[i];
3353                                                    if (fabs(value) > 1.0e-12) {
3354                                                        gradient[n] = value;
3355                                                        rhs += value * solution[i];
3356                                                        column[n++] = i;
3357                                                    }
3358                                                }
3359                                                gradient[n] = -1.0;
3360                                                column[n++] = numberColumns;
3361                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3362                                                delete [] gradient;
3363                                                delete [] column;
3364                                            }
3365                                            // could do three way branching round a) continuous b) best solution
3366                                            printf("obj %g\n", bestObjectiveValue);
3367                                            linkSolver->initialSolve();
3368                                        }
3369                                    }
3370                                }
3371#endif
3372#endif
3373                                if (logLevel <= 1)
3374                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3375#ifndef CBC_OTHER_SOLVER
3376                                si->setSpecialOptions(0x40000000);
3377#endif
3378                            }
3379                            if (!miplib) {
3380                                if (!preSolve) {
3381                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3382                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3383                                }
3384                                double time1a = CoinCpuTime();
3385                                OsiSolverInterface * solver = model_.solver();
3386#ifndef CBC_OTHER_SOLVER
3387                                OsiClpSolverInterface * si =
3388                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3389                                if (si)
3390                                    si->setSpecialOptions(si->specialOptions() | 1024);
3391#endif
3392                                model_.initialSolve();
3393#ifndef CBC_OTHER_SOLVER
3394                                ClpSimplex * clpSolver = si->getModelPtr();
3395                                int iStatus = clpSolver->status();
3396                                int iStatus2 = clpSolver->secondaryStatus();
3397                                if (iStatus == 0) {
3398                                    iStatus2 = 0;
3399                                } else if (iStatus == 1) {
3400                                    iStatus = 0;
3401                                    iStatus2 = 1; // say infeasible
3402                                } else if (iStatus == 2) {
3403                                    iStatus = 0;
3404                                    iStatus2 = 7; // say unbounded
3405                                } else if (iStatus == 3) {
3406                                    iStatus = 1;
3407                                    if (iStatus2 == 9)
3408                                        iStatus2 = 4;
3409                                    else
3410                                        iStatus2 = 3; // Use nodes - as closer than solutions
3411                                } else if (iStatus == 4) {
3412                                    iStatus = 2; // difficulties
3413                                    iStatus2 = 0;
3414                                }
3415                                model_.setProblemStatus(iStatus);
3416                                model_.setSecondaryStatus(iStatus2);
3417                                si->setWarmStart(NULL);
3418                                int returnCode = callBack(&model_, 1);
3419                                if (returnCode) {
3420                                    // exit if user wants
3421                                    delete babModel_;
3422                                    babModel_ = NULL;
3423                                    return returnCode;
3424                                }
3425                                if (clpSolver->status() > 0) {
3426                                    // and in babModel if exists
3427                                    if (babModel_) {
3428                                        babModel_->setProblemStatus(iStatus);
3429                                        babModel_->setSecondaryStatus(iStatus2);
3430                                    }
3431                                    if (!noPrinting_) {
3432                                        iStatus = clpSolver->status();
3433                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3434                                                              "difficulties", "other"
3435                                                             };
3436                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3437                                                msg[iStatus-1], CoinCpuTime() - time1a);
3438                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3439                                        << generalPrint
3440                                        << CoinMessageEol;
3441                                    }
3442                                    break;
3443                                }
3444                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3445#elif CBC_OTHER_SOLVER==1
3446#endif
3447                                if (!noPrinting_) {
3448                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3449                                            solver->getObjValue(), CoinCpuTime() - time1a);
3450                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3451                                    << generalPrint
3452                                    << CoinMessageEol;
3453                                }
3454                                if (model_.getMaximumNodes() == -987654321) {
3455                                    // See if No objective!
3456                                    int numberColumns = clpSolver->getNumCols();
3457                                    const double * obj = clpSolver->getObjCoefficients();
3458                                    const double * lower = clpSolver->getColLower();
3459                                    const double * upper = clpSolver->getColUpper();
3460                                    int nObj = 0;
3461                                    for (int i = 0; i < numberColumns; i++) {
3462                                        if (upper[i] > lower[i] && obj[i])
3463                                            nObj++;
3464                                    }
3465                                    if (!nObj) {
3466                                        printf("************No objective!!\n");
3467                                        model_.setMaximumSolutions(1);
3468                                        // Column copy
3469                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3470                                        //const double * element = matrixByCol.getElements();
3471                                        //const int * row = matrixByCol.getIndices();
3472                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3473                                        const int * columnLength = matrixByCol.getVectorLengths();
3474                                        for (int i = 0; i < numberColumns; i++) {
3475                                            double value = (CoinDrand48() + 0.5) * 10000;
3476                                            value = 10;
3477                                            value *= columnLength[i];
3478                                            int iValue = static_cast<int> (value) / 10;
3479                                            //iValue=1;
3480                                            clpSolver->setObjCoeff(i, iValue);
3481                                        }
3482                                    }
3483                                }
3484#ifndef CBC_OTHER_SOLVER
3485                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3486#ifndef DISALLOW_PRINTING
3487                                    std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3488#endif
3489                                    model_.setProblemStatus(0);
3490                                    model_.setSecondaryStatus(1);
3491                                    // and in babModel if exists
3492                                    if (babModel_) {
3493                                        babModel_->setProblemStatus(0);
3494                                        babModel_->setSecondaryStatus(1);
3495                                    }
3496                                    break;
3497                                }
3498                                if (clpSolver->dualBound() == 1.0e10) {
3499                                    ClpSimplex temp = *clpSolver;
3500                                    temp.setLogLevel(0);
3501                                    temp.dual(0, 7);
3502                                    // user did not set - so modify
3503                                    // get largest scaled away from bound
3504                                    double largest = 1.0e-12;
3505                                    double largestScaled = 1.0e-12;
3506                                    int numberRows = temp.numberRows();
3507                                    const double * rowPrimal = temp.primalRowSolution();
3508                                    const double * rowLower = temp.rowLower();
3509                                    const double * rowUpper = temp.rowUpper();
3510                                    const double * rowScale = temp.rowScale();
3511                                    int iRow;
3512                                    for (iRow = 0; iRow < numberRows; iRow++) {
3513                                        double value = rowPrimal[iRow];
3514                                        double above = value - rowLower[iRow];
3515                                        double below = rowUpper[iRow] - value;
3516                                        if (above < 1.0e12) {
3517                                            largest = CoinMax(largest, above);
3518                                        }
3519                                        if (below < 1.0e12) {
3520                                            largest = CoinMax(largest, below);
3521                                        }
3522                                        if (rowScale) {
3523                                            double multiplier = rowScale[iRow];
3524                                            above *= multiplier;
3525                                            below *= multiplier;
3526                                        }
3527                                        if (above < 1.0e12) {
3528                                            largestScaled = CoinMax(largestScaled, above);
3529                                        }
3530                                        if (below < 1.0e12) {
3531                                            largestScaled = CoinMax(largestScaled, below);
3532                                        }
3533                                    }
3534
3535                                    int numberColumns = temp.numberColumns();
3536                                    const double * columnPrimal = temp.primalColumnSolution();
3537                                    const double * columnLower = temp.columnLower();
3538                                    const double * columnUpper = temp.columnUpper();
3539                                    const double * columnScale = temp.columnScale();
3540                                    int iColumn;
3541                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3542                                        double value = columnPrimal[iColumn];
3543                                        double above = value - columnLower[iColumn];
3544                                        double below = columnUpper[iColumn] - value;
3545                                        if (above < 1.0e12) {
3546                                            largest = CoinMax(largest, above);
3547                                        }
3548                                        if (below < 1.0e12) {
3549                                            largest = CoinMax(largest, below);
3550                                        }
3551                                        if (columnScale) {
3552                                            double multiplier = 1.0 / columnScale[iColumn];
3553                                            above *= multiplier;
3554                                            below *= multiplier;
3555                                        }
3556                                        if (above < 1.0e12) {
3557                                            largestScaled = CoinMax(largestScaled, above);
3558                                        }
3559                                        if (below < 1.0e12) {
3560                                            largestScaled = CoinMax(largestScaled, below);
3561                                        }
3562                                    }
3563#ifdef COIN_DEVELOP
3564                                    if (!noPrinting_)
3565                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3566                                                  << " unscaled " << largest << std::endl;
3567#endif
3568                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3569                                }
3570                                si->resolve();  // clean up
3571#endif
3572                            }
3573                            // If user made settings then use them
3574                            if (!defaultSettings) {
3575                                OsiSolverInterface * solver = model_.solver();
3576                                if (!doScaling)
3577                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3578#ifndef CBC_OTHER_SOLVER
3579                                OsiClpSolverInterface * si =
3580                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3581                                assert (si != NULL);
3582                                // get clp itself
3583                                ClpSimplex * modelC = si->getModelPtr();
3584                                //if (modelC->tightenPrimalBounds()!=0) {
3585                                //std::cout<<"Problem is infeasible!"<<std::endl;
3586                                //break;
3587                                //}
3588                                // bounds based on continuous
3589                                if (tightenFactor && !complicatedInteger) {
3590                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3591#ifndef DISALLOW_PRINTING
3592                                        std::cout << "Problem is infeasible!" << std::endl;
3593#endif
3594                                        model_.setProblemStatus(0);
3595                                        model_.setSecondaryStatus(1);
3596                                        // and in babModel if exists
3597                                        if (babModel_) {
3598                                            babModel_->setProblemStatus(0);
3599                                            babModel_->setSecondaryStatus(1);
3600                                        }
3601                                        break;
3602                                    }
3603                                }
3604#endif
3605                            }
3606                            // See if we want preprocessing
3607                            OsiSolverInterface * saveSolver = NULL;
3608                            CglPreProcess process;
3609                            // Say integers in sync
3610                            bool integersOK = true;
3611                            delete babModel_;
3612                            babModel_ = new CbcModel(model_);
3613#ifndef CBC_OTHER_SOLVER
3614                            int numberChanged = 0;
3615                            OsiSolverInterface * solver3 = clpSolver->clone();
3616                            babModel_->assignSolver(solver3);
3617                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3618                            if (clpSolver2->messageHandler()->logLevel())
3619                                clpSolver2->messageHandler()->setLogLevel(1);
3620                            if (logLevel > -1)
3621                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3622                            lpSolver = clpSolver2->getModelPtr();
3623                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3624                                // User did not touch preset
3625                                int numberRows = lpSolver->numberRows();
3626                                const int cutoff1 = 10000;
3627                                const int cutoff2 = 100000;
3628                                const int base = 75;
3629                                const int freq0 = 50;
3630                                const int freq1 = 200;
3631                                const int freq2 = 400;
3632                                const int maximum = 1000;
3633                                int frequency;
3634                                if (numberRows < cutoff1)
3635                                    frequency = base + numberRows / freq0;
3636                                else if (numberRows < cutoff2)
3637                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3638                                else
3639                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3640                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3641                            }
3642#elif CBC_OTHER_SOLVER==1
3643                            OsiSolverInterface * solver3 = model_.solver()->clone();
3644                            babModel_->assignSolver(solver3);
3645#endif
3646                            time2 = CoinCpuTime();
3647                            totalTime += time2 - time1;
3648                            //time1 = time2;
3649                            double timeLeft = babModel_->getMaximumSeconds();
3650                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3651                            if (preProcess == 7) {
3652                                // use strategy instead
3653                                preProcess = 0;
3654                                useStrategy = true;
3655#ifdef COIN_HAS_LINK
3656                                // empty out any cuts
3657                                if (storedAmpl.sizeRowCuts()) {
3658                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3659                                    CglStored temp;
3660                                    storedAmpl = temp;
3661                                }
3662#endif
3663                            }
3664                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3665                              // see whether to switch off preprocessing
3666                              // only allow SOS and integer
3667                              OsiObject ** objects = babModel_->objects();
3668                              int numberObjects = babModel_->numberObjects();
3669                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3670                                CbcSOS * objSOS =
3671                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
3672                                CbcSimpleInteger * objSimpleInteger =
3673                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3674                                if (!objSimpleInteger&&!objSOS) {
3675                                  preProcess=0;
3676                                  break;
3677                                }
3678                              }
3679                            }
3680                            if (type == CBC_PARAM_ACTION_BAB) {
3681                                double limit;
3682                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
3683                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
3684                                        limit*clpSolver->getObjSense())
3685                                    preProcess = 0;
3686                            }
3687                            if (mipStartBefore.size())
3688                              {
3689                                CbcModel tempModel=*babModel_;
3690                                std::vector< std::string > colNames;
3691                                for ( int i=0 ; (i<babModel_->solver()->getNumCols()) ; ++i )
3692                                  colNames.push_back( model_.solver()->getColName(i) );
3693                                std::vector< double > x( babModel_->getNumCols(), 0.0 );
3694                                double obj;
3695                                int status = computeCompleteSolution( &tempModel, colNames, mipStartBefore, &x[0], obj );
3696                                // set cutoff
3697                                if (!status)
3698                                  babModel_->setCutoff(CoinMin(babModel_->getCutoff(),obj+1.0e-4));
3699                              }
3700                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3701#ifndef CBC_OTHER_SOLVER
3702                                // See if sos from mps file
3703                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
3704                                    // SOS
3705                                    numberSOS = clpSolver->numberSOS();
3706                                    const CoinSet * setInfo = clpSolver->setInfo();
3707                                    sosStart = new int [numberSOS+1];
3708                                    sosType = new char [numberSOS];
3709                                    int i;
3710                                    int nTotal = 0;
3711                                    sosStart[0] = 0;
3712                                    for ( i = 0; i < numberSOS; i++) {
3713                                        int type = setInfo[i].setType();
3714                                        int n = setInfo[i].numberEntries();
3715                                        sosType[i] = static_cast<char>(type);
3716                                        nTotal += n;
3717                                        sosStart[i+1] = nTotal;
3718                                    }
3719                                    sosIndices = new int[nTotal];
3720                                    sosReference = new double [nTotal];
3721                                    for (i = 0; i < numberSOS; i++) {
3722                                        int n = setInfo[i].numberEntries();
3723                                        const int * which = setInfo[i].which();
3724                                        const double * weights = setInfo[i].weights();
3725                                        int base = sosStart[i];
3726                                        for (int j = 0; j < n; j++) {
3727                                            int k = which[j];
3728                                            sosIndices[j+base] = k;
3729                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
3730                                        }
3731                                    }
3732                                }
3733#endif
3734                                saveSolver = babModel_->solver()->clone();
3735                                /* Do not try and produce equality cliques and
3736                                   do up to 10 passes */
3737                                OsiSolverInterface * solver2;
3738                                {
3739                                    // Tell solver we are in Branch and Cut
3740                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
3741                                    // Default set of cut generators
3742                                    CglProbing generator1;
3743                                    generator1.setUsingObjective(1);
3744                                    generator1.setMaxPass(1);
3745                                    generator1.setMaxPassRoot(1);
3746                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
3747                                    generator1.setMaxElements(100);
3748                                    generator1.setMaxElementsRoot(200);
3749                                    generator1.setMaxLookRoot(50);
3750                                    if (saveSolver->getNumCols() > 3000)
3751                                        generator1.setMaxProbeRoot(123);
3752                                    generator1.setRowCuts(3);
3753                                    if ((tunePreProcess&1) != 0) {
3754                                        // heavy probing
3755                                        generator1.setMaxPassRoot(2);
3756                                        generator1.setMaxElements(300);
3757                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
3758                                    }
3759                                    if ((babModel_->specialOptions()&65536) != 0)
3760                                        process.setOptions(1);
3761                                    // Add in generators
3762                                    if ((model_.moreSpecialOptions()&65536)==0)
3763                                      process.addCutGenerator(&generator1);
3764                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
3765                                    process.passInMessageHandler(babModel_->messageHandler());
3766                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
3767#ifdef COIN_HAS_ASL
3768                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
3769                                        // SOS
3770                                        numberSOS = info.numberSos;
3771                                        sosStart = info.sosStart;
3772                                        sosIndices = info.sosIndices;
3773                                    }
3774#endif
3775                                    if (numberSOS && doSOS) {
3776                                        // SOS
3777                                        int numberColumns = saveSolver->getNumCols();
3778                                        char * prohibited = new char[numberColumns];
3779                                        memset(prohibited, 0, numberColumns);
3780                                        int n = sosStart[numberSOS];
3781                                        for (int i = 0; i < n; i++) {
3782                                            int iColumn = sosIndices[i];
3783                                            prohibited[iColumn] = 1;
3784                                        }
3785                                        process.passInProhibited(prohibited, numberColumns);
3786                                        delete [] prohibited;
3787                                    }
3788                                    if (0) {
3789                                     
3790                                      // Special integers
3791                                      int numberColumns = saveSolver->getNumCols();
3792                                      char * prohibited = new char[numberColumns];
3793                                      memset(prohibited, 0, numberColumns);
3794                                      const CoinPackedMatrix * matrix = saveSolver->getMatrixByCol();
3795                                      const int * columnLength = matrix->getVectorLengths();
3796                                      int numberProhibited=0;
3797                                      for (int iColumn = numberColumns-1; iColumn >=0; iColumn--) {
3798                                        if (!saveSolver->isInteger(iColumn)||
3799                                            columnLength[iColumn]>1)
3800                                          break;
3801                                        numberProhibited++;
3802                                        prohibited[iColumn] = 1;
3803                                      }
3804                                      if (numberProhibited) {
3805                                        process.passInProhibited(prohibited, numberColumns);
3806                                        printf("**** Treating last %d integers as special - give high priority?\n",numberProhibited);
3807                                      }
3808                                      delete [] prohibited;
3809                                    }
3810                                    if (!model_.numberObjects() && true) {
3811                                        /* model may not have created objects
3812                                           If none then create
3813                                        */
3814                                        model_.findIntegers(true);
3815                                    }
3816                                    if (model_.numberObjects()) {
3817                                        OsiObject ** oldObjects = babModel_->objects();
3818                                        int numberOldObjects = babModel_->numberObjects();
3819                                        // SOS
3820                                        int numberColumns = saveSolver->getNumCols();
3821                                        char * prohibited = new char[numberColumns];
3822                                        memset(prohibited, 0, numberColumns);
3823                                        int numberProhibited = 0;
3824                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
3825                                            CbcSOS * obj =
3826                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
3827                                            if (obj) {
3828                                                int n = obj->numberMembers();
3829                                                const int * which = obj->members();
3830                                                for (int i = 0; i < n; i++) {
3831                                                    int iColumn = which[i];
3832                                                    prohibited[iColumn] = 1;
3833                                                    numberProhibited++;
3834                                                }
3835                                            }
3836                                            CbcLotsize * obj2 =
3837                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
3838                                            if (obj2) {
3839                                                int iColumn = obj2->columnNumber();
3840                                                prohibited[iColumn] = 1;
3841                                                numberProhibited++;
3842                                            }
3843                                        }
3844                                        if (numberProhibited)
3845                                            process.passInProhibited(prohibited, numberColumns);
3846                                        delete [] prohibited;
3847                                    }
3848                                    int numberPasses = 10;
3849                                    if (tunePreProcess >= 1000000) {
3850                                        numberPasses = (tunePreProcess / 1000000) - 1;
3851                                        tunePreProcess = tunePreProcess % 1000000;
3852                                    } else if (tunePreProcess >= 1000) {
3853                                        numberPasses = (tunePreProcess / 1000) - 1;
3854                                        tunePreProcess = tunePreProcess % 1000;
3855                                    }
3856#ifndef CBC_OTHER_SOLVER
3857                                    if (doSprint > 0) {
3858                                        // Sprint for primal solves
3859                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
3860                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
3861                                        int numberPasses = 5;
3862                                        int options[] = {0, 3, 0, 0, 0, 0};
3863                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
3864                                        extraInfo[1] = doSprint;
3865                                        int independentOptions[] = {0, 0, 3};
3866                                        ClpSolve clpSolve(method, presolveType, numberPasses,
3867                                                          options, extraInfo, independentOptions);
3868                                        // say use in OsiClp
3869                                        clpSolve.setSpecialOption(6, 1);
3870                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3871                                        osiclp->setSolveOptions(clpSolve);
3872                                        osiclp->setHintParam(OsiDoDualInResolve, false);
3873                                        // switch off row copy
3874                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
3875                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
3876                                    }
3877#endif
3878#ifndef CBC_OTHER_SOLVER
3879                                    {
3880                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3881                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
3882                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
3883                                        //#define CBC_TEMP1
3884#ifdef CBC_TEMP1
3885                                        if (savePerturbation == 50)
3886                                            osiclp->getModelPtr()->setPerturbation(52); // try less
3887#endif
3888                                        if ((model_.moreSpecialOptions()&65536)!=0)
3889                                          process.setOptions(2+4+8); // no cuts
3890                                        cbcPreProcessPointer = & process;
3891                                        int saveOptions = osiclp->getModelPtr()->moreSpecialOptions();
3892                                        if ((model_.specialOptions()&16777216)!=0&&
3893                                            model_.getCutoff()>1.0e30) {
3894                                          osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions|262144);
3895                                        }
3896                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3897                                                                               tunePreProcess);
3898                                        /*solver2->writeMps("after");
3899                                          saveSolver->writeMps("before");*/
3900                                        osiclp->getModelPtr()->setPerturbation(savePerturbation);
3901                                        osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions);
3902                                    }
3903#elif CBC_OTHER_SOLVER==1
3904                                    cbcPreProcessPointer = & process;
3905                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3906                                                                           tunePreProcess);
3907#endif
3908                                    integersOK = false; // We need to redo if CbcObjects exist
3909                                    // Tell solver we are not in Branch and Cut
3910                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3911                                    if (solver2)
3912                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3913                                }
3914#ifdef COIN_HAS_ASL
3915                                if (!solver2 && statusUserFunction_[0]) {
3916                                    // infeasible
3917                                    info.problemStatus = 1;
3918                                    info.objValue = 1.0e100;
3919                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
3920                                    info.primalSolution = NULL;
3921                                    info.dualSolution = NULL;
3922                                    break;
3923                                }
3924#endif
3925                                if (!noPrinting_) {
3926                                    if (!solver2) {
3927                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
3928                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3929                                        << generalPrint
3930                                        << CoinMessageEol;
3931                                    } else {
3932                                        //printf("processed model has %d rows, %d columns and %d elements\n",
3933                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
3934                                    }
3935                                }
3936                                if (!solver2) {
3937                                    // say infeasible for solution
3938                                    integerStatus = 6;
3939                                    model_.setProblemStatus(0);
3940                                    model_.setSecondaryStatus(1);
3941                                    babModel_->setProblemStatus(0);
3942                                    babModel_->setSecondaryStatus(1);
3943                                } else {
3944                                    statistics_nprocessedrows = solver2->getNumRows();
3945                                    statistics_nprocessedcols = solver2->getNumCols();
3946                                    model_.setProblemStatus(-1);
3947                                    babModel_->setProblemStatus(-1);
3948                                }
3949                                int returnCode = callBack(babModel_, 2);
3950                                if (returnCode) {
3951                                    // exit if user wants
3952                                    delete babModel_;
3953                                    babModel_ = NULL;
3954                                    return returnCode;
3955                                }
3956                                if (!solver2)
3957                                    break;
3958                                if (model_.bestSolution()) {
3959                                    // need to redo - in case no better found in BAB
3960                                    // just get integer part right
3961                                    const int * originalColumns = process.originalColumns();
3962                                    int numberColumns = solver2->getNumCols();
3963                                    double * bestSolution = babModel_->bestSolution();
3964                                    const double * oldBestSolution = model_.bestSolution();
3965                                    for (int i = 0; i < numberColumns; i++) {
3966                                        int jColumn = originalColumns[i];
3967                                        bestSolution[i] = oldBestSolution[jColumn];
3968                                    }
3969                                }
3970                                //solver2->resolve();
3971                                if (preProcess == 2) {
3972                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3973                                    ClpSimplex * lpSolver = clpSolver2->getModelPtr();
3974                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
3975                                    printf("Preprocessed model (minimization) on presolved.mps\n");
3976                                }
3977                                {
3978                                    // look at new integers
3979                                    int numberOriginalColumns =
3980                                        process.originalModel()->getNumCols();
3981                                    const int * originalColumns = process.originalColumns();
3982                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3983                                    int numberColumns = osiclp2->getNumCols();
3984                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3985                                    for (int i = 0; i < numberColumns; i++) {
3986                                        int iColumn = originalColumns[i];
3987                                        if (iColumn < numberOriginalColumns) {
3988                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
3989                                                osiclp2->setOptionalInteger(i); // say optional
3990                                        }
3991                                    }
3992                                }
3993                                // we have to keep solver2 so pass clone
3994                                solver2 = solver2->clone();
3995                                // see if extra variables wanted
3996                                int threshold = 
3997                                  parameters_[whichParam(CBC_PARAM_INT_EXTRA_VARIABLES, numberParameters_, parameters_)].intValue();
3998                                if (threshold) {
3999                                  int numberColumns = solver2->getNumCols();
4000                                  int highPriority=0;
4001                                  /*
4002                                    normal - no priorities
4003                                    >10000 equal high priority
4004                                    >20000 higher priority for higher cost
4005                                  */
4006                                  if (threshold>10000) {
4007                                    highPriority=threshold/10000;
4008                                    threshold -= 10000*highPriority;
4009                                  }
4010                                  const double * columnLower = solver2->getColLower();
4011                                  const double * columnUpper = solver2->getColUpper();
4012                                  const double * objective = solver2->getObjCoefficients();
4013                                  int numberIntegers = 0;
4014                                  int numberBinary = 0;
4015                                  int numberTotalIntegers=0;
4016                                  double * obj = new double [numberColumns];
4017                                  int * which = new int [numberColumns];
4018                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4019                                    if (solver2->isInteger(iColumn)) {
4020                                      numberTotalIntegers++;
4021                                      if (columnUpper[iColumn] > columnLower[iColumn]) {
4022                                        numberIntegers++;
4023                                        if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1)
4024                                          numberBinary++;
4025                                      }
4026                                    }
4027                                  }
4028                                  int numberSort=0;
4029                                  int numberZero=0;
4030                                  int numberZeroContinuous=0;
4031                                  int numberDifferentObj=0;
4032                                  int numberContinuous=0;
4033                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4034                                    if (columnUpper[iColumn] > columnLower[iColumn]) {
4035                                      if (solver2->isInteger(iColumn)) {
4036                                        if (!objective[iColumn]) {
4037                                          numberZero++;
4038                                        } else {
4039                                          obj[numberSort]= fabs(objective[iColumn]);
4040                                          which[numberSort++]=iColumn;
4041                                        }
4042                                      } else if (objective[iColumn]) {
4043                                        numberContinuous++;
4044                                      } else {
4045                                        numberZeroContinuous++;
4046                                      }
4047                                    }
4048                                  }
4049                                  CoinSort_2(obj,obj+numberSort,which);
4050                                  double last=obj[0];
4051                                  for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4052                                    if (fabs(obj[jColumn]-last)>1.0e-12) {
4053                                      numberDifferentObj++;
4054                                      last=obj[jColumn];
4055                                    }
4056                                  }
4057                                  numberDifferentObj++;
4058                                  sprintf(generalPrint,"Problem has %d integers (%d of which binary) and %d continuous",
4059                                         numberIntegers,numberBinary,numberColumns-numberIntegers);
4060                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4061                                    << generalPrint
4062                                    << CoinMessageEol;
4063                                  if (numberColumns>numberIntegers) {
4064                                    sprintf(generalPrint,"%d continuous have nonzero objective, %d have zero objective",
4065                                            numberContinuous,numberZeroContinuous);
4066                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4067                                      << generalPrint
4068                                      << CoinMessageEol;
4069                                  }
4070                                  sprintf(generalPrint,"%d integer have nonzero objective, %d have zero objective, %d different nonzero (taking abs)",
4071                                          numberSort,numberZero,numberDifferentObj);
4072                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4073                                    << generalPrint
4074                                    << CoinMessageEol;
4075                                  if (numberDifferentObj<=threshold + (numberZero) ? 1 : 0 && numberDifferentObj) {
4076                                    int * backward=NULL;
4077                                    if (highPriority) {
4078                                      newPriorities = new int [numberTotalIntegers+numberDifferentObj+numberColumns];
4079                                      backward=newPriorities+numberTotalIntegers+numberDifferentObj;
4080                                      numberTotalIntegers=0;
4081                                      for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4082                                        if (solver2->isInteger(iColumn)) {
4083                                          backward[iColumn]=numberTotalIntegers;
4084                                          newPriorities[numberTotalIntegers++]=10000;
4085                                        }
4086                                      }
4087                                    }
4088                                    int iLast=0;
4089                                    double last=obj[0];
4090                                    for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4091                                      if (fabs(obj[jColumn]-last)>1.0e-12) {
4092                                        sprintf(generalPrint,"%d variables have objective of %g",
4093                                               jColumn-iLast,last);
4094                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4095                                          << generalPrint
4096                                          << CoinMessageEol;
4097                                        iLast=jColumn;
4098                                        last=obj[jColumn];
4099                                      }
4100                                    }
4101                                    sprintf(generalPrint,"%d variables have objective of %g",
4102                                           numberSort-iLast,last);
4103                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4104                                      << generalPrint
4105                                      << CoinMessageEol;
4106                                    int spaceNeeded=numberSort+numberDifferentObj;
4107                                    int * columnAdd = new int[spaceNeeded+numberDifferentObj+1];
4108                                    double * elementAdd = new double[spaceNeeded];
4109                                    int * rowAdd = new int[numberDifferentObj+1];
4110                                    double * objectiveNew = new double[3*numberDifferentObj];
4111                                    double * lowerNew = objectiveNew+numberDifferentObj;
4112                                    double * upperNew = lowerNew+numberDifferentObj;
4113                                    memset(columnAdd+spaceNeeded,0,
4114                                           (numberDifferentObj+1)*sizeof(int));
4115                                    iLast=0;
4116                                    last=obj[0];
4117                                    numberDifferentObj=0;
4118                                    int priorityLevel=9999;
4119                                    int numberElements=0;
4120                                    rowAdd[0]=0;
4121                                    for (int jColumn = 1; jColumn < numberSort+1; jColumn++) {
4122                                      if (jColumn==numberSort||fabs(obj[jColumn]-last)>1.0e-12) {
4123                                        // not if just one
4124                                        if (jColumn-iLast>1) {
4125                                          // do priority
4126                                          if (highPriority==1) {
4127                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4128                                              = 500;
4129                                          } else if (highPriority==2) {
4130                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4131                                              = priorityLevel;
4132                                            priorityLevel--;
4133                                          }
4134                                          int iColumn=which[iLast];
4135                                          objectiveNew[numberDifferentObj]=objective[iColumn];
4136                                          double lower=0.0;
4137                                          double upper=0.0;
4138                                          for (int kColumn=iLast;kColumn<jColumn;kColumn++) {
4139                                            iColumn=which[kColumn];
4140                                            solver2->setObjCoeff(iColumn,0.0);
4141                                            double lowerValue=columnLower[iColumn];
4142                                            double upperValue=columnUpper[iColumn];
4143                                            double elementValue=-1.0;
4144                                            if (objectiveNew[numberDifferentObj]*objective[iColumn]<0.0) {
4145                                              lowerValue=-columnUpper[iColumn];
4146                                              upperValue=-columnLower[iColumn];
4147                                              elementValue=1.0;
4148                                            }
4149                                            columnAdd[numberElements]=iColumn;
4150                                            elementAdd[numberElements++]=elementValue;
4151                                            if (lower!=-COIN_DBL_MAX) {
4152                                              if (lowerValue!=-COIN_DBL_MAX)
4153                                                lower += lowerValue;
4154                                              else
4155                                                lower=-COIN_DBL_MAX;
4156                                            }
4157                                            if (upper!=COIN_DBL_MAX) {
4158                                              if (upperValue!=COIN_DBL_MAX)
4159                                                upper += upperValue;
4160                                              else
4161                                                upper=COIN_DBL_MAX;
4162                                            }
4163                                          }
4164                                          columnAdd[numberElements]=numberColumns+numberDifferentObj;
4165                                          elementAdd[numberElements++]=1.0;
4166                                          lowerNew[numberDifferentObj]=lower;
4167                                          upperNew[numberDifferentObj]=upper;
4168                                          numberDifferentObj++;
4169                                          rowAdd[numberDifferentObj]=numberElements;
4170                                        } else if (highPriority) {
4171                                          // just one
4172                                          // do priority
4173                                          int iColumn=which[iLast];
4174                                          int iInt=backward[iColumn];
4175                                          if (highPriority==1) {
4176                                            newPriorities[iInt] = 500;
4177                                          } else {
4178                                            newPriorities[iInt] = priorityLevel;
4179                                            priorityLevel--;
4180                                          }
4181                                        }
4182                                        if (jColumn<numberSort) {
4183                                          iLast=jColumn;
4184                                          last=obj[jColumn];
4185                                        }
4186                                      }
4187                                    }
4188                                    if (numberDifferentObj) {
4189                                      // add columns
4190                                      solver2->addCols(numberDifferentObj, 
4191                                                       columnAdd+spaceNeeded, NULL, NULL,
4192                                                       lowerNew, upperNew,objectiveNew);
4193                                      // add constraints and make integer if all integer in group
4194                                      for (int iObj=0; iObj < numberDifferentObj; iObj++) {
4195                                        lowerNew[iObj]=0.0;
4196                                        upperNew[iObj]=0.0;
4197                                        solver2->setInteger(numberColumns+iObj);
4198                                      }
4199                                      solver2->addRows(numberDifferentObj, 
4200                                                       rowAdd,columnAdd,elementAdd,
4201                                                       lowerNew, upperNew);
4202                                      sprintf(generalPrint,"Replacing model - %d new variables",numberDifferentObj);
4203                                      generalMessageHandler->message(CLP_GENERAL, generalMessages)
4204                                        << generalPrint
4205                                        << CoinMessageEol;
4206                                      truncateColumns=numberColumns;
4207                                    }
4208                                    delete [] columnAdd;
4209                                    delete [] elementAdd;
4210                                    delete [] rowAdd;
4211                                    delete [] objectiveNew;
4212                                  }
4213                                  delete [] which;
4214                                  delete [] obj;
4215                                }
4216                                babModel_->assignSolver(solver2);
4217                                babModel_->setOriginalColumns(process.originalColumns(),
4218                                                              truncateColumns);
4219                                babModel_->initialSolve();
4220                                babModel_->setMaximumSeconds(timeLeft - (CoinCpuTime() - time2));
4221                            }
4222                            // now tighten bounds
4223                            if (!miplib) {
4224#ifndef CBC_OTHER_SOLVER
4225                                OsiClpSolverInterface * si =
4226                                    dynamic_cast<OsiClpSolverInterface *>(babModel_->solver()) ;
4227                                assert (si != NULL);
4228                                // get clp itself
4229                                ClpSimplex * modelC = si->getModelPtr();
4230                                //if (noPrinting_)
4231                                //modelC->setLogLevel(0);
4232                                if (!complicatedInteger && modelC->tightenPrimalBounds() != 0) {
4233#ifndef DISALLOW_PRINTING
4234                                    std::cout << "Problem is infeasible!" << std::endl;
4235#endif
4236                                    model_.setProblemStatus(0);
4237                                    model_.setSecondaryStatus(1);
4238                                    // and in babModel_ if exists
4239                                    if (babModel_) {
4240                                        babModel_->setProblemStatus(0);
4241                                        babModel_->setSecondaryStatus(1);
4242                                    }
4243                                    break;
4244                                }
4245                                si->resolve();
4246#elif CBC_OTHER_SOLVER==1
4247#endif
4248                            }
4249                            if (debugValues) {
4250                                // for debug
4251                                std::string problemName ;
4252                                babModel_->solver()->getStrParam(OsiProbName, problemName) ;
4253                                babModel_->solver()->activateRowCutDebugger(problemName.c_str()) ;
4254                                twomirGen.probname_ = CoinStrdup(problemName.c_str());
4255                                // checking seems odd
4256                                //redsplitGen.set_given_optsol(babModel_->solver()->getRowCutDebuggerAlways()->optimalSolution(),
4257                                //                         babModel_->getNumCols());
4258                            }
4259                            int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
4260                            //#ifdef COIN_HAS_ASL
4261#ifndef JJF_ONE
4262                            // If linked then see if expansion wanted
4263                            {
4264                                OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel_->solver());
4265                                int options = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() / 10000;
4266                                if (solver3 || (options&16) != 0) {
4267                                    if (options) {
4268                                        /*
4269                                          1 - force mini branch and bound
4270                                          2 - set priorities high on continuous
4271                                          4 - try adding OA cuts
4272                                          8 - try doing quadratic linearization
4273                                          16 - try expanding knapsacks
4274                                        */
4275                                        if ((options&16)) {
4276                                            int numberColumns = saveCoinModel.numberColumns();
4277                                            int numberRows = saveCoinModel.numberRows();
4278                                            whichColumn = new int[numberColumns];
4279                                            knapsackStart = new int[numberRows+1];
4280                                            knapsackRow = new int[numberRows];
4281                                            numberKnapsack = 10000;
4282                                            int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
4283                                            int extra2 = parameters_[whichParam(CBC_PARAM_INT_EXTRA2, numberParameters_, parameters_)].intValue();
4284                                            int logLevel = parameters_[log].intValue();
4285                                            OsiSolverInterface * solver = expandKnapsack(saveCoinModel, whichColumn, knapsackStart,
4286                                                                          knapsackRow, numberKnapsack,
4287                                                                          storedAmpl, logLevel, extra1, extra2,
4288                                                                          saveTightenedModel);
4289                                            if (solver) {
4290#ifndef CBC_OTHER_SOLVER
4291                                                clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
4292                                                assert (clpSolver);
4293                                                lpSolver = clpSolver->getModelPtr();
4294#endif
4295                                                babModel_->assignSolver(solver);
4296                                                testOsiOptions = 0;
4297                                                // allow gomory
4298                                                complicatedInteger = 0;
4299#ifdef COIN_HAS_ASL
4300                                                // Priorities already done
4301                                                free(info.priorities);
4302                                                info.priorities = NULL;
4303#endif
4304                                            } else {
4305                                                numberKnapsack = 0;
4306                                                delete [] whichColumn;
4307                                                delete [] knapsackStart;
4308                                                delete [] knapsackRow;
4309                                                whichColumn = NULL;
4310                                                knapsackStart = NULL;
4311                                                knapsackRow = NULL;
4312                                            }
4313                                        }
4314                                    }
4315                                }
4316                            }
4317#endif
4318                            if (useCosts && testOsiOptions < 0) {
4319                                int numberColumns = babModel_->getNumCols();
4320                                int * sort = new int[numberColumns];
4321                                double * dsort = new double[numberColumns];
4322                                int * priority = new int [numberColumns];
4323                                const double * objective = babModel_->getObjCoefficients();
4324                                const double * lower = babModel_->getColLower() ;
4325                                const double * upper = babModel_->getColUpper() ;
4326                                const CoinPackedMatrix * matrix = babModel_->solver()->getMatrixByCol();
4327                                const int * columnLength = matrix->getVectorLengths();
4328                                int iColumn;
4329                                int n = 0;
4330                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4331                                    if (babModel_->isInteger(iColumn)) {
4332                                        sort[n] = n;
4333                                        if (useCosts == 1)
4334                                            dsort[n++] = -fabs(objective[iColumn]);
4335                                        else if (useCosts == 2)
4336                                            dsort[n++] = iColumn;
4337                                        else if (useCosts == 3)
4338                                            dsort[n++] = upper[iColumn] - lower[iColumn];
4339                                        else if (useCosts == 4)
4340                                            dsort[n++] = -(upper[iColumn] - lower[iColumn]);
4341                                        else if (useCosts == 5)
4342                                            dsort[n++] = -columnLength[iColumn];
4343                                        else if (useCosts == 6)
4344                                            dsort[n++] = (columnLength[iColumn]==1) ? -1.0 : 0.0;
4345                                        else if (useCosts == 7)
4346                                            dsort[n++] = (objective[iColumn]) ? -1.0 : 0.0;
4347                                    }
4348                                }
4349                                CoinSort_2(dsort, dsort + n, sort);
4350                                int level = 0;
4351                                double last = -1.0e100;
4352                                for (int i = 0; i < n; i++) {
4353                                    int iPut = sort[i];
4354                                    if (dsort[i] != last) {
4355                                        level++;
4356                                        last = dsort[i];
4357                                    }
4358                                    priority[iPut] = level;
4359                                }
4360                                if(newPriorities ) {
4361                                  // get rid of
4362                                  delete [] newPriorities;
4363                                  newPriorities = NULL;
4364                                }
4365                                babModel_->passInPriorities( priority, false);
4366                                integersOK = true;
4367                                delete [] priority;
4368                                delete [] sort;
4369                                delete [] dsort;
4370                            }
4371                            // Set up heuristics
4372                            doHeuristics(babModel_, ((!miplib) ? 1 : 10), parameters_,
4373                                         numberParameters_, noPrinting_, initialPumpTune);
4374                            if (!miplib) {
4375                                if (parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].currentOptionAsInteger()) {
4376                                    CbcTreeLocal localTree(babModel_, NULL, 10, 0, 0, 10000, 2000);
4377                                    babModel_->passInTreeHandler(localTree);
4378                                }
4379                            }
4380                            if (type == CBC_PARAM_ACTION_MIPLIB) {
4381                                if (babModel_->numberStrong() == 5 && babModel_->numberBeforeTrust() == 5)
4382                                    babModel_->setNumberBeforeTrust(10);
4383                            }
4384                            int experimentFlag = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
4385                                                             parameters_)].intValue();
4386                            int strategyFlag = parameters_[whichParam(CBC_PARAM_INT_STRATEGY, numberParameters_,
4387                                                           parameters_)].intValue();
4388                            int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag);
4389                            // add cut generators if wanted
4390                            int switches[30];
4391                            int accuracyFlag[30];
4392                            char doAtEnd[30];
4393                            memset(doAtEnd,0,30);
4394                            int numberGenerators = 0;
4395                            int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1};
4396                            int maximumSlowPasses = 
4397                              parameters_[whichParam(CBC_PARAM_INT_MAX_SLOW_CUTS, 
4398                                                     numberParameters_, parameters_)].intValue();
4399                            if (probingAction) {
4400                                int numberColumns = babModel_->solver()->getNumCols();
4401                                if (probingAction > 7) {
4402                                    probingGen.setMaxElements(numberColumns);
4403                                    probingGen.setMaxElementsRoot(numberColumns);
4404                                }
4405                                probingGen.setMaxProbeRoot(CoinMin(2000, numberColumns));
4406                                probingGen.setMaxProbeRoot(123);
4407                                probingGen.setMaxProbe(123);
4408                                probingGen.setMaxLookRoot(20);
4409                                if (probingAction == 7 || probingAction == 9)
4410                                    probingGen.setRowCuts(-3); // strengthening etc just at root
4411                                if (probingAction == 8 || probingAction == 9) {
4412                                    // Number of unsatisfied variables to look at
4413                                    probingGen.setMaxProbeRoot(numberColumns);
4414                                    probingGen.setMaxProbe(numberColumns);
4415                                    // How far to follow the consequences
4416                                    probingGen.setMaxLook(50);
4417                                    probingGen.setMaxLookRoot(50);
4418                                }
4419                                if (probingAction == 10) {
4420                                    probingGen.setMaxPassRoot(2);
4421                                    probingGen.setMaxProbeRoot(numberColumns);
4422                                    probingGen.setMaxLookRoot(100);
4423                                }
4424                                // If 5 then force on
4425                                int iAction = translate[probingAction];
4426                                if (probingAction == 5)
4427                                    iAction = 1;
4428                                babModel_->addCutGenerator(&probingGen, iAction, "Probing");
4429                                accuracyFlag[numberGenerators] = 5;
4430                                switches[numberGenerators++] = 0;
4431                            }
4432                            if (gomoryAction && (complicatedInteger != 1 ||
4433                                                 (gomoryAction == 1 || gomoryAction >= 4))) {
4434                                // try larger limit
4435                                int numberColumns = babModel_->getNumCols();
4436                                if (gomoryAction == 7) {
4437                                    gomoryAction = 4;
4438                                    gomoryGen.setLimitAtRoot(numberColumns);
4439                                    gomoryGen.setLimit(numberColumns);
4440                                } else if (gomoryAction == 8) {
4441                                    gomoryAction = 3;
4442                                    gomoryGen.setLimitAtRoot(numberColumns);
4443                                    gomoryGen.setLimit(200);
4444                                } else if (numberColumns > 5000) {
4445                                    //#define MORE_CUTS2
4446#ifdef MORE_CUTS2
4447                                    // try larger limit
4448                                    gomoryGen.setLimitAtRoot(numberColumns);
4449                                    gomoryGen.setLimit(200);
4450#else
4451                                    gomoryGen.setLimitAtRoot(2000);
4452                                    //gomoryGen.setLimit(200);
4453#endif
4454                                } else {
4455#ifdef MORE_CUTS2
4456                                    // try larger limit
4457                                    gomoryGen.setLimitAtRoot(numberColumns);
4458                                    gomoryGen.setLimit(200);
4459#endif
4460                                }
4461                                int cutLength =
4462                                    parameters_[whichParam(CBC_PARAM_INT_CUTLENGTH, numberParameters_, parameters_)].intValue();
4463                                if (cutLength != -1) {
4464                                    gomoryGen.setLimitAtRoot(cutLength);
4465                                    if (cutLength < 10000000) {
4466                                        gomoryGen.setLimit(cutLength);
4467                                    } else {
4468                                        gomoryGen.setLimit(cutLength % 10000000);
4469                                    }
4470                                }
4471                                int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
4472                                int gType = translate[gomoryAction];
4473                                if (!laGomory) {
4474                                  // Normal
4475                                  babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory");
4476                                  accuracyFlag[numberGenerators] = 3;
4477                                  switches[numberGenerators++] = 0;
4478                                } else {
4479                                  laGomory--;
4480                                  int type = (laGomory % 3)+1;
4481                                  int when = laGomory/3;
4482                                  char atEnd = (when<2) ? 1 : 0;
4483                                  int gomoryTypeMajor = 10;
4484                                  if (when<3) {
4485                                    // normal as well
4486                                    babModel_->addCutGenerator(&gomoryGen, gType, "Gomory");
4487                                    accuracyFlag[numberGenerators] = 3;
4488                                    switches[numberGenerators++] = 0;
4489                                    if (when==2)
4490                                      gomoryTypeMajor=20;
4491                                  } else {
4492                                    when--; // so on
4493                                    gomoryTypeMajor=20;
4494                                  }
4495                                  if (!when)
4496                                    gType=-99; // root
4497                                  gomoryGen.passInOriginalSolver(babModel_->solver());
4498                                  if ((type&1) !=0) {
4499                                    // clean
4500                                    gomoryGen.setGomoryType(gomoryTypeMajor+1);
4501                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1");
4502                                    accuracyFlag[numberGenerators] = 3;
4503                                    doAtEnd[numberGenerators]=atEnd;
4504                                    if (atEnd) {
4505                                      babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4506                                      babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4507                                    }
4508                                    switches[numberGenerators++] = 0;
4509                                  }
4510                                  if ((type&2) !=0) {
4511                                    // simple
4512                                    gomoryGen.setGomoryType(gomoryTypeMajor+2);
4513                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2");
4514                                    accuracyFlag[numberGenerators] = 3;
4515                                    doAtEnd[numberGenerators]=atEnd;
4516                                    if (atEnd) {
4517                                      babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4518                                      babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4519                                    }
4520                                    switches[numberGenerators++] = 0;
4521                                  }
4522                                }
4523                            }
4524#ifdef CLIQUE_ANALYSIS
4525                            if (miplib && !storedAmpl.sizeRowCuts()) {
4526                                printf("looking at probing\n");
4527                                babModel_->addCutGenerator(&storedAmpl, 1, "Stored");
4528                            }
4529#endif
4530                            if (knapsackAction) {
4531                                babModel_->addCutGenerator(&knapsackGen, translate[knapsackAction], "Knapsack");
4532                                accuracyFlag[numberGenerators] = 1;
4533                                switches[numberGenerators++] = -2;
4534                            }
4535                            if (redsplitAction && !complicatedInteger) {
4536                                babModel_->addCutGenerator(&redsplitGen, translate[redsplitAction], "Reduce-and-split");
4537                                accuracyFlag[numberGenerators] = 5;
4538                                // slow ? - just do a few times
4539                                if (redsplitAction!=1) {
4540                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(maximumSlowPasses);
4541                                  babModel_->cutGenerator(numberGenerators)->setHowOften(10);
4542                                }
4543                                switches[numberGenerators++] = 1;
4544                            }
4545                            if (redsplit2Action && !complicatedInteger) {
4546                                int maxLength=256;
4547                                if (redsplit2Action>2) {
4548                                  redsplit2Action-=2;
4549                                  maxLength=COIN_INT_MAX;
4550                                }
4551                                CglRedSplit2Param & parameters = redsplit2Gen.getParam();
4552                                parameters.setMaxNonzeroesTab(maxLength);
4553                                babModel_->addCutGenerator(&redsplit2Gen, translate[redsplit2Action], "Reduce-and-split(2)");
4554                                accuracyFlag[numberGenerators] = 5;
4555                                // slow ? - just do a few times
4556                                if (redsplit2Action!=1) {
4557                                  babModel_->cutGenerator(numberGenerators)->setHowOften(maximumSlowPasses);
4558                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(maximumSlowPasses);
4559                                  babModel_->cutGenerator(numberGenerators)->setHowOften(5);
4560                                }
4561                               
4562                                switches[numberGenerators++] = 1;
4563                            }
4564                            if (GMIAction && !complicatedInteger) {
4565                                if (GMIAction>5) {
4566                                  // long
4567                                  GMIAction-=5;
4568                                  CglGMIParam & parameters = GMIGen.getParam();
4569                                  parameters.setMaxSupportRel(1.0);
4570                                }
4571                                babModel_->addCutGenerator(&GMIGen, translate[GMIAction], "Gomory(2)");
4572                                if (GMIAction==5) {
4573                                  // just at end and root
4574                                  GMIAction=2;
4575                                  doAtEnd[numberGenerators]=1;
4576                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4577                                  babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4578                                }
4579                                accuracyFlag[numberGenerators] = 5;
4580                                switches[numberGenerators++] = 0;
4581                            }
4582                            if (cliqueAction) {
4583                                babModel_->addCutGenerator(&cliqueGen, translate[cliqueAction], "Clique");
4584                                accuracyFlag[numberGenerators] = 0;
4585                                switches[numberGenerators++] = 0;
4586                            }
4587                            if (mixedAction) {
4588                                babModel_->addCutGenerator(&mixedGen, translate[mixedAction], "MixedIntegerRounding2");
4589                                accuracyFlag[numberGenerators] = 2;
4590                                switches[numberGenerators++] = 0;
4591                            }
4592                            if (flowAction) {
4593                                babModel_->addCutGenerator(&flowGen, translate[flowAction], "FlowCover");
4594                                accuracyFlag[numberGenerators] = 2;
4595                                switches[numberGenerators++] = 1;
4596                            }
4597                            if (twomirAction && (complicatedInteger != 1 ||
4598                                                 (twomirAction == 1 || twomirAction >= 4))) {
4599                                // try larger limit
4600                                int numberColumns = babModel_->getNumCols();
4601                                if (twomirAction == 7) {
4602                                    twomirAction = 4;
4603                                    twomirGen.setMaxElements(numberColumns);
4604                                } else if (numberColumns > 5000 && twomirAction == 4) {
4605                                    twomirGen.setMaxElements(2000);
4606                                }
4607                                int laTwomir = parameters_[whichParam(CBC_PARAM_STR_LATWOMIRCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
4608                                int twomirType = translate[twomirAction];
4609                                if (!laTwomir) {
4610                                  // Normal
4611                                  babModel_->addCutGenerator(&twomirGen, translate[twomirAction], "TwoMirCuts");
4612                                  accuracyFlag[numberGenerators] = 4;
4613                                  switches[numberGenerators++] = 1;
4614                                } else {
4615                                  laTwomir--;
4616                                  int type = (laTwomir % 3)+1;
4617                                  int when = laTwomir/3;
4618                                  char atEnd = (when<2) ? 1 : 0;
4619                                  int twomirTypeMajor = 10;
4620                                  if (when<3) {
4621                                    // normal as well
4622                                    babModel_->addCutGenerator(&twomirGen, translate[twomirAction], "TwoMirCuts");
4623                                    accuracyFlag[numberGenerators] = 4;
4624                                    switches[numberGenerators++] = 1;
4625                                    if (when==2)
4626                                      twomirTypeMajor=10;
4627                                  } else {
4628                                    when--; // so on
4629                                    twomirTypeMajor=20;
4630                                  }
4631                                  if (!when)
4632                                    twomirType=-99; // root
4633                                  twomirGen.passInOriginalSolver(babModel_->solver());
4634                                  if ((type&1) !=0) {
4635                                    // clean
4636                                    twomirGen.setTwomirType(twomirTypeMajor+1);
4637                                    babModel_->addCutGenerator(&twomirGen, twomirType, "TwoMirCutsL1");
4638                                    accuracyFlag[numberGenerators] = 4;
4639                                    doAtEnd[numberGenerators]=atEnd;
4640                                    switches[numberGenerators++] = atEnd ? 0 : 1;
4641                                  }
4642                                  if ((type&2) !=0) {
4643                                    // simple
4644                                    twomirGen.setTwomirType(twomirTypeMajor+2);
4645                                    babModel_->addCutGenerator(&twomirGen, twomirType, "TwoMirCutsL2");
4646                                    accuracyFlag[numberGenerators] = 4;
4647                                    doAtEnd[numberGenerators]=atEnd;
4648                                    switches[numberGenerators++] = atEnd ? 0 : 1;
4649                                  }
4650                                }
4651                            }
4652#ifndef DEBUG_MALLOC
4653                            if (landpAction) {
4654                                babModel_->addCutGenerator(&landpGen, translate[landpAction], "LiftAndProject");
4655                                accuracyFlag[numberGenerators] = 5;
4656                                // slow ? - just do a few times
4657                                if (landpAction!=1) {
4658                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(maximumSlowPasses);
4659                                  babModel_->cutGenerator(numberGenerators)->setHowOften(10);
4660                                }
4661                                switches[numberGenerators++] = 1;
4662                            }
4663#endif
4664                            if (residualCapacityAction) {
4665                                babModel_->addCutGenerator(&residualCapacityGen, translate[residualCapacityAction], "ResidualCapacity");
4666                                accuracyFlag[numberGenerators] = 5;
4667                                switches[numberGenerators++] = 1;
4668                            }
4669                            if (zerohalfAction) {
4670                                if (zerohalfAction > 4) {
4671                                    //zerohalfAction -=4;
4672                                    zerohalfGen.setFlags(1);
4673                                }
4674                                babModel_->addCutGenerator(&zerohalfGen, translate[zerohalfAction], "ZeroHalf");
4675                                accuracyFlag[numberGenerators] = 5;
4676                                switches[numberGenerators++] = 2;
4677                            }
4678                            if (dominatedCuts)
4679                                babModel_->setSpecialOptions(babModel_->specialOptions() | 64);
4680                            // Say we want timings
4681                            numberGenerators = babModel_->numberCutGenerators();
4682                            int iGenerator;
4683                            int cutDepth =
4684                                parameters_[whichParam(CBC_PARAM_INT_CUTDEPTH, numberParameters_, parameters_)].intValue();
4685                            for (iGenerator = 0; iGenerator < numberGenerators; iGenerator++) {
4686                                CbcCutGenerator * generator = babModel_->cutGenerator(iGenerator);
4687                                int howOften = generator->howOften();
4688                                if (howOften == -98 || howOften == -99 || generator->maximumTries()>0)
4689                                    generator->setSwitchOffIfLessThan(switches[iGenerator]);
4690                                // Use if any at root as more likely later and fairly cheap
4691                                //if (switches[iGenerator]==-2)
4692                                //generator->setWhetherToUse(true);
4693                                generator->setInaccuracy(accuracyFlag[iGenerator]);
4694                                if (doAtEnd[iGenerator]) {
4695                                    generator->setWhetherCallAtEnd(true);
4696                                    //generator->setMustCallAgain(true);
4697                                }
4698                                generator->setTiming(true);
4699                                if (cutDepth >= 0)
4700                                    generator->setWhatDepth(cutDepth) ;
4701                            }
4702                            // Could tune more
4703                            if (!miplib) {
4704                                double minimumDrop =
4705                                    fabs(babModel_->solver()->getObjValue()) * 1.0e-5 + 1.0e-5;
4706                                babModel_->setMinimumDrop(CoinMin(5.0e-2, minimumDrop));
4707                                if (cutPass == -1234567) {
4708                                    if (babModel_->getNumCols() < 500)
4709                                        babModel_->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
4710                                    else if (babModel_->getNumCols() < 5000)
4711                                        babModel_->setMaximumCutPassesAtRoot(100); // use minimum drop
4712                                    else
4713                                        babModel_->setMaximumCutPassesAtRoot(20);
4714                                } else {
4715                                    babModel_->setMaximumCutPassesAtRoot(cutPass);
4716                                }
4717                                if (cutPassInTree == -1234567)
4718                                    babModel_->setMaximumCutPasses(4);
4719                                else
4720                                    babModel_->setMaximumCutPasses(cutPassInTree);
4721                            } else if (cutPass != -1234567) {
4722                                babModel_->setMaximumCutPassesAtRoot(cutPass);
4723                            }
4724                            // Do more strong branching if small
4725                            //if (babModel_->getNumCols()<5000)
4726                            //babModel_->setNumberStrong(20);
4727                            // Switch off strong branching if wanted
4728                            //if (babModel_->getNumCols()>10*babModel_->getNumRows())
4729                            //babModel_->setNumberStrong(0);
4730                            if (!noPrinting_) {
4731                                int iLevel = parameters_[log].intValue();
4732                                if (iLevel < 0) {
4733                                    if (iLevel > -10) {
4734                                        babModel_->setPrintingMode(1);
4735                                    } else {
4736                                        babModel_->setPrintingMode(2);
4737                                        iLevel += 10;
4738                                        parameters_[log].setIntValue(iLevel);
4739                                    }
4740                                    iLevel = -iLevel;
4741                                }
4742                                babModel_->messageHandler()->setLogLevel(iLevel);
4743                                if (babModel_->getNumCols() > 2000 || babModel_->getNumRows() > 1500 ||
4744                                        babModel_->messageHandler()->logLevel() > 1)
4745                                    babModel_->setPrintFrequency(100);
4746                            }
4747
4748                            babModel_->solver()->setIntParam(OsiMaxNumIterationHotStart,
4749                                                             parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].intValue());
4750#ifndef CBC_OTHER_SOLVER
4751                            OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
4752                            // go faster stripes
4753                            if ((osiclp