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

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

allow glpk solution file

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