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

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

allow absolute paths in gmpl files

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