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

Last change on this file since 1706 was 1706, checked in by forrest, 8 years ago

allow names for gmpl

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