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

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

fix error if orbital not activated and add example

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