source: branches/sandbox/Cbc/src/CbcSolver.cpp @ 1395

Last change on this file since 1395 was 1395, checked in by bjarni, 10 years ago

Extracted analyze() from CbcSolver?.cpp and placed it in CbcSolverAnalyze?.cpp, updated libCbc.vcproj (v9) to include CbcSolverAnalyze?.cpp

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