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

Last change on this file since 1780 was 1780, checked in by forrest, 7 years ago

to print out saying optimal in more cases

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