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

Last change on this file since 1656 was 1656, checked in by forrest, 8 years ago

allow end cuts and lagomory

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