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

Last change on this file since 1607 was 1607, checked in by lou, 9 years ago

Make logLevel command work again. New build system does not define
COIN_HAS_CBC in cbc. Remove useless include from CoinSolve?.

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