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

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

merge r1773 and r1775 from trunk

File size: 504.5 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#define CBCMAXPARAMETERS 200
1105static CbcOrClpParam parameters[CBCMAXPARAMETERS];
1106static int numberParameters = 0 ;
1107CglPreProcess * cbcPreProcessPointer=NULL;
1108
1109int CbcClpUnitTest (const CbcModel & saveModel,
1110                    const std::string& dirMiplib, int testSwitch,
1111                    const double * stuff);
1112
1113int CbcMain1 (int argc, const char *argv[],
1114              CbcModel  & model)
1115{
1116    return CbcMain1(argc, argv, model, dummyCallBack);
1117}
1118
1119
1120/*
1121  Meaning of whereFrom:
1122    1 after initial solve by dualsimplex etc
1123    2 after preprocessing
1124    3 just before branchAndBound (so user can override)
1125    4 just after branchAndBound (before postprocessing)
1126    5 after postprocessing
1127    6 after a user called heuristic phase
1128*/
1129
1130int CbcMain1 (int argc, const char *argv[],
1131              CbcModel  & model,
1132              int callBack(CbcModel * currentSolver, int whereFrom))
1133{
1134    CbcOrClpParam * parameters_ = parameters;
1135    int numberParameters_ = numberParameters;
1136    CbcModel & model_ = model;
1137#ifdef CBC_USE_INITIAL_TIME
1138    if (model_.useElapsedTime())
1139      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1140    else
1141      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1142#endif
1143    CbcModel * babModel_ = NULL;
1144    int returnMode = 1;
1145    CbcOrClpRead_mode = 1;
1146    int statusUserFunction_[1];
1147    int numberUserFunctions_ = 1; // to allow for ampl
1148    // Statistics
1149    double statistics_seconds = 0.0, statistics_obj = 0.0;
1150    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1151    CoinWallclockTime();
1152    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1153    double statistics_cut_time = 0.0;
1154    int statistics_nodes = 0, statistics_iterations = 0;
1155    int statistics_nrows = 0, statistics_ncols = 0;
1156    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1157    std::string statistics_result;
1158    int * statistics_number_cuts = NULL;
1159    const char ** statistics_name_generators = NULL;
1160    int statistics_number_generators = 0;
1161    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1162    /* Note
1163       This is meant as a stand-alone executable to do as much of coin as possible.
1164       It should only have one solver known to it.
1165    */
1166    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1167    generalMessageHandler->setPrefix(false);
1168#ifndef CBC_OTHER_SOLVER
1169    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1170    assert (originalSolver);
1171    // Move handler across if not default
1172    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1173        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1174    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1175    char generalPrint[10000];
1176    if (originalSolver->getModelPtr()->logLevel() == 0)
1177        noPrinting = true;
1178#elif CBC_OTHER_SOLVER==1
1179    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1180    assert (originalSolver);
1181    OsiClpSolverInterface dummySolver;
1182    OsiCpxSolverInterface * clpSolver = originalSolver;
1183    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1184    char generalPrint[10000];
1185    noPrinting = true;
1186#endif
1187    bool noPrinting_ = noPrinting;
1188    // Say not in integer
1189    int integerStatus = -1;
1190    // Say no resolve after cuts
1191    model_.setResolveAfterTakeOffCuts(false);
1192    // see if log in list
1193    for (int i = 1; i < argc; i++) {
1194        if (!strncmp(argv[i], "log", 3)) {
1195            const char * equals = strchr(argv[i], '=');
1196            if (equals && atoi(equals + 1) != 0)
1197                noPrinting_ = false;
1198            else
1199                noPrinting_ = true;
1200            break;
1201        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1202            if (atoi(argv[i+1]) != 0)
1203                noPrinting_ = false;
1204            else
1205                noPrinting_ = true;
1206            break;
1207        }
1208    }
1209    double time0;
1210    double time0Elapsed = CoinGetTimeOfDay();
1211    {
1212        double time1 = CoinCpuTime(), time2;
1213        time0 = time1;
1214        double time1Elapsed = time0Elapsed;
1215        bool goodModel = (originalSolver->getNumCols()) ? true : false;
1216
1217        // register signal handler
1218        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
1219#if CBC_QUIET < 2
1220        signal(SIGINT, signal_handler);
1221#endif
1222        // Set up all non-standard stuff
1223        int cutPass = -1234567;
1224        int cutPassInTree = -1234567;
1225        int tunePreProcess = 0;
1226        int testOsiParameters = -1;
1227        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1228        int complicatedInteger = 0;
1229        OsiSolverInterface * solver = model_.solver();
1230        if (noPrinting_)
1231            setCbcOrClpPrinting(false);
1232#ifndef CBC_OTHER_SOLVER
1233        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1234        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1235        if (noPrinting_) {
1236            lpSolver->setLogLevel(0);
1237        }
1238#else
1239        ClpSimplex * lpSolver = NULL;
1240#endif
1241        // For priorities etc
1242        int * priorities = NULL;
1243        int * branchDirection = NULL;
1244        double * pseudoDown = NULL;
1245        double * pseudoUp = NULL;
1246        double * solutionIn = NULL;
1247        int * prioritiesIn = NULL;
1248        int numberSOS = 0;
1249        int * sosStart = NULL;
1250        int * sosIndices = NULL;
1251        char * sosType = NULL;
1252        double * sosReference = NULL;
1253        int * cut = NULL;
1254        int * sosPriority = NULL;
1255        CglStored storedAmpl;
1256        CoinModel * coinModel = NULL;
1257        CoinModel saveCoinModel;
1258        CoinModel saveTightenedModel;
1259        int * whichColumn = NULL;
1260        int * knapsackStart = NULL;
1261        int * knapsackRow = NULL;
1262        int numberKnapsack = 0;
1263#ifdef COIN_HAS_ASL
1264        ampl_info info;
1265        {
1266            memset(&info, 0, sizeof(info));
1267            if (argc > 2 && !strcmp(argv[2], "-AMPL")) {
1268                statusUserFunction_[0] = 1;
1269                // see if log in list
1270                noPrinting_ = true;
1271                for (int i = 1; i < argc; i++) {
1272                    if (!strncmp(argv[i], "log", 3)) {
1273                        const char * equals = strchr(argv[i], '=');
1274                        if (equals && atoi(equals + 1) > 0) {
1275                            noPrinting_ = false;
1276                            info.logLevel = atoi(equals + 1);
1277                            int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1278                            parameters_[log].setIntValue(info.logLevel);
1279                            // mark so won't be overWritten
1280                            info.numberRows = -1234567;
1281                            break;
1282                        }
1283                    }
1284                }
1285
1286                union {
1287                    void * voidModel;
1288                    CoinModel * model;
1289                } coinModelStart;
1290                coinModelStart.model = NULL;
1291                int returnCode = readAmpl(&info, argc, const_cast<char **>(argv), & coinModelStart.voidModel);
1292                coinModel = coinModelStart.model;
1293                if (returnCode)
1294                    return returnCode;
1295                CbcOrClpRead_mode = 2; // so will start with parameters
1296                // see if log in list (including environment)
1297                for (int i = 1; i < info.numberArguments; i++) {
1298                    if (!strcmp(info.arguments[i], "log")) {
1299                        if (i < info.numberArguments - 1 && atoi(info.arguments[i+1]) > 0)
1300                            noPrinting_ = false;
1301                        break;
1302                    }
1303                }
1304                if (noPrinting_) {
1305                    model_.messageHandler()->setLogLevel(0);
1306                    setCbcOrClpPrinting(false);
1307                }
1308                if (!noPrinting_)
1309                    printf("%d rows, %d columns and %d elements\n",
1310                           info.numberRows, info.numberColumns, info.numberElements);
1311#ifdef COIN_HAS_LINK
1312                if (!coinModel) {
1313#endif
1314                    solver->loadProblem(info.numberColumns, info.numberRows, info.starts,
1315                                        info.rows, info.elements,
1316                                        info.columnLower, info.columnUpper, info.objective,
1317                                        info.rowLower, info.rowUpper);
1318                    // take off cuts if ampl wants that
1319                    if (info.cut && 0) {
1320                        printf("AMPL CUTS OFF until global cuts fixed\n");
1321                        info.cut = NULL;
1322                    }
1323                    if (info.cut) {
1324                        int numberRows = info.numberRows;
1325                        int * whichRow = new int [numberRows];
1326                        // Row copy
1327                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1328                        const double * elementByRow = matrixByRow->getElements();
1329                        const int * column = matrixByRow->getIndices();
1330                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1331                        const int * rowLength = matrixByRow->getVectorLengths();
1332
1333                        const double * rowLower = solver->getRowLower();
1334                        const double * rowUpper = solver->getRowUpper();
1335                        int nDelete = 0;
1336                        for (int iRow = 0; iRow < numberRows; iRow++) {
1337                            if (info.cut[iRow]) {
1338                                whichRow[nDelete++] = iRow;
1339                                int start = rowStart[iRow];
1340                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1341                                                  rowLength[iRow], column + start, elementByRow + start);
1342                            }
1343                        }
1344                        solver->deleteRows(nDelete, whichRow);
1345                        delete [] whichRow;
1346                    }
1347#ifdef COIN_HAS_LINK
1348                } else {
1349#ifndef CBC_OTHER_SOLVER
1350                    // save
1351                    saveCoinModel = *coinModel;
1352                    // load from coin model
1353                    OsiSolverLink solver1;
1354                    OsiSolverInterface * solver2 = solver1.clone();
1355                    model_.assignSolver(solver2, false);
1356                    OsiSolverLink * si =
1357                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1358                    assert (si != NULL);
1359                    si->setDefaultMeshSize(0.001);
1360                    // need some relative granularity
1361                    si->setDefaultBound(100.0);
1362                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
1363                    if (dextra3)
1364                        si->setDefaultMeshSize(dextra3);
1365                    si->setDefaultBound(100000.0);
1366                    si->setIntegerPriority(1000);
1367                    si->setBiLinearPriority(10000);
1368                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
1369                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1370                    si->load(*model2, true, logLevel);
1371                    // redo
1372                    solver = model_.solver();
1373                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1374                    lpSolver = clpSolver->getModelPtr();
1375                    clpSolver->messageHandler()->setLogLevel(0) ;
1376                    testOsiParameters = 0;
1377                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
1378                    complicatedInteger = 1;
1379                    if (info.cut) {
1380                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1381                        abort();
1382                        int numberRows = info.numberRows;
1383                        int * whichRow = new int [numberRows];
1384                        // Row copy
1385                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1386                        const double * elementByRow = matrixByRow->getElements();
1387                        const int * column = matrixByRow->getIndices();
1388                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1389                        const int * rowLength = matrixByRow->getVectorLengths();
1390
1391                        const double * rowLower = solver->getRowLower();
1392                        const double * rowUpper = solver->getRowUpper();
1393                        int nDelete = 0;
1394                        for (int iRow = 0; iRow < numberRows; iRow++) {
1395                            if (info.cut[iRow]) {
1396                                whichRow[nDelete++] = iRow;
1397                                int start = rowStart[iRow];
1398                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1399                                                  rowLength[iRow], column + start, elementByRow + start);
1400                            }
1401                        }
1402                        solver->deleteRows(nDelete, whichRow);
1403                        // and special matrix
1404                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1405                        delete [] whichRow;
1406                    }
1407#endif
1408                }
1409#endif
1410                // If we had a solution use it
1411                if (info.primalSolution) {
1412                    solver->setColSolution(info.primalSolution);
1413                }
1414                // status
1415                if (info.rowStatus) {
1416                    unsigned char * statusArray = lpSolver->statusArray();
1417                    int i;
1418                    for (i = 0; i < info.numberColumns; i++)
1419                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1420                    statusArray += info.numberColumns;
1421                    for (i = 0; i < info.numberRows; i++)
1422                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1423                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1424                    solver->setWarmStart(basis);
1425                    delete basis;
1426                }
1427                freeArrays1(&info);
1428                // modify objective if necessary
1429                solver->setObjSense(info.direction);
1430                solver->setDblParam(OsiObjOffset, info.offset);
1431                if (info.offset) {
1432                    sprintf(generalPrint, "Ampl objective offset is %g",
1433                            info.offset);
1434                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1435                    << generalPrint
1436                    << CoinMessageEol;
1437                }
1438                // Set integer variables (unless nonlinear when set)
1439                if (!info.nonLinear) {
1440                    for (int i = info.numberColumns - info.numberIntegers;
1441                            i < info.numberColumns; i++)
1442                        solver->setInteger(i);
1443                }
1444                goodModel = true;
1445                // change argc etc
1446                argc = info.numberArguments;
1447                argv = const_cast<const char **>(info.arguments);
1448            }
1449        }
1450#endif
1451        // default action on import
1452        int allowImportErrors = 0;
1453        int keepImportNames = 1;
1454        int doIdiot = -1;
1455        int outputFormat = 2;
1456        int slpValue = -1;
1457        int cppValue = -1;
1458        int printOptions = 0;
1459        int printMode = 0;
1460        int presolveOptions = 0;
1461        int substitution = 3;
1462        int dualize = 3;
1463        int doCrash = 0;
1464        int doVector = 0;
1465        int doSprint = -1;
1466        int doScaling = 4;
1467        // set reasonable defaults
1468        int preSolve = 5;
1469        int preProcess = 4;
1470        bool useStrategy = false;
1471        bool preSolveFile = false;
1472        bool strongChanged = false;
1473        bool pumpChanged = false;
1474
1475        double djFix = 1.0e100;
1476        double tightenFactor = 0.0;
1477        const char dirsep =  CoinFindDirSeparator();
1478        std::string directory;
1479        std::string dirSample;
1480        std::string dirNetlib;
1481        std::string dirMiplib;
1482        if (dirsep == '/') {
1483            directory = "./";
1484            dirSample = "../../Data/Sample/";
1485            dirNetlib = "../../Data/Netlib/";
1486            dirMiplib = "../../Data/miplib3/";
1487        } else {
1488            directory = ".\\";
1489            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1490            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1491            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
1492        }
1493        std::string defaultDirectory = directory;
1494        std::string importFile = "";
1495        std::string exportFile = "default.mps";
1496        std::string importBasisFile = "";
1497        std::string importPriorityFile = "";
1498        std::string debugFile = "";
1499        std::string printMask = "";
1500        double * debugValues = NULL;
1501        int numberDebugValues = -1;
1502        int basisHasValues = 0;
1503        std::string exportBasisFile = "default.bas";
1504        std::string saveFile = "default.prob";
1505        std::string restoreFile = "default.prob";
1506        std::string solutionFile = "stdout";
1507        std::string solutionSaveFile = "solution.file";
1508        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1509        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1510#ifndef CBC_OTHER_SOLVER
1511        double normalIncrement = model_.getCutoffIncrement();;
1512#endif
1513        if (testOsiParameters >= 0) {
1514            // trying nonlinear - switch off some stuff
1515            preProcess = 0;
1516        }
1517        // Set up likely cut generators and defaults
1518        int nodeStrategy = 0;
1519        bool dominatedCuts = false;
1520        int doSOS = 1;
1521        int verbose = 0;
1522        CglGomory gomoryGen;
1523        // try larger limit
1524        gomoryGen.setLimitAtRoot(1000);
1525        gomoryGen.setLimit(50);
1526        // set default action (0=off,1=on,2=root)
1527        int gomoryAction = 3;
1528
1529        CglProbing probingGen;
1530        probingGen.setUsingObjective(1);
1531        probingGen.setMaxPass(1);
1532        probingGen.setMaxPassRoot(1);
1533        // Number of unsatisfied variables to look at
1534        probingGen.setMaxProbe(10);
1535        probingGen.setMaxProbeRoot(50);
1536        // How far to follow the consequences
1537        probingGen.setMaxLook(10);
1538        probingGen.setMaxLookRoot(50);
1539        probingGen.setMaxLookRoot(10);
1540        // Only look at rows with fewer than this number of elements
1541        probingGen.setMaxElements(200);
1542        probingGen.setMaxElementsRoot(300);
1543        probingGen.setRowCuts(3);
1544        // set default action (0=off,1=on,2=root)
1545        int probingAction = 1;
1546
1547        CglKnapsackCover knapsackGen;
1548        //knapsackGen.switchOnExpensive();
1549        //knapsackGen.setMaxInKnapsack(100);
1550        // set default action (0=off,1=on,2=root)
1551        int knapsackAction = 3;
1552
1553        CglRedSplit redsplitGen;
1554        //redsplitGen.setLimit(100);
1555        // set default action (0=off,1=on,2=root)
1556        // Off as seems to give some bad cuts
1557        int redsplitAction = 0;
1558
1559        CglFakeClique cliqueGen(NULL, false);
1560        //CglClique cliqueGen(false,true);
1561        cliqueGen.setStarCliqueReport(false);
1562        cliqueGen.setRowCliqueReport(false);
1563        cliqueGen.setMinViolation(0.1);
1564        // set default action (0=off,1=on,2=root)
1565        int cliqueAction = 3;
1566
1567        // maxaggr,multiply,criterion(1-3)
1568        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1569        // set default action (0=off,1=on,2=root)
1570        int mixedAction = 3;
1571
1572        CglFlowCover flowGen;
1573        // set default action (0=off,1=on,2=root)
1574        int flowAction = 3;
1575
1576        CglTwomir twomirGen;
1577        twomirGen.setMaxElements(250);
1578        // set default action (0=off,1=on,2=root)
1579        int twomirAction = 2;
1580#ifndef DEBUG_MALLOC
1581        CglLandP landpGen;
1582#endif
1583        // set default action (0=off,1=on,2=root)
1584        int landpAction = 0;
1585        CglResidualCapacity residualCapacityGen;
1586        // set default action (0=off,1=on,2=root)
1587        int residualCapacityAction = 0;
1588
1589#ifdef ZERO_HALF_CUTS
1590        CglZeroHalf zerohalfGen;
1591        //zerohalfGen.switchOnExpensive();
1592        // set default action (0=off,1=on,2=root)
1593        int zerohalfAction = 0;
1594#endif
1595
1596        // Stored cuts
1597        //bool storedCuts = false;
1598
1599        int useCosts = 0;
1600        // don't use input solution
1601        int useSolution = -1;
1602
1603        // total number of commands read
1604        int numberGoodCommands = 0;
1605        // Set false if user does anything advanced
1606        bool defaultSettings = true;
1607
1608        // Hidden stuff for barrier
1609        int choleskyType = 0;
1610        int gamma = 0;
1611        int scaleBarrier = 0;
1612        int doKKT = 0;
1613        int crossover = 2; // do crossover unless quadratic
1614        // For names
1615        int lengthName = 0;
1616        std::vector<std::string> rowNames;
1617        std::vector<std::string> columnNames;
1618        // Default strategy stuff
1619        {
1620            // try changing tolerance at root
1621#define MORE_CUTS
1622#ifdef MORE_CUTS
1623            gomoryGen.setAwayAtRoot(0.005);
1624            twomirGen.setAwayAtRoot(0.005);
1625            twomirGen.setAway(0.01);
1626            //twomirGen.setMirScale(1,1);
1627            //twomirGen.setTwomirScale(1,1);
1628            //twomirGen.setAMax(2);
1629#else
1630            gomoryGen.setAwayAtRoot(0.01);
1631            twomirGen.setAwayAtRoot(0.01);
1632            twomirGen.setAway(0.01);
1633#endif
1634            int iParam;
1635            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
1636            parameters_[iParam].setIntValue(3);
1637            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
1638            parameters_[iParam].setIntValue(30);
1639            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
1640            parameters_[iParam].setIntValue(1005043);
1641            initialPumpTune = 1005043;
1642            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
1643            parameters_[iParam].setIntValue(6);
1644            tunePreProcess = 6;
1645            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
1646            parameters_[iParam].setCurrentOption("on");
1647            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
1648            parameters_[iParam].setCurrentOption("on");
1649            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
1650            parameters_[iParam].setCurrentOption("on");
1651            probingAction = 1;
1652            parameters_[iParam].setCurrentOption("forceOnStrong");
1653            probingAction = 8;
1654        }
1655        std::string field;
1656#if CBC_QUIET == 0
1657        if (!noPrinting_) {
1658           sprintf(generalPrint,
1659                   "Welcome to the CBC MILP Solver \n");
1660            if (strcmp(CBC_VERSION, "trunk")){
1661               sprintf(generalPrint + strlen(generalPrint),
1662                       "Version: %s \n", CBC_VERSION);
1663            }else{
1664               sprintf(generalPrint + strlen(generalPrint),
1665                       "Version: Trunk (unstable) \n");
1666            }
1667            sprintf(generalPrint + strlen(generalPrint),
1668                    "Build Date: %s \n", __DATE__);
1669#ifdef CBC_SVN_REV
1670            sprintf(generalPrint + strlen(generalPrint),
1671                    "Revision Number: %d \n", CBC_SVN_REV);
1672#endif
1673            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1674            << generalPrint
1675            << CoinMessageEol;
1676            // Print command line
1677            if (argc > 1) {
1678                bool foundStrategy = false;
1679                sprintf(generalPrint, "command line - ");
1680                for (int i = 0; i < argc; i++) {
1681                    if (!argv[i])
1682                        break;
1683                    if (strstr(argv[i], "strat"))
1684                        foundStrategy = true;
1685                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1686                }
1687                if (!foundStrategy)
1688                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1689                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1690                << generalPrint
1691                << CoinMessageEol;
1692            }
1693        }
1694#endif
1695        while (1) {
1696            // next command
1697            field = CoinReadGetCommand(argc, argv);
1698            // Reset time
1699            time1 = CoinCpuTime();
1700            time1Elapsed = CoinGetTimeOfDay();
1701            // adjust field if has odd trailing characters
1702            char temp [200];
1703            strcpy(temp, field.c_str());
1704            int length = static_cast<int>(strlen(temp));
1705            for (int k = length - 1; k >= 0; k--) {
1706                if (temp[k] < ' ')
1707                    length--;
1708                else
1709                    break;
1710            }
1711            temp[length] = '\0';
1712            field = temp;
1713            // exit if null or similar
1714            if (!field.length()) {
1715                if (numberGoodCommands == 1 && goodModel) {
1716                    // we just had file name - do branch and bound
1717                    field = "branch";
1718                } else if (!numberGoodCommands) {
1719                    // let's give the sucker a hint
1720                    std::cout
1721                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1722                        << std::endl
1723                        << "Enter ? for list of commands or help" << std::endl;
1724                    field = "-";
1725                } else {
1726                    break;
1727                }
1728            }
1729
1730            // see if ? at end
1731            size_t numberQuery = 0;
1732            if (field != "?" && field != "???") {
1733                size_t length = field.length();
1734                size_t i;
1735                for (i = length - 1; i > 0; i--) {
1736                    if (field[i] == '?')
1737                        numberQuery++;
1738                    else
1739                        break;
1740                }
1741                field = field.substr(0, length - numberQuery);
1742            }
1743            // find out if valid command
1744            int iParam;
1745            int numberMatches = 0;
1746            int firstMatch = -1;
1747            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1748                int match = parameters_[iParam].matches(field);
1749                if (match == 1) {
1750                    numberMatches = 1;
1751                    firstMatch = iParam;
1752                    break;
1753                } else {
1754                    if (match && firstMatch < 0)
1755                        firstMatch = iParam;
1756                    numberMatches += match >> 1;
1757                }
1758            }
1759            if (iParam < numberParameters_ && !numberQuery) {
1760                // found
1761                CbcOrClpParam found = parameters_[iParam];
1762                CbcOrClpParameterType type = found.type();
1763                int valid;
1764                numberGoodCommands++;
1765                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
1766#ifndef CBC_USE_INITIAL_TIME
1767                  if (model_.useElapsedTime())
1768                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1769                  else
1770                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1771#endif
1772                    // check if any integers
1773#ifndef CBC_OTHER_SOLVER
1774#ifdef COIN_HAS_ASL
1775                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1776                        // SOS
1777                        numberSOS = info.numberSos;
1778                    }
1779#endif
1780                    lpSolver = clpSolver->getModelPtr();
1781                    if (!lpSolver->integerInformation() && !numberSOS &&
1782                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
1783                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
1784#endif
1785                }
1786                if (type == CBC_PARAM_GENERALQUERY) {
1787                    bool evenHidden = false;
1788                    int printLevel =
1789                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
1790                                               numberParameters_, parameters_)].currentOptionAsInteger();
1791                    int convertP[] = {2, 1, 0};
1792                    printLevel = convertP[printLevel];
1793                    if ((verbose&8) != 0) {
1794                        // even hidden
1795                        evenHidden = true;
1796                        verbose &= ~8;
1797                    }
1798#ifdef COIN_HAS_ASL
1799                    if (verbose < 4 && statusUserFunction_[0])
1800                        verbose += 4;
1801#endif
1802                    if (verbose < 4) {
1803                        std::cout << "In argument list keywords have leading - "
1804                                  ", -stdin or just - switches to stdin" << std::endl;
1805                        std::cout << "One command per line (and no -)" << std::endl;
1806                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
1807                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
1808                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
1809                        std::cout << "abcd value sets value" << std::endl;
1810                        std::cout << "Commands are:" << std::endl;
1811                    } else {
1812                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
1813                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
1814                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
1815                    }
1816                    int maxAcross = 10;
1817                    if ((verbose % 4) != 0)
1818                        maxAcross = 1;
1819                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
1820                    std::vector<std::string> types;
1821                    types.push_back("Double parameters:");
1822                    types.push_back("Branch and Cut double parameters:");
1823                    types.push_back("Integer parameters:");
1824                    types.push_back("Branch and Cut integer parameters:");
1825                    types.push_back("Keyword parameters:");
1826                    types.push_back("Branch and Cut keyword parameters:");
1827                    types.push_back("Actions or string parameters:");
1828                    types.push_back("Branch and Cut actions:");
1829                    int iType;
1830                    for (iType = 0; iType < 8; iType++) {
1831                        int across = 0;
1832                        int lengthLine = 0;
1833                        if ((verbose % 4) != 0)
1834                            std::cout << std::endl;
1835                        std::cout << types[iType] << std::endl;
1836                        if ((verbose&2) != 0)
1837                            std::cout << std::endl;
1838                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1839                            int type = parameters_[iParam].type();
1840                            //printf("%d type %d limits %d %d display %d\n",iParam,
1841                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
1842                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
1843                                    type >= limits[iType]
1844                                    && type < limits[iType+1]) {
1845                                // but skip if not useful for ampl (and in ampl mode)
1846                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
1847                                    continue;
1848                                if (!across) {
1849                                    if ((verbose&2) != 0)
1850                                        std::cout << "Command ";
1851                                }
1852                                int length = parameters_[iParam].lengthMatchName() + 1;
1853                                if (lengthLine + length > 80) {
1854                                    std::cout << std::endl;
1855                                    across = 0;
1856                                    lengthLine = 0;
1857                                }
1858                                std::cout << " " << parameters_[iParam].matchName();
1859                                lengthLine += length;
1860                                across++;
1861                                if (across == maxAcross) {
1862                                    across = 0;
1863                                    if ((verbose % 4) != 0) {
1864                                        // put out description as well
1865                                        if ((verbose&1) != 0)
1866                                            std::cout << " " << parameters_[iParam].shortHelp();
1867                                        std::cout << std::endl;
1868                                        if ((verbose&2) != 0) {
1869                                            std::cout << "---- description" << std::endl;
1870                                            parameters_[iParam].printLongHelp();
1871                                            std::cout << "----" << std::endl << std::endl;
1872                                        }
1873                                    } else {
1874                                        std::cout << std::endl;
1875                                    }
1876                                }
1877                            }
1878                        }
1879                        if (across)
1880                            std::cout << std::endl;
1881                    }
1882                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
1883                    std::cout << "Full list of commands is:" << std::endl;
1884                    int maxAcross = 5;
1885                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
1886                    std::vector<std::string> types;
1887                    types.push_back("Double parameters:");
1888                    types.push_back("Branch and Cut double parameters:");
1889                    types.push_back("Integer parameters:");
1890                    types.push_back("Branch and Cut integer parameters:");
1891                    types.push_back("Keyword parameters:");
1892                    types.push_back("Branch and Cut keyword parameters:");
1893                    types.push_back("Actions or string parameters:");
1894                    types.push_back("Branch and Cut actions:");
1895                    int iType;
1896                    for (iType = 0; iType < 8; iType++) {
1897                        int across = 0;
1898                        std::cout << types[iType] << "  ";
1899                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1900                            int type = parameters_[iParam].type();
1901                            if (type >= limits[iType]
1902                                    && type < limits[iType+1]) {
1903                                if (!across)
1904                                    std::cout << "  ";
1905                                std::cout << parameters_[iParam].matchName() << "  ";
1906                                across++;
1907                                if (across == maxAcross) {
1908                                    std::cout << std::endl;
1909                                    across = 0;
1910                                }
1911                            }
1912                        }
1913                        if (across)
1914                            std::cout << std::endl;
1915                    }
1916                } else if (type < 101) {
1917                    // get next field as double
1918                    double value = CoinReadGetDoubleField(argc, argv, &valid);
1919                    if (!valid) {
1920                        if (type < 51) {
1921                            int returnCode;
1922                            const char * message =
1923                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
1924                            if (!noPrinting_ && strlen(message)) {
1925                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1926                                << message
1927                                << CoinMessageEol;
1928                            }
1929                        } else if (type < 81) {
1930                            int returnCode;
1931                            const char * message =
1932                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
1933                            if (!noPrinting_ && strlen(message)) {
1934                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1935                                << message
1936                                << CoinMessageEol;
1937                            }
1938                        } else {
1939                            int returnCode;
1940                            const char * message =
1941                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
1942                            if (!noPrinting_ && strlen(message)) {
1943                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1944                                << message
1945                                << CoinMessageEol;
1946                            }
1947                            switch (type) {
1948                            case CBC_PARAM_DBL_DJFIX:
1949                                djFix = value;
1950#ifndef CBC_OTHER_SOLVER
1951                                if (goodModel && djFix < 1.0e20) {
1952                                    // do some fixing
1953                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
1954                                    clpSolver->initialSolve();
1955                                    lpSolver = clpSolver->getModelPtr();
1956                                    int numberColumns = lpSolver->numberColumns();
1957                                    int i;
1958                                    const char * type = lpSolver->integerInformation();
1959                                    double * lower = lpSolver->columnLower();
1960                                    double * upper = lpSolver->columnUpper();
1961                                    double * solution = lpSolver->primalColumnSolution();
1962                                    double * dj = lpSolver->dualColumnSolution();
1963                                    int numberFixed = 0;
1964                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
1965                                    if (dextra4)
1966                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
1967                                    for (i = 0; i < numberColumns; i++) {
1968                                        double djValue = dj[i];
1969                                        if (!type[i])
1970                                            djValue *= dextra4;
1971                                        if (type[i] || dextra4) {
1972                                            double value = solution[i];
1973                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
1974                                                solution[i] = lower[i];
1975                                                upper[i] = lower[i];
1976                                                numberFixed++;
1977                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
1978                                                solution[i] = upper[i];
1979                                                lower[i] = upper[i];
1980                                                numberFixed++;
1981                                            }
1982                                        }
1983                                    }
1984                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
1985                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1986                                    << generalPrint
1987                                    << CoinMessageEol;
1988                                }
1989#endif
1990                                break;
1991                            case CBC_PARAM_DBL_TIGHTENFACTOR:
1992                                tightenFactor = value;
1993                                if (!complicatedInteger)
1994                                    defaultSettings = false; // user knows what she is doing
1995                                break;
1996                            default:
1997                                break;
1998                            }
1999                        }
2000                    } else if (valid == 1) {
2001                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2002                                  parameters_[iParam].doubleValue() << std::endl;
2003                    } else {
2004                        std::cout << parameters_[iParam].name() << " has value " <<
2005                                  parameters_[iParam].doubleValue() << std::endl;
2006                    }
2007                } else if (type < 201) {
2008                    // get next field as int
2009                    int value = CoinReadGetIntField(argc, argv, &valid);
2010                    if (!valid) {
2011                        if (type < 151) {
2012                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
2013                                preSolve = value;
2014                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
2015                                doIdiot = value;
2016                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
2017                                doSprint = value;
2018                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
2019                                outputFormat = value;
2020                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
2021                                slpValue = value;
2022                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
2023                                cppValue = value;
2024                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
2025                                presolveOptions = value;
2026                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
2027                                printOptions = value;
2028                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
2029                                substitution = value;
2030                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
2031                                dualize = value;
2032                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
2033                                tunePreProcess = value;
2034                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
2035                                useSolution = value;
2036                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
2037                                verbose = value;
2038                            int returnCode;
2039                            const char * message =
2040                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2041                            if (!noPrinting_ && strlen(message)) {
2042                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2043                                << message
2044                                << CoinMessageEol;
2045                            }
2046                        } else {
2047                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
2048                                cutPass = value;
2049                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
2050                                cutPassInTree = value;
2051                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2052                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
2053                                strongChanged = true;
2054                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2055                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2056                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
2057                                pumpChanged = true;
2058                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
2059                                int addFlags=0;
2060                                if (value>=10) {
2061                                  addFlags = 1048576*(value/10);
2062                                  value = value % 10;
2063                                  parameters[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters, parameters)].setIntValue(value);
2064                                }
2065                                if (value >= 1) {
2066                                    int values[]={24003,280003,792003,24003,24003};
2067                                    if (value>=2&&value<=3) {
2068                                      // swap default diving
2069                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2070                                      parameters_[iParam].setCurrentOption("off");
2071                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2072                                      parameters_[iParam].setCurrentOption("on");
2073                                    }
2074                                    int extra4 = values[value-1]+addFlags;
2075                                    parameters[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters, parameters)].setIntValue(extra4);
2076                                    if (!noPrinting_) {
2077                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2078                                        << "switching on global root cuts for gomory and knapsack"
2079                                        << CoinMessageEol;
2080                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2081                                        << "using OSL factorization"
2082                                        << CoinMessageEol;
2083                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2084                                        << "extra options - -rens on -extra4 "
2085                                        <<extra4<<" -passc 1000!"
2086                                        << CoinMessageEol;
2087                                    }
2088                                    parameters[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters, parameters)].setCurrentOption("forceOnStrong");
2089                                    probingAction = 8;
2090                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2091                                    gomoryAction = 5;
2092                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2093                                    knapsackAction = 5;
2094                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
2095                                    lpSolver->factorization()->forceOtherFactorization(3);
2096                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
2097                                    parameters[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters, parameters)].setIntValue(1000);
2098                                    cutPass = 1000;
2099                                    parameters[whichParam(CBC_PARAM_STR_RENS, numberParameters, parameters)].setCurrentOption("on");
2100                                }
2101                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
2102                                if (value == 0) {
2103                                    gomoryGen.setAwayAtRoot(0.05);
2104                                    int iParam;
2105                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
2106                                    parameters_[iParam].setIntValue(-1);
2107                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
2108                                    parameters_[iParam].setIntValue(20);
2109                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
2110                                    parameters_[iParam].setIntValue(1003);
2111                                    initialPumpTune = 1003;
2112                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
2113                                    parameters_[iParam].setIntValue(-1);
2114                                    tunePreProcess = 0;
2115                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2116                                    parameters_[iParam].setCurrentOption("off");
2117                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
2118                                    parameters_[iParam].setCurrentOption("off");
2119                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
2120                                    parameters_[iParam].setCurrentOption("on");
2121                                    probingAction = 1;
2122                                }
2123                            }
2124                            int returnCode;
2125                            const char * message =
2126                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2127                            if (!noPrinting_ && strlen(message)) {
2128                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2129                                << message
2130                                << CoinMessageEol;
2131                            }
2132                        }
2133                    } else if (valid == 1) {
2134                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2135                                  parameters_[iParam].intValue() << std::endl;
2136                    } else {
2137                        std::cout << parameters_[iParam].name() << " has value " <<
2138                                  parameters_[iParam].intValue() << std::endl;
2139                    }
2140                } else if (type < 301) {
2141                    // one of several strings
2142                    std::string value = CoinReadGetString(argc, argv);
2143                    int action = parameters_[iParam].parameterOption(value);
2144                    if (action < 0) {
2145                        if (value != "EOL") {
2146                            // no match
2147                            parameters_[iParam].printOptions();
2148                        } else {
2149                            // print current value
2150                            std::cout << parameters_[iParam].name() << " has value " <<
2151                                      parameters_[iParam].currentOption() << std::endl;
2152                        }
2153                    } else {
2154                        const char * message =
2155                            parameters_[iParam].setCurrentOptionWithMessage(action);
2156                        if (!noPrinting_ && strlen(message)) {
2157                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2158                            << message
2159                            << CoinMessageEol;
2160                        }
2161                        // for now hard wired
2162                        switch (type) {
2163                        case CLP_PARAM_STR_DIRECTION:
2164                            if (action == 0)
2165                                lpSolver->setOptimizationDirection(1);
2166                            else if (action == 1)
2167                                lpSolver->setOptimizationDirection(-1);
2168                            else
2169                                lpSolver->setOptimizationDirection(0);
2170                            break;
2171                        case CLP_PARAM_STR_DUALPIVOT:
2172                            if (action == 0) {
2173                                ClpDualRowSteepest steep(3);
2174                                lpSolver->setDualRowPivotAlgorithm(steep);
2175                            } else if (action == 1) {
2176                                ClpDualRowDantzig dantzig;
2177                                //ClpDualRowSteepest dantzig(5);
2178                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2179                            } else if (action == 2) {
2180                                // partial steep
2181                                ClpDualRowSteepest steep(2);
2182                                lpSolver->setDualRowPivotAlgorithm(steep);
2183                            } else {
2184                                ClpDualRowSteepest steep;
2185                                lpSolver->setDualRowPivotAlgorithm(steep);
2186                            }
2187                            break;
2188                        case CLP_PARAM_STR_PRIMALPIVOT:
2189                            if (action == 0) {
2190                                ClpPrimalColumnSteepest steep(3);
2191                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2192                            } else if (action == 1) {
2193                                ClpPrimalColumnSteepest steep(0);
2194                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2195                            } else if (action == 2) {
2196                                ClpPrimalColumnDantzig dantzig;
2197                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2198                            } else if (action == 3) {
2199                                ClpPrimalColumnSteepest steep(4);
2200                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2201                            } else if (action == 4) {
2202                                ClpPrimalColumnSteepest steep(1);
2203                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2204                            } else if (action == 5) {
2205                                ClpPrimalColumnSteepest steep(2);
2206                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2207                            } else if (action == 6) {
2208                                ClpPrimalColumnSteepest steep(10);
2209                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2210                            }
2211                            break;
2212                        case CLP_PARAM_STR_SCALING:
2213                            lpSolver->scaling(action);
2214                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2215                            doScaling = action;
2216                            break;
2217                        case CLP_PARAM_STR_AUTOSCALE:
2218                            lpSolver->setAutomaticScaling(action != 0);
2219                            break;
2220                        case CLP_PARAM_STR_SPARSEFACTOR:
2221                            lpSolver->setSparseFactorization((1 - action) != 0);
2222                            break;
2223                        case CLP_PARAM_STR_BIASLU:
2224                            lpSolver->factorization()->setBiasLU(action);
2225                            break;
2226                        case CLP_PARAM_STR_PERTURBATION:
2227                            if (action == 0)
2228                                lpSolver->setPerturbation(50);
2229                            else
2230                                lpSolver->setPerturbation(100);
2231                            break;
2232                        case CLP_PARAM_STR_ERRORSALLOWED:
2233                            allowImportErrors = action;
2234                            break;
2235                        case CLP_PARAM_STR_INTPRINT:
2236                            printMode = action;
2237                            break;
2238                            //case CLP_PARAM_NOTUSED_ALGORITHM:
2239                            //algorithm  = action;
2240                            //defaultSettings=false; // user knows what she is doing
2241                            //abort();
2242                            //break;
2243                        case CLP_PARAM_STR_KEEPNAMES:
2244                            keepImportNames = 1 - action;
2245                            break;
2246                        case CLP_PARAM_STR_PRESOLVE:
2247                            if (action == 0)
2248                                preSolve = 5;
2249                            else if (action == 1)
2250                                preSolve = 0;
2251                            else if (action == 2)
2252                                preSolve = 10;
2253                            else
2254                                preSolveFile = true;
2255                            break;
2256                        case CLP_PARAM_STR_PFI:
2257                            lpSolver->factorization()->setForrestTomlin(action == 0);
2258                            break;
2259                        case CLP_PARAM_STR_FACTORIZATION:
2260                            lpSolver->factorization()->forceOtherFactorization(action);
2261                            break;
2262                        case CLP_PARAM_STR_CRASH:
2263                            doCrash = action;
2264                            break;
2265                        case CLP_PARAM_STR_VECTOR:
2266                            doVector = action;
2267                            break;
2268                        case CLP_PARAM_STR_MESSAGES:
2269                            lpSolver->messageHandler()->setPrefix(action != 0);
2270                            break;
2271                        case CLP_PARAM_STR_CHOLESKY:
2272                            choleskyType = action;
2273                            break;
2274                        case CLP_PARAM_STR_GAMMA:
2275                            gamma = action;
2276                            break;
2277                        case CLP_PARAM_STR_BARRIERSCALE:
2278                            scaleBarrier = action;
2279                            break;
2280                        case CLP_PARAM_STR_KKT:
2281                            doKKT = action;
2282                            break;
2283                        case CLP_PARAM_STR_CROSSOVER:
2284                            crossover = action;
2285                            break;
2286                        case CLP_PARAM_STR_TIME_MODE:
2287                            model_.setUseElapsedTime(action!=0);
2288                            break;
2289                        case CBC_PARAM_STR_SOS:
2290                            doSOS = action;
2291                            break;
2292                        case CBC_PARAM_STR_GOMORYCUTS:
2293                            defaultSettings = false; // user knows what she is doing
2294                            gomoryAction = action;
2295                            break;
2296                        case CBC_PARAM_STR_PROBINGCUTS:
2297                            defaultSettings = false; // user knows what she is doing
2298                            probingAction = action;
2299                            break;
2300                        case CBC_PARAM_STR_KNAPSACKCUTS:
2301                            defaultSettings = false; // user knows what she is doing
2302                            knapsackAction = action;
2303                            break;
2304                        case CBC_PARAM_STR_REDSPLITCUTS:
2305                            defaultSettings = false; // user knows what she is doing
2306                            redsplitAction = action;
2307                            break;
2308                        case CBC_PARAM_STR_CLIQUECUTS:
2309                            defaultSettings = false; // user knows what she is doing
2310                            cliqueAction = action;
2311                            break;
2312                        case CBC_PARAM_STR_FLOWCUTS:
2313                            defaultSettings = false; // user knows what she is doing
2314                            flowAction = action;
2315                            break;
2316                        case CBC_PARAM_STR_MIXEDCUTS:
2317                            defaultSettings = false; // user knows what she is doing
2318                            mixedAction = action;
2319                            break;
2320                        case CBC_PARAM_STR_TWOMIRCUTS:
2321                            defaultSettings = false; // user knows what she is doing
2322                            twomirAction = action;
2323                            break;
2324                        case CBC_PARAM_STR_LANDPCUTS:
2325                            defaultSettings = false; // user knows what she is doing
2326                            landpAction = action;
2327                            break;
2328                        case CBC_PARAM_STR_RESIDCUTS:
2329                            defaultSettings = false; // user knows what she is doing
2330                            residualCapacityAction = action;
2331                            break;
2332#ifdef ZERO_HALF_CUTS
2333                        case CBC_PARAM_STR_ZEROHALFCUTS:
2334                            defaultSettings = false; // user knows what she is doing
2335                            zerohalfAction = action;
2336                            break;
2337#endif
2338                        case CBC_PARAM_STR_ROUNDING:
2339                            defaultSettings = false; // user knows what she is doing
2340                            break;
2341                        case CBC_PARAM_STR_FPUMP:
2342                            defaultSettings = false; // user knows what she is doing
2343                            break;
2344                        case CBC_PARAM_STR_RINS:
2345                            break;
2346                        case CBC_PARAM_STR_DINS:
2347                            break;
2348                        case CBC_PARAM_STR_RENS:
2349                            break;
2350                        case CBC_PARAM_STR_CUTSSTRATEGY:
2351                            gomoryAction = action;
2352                            probingAction = action;
2353                            knapsackAction = action;
2354#ifdef ZERO_HALF_CUTS
2355                            zerohalfAction = action;
2356#endif
2357                            cliqueAction = action;
2358                            flowAction = action;
2359                            mixedAction = action;
2360                            twomirAction = action;
2361                            //landpAction = action;
2362                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2363                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2364                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2365                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2366                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2367                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2368                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2369#ifdef ZERO_HALF_CUTS
2370                            parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2371#endif
2372                            if (!action) {
2373                                redsplitAction = action;
2374                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2375                                landpAction = action;
2376                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2377                                residualCapacityAction = action;
2378                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2379                            }
2380                            break;
2381                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2382                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2383                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2384                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2385                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2386                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2387                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2388                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
2389                            break;
2390                        case CBC_PARAM_STR_GREEDY:
2391                        case CBC_PARAM_STR_DIVINGS:
2392                        case CBC_PARAM_STR_DIVINGC:
2393                        case CBC_PARAM_STR_DIVINGF:
2394                        case CBC_PARAM_STR_DIVINGG:
2395                        case CBC_PARAM_STR_DIVINGL:
2396                        case CBC_PARAM_STR_DIVINGP:
2397                        case CBC_PARAM_STR_DIVINGV:
2398                        case CBC_PARAM_STR_COMBINE:
2399                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2400                        case CBC_PARAM_STR_PIVOTANDFIX:
2401                        case CBC_PARAM_STR_RANDROUND:
2402                        case CBC_PARAM_STR_LOCALTREE:
2403                        case CBC_PARAM_STR_NAIVE:
2404                        case CBC_PARAM_STR_CPX:
2405                            defaultSettings = false; // user knows what she is doing
2406                            break;
2407                        case CBC_PARAM_STR_COSTSTRATEGY:
2408                            useCosts = action;
2409                            break;
2410                        case CBC_PARAM_STR_NODESTRATEGY:
2411                            nodeStrategy = action;
2412                            break;
2413                        case CBC_PARAM_STR_PREPROCESS:
2414                            preProcess = action;
2415                            break;
2416                        default:
2417                            //abort();
2418                            break;
2419                        }
2420                    }
2421                } else {
2422                    // action
2423                    if (type == CLP_PARAM_ACTION_EXIT) {
2424#ifdef COIN_HAS_ASL
2425                        if (statusUserFunction_[0]) {
2426                            if (info.numberIntegers || info.numberBinary) {
2427                                // integer
2428                            } else {
2429                                // linear
2430                            }
2431                            writeAmpl(&info);
2432                            freeArrays2(&info);
2433                            freeArgs(&info);
2434                        }
2435#endif
2436                        break; // stop all
2437                    }
2438                    switch (type) {
2439                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2440                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2441                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2442                    case CLP_PARAM_ACTION_BARRIER:
2443                        if (goodModel) {
2444                            // Say not in integer
2445                            integerStatus = -1;
2446                            double objScale =
2447                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
2448                            if (objScale != 1.0) {
2449                                int iColumn;
2450                                int numberColumns = lpSolver->numberColumns();
2451                                double * dualColumnSolution =
2452                                    lpSolver->dualColumnSolution();
2453                                ClpObjective * obj = lpSolver->objectiveAsObject();
2454                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2455                                double offset;
2456                                double * objective = obj->gradient(NULL, NULL, offset, true);
2457                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2458                                    dualColumnSolution[iColumn] *= objScale;
2459                                    objective[iColumn] *= objScale;;
2460                                }
2461                                int iRow;
2462                                int numberRows = lpSolver->numberRows();
2463                                double * dualRowSolution =
2464                                    lpSolver->dualRowSolution();
2465                                for (iRow = 0; iRow < numberRows; iRow++)
2466                                    dualRowSolution[iRow] *= objScale;
2467                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2468                            }
2469                            ClpSolve::SolveType method;
2470                            ClpSolve::PresolveType presolveType;
2471                            ClpSimplex * model2 = lpSolver;
2472                            if (dualize) {
2473                                bool tryIt = true;
2474                                double fractionColumn = 1.0;
2475                                double fractionRow = 1.0;
2476                                if (dualize == 3) {
2477                                    dualize = 1;
2478                                    int numberColumns = lpSolver->numberColumns();
2479                                    int numberRows = lpSolver->numberRows();
2480                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2481                                        tryIt = false;
2482                                    } else {
2483                                        fractionColumn = 0.1;
2484                                        fractionRow = 0.1;
2485                                    }
2486                                }
2487                                if (tryIt) {
2488                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2489                                    if (model2) {
2490                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2491                                                model2->numberRows(), model2->numberColumns());
2492                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2493                                        << generalPrint
2494                                        << CoinMessageEol;
2495                                        model2->setOptimizationDirection(1.0);
2496                                    } else {
2497                                        model2 = lpSolver;
2498                                        dualize = 0;
2499                                    }
2500                                } else {
2501                                    dualize = 0;
2502                                }
2503                            }
2504                            if (noPrinting_)
2505                                lpSolver->setLogLevel(0);
2506                            ClpSolve solveOptions;
2507                            solveOptions.setPresolveActions(presolveOptions);
2508                            solveOptions.setSubstitution(substitution);
2509                            if (preSolve != 5 && preSolve) {
2510                                presolveType = ClpSolve::presolveNumber;
2511                                if (preSolve < 0) {
2512                                    preSolve = - preSolve;
2513                                    if (preSolve <= 100) {
2514                                        presolveType = ClpSolve::presolveNumber;
2515                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2516                                                preSolve);
2517                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2518                                        << generalPrint
2519                                        << CoinMessageEol;
2520                                        solveOptions.setDoSingletonColumn(true);
2521                                    } else {
2522                                        preSolve -= 100;
2523                                        presolveType = ClpSolve::presolveNumberCost;
2524                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2525                                                preSolve);
2526                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2527                                        << generalPrint
2528                                        << CoinMessageEol;
2529                                    }
2530                                }
2531                            } else if (preSolve) {
2532                                presolveType = ClpSolve::presolveOn;
2533                            } else {
2534                                presolveType = ClpSolve::presolveOff;
2535                            }
2536                            solveOptions.setPresolveType(presolveType, preSolve);
2537                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2538                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
2539                                method = ClpSolve::useDual;
2540                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
2541                                method = ClpSolve::usePrimalorSprint;
2542                            } else {
2543                                method = ClpSolve::useBarrier;
2544                                if (crossover == 1) {
2545                                    method = ClpSolve::useBarrierNoCross;
2546                                } else if (crossover == 2) {
2547                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2548                                    if (obj->type() > 1) {
2549                                        method = ClpSolve::useBarrierNoCross;
2550                                        presolveType = ClpSolve::presolveOff;
2551                                        solveOptions.setPresolveType(presolveType, preSolve);
2552                                    }
2553                                }
2554                            }
2555                            solveOptions.setSolveType(method);
2556                            if (preSolveFile)
2557                                presolveOptions |= 0x40000000;
2558                            solveOptions.setSpecialOption(4, presolveOptions);
2559                            solveOptions.setSpecialOption(5, printOptions);
2560                            if (doVector) {
2561                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2562                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2563                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2564                                    clpMatrix->makeSpecialColumnCopy();
2565                                }
2566                            }
2567                            if (method == ClpSolve::useDual) {
2568                                // dual
2569                                if (doCrash)
2570                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2571                                else if (doIdiot)
2572                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2573                            } else if (method == ClpSolve::usePrimalorSprint) {
2574                                // primal
2575                                // if slp turn everything off
2576                                if (slpValue > 0) {
2577                                    doCrash = false;
2578                                    doSprint = 0;
2579                                    doIdiot = -1;
2580                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2581                                    method = ClpSolve::usePrimal;
2582                                }
2583                                if (doCrash) {
2584                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2585                                } else if (doSprint > 0) {
2586                                    // sprint overrides idiot
2587                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2588                                } else if (doIdiot > 0) {
2589                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2590                                } else if (slpValue <= 0) {
2591                                    if (doIdiot == 0) {
2592                                        if (doSprint == 0)
2593                                            solveOptions.setSpecialOption(1, 4); // all slack
2594                                        else
2595                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2596                                    } else {
2597                                        if (doSprint == 0)
2598                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2599                                        else
2600                                            solveOptions.setSpecialOption(1, 7); // initiative
2601                                    }
2602                                }
2603                                if (basisHasValues == -1)
2604                                    solveOptions.setSpecialOption(1, 11); // switch off values
2605                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2606                                int barrierOptions = choleskyType;
2607                                if (scaleBarrier)
2608                                    barrierOptions |= 8;
2609                                if (doKKT)
2610                                    barrierOptions |= 16;
2611                                if (gamma)
2612                                    barrierOptions |= 32 * gamma;
2613                                if (crossover == 3)
2614                                    barrierOptions |= 256; // try presolve in crossover
2615                                solveOptions.setSpecialOption(4, barrierOptions);
2616                            }
2617                            model2->setMaximumSeconds(model_.getMaximumSeconds());
2618#ifdef COIN_HAS_LINK
2619                            OsiSolverInterface * coinSolver = model_.solver();
2620                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2621                            if (!linkSolver) {
2622                                model2->initialSolve(solveOptions);
2623                            } else {
2624                                // special solver
2625                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
2626                                double * solution = NULL;
2627                                if (testOsiOptions < 10) {
2628                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2629                                } else if (testOsiOptions >= 10) {
2630                                    CoinModel coinModel = *linkSolver->coinModel();
2631                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2632                                    assert (tempModel);
2633                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2634                                    model2->setObjectiveValue(tempModel->objectiveValue());
2635                                    model2->setProblemStatus(tempModel->problemStatus());
2636                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2637                                    delete tempModel;
2638                                }
2639                                if (solution) {
2640                                    memcpy(model2->primalColumnSolution(), solution,
2641                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2642                                    delete [] solution;
2643                                } else {
2644                                    printf("No nonlinear solution\n");
2645                                }
2646                            }
2647#else
2648                            model2->initialSolve(solveOptions);
2649#endif
2650                            {
2651                                // map states
2652                                /* clp status
2653                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2654                                   0 - optimal
2655                                   1 - primal infeasible
2656                                   2 - dual infeasible
2657                                   3 - stopped on iterations or time
2658                                   4 - stopped due to errors
2659                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2660                                /* cbc status
2661                                   -1 before branchAndBound
2662                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2663                                   (or check value of best solution)
2664                                   1 stopped - on maxnodes, maxsols, maxtime
2665                                   2 difficulties so run was abandoned
2666                                   (5 event user programmed event occurred) */
2667                                /* clp secondary status of problem - may get extended
2668                                   0 - none
2669                                   1 - primal infeasible because dual limit reached OR probably primal
2670                                   infeasible but can't prove it (main status 4)
2671                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2672                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
2673                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
2674                                   5 - giving up in primal with flagged variables
2675                                   6 - failed due to empty problem check
2676                                   7 - postSolve says not optimal
2677                                   8 - failed due to bad element check
2678                                   9 - status was 3 and stopped on time
2679                                   100 up - translation of enum from ClpEventHandler
2680                                */
2681                                /* cbc secondary status of problem
2682                                   -1 unset (status_ will also be -1)
2683                                   0 search completed with solution
2684                                   1 linear relaxation not feasible (or worse than cutoff)
2685                                   2 stopped on gap
2686                                   3 stopped on nodes
2687                                   4 stopped on time
2688                                   5 stopped on user event
2689                                   6 stopped on solutions
2690                                   7 linear relaxation unbounded
2691                                */
2692                                int iStatus = model2->status();
2693                                int iStatus2 = model2->secondaryStatus();
2694                                if (iStatus == 0) {
2695                                    iStatus2 = 0;
2696                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
2697                                        // set best solution in model as no integers
2698                                        model_.setBestSolution(model2->primalColumnSolution(),
2699                                                               model2->numberColumns(),
2700                                                               model2->getObjValue()*
2701                                                               model2->getObjSense());
2702                                    }
2703                                } else if (iStatus == 1) {
2704                                    iStatus = 0;
2705                                    iStatus2 = 1; // say infeasible
2706                                } else if (iStatus == 2) {
2707                                    iStatus = 0;
2708                                    iStatus2 = 7; // say unbounded
2709                                } else if (iStatus == 3) {
2710                                    iStatus = 1;
2711                                    if (iStatus2 == 9)
2712                                        iStatus2 = 4;
2713                                    else
2714                                        iStatus2 = 3; // Use nodes - as closer than solutions
2715                                } else if (iStatus == 4) {
2716                                    iStatus = 2; // difficulties
2717                                    iStatus2 = 0;
2718                                }
2719                                model_.setProblemStatus(iStatus);
2720                                model_.setSecondaryStatus(iStatus2);
2721                                if ((iStatus == 2 || iStatus2 > 0) &&
2722                                    !noPrinting_) {
2723                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
2724                                   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"};
2725                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
2726                                           statusName[iStatus].c_str(), 
2727                                           minor[iStatus2].c_str());
2728                                   sprintf(generalPrint + strlen(generalPrint),
2729                                           "Enumerated nodes:           0\n");
2730                                   sprintf(generalPrint + strlen(generalPrint), 
2731                                           "Total iterations:           0\n");
2732#if CBC_QUIET == 0
2733                                   sprintf(generalPrint + strlen(generalPrint),
2734                                           "Time (CPU seconds):         %.2f\n", 
2735                                           CoinCpuTime() - time0);
2736                                   sprintf(generalPrint + strlen(generalPrint),
2737                                           "Time (Wallclock Seconds):   %.2f\n", 
2738                                           CoinGetTimeOfDay()-time0Elapsed);
2739#endif
2740                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
2741                                      << generalPrint
2742                                      << CoinMessageEol;
2743                                }
2744                                //assert (lpSolver==clpSolver->getModelPtr());
2745                                assert (clpSolver == model_.solver());
2746                                clpSolver->setWarmStart(NULL);
2747                                // and in babModel if exists
2748                                if (babModel_) {
2749                                    babModel_->setProblemStatus(iStatus);
2750                                    babModel_->setSecondaryStatus(iStatus2);
2751                                }
2752                                int returnCode = callBack(&model, 1);
2753                                if (returnCode) {
2754                                    // exit if user wants
2755                                    delete babModel_;
2756                                    babModel_ = NULL;
2757                                    return returnCode;
2758                                }
2759                            }
2760                            basisHasValues = 1;
2761                            if (dualize) {
2762                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
2763                                if (model2->status() == 3)
2764                                    returnCode = 0;
2765                                delete model2;
2766                                if (returnCode && dualize != 2)
2767                                    lpSolver->primal(1);
2768                                model2 = lpSolver;
2769                            }
2770#ifdef COIN_HAS_ASL
2771                            if (statusUserFunction_[0]) {
2772                                double value = model2->getObjValue() * model2->getObjSense();
2773                                char buf[300];
2774                                int pos = 0;
2775                                int iStat = model2->status();
2776                                if (iStat == 0) {
2777                                    pos += sprintf(buf + pos, "optimal," );
2778                                } else if (iStat == 1) {
2779                                    // infeasible
2780                                    pos += sprintf(buf + pos, "infeasible,");
2781                                } else if (iStat == 2) {
2782                                    // unbounded
2783                                    pos += sprintf(buf + pos, "unbounded,");
2784                                } else if (iStat == 3) {
2785                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
2786                                } else if (iStat == 4) {
2787                                    iStat = 7;
2788                                    pos += sprintf(buf + pos, "stopped on difficulties,");
2789                                } else if (iStat == 5) {
2790                                    iStat = 3;
2791                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
2792                                } else if (iStat == 6) {
2793                                    // bab infeasible
2794                                    pos += sprintf(buf + pos, "integer infeasible,");
2795                                    iStat = 1;
2796                                } else {
2797                                    pos += sprintf(buf + pos, "status unknown,");
2798                                    iStat = 6;
2799                                }
2800                                info.problemStatus = iStat;
2801                                info.objValue = value;
2802                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
2803                                               value);
2804                                sprintf(buf + pos, "\n%d iterations",
2805                                        model2->getIterationCount());
2806                                free(info.primalSolution);
2807                                int numberColumns = model2->numberColumns();
2808                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
2809                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
2810                                int numberRows = model2->numberRows();
2811                                free(info.dualSolution);
2812                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
2813                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
2814                                CoinWarmStartBasis * basis = model2->getBasis();
2815                                free(info.rowStatus);
2816                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
2817                                free(info.columnStatus);
2818                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
2819                                // Put basis in
2820                                int i;
2821                                // free,basic,ub,lb are 0,1,2,3
2822                                for (i = 0; i < numberRows; i++) {
2823                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
2824                                    info.rowStatus[i] = status;
2825                                }
2826                                for (i = 0; i < numberColumns; i++) {
2827                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
2828                                    info.columnStatus[i] = status;
2829                                }
2830                                // put buffer into info
2831                                strcpy(info.buffer, buf);
2832                                delete basis;
2833                            }
2834#endif
2835                        } else {
2836#ifndef DISALLOW_PRINTING
2837                            std::cout << "** Current model not valid" << std::endl;
2838#endif
2839                        }
2840                        break;
2841                    case CLP_PARAM_ACTION_STATISTICS:
2842                        if (goodModel) {
2843                            // If presolve on look at presolved
2844                            bool deleteModel2 = false;
2845                            ClpSimplex * model2 = lpSolver;
2846                            if (preSolve) {
2847                                ClpPresolve pinfo;
2848                                int presolveOptions2 = presolveOptions&~0x40000000;
2849                                if ((presolveOptions2&0xffff) != 0)
2850                                    pinfo.setPresolveActions(presolveOptions2);
2851                                pinfo.setSubstitution(substitution);
2852                                if ((printOptions&1) != 0)
2853                                    pinfo.statistics();
2854                                double presolveTolerance =
2855                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
2856                                model2 =
2857                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
2858                                                         true, preSolve);
2859                                if (model2) {
2860                                    printf("Statistics for presolved model\n");
2861                                    deleteModel2 = true;
2862                                } else {
2863                                    printf("Presolved model looks infeasible - will use unpresolved\n");
2864                                    model2 = lpSolver;
2865                                }
2866                            } else {
2867                                printf("Statistics for unpresolved model\n");
2868                                model2 =  lpSolver;
2869                            }
2870                            statistics(lpSolver, model2);
2871                            if (deleteModel2)
2872                                delete model2;
2873                        } else {
2874#ifndef DISALLOW_PRINTING
2875                            std::cout << "** Current model not valid" << std::endl;
2876#endif
2877                        }
2878                        break;
2879                    case CLP_PARAM_ACTION_TIGHTEN:
2880                        if (goodModel) {
2881                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
2882                            if (numberInfeasibilities)
2883                                std::cout << "** Analysis indicates model infeasible" << std::endl;
2884                        } else {
2885#ifndef DISALLOW_PRINTING
2886                            std::cout << "** Current model not valid" << std::endl;
2887#endif
2888                        }
2889                        break;
2890                    case CLP_PARAM_ACTION_PLUSMINUS:
2891                        if (goodModel) {
2892                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
2893                            ClpPackedMatrix* clpMatrix =
2894                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
2895                            if (clpMatrix) {
2896                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
2897                                if (newMatrix->getIndices()) {
2898                                    lpSolver->replaceMatrix(newMatrix);
2899                                    delete saveMatrix;
2900                                    std::cout << "Matrix converted to +- one matrix" << std::endl;
2901                                } else {
2902                                    std::cout << "Matrix can not be converted to +- 1 matrix" << std::endl;
2903                                }
2904                            } else {
2905                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
2906                            }
2907                        } else {
2908#ifndef DISALLOW_PRINTING
2909                            std::cout << "** Current model not valid" << std::endl;
2910#endif
2911                        }
2912                        break;
2913                    case CLP_PARAM_ACTION_OUTDUPROWS:
2914                        dominatedCuts = true;
2915#ifdef JJF_ZERO
2916                        if (goodModel) {
2917                            int numberRows = clpSolver->getNumRows();
2918                            //int nOut = outDupRow(clpSolver);
2919                            CglDuplicateRow dupcuts(clpSolver);
2920                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
2921                            int nOut = numberRows - clpSolver->getNumRows();
2922                            if (nOut && !noPrinting_)
2923                                sprintf(generalPrint, "%d rows eliminated", nOut);
2924                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2925                            << generalPrint
2926                            << CoinMessageEol;
2927                        } else {
2928#ifndef DISALLOW_PRINTING
2929                            std::cout << "** Current model not valid" << std::endl;
2930#endif
2931                        }
2932#endif
2933                        break;
2934                    case CLP_PARAM_ACTION_NETWORK:
2935                        if (goodModel) {
2936                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
2937                            ClpPackedMatrix* clpMatrix =
2938                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
2939                            if (clpMatrix) {
2940                                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
2941                                if (newMatrix->getIndices()) {
2942                                    lpSolver->replaceMatrix(newMatrix);
2943                                    delete saveMatrix;
2944                                    std::cout << "Matrix converted to network matrix" << std::endl;
2945                                } else {
2946                                    std::cout << "Matrix can not be converted to network matrix" << std::endl;
2947                                }
2948                            } else {
2949                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
2950                            }
2951                        } else {
2952#ifndef DISALLOW_PRINTING
2953                            std::cout << "** Current model not valid" << std::endl;
2954#endif
2955                        }
2956                        break;
2957                    case CBC_PARAM_ACTION_DOHEURISTIC:
2958                        if (goodModel) {
2959                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
2960                            if (vubAction != -1) {
2961                                // look at vubs
2962                                // extra1 is number of ints to leave free
2963                                // Just ones which affect >= extra3
2964                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
2965                                /* 2 is cost above which to fix if feasible
2966                                   3 is fraction of integer variables fixed if relaxing (0.97)
2967                                   4 is fraction of all variables fixed if relaxing (0.0)
2968                                */
2969                                double dextra[6];
2970                                int extra[5];
2971                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
2972                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
2973                                                                  parameters_)].intValue();
2974                                if (exp1 == 4 && extra[1] == -1)
2975                                    extra[1] = 999998;
2976                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
2977                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
2978                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
2979                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
2980                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
2981                                if (!dextra[3])
2982                                    dextra[3] = 0.97;
2983                                //OsiClpSolverInterface * newSolver =
2984                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
2985                                        debugValues, dextra, extra);
2986                                //assert (!newSolver);
2987                            }
2988                            // Actually do heuristics
2989                            doHeuristics(&model_, 2, parameters_,
2990                                         numberParameters_, noPrinting_, initialPumpTune);
2991                            if (model_.bestSolution()) {
2992                                model_.setProblemStatus(1);
2993                                model_.setSecondaryStatus(6);
2994#ifdef COIN_HAS_ASL
2995                                if (statusUserFunction_[0]) {
2996                                    double value = model_.getObjValue();
2997                                    char buf[300];
2998                                    int pos = 0;
2999                                    pos += sprintf(buf + pos, "feasible,");
3000                                    info.problemStatus = 0;
3001                                    info.objValue = value;
3002                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3003                                                   value);
3004                                    sprintf(buf + pos, "\n0 iterations");
3005                                    free(info.primalSolution);
3006                                    int numberColumns = lpSolver->numberColumns();
3007                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3008                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3009                                    int numberRows = lpSolver->numberRows();
3010                                    free(info.dualSolution);
3011                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3012                                    CoinZeroN(info.dualSolution, numberRows);
3013                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3014                                    free(info.rowStatus);
3015                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3016                                    free(info.columnStatus);
3017                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3018                                    // Put basis in
3019                                    int i;
3020                                    // free,basic,ub,lb are 0,1,2,3
3021                                    for (i = 0; i < numberRows; i++) {
3022                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3023                                        info.rowStatus[i] = status;
3024                                    }
3025                                    for (i = 0; i < numberColumns; i++) {
3026                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3027                                        info.columnStatus[i] = status;
3028                                    }
3029                                    // put buffer into info
3030                                    strcpy(info.buffer, buf);
3031                                    delete basis;
3032                                }
3033#endif
3034                            }
3035                            int returnCode = callBack(&model, 6);
3036                            if (returnCode) {
3037                                // exit if user wants
3038                                delete babModel_;
3039                                babModel_ = NULL;
3040                                return returnCode;
3041                            }
3042                        }
3043                        break;
3044                    case CBC_PARAM_ACTION_MIPLIB:
3045                        // User can set options - main difference is lack of model and CglPreProcess
3046                        goodModel = true;
3047                        /*
3048                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3049                          Print elapsed time at the end.
3050                        */
3051                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3052                        // obsolete case STRENGTHEN:
3053                        if (goodModel) {
3054                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3055                            int logLevel = parameters_[slog].intValue();
3056                            // Reduce printout
3057                            if (logLevel <= 1) {
3058                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3059                            } else {
3060                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3061                            }
3062                            {
3063                                OsiSolverInterface * solver = model_.solver();
3064#ifndef CBC_OTHER_SOLVER
3065                                OsiClpSolverInterface * si =
3066                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3067                                assert (si != NULL);
3068                                si->getModelPtr()->scaling(doScaling);
3069                                ClpSimplex * lpSolver = si->getModelPtr();
3070                                if (doVector) {
3071                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3072                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3073                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3074                                        clpMatrix->makeSpecialColumnCopy();
3075                                    }
3076                                }
3077#elif CBC_OTHER_SOLVER==1
3078                                OsiCpxSolverInterface * si =
3079                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3080                                assert (si != NULL);
3081#endif
3082                                statistics_nrows = si->getNumRows();
3083                                statistics_ncols = si->getNumCols();
3084                                statistics_nprocessedrows = si->getNumRows();
3085                                statistics_nprocessedcols = si->getNumCols();
3086                                // See if quadratic
3087#ifndef CBC_OTHER_SOLVER
3088#ifdef COIN_HAS_LINK
3089                                if (!complicatedInteger) {
3090                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3091                                    if (obj) {
3092                                        preProcess = 0;
3093                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3094                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3095                                        // create coin model
3096                                        coinModel = lpSolver->createCoinModel();
3097                                        assert (coinModel);
3098                                        // load from coin model
3099                                        OsiSolverLink solver1;
3100                                        OsiSolverInterface * solver2 = solver1.clone();
3101                                        model_.assignSolver(solver2, false);
3102                                        OsiSolverLink * si =
3103                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3104                                        assert (si != NULL);
3105                                        si->setDefaultMeshSize(0.001);
3106                                        // need some relative granularity
3107                                        si->setDefaultBound(100.0);
3108                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3109                                        if (dextra3)
3110                                            si->setDefaultMeshSize(dextra3);
3111                                        si->setDefaultBound(1000.0);
3112                                        si->setIntegerPriority(1000);
3113                                        si->setBiLinearPriority(10000);
3114                                        si->setSpecialOptions2(2 + 4 + 8);
3115                                        CoinModel * model2 = coinModel;
3116                                        si->load(*model2, true, parameters_[log].intValue());
3117                                        // redo
3118                                        solver = model_.solver();
3119                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3120                                        lpSolver = clpSolver->getModelPtr();
3121                                        clpSolver->messageHandler()->setLogLevel(0) ;
3122                                        testOsiParameters = 0;
3123                                        complicatedInteger = 2;  // allow cuts
3124                                        OsiSolverInterface * coinSolver = model_.solver();
3125                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3126                                        if (linkSolver->quadraticModel()) {
3127                                            ClpSimplex * qp = linkSolver->quadraticModel();
3128                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3129                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3130                                            qp->primal(1);
3131                                            OsiSolverLinearizedQuadratic solver2(qp);
3132                                            const double * solution = NULL;
3133                                            // Reduce printout
3134                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3135                                            CbcModel model2(solver2);
3136                                            // Now do requested saves and modifications
3137                                            CbcModel * cbcModel = & model2;
3138                                            OsiSolverInterface * osiModel = model2.solver();
3139                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3140                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3141
3142                                            // Set changed values
3143
3144                                            CglProbing probing;
3145                                            probing.setMaxProbe(10);
3146                                            probing.setMaxLook(10);
3147                                            probing.setMaxElements(200);
3148                                            probing.setMaxProbeRoot(50);
3149                                            probing.setMaxLookRoot(10);
3150                                            probing.setRowCuts(3);
3151                                            probing.setUsingObjective(true);
3152                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3153                                            cbcModel->cutGenerator(0)->setTiming(true);
3154
3155                                            CglGomory gomory;
3156                                            gomory.setLimitAtRoot(512);
3157                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3158                                            cbcModel->cutGenerator(1)->setTiming(true);
3159
3160                                            CglKnapsackCover knapsackCover;
3161                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3162                                            cbcModel->cutGenerator(2)->setTiming(true);
3163
3164                                            CglRedSplit redSplit;
3165                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3166                                            cbcModel->cutGenerator(3)->setTiming(true);
3167
3168                                            CglClique clique;
3169                                            clique.setStarCliqueReport(false);
3170                                            clique.setRowCliqueReport(false);
3171                                            clique.setMinViolation(0.1);
3172                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3173                                            cbcModel->cutGenerator(4)->setTiming(true);
3174
3175                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3176                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3177                                            cbcModel->cutGenerator(5)->setTiming(true);
3178
3179                                            CglFlowCover flowCover;
3180                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3181                                            cbcModel->cutGenerator(6)->setTiming(true);
3182
3183                                            CglTwomir twomir;
3184                                            twomir.setMaxElements(250);
3185                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3186                                            cbcModel->cutGenerator(7)->setTiming(true);
3187
3188                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3189                                            heuristicFPump.setWhen(13);
3190                                            heuristicFPump.setMaximumPasses(20);
3191                                            heuristicFPump.setMaximumRetries(7);
3192                                            heuristicFPump.setHeuristicName("feasibility pump");
3193                                            heuristicFPump.setInitialWeight(1);
3194                                            heuristicFPump.setFractionSmall(0.6);
3195                                            cbcModel->addHeuristic(&heuristicFPump);
3196
3197                                            CbcRounding rounding(*cbcModel);
3198                                            rounding.setHeuristicName("rounding");
3199                                            cbcModel->addHeuristic(&rounding);
3200
3201                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3202                                            heuristicLocal.setHeuristicName("combine solutions");
3203                                            heuristicLocal.setSearchType(1);
3204                                            heuristicLocal.setFractionSmall(0.6);
3205                                            cbcModel->addHeuristic(&heuristicLocal);
3206
3207                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3208                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3209                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3210
3211                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3212                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3213                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3214
3215                                            CbcCompareDefault compare;
3216                                            cbcModel->setNodeComparison(compare);
3217                                            cbcModel->setNumberBeforeTrust(5);
3218                                            cbcModel->setSpecialOptions(2);
3219                                            cbcModel->messageHandler()->setLogLevel(1);
3220                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3221                                            cbcModel->setMaximumCutPasses(1);
3222                                            cbcModel->setMinimumDrop(0.05);
3223                                            // For branchAndBound this may help
3224                                            clpModel->defaultFactorizationFrequency();
3225                                            clpModel->setDualBound(1.0001e+08);
3226                                            clpModel->setPerturbation(50);
3227                                            osiclpModel->setSpecialOptions(193);
3228                                            osiclpModel->messageHandler()->setLogLevel(0);
3229                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3230                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3231                                            // You can save some time by switching off message building
3232                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3233
3234                                            // Solve
3235
3236                                            cbcModel->initialSolve();
3237                                            if (clpModel->tightenPrimalBounds() != 0) {
3238#ifndef DISALLOW_PRINTING
3239                                                std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3240#endif
3241                                                break;
3242                                            }
3243                                            clpModel->dual();  // clean up
3244                                            cbcModel->initialSolve();
3245#ifdef CBC_THREAD
3246                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3247                                            cbcModel->setNumberThreads(numberThreads % 100);
3248                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3249#endif
3250                                            //setCutAndHeuristicOptions(*cbcModel);
3251                                            cbcModel->branchAndBound();
3252                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3253                                            assert (solver3);
3254                                            solution = solver3->bestSolution();
3255                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3256                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3257                                            linkSolver->setBestSolution(solution, solver3->getNumCols());
3258                                            CbcHeuristicDynamic3 dynamic(model_);
3259                                            dynamic.setHeuristicName("dynamic pass thru");
3260                                            model_.addHeuristic(&dynamic);
3261                                            // if convex
3262                                            if ((linkSolver->specialOptions2()&4) != 0) {
3263                                                int numberColumns = coinModel->numberColumns();
3264                                                assert (linkSolver->objectiveVariable() == numberColumns);
3265                                                // add OA cut
3266                                                double offset;
3267                                                double * gradient = new double [numberColumns+1];
3268                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3269                                                       numberColumns*sizeof(double));
3270                                                double rhs = 0.0;
3271                                                int * column = new int[numberColumns+1];
3272                                                int n = 0;
3273                                                for (int i = 0; i < numberColumns; i++) {
3274                                                    double value = gradient[i];
3275                                                    if (fabs(value) > 1.0e-12) {
3276                                                        gradient[n] = value;
3277                                                        rhs += value * solution[i];
3278                                                        column[n++] = i;
3279                                                    }
3280                                                }
3281                                                gradient[n] = -1.0;
3282                                                column[n++] = numberColumns;
3283                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3284                                                delete [] gradient;
3285                                                delete [] column;
3286                                            }
3287                                            // could do three way branching round a) continuous b) best solution
3288                                            printf("obj %g\n", bestObjectiveValue);
3289                                            linkSolver->initialSolve();
3290                                        }
3291                                    }
3292                                }
3293#endif
3294#endif
3295                                if (logLevel <= 1)
3296                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3297#ifndef CBC_OTHER_SOLVER
3298                                si->setSpecialOptions(0x40000000);
3299#endif
3300                            }
3301                            if (!miplib) {
3302                                if (!preSolve) {
3303                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3304                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3305                                }
3306                                double time1a = CoinCpuTime();
3307                                OsiSolverInterface * solver = model_.solver();
3308#ifndef CBC_OTHER_SOLVER
3309                                OsiClpSolverInterface * si =
3310                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3311                                if (si)
3312                                    si->setSpecialOptions(si->specialOptions() | 1024);
3313#endif
3314                                model_.initialSolve();
3315#ifndef CBC_OTHER_SOLVER
3316                                ClpSimplex * clpSolver = si->getModelPtr();
3317                                int iStatus = clpSolver->status();
3318                                int iStatus2 = clpSolver->secondaryStatus();
3319                                if (iStatus == 0) {
3320                                    iStatus2 = 0;
3321                                } else if (iStatus == 1) {
3322                                    iStatus = 0;
3323                                    iStatus2 = 1; // say infeasible
3324                                } else if (iStatus == 2) {
3325                                    iStatus = 0;
3326                                    iStatus2 = 7; // say unbounded
3327                                } else if (iStatus == 3) {
3328                                    iStatus = 1;
3329                                    if (iStatus2 == 9)
3330                                        iStatus2 = 4;
3331                                    else
3332                                        iStatus2 = 3; // Use nodes - as closer than solutions
3333                                } else if (iStatus == 4) {
3334                                    iStatus = 2; // difficulties
3335                                    iStatus2 = 0;
3336                                }
3337                                model_.setProblemStatus(iStatus);
3338                                model_.setSecondaryStatus(iStatus2);
3339                                si->setWarmStart(NULL);
3340                                int returnCode = callBack(&model_, 1);
3341                                if (returnCode) {
3342                                    // exit if user wants
3343                                    delete babModel_;
3344                                    babModel_ = NULL;
3345                                    return returnCode;
3346                                }
3347                                if (clpSolver->status() > 0) {
3348                                    // and in babModel if exists
3349                                    if (babModel_) {
3350                                        babModel_->setProblemStatus(iStatus);
3351                                        babModel_->setSecondaryStatus(iStatus2);
3352                                    }
3353                                    if (!noPrinting_) {
3354                                        iStatus = clpSolver->status();
3355                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3356                                                              "difficulties", "other"
3357                                                             };
3358                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3359                                                msg[iStatus-1], CoinCpuTime() - time1a);
3360                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3361                                        << generalPrint
3362                                        << CoinMessageEol;
3363                                    }
3364                                    break;
3365                                }
3366                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3367#elif CBC_OTHER_SOLVER==1
3368#endif
3369                                if (!noPrinting_) {
3370                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3371                                            solver->getObjValue(), CoinCpuTime() - time1a);
3372                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3373                                    << generalPrint
3374                                    << CoinMessageEol;
3375                                }
3376                                if (model_.getMaximumNodes() == -987654321) {
3377                                    // See if No objective!
3378                                    int numberColumns = clpSolver->getNumCols();
3379                                    const double * obj = clpSolver->getObjCoefficients();
3380                                    const double * lower = clpSolver->getColLower();
3381                                    const double * upper = clpSolver->getColUpper();
3382                                    int nObj = 0;
3383                                    for (int i = 0; i < numberColumns; i++) {
3384                                        if (upper[i] > lower[i] && obj[i])
3385                                            nObj++;
3386                                    }
3387                                    if (!nObj) {
3388                                        printf("************No objective!!\n");
3389                                        model_.setMaximumSolutions(1);
3390                                        // Column copy
3391                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3392                                        //const double * element = matrixByCol.getElements();
3393                                        //const int * row = matrixByCol.getIndices();
3394                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3395                                        const int * columnLength = matrixByCol.getVectorLengths();
3396                                        for (int i = 0; i < numberColumns; i++) {
3397                                            double value = (CoinDrand48() + 0.5) * 10000;
3398                                            value = 10;
3399                                            value *= columnLength[i];
3400                                            int iValue = static_cast<int> (value) / 10;
3401                                            //iValue=1;
3402                                            clpSolver->setObjCoeff(i, iValue);
3403                                        }
3404                                    }
3405                                }
3406#ifndef CBC_OTHER_SOLVER
3407                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3408#ifndef DISALLOW_PRINTING
3409                                    std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3410#endif
3411                                    model_.setProblemStatus(0);
3412                                    model_.setSecondaryStatus(1);
3413                                    // and in babModel if exists
3414                                    if (babModel_) {
3415                                        babModel_->setProblemStatus(0);
3416                                        babModel_->setSecondaryStatus(1);
3417                                    }
3418                                    break;
3419                                }
3420                                if (clpSolver->dualBound() == 1.0e10) {
3421                                    ClpSimplex temp = *clpSolver;
3422                                    temp.setLogLevel(0);
3423                                    temp.dual(0, 7);
3424                                    // user did not set - so modify
3425                                    // get largest scaled away from bound
3426                                    double largest = 1.0e-12;
3427                                    double largestScaled = 1.0e-12;
3428                                    int numberRows = temp.numberRows();
3429                                    const double * rowPrimal = temp.primalRowSolution();
3430                                    const double * rowLower = temp.rowLower();
3431                                    const double * rowUpper = temp.rowUpper();
3432                                    const double * rowScale = temp.rowScale();
3433                                    int iRow;
3434                                    for (iRow = 0; iRow < numberRows; iRow++) {
3435                                        double value = rowPrimal[iRow];
3436                                        double above = value - rowLower[iRow];
3437                                        double below = rowUpper[iRow] - value;
3438                                        if (above < 1.0e12) {
3439                                            largest = CoinMax(largest, above);
3440                                        }
3441                                        if (below < 1.0e12) {
3442                                            largest = CoinMax(largest, below);
3443                                        }
3444                                        if (rowScale) {
3445                                            double multiplier = rowScale[iRow];
3446                                            above *= multiplier;
3447                                            below *= multiplier;
3448                                        }
3449                                        if (above < 1.0e12) {
3450                                            largestScaled = CoinMax(largestScaled, above);
3451                                        }
3452                                        if (below < 1.0e12) {
3453                                            largestScaled = CoinMax(largestScaled, below);
3454                                        }
3455                                    }
3456
3457                                    int numberColumns = temp.numberColumns();
3458                                    const double * columnPrimal = temp.primalColumnSolution();
3459                                    const double * columnLower = temp.columnLower();
3460                                    const double * columnUpper = temp.columnUpper();
3461                                    const double * columnScale = temp.columnScale();
3462                                    int iColumn;
3463                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3464                                        double value = columnPrimal[iColumn];
3465                                        double above = value - columnLower[iColumn];
3466                                        double below = columnUpper[iColumn] - value;
3467                                        if (above < 1.0e12) {
3468                                            largest = CoinMax(largest, above);
3469                                        }
3470                                        if (below < 1.0e12) {
3471                                            largest = CoinMax(largest, below);
3472                                        }
3473                                        if (columnScale) {
3474                                            double multiplier = 1.0 / columnScale[iColumn];
3475                                            above *= multiplier;
3476                                            below *= multiplier;
3477                                        }
3478                                        if (above < 1.0e12) {
3479                                            largestScaled = CoinMax(largestScaled, above);
3480                                        }
3481                                        if (below < 1.0e12) {
3482                                            largestScaled = CoinMax(largestScaled, below);
3483                                        }
3484                                    }
3485#ifdef COIN_DEVELOP
3486                                    if (!noPrinting_)
3487                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3488                                                  << " unscaled " << largest << std::endl;
3489#endif
3490                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3491                                }
3492                                si->resolve();  // clean up
3493#endif
3494                            }
3495                            // If user made settings then use them
3496                            if (!defaultSettings) {
3497                                OsiSolverInterface * solver = model_.solver();
3498                                if (!doScaling)
3499                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3500#ifndef CBC_OTHER_SOLVER
3501                                OsiClpSolverInterface * si =
3502                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3503                                assert (si != NULL);
3504                                // get clp itself
3505                                ClpSimplex * modelC = si->getModelPtr();
3506                                //if (modelC->tightenPrimalBounds()!=0) {
3507                                //std::cout<<"Problem is infeasible!"<<std::endl;
3508                                //break;
3509                                //}
3510                                // bounds based on continuous
3511                                if (tightenFactor && !complicatedInteger) {
3512                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3513#ifndef DISALLOW_PRINTING
3514                                        std::cout << "Problem is infeasible!" << std::endl;
3515#endif
3516                                        model_.setProblemStatus(0);
3517                                        model_.setSecondaryStatus(1);
3518                                        // and in babModel if exists
3519                                        if (babModel_) {
3520                                            babModel_->setProblemStatus(0);
3521                                            babModel_->setSecondaryStatus(1);
3522                                        }
3523                                        break;
3524                                    }
3525                                }
3526#endif
3527                            }
3528                            // See if we want preprocessing
3529                            OsiSolverInterface * saveSolver = NULL;
3530                            CglPreProcess process;
3531                            cbcPreProcessPointer = & process;
3532                            // Say integers in sync
3533                            bool integersOK = true;
3534                            delete babModel_;
3535                            babModel_ = new CbcModel(model_);
3536#ifndef CBC_OTHER_SOLVER
3537                            int numberChanged = 0;
3538                            OsiSolverInterface * solver3 = clpSolver->clone();
3539                            babModel_->assignSolver(solver3);
3540                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3541                            if (clpSolver2->messageHandler()->logLevel())
3542                                clpSolver2->messageHandler()->setLogLevel(1);
3543                            if (logLevel > -1)
3544                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3545                            lpSolver = clpSolver2->getModelPtr();
3546                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3547                                // User did not touch preset
3548                                int numberRows = lpSolver->numberRows();
3549                                const int cutoff1 = 10000;
3550                                const int cutoff2 = 100000;
3551                                const int base = 75;
3552                                const int freq0 = 50;
3553                                const int freq1 = 200;
3554                                const int freq2 = 400;
3555                                const int maximum = 1000;
3556                                int frequency;
3557                                if (numberRows < cutoff1)
3558                                    frequency = base + numberRows / freq0;
3559                                else if (numberRows < cutoff2)
3560                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3561                                else
3562                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3563                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3564                            }
3565#elif CBC_OTHER_SOLVER==1
3566                            OsiSolverInterface * solver3 = model_.solver()->clone();
3567                            babModel_->assignSolver(solver3);
3568#endif
3569                            time2 = CoinCpuTime();
3570                            totalTime += time2 - time1;
3571                            //time1 = time2;
3572                            double timeLeft = babModel_->getMaximumSeconds();
3573                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3574                            if (preProcess == 7) {
3575                                // use strategy instead
3576                                preProcess = 0;
3577                                useStrategy = true;
3578#ifdef COIN_HAS_LINK
3579                                // empty out any cuts
3580                                if (storedAmpl.sizeRowCuts()) {
3581                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3582                                    CglStored temp;
3583                                    storedAmpl = temp;
3584                                }
3585#endif
3586                            }
3587                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3588                              // see whether to switch off preprocessing
3589                              // only allow SOS and integer
3590                              OsiObject ** objects = babModel_->objects();
3591                              int numberObjects = babModel_->numberObjects();
3592                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3593                                CbcSOS * objSOS =
3594                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
3595                                CbcSimpleInteger * objSimpleInteger =
3596                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3597                                if (!objSimpleInteger&&!objSOS) {
3598                                  preProcess=0;
3599                                  break;
3600                                }
3601                              }
3602                            }
3603                            if (type == CBC_PARAM_ACTION_BAB) {
3604                                double limit;
3605                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
3606                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
3607                                        limit*clpSolver->getObjSense())
3608                                    preProcess = 0;
3609                            }
3610                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3611#ifndef CBC_OTHER_SOLVER
3612                                // See if sos from mps file
3613                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
3614                                    // SOS
3615                                    numberSOS = clpSolver->numberSOS();
3616                                    const CoinSet * setInfo = clpSolver->setInfo();
3617                                    sosStart = new int [numberSOS+1];
3618                                    sosType = new char [numberSOS];
3619                                    int i;
3620                                    int nTotal = 0;
3621                                    sosStart[0] = 0;
3622                                    for ( i = 0; i < numberSOS; i++) {
3623                                        int type = setInfo[i].setType();
3624                                        int n = setInfo[i].numberEntries();
3625                                        sosType[i] = static_cast<char>(type);
3626                                        nTotal += n;
3627                                        sosStart[i+1] = nTotal;
3628                                    }
3629                                    sosIndices = new int[nTotal];
3630                                    sosReference = new double [nTotal];
3631                                    for (i = 0; i < numberSOS; i++) {
3632                                        int n = setInfo[i].numberEntries();
3633                                        const int * which = setInfo[i].which();
3634                                        const double * weights = setInfo[i].weights();
3635                                        int base = sosStart[i];
3636                                        for (int j = 0; j < n; j++) {
3637                                            int k = which[j];
3638                                            sosIndices[j+base] = k;
3639                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
3640                                        }
3641                                    }
3642                                }
3643#endif
3644                                saveSolver = babModel_->solver()->clone();
3645                                /* Do not try and produce equality cliques and
3646                                   do up to 10 passes */
3647                                OsiSolverInterface * solver2;
3648                                {
3649                                    // Tell solver we are in Branch and Cut
3650                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
3651                                    // Default set of cut generators
3652                                    CglProbing generator1;
3653                                    generator1.setUsingObjective(1);
3654                                    generator1.setMaxPass(1);
3655                                    generator1.setMaxPassRoot(1);
3656                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
3657                                    generator1.setMaxElements(100);
3658                                    generator1.setMaxElementsRoot(200);
3659                                    generator1.setMaxLookRoot(50);
3660                                    if (saveSolver->getNumCols() > 3000)
3661                                        generator1.setMaxProbeRoot(123);
3662                                    generator1.setRowCuts(3);
3663                                    if ((tunePreProcess&1) != 0) {
3664                                        // heavy probing
3665                                        generator1.setMaxPassRoot(2);
3666                                        generator1.setMaxElements(300);
3667                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
3668                                    }
3669                                    if ((babModel_->specialOptions()&65536) != 0)
3670                                        process.setOptions(1);
3671                                    // Add in generators
3672                                    if ((model_.moreSpecialOptions()&65536)==0)
3673                                      process.addCutGenerator(&generator1);
3674                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
3675                                    process.passInMessageHandler(babModel_->messageHandler());
3676                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
3677#ifdef COIN_HAS_ASL
3678                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
3679                                        // SOS
3680                                        numberSOS = info.numberSos;
3681                                        sosStart = info.sosStart;
3682                                        sosIndices = info.sosIndices;
3683                                    }
3684#endif
3685                                    if (numberSOS && doSOS) {
3686                                        // SOS
3687                                        int numberColumns = saveSolver->getNumCols();
3688                                        char * prohibited = new char[numberColumns];
3689                                        memset(prohibited, 0, numberColumns);
3690                                        int n = sosStart[numberSOS];
3691                                        for (int i = 0; i < n; i++) {
3692                                            int iColumn = sosIndices[i];
3693                                            prohibited[iColumn] = 1;
3694                                        }
3695                                        process.passInProhibited(prohibited, numberColumns);
3696                                        delete [] prohibited;
3697                                    }
3698                                    if (!model_.numberObjects() && true) {
3699                                        /* model may not have created objects
3700                                           If none then create
3701                                        */
3702                                        model_.findIntegers(true);
3703                                    }
3704                                    if (model_.numberObjects()) {
3705                                        OsiObject ** oldObjects = babModel_->objects();
3706                                        int numberOldObjects = babModel_->numberObjects();
3707                                        // SOS
3708                                        int numberColumns = saveSolver->getNumCols();
3709                                        char * prohibited = new char[numberColumns];
3710                                        memset(prohibited, 0, numberColumns);
3711                                        int numberProhibited = 0;
3712                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
3713                                            CbcSOS * obj =
3714                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
3715                                            if (obj) {
3716                                                int n = obj->numberMembers();
3717                                                const int * which = obj->members();
3718                                                for (int i = 0; i < n; i++) {
3719                                                    int iColumn = which[i];
3720                                                    prohibited[iColumn] = 1;
3721                                                    numberProhibited++;
3722                                                }
3723                                            }
3724                                            CbcLotsize * obj2 =
3725                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
3726                                            if (obj2) {
3727                                                int iColumn = obj2->columnNumber();
3728                                                prohibited[iColumn] = 1;
3729                                                numberProhibited++;
3730                                            }
3731                                        }
3732                                        if (numberProhibited)
3733                                            process.passInProhibited(prohibited, numberColumns);
3734                                        delete [] prohibited;
3735                                    }
3736                                    int numberPasses = 10;
3737                                    if (tunePreProcess >= 1000000) {
3738                                        numberPasses = (tunePreProcess / 1000000) - 1;
3739                                        tunePreProcess = tunePreProcess % 1000000;
3740                                    } else if (tunePreProcess >= 1000) {
3741                                        numberPasses = (tunePreProcess / 1000) - 1;
3742                                        tunePreProcess = tunePreProcess % 1000;
3743                                    }
3744#ifndef CBC_OTHER_SOLVER
3745                                    if (doSprint > 0) {
3746                                        // Sprint for primal solves
3747                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
3748                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
3749                                        int numberPasses = 5;
3750                                        int options[] = {0, 3, 0, 0, 0, 0};
3751                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
3752                                        extraInfo[1] = doSprint;
3753                                        int independentOptions[] = {0, 0, 3};
3754                                        ClpSolve clpSolve(method, presolveType, numberPasses,
3755                                                          options, extraInfo, independentOptions);
3756                                        // say use in OsiClp
3757                                        clpSolve.setSpecialOption(6, 1);
3758                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3759                                        osiclp->setSolveOptions(clpSolve);
3760                                        osiclp->setHintParam(OsiDoDualInResolve, false);
3761                                        // switch off row copy
3762                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
3763                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
3764                                    }
3765#endif
3766#ifndef CBC_OTHER_SOLVER
3767                                    {
3768                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3769                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
3770                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
3771                                        //#define CBC_TEMP1
3772#ifdef CBC_TEMP1
3773                                        if (savePerturbation == 50)
3774                                            osiclp->getModelPtr()->setPerturbation(52); // try less
3775#endif
3776                                        if ((model_.moreSpecialOptions()&65536)!=0)
3777                                          process.setOptions(2+4+8); // no cuts
3778                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3779                                                                               tunePreProcess);
3780                                        /*solver2->writeMps("after");
3781                                          saveSolver->writeMps("before");*/
3782                                        osiclp->getModelPtr()->setPerturbation(savePerturbation);
3783                                    }
3784#elif CBC_OTHER_SOLVER==1
3785                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3786                                                                           tunePreProcess);
3787#endif
3788                                    integersOK = false; // We need to redo if CbcObjects exist
3789                                    // Tell solver we are not in Branch and Cut
3790                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3791                                    if (solver2)
3792                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3793                                }
3794#ifdef COIN_HAS_ASL
3795                                if (!solver2 && statusUserFunction_[0]) {
3796                                    // infeasible
3797                                    info.problemStatus = 1;
3798                                    info.objValue = 1.0e100;
3799                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
3800                                    info.primalSolution = NULL;
3801                                    info.dualSolution = NULL;
3802                                    break;
3803                                }
3804#endif
3805                                if (!noPrinting_) {
3806                                    if (!solver2) {
3807                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
3808                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3809                                        << generalPrint
3810                                        << CoinMessageEol;
3811                                    } else {
3812                                        //printf("processed model has %d rows, %d columns and %d elements\n",
3813                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
3814                                    }
3815                                }
3816                                if (!solver2) {
3817                                    // say infeasible for solution
3818                                    integerStatus = 6;
3819                                    model_.setProblemStatus(0);
3820                                    model_.setSecondaryStatus(1);
3821                                    babModel_->setProblemStatus(0);
3822                                    babModel_->setSecondaryStatus(1);
3823                                } else {
3824                                    statistics_nprocessedrows = solver2->getNumRows();
3825                                    statistics_nprocessedcols = solver2->getNumCols();
3826                                    model_.setProblemStatus(-1);
3827                                    babModel_->setProblemStatus(-1);
3828                                }
3829                                int returnCode = callBack(babModel_, 2);
3830                                if (returnCode) {
3831                                    // exit if user wants
3832                                    delete babModel_;
3833                                    babModel_ = NULL;
3834                                    return returnCode;
3835                                }
3836                                if (!solver2)
3837                                    break;
3838                                if (model_.bestSolution()) {
3839                                    // need to redo - in case no better found in BAB
3840                                    // just get integer part right
3841                                    const int * originalColumns = process.originalColumns();
3842                                    int numberColumns = solver2->getNumCols();
3843                                    double * bestSolution = babModel_->bestSolution();
3844                                    const double * oldBestSolution = model_.bestSolution();
3845                                    for (int i = 0; i < numberColumns; i++) {
3846                                        int jColumn = originalColumns[i];
3847                                        bestSolution[i] = oldBestSolution[jColumn];
3848                                    }
3849                                }
3850                                //solver2->resolve();
3851                                if (preProcess == 2) {
3852                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3853                                    ClpSimplex * lpSolver = clpSolver2->getModelPtr();
3854                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
3855                                    printf("Preprocessed model (minimization) on presolved.mps\n");
3856                                }
3857                                {
3858                                    // look at new integers
3859                                    int numberOriginalColumns =
3860                                        process.originalModel()->getNumCols();
3861                                    const int * originalColumns = process.originalColumns();
3862                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3863                                    int numberColumns = osiclp2->getNumCols();
3864                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3865                                    for (int i = 0; i < numberColumns; i++) {
3866                                        int iColumn = originalColumns[i];
3867                                        if (iColumn < numberOriginalColumns) {
3868                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
3869                                                osiclp2->setOptionalInteger(i); // say optional
3870                                        }
3871                                    }
3872                                }
3873                                // we have to keep solver2 so pass clone
3874                                solver2 = solver2->clone();
3875                                babModel_->assignSolver(solver2);
3876                                babModel_->setOriginalColumns(process.originalColumns());
3877                                babModel_->initialSolve();
3878                                babModel_->setMaximumSeconds(timeLeft - (CoinCpuTime() - time2));
3879                            }
3880                            // now tighten bounds
3881                            if (!miplib) {
3882#ifndef CBC_OTHER_SOLVER
3883                                OsiClpSolverInterface * si =
3884                                    dynamic_cast<OsiClpSolverInterface *>(babModel_->solver()) ;
3885                                assert (si != NULL);
3886                                // get clp itself
3887                                ClpSimplex * modelC = si->getModelPtr();
3888                                //if (noPrinting_)
3889                                //modelC->setLogLevel(0);
3890                                if (!complicatedInteger && modelC->tightenPrimalBounds() != 0) {
3891#ifndef DISALLOW_PRINTING
3892                                    std::cout << "Problem is infeasible!" << std::endl;
3893#endif
3894                                    model_.setProblemStatus(0);
3895                                    model_.setSecondaryStatus(1);
3896                                    // and in babModel_ if exists
3897                                    if (babModel_) {
3898                                        babModel_->setProblemStatus(0);
3899                                        babModel_->setSecondaryStatus(1);
3900                                    }
3901                                    break;
3902                                }
3903                                si->resolve();
3904#elif CBC_OTHER_SOLVER==1
3905#endif
3906                            }
3907                            if (debugValues) {
3908                                // for debug
3909                                std::string problemName ;
3910                                babModel_->solver()->getStrParam(OsiProbName, problemName) ;
3911                                babModel_->solver()->activateRowCutDebugger(problemName.c_str()) ;
3912                                twomirGen.probname_ = CoinStrdup(problemName.c_str());
3913                                // checking seems odd
3914                                //redsplitGen.set_given_optsol(babModel_->solver()->getRowCutDebuggerAlways()->optimalSolution(),
3915                                //                         babModel_->getNumCols());
3916                            }
3917                            int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3918                            //#ifdef COIN_HAS_ASL
3919#ifndef JJF_ONE
3920                            // If linked then see if expansion wanted
3921                            {
3922                                OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel_->solver());
3923                                int options = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() / 10000;
3924                                if (solver3 || (options&16) != 0) {
3925                                    if (options) {
3926                                        /*
3927                                          1 - force mini branch and bound
3928                                          2 - set priorities high on continuous
3929                                          4 - try adding OA cuts
3930                                          8 - try doing quadratic linearization
3931                                          16 - try expanding knapsacks
3932                                        */
3933                                        if ((options&16)) {
3934                                            int numberColumns = saveCoinModel.numberColumns();
3935                                            int numberRows = saveCoinModel.numberRows();
3936                                            whichColumn = new int[numberColumns];
3937                                            knapsackStart = new int[numberRows+1];
3938                                            knapsackRow = new int[numberRows];
3939                                            numberKnapsack = 10000;
3940                                            int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3941                                            int extra2 = parameters_[whichParam(CBC_PARAM_INT_EXTRA2, numberParameters_, parameters_)].intValue();
3942                                            int logLevel = parameters_[log].intValue();
3943                                            OsiSolverInterface * solver = expandKnapsack(saveCoinModel, whichColumn, knapsackStart,
3944                                                                          knapsackRow, numberKnapsack,
3945                                                                          storedAmpl, logLevel, extra1, extra2,
3946                                                                          saveTightenedModel);
3947                                            if (solver) {
3948#ifndef CBC_OTHER_SOLVER
3949                                                clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3950                                                assert (clpSolver);
3951                                                lpSolver = clpSolver->getModelPtr();
3952#endif
3953                                                babModel_->assignSolver(solver);
3954                                                testOsiOptions = 0;
3955                                                // allow gomory
3956                                                complicatedInteger = 0;
3957#ifdef COIN_HAS_ASL
3958                                                // Priorities already done
3959                                                free(info.priorities);
3960                                                info.priorities = NULL;
3961#endif
3962                                            } else {
3963                                                numberKnapsack = 0;
3964                                                delete [] whichColumn;
3965                                                delete [] knapsackStart;
3966                                                delete [] knapsackRow;
3967                                                whichColumn = NULL;
3968                                                knapsackStart = NULL;
3969                                                knapsackRow = NULL;
3970                                            }
3971                                        }
3972                                    }
3973                                }
3974                            }
3975#endif
3976                            if (useCosts && testOsiOptions < 0) {
3977                                int numberColumns = babModel_->getNumCols();
3978                                int * sort = new int[numberColumns];
3979                                double * dsort = new double[numberColumns];
3980                                int * priority = new int [numberColumns];
3981                                const double * objective = babModel_->getObjCoefficients();
3982                                const double * lower = babModel_->getColLower() ;
3983                                const double * upper = babModel_->getColUpper() ;
3984                                const CoinPackedMatrix * matrix = babModel_->solver()->getMatrixByCol();
3985                                const int * columnLength = matrix->getVectorLengths();
3986                                int iColumn;
3987                                int n = 0;
3988                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3989                                    if (babModel_->isInteger(iColumn)) {
3990                                        sort[n] = n;
3991                                        if (useCosts == 1)
3992                                            dsort[n++] = -fabs(objective[iColumn]);
3993                                        else if (useCosts == 2)
3994                                            dsort[n++] = iColumn;
3995                                        else if (useCosts == 3)
3996                                            dsort[n++] = upper[iColumn] - lower[iColumn];
3997                                        else if (useCosts == 4)
3998                                            dsort[n++] = -(upper[iColumn] - lower[iColumn]);
3999                                        else if (useCosts == 5)
4000                                            dsort[n++] = -columnLength[iColumn];
4001                                    }
4002                                }
4003                                CoinSort_2(dsort, dsort + n, sort);
4004                                int level = 0;
4005                                double last = -1.0e100;
4006                                for (int i = 0; i < n; i++) {
4007                                    int iPut = sort[i];
4008                                    if (dsort[i] != last) {
4009                                        level++;
4010                                        last = dsort[i];
4011                                    }
4012                                    priority[iPut] = level;
4013                                }
4014                                babModel_->passInPriorities( priority, false);
4015                                integersOK = true;
4016                                delete [] priority;
4017                                delete [] sort;
4018                                delete [] dsort;
4019                            }
4020                            // Set up heuristics
4021                            doHeuristics(babModel_, ((!miplib) ? 1 : 10), parameters_,
4022                                         numberParameters_, noPrinting_, initialPumpTune);
4023                            if (!miplib) {
4024                                if (parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].currentOptionAsInteger()) {
4025                                    CbcTreeLocal localTree(babModel_, NULL, 10, 0, 0, 10000, 2000);
4026                                    babModel_->passInTreeHandler(localTree);
4027                                }
4028                            }
4029                            if (type == CBC_PARAM_ACTION_MIPLIB) {
4030                                if (babModel_->numberStrong() == 5 && babModel_->numberBeforeTrust() == 5)
4031                                    babModel_->setNumberBeforeTrust(10);
4032                            }
4033                            int experimentFlag = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
4034                                                             parameters_)].intValue();
4035                            int strategyFlag = parameters_[whichParam(CBC_PARAM_INT_STRATEGY, numberParameters_,
4036                                                           parameters_)].intValue();
4037                            int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag);
4038                            // add cut generators if wanted
4039                            int switches[30];
4040                            int accuracyFlag[30];
4041                            char doAtEnd[30];
4042                            memset(doAtEnd,0,30);
4043                            int numberGenerators = 0;
4044                            int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1};
4045                            if (probingAction) {
4046                                int numberColumns = babModel_->solver()->getNumCols();
4047                                if (probingAction > 7) {
4048                                    probingGen.setMaxElements(numberColumns);
4049                                    probingGen.setMaxElementsRoot(numberColumns);
4050                                }
4051                                probingGen.setMaxProbeRoot(CoinMin(2000, numberColumns));
4052                                probingGen.setMaxProbeRoot(123);
4053                                probingGen.setMaxProbe(123);
4054                                probingGen.setMaxLookRoot(20);
4055                                if (probingAction == 7 || probingAction == 9)
4056                                    probingGen.setRowCuts(-3); // strengthening etc just at root
4057                                if (probingAction == 8 || probingAction == 9) {
4058                                    // Number of unsatisfied variables to look at
4059                                    probingGen.setMaxProbeRoot(numberColumns);
4060                                    probingGen.setMaxProbe(numberColumns);
4061                                    // How far to follow the consequences
4062                                    probingGen.setMaxLook(50);
4063                                    probingGen.setMaxLookRoot(50);
4064                                }
4065                                if (probingAction == 10) {
4066                                    probingGen.setMaxPassRoot(2);
4067                                    probingGen.setMaxProbeRoot(numberColumns);
4068                                    probingGen.setMaxLookRoot(100);
4069                                }
4070                                // If 5 then force on
4071                                int iAction = translate[probingAction];
4072                                if (probingAction == 5)
4073                                    iAction = 1;
4074                                babModel_->addCutGenerator(&probingGen, iAction, "Probing");
4075                                accuracyFlag[numberGenerators] = 5;
4076                                switches[numberGenerators++] = 0;
4077                            }
4078                            if (gomoryAction && (complicatedInteger != 1 ||
4079                                                 (gomoryAction == 1 || gomoryAction >= 4))) {
4080                                // try larger limit
4081                                int numberColumns = babModel_->getNumCols();
4082                                if (gomoryAction == 7) {
4083                                    gomoryAction = 4;
4084                                    gomoryGen.setLimitAtRoot(numberColumns);
4085                                    gomoryGen.setLimit(numberColumns);
4086                                } else if (gomoryAction == 8) {
4087                                    gomoryAction = 3;
4088                                    gomoryGen.setLimitAtRoot(numberColumns);
4089                                    gomoryGen.setLimit(200);
4090                                } else if (numberColumns > 5000) {
4091                                    //#define MORE_CUTS2
4092#ifdef MORE_CUTS2
4093                                    // try larger limit
4094                                    gomoryGen.setLimitAtRoot(numberColumns);
4095                                    gomoryGen.setLimit(200);
4096#else
4097                                    gomoryGen.setLimitAtRoot(2000);
4098                                    //gomoryGen.setLimit(200);
4099#endif
4100                                } else {
4101#ifdef MORE_CUTS2
4102                                    // try larger limit
4103                                    gomoryGen.setLimitAtRoot(numberColumns);
4104                                    gomoryGen.setLimit(200);
4105#endif
4106                                }
4107                                int cutLength =
4108                                    parameters_[whichParam(CBC_PARAM_INT_CUTLENGTH, numberParameters_, parameters_)].intValue();
4109                                if (cutLength != -1) {
4110                                    gomoryGen.setLimitAtRoot(cutLength);
4111                                    if (cutLength < 10000000) {
4112                                        gomoryGen.setLimit(cutLength);
4113                                    } else {
4114                                        gomoryGen.setLimit(cutLength % 10000000);
4115                                    }
4116                                }
4117                                int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
4118                                int gType = translate[gomoryAction];
4119                                if (!laGomory) {
4120                                  // Normal
4121                                  babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory");
4122                                  accuracyFlag[numberGenerators] = 3;
4123                                  switches[numberGenerators++] = 0;
4124                                } else {
4125                                  laGomory--;
4126                                  int type = (laGomory % 3)+1;
4127                                  int when = laGomory/3;
4128                                  char atEnd = (when<2) ? 1 : 0;
4129                                  int gomoryTypeMajor = 0;
4130                                  if (when<3) {
4131                                    // normal as well
4132                                    babModel_->addCutGenerator(&gomoryGen, gType, "Gomory");
4133                                    accuracyFlag[numberGenerators] = 3;
4134                                    switches[numberGenerators++] = 0;
4135                                    if (when==2)
4136                                      gomoryTypeMajor=10;
4137                                  } else {
4138                                    when--; // so on
4139                                    gomoryTypeMajor=20;
4140                                  }
4141                                  if (!when)
4142                                    gType=-99; // root
4143                                  gomoryGen.passInOriginalSolver(babModel_->solver());
4144                                  if ((type&1) !=0) {
4145                                    // clean
4146                                    gomoryGen.setGomoryType(gomoryTypeMajor+1);
4147                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1");
4148                                    accuracyFlag[numberGenerators] = 3;
4149                                    doAtEnd[numberGenerators]=atEnd;
4150                                    switches[numberGenerators++] = 0;
4151                                  }
4152                                  if ((type&2) !=0) {
4153                                    // simple
4154                                    gomoryGen.setGomoryType(gomoryTypeMajor+2);
4155                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2");
4156                                    accuracyFlag[numberGenerators] = 3;
4157                                    doAtEnd[numberGenerators]=atEnd;
4158                                    switches[numberGenerators++] = 0;
4159                                  }
4160                                }
4161                            }
4162#ifdef CLIQUE_ANALYSIS
4163                            if (miplib && !storedAmpl.sizeRowCuts()) {
4164                                printf("looking at probing\n");
4165                                babModel_->addCutGenerator(&storedAmpl, 1, "Stored");
4166                            }
4167#endif
4168                            if (knapsackAction) {
4169                                babModel_->addCutGenerator(&knapsackGen, translate[knapsackAction], "Knapsack");
4170                                accuracyFlag[numberGenerators] = 1;
4171                                switches[numberGenerators++] = -2;
4172                            }
4173                            if (redsplitAction && !complicatedInteger) {
4174                                babModel_->addCutGenerator(&redsplitGen, translate[redsplitAction], "Reduce-and-split");
4175                                accuracyFlag[numberGenerators] = 5;
4176                                switches[numberGenerators++] = 1;
4177                            }
4178                            if (cliqueAction) {
4179                                babModel_->addCutGenerator(&cliqueGen, translate[cliqueAction], "Clique");
4180                                accuracyFlag[numberGenerators] = 0;
4181                                switches[numberGenerators++] = 0;
4182                            }
4183                            if (mixedAction) {
4184                                babModel_->addCutGenerator(&mixedGen, translate[mixedAction], "MixedIntegerRounding2");
4185                                accuracyFlag[numberGenerators] = 2;
4186                                switches[numberGenerators++] = 0;
4187                            }
4188                            if (flowAction) {
4189                                babModel_->addCutGenerator(&flowGen, translate[flowAction], "FlowCover");
4190                                accuracyFlag[numberGenerators] = 2;
4191                                switches[numberGenerators++] = 1;
4192                            }
4193                            if (twomirAction && (complicatedInteger != 1 ||
4194                                                 (twomirAction == 1 || twomirAction >= 4))) {
4195                                // try larger limit
4196                                int numberColumns = babModel_->getNumCols();
4197                                if (twomirAction == 7) {
4198                                    twomirAction = 4;
4199                                    twomirGen.setMaxElements(numberColumns);
4200                                } else if (numberColumns > 5000 && twomirAction == 4) {
4201                                    twomirGen.setMaxElements(2000);
4202                                }
4203                                babModel_->addCutGenerator(&twomirGen, translate[twomirAction], "TwoMirCuts");
4204                                accuracyFlag[numberGenerators] = 4;
4205                                switches[numberGenerators++] = 1;
4206                            }
4207#ifndef DEBUG_MALLOC
4208                            if (landpAction) {
4209                                babModel_->addCutGenerator(&landpGen, translate[landpAction], "LiftAndProject");
4210                                accuracyFlag[numberGenerators] = 5;
4211                                switches[numberGenerators++] = 1;
4212                            }
4213#endif
4214                            if (residualCapacityAction) {
4215                                babModel_->addCutGenerator(&residualCapacityGen, translate[residualCapacityAction], "ResidualCapacity");
4216                                accuracyFlag[numberGenerators] = 5;
4217                                switches[numberGenerators++] = 1;
4218                            }
4219#ifdef ZERO_HALF_CUTS
4220                            if (zerohalfAction) {
4221                                if (zerohalfAction > 4) {
4222                                    //zerohalfAction -=4;
4223                                    zerohalfGen.setFlags(1);
4224                                }
4225                                babModel_->addCutGenerator(&zerohalfGen, translate[zerohalfAction], "ZeroHalf");
4226                                accuracyFlag[numberGenerators] = 5;
4227                                switches[numberGenerators++] = 2;
4228                            }
4229#endif
4230                            if (dominatedCuts)
4231                                babModel_->setSpecialOptions(babModel_->specialOptions() | 64);
4232                            // Say we want timings
4233                            numberGenerators = babModel_->numberCutGenerators();
4234                            int iGenerator;
4235                            int cutDepth =
4236                                parameters_[whichParam(CBC_PARAM_INT_CUTDEPTH, numberParameters_, parameters_)].intValue();
4237                            for (iGenerator = 0; iGenerator < numberGenerators; iGenerator++) {
4238                                CbcCutGenerator * generator = babModel_->cutGenerator(iGenerator);
4239                                int howOften = generator->howOften();
4240                                if (howOften == -98 || howOften == -99)
4241                                    generator->setSwitchOffIfLessThan(switches[iGenerator]);
4242                                // Use if any at root as more likely later and fairly cheap
4243                                //if (switches[iGenerator]==-2)
4244                                //generator->setWhetherToUse(true);
4245                                generator->setInaccuracy(accuracyFlag[iGenerator]);
4246                                if (doAtEnd[iGenerator]) {
4247                                  generator->setWhetherCallAtEnd(true);
4248                                  generator->setMustCallAgain(true);
4249                                }
4250                                generator->setTiming(true);
4251                                if (cutDepth >= 0)
4252                                    generator->setWhatDepth(cutDepth) ;
4253                            }
4254                            // Could tune more
4255                            if (!miplib) {
4256                                double minimumDrop =
4257                                    fabs(babModel_->solver()->getObjValue()) * 1.0e-5 + 1.0e-5;
4258                                babModel_->setMinimumDrop(CoinMin(5.0e-2, minimumDrop));
4259                                if (cutPass == -1234567) {
4260                                    if (babModel_->getNumCols() < 500)
4261                                        babModel_->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
4262                                    else if (babModel_->getNumCols() < 5000)
4263                                        babModel_->setMaximumCutPassesAtRoot(100); // use minimum drop
4264                                    else
4265                                        babModel_->setMaximumCutPassesAtRoot(20);
4266                                } else {
4267                                    babModel_->setMaximumCutPassesAtRoot(cutPass);
4268                                }
4269                                if (cutPassInTree == -1234567)
4270                                    babModel_->setMaximumCutPasses(4);
4271                                else
4272                                    babModel_->setMaximumCutPasses(cutPassInTree);
4273                            } else if (cutPass != -1234567) {
4274                                babModel_->setMaximumCutPassesAtRoot(cutPass);
4275                            }
4276                            // Do more strong branching if small
4277                            //if (babModel_->getNumCols()<5000)
4278                            //babModel_->setNumberStrong(20);
4279                            // Switch off strong branching if wanted
4280                            //if (babModel_->getNumCols()>10*babModel_->getNumRows())
4281                            //babModel_->setNumberStrong(0);
4282                            if (!noPrinting_) {
4283                                int iLevel = parameters_[log].intValue();
4284                                if (iLevel < 0) {
4285                                    if (iLevel > -10) {
4286                                        babModel_->setPrintingMode(1);
4287                                    } else {
4288                                        babModel_->setPrintingMode(2);
4289                                        iLevel += 10;
4290                                        parameters_[log].setIntValue(iLevel);
4291                                    }
4292                                    iLevel = -iLevel;
4293                                }
4294                                babModel_->messageHandler()->setLogLevel(iLevel);
4295                                if (babModel_->getNumCols() > 2000 || babModel_->getNumRows() > 1500 ||
4296                                        babModel_->messageHandler()->logLevel() > 1)
4297                                    babModel_->setPrintFrequency(100);
4298                            }
4299
4300                            babModel_->solver()->setIntParam(OsiMaxNumIterationHotStart,
4301                                                             parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].intValue());
4302#ifndef CBC_OTHER_SOLVER
4303                            OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
4304                            // go faster stripes
4305                            if ((osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500)) {
4306                                osiclp->setupForRepeatedUse(2, parameters_[slog].intValue());
4307                                if (bothFlags >= 1) {
4308                                    ClpSimplex * lp = osiclp->getModelPtr();
4309                                    int specialOptions = lp->specialOptions();
4310                                    lp->setSpecialOptions(specialOptions | (2048 + 4096));
4311                                }
4312                            } else {
4313                                osiclp->setupForRepeatedUse(0, parameters_[slog].intValue());
4314                            }
4315                            if (bothFlags >= 2) {
4316                                ClpSimplex * lp = osiclp->getModelPtr();
4317                                int specialOptions = lp->specialOptions();
4318                                lp->setSpecialOptions(specialOptions | (2048 + 4096));
4319                            }
4320                            double increment = babModel_->getCutoffIncrement();;
4321                            int * changed = NULL;
4322                            if (!miplib && increment == normalIncrement)
4323                                changed = analyze( osiclp, numberChanged, increment, false, generalMessageHandler, noPrinting);
4324#elif CBC_OTHER_SOLVER==1
4325                            double increment = babModel_->getCutoffIncrement();;
4326#endif
4327                            if (debugValues) {
4328                                int numberColumns = babModel_->solver()->getNumCols();
4329                                if (numberDebugValues == numberColumns) {
4330                                    // for debug
4331                                    babModel_->solver()->activateRowCutDebugger(debugValues) ;
4332                                } else {
4333                                    int numberOriginalColumns =
4334                                        process.originalModel()->getNumCols();
4335                                    if (numberDebugValues <= numberOriginalColumns) {
4336                                        const int * originalColumns = process.originalColumns();
4337                                        double * newValues = new double [numberColumns];
4338                                        // in case preprocess added columns!
4339                                        // need to find values
4340                                        OsiSolverInterface * siCopy =
4341                                            babModel_->solver()->clone();
4342                                        for (int i = 0; i < numberColumns; i++) {
4343                                            int jColumn = originalColumns[i];
4344                                            if (jColumn < numberDebugValues &&
4345                                                    siCopy->isInteger(i)) {
4346                                                // integer variable
4347                                                double soln = floor(debugValues[jColumn] + 0.5);
4348                                                // Set bounds to fix variable to its solution
4349                                                siCopy->setColUpper(i, soln);
4350                                                siCopy->setColLower(i, soln);
4351                                            }
4352                                        }
4353                                        // All integers have been fixed at optimal value.
4354                                        // Now solve to get continuous values
4355                                        siCopy->setHintParam(OsiDoScale, false);
4356                                        siCopy->initialSolve();
4357                                        if (siCopy->isProvenOptimal()) {
4358                                            memcpy(newValues, siCopy->getColSolution(),
4359                                                   numberColumns*sizeof(double));
4360                                        } else {
4361                                            printf("BAD debug file\n");
4362                                            siCopy->writeMps("Bad");
4363                                            exit(22);
4364                                        }
4365                                        delete siCopy;
4366                                        // for debug
4367                                        babModel_->solver()->activateRowCutDebugger(newValues) ;
4368                                        delete [] newValues;
4369                                    } else {
4370                                        printf("debug file has incorrect number of columns\n");
4371                                    }
4372                                }
4373                            }
4374                            babModel_->setCutoffIncrement(CoinMax(babModel_->getCutoffIncrement(), increment));
4375                            // Turn this off if you get problems
4376                            // Used to be automatically set
4377                            int mipOptions = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() % 10000;
4378                            if (mipOptions != (1057)) {
4379                                sprintf(generalPrint, "mip options %d", mipOptions);
4380                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
4381                                << generalPrint
4382                                << CoinMessageEol;
4383                            }
4384#ifndef CBC_OTHER_SOLVER
4385                            osiclp->setSpecialOptions(mipOptions);
4386#elif CBC_OTHER_SOLVER==1
4387#endif
4388                            // probably faster to use a basis to get integer solutions
4389                            babModel_->setSpecialOptions(babModel_->specialOptions() | 2);
4390                            currentBranchModel = babModel_;
4391                            //OsiSolverInterface * strengthenedModel=NULL;
4392                            if (type == CBC_PARAM_ACTION_BAB ||
4393                                    type == CBC_PARAM_ACTION_MIPLIB) {
4394                                if (strategyFlag == 1) {
4395                                    // try reduced model
4396                                    babModel_->setSpecialOptions(babModel_->specialOptions() | 512);
4397                                }
4398                                if (experimentFlag >= 5 || strategyFlag == 2) {
4399                                    // try reduced model at root
4400                                    babModel_->setSpecialOptions(babModel_->specialOptions() | 32768);
4401                                }
4402                                {
4403                                    int depthMiniBab = parameters_[whichParam(CBC_PARAM_INT_DEPTHMINIBAB, numberParameters_, parameters_)].intValue();
4404                                    if (depthMiniBab != -1)
4405                                        babModel_->setFastNodeDepth(depthMiniBab);
4406                                }
4407                                int extra4 = parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].intValue();
4408                                if (extra4 >= 0) {
4409                                    int strategy = extra4 % 10;
4410                                    extra4 /= 10;
4411                                    int method = extra4 % 100;
4412                                    extra4 /= 100;
4413                                    extra4 = strategy + method * 8 + extra4 * 1024;
4414                                    babModel_->setMoreSpecialOptions(extra4);
4415                                }
4416                                int moreMipOptions = parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].intValue();
4417                                if (moreMipOptions >= 0) {
4418                                    sprintf(generalPrint, "more mip options %d", moreMipOptions);
4419                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4420                                    << generalPrint
4421                                    << CoinMessageEol;
4422                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
4423                                    if (moreMipOptions == 10000) {
4424                                        // test memory saving
4425                                        moreMipOptions -= 10000;
4426                                        ClpSimplex * lpSolver = osiclp->getModelPtr();
4427                                        lpSolver->setPersistenceFlag(1);
4428                                        // switch off row copy if few rows
4429                                        if (lpSolver->numberRows() < 150)
4430                                            lpSolver->setSpecialOptions(lpSolver->specialOptions() | 256);
4431                                    }
4432                                    if (moreMipOptions < 10000 && moreMipOptions) {
4433                                        if (((moreMipOptions + 1) % 1000000) != 0)
4434                                            babModel_->setSearchStrategy(moreMipOptions % 1000000);
4435                                    } else if (moreMipOptions < 100000) {
4436                                        // try reduced model
4437                                        babModel_->setSpecialOptions(babModel_->specialOptions() | 512);
4438                                    }
4439                                    // go faster stripes
4440                                    if ( moreMipOptions >= 999999) {
4441                                        if (osiclp) {
4442                                            int save = osiclp->specialOptions();
4443                                            osiclp->setupForRepeatedUse(2, 0);
4444                                            osiclp->setSpecialOptions(save | osiclp->specialOptions());
4445                                        }
4446                                    }
4447                                }
4448                            }
4449                            {
4450                                int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
4451                                if (extra1 != -1) {
4452                                    if (extra1 < 0) {
4453                                        if (extra1 == -7777)
4454                                            extra1 = -1;
4455                                        else if (extra1 == -8888)
4456                                            extra1 = 1;
4457                                        babModel_->setWhenCuts(-extra1);
4458                                    } else if (extra1 < 19000) {
4459                                        babModel_->setSearchStrategy(extra1);
4460                                        printf("XXXXX searchStrategy %d\n", extra1);
4461                                    } else {
4462                                        int n = extra1 - 20000;
4463                                        if (!n)
4464                                            n--;
4465                                        babModel_->setNumberAnalyzeIterations(n);
4466                                        printf("XXXXX analyze %d\n", extra1);
4467                                    }
4468                                } else if (bothFlags >= 1) {
4469                                    babModel_->setWhenCuts(999998);
4470                                }
4471                            }
4472                            if (type == CBC_PARAM_ACTION_BAB) {
4473#ifdef COIN_HAS_ASL
4474                                if (statusUserFunction_[0]) {
4475                                    priorities = info.priorities;
4476                                    branchDirection = info.branchDirection;
4477                                    pseudoDown = info.pseudoDown;
4478                                    pseudoUp = info.pseudoUp;
4479                                    solutionIn = info.primalSolution;
4480                                    prioritiesIn = info.priorities;
4481                                    if (info.numberSos && doSOS) {
4482                                        // SOS
4483                                        numberSOS = info.numberSos;
4484                                        sosStart = info.sosStart;
4485                                        sosIndices = info.sosIndices;
4486                                        sosType = info.sosType;
4487                                        sosReference = info.sosReference;
4488                                        sosPriority = info.sosPriority;
4489                                    }
4490                                }
4491#endif
4492                                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
4493                                if (solutionIn && useSolution >= 0) {
4494                                    if (!prioritiesIn) {
4495                                        int n;
4496                                        if (preProcess) {
4497                                            int numberColumns = babModel_->getNumCols();
4498                                            // extend arrays in case SOS
4499                                            n = originalColumns[numberColumns-1] + 1;
4500                                        } else {
4501                                            n = babModel_->getNumCols();
4502                                        }
4503                                        prioritiesIn = reinterpret_cast<int *> (malloc(n * sizeof(int)));
4504                                        for (int i = 0; i < n; i++)
4505                                            prioritiesIn[i] = 100;
4506                                    }
4507                                    if (preProcess) {
4508                                        int numberColumns = babModel_->getNumCols();
4509                                        // extend arrays in case SOS
4510                                        int n = originalColumns[numberColumns-1] + 1;
4511                                        int nSmaller = CoinMin(n, numberOriginalColumns);
4512                                        double * solutionIn2 = new double [n];
4513                                        int * prioritiesIn2 = new int[n];
4514                                        int i;
4515                                        for (i = 0; i < nSmaller; i++) {
4516                                            solutionIn2[i] = solutionIn[i];
4517                                            prioritiesIn2[i] = prioritiesIn[i];
4518                                        }
4519                                        for (; i < n; i++) {
4520                                            solutionIn2[i] = 0.0;
4521                                            prioritiesIn2[i] = 1000000;
4522                                        }
4523                                        int iLast = -1;
4524                                        for (i = 0; i < numberColumns; i++) {
4525                                            int iColumn = originalColumns[i];
4526                                            assert (iColumn > iLast);
4527                                            iLast = iColumn;
4528                                            solutionIn2[i] = solutionIn2[iColumn];
4529                                            if (prioritiesIn)
4530                                                prioritiesIn2[i] = prioritiesIn2[iColumn];
4531                                        }
4532                                        if (useSolution)
4533                                            babModel_->setHotstartSolution(solutionIn2, prioritiesIn2);
4534                                        else
4535                                            babModel_->setBestSolution(solutionIn2, numberColumns,
4536                                                                       COIN_DBL_MAX, true);
4537                                        delete [] solutionIn2;
4538                                        delete [] prioritiesIn2;
4539                                    } else {
4540                                        if (useSolution)
4541                                            babModel_->setHotstartSolution(solutionIn, prioritiesIn);
4542                                        else
4543                                            babModel_->setBestSolution(solutionIn, babModel_->getNumCols(),
4544                                                                       COIN_DBL_MAX, true);
4545                                    }
4546                                }
4547                                OsiSolverInterface * testOsiSolver = (testOsiOptions >= 0) ? babModel_->solver() : NULL;
4548                                if (!testOsiSolver) {
4549                                    // *************************************************************
4550                                    // CbcObjects
4551                                    if (preProcess && (process.numberSOS() || babModel_->numberObjects())) {
4552                                        int numberSOS = process.numberSOS();
4553                                        int numberIntegers = babModel_->numberIntegers();
4554                                        /* model may not have created objects
4555                                           If none then create
4556                                        */
4557                                        if (!numberIntegers || !babModel_->numberObjects()) {
4558                                            int type = (pseudoUp) ? 1 : 0;
4559                                            babModel_->findIntegers(true, type);
4560                                            numberIntegers = babModel_->numberIntegers();
4561                                            integersOK = true;
4562                                        }
4563                                        OsiObject ** oldObjects = babModel_->objects();
4564                                        // Do sets and priorities
4565                                        OsiObject ** objects = new OsiObject * [numberSOS];
4566                                        // set old objects to have low priority
4567                                        int numberOldObjects = babModel_->numberObjects();
4568                                        int numberColumns = babModel_->getNumCols();
4569                                        // backward pointer to new variables
4570                                        // extend arrays in case SOS
4571                                        assert (originalColumns);
4572                                        int n = originalColumns[numberColumns-1] + 1;
4573                                        n = CoinMax(n, CoinMax(numberColumns, numberOriginalColumns));
4574                                        int * newColumn = new int[n];
4575                                        int i;
4576                                        for (i = 0; i < numberOriginalColumns; i++)
4577                                            newColumn[i] = -1;
4578                                        for (i = 0; i < numberColumns; i++)
4579                                            newColumn[originalColumns[i]] = i;
4580                                        if (!integersOK) {
4581                                            // Change column numbers etc
4582                                            int n = 0;
4583                                            for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4584                                                int iColumn = oldObjects[iObj]->columnNumber();
4585                                                if (iColumn < 0 || iColumn >= numberOriginalColumns) {
4586                                                    oldObjects[n++] = oldObjects[iObj];
4587                                                } else {
4588                                                    iColumn = newColumn[iColumn];
4589                                                    if (iColumn >= 0) {
4590                                                        CbcSimpleInteger * obj =
4591                                                            dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
4592                                                        if (obj) {
4593                                                            obj->setColumnNumber(iColumn);
4594                                                        } else {
4595                                                            // only other case allowed is lotsizing
4596                                                            CbcLotsize * obj2 =
4597                                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
4598                                                            assert (obj2);
4599                                                            obj2->setModelSequence(iColumn);
4600                                                        }
4601                                                        oldObjects[n++] = oldObjects[iObj];
4602                                                    } else {
4603                                                        delete oldObjects[iObj];
4604                                                    }
4605                                                }
4606                                            }
4607                                            babModel_->setNumberObjects(n);
4608                                            numberOldObjects = n;
4609                                            babModel_->zapIntegerInformation();
4610                                        }
4611                                        int nMissing = 0;
4612                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4613                                            if (process.numberSOS())
4614                                                oldObjects[iObj]->setPriority(numberColumns + 1);
4615                                            int iColumn = oldObjects[iObj]->columnNumber();
4616                                            if (iColumn < 0 || iColumn >= numberOriginalColumns) {
4617                                                CbcSOS * obj =
4618                                                    dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
4619                                                if (obj) {
4620                                                    int n = obj->numberMembers();
4621                                                    int * which = obj->mutableMembers();
4622                                                    double * weights = obj->mutableWeights();
4623                                                    int nn = 0;
4624                                                    for (i = 0; i < n; i++) {
4625                                                        int iColumn = which[i];
4626                                                        int jColumn = newColumn[iColumn];
4627                                                        if (jColumn >= 0) {
4628                                                            which[nn] = jColumn;
4629                                                            weights[nn++] = weights[i];
4630                                                        } else {
4631                                                            nMissing++;
4632                                                        }
4633                                                    }
4634                                                    obj->setNumberMembers(nn);
4635                                                }
4636                                                continue;
4637                                            }
4638                                            if (originalColumns)
4639                                                iColumn = originalColumns[iColumn];
4640                                            if (branchDirection) {
4641                                                CbcSimpleInteger * obj =
4642                                                    dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
4643                                                if (obj) {
4644                                                    obj->setPreferredWay(branchDirection[iColumn]);
4645                                                } else {
4646                                                    CbcObject * obj =
4647                                                        dynamic_cast <CbcObject *>(oldObjects[iObj]) ;
4648                                                    assert (obj);
4649                                                    obj->setPreferredWay(branchDirection[iColumn]);
4650                                                }
4651                                            }
4652                                            if (pseudoUp) {
4653                                                CbcSimpleIntegerPseudoCost * obj1a =
4654                                                    dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
4655                                                assert (obj1a);
4656                                                if (pseudoDown[iColumn] > 0.0)
4657                                                    obj1a->setDownPseudoCost(pseudoDown[iColumn]);
4658                                                if (pseudoUp[iColumn] > 0.0)
4659                                                    obj1a->setUpPseudoCost(pseudoUp[iColumn]);
4660                                            }
4661                                        }
4662                                        if (nMissing) {
4663                                            sprintf(generalPrint, "%d SOS variables vanished due to pre processing? - check validity?", nMissing);
4664                                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
4665                                            << generalPrint
4666                                            << CoinMessageEol;
4667                                        }
4668                                        delete [] newColumn;
4669                                        const int * starts = process.startSOS();
4670                                        const int * which = process.whichSOS();
4671                                        const int * type = process.typeSOS();
4672                                        const double * weight = process.weightSOS();
4673                                        int iSOS;
4674                                        for (iSOS = 0; iSOS < numberSOS; iSOS++) {
4675                                            int iStart = starts[iSOS];
4676                                            int n = starts[iSOS+1] - iStart;
4677                                            objects[iSOS] = new CbcSOS(babModel_, n, which + iStart, weight + iStart,
4678                                                                       iSOS, type[iSOS]);
4679                                            // branch on long sets first
4680                                            objects[iSOS]->setPriority(numberColumns - n);
4681                                        }
4682                                        if (numberSOS)
4683                                            babModel_->addObjects(numberSOS, objects);
4684                                        for (iSOS = 0; iSOS < numberSOS; iSOS++)
4685                                            delete objects[iSOS];
4686                                        delete [] objects;
4687                                    } else if (priorities || branchDirection || pseudoDown || pseudoUp || numberSOS) {
4688                                        // do anyway for priorities etc
4689                                        int numberIntegers = babModel_->numberIntegers();
4690                                        /* model may not have created objects
4691                                           If none then create
4692                                        */
4693                                        if (!numberIntegers || !babModel_->numberObjects()) {
4694                                            int type = (pseudoUp) ? 1 : 0;
4695                                            babModel_->findIntegers(true, type);
4696                                        }
4697                                        if (numberSOS) {
4698                                            // Do sets and priorities
4699                                            OsiObject ** objects = new OsiObject * [numberSOS];
4700                                            int iSOS;
4701                                            if (originalColumns) {
4702                                                // redo sequence numbers
4703                                                int numberColumns = babModel_->getNumCols();
4704                                                int nOld = originalColumns[numberColumns-1] + 1;
4705                                                int * back = new int[nOld];
4706                                                int i;
4707                                                for (i = 0; i < nOld; i++)
4708                                                    back[i] = -1;
4709                                                for (i = 0; i < numberColumns; i++)
4710                                                    back[originalColumns[i]] = i;
4711                                                // Really need better checks
4712                                                int nMissing = 0;
4713                                                int n = sosStart[numberSOS];
4714                                                for (i = 0; i < n; i++) {
4715                                                    int iColumn = sosIndices[i];
4716                                                    int jColumn = back[iColumn];
4717                                                    if (jColumn >= 0)
4718                                                        sosIndices[i] = jColumn;
4719                                                    else
4720                                                        nMissing++;
4721                                                }
4722                                                delete [] back;
4723                                                if (nMissing) {
4724                                                    sprintf(generalPrint, "%d SOS variables vanished due to pre processing? - check validity?", nMissing);
4725                                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4726                                                    << generalPrint
4727                                                    << CoinMessageEol;
4728                                                }
4729                                            }
4730                                            for (iSOS = 0; iSOS < numberSOS; iSOS++) {
4731                                                int iStart = sosStart[iSOS];
4732                                                int n = sosStart[iSOS+1] - iStart;
4733                                                objects[iSOS] = new CbcSOS(babModel_, n, sosIndices + iStart, sosReference + iStart,
4734                                                                           iSOS, sosType[iSOS]);
4735                                                if (sosPriority)
4736                                                    objects[iSOS]->setPriority(sosPriority[iSOS]);
4737                                                else if (!prioritiesIn)
4738                                                    objects[iSOS]->setPriority(10);  // rather than 1000
4739                                            }
4740