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

Last change on this file since 1573 was 1573, checked in by lou, 8 years ago

Change to EPL license notice.

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