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

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

Attempt to fix AMPL interface

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