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

Last change on this file since 2040 was 2040, checked in by forrest, 5 years ago

fixes for odd SOS

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