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

Last change on this file since 1626 was 1626, checked in by forrest, 10 years ago

correct timings printed

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