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

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

make zerohalf work with threads

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