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

Last change on this file since 1769 was 1769, checked in by forrest, 10 years ago

changes to allow multiple solutions in standalone executable

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