source: stable/2.6/Cbc/src/CbcSolver.cpp @ 1627

Last change on this file since 1627 was 1627, checked in by tkr, 8 years ago

Merging r1623 from trunk

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