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

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

Change CBCVERSION to CBC_VERSION for compatibility. Update externals for final
stable prior to move to split configuration. Add Dependencies file.

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