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

Last change on this file since 1650 was 1650, checked in by forrest, 9 years ago

messages for fathoming plus soem attempts at robustness

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