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

Last change on this file since 1954 was 1954, checked in by forrest, 6 years ago

new event plus flexible output format

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