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

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

fix segfault if infeasible

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