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

Last change on this file since 1826 was 1826, checked in by stefan, 7 years ago

remove ifdef for KEEP_POSTPROCESS, its always on in Cgl trunk and 0.58

File size: 511.7 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#include "CbcMipStartIO.hpp"
52
53#include "CbcSolverHeuristics.hpp"
54#ifdef COIN_HAS_GLPK
55#include "glpk.h"
56extern glp_tran* cbc_glp_tran;
57extern glp_prob* cbc_glp_prob;
58#else
59#define GLP_UNDEF 1
60#define GLP_FEAS 2
61#define GLP_INFEAS 3
62#define GLP_NOFEAS 4
63#define GLP_OPT 5
64#endif
65
66#ifndef CBC_QUIET
67#define CBC_QUIET 0
68#endif
69
70//#define USER_HAS_FAKE_CLP
71//#define USER_HAS_FAKE_CBC
72
73//#define CLP_MALLOC_STATISTICS
74
75#ifdef CLP_MALLOC_STATISTICS
76#include <malloc.h>
77#include <exception>
78#include <new>
79#include "stolen_from_ekk_malloc.cpp"
80static double malloc_times = 0.0;
81static double malloc_total = 0.0;
82static int malloc_amount[] = {0, 32, 128, 256, 1024, 4096, 16384, 65536, 262144, INT_MAX};
83static int malloc_n = 10;
84double malloc_counts[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
85bool malloc_counts_on = true;
86void * operator new (size_t size) throw (std::bad_alloc)
87{
88    malloc_times ++;
89    malloc_total += size;
90    int i;
91    for (i = 0; i < malloc_n; i++) {
92        if ((int) size <= malloc_amount[i]) {
93            malloc_counts[i]++;
94            break;
95        }
96    }
97# ifdef DEBUG_MALLOC
98    void *p;
99    if (malloc_counts_on)
100        p = stolen_from_ekk_mallocBase(size);
101    else
102        p = malloc(size);
103# else
104    void * p = malloc(size);
105# endif
106    //char * xx = (char *) p;
107    //memset(xx,0,size);
108    // Initialize random seed
109    //CoinSeedRandom(987654321);
110    return p;
111}
112void operator delete (void *p) throw()
113{
114# ifdef DEBUG_MALLOC
115    if (malloc_counts_on)
116        stolen_from_ekk_freeBase(p);
117    else
118        free(p);
119# else
120    free(p);
121# endif
122}
123static void malloc_stats2()
124{
125    double average = malloc_total / malloc_times;
126    printf("count %g bytes %g - average %g\n", malloc_times, malloc_total, average);
127    for (int i = 0; i < malloc_n; i++)
128        printf("%g ", malloc_counts[i]);
129    printf("\n");
130    malloc_times = 0.0;
131    malloc_total = 0.0;
132    memset(malloc_counts, 0, sizeof(malloc_counts));
133    // print results
134}
135#else   //CLP_MALLOC_STATISTICS
136//void stolen_from_ekk_memory(void * dummy,int type)
137//{
138//}
139//bool malloc_counts_on=false;
140#endif  //CLP_MALLOC_STATISTICS
141
142//#define DMALLOC
143#ifdef DMALLOC
144#include "dmalloc.h"
145#endif
146
147#ifdef WSSMP_BARRIER
148#define FOREIGN_BARRIER
149#endif
150
151#ifdef UFL_BARRIER
152#define FOREIGN_BARRIER
153#endif
154
155#ifdef TAUCS_BARRIER
156#define FOREIGN_BARRIER
157#endif
158
159static int initialPumpTune = -1;
160#include "CoinWarmStartBasis.hpp"
161
162#include "OsiSolverInterface.hpp"
163#include "OsiCuts.hpp"
164#include "OsiRowCut.hpp"
165#include "OsiColCut.hpp"
166
167#ifndef COIN_HAS_LINK
168#define COIN_HAS_LINK
169#endif
170#ifdef COIN_HAS_LINK
171#include "CbcLinked.hpp"
172#endif
173
174#include "CglPreProcess.hpp"
175#include "CglCutGenerator.hpp"
176#include "CglGomory.hpp"
177#include "CglProbing.hpp"
178#include "CglKnapsackCover.hpp"
179#include "CglRedSplit.hpp"
180#include "CglClique.hpp"
181#include "CglFlowCover.hpp"
182#include "CglMixedIntegerRounding2.hpp"
183#include "CglTwomir.hpp"
184#include "CglDuplicateRow.hpp"
185#include "CglStored.hpp"
186#include "CglLandP.hpp"
187#include "CglResidualCapacity.hpp"
188
189#ifdef ZERO_HALF_CUTS
190#include "CglZeroHalf.hpp"
191#endif
192//#define CGL_WRITEMPS
193#ifdef CGL_WRITEMPS
194extern double * debugSolution;
195extern int debugNumberColumns;
196#endif
197#include "CbcModel.hpp"
198#include "CbcHeuristic.hpp"
199#include "CbcHeuristicLocal.hpp"
200#include "CbcHeuristicPivotAndFix.hpp"
201//#include "CbcHeuristicPivotAndComplement.hpp"
202#include "CbcHeuristicRandRound.hpp"
203#include "CbcHeuristicGreedy.hpp"
204#include "CbcHeuristicFPump.hpp"
205#include "CbcHeuristicRINS.hpp"
206#include "CbcHeuristicDiveCoefficient.hpp"
207#include "CbcHeuristicDiveFractional.hpp"
208#include "CbcHeuristicDiveGuided.hpp"
209#include "CbcHeuristicDiveVectorLength.hpp"
210#include "CbcHeuristicDivePseudoCost.hpp"
211#include "CbcHeuristicDiveLineSearch.hpp"
212#include "CbcTreeLocal.hpp"
213#include "CbcCompareActual.hpp"
214#include "CbcBranchActual.hpp"
215#include "CbcBranchLotsize.hpp"
216#include  "CbcOrClpParam.hpp"
217#include  "CbcCutGenerator.hpp"
218#include  "CbcStrategy.hpp"
219#include "CbcBranchCut.hpp"
220
221#include "OsiClpSolverInterface.hpp"
222
223#include "CbcSolverAnalyze.hpp"
224#include "CbcSolverExpandKnapsack.hpp"
225
226#include "CbcSolver.hpp"
227
228//#define IN_BRANCH_AND_BOUND (0x01000000|262144)
229#define IN_BRANCH_AND_BOUND (0x01000000|262144|128|1024|2048)
230//#define IN_BRANCH_AND_BOUND (0x01000000|262144|128)
231
232/*
233  CbcStopNow class definitions.
234*/
235
236CbcStopNow::CbcStopNow()
237{
238}
239CbcStopNow::~CbcStopNow()
240{
241}
242// Copy constructor
243CbcStopNow::CbcStopNow ( const CbcStopNow & )
244{
245}
246// Assignment operator
247CbcStopNow &
248CbcStopNow::operator=(const CbcStopNow & rhs)
249{
250    if (this != &rhs) {
251    }
252    return *this;
253}
254// Clone
255CbcStopNow *
256CbcStopNow::clone() const
257{
258    return new CbcStopNow(*this);
259}
260
261/*
262  CbcUser class definitions.
263*/
264
265// User stuff (base class)
266CbcUser::CbcUser()
267        : coinModel_(NULL),
268        userName_("null")
269{
270}
271CbcUser::~CbcUser()
272{
273    delete coinModel_;
274}
275// Copy constructor
276CbcUser::CbcUser ( const CbcUser & rhs)
277{
278    if (rhs.coinModel_)
279        coinModel_ = new CoinModel(*rhs.coinModel_);
280    else
281        coinModel_ = NULL;
282    userName_ = rhs.userName_;
283}
284// Assignment operator
285CbcUser &
286CbcUser::operator=(const CbcUser & rhs)
287{
288    if (this != &rhs) {
289        if (rhs.coinModel_)
290            coinModel_ = new CoinModel(*rhs.coinModel_);
291        else
292            coinModel_ = NULL;
293        userName_ = rhs.userName_;
294    }
295    return *this;
296}
297
298static void putBackOtherSolutions(CbcModel * presolvedModel, CbcModel * model,
299                           CglPreProcess * preProcess)
300{
301  int numberSolutions=presolvedModel->numberSavedSolutions();
302  int numberColumns=presolvedModel->getNumCols();
303  if (numberSolutions>1) {
304    double * bestSolution = CoinCopyOfArray(presolvedModel->bestSolution(),numberColumns);
305    //double cutoff = presolvedModel->getCutoff();
306    double objectiveValue=presolvedModel->getObjValue();
307    //model->createSpaceForSavedSolutions(numberSolutions-1);
308    for (int iSolution=numberSolutions-1;iSolution>=0;iSolution--) {
309      presolvedModel->setCutoff(COIN_DBL_MAX);
310      presolvedModel->solver()->setColSolution(presolvedModel->savedSolution(iSolution));
311      //presolvedModel->savedSolutionObjective(iSolution));
312      preProcess->postProcess(*presolvedModel->solver(),false);
313      model->setBestSolution(preProcess->originalModel()->getColSolution(),model->solver()->getNumCols(),
314                             presolvedModel->savedSolutionObjective(iSolution));
315    }
316    presolvedModel->setBestObjectiveValue(objectiveValue);
317    presolvedModel->solver()->setColSolution(bestSolution);
318    //presolvedModel->setBestSolution(bestSolution,numberColumns,objectiveValue);
319  }
320}
321
322/*
323  CbcSolver class definitions
324*/
325
326CbcSolver::CbcSolver()
327        : babModel_(NULL),
328        userFunction_(NULL),
329        statusUserFunction_(NULL),
330        originalSolver_(NULL),
331        originalCoinModel_(NULL),
332        cutGenerator_(NULL),
333        numberUserFunctions_(0),
334        numberCutGenerators_(0),
335        startTime_(CoinCpuTime()),
336        parameters_(NULL),
337        numberParameters_(0),
338        doMiplib_(false),
339        noPrinting_(false),
340        readMode_(1)
341{
342    callBack_ = new CbcStopNow();
343    fillParameters();
344}
345CbcSolver::CbcSolver(const OsiClpSolverInterface & solver)
346        : babModel_(NULL),
347        userFunction_(NULL),
348        statusUserFunction_(NULL),
349        originalSolver_(NULL),
350        originalCoinModel_(NULL),
351        cutGenerator_(NULL),
352        numberUserFunctions_(0),
353        numberCutGenerators_(0),
354        startTime_(CoinCpuTime()),
355        parameters_(NULL),
356        numberParameters_(0),
357        doMiplib_(false),
358        noPrinting_(false),
359        readMode_(1)
360{
361    callBack_ = new CbcStopNow();
362    model_ = CbcModel(solver);
363    fillParameters();
364}
365CbcSolver::CbcSolver(const CbcModel & solver)
366        : babModel_(NULL),
367        userFunction_(NULL),
368        statusUserFunction_(NULL),
369        originalSolver_(NULL),
370        originalCoinModel_(NULL),
371        cutGenerator_(NULL),
372        numberUserFunctions_(0),
373        numberCutGenerators_(0),
374        startTime_(CoinCpuTime()),
375        parameters_(NULL),
376        numberParameters_(0),
377        doMiplib_(false),
378        noPrinting_(false),
379        readMode_(1)
380{
381    callBack_ = new CbcStopNow();
382    model_ = solver;
383    fillParameters();
384}
385CbcSolver::~CbcSolver()
386{
387    int i;
388    for (i = 0; i < numberUserFunctions_; i++)
389        delete userFunction_[i];
390    delete [] userFunction_;
391    for (i = 0; i < numberCutGenerators_; i++)
392        delete cutGenerator_[i];
393    delete [] cutGenerator_;
394    delete [] statusUserFunction_;
395    delete originalSolver_;
396    delete originalCoinModel_;
397    delete babModel_;
398    delete [] parameters_;
399    delete callBack_;
400}
401// Copy constructor
402CbcSolver::CbcSolver ( const CbcSolver & rhs)
403        : model_(rhs.model_),
404        babModel_(NULL),
405        userFunction_(NULL),
406        statusUserFunction_(NULL),
407        numberUserFunctions_(rhs.numberUserFunctions_),
408        startTime_(CoinCpuTime()),
409        parameters_(NULL),
410        numberParameters_(rhs.numberParameters_),
411        doMiplib_(rhs.doMiplib_),
412        noPrinting_(rhs.noPrinting_),
413        readMode_(rhs.readMode_)
414{
415    fillParameters();
416    if (rhs.babModel_)
417        babModel_ = new CbcModel(*rhs.babModel_);
418    userFunction_ = new CbcUser * [numberUserFunctions_];
419    int i;
420    for (i = 0; i < numberUserFunctions_; i++)
421        userFunction_[i] = rhs.userFunction_[i]->clone();
422    for (i = 0; i < numberParameters_; i++)
423        parameters_[i] = rhs.parameters_[i];
424    for (i = 0; i < numberCutGenerators_; i++)
425        cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
426    callBack_ = rhs.callBack_->clone();
427    originalSolver_ = NULL;
428    if (rhs.originalSolver_) {
429        OsiSolverInterface * temp = rhs.originalSolver_->clone();
430        originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
431        assert (originalSolver_);
432    }
433    originalCoinModel_ = NULL;
434    if (rhs.originalCoinModel_)
435        originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
436}
437// Assignment operator
438CbcSolver &
439CbcSolver::operator=(const CbcSolver & rhs)
440{
441    if (this != &rhs) {
442        int i;
443        for (i = 0; i < numberUserFunctions_; i++)
444            delete userFunction_[i];
445        delete [] userFunction_;
446        for (i = 0; i < numberCutGenerators_; i++)
447            delete cutGenerator_[i];
448        delete [] cutGenerator_;
449        delete [] statusUserFunction_;
450        delete originalSolver_;
451        delete originalCoinModel_;
452        statusUserFunction_ = NULL;
453        delete babModel_;
454        delete [] parameters_;
455        delete callBack_;
456        numberUserFunctions_ = rhs.numberUserFunctions_;
457        startTime_ = rhs.startTime_;
458        numberParameters_ = rhs.numberParameters_;
459        for (i = 0; i < numberParameters_; i++)
460            parameters_[i] = rhs.parameters_[i];
461        for (i = 0; i < numberCutGenerators_; i++)
462            cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
463        noPrinting_ = rhs.noPrinting_;
464        readMode_ = rhs.readMode_;
465        doMiplib_ = rhs.doMiplib_;
466        model_ = rhs.model_;
467        if (rhs.babModel_)
468            babModel_ = new CbcModel(*rhs.babModel_);
469        else
470            babModel_ = NULL;
471        userFunction_ = new CbcUser * [numberUserFunctions_];
472        for (i = 0; i < numberUserFunctions_; i++)
473            userFunction_[i] = rhs.userFunction_[i]->clone();
474        callBack_ = rhs.callBack_->clone();
475        originalSolver_ = NULL;
476        if (rhs.originalSolver_) {
477            OsiSolverInterface * temp = rhs.originalSolver_->clone();
478            originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
479            assert (originalSolver_);
480        }
481        originalCoinModel_ = NULL;
482        if (rhs.originalCoinModel_)
483            originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
484    }
485    return *this;
486}
487// Get int value
488int CbcSolver::intValue(CbcOrClpParameterType type) const
489{
490    return parameters_[whichParam(type, numberParameters_, parameters_)].intValue();
491}
492// Set int value
493void CbcSolver::setIntValue(CbcOrClpParameterType type, int value)
494{
495    parameters_[whichParam(type, numberParameters_, parameters_)].setIntValue(value);
496}
497// Get double value
498double CbcSolver::doubleValue(CbcOrClpParameterType type) const
499{
500    return parameters_[whichParam(type, numberParameters_, parameters_)].doubleValue();
501}
502// Set double value
503void CbcSolver::setDoubleValue(CbcOrClpParameterType type, double value)
504{
505    parameters_[whichParam(type, numberParameters_, parameters_)].setDoubleValue(value);
506}
507// User function (NULL if no match)
508CbcUser * CbcSolver::userFunction(const char * name) const
509{
510    int i;
511    for (i = 0; i < numberUserFunctions_; i++) {
512        if (!strcmp(name, userFunction_[i]->name().c_str()))
513            break;
514    }
515    if (i < numberUserFunctions_)
516        return userFunction_[i];
517    else
518        return NULL;
519}
520void CbcSolver::fillParameters()
521{
522    int maxParam = 200;
523    CbcOrClpParam * parameters = new CbcOrClpParam [maxParam];
524    numberParameters_ = 0 ;
525    establishParams(numberParameters_, parameters) ;
526    assert (numberParameters_ <= maxParam);
527    parameters_ = new CbcOrClpParam [numberParameters_];
528    int i;
529    for (i = 0; i < numberParameters_; i++)
530        parameters_[i] = parameters[i];
531    delete [] parameters;
532    const char dirsep =  CoinFindDirSeparator();
533    std::string directory;
534    std::string dirSample;
535    std::string dirNetlib;
536    std::string dirMiplib;
537    if (dirsep == '/') {
538        directory = "./";
539        dirSample = "../../Data/Sample/";
540        dirNetlib = "../../Data/Netlib/";
541        dirMiplib = "../../Data/miplib3/";
542    } else {
543        directory = ".\\";
544        dirSample = "..\\..\\..\\..\\Data\\Sample\\";
545        dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
546        dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
547    }
548    std::string defaultDirectory = directory;
549    std::string importFile = "";
550    std::string exportFile = "default.mps";
551    std::string importBasisFile = "";
552    std::string importPriorityFile = "";
553    std::string mipStartFile = "";
554    std::string debugFile = "";
555    std::string printMask = "";
556    std::string exportBasisFile = "default.bas";
557    std::string saveFile = "default.prob";
558    std::string restoreFile = "default.prob";
559    std::string solutionFile = "stdout";
560    std::string solutionSaveFile = "solution.file";
561    int doIdiot = -1;
562    int outputFormat = 2;
563    int substitution = 3;
564    int dualize = 3;
565    int preSolve = 5;
566    int doSprint = -1;
567    int testOsiParameters = -1;
568    int createSolver = 0;
569    ClpSimplex * lpSolver;
570    OsiClpSolverInterface * clpSolver;
571    if (model_.solver()) {
572        clpSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
573        assert (clpSolver);
574        lpSolver = clpSolver->getModelPtr();
575        assert (lpSolver);
576    } else {
577        lpSolver = new ClpSimplex();
578        clpSolver = new OsiClpSolverInterface(lpSolver, true);
579        createSolver = 1 ;
580    }
581    parameters_[whichParam(CLP_PARAM_ACTION_BASISIN, numberParameters_, parameters_)].setStringValue(importBasisFile);
582    parameters_[whichParam(CBC_PARAM_ACTION_PRIORITYIN, numberParameters_, parameters_)].setStringValue(importPriorityFile);
583    parameters_[whichParam(CBC_PARAM_ACTION_MIPSTART, numberParameters_, parameters_)].setStringValue(mipStartFile);
584    parameters_[whichParam(CLP_PARAM_ACTION_BASISOUT, numberParameters_, parameters_)].setStringValue(exportBasisFile);
585    parameters_[whichParam(CLP_PARAM_ACTION_DEBUG, numberParameters_, parameters_)].setStringValue(debugFile);
586    parameters_[whichParam(CLP_PARAM_ACTION_PRINTMASK, numberParameters_, parameters_)].setStringValue(printMask);
587    parameters_[whichParam(CLP_PARAM_ACTION_DIRECTORY, numberParameters_, parameters_)].setStringValue(directory);
588    parameters_[whichParam(CLP_PARAM_ACTION_DIRSAMPLE, numberParameters_, parameters_)].setStringValue(dirSample);
589    parameters_[whichParam(CLP_PARAM_ACTION_DIRNETLIB, numberParameters_, parameters_)].setStringValue(dirNetlib);
590    parameters_[whichParam(CBC_PARAM_ACTION_DIRMIPLIB, numberParameters_, parameters_)].setStringValue(dirMiplib);
591    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
592    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
593    parameters_[whichParam(CLP_PARAM_ACTION_EXPORT, numberParameters_, parameters_)].setStringValue(exportFile);
594    parameters_[whichParam(CLP_PARAM_INT_IDIOT, numberParameters_, parameters_)].setIntValue(doIdiot);
595    parameters_[whichParam(CLP_PARAM_ACTION_IMPORT, numberParameters_, parameters_)].setStringValue(importFile);
596    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].setDoubleValue(1.0e-8);
597    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
598    int value = 1;
599    clpSolver->messageHandler()->setLogLevel(1) ;
600    lpSolver->setLogLevel(1);
601    parameters_[iParam].setIntValue(value);
602    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
603    model_.messageHandler()->setLogLevel(value);
604    parameters_[iParam].setIntValue(value);
605    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
606    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
607    parameters_[whichParam(CLP_PARAM_INT_OUTPUTFORMAT, numberParameters_, parameters_)].setIntValue(outputFormat);
608    parameters_[whichParam(CLP_PARAM_INT_PRESOLVEPASS, numberParameters_, parameters_)].setIntValue(preSolve);
609    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
610    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
611    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
612    parameters_[whichParam(CLP_PARAM_ACTION_RESTORE, numberParameters_, parameters_)].setStringValue(restoreFile);
613    parameters_[whichParam(CLP_PARAM_ACTION_SAVE, numberParameters_, parameters_)].setStringValue(saveFile);
614    //parameters_[whichParam(CLP_PARAM_DBL_TIMELIMIT,numberParameters_,parameters_)].setDoubleValue(1.0e8);
615    parameters_[whichParam(CBC_PARAM_DBL_TIMELIMIT_BAB, numberParameters_, parameters_)].setDoubleValue(1.0e8);
616    parameters_[whichParam(CLP_PARAM_ACTION_SOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
617    parameters_[whichParam(CLP_PARAM_ACTION_NEXTBESTSOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
618    parameters_[whichParam(CLP_PARAM_ACTION_SAVESOL, numberParameters_, parameters_)].setStringValue(solutionSaveFile);
619    parameters_[whichParam(CLP_PARAM_INT_SPRINT, numberParameters_, parameters_)].setIntValue(doSprint);
620    parameters_[whichParam(CLP_PARAM_INT_SUBSTITUTION, numberParameters_, parameters_)].setIntValue(substitution);
621    parameters_[whichParam(CLP_PARAM_INT_DUALIZE, numberParameters_, parameters_)].setIntValue(dualize);
622    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
623    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
624    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
625    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
626    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
627    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
628    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(testOsiParameters);
629    parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_)].setIntValue(1003);
630    initialPumpTune = 1003;
631#ifdef CBC_THREAD
632    parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].setIntValue(0);
633#endif
634    // Set up likely cut generators and defaults
635    parameters_[whichParam(CBC_PARAM_STR_PREPROCESS, numberParameters_, parameters_)].setCurrentOption("sos");
636    parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValue(1057);
637    parameters_[whichParam(CBC_PARAM_INT_CUTPASSINTREE, numberParameters_, parameters_)].setIntValue(1);
638    parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].setIntValue(-1);
639    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
640    parameters_[whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
641    parameters_[whichParam(CBC_PARAM_STR_HEURISTICSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
642    parameters_[whichParam(CBC_PARAM_STR_NODESTRATEGY, numberParameters_, parameters_)].setCurrentOption("fewest");
643    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
644    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
645    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
646#ifdef ZERO_HALF_CUTS
647    parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption("off");
648#endif
649    parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption("off");
650    parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
651    parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
652    parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
653    parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption("root");
654    parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption("off");
655    parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption("off");
656    parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption("on");
657    parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption("on");
658    parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption("on");
659    parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption("on");
660    parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters_, parameters_)].setCurrentOption("off");
661    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters_, parameters_)].setCurrentOption("off");
662    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters_, parameters_)].setCurrentOption("off");
663    parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].setCurrentOption("off");
664    parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].setCurrentOption("off");
665    parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption("off");
666    parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].setCurrentOption("off");
667    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("off");
668    parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].setCurrentOption("off");
669    parameters_[whichParam(CBC_PARAM_STR_COSTSTRATEGY, numberParameters_, parameters_)].setCurrentOption("off");
670    if (createSolver)
671        delete clpSolver;
672}
673
674/*
675  Initialise a subset of the parameters prior to processing any input from
676  the user.
677
678  Why this choice of subset?
679*/
680/*!
681  \todo Guard/replace clp-specific code
682*/
683void CbcSolver::fillValuesInSolver()
684{
685    OsiSolverInterface * solver = model_.solver();
686    OsiClpSolverInterface * clpSolver =
687        dynamic_cast< OsiClpSolverInterface*> (solver);
688    assert (clpSolver);
689    ClpSimplex * lpSolver = clpSolver->getModelPtr();
690
691    /*
692      Why are we reaching into the underlying solver(s) for these settings?
693      Shouldn't CbcSolver have its own defaults, which are then imposed on the
694      underlying solver?
695
696      Coming at if from the other side, if CbcSolver had the capability to use
697      multiple solvers then it definitely makes sense to acquire the defaults from
698      the solver (on the assumption that we haven't processed command line
699      parameters yet, which can then override the defaults). But then it's more of
700      a challenge to avoid solver-specific coding here.
701    */
702    noPrinting_ = (lpSolver->logLevel() == 0);
703    CoinMessageHandler * generalMessageHandler = clpSolver->messageHandler();
704    generalMessageHandler->setPrefix(true);
705
706    lpSolver->setPerturbation(50);
707    lpSolver->messageHandler()->setPrefix(false);
708
709    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
710    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
711    /*
712      Why are we doing this? We read the log level from parameters_, set it into
713      the message handlers for cbc and the underlying solver. Then we read the
714      log level back from the handlers and use it to set the values in
715      parameters_!
716    */
717    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
718    int value = parameters_[iParam].intValue();
719    clpSolver->messageHandler()->setLogLevel(value) ;
720    lpSolver->setLogLevel(value);
721    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
722    value = parameters_[iParam].intValue();
723    model_.messageHandler()->setLogLevel(value);
724    parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].setIntValue(model_.logLevel());
725    parameters_[whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_)].setIntValue(lpSolver->logLevel());
726    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
727    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
728    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
729    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
730    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
731    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
732    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
733    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
734    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
735    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
736    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
737}
738// Add user function
739void
740CbcSolver::addUserFunction(CbcUser * function)
741{
742    CbcUser ** temp = new CbcUser * [numberUserFunctions_+1];
743    int i;
744    for (i = 0; i < numberUserFunctions_; i++)
745        temp[i] = userFunction_[i];
746    delete [] userFunction_;
747    userFunction_ = temp;
748    userFunction_[numberUserFunctions_++] = function->clone();
749    delete [] statusUserFunction_;
750    statusUserFunction_ = NULL;
751}
752// Set user call back
753void
754CbcSolver::setUserCallBack(CbcStopNow * function)
755{
756    delete callBack_;
757    callBack_ = function->clone();
758}
759// Copy of model on initial load (will contain output solutions)
760void
761CbcSolver::setOriginalSolver(OsiClpSolverInterface * originalSolver)
762{
763    delete originalSolver_;
764    OsiSolverInterface * temp = originalSolver->clone();
765    originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
766    assert (originalSolver_);
767
768}
769// Copy of model on initial load
770void
771CbcSolver::setOriginalCoinModel(CoinModel * originalCoinModel)
772{
773    delete originalCoinModel_;
774    originalCoinModel_ = new CoinModel(*originalCoinModel);
775}
776// Add cut generator
777void
778CbcSolver::addCutGenerator(CglCutGenerator * generator)
779{
780    CglCutGenerator ** temp = new CglCutGenerator * [numberCutGenerators_+1];
781    int i;
782    for (i = 0; i < numberCutGenerators_; i++)
783        temp[i] = cutGenerator_[i];
784    delete [] cutGenerator_;
785    cutGenerator_ = temp;
786    cutGenerator_[numberCutGenerators_++] = generator->clone();
787}
788
789/*
790  The only other solver that's ever been used is cplex, and the use is
791  limited -- do the root with clp and all the cbc smarts, then give the
792  problem over to cplex to finish. Although the defines can be read in some
793  places to allow other options, nothing's been tested and success is
794  unlikely.
795
796  CBC_OTHER_SOLVER == 1 is cplex.
797*/
798
799#if CBC_OTHER_SOLVER==1
800#  ifndef COIN_HAS_CPX
801#    error "Configuration did not detect cplex installation."
802#  else
803#    include "OsiCpxSolverInterface.hpp"
804#  endif
805#endif
806
807#ifdef COIN_HAS_ASL
808#include "Cbc_ampl.h"
809#endif
810
811static double totalTime = 0.0;
812static void statistics(ClpSimplex * originalModel, ClpSimplex * model);
813static bool maskMatches(const int * starts, char ** masks,
814                        std::string & check);
815static void generateCode(CbcModel * model, const char * fileName, int type, int preProcess);
816
817// dummy fake main programs for UserClp and UserCbc
818void fakeMain (ClpSimplex & model, OsiSolverInterface & osiSolver, CbcModel & babSolver);
819void fakeMain2 (ClpSimplex & model, OsiClpSolverInterface & osiSolver, int options);
820
821// Allow for interrupts
822// But is this threadsafe? (so switched off by option)
823
824#include "CoinSignal.hpp"
825static CbcModel * currentBranchModel = NULL;
826
827extern "C" {
828    static void signal_handler(int /*whichSignal*/) {
829        if (currentBranchModel != NULL)
830            currentBranchModel->sayEventHappened(); // say why stopped
831        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
1129static CbcOrClpParam parameters[CBCMAXPARAMETERS];
1130static int numberParameters = 0 ;
1131CglPreProcess * cbcPreProcessPointer=NULL;
1132
1133int CbcClpUnitTest (const CbcModel & saveModel,
1134                    const std::string& dirMiplib, int testSwitch,
1135                    const double * stuff);
1136
1137int CbcMain1 (int argc, const char *argv[],
1138              CbcModel  & model)
1139{
1140    return CbcMain1(argc, argv, model, dummyCallBack);
1141}
1142
1143
1144/*
1145  Meaning of whereFrom:
1146    1 after initial solve by dualsimplex etc
1147    2 after preprocessing
1148    3 just before branchAndBound (so user can override)
1149    4 just after branchAndBound (before postprocessing)
1150    5 after postprocessing
1151    6 after a user called heuristic phase
1152*/
1153
1154int CbcMain1 (int argc, const char *argv[],
1155              CbcModel  & model,
1156              int callBack(CbcModel * currentSolver, int whereFrom))
1157{
1158    CbcOrClpParam * parameters_ = parameters;
1159    int numberParameters_ = numberParameters;
1160    CbcModel & model_ = model;
1161#ifdef CBC_USE_INITIAL_TIME
1162    if (model_.useElapsedTime())
1163      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1164    else
1165      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1166#endif
1167    CbcModel * babModel_ = NULL;
1168    int returnMode = 1;
1169    CbcOrClpRead_mode = 1;
1170    int statusUserFunction_[1];
1171    int numberUserFunctions_ = 1; // to allow for ampl
1172    // Statistics
1173    double statistics_seconds = 0.0, statistics_obj = 0.0;
1174    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1175    CoinWallclockTime();
1176    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1177    double statistics_cut_time = 0.0;
1178    int statistics_nodes = 0, statistics_iterations = 0;
1179    int statistics_nrows = 0, statistics_ncols = 0;
1180    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1181    std::string statistics_result;
1182    int * statistics_number_cuts = NULL;
1183    const char ** statistics_name_generators = NULL;
1184    int statistics_number_generators = 0;
1185    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1186    /* Note
1187       This is meant as a stand-alone executable to do as much of coin as possible.
1188       It should only have one solver known to it.
1189    */
1190    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1191    generalMessageHandler->setPrefix(false);
1192#ifndef CBC_OTHER_SOLVER
1193    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1194    assert (originalSolver);
1195    // Move handler across if not default
1196    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1197        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1198    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1199    char generalPrint[10000];
1200    if (originalSolver->getModelPtr()->logLevel() == 0)
1201        noPrinting = true;
1202#elif CBC_OTHER_SOLVER==1
1203    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1204    assert (originalSolver);
1205    OsiClpSolverInterface dummySolver;
1206    OsiCpxSolverInterface * clpSolver = originalSolver;
1207    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1208    char generalPrint[10000];
1209    noPrinting = true;
1210#endif
1211    bool noPrinting_ = noPrinting;
1212    // Say not in integer
1213    int integerStatus = -1;
1214    // Say no resolve after cuts
1215    model_.setResolveAfterTakeOffCuts(false);
1216    // see if log in list
1217    for (int i = 1; i < argc; i++) {
1218        if (!strncmp(argv[i], "log", 3)) {
1219            const char * equals = strchr(argv[i], '=');
1220            if (equals && atoi(equals + 1) != 0)
1221                noPrinting_ = false;
1222            else
1223                noPrinting_ = true;
1224            break;
1225        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1226            if (atoi(argv[i+1]) != 0)
1227                noPrinting_ = false;
1228            else
1229                noPrinting_ = true;
1230            break;
1231        }
1232    }
1233    double time0;
1234    double time0Elapsed = CoinGetTimeOfDay();
1235    {
1236        double time1 = CoinCpuTime(), time2;
1237        time0 = time1;
1238        double time1Elapsed = time0Elapsed;
1239        bool goodModel = (originalSolver->getNumCols()) ? true : false;
1240
1241        // register signal handler
1242        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
1243#if CBC_QUIET < 2
1244        signal(SIGINT, signal_handler);
1245#endif
1246        // Set up all non-standard stuff
1247        int cutPass = -1234567;
1248        int cutPassInTree = -1234567;
1249        int tunePreProcess = 0;
1250        int testOsiParameters = -1;
1251        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1252        int complicatedInteger = 0;
1253        OsiSolverInterface * solver = model_.solver();
1254        if (noPrinting_)
1255            setCbcOrClpPrinting(false);
1256#ifndef CBC_OTHER_SOLVER
1257        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1258        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1259        if (noPrinting_) {
1260            lpSolver->setLogLevel(0);
1261        }
1262#else
1263        ClpSimplex * lpSolver = NULL;
1264#endif
1265        // For priorities etc
1266        int * priorities = NULL;
1267        int * branchDirection = NULL;
1268        double * pseudoDown = NULL;
1269        double * pseudoUp = NULL;
1270        double * solutionIn = NULL;
1271        int * prioritiesIn = NULL;
1272        std::vector< std::pair< std::string, double > > mipStart;
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                                   8 stopped on iterations limit
2717                                */
2718                                int iStatus = model2->status();
2719                                int iStatus2 = model2->secondaryStatus();
2720                                if (iStatus == 0) {
2721                                    iStatus2 = 0;
2722                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
2723                                        // set best solution in model as no integers
2724                                        model_.setBestSolution(model2->primalColumnSolution(),
2725                                                               model2->numberColumns(),
2726                                                               model2->getObjValue()*
2727                                                               model2->getObjSense());
2728                                    }
2729                                } else if (iStatus == 1) {
2730                                    iStatus = 0;
2731                                    iStatus2 = 1; // say infeasible
2732                                } else if (iStatus == 2) {
2733                                    iStatus = 0;
2734                                    iStatus2 = 7; // say unbounded
2735                                } else if (iStatus == 3) {
2736                                    iStatus = 1;
2737                                    if (iStatus2 == 9)  // what does 9 mean ?????????????
2738                                        iStatus2 = 4;
2739                                    else
2740                                        iStatus2 = 3; // Use nodes - as closer than solutions
2741                                } else if (iStatus == 4) {
2742                                    iStatus = 2; // difficulties
2743                                    iStatus2 = 0;
2744                                }
2745                                model_.setProblemStatus(iStatus);
2746                                model_.setSecondaryStatus(iStatus2);
2747                                if ((iStatus == 2 || iStatus2 > 0) &&
2748                                    !noPrinting_) {
2749                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
2750                                   std::string minor[] = {"Optimal solution found", "Linear relaxation infeasible", "Optimal solution found (within gap tolerance)", "node limit", "time limit", "user ctrl-c", "solution limit", "Linear relaxation unbounded", "iterations limit", "Problem proven infeasible"};
2751                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
2752                                           statusName[iStatus].c_str(), 
2753                                           minor[iStatus2].c_str());
2754                                   sprintf(generalPrint + strlen(generalPrint),
2755                                           "Enumerated nodes:           0\n");
2756                                   sprintf(generalPrint + strlen(generalPrint), 
2757                                           "Total iterations:           0\n");
2758#if CBC_QUIET == 0
2759                                   sprintf(generalPrint + strlen(generalPrint),
2760                                           "Time (CPU seconds):         %.2f\n", 
2761                                           CoinCpuTime() - time0);
2762                                   sprintf(generalPrint + strlen(generalPrint),
2763                                           "Time (Wallclock Seconds):   %.2f\n", 
2764                                           CoinGetTimeOfDay()-time0Elapsed);
2765#endif
2766                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
2767                                      << generalPrint
2768                                      << CoinMessageEol;
2769                                }
2770                                //assert (lpSolver==clpSolver->getModelPtr());
2771                                assert (clpSolver == model_.solver());
2772                                clpSolver->setWarmStart(NULL);
2773                                // and in babModel if exists
2774                                if (babModel_) {
2775                                    babModel_->setProblemStatus(iStatus);
2776                                    babModel_->setSecondaryStatus(iStatus2);
2777                                }
2778                                int returnCode = callBack(&model, 1);
2779                                if (returnCode) {
2780                                    // exit if user wants
2781                                    delete babModel_;
2782                                    babModel_ = NULL;
2783                                    return returnCode;
2784                                }
2785                            }
2786                            basisHasValues = 1;
2787                            if (dualize) {
2788                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
2789                                if (model2->status() == 3)
2790                                    returnCode = 0;
2791                                delete model2;
2792                                if (returnCode && dualize != 2)
2793                                    lpSolver->primal(1);
2794                                model2 = lpSolver;
2795                            }
2796#ifdef COIN_HAS_ASL
2797                            if (statusUserFunction_[0]) {
2798                                double value = model2->getObjValue() * model2->getObjSense();
2799                                char buf[300];
2800                                int pos = 0;
2801                                int iStat = model2->status();
2802                                if (iStat == 0) {
2803                                    pos += sprintf(buf + pos, "optimal," );
2804                                } else if (iStat == 1) {
2805                                    // infeasible
2806                                    pos += sprintf(buf + pos, "infeasible,");
2807                                } else if (iStat == 2) {
2808                                    // unbounded
2809                                    pos += sprintf(buf + pos, "unbounded,");
2810                                } else if (iStat == 3) {
2811                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
2812                                } else if (iStat == 4) {
2813                                    iStat = 7;
2814                                    pos += sprintf(buf + pos, "stopped on difficulties,");
2815                                } else if (iStat == 5) {
2816                                    iStat = 3;
2817                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
2818                                } else if (iStat == 6) {
2819                                    // bab infeasible
2820                                    pos += sprintf(buf + pos, "integer infeasible,");
2821                                    iStat = 1;
2822                                } else {
2823                                    pos += sprintf(buf + pos, "status unknown,");
2824                                    iStat = 6;
2825                                }
2826                                info.problemStatus = iStat;
2827                                info.objValue = value;
2828                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
2829                                               value);
2830                                sprintf(buf + pos, "\n%d iterations",
2831                                        model2->getIterationCount());
2832                                free(info.primalSolution);
2833                                int numberColumns = model2->numberColumns();
2834                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
2835                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
2836                                int numberRows = model2->numberRows();
2837                                free(info.dualSolution);
2838                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
2839                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
2840                                CoinWarmStartBasis * basis = model2->getBasis();
2841                                free(info.rowStatus);
2842                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
2843                                free(info.columnStatus);
2844                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
2845                                // Put basis in
2846                                int i;
2847                                // free,basic,ub,lb are 0,1,2,3
2848                                for (i = 0; i < numberRows; i++) {
2849                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
2850                                    info.rowStatus[i] = status;
2851                                }
2852                                for (i = 0; i < numberColumns; i++) {
2853                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
2854                                    info.columnStatus[i] = status;
2855                                }
2856                                // put buffer into info
2857                                strcpy(info.buffer, buf);
2858                                delete basis;
2859                            }
2860#endif
2861                        } else {
2862#ifndef DISALLOW_PRINTING
2863                            std::cout << "** Current model not valid" << std::endl;
2864#endif
2865                        }
2866                        break;
2867                    case CLP_PARAM_ACTION_STATISTICS:
2868                        if (goodModel) {
2869                            // If presolve on look at presolved
2870                            bool deleteModel2 = false;
2871                            ClpSimplex * model2 = lpSolver;
2872                            if (preSolve) {
2873                                ClpPresolve pinfo;
2874                                int presolveOptions2 = presolveOptions&~0x40000000;
2875                                if ((presolveOptions2&0xffff) != 0)
2876                                    pinfo.setPresolveActions(presolveOptions2);
2877                                pinfo.setSubstitution(substitution);
2878                                if ((printOptions&1) != 0)
2879                                    pinfo.statistics();
2880                                double presolveTolerance =
2881                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
2882                                model2 =
2883                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
2884                                                         true, preSolve);
2885                                if (model2) {
2886                                    printf("Statistics for presolved model\n");
2887                                    deleteModel2 = true;
2888                                } else {
2889                                    printf("Presolved model looks infeasible - will use unpresolved\n");
2890                                    model2 = lpSolver;
2891                                }
2892                            } else {
2893                                printf("Statistics for unpresolved model\n");
2894                                model2 =  lpSolver;
2895                            }
2896                            statistics(lpSolver, model2);
2897                            if (deleteModel2)
2898                                delete model2;
2899                        } else {
2900#ifndef DISALLOW_PRINTING
2901                            std::cout << "** Current model not valid" << std::endl;
2902#endif
2903                        }
2904                        break;
2905                    case CLP_PARAM_ACTION_TIGHTEN:
2906                        if (goodModel) {
2907                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
2908                            if (numberInfeasibilities)
2909                                std::cout << "** Analysis indicates model infeasible" << std::endl;
2910                        } else {
2911#ifndef DISALLOW_PRINTING
2912                            std::cout << "** Current model not valid" << std::endl;
2913#endif
2914                        }
2915                        break;
2916                    case CLP_PARAM_ACTION_PLUSMINUS:
2917                        if (goodModel) {
2918                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
2919                            ClpPackedMatrix* clpMatrix =
2920                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
2921                            if (clpMatrix) {
2922                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
2923                                if (newMatrix->getIndices()) {
2924                                    lpSolver->replaceMatrix(newMatrix);
2925                                    delete saveMatrix;
2926                                    std::cout << "Matrix converted to +- one matrix" << std::endl;
2927                                } else {
2928                                    std::cout << "Matrix can not be converted to +- 1 matrix" << std::endl;
2929                                }
2930                            } else {
2931                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
2932                            }
2933                        } else {
2934#ifndef DISALLOW_PRINTING
2935                            std::cout << "** Current model not valid" << std::endl;
2936#endif
2937                        }
2938                        break;
2939                    case CLP_PARAM_ACTION_OUTDUPROWS:
2940                        dominatedCuts = true;
2941#ifdef JJF_ZERO
2942                        if (goodModel) {
2943                            int numberRows = clpSolver->getNumRows();
2944                            //int nOut = outDupRow(clpSolver);
2945                            CglDuplicateRow dupcuts(clpSolver);
2946                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
2947                            int nOut = numberRows - clpSolver->getNumRows();
2948                            if (nOut && !noPrinting_)
2949                                sprintf(generalPrint, "%d rows eliminated", nOut);
2950                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2951                            << generalPrint
2952                            << CoinMessageEol;
2953                        } else {
2954#ifndef DISALLOW_PRINTING
2955                            std::cout << "** Current model not valid" << std::endl;
2956#endif
2957                        }
2958#endif
2959                        break;
2960                    case CLP_PARAM_ACTION_NETWORK:
2961                        if (goodModel) {
2962                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
2963                            ClpPackedMatrix* clpMatrix =
2964                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
2965                            if (clpMatrix) {
2966                                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
2967                                if (newMatrix->getIndices()) {
2968                                    lpSolver->replaceMatrix(newMatrix);
2969                                    delete saveMatrix;
2970                                    std::cout << "Matrix converted to network matrix" << std::endl;
2971                                } else {
2972                                    std::cout << "Matrix can not be converted to network matrix" << std::endl;
2973                                }
2974                            } else {
2975                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
2976                            }
2977                        } else {
2978#ifndef DISALLOW_PRINTING
2979                            std::cout << "** Current model not valid" << std::endl;
2980#endif
2981                        }
2982                        break;
2983                    case CBC_PARAM_ACTION_DOHEURISTIC:
2984                        if (goodModel) {
2985                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
2986                            if (vubAction != -1) {
2987                                // look at vubs
2988                                // extra1 is number of ints to leave free
2989                                // Just ones which affect >= extra3
2990                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
2991                                /* 2 is cost above which to fix if feasible
2992                                   3 is fraction of integer variables fixed if relaxing (0.97)
2993                                   4 is fraction of all variables fixed if relaxing (0.0)
2994                                */
2995                                double dextra[6];
2996                                int extra[5];
2997                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
2998                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
2999                                                                  parameters_)].intValue();
3000                                if (exp1 == 4 && extra[1] == -1)
3001                                    extra[1] = 999998;
3002                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
3003                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
3004                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3005                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
3006                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
3007                                if (!dextra[3])
3008                                    dextra[3] = 0.97;
3009                                //OsiClpSolverInterface * newSolver =
3010                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
3011                                        debugValues, dextra, extra);
3012                                //assert (!newSolver);
3013                            }
3014                            // Actually do heuristics
3015                            doHeuristics(&model_, 2, parameters_,
3016                                         numberParameters_, noPrinting_, initialPumpTune);
3017                            if (model_.bestSolution()) {
3018                                model_.setProblemStatus(1);
3019                                model_.setSecondaryStatus(6);
3020#ifdef COIN_HAS_ASL
3021                                if (statusUserFunction_[0]) {
3022                                    double value = model_.getObjValue();
3023                                    char buf[300];
3024                                    int pos = 0;
3025                                    pos += sprintf(buf + pos, "feasible,");
3026                                    info.problemStatus = 0;
3027                                    info.objValue = value;
3028                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3029                                                   value);
3030                                    sprintf(buf + pos, "\n0 iterations");
3031                                    free(info.primalSolution);
3032                                    int numberColumns = lpSolver->numberColumns();
3033                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3034                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3035                                    int numberRows = lpSolver->numberRows();
3036                                    free(info.dualSolution);
3037                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3038                                    CoinZeroN(info.dualSolution, numberRows);
3039                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3040                                    free(info.rowStatus);
3041                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3042                                    free(info.columnStatus);
3043                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3044                                    // Put basis in
3045                                    int i;
3046                                    // free,basic,ub,lb are 0,1,2,3
3047                                    for (i = 0; i < numberRows; i++) {
3048                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3049                                        info.rowStatus[i] = status;
3050                                    }
3051                                    for (i = 0; i < numberColumns; i++) {
3052                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3053                                        info.columnStatus[i] = status;
3054                                    }
3055                                    // put buffer into info
3056                                    strcpy(info.buffer, buf);
3057                                    delete basis;
3058                                }
3059#endif
3060                            }
3061                            int returnCode = callBack(&model, 6);
3062                            if (returnCode) {
3063                                // exit if user wants
3064                                delete babModel_;
3065                                babModel_ = NULL;
3066                                return returnCode;
3067                            }
3068                        }
3069                        break;
3070                    case CBC_PARAM_ACTION_MIPLIB:
3071                        // User can set options - main difference is lack of model and CglPreProcess
3072                        goodModel = true;
3073                        /*
3074                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3075                          Print elapsed time at the end.
3076                        */
3077                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3078                        // obsolete case STRENGTHEN:
3079                        if (goodModel) {
3080                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3081                            int logLevel = parameters_[slog].intValue();
3082                            // Reduce printout
3083                            if (logLevel <= 1) {
3084                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3085                            } else {
3086                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3087                            }
3088                            {
3089                                OsiSolverInterface * solver = model_.solver();
3090#ifndef CBC_OTHER_SOLVER
3091                                OsiClpSolverInterface * si =
3092                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3093                                assert (si != NULL);
3094                                si->getModelPtr()->scaling(doScaling);
3095                                ClpSimplex * lpSolver = si->getModelPtr();
3096                                if (doVector) {
3097                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3098                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3099                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3100                                        clpMatrix->makeSpecialColumnCopy();
3101                                    }
3102                                }
3103#elif CBC_OTHER_SOLVER==1
3104                                OsiCpxSolverInterface * si =
3105                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3106                                assert (si != NULL);
3107#endif
3108                                statistics_nrows = si->getNumRows();
3109                                statistics_ncols = si->getNumCols();
3110                                statistics_nprocessedrows = si->getNumRows();
3111                                statistics_nprocessedcols = si->getNumCols();
3112                                // See if quadratic
3113#ifndef CBC_OTHER_SOLVER
3114#ifdef COIN_HAS_LINK
3115                                if (!complicatedInteger) {
3116                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3117                                    if (obj) {
3118                                        preProcess = 0;
3119                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3120                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3121                                        // create coin model
3122                                        coinModel = lpSolver->createCoinModel();
3123                                        assert (coinModel);
3124                                        // load from coin model
3125                                        OsiSolverLink solver1;
3126                                        OsiSolverInterface * solver2 = solver1.clone();
3127                                        model_.assignSolver(solver2, false);
3128                                        OsiSolverLink * si =
3129                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3130                                        assert (si != NULL);
3131                                        si->setDefaultMeshSize(0.001);
3132                                        // need some relative granularity
3133                                        si->setDefaultBound(100.0);
3134                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3135                                        if (dextra3)
3136                                            si->setDefaultMeshSize(dextra3);
3137                                        si->setDefaultBound(1000.0);
3138                                        si->setIntegerPriority(1000);
3139                                        si->setBiLinearPriority(10000);
3140                                        si->setSpecialOptions2(2 + 4 + 8);
3141                                        CoinModel * model2 = coinModel;
3142                                        si->load(*model2, true, parameters_[log].intValue());
3143                                        // redo
3144                                        solver = model_.solver();
3145                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3146                                        lpSolver = clpSolver->getModelPtr();
3147                                        clpSolver->messageHandler()->setLogLevel(0) ;
3148                                        testOsiParameters = 0;
3149                                        complicatedInteger = 2;  // allow cuts
3150                                        OsiSolverInterface * coinSolver = model_.solver();
3151                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3152                                        if (linkSolver->quadraticModel()) {
3153                                            ClpSimplex * qp = linkSolver->quadraticModel();
3154                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3155                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3156                                            qp->primal(1);
3157                                            OsiSolverLinearizedQuadratic solver2(qp);
3158                                            const double * solution = NULL;
3159                                            // Reduce printout
3160                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3161                                            CbcModel model2(solver2);
3162                                            // Now do requested saves and modifications
3163                                            CbcModel * cbcModel = & model2;
3164                                            OsiSolverInterface * osiModel = model2.solver();
3165                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3166                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3167
3168                                            // Set changed values
3169
3170                                            CglProbing probing;
3171                                            probing.setMaxProbe(10);
3172                                            probing.setMaxLook(10);
3173                                            probing.setMaxElements(200);
3174                                            probing.setMaxProbeRoot(50);
3175                                            probing.setMaxLookRoot(10);
3176                                            probing.setRowCuts(3);
3177                                            probing.setUsingObjective(true);
3178                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3179                                            cbcModel->cutGenerator(0)->setTiming(true);
3180
3181                                            CglGomory gomory;
3182                                            gomory.setLimitAtRoot(512);
3183                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3184                                            cbcModel->cutGenerator(1)->setTiming(true);
3185
3186                                            CglKnapsackCover knapsackCover;
3187                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3188                                            cbcModel->cutGenerator(2)->setTiming(true);
3189
3190                                            CglRedSplit redSplit;
3191                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3192                                            cbcModel->cutGenerator(3)->setTiming(true);
3193
3194                                            CglClique clique;
3195                                            clique.setStarCliqueReport(false);
3196                                            clique.setRowCliqueReport(false);
3197                                            clique.setMinViolation(0.1);
3198                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3199                                            cbcModel->cutGenerator(4)->setTiming(true);
3200
3201                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3202                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3203                                            cbcModel->cutGenerator(5)->setTiming(true);
3204
3205                                            CglFlowCover flowCover;
3206                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3207                                            cbcModel->cutGenerator(6)->setTiming(true);
3208
3209                                            CglTwomir twomir;
3210                                            twomir.setMaxElements(250);
3211                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3212                                            cbcModel->cutGenerator(7)->setTiming(true);
3213
3214                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3215                                            heuristicFPump.setWhen(13);
3216                                            heuristicFPump.setMaximumPasses(20);
3217                                            heuristicFPump.setMaximumRetries(7);
3218                                            heuristicFPump.setHeuristicName("feasibility pump");
3219                                            heuristicFPump.setInitialWeight(1);
3220                                            heuristicFPump.setFractionSmall(0.6);
3221                                            cbcModel->addHeuristic(&heuristicFPump);
3222
3223                                            CbcRounding rounding(*cbcModel);
3224                                            rounding.setHeuristicName("rounding");
3225                                            cbcModel->addHeuristic(&rounding);
3226
3227                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3228                                            heuristicLocal.setHeuristicName("combine solutions");
3229                                            heuristicLocal.setSearchType(1);
3230                                            heuristicLocal.setFractionSmall(0.6);
3231                                            cbcModel->addHeuristic(&heuristicLocal);
3232
3233                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3234                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3235                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3236
3237                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3238                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3239                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3240
3241                                            CbcCompareDefault compare;
3242                                            cbcModel->setNodeComparison(compare);
3243                                            cbcModel->setNumberBeforeTrust(5);
3244                                            cbcModel->setSpecialOptions(2);
3245                                            cbcModel->messageHandler()->setLogLevel(1);
3246                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3247                                            cbcModel->setMaximumCutPasses(1);
3248                                            cbcModel->setMinimumDrop(0.05);
3249                                            // For branchAndBound this may help
3250                                            clpModel->defaultFactorizationFrequency();
3251                                            clpModel->setDualBound(1.0001e+08);
3252                                            clpModel->setPerturbation(50);
3253                                            osiclpModel->setSpecialOptions(193);
3254                                            osiclpModel->messageHandler()->setLogLevel(0);
3255                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3256                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3257                                            // You can save some time by switching off message building
3258                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3259
3260                                            // Solve
3261
3262                                            cbcModel->initialSolve();
3263                                            if (clpModel->tightenPrimalBounds() != 0) {
3264#ifndef DISALLOW_PRINTING
3265                                                std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3266#endif
3267                                                break;
3268                                            }
3269                                            clpModel->dual();  // clean up
3270                                            cbcModel->initialSolve();
3271#ifdef CBC_THREAD
3272                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3273                                            cbcModel->setNumberThreads(numberThreads % 100);
3274                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3275#endif
3276                                            //setCutAndHeuristicOptions(*cbcModel);
3277                                            cbcModel->branchAndBound();
3278                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3279                                            assert (solver3);
3280                                            solution = solver3->bestSolution();
3281                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3282                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3283                                            linkSolver->setBestSolution(solution, solver3->getNumCols());
3284                                            CbcHeuristicDynamic3 dynamic(model_);
3285                                            dynamic.setHeuristicName("dynamic pass thru");
3286                                            model_.addHeuristic(&dynamic);
3287                                            // if convex
3288                                            if ((linkSolver->specialOptions2()&4) != 0) {
3289                                                int numberColumns = coinModel->numberColumns();
3290                                                assert (linkSolver->objectiveVariable() == numberColumns);
3291                                                // add OA cut
3292                                                double offset;
3293                                                double * gradient = new double [numberColumns+1];
3294                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3295                                                       numberColumns*sizeof(double));
3296                                                double rhs = 0.0;
3297                                                int * column = new int[numberColumns+1];
3298                                                int n = 0;
3299                                                for (int i = 0; i < numberColumns; i++) {
3300                                                    double value = gradient[i];
3301                                                    if (fabs(value) > 1.0e-12) {
3302                                                        gradient[n] = value;
3303                                                        rhs += value * solution[i];
3304                                                        column[n++] = i;
3305                                                    }
3306                                                }
3307                                                gradient[n] = -1.0;
3308                                                column[n++] = numberColumns;
3309                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3310                                                delete [] gradient;
3311                                                delete [] column;
3312                                            }
3313                                            // could do three way branching round a) continuous b) best solution
3314                                            printf("obj %g\n", bestObjectiveValue);
3315                                            linkSolver->initialSolve();
3316                                        }
3317                                    }
3318                                }
3319#endif
3320#endif
3321                                if (logLevel <= 1)
3322                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3323#ifndef CBC_OTHER_SOLVER
3324                                si->setSpecialOptions(0x40000000);
3325#endif
3326                            }
3327                            if (!miplib) {
3328                                if (!preSolve) {
3329                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3330                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3331                                }
3332                                double time1a = CoinCpuTime();
3333                                OsiSolverInterface * solver = model_.solver();
3334#ifndef CBC_OTHER_SOLVER
3335                                OsiClpSolverInterface * si =
3336                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3337                                if (si)
3338                                    si->setSpecialOptions(si->specialOptions() | 1024);
3339#endif
3340                                model_.initialSolve();
3341#ifndef CBC_OTHER_SOLVER
3342                                ClpSimplex * clpSolver = si->getModelPtr();
3343                                int iStatus = clpSolver->status();
3344                                int iStatus2 = clpSolver->secondaryStatus();
3345                                if (iStatus == 0) {
3346                                    iStatus2 = 0;
3347                                } else if (iStatus == 1) {
3348                                    iStatus = 0;
3349                                    iStatus2 = 1; // say infeasible
3350                                } else if (iStatus == 2) {
3351                                    iStatus = 0;
3352                                    iStatus2 = 7; // say unbounded
3353                                } else if (iStatus == 3) {
3354                                    iStatus = 1;
3355                                    if (iStatus2 == 9)
3356                                        iStatus2 = 4;
3357                                    else
3358                                        iStatus2 = 3; // Use nodes - as closer than solutions
3359                                } else if (iStatus == 4) {
3360                                    iStatus = 2; // difficulties
3361                                    iStatus2 = 0;
3362                                }
3363                                model_.setProblemStatus(iStatus);
3364                                model_.setSecondaryStatus(iStatus2);
3365                                si->setWarmStart(NULL);
3366                                int returnCode = callBack(&model_, 1);
3367                                if (returnCode) {
3368                                    // exit if user wants
3369                                    delete babModel_;
3370                                    babModel_ = NULL;
3371                                    return returnCode;
3372                                }
3373                                if (clpSolver->status() > 0) {
3374                                    // and in babModel if exists
3375                                    if (babModel_) {
3376                                        babModel_->setProblemStatus(iStatus);
3377                                        babModel_->setSecondaryStatus(iStatus2);
3378                                    }
3379                                    if (!noPrinting_) {
3380                                        iStatus = clpSolver->status();
3381                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3382                                                              "difficulties", "other"
3383                                                             };
3384                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3385                                                msg[iStatus-1], CoinCpuTime() - time1a);
3386                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3387                                        << generalPrint
3388                                        << CoinMessageEol;
3389                                    }
3390                                    break;
3391                                }
3392                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3393#elif CBC_OTHER_SOLVER==1
3394#endif
3395                                if (!noPrinting_) {
3396                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3397                                            solver->getObjValue(), CoinCpuTime() - time1a);
3398                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3399                                    << generalPrint
3400                                    << CoinMessageEol;
3401                                }
3402                                if (model_.getMaximumNodes() == -987654321) {
3403                                    // See if No objective!
3404                                    int numberColumns = clpSolver->getNumCols();
3405                                    const double * obj = clpSolver->getObjCoefficients();
3406                                    const double * lower = clpSolver->getColLower();
3407                                    const double * upper = clpSolver->getColUpper();
3408                                    int nObj = 0;
3409                                    for (int i = 0; i < numberColumns; i++) {
3410                                        if (upper[i] > lower[i] && obj[i])
3411                                            nObj++;
3412                                    }
3413                                    if (!nObj) {
3414                                        printf("************No objective!!\n");
3415                                        model_.setMaximumSolutions(1);
3416                                        // Column copy
3417                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3418                                        //const double * element = matrixByCol.getElements();
3419                                        //const int * row = matrixByCol.getIndices();
3420                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3421                                        const int * columnLength = matrixByCol.getVectorLengths();
3422                                        for (int i = 0; i < numberColumns; i++) {
3423                                            double value = (CoinDrand48() + 0.5) * 10000;
3424                                            value = 10;
3425                                            value *= columnLength[i];
3426                                            int iValue = static_cast<int> (value) / 10;
3427                                            //iValue=1;
3428                                            clpSolver->setObjCoeff(i, iValue);
3429                                        }
3430                                    }
3431                                }
3432#ifndef CBC_OTHER_SOLVER
3433                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3434#ifndef DISALLOW_PRINTING
3435                                    std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3436#endif
3437                                    model_.setProblemStatus(0);
3438                                    model_.setSecondaryStatus(1);
3439                                    // and in babModel if exists
3440                                    if (babModel_) {
3441                                        babModel_->setProblemStatus(0);
3442                                        babModel_->setSecondaryStatus(1);
3443                                    }
3444                                    break;
3445                                }
3446                                if (clpSolver->dualBound() == 1.0e10) {
3447                                    ClpSimplex temp = *clpSolver;
3448                                    temp.setLogLevel(0);
3449                                    temp.dual(0, 7);
3450                                    // user did not set - so modify
3451                                    // get largest scaled away from bound
3452                                    double largest = 1.0e-12;
3453                                    double largestScaled = 1.0e-12;
3454                                    int numberRows = temp.numberRows();
3455                                    const double * rowPrimal = temp.primalRowSolution();
3456                                    const double * rowLower = temp.rowLower();
3457                                    const double * rowUpper = temp.rowUpper();
3458                                    const double * rowScale = temp.rowScale();
3459                                    int iRow;
3460                                    for (iRow = 0; iRow < numberRows; iRow++) {
3461                                        double value = rowPrimal[iRow];
3462                                        double above = value - rowLower[iRow];
3463                                        double below = rowUpper[iRow] - value;
3464                                        if (above < 1.0e12) {
3465                                            largest = CoinMax(largest, above);
3466                                        }
3467                                        if (below < 1.0e12) {
3468                                            largest = CoinMax(largest, below);
3469                                        }
3470                                        if (rowScale) {
3471                                            double multiplier = rowScale[iRow];
3472                                            above *= multiplier;
3473                                            below *= multiplier;
3474                                        }
3475                                        if (above < 1.0e12) {
3476                                            largestScaled = CoinMax(largestScaled, above);
3477                                        }
3478                                        if (below < 1.0e12) {
3479                                            largestScaled = CoinMax(largestScaled, below);
3480                                        }
3481                                    }
3482
3483                                    int numberColumns = temp.numberColumns();
3484                                    const double * columnPrimal = temp.primalColumnSolution();
3485                                    const double * columnLower = temp.columnLower();
3486                                    const double * columnUpper = temp.columnUpper();
3487                                    const double * columnScale = temp.columnScale();
3488                                    int iColumn;
3489                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3490                                        double value = columnPrimal[iColumn];
3491                                        double above = value - columnLower[iColumn];
3492                                        double below = columnUpper[iColumn] - value;
3493                                        if (above < 1.0e12) {
3494                                            largest = CoinMax(largest, above);
3495                                        }
3496                                        if (below < 1.0e12) {
3497                                            largest = CoinMax(largest, below);
3498                                        }
3499                                        if (columnScale) {
3500                                            double multiplier = 1.0 / columnScale[iColumn];
3501                                            above *= multiplier;
3502                                            below *= multiplier;
3503                                        }
3504                                        if (above < 1.0e12) {
3505                                            largestScaled = CoinMax(largestScaled, above);
3506                                        }
3507                                        if (below < 1.0e12) {
3508                                            largestScaled = CoinMax(largestScaled, below);
3509                                        }
3510                                    }
3511#ifdef COIN_DEVELOP
3512                                    if (!noPrinting_)
3513                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3514                                                  << " unscaled " << largest << std::endl;
3515#endif
3516                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3517                                }
3518                                si->resolve();  // clean up
3519#endif
3520                            }
3521                            // If user made settings then use them
3522                            if (!defaultSettings) {
3523                                OsiSolverInterface * solver = model_.solver();
3524                                if (!doScaling)
3525                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3526#ifndef CBC_OTHER_SOLVER
3527                                OsiClpSolverInterface * si =
3528                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3529                                assert (si != NULL);
3530                                // get clp itself
3531                                ClpSimplex * modelC = si->getModelPtr();
3532                                //if (modelC->tightenPrimalBounds()!=0) {
3533                                //std::cout<<"Problem is infeasible!"<<std::endl;
3534                                //break;
3535                                //}
3536                                // bounds based on continuous
3537                                if (tightenFactor && !complicatedInteger) {
3538                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3539#ifndef DISALLOW_PRINTING
3540                                        std::cout << "Problem is infeasible!" << std::endl;
3541#endif
3542                                        model_.setProblemStatus(0);
3543                                        model_.setSecondaryStatus(1);
3544                                        // and in babModel if exists
3545                                        if (babModel_) {
3546                                            babModel_->setProblemStatus(0);
3547                                            babModel_->setSecondaryStatus(1);
3548                                        }
3549                                        break;
3550                                    }
3551                                }
3552#endif
3553                            }
3554                            // See if we want preprocessing
3555                            OsiSolverInterface * saveSolver = NULL;
3556                            CglPreProcess process;
3557                            // Say integers in sync
3558                            bool integersOK = true;
3559                            delete babModel_;
3560                            babModel_ = new CbcModel(model_);
3561#ifndef CBC_OTHER_SOLVER
3562                            int numberChanged = 0;
3563                            OsiSolverInterface * solver3 = clpSolver->clone();
3564                            babModel_->assignSolver(solver3);
3565                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3566                            if (clpSolver2->messageHandler()->logLevel())
3567                                clpSolver2->messageHandler()->setLogLevel(1);
3568                            if (logLevel > -1)
3569                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3570                            lpSolver = clpSolver2->getModelPtr();
3571                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3572                                // User did not touch preset
3573                                int numberRows = lpSolver->numberRows();
3574                                const int cutoff1 = 10000;
3575                                const int cutoff2 = 100000;
3576                                const int base = 75;
3577                                const int freq0 = 50;
3578                                const int freq1 = 200;
3579                                const int freq2 = 400;
3580                                const int maximum = 1000;
3581                                int frequency;
3582                                if (numberRows < cutoff1)
3583                                    frequency = base + numberRows / freq0;
3584                                else if (numberRows < cutoff2)
3585                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3586                                else
3587                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3588                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3589                            }
3590#elif CBC_OTHER_SOLVER==1
3591                            OsiSolverInterface * solver3 = model_.solver()->clone();
3592                            babModel_->assignSolver(solver3);
3593#endif
3594                            time2 = CoinCpuTime();
3595                            totalTime += time2 - time1;
3596                            //time1 = time2;
3597                            double timeLeft = babModel_->getMaximumSeconds();
3598                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3599                            if (preProcess == 7) {
3600                                // use strategy instead
3601                                preProcess = 0;
3602                                useStrategy = true;
3603#ifdef COIN_HAS_LINK
3604                                // empty out any cuts
3605                                if (storedAmpl.sizeRowCuts()) {
3606                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3607                                    CglStored temp;
3608                                    storedAmpl = temp;
3609                                }
3610#endif
3611                            }
3612                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3613                              // see whether to switch off preprocessing
3614                              // only allow SOS and integer
3615                              OsiObject ** objects = babModel_->objects();
3616                              int numberObjects = babModel_->numberObjects();
3617                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3618                                CbcSOS * objSOS =
3619                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
3620                                CbcSimpleInteger * objSimpleInteger =
3621                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3622                                if (!objSimpleInteger&&!objSOS) {
3623                                  preProcess=0;
3624                                  break;
3625                                }
3626                              }
3627                            }
3628                            if (type == CBC_PARAM_ACTION_BAB) {
3629                                double limit;
3630                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
3631                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
3632                                        limit*clpSolver->getObjSense())
3633                                    preProcess = 0;
3634                            }
3635                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3636#ifndef CBC_OTHER_SOLVER
3637                                // See if sos from mps file
3638                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
3639                                    // SOS
3640                                    numberSOS = clpSolver->numberSOS();
3641                                    const CoinSet * setInfo = clpSolver->setInfo();
3642                                    sosStart = new int [numberSOS+1];
3643                                    sosType = new char [numberSOS];
3644                                    int i;
3645                                    int nTotal = 0;
3646                                    sosStart[0] = 0;
3647                                    for ( i = 0; i < numberSOS; i++) {
3648                                        int type = setInfo[i].setType();
3649                                        int n = setInfo[i].numberEntries();
3650                                        sosType[i] = static_cast<char>(type);
3651                                        nTotal += n;
3652                                        sosStart[i+1] = nTotal;
3653                                    }
3654                                    sosIndices = new int[nTotal];
3655                                    sosReference = new double [nTotal];
3656                                    for (i = 0; i < numberSOS; i++) {
3657                                        int n = setInfo[i].numberEntries();
3658                                        const int * which = setInfo[i].which();
3659                                        const double * weights = setInfo[i].weights();
3660                                        int base = sosStart[i];
3661                                        for (int j = 0; j < n; j++) {
3662                                            int k = which[j];
3663                                            sosIndices[j+base] = k;
3664                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
3665                                        }
3666                                    }
3667                                }
3668#endif
3669                                saveSolver = babModel_->solver()->clone();
3670                                /* Do not try and produce equality cliques and
3671                                   do up to 10 passes */
3672                                OsiSolverInterface * solver2;
3673                                {
3674                                    // Tell solver we are in Branch and Cut
3675                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
3676                                    // Default set of cut generators
3677                                    CglProbing generator1;
3678                                    generator1.setUsingObjective(1);
3679                                    generator1.setMaxPass(1);
3680                                    generator1.setMaxPassRoot(1);
3681                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
3682                                    generator1.setMaxElements(100);
3683                                    generator1.setMaxElementsRoot(200);
3684                                    generator1.setMaxLookRoot(50);
3685                                    if (saveSolver->getNumCols() > 3000)
3686                                        generator1.setMaxProbeRoot(123);
3687                                    generator1.setRowCuts(3);
3688                                    if ((tunePreProcess&1) != 0) {
3689                                        // heavy probing
3690                                        generator1.setMaxPassRoot(2);
3691                                        generator1.setMaxElements(300);
3692                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
3693                                    }
3694                                    if ((babModel_->specialOptions()&65536) != 0)
3695                                        process.setOptions(1);
3696                                    // Add in generators
3697                                    if ((model_.moreSpecialOptions()&65536)==0)
3698                                      process.addCutGenerator(&generator1);
3699                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
3700                                    process.passInMessageHandler(babModel_->messageHandler());
3701                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
3702#ifdef COIN_HAS_ASL
3703                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
3704                                        // SOS
3705                                        numberSOS = info.numberSos;
3706                                        sosStart = info.sosStart;
3707                                        sosIndices = info.sosIndices;
3708                                    }
3709#endif
3710                                    if (numberSOS && doSOS) {
3711                                        // SOS
3712                                        int numberColumns = saveSolver->getNumCols();
3713                                        char * prohibited = new char[numberColumns];
3714                                        memset(prohibited, 0, numberColumns);
3715                                        int n = sosStart[numberSOS];
3716                                        for (int i = 0; i < n; i++) {
3717                                            int iColumn = sosIndices[i];
3718                                            prohibited[iColumn] = 1;
3719                                        }
3720                                        process.passInProhibited(prohibited, numberColumns);
3721                                        delete [] prohibited;
3722                                    }
3723                                    if (!model_.numberObjects() && true) {
3724                                        /* model may not have created objects
3725                                           If none then create
3726                                        */
3727                                        model_.findIntegers(true);
3728                                    }
3729                                    if (model_.numberObjects()) {
3730                                        OsiObject ** oldObjects = babModel_->objects();
3731                                        int numberOldObjects = babModel_->numberObjects();
3732                                        // SOS
3733                                        int numberColumns = saveSolver->getNumCols();
3734                                        char * prohibited = new char[numberColumns];
3735                                        memset(prohibited, 0, numberColumns);
3736                                        int numberProhibited = 0;
3737                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
3738                                            CbcSOS * obj =
3739                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
3740                                            if (obj) {
3741                                                int n = obj->numberMembers();
3742                                                const int * which = obj->members();
3743                                                for (int i = 0; i < n; i++) {
3744                                                    int iColumn = which[i];
3745                                                    prohibited[iColumn] = 1;
3746                                                    numberProhibited++;
3747                                                }
3748                                            }
3749                                            CbcLotsize * obj2 =
3750                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
3751                                            if (obj2) {
3752                                                int iColumn = obj2->columnNumber();
3753                                                prohibited[iColumn] = 1;
3754                                                numberProhibited++;
3755                                            }
3756                                        }
3757                                        if (numberProhibited)
3758                                            process.passInProhibited(prohibited, numberColumns);
3759                                        delete [] prohibited;
3760                                    }
3761                                    int numberPasses = 10;
3762                                    if (tunePreProcess >= 1000000) {
3763                                        numberPasses = (tunePreProcess / 1000000) - 1;
3764                                        tunePreProcess = tunePreProcess % 1000000;
3765                                    } else if (tunePreProcess >= 1000) {
3766                                        numberPasses = (tunePreProcess / 1000) - 1;
3767                                        tunePreProcess = tunePreProcess % 1000;
3768                                    }
3769#ifndef CBC_OTHER_SOLVER
3770                                    if (doSprint > 0) {
3771                                        // Sprint for primal solves
3772                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
3773                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
3774                                        int numberPasses = 5;
3775                                        int options[] = {0, 3, 0, 0, 0, 0};
3776                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
3777                                        extraInfo[1] = doSprint;
3778                                        int independentOptions[] = {0, 0, 3};
3779                                        ClpSolve clpSolve(method, presolveType, numberPasses,
3780                                                          options, extraInfo, independentOptions);
3781                                        // say use in OsiClp
3782                                        clpSolve.setSpecialOption(6, 1);
3783                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3784                                        osiclp->setSolveOptions(clpSolve);
3785                                        osiclp->setHintParam(OsiDoDualInResolve, false);
3786                                        // switch off row copy
3787                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
3788                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
3789                                    }
3790#endif
3791#ifndef CBC_OTHER_SOLVER
3792                                    {
3793                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3794                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
3795                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
3796                                        //#define CBC_TEMP1
3797#ifdef CBC_TEMP1
3798                                        if (savePerturbation == 50)
3799                                            osiclp->getModelPtr()->setPerturbation(52); // try less
3800#endif
3801                                        if ((model_.moreSpecialOptions()&65536)!=0)
3802                                          process.setOptions(2+4+8); // no cuts
3803                                        cbcPreProcessPointer = & process;
3804                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3805                                                                               tunePreProcess);
3806                                        /*solver2->writeMps("after");
3807                                          saveSolver->writeMps("before");*/
3808                                        osiclp->getModelPtr()->setPerturbation(savePerturbation);
3809                                    }
3810#elif CBC_OTHER_SOLVER==1
3811                                    cbcPreProcessPointer = & process;
3812                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
3813                                                                           tunePreProcess);
3814#endif
3815                                    integersOK = false; // We need to redo if CbcObjects exist
3816                                    // Tell solver we are not in Branch and Cut
3817                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3818                                    if (solver2)
3819                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
3820                                }
3821#ifdef COIN_HAS_ASL
3822                                if (!solver2 && statusUserFunction_[0]) {
3823                                    // infeasible
3824                                    info.problemStatus = 1;
3825                                    info.objValue = 1.0e100;
3826                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
3827                                    info.primalSolution = NULL;
3828                                    info.dualSolution = NULL;
3829                                    break;
3830                                }
3831#endif
3832                                if (!noPrinting_) {
3833                                    if (!solver2) {
3834                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
3835                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3836                                        << generalPrint
3837                                        << CoinMessageEol;
3838                                    } else {
3839                                        //printf("processed model has %d rows, %d columns and %d elements\n",
3840                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
3841                                    }
3842                                }
3843                                if (!solver2) {
3844                                    // say infeasible for solution
3845                                    integerStatus = 6;
3846                                    model_.setProblemStatus(0);
3847                                    model_.setSecondaryStatus(1);
3848                                    babModel_->setProblemStatus(0);
3849                                    babModel_->setSecondaryStatus(1);
3850                                } else {
3851                                    statistics_nprocessedrows = solver2->getNumRows();
3852                                    statistics_nprocessedcols = solver2->getNumCols();
3853                                    model_.setProblemStatus(-1);
3854                                    babModel_->setProblemStatus(-1);
3855                                }
3856                                int returnCode = callBack(babModel_, 2);
3857                                if (returnCode) {
3858                                    // exit if user wants
3859                                    delete babModel_;
3860                                    babModel_ = NULL;
3861                                    return returnCode;
3862                                }
3863                                if (!solver2)
3864                                    break;
3865                                if (model_.bestSolution()) {
3866                                    // need to redo - in case no better found in BAB
3867                                    // just get integer part right
3868                                    const int * originalColumns = process.originalColumns();
3869                                    int numberColumns = solver2->getNumCols();
3870                                    double * bestSolution = babModel_->bestSolution();
3871                                    const double * oldBestSolution = model_.bestSolution();
3872                                    for (int i = 0; i < numberColumns; i++) {
3873                                        int jColumn = originalColumns[i];
3874                                        bestSolution[i] = oldBestSolution[jColumn];
3875                                    }
3876                                }
3877                                //solver2->resolve();
3878                                if (preProcess == 2) {
3879                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3880                                    ClpSimplex * lpSolver = clpSolver2->getModelPtr();
3881                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
3882                                    printf("Preprocessed model (minimization) on presolved.mps\n");
3883                                }
3884                                {
3885                                    // look at new integers
3886                                    int numberOriginalColumns =
3887                                        process.originalModel()->getNumCols();
3888                                    const int * originalColumns = process.originalColumns();
3889                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
3890                                    int numberColumns = osiclp2->getNumCols();
3891                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
3892                                    for (int i = 0; i < numberColumns; i++) {
3893                                        int iColumn = originalColumns[i];
3894                                        if (iColumn < numberOriginalColumns) {
3895                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
3896                                                osiclp2->setOptionalInteger(i); // say optional
3897                                        }
3898                                    }
3899                                }
3900                                // we have to keep solver2 so pass clone
3901                                solver2 = solver2->clone();
3902                                babModel_->assignSolver(solver2);
3903                                babModel_->setOriginalColumns(process.originalColumns());
3904                                babModel_->initialSolve();
3905                                babModel_->setMaximumSeconds(timeLeft - (CoinCpuTime() - time2));
3906                            }
3907                            // now tighten bounds
3908                            if (!miplib) {
3909#ifndef CBC_OTHER_SOLVER
3910                                OsiClpSolverInterface * si =
3911                                    dynamic_cast<OsiClpSolverInterface *>(babModel_->solver()) ;
3912                                assert (si != NULL);
3913                                // get clp itself
3914                                ClpSimplex * modelC = si->getModelPtr();
3915                                //if (noPrinting_)
3916                                //modelC->setLogLevel(0);
3917                                if (!complicatedInteger && modelC->tightenPrimalBounds() != 0) {
3918#ifndef DISALLOW_PRINTING
3919                                    std::cout << "Problem is infeasible!" << std::endl;
3920#endif
3921                                    model_.setProblemStatus(0);
3922                                    model_.setSecondaryStatus(1);
3923                                    // and in babModel_ if exists
3924                                    if (babModel_) {
3925                                        babModel_->setProblemStatus(0);
3926                                        babModel_->setSecondaryStatus(1);
3927                                    }
3928                                    break;
3929                                }
3930                                si->resolve();
3931#elif CBC_OTHER_SOLVER==1
3932#endif
3933                            }
3934                            if (debugValues) {
3935                                // for debug
3936                                std::string problemName ;
3937                                babModel_->solver()->getStrParam(OsiProbName, problemName) ;
3938                                babModel_->solver()->activateRowCutDebugger(problemName.c_str()) ;
3939                                twomirGen.probname_ = CoinStrdup(problemName.c_str());
3940                                // checking seems odd
3941                                //redsplitGen.set_given_optsol(babModel_->solver()->getRowCutDebuggerAlways()->optimalSolution(),
3942                                //                         babModel_->getNumCols());
3943                            }
3944                            int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3945                            //#ifdef COIN_HAS_ASL
3946#ifndef JJF_ONE
3947                            // If linked then see if expansion wanted
3948                            {
3949                                OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel_->solver());
3950                                int options = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() / 10000;
3951                                if (solver3 || (options&16) != 0) {
3952                                    if (options) {
3953                                        /*
3954                                          1 - force mini branch and bound
3955                                          2 - set priorities high on continuous
3956                                          4 - try adding OA cuts
3957                                          8 - try doing quadratic linearization
3958                                          16 - try expanding knapsacks
3959                                        */
3960                                        if ((options&16)) {
3961                                            int numberColumns = saveCoinModel.numberColumns();
3962                                            int numberRows = saveCoinModel.numberRows();
3963                                            whichColumn = new int[numberColumns];
3964                                            knapsackStart = new int[numberRows+1];
3965                                            knapsackRow = new int[numberRows];
3966                                            numberKnapsack = 10000;
3967                                            int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3968                                            int extra2 = parameters_[whichParam(CBC_PARAM_INT_EXTRA2, numberParameters_, parameters_)].intValue();
3969                                            int logLevel = parameters_[log].intValue();
3970                                            OsiSolverInterface * solver = expandKnapsack(saveCoinModel, whichColumn, knapsackStart,
3971                                                                          knapsackRow, numberKnapsack,
3972                                                                          storedAmpl, logLevel, extra1, extra2,
3973                                                                          saveTightenedModel);
3974                                            if (solver) {
3975#ifndef CBC_OTHER_SOLVER
3976                                                clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3977                                                assert (clpSolver);
3978                                                lpSolver = clpSolver->getModelPtr();
3979#endif
3980                                                babModel_->assignSolver(solver);
3981                                                testOsiOptions = 0;
3982                                                // allow gomory
3983                                                complicatedInteger = 0;
3984#ifdef COIN_HAS_ASL
3985                                                // Priorities already done
3986                                                free(info.priorities);
3987                                                info.priorities = NULL;
3988#endif
3989                                            } else {
3990                                                numberKnapsack = 0;
3991                                                delete [] whichColumn;
3992                                                delete [] knapsackStart;
3993                                                delete [] knapsackRow;
3994                                                whichColumn = NULL;
3995                                                knapsackStart = NULL;
3996                                                knapsackRow = NULL;
3997                                            }
3998                                        }
3999                                    }
4000                                }
4001                            }
4002#endif
4003                            if (useCosts && testOsiOptions < 0) {
4004                                int numberColumns = babModel_->getNumCols();
4005                                int * sort = new int[numberColumns];
4006                                double * dsort = new double[numberColumns];
4007                                int * priority = new int [numberColumns];
4008                                const double * objective = babModel_->getObjCoefficients();
4009                                const double * lower = babModel_->getColLower() ;
4010                                const double * upper = babModel_->getColUpper() ;
4011                                const CoinPackedMatrix * matrix = babModel_->solver()->getMatrixByCol();
4012                                const int * columnLength = matrix->getVectorLengths();
4013                                int iColumn;
4014                                int n = 0;
4015                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4016                                    if (babModel_->isInteger(iColumn)) {
4017                                        sort[n] = n;
4018                                        if (useCosts == 1)
4019                                            dsort[n++] = -fabs(objective[iColumn]);
4020                                        else if (useCosts == 2)
4021                                            dsort[n++] = iColumn;
4022                                        else if (useCosts == 3)
4023                                            dsort[n++] = upper[iColumn] - lower[iColumn];
4024                                        else if (useCosts == 4)
4025                                            dsort[n++] = -(upper[iColumn] - lower[iColumn]);
4026                                        else if (useCosts == 5)
4027                                            dsort[n++] = -columnLength[iColumn];
4028                                    }
4029                                }
4030                                CoinSort_2(dsort, dsort + n, sort);
4031                                int level = 0;
4032                                double last = -1.0e100;
4033                                for (int i = 0; i < n; i++) {
4034                                    int iPut = sort[i];
4035                                    if (dsort[i] != last) {
4036                                        level++;
4037                                        last = dsort[i];
4038                                    }
4039                                    priority[iPut] = level;
4040                                }
4041                                babModel_->passInPriorities( priority, false);
4042                                integersOK = true;
4043                                delete [] priority;
4044                                delete [] sort;
4045                                delete [] dsort;
4046                            }
4047                            // Set up heuristics
4048                            doHeuristics(babModel_, ((!miplib) ? 1 : 10), parameters_,
4049                                         numberParameters_, noPrinting_, initialPumpTune);
4050                            if (!miplib) {
4051                                if (parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].currentOptionAsInteger()) {
4052                                    CbcTreeLocal localTree(babModel_, NULL, 10, 0, 0, 10000, 2000);
4053                                    babModel_->passInTreeHandler(localTree);
4054                                }
4055                            }
4056                            if (type == CBC_PARAM_ACTION_MIPLIB) {
4057                                if (babModel_->numberStrong() == 5 && babModel_->numberBeforeTrust() == 5)
4058                                    babModel_->setNumberBeforeTrust(10);
4059                            }
4060                            int experimentFlag = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
4061                                                             parameters_)].intValue();
4062                            int strategyFlag = parameters_[whichParam(CBC_PARAM_INT_STRATEGY, numberParameters_,
4063                                                           parameters_)].intValue();
4064                            int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag);
4065                            // add cut generators if wanted
4066                            int switches[30];
4067                            int accuracyFlag[30];
4068                            char doAtEnd[30];
4069                            memset(doAtEnd,0,30);
4070                            int numberGenerators = 0;
4071                            int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1};
4072                            if (probingAction) {
4073                                int numberColumns = babModel_->solver()->getNumCols();
4074                                if (probingAction > 7) {
4075                                    probingGen.setMaxElements(numberColumns);
4076                                    probingGen.setMaxElementsRoot(numberColumns);
4077                                }
4078                                probingGen.setMaxProbeRoot(CoinMin(2000, numberColumns));
4079                                probingGen.setMaxProbeRoot(123);
4080                                probingGen.setMaxProbe(123);
4081                                probingGen.setMaxLookRoot(20);
4082                                if (probingAction == 7 || probingAction == 9)
4083                                    probingGen.setRowCuts(-3); // strengthening etc just at root
4084                                if (probingAction == 8 || probingAction == 9) {
4085                                    // Number of unsatisfied variables to look at
4086                                    probingGen.setMaxProbeRoot(numberColumns);
4087                                    probingGen.setMaxProbe(numberColumns);
4088                                    // How far to follow the consequences
4089                                    probingGen.setMaxLook(50);
4090                                    probingGen.setMaxLookRoot(50);
4091                                }
4092                                if (probingAction == 10) {
4093                                    probingGen.setMaxPassRoot(2);
4094                                    probingGen.setMaxProbeRoot(numberColumns);
4095                                    probingGen.setMaxLookRoot(100);
4096                                }
4097                                // If 5 then force on
4098                                int iAction = translate[probingAction];
4099                                if (probingAction == 5)
4100                                    iAction = 1;
4101                                babModel_->addCutGenerator(&probingGen, iAction, "Probing");
4102                                accuracyFlag[numberGenerators] = 5;
4103                                switches[numberGenerators++] = 0;
4104                            }
4105                            if (gomoryAction && (complicatedInteger != 1 ||
4106                                                 (gomoryAction == 1 || gomoryAction >= 4))) {
4107                                // try larger limit
4108                                int numberColumns = babModel_->getNumCols();
4109                                if (gomoryAction == 7) {
4110                                    gomoryAction = 4;
4111                                    gomoryGen.setLimitAtRoot(numberColumns);
4112                                    gomoryGen.setLimit(numberColumns);
4113                                } else if (gomoryAction == 8) {
4114                                    gomoryAction = 3;
4115                                    gomoryGen.setLimitAtRoot(numberColumns);
4116                                    gomoryGen.setLimit(200);
4117                                } else if (numberColumns > 5000) {
4118                                    //#define MORE_CUTS2
4119#ifdef MORE_CUTS2
4120                                    // try larger limit
4121                                    gomoryGen.setLimitAtRoot(numberColumns);
4122                                    gomoryGen.setLimit(200);
4123#else
4124                                    gomoryGen.setLimitAtRoot(2000);
4125                                    //gomoryGen.setLimit(200);
4126#endif
4127                                } else {
4128#ifdef MORE_CUTS2
4129                                    // try larger limit
4130                                    gomoryGen.setLimitAtRoot(numberColumns);
4131                                    gomoryGen.setLimit(200);
4132#endif
4133                                }
4134                                int cutLength =
4135                                    parameters_[whichParam(CBC_PARAM_INT_CUTLENGTH, numberParameters_, parameters_)].intValue();
4136                                if (cutLength != -1) {
4137                                    gomoryGen.setLimitAtRoot(cutLength);
4138                                    if (cutLength < 10000000) {
4139                                        gomoryGen.setLimit(cutLength);
4140                                    } else {
4141                                        gomoryGen.setLimit(cutLength % 10000000);
4142                                    }
4143                                }
4144                                int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
4145                                int gType = translate[gomoryAction];
4146                                if (!laGomory) {
4147                                  // Normal
4148                                  babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory");
4149                                  accuracyFlag[numberGenerators] = 3;
4150                                  switches[numberGenerators++] = 0;
4151                                } else {
4152                                  laGomory--;
4153                                  int type = (laGomory % 3)+1;
4154                                  int when = laGomory/3;
4155                                  char atEnd = (when<2) ? 1 : 0;
4156                                  int gomoryTypeMajor = 0;
4157                                  if (when<3) {
4158                                    // normal as well
4159                                    babModel_->addCutGenerator(&gomoryGen, gType, "Gomory");
4160                                    accuracyFlag[numberGenerators] = 3;
4161                                    switches[numberGenerators++] = 0;
4162                                    if (when==2)
4163                                      gomoryTypeMajor=10;
4164                                  } else {
4165                                    when--; // so on
4166                                    gomoryTypeMajor=20;
4167                                  }
4168                                  if (!when)
4169                                    gType=-99; // root
4170                                  gomoryGen.passInOriginalSolver(babModel_->solver());
4171                                  if ((type&1) !=0) {
4172                                    // clean
4173                                    gomoryGen.setGomoryType(gomoryTypeMajor+1);
4174                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1");
4175                                    accuracyFlag[numberGenerators] = 3;
4176                                    doAtEnd[numberGenerators]=atEnd;
4177                                    switches[numberGenerators++] = 0;
4178                                  }
4179                                  if ((type&2) !=0) {
4180                                    // simple
4181                                    gomoryGen.setGomoryType(gomoryTypeMajor+2);
4182                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2");
4183                                    accuracyFlag[numberGenerators] = 3;
4184                                    doAtEnd[numberGenerators]=atEnd;
4185                                    switches[numberGenerators++] = 0;
4186                                  }
4187                                }
4188                            }
4189#ifdef CLIQUE_ANALYSIS
4190                            if (miplib && !storedAmpl.sizeRowCuts()) {
4191                                printf("looking at probing\n");
4192                                babModel_->addCutGenerator(&storedAmpl, 1, "Stored");
4193                            }
4194#endif
4195                            if (knapsackAction) {
4196                                babModel_->addCutGenerator(&knapsackGen, translate[knapsackAction], "Knapsack");
4197                                accuracyFlag[numberGenerators] = 1;
4198                                switches[numberGenerators++] = -2;
4199                            }
4200                            if (redsplitAction && !complicatedInteger) {
4201                                babModel_->addCutGenerator(&redsplitGen, translate[redsplitAction], "Reduce-and-split");
4202                                accuracyFlag[numberGenerators] = 5;
4203                                switches[numberGenerators++] = 1;
4204                            }
4205                            if (cliqueAction) {
4206                                babModel_->addCutGenerator(&cliqueGen, translate[cliqueAction], "Clique");
4207                                accuracyFlag[numberGenerators] = 0;
4208                                switches[numberGenerators++] = 0;
4209                            }
4210                            if (mixedAction) {
4211                                babModel_->addCutGenerator(&mixedGen, translate[mixedAction], "MixedIntegerRounding2");
4212                                accuracyFlag[numberGenerators] = 2;
4213                                switches[numberGenerators++] = 0;
4214                            }
4215                            if (flowAction) {
4216                                babModel_->addCutGenerator(&flowGen, translate[flowAction], "FlowCover");
4217                                accuracyFlag[numberGenerators] = 2;
4218                                switches[numberGenerators++] = 1;
4219                            }
4220                            if (twomirAction && (complicatedInteger != 1 ||
4221                                                 (twomirAction == 1 || twomirAction >= 4))) {
4222                                // try larger limit
4223                                int numberColumns = babModel_->getNumCols();
4224                                if (twomirAction == 7) {
4225                                    twomirAction = 4;
4226                                    twomirGen.setMaxElements(numberColumns);
4227                                } else if (numberColumns > 5000 && twomirAction == 4) {
4228                                    twomirGen.setMaxElements(2000);
4229                                }
4230                                babModel_->addCutGenerator(&twomirGen, translate[twomirAction], "TwoMirCuts");
4231                                accuracyFlag[numberGenerators] = 4;
4232                                switches[numberGenerators++] = 1;
4233                            }
4234#ifndef DEBUG_MALLOC
4235                            if (landpAction) {
4236                                babModel_->addCutGenerator(&landpGen, translate[landpAction], "LiftAndProject");
4237                                accuracyFlag[numberGenerators] = 5;
4238                                switches[numberGenerators++] = 1;
4239                            }
4240#endif
4241                            if (residualCapacityAction) {
4242                                babModel_->addCutGenerator(&residualCapacityGen, translate[residualCapacityAction], "ResidualCapacity");
4243                                accuracyFlag[numberGenerators] = 5;
4244                                switches[numberGenerators++] = 1;
4245                            }
4246#ifdef ZERO_HALF_CUTS
4247                            if (zerohalfAction) {
4248                                if (zerohalfAction > 4) {
4249                                    //zerohalfAction -=4;
4250                                    zerohalfGen.setFlags(1);
4251                                }
4252                                babModel_->addCutGenerator(&zerohalfGen, translate[zerohalfAction], "ZeroHalf");
4253                                accuracyFlag[numberGenerators] = 5;
4254                                switches[numberGenerators++] = 2;
4255                            }
4256#endif
4257                            if (dominatedCuts)
4258                                babModel_->setSpecialOptions(babModel_->specialOptions() | 64);
4259                            // Say we want timings
4260                            numberGenerators = babModel_->numberCutGenerators();
4261                            int iGenerator;
4262                            int cutDepth =
4263                                parameters_[whichParam(CBC_PARAM_INT_CUTDEPTH, numberParameters_, parameters_)].intValue();
4264                            for (iGenerator = 0; iGenerator < numberGenerators; iGenerator++) {
4265                                CbcCutGenerator * generator = babModel_->cutGenerator(iGenerator);
4266                                int howOften = generator->howOften();
4267                                if (howOften == -98 || howOften == -99)
4268                                    generator->setSwitchOffIfLessThan(switches[iGenerator]);
4269                                // Use if any at root as more likely later and fairly cheap
4270                                //if (switches[iGenerator]==-2)
4271                                //generator->setWhetherToUse(true);
4272                                generator->setInaccuracy(accuracyFlag[iGenerator]);
4273                                if (doAtEnd[iGenerator]) {
4274                                  generator->setWhetherCallAtEnd(true);
4275                                  generator->setMustCallAgain(true);
4276                                }
4277                                generator->setTiming(true);
4278                                if (cutDepth >= 0)
4279                                    generator->setWhatDepth(cutDepth) ;
4280                            }
4281                            // Could tune more
4282                            if (!miplib) {
4283                                double minimumDrop =
4284                                    fabs(babModel_->solver()->getObjValue()) * 1.0e-5 + 1.0e-5;
4285                                babModel_->setMinimumDrop(CoinMin(5.0e-2, minimumDrop));
4286                                if (cutPass == -1234567) {
4287                                    if (babModel_->getNumCols() < 500)
4288                                        babModel_->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
4289                                    else if (babModel_->getNumCols() < 5000)
4290                                        babModel_->setMaximumCutPassesAtRoot(100); // use minimum drop
4291                                    else
4292                                        babModel_->setMaximumCutPassesAtRoot(20);
4293                                } else {
4294                                    babModel_->setMaximumCutPassesAtRoot(cutPass);
4295                                }
4296                                if (cutPassInTree == -1234567)
4297                                    babModel_->setMaximumCutPasses(4);
4298                                else
4299                                    babModel_->setMaximumCutPasses(cutPassInTree);
4300                            } else if (cutPass != -1234567) {
4301                                babModel_->setMaximumCutPassesAtRoot(cutPass);
4302                            }
4303                            // Do more strong branching if small
4304                            //if (babModel_->getNumCols()<5000)
4305                            //babModel_->setNumberStrong(20);
4306                            // Switch off strong branching if wanted
4307                            //if (babModel_->getNumCols()>10*babModel_->getNumRows())
4308                            //babModel_->setNumberStrong(0);
4309                            if (!noPrinting_) {
4310                                int iLevel = parameters_[log].intValue();
4311                                if (iLevel < 0) {
4312                                    if (iLevel > -10) {
4313                                        babModel_->setPrintingMode(1);
4314                                    } else {
4315                                        babModel_->setPrintingMode(2);
4316                                        iLevel += 10;
4317                                        parameters_[log].setIntValue(iLevel);
4318                                    }
4319                                    iLevel = -iLevel;
4320                                }
4321                                babModel_->messageHandler()->setLogLevel(iLevel);
4322                                if (babModel_->getNumCols() > 2000 || babModel_->getNumRows() > 1500 ||
4323                                        babModel_->messageHandler()->logLevel() > 1)
4324                                    babModel_->setPrintFrequency(100);
4325                            }
4326
4327                            babModel_->solver()->setIntParam(OsiMaxNumIterationHotStart,
4328                                                             parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].intValue());
4329#ifndef CBC_OTHER_SOLVER
4330                            OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
4331                            // go faster stripes
4332                            if ((osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500)) {
4333                                osiclp->setupForRepeatedUse(2, parameters_[slog].intValue());
4334                                if (bothFlags >= 1) {
4335                                    ClpSimplex * lp = osiclp->getModelPtr();
4336                                    int specialOptions = lp->specialOptions();
4337                                    lp->setSpecialOptions(specialOptions | (2048 + 4096));
4338                                }
4339                            } else {
4340                                osiclp->setupForRepeatedUse(0, parameters_[slog].intValue());
4341                            }
4342                            if (bothFlags >= 2) {
4343                                ClpSimplex * lp = osiclp->getModelPtr();
4344                                int specialOptions = lp->specialOptions();
4345                                lp->setSpecialOptions(specialOptions | (2048 + 4096));
4346                            }
4347                            double increment = babModel_->getCutoffIncrement();;
4348                            int * changed = NULL;
4349                            if (!miplib && increment == normalIncrement)
4350                                changed = analyze( osiclp, numberChanged, increment, false, generalMessageHandler, noPrinting);
4351#elif CBC_OTHER_SOLVER==1
4352                            double increment = babModel_->getCutoffIncrement();;
4353#endif
4354                            if (debugValues) {
4355                                int numberColumns = babModel_->solver()->getNumCols();
4356                                if (numberDebugValues == numberColumns) {
4357                                    // for debug
4358                                    babModel_->solver()->activateRowCutDebugger(debugValues) ;
4359                                } else {
4360                                    int numberOriginalColumns =
4361                                        process.originalModel()->getNumCols();
4362                                    if (numberDebugValues <= numberOriginalColumns) {
4363                                        const int * originalColumns = process.originalColumns();
4364                                        double * newValues = new double [numberColumns];
4365                                        // in case preprocess added columns!
4366                                        // need to find values
4367                                        OsiSolverInterface * siCopy =
4368                                            babModel_->solver()->clone();
4369                                        for (int i = 0; i < numberColumns; i++) {
4370                                            int jColumn = originalColumns[i];
4371                                            if (jColumn < numberDebugValues &&
4372                                                    siCopy->isInteger(i)) {
4373                                                // integer variable
4374                                                double soln = floor(debugValues[jColumn] + 0.5);
4375                                                // Set bounds to fix variable to its solution
4376                                                siCopy->setColUpper(i, soln);
4377                                                siCopy->setColLower(i, soln);
4378                                            }
4379                                        }
4380                                        // All integers have been fixed at optimal value.
4381                                        // Now solve to get continuous values
4382                                        siCopy->setHintParam(OsiDoScale, false);
4383                                        siCopy->initialSolve();
4384                                        if (siCopy->isProvenOptimal()) {
4385                                            memcpy(newValues, siCopy->getColSolution(),
4386                                                   numberColumns*sizeof(double));
4387                                        } else {
4388                                            printf("BAD debug file\n");
4389                                            siCopy->writeMps("Bad");
4390                                            exit(22);
4391                                        }
4392                                        delete siCopy;
4393                                        // for debug
4394                                        babModel_->solver()->activateRowCutDebugger(newValues) ;
4395                                        delete [] newValues;
4396                                    } else {
4397                                        printf("debug file has incorrect number of columns\n");
4398                                    }
4399                                }
4400                            }
4401                            babModel_->setCutoffIncrement(CoinMax(babModel_->getCutoffIncrement(), increment));
4402                            // Turn this off if you get problems
4403                            // Used to be automatically set
4404                            int mipOptions = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() % 10000;
4405                            if (mipOptions != (1057)) {
4406                                sprintf(generalPrint, "mip options %d", mipOptions);
4407                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
4408                                << generalPrint
4409                                << CoinMessageEol;
4410                            }
4411#ifndef CBC_OTHER_SOLVER
4412                            osiclp->setSpecialOptions(mipOptions);
4413#elif CBC_OTHER_SOLVER==1
4414#endif
4415                            // probably faster to use a basis to get integer solutions
4416                            babModel_->setSpecialOptions(babModel_->specialOptions() | 2);
4417                            currentBranchModel = babModel_;
4418                            //OsiSolverInterface * strengthenedModel=NULL;
4419                            if (type == CBC_PARAM_ACTION_BAB ||
4420                                    type == CBC_PARAM_ACTION_MIPLIB) {
4421                                if (strategyFlag == 1) {
4422                                    // try reduced model
4423                                    babModel_->setSpecialOptions(babModel_->specialOptions() | 512);
4424                                }
4425                                if (experimentFlag >= 5 || strategyFlag == 2) {
4426                                    // try reduced model at root
4427                                    babModel_->setSpecialOptions(babModel_->specialOptions() | 32768);
4428                                }
4429                                {
4430                                    int depthMiniBab = parameters_[whichParam(CBC_PARAM_INT_DEPTHMINIBAB, numberParameters_, parameters_)].intValue();
4431                                    if (depthMiniBab != -1)
4432                                        babModel_->setFastNodeDepth(depthMiniBab);
4433                                }
4434                                int extra4 = parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].intValue();
4435                                if (extra4 >= 0) {
4436                                    int strategy = extra4 % 10;
4437                                    extra4 /= 10;
4438                                    int method = extra4 % 100;
4439                                    extra4 /= 100;
4440                                    extra4 = strategy + method * 8 + extra4 * 1024;
4441                                    babModel_->setMoreSpecialOptions(extra4);
4442                                }
4443                                int moreMipOptions = parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].intValue();
4444                                if (moreMipOptions >= 0) {
4445                                    sprintf(generalPrint, "more mip options %d", moreMipOptions);
4446                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4447                                    << generalPrint
4448                                    << CoinMessageEol;
4449                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
4450                                    if (moreMipOptions == 10000) {
4451                                        // test memory saving
4452                                        moreMipOptions -= 10000;
4453                                        ClpSimplex * lpSolver = osiclp->getModelPtr();
4454                                        lpSolver->setPersistenceFlag(1);
4455                                        // switch off row copy if few rows
4456                                        if (lpSolver->numberRows() < 150)
4457                                            lpSolver->setSpecialOptions(lpSolver->specialOptions() | 256);
4458                                    }
4459                                    if (moreMipOptions < 10000 && moreMipOptions) {
4460                                        if (((moreMipOptions + 1) % 1000000) != 0)
4461                                            babModel_->setSearchStrategy(moreMipOptions % 1000000);
4462                                    } else if (moreMipOptions < 100000) {
4463                                        // try reduced model
4464                                        babModel_->setSpecialOptions(babModel_->specialOptions() | 512);
4465                                    }
4466                                    // go faster stripes
4467                                    if ( moreMipOptions >= 999999) {
4468                                        if (osiclp) {
4469                                            int save = osiclp->specialOptions();
4470                                            osiclp->setupForRepeatedUse(2, 0);
4471                                            osiclp->setSpecialOptions(save | osiclp->specialOptions());
4472                                        }
4473                                    }
4474                                }
4475                            }
4476                            {
4477                                int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
4478                                if (extra1 != -1) {
4479                                    if (extra1 < 0) {
4480                                        if (extra1 == -7777)
4481                                            extra1 = -1;
4482                                        else if (extra1 == -8888)
4483                                            extra1 = 1;
4484                                        babModel_->setWhenCuts(-extra1);
4485                                    } else if (extra1 < 19000) {
4486                                        babModel_->setSearchStrategy(extra1);
4487                                        printf("XXXXX searchStrategy %d\n", extra1);
4488                                    } else {
4489                                        int n = extra1 - 20000;
4490                                        if (!n)
4491                                            n--;
4492                                        babModel_->setNumberAnalyzeIterations(n);
4493                                        printf("XXXXX analyze %d\n", extra1);
4494                                    }
4495                                } else if (bothFlags >= 1) {
4496                                    babModel_->setWhenCuts(999998);
4497                                }
4498                            }
4499                            if (type == CBC_PARAM_ACTION_BAB) {
4500#ifdef COIN_HAS_ASL
4501                                if (statusUserFunction_[0]) {
4502                                    priorities = info.priorities;
4503                                    branchDirection = info.branchDirection;
4504                                    pseudoDown = info.pseudoDown;
4505                                    pseudoUp = info.pseudoUp;
4506                                    solutionIn = info.primalSolution;
4507                                    prioritiesIn = info.priorities;
4508                                    if (info.numberSos && doSOS) {
4509                                        // SOS
4510                                        numberSOS = info.numberSos;
4511                                        sosStart = info.sosStart;
4512                                        sosIndices = info.sosIndices;
4513                                        sosType = info.sosType;
4514                                        sosReference = info.sosReference;
4515                                        sosPriority = info.sosPriority;
4516                                    }
4517                                }
4518#endif
4519                                const int * originalColumns = preProcess ? process.originalColumns() : NULL;
4520
4521                                if (mipStart.size())
4522                                {
4523                                   if (preProcess)
4524                                   {
4525                                      std::vector< std::string > colNames;
4526                                      for ( int i=0 ; (i<babModel_->solver()->getNumCols()) ; ++i )
4527                                         colNames.push_back( model_.solver()->getColName( babModel_->originalColumns()[i] ) );
4528                                      //printf("--- %s %d\n", babModel_->solver()->getColName(0).c_str(), babModel_->solver()->getColNames().size() );
4529                                      //printf("-- SIZES of models %d %d %d\n", model_.getNumCols(),  babModel_->solver()->getNumCols(), babModel_->solver()->getColNames().size() );
4530                                      std::vector< double > x( babModel_->getNumCols(), 0.0 );
4531                                      double obj;
4532                                      int status = computeCompleteSolution( babModel_, colNames, mipStart, &x[0], obj );
4533                                      if (!status)
4534                                         babModel_->setBestSolution( &x[0], x.size(), obj, false );
4535                                   }
4536                                }
4537
4538                                if (solutionIn && useSolution >= 0) {
4539                                    if (!prioritiesIn) {
4540                                        int n;
4541                                        if (preProcess) {
4542                                            int numberColumns = babModel_->getNumCols();
4543                                            // extend arrays in case SOS
4544                                            n = originalColumns[numberColumns-1] + 1;
4545                                        } else {
4546                                            n = babModel_->getNumCols();
4547                                        }
4548                                        prioritiesIn = reinterpret_cast<int *> (malloc(n * sizeof(int)));
4549                                        for (int i = 0; i < n; i++)
4550                                            prioritiesIn[i] = 100;
4551                                    }
4552                                    if (preProcess) {
4553                                        int numberColumns = babModel_->getNumCols();
4554                                        // extend arrays in case SOS
4555                                        int n = originalColumns[numberColumns-1] + 1;
4556                                        int nSmaller = CoinMin(n, numberOriginalColumns);
4557                                        double * solutionIn2 = new double [n];
4558                                        int * prioritiesIn2 = new int[n];
4559                                        int i;
4560                                        for (i = 0; i < nSmaller; i++) {
4561                                            solutionIn2[i] = solutionIn[i];
4562                                            prioritiesIn2[i] = prioritiesIn[i];
4563                                        }
4564                                        for (; i < n; i++) {
4565                                            solutionIn2[i] = 0.0;
4566                                            prioritiesIn2[i] = 1000000;
4567                                        }
4568                                        int iLast = -1;
4569                                        for (i = 0; i < numberColumns; i++) {
4570                                            int iColumn = originalColumns[i];
4571                                            assert (iColumn > iLast);
4572                                            iLast = iColumn;
4573                                            solutionIn2[i] = solutionIn2[iColumn];
4574                                            if (prioritiesIn)
4575                                                prioritiesIn2[i] = prioritiesIn2[iColumn];
4576                                        }
4577                                        if (useSolution)
4578                                            babModel_->setHotstartSolution(solutionIn2, prioritiesIn2);
4579                                        else
4580                                            babModel_->setBestSolution(solutionIn2, numberColumns,
4581                                                                       COIN_DBL_MAX, true);
4582                                        delete [] solutionIn2;
4583                                        delete [] prioritiesIn2;
4584                                    } else {
4585                                        if (useSolution)
4586                                            babModel_->setHotstartSolution(solutionIn, prioritiesIn);
4587                                        else
4588                                            babModel_->setBestSolution(solutionIn, babModel_->getNumCols(),
4589                                                                       COIN_DBL_MAX, true);
4590                                    }
4591                                }
4592                                OsiSolverInterface * testOsiSolver = (testOsiOptions >= 0) ? babModel_->solver() : NULL;
4593                                if (!testOsiSolver) {
4594                                    // *************************************************************
4595                                    // CbcObjects
4596                                    if (preProcess && (process.numberSOS() || babModel_->numberObjects())) {
4597                                        int numberSOS = process.numberSOS();
4598                                        int numberIntegers = babModel_->numberIntegers();
4599                                        /* model may not have created objects
4600                                           If none then create
4601                                        */
4602                                        if (!numberIntegers || !babModel_->numberObjects()) {
4603                                            int type = (pseudoUp) ? 1 : 0;
4604                                            babModel_->findIntegers(true, type);
4605                                            numberIntegers = babModel_->numberIntegers();
4606                                            integersOK = true;
4607                                        }
4608                                        OsiObject ** oldObjects = babModel_->objects();
4609                                        // Do sets and priorities
4610                                        OsiObject ** objects = new OsiObject * [numberSOS];
4611                                        // set old objects to have low priority
4612                                        int numberOldObjects = babModel_->numberObjects();
4613                                        int numberColumns = babModel_->getNumCols();
4614                                        // backward pointer to new variables
4615                                        // extend arrays in case SOS
4616                                        assert (originalColumns);
4617                                        int n = originalColumns[numberColumns-1] + 1;
4618                                        n = CoinMax(n, CoinMax(numberColumns, numberOriginalColumns));
4619                                        int * newColumn = new int[n];
4620                                        int i;
4621                                        for (i = 0; i < numberOriginalColumns; i++)
4622                                            newColumn[i] = -1;
4623                                        for (i = 0; i < numberColumns; i++)
4624                                            newColumn[originalColumns[i]] = i;
4625                                        if (!integersOK) {
4626                                            // Change column numbers etc
4627                                            int n = 0;
4628                                            for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4629                                                int iColumn = oldObjects[iObj]->columnNumber();
4630                                                if (iColumn < 0 || iColumn >= numberOriginalColumns) {
4631                                                    oldObjects[n++] = oldObjects[iObj];
4632                                                } else {
4633                                                    iColumn = newColumn[iColumn];
4634                                                    if (iColumn >= 0) {
4635                                                        CbcSimpleInteger * obj =
4636                                                            dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
4637                                                        if (obj) {
4638                                                            obj->setColumnNumber(iColumn);
4639                                                        } else {
4640                                                            // only other case allowed is lotsizing
4641                                                            CbcLotsize * obj2 =
4642                                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
4643                                                            assert (obj2);
4644                                                            obj2->setModelSequence(iColumn);
4645                                                        }
4646                                                        oldObjects[n++] = oldObjects[iObj];
4647                                                    } else {
4648                                                        delete oldObjects[iObj];
4649                                                    }
4650                                                }
4651                                            }
4652                                            babModel_->setNumberObjects(n);
4653                                            numberOldObjects = n;
4654                                            babModel_->zapIntegerInformation();
4655                                        }
4656                                        int nMissing = 0;
4657                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4658                                            if (process.numberSOS())
4659                                                oldObjects[iObj]->setPriority(numberColumns + 1);
4660                                            int iColumn = oldObjects[iObj]->columnNumber();
4661                                            if (iColumn < 0 || iColumn >= numberOriginalColumns) {
4662                                                CbcSOS * obj =
4663                                                    dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
4664                                                if (obj) {
4665                                                    int n = obj->numberMembers();
4666                                                    int * which = obj->mutableMembers();
4667                                                    double * weights = obj->mutableWeights();
4668                                                    int nn = 0;
4669                                                    for (i = 0; i < n; i++) {
4670                                                        int iColumn = which[i];
4671                                                        int jColumn = newColumn[iColumn];
4672                                                        if (jColumn >= 0) {
4673                                                            which[nn] = jColumn;
4674                                                            weights[nn++] = weights[i];
4675                                                        } else {
4676                                                            nMissing++;
4677                                                        }
4678                                                    }
4679                                                    obj->setNumberMembers(nn);
4680                                                }
4681                                                continue;
4682                                            }
4683                                            if (originalColumns)
4684                                                iColumn = originalColumns[iColumn];
4685                                            if (branchDirection) {
4686                                                CbcSimpleInteger * obj =
4687                                                    dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
4688                                                if (obj) {
4689                                                    obj->setPreferredWay(branchDirection[iColumn]);
4690                                                } else {
4691                                                    CbcObject * obj =
4692                                                        dynamic_cast <CbcObject *>(oldObjects[iObj]) ;
4693                                                    assert (obj);
4694                                                    obj->setPreferredWay(branchDirection[iColumn]);
4695                                                }
4696                                            }
4697                                            if (pseudoUp) {
4698                                                CbcSimpleIntegerPseudoCost * obj1a =
4699                                                    dynamic_cast <CbcSimpleIntegerPseudoCost *>(oldObjects[iObj]) ;
4700                                                assert (obj1a);
4701                                                if (pseudoDown[iColumn] > 0.0)
4702                                                    obj1a->setDownPseudoCost(pseudoDown[iColumn]);
4703                                                if (pseudoUp[iColumn] > 0.0)
4704                                                    obj1a->setUpPseudoCost(pseudoUp[iColumn]);
4705                                            }
4706                                        }
4707                                        if (nMissing) {
4708                                            sprintf(generalPrint, "%d SOS variables vanished due to pre processing? - check validity?", nMissing);
4709                                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
4710                                            << generalPrint
4711                                            << CoinMessageEol;
4712                                        }
4713                                        delete [] newColumn;
4714                                        const int * starts = process.startSOS();
4715                                        const int * which = process.whichSOS();
4716                                        const int * type = process.typeSOS();
4717                                        const double * weight = process.weightSOS();
4718                                        int iSOS;
4719                                        for (iSOS = 0; iSOS < numberSOS; iSOS++) {
4720                                            int iStart = starts[iSOS];
4721                                            int n = starts[iSOS+1] - iStart;
4722                                            objects[iSOS] = new CbcSOS(babModel_, n, which + iStart, weight + iStart,
4723                                                                       iSOS, type[iSOS]);
4724                                            // branch on long sets first
4725                                            objects[iSOS]->setPriority(numberColumns - n);
4726                                        }
4727                                        if (numberSOS)
4728                                            babModel_->addObjects(numberSOS, objects);
4729                                        for (iSOS = 0; iSOS < numberSOS; iSOS++)
4730                                            delete objects[iSOS];
4731                                        delete [] objects;
4732                                    } else if (priorities || branchDirection || pseudoDown || pseudoUp || numberSOS) {
4733                                        // do anyway for priorities etc
4734                                        int numberIntegers = babModel_->numberIntegers();
4735                                        /* model may not have created objects
4736                                           If none then create
4737                                        */
4738                                        if (!numberIntegers || !babModel_->numberObjects()) {
4739                                            int type = (pseudoUp) ? 1 : 0;
4740                                            babModel_->findIntegers(true, type);
4741                                        }
4742                                        if (numberSOS) {
4743                                            // Do sets and priorities
4744                                            OsiObject ** objects = new OsiObject * [numberSOS];
4745                                            int iSOS;
4746