source: stable/2.6/Cbc/src/CbcSolver.cpp @ 1615

Last change on this file since 1615 was 1615, checked in by tkr, 8 years ago

Merging changesets 1539, 1540, 1555, 1556, 1557, and 1558 from trunk

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