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

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

allow for elapsed time on unix

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