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

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

merge r1831 from trunk

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