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

Last change on this file since 1876 was 1876, checked in by forrest, 9 years ago

changes for cuts and extra variables

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