source: stable/2.7/Cbc/src/CbcSolver.cpp

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

don't attempt redefine

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