source: stable/2.8/Cbc/src/CbcSolver.cpp @ 1815

Last change on this file since 1815 was 1815, checked in by stefan, 9 years ago

merge r1813 from trunk

File size: 511.9 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
1133static CbcOrClpParam parameters[CBCMAXPARAMETERS];
1134static int numberParameters = 0 ;
1135CglPreProcess * cbcPreProcessPointer=NULL;
1136
1137int CbcClpUnitTest (const CbcModel & saveModel,
1138                    const std::string& dirMiplib, int testSwitch,
1139                    const double * stuff);
1140
1141int CbcMain1 (int argc, const char *argv[],
1142              CbcModel  & model)
1143{
1144    return CbcMain1(argc, argv, model, dummyCallBack);
1145}
1146
1147
1148/*
1149  Meaning of whereFrom:
1150    1 after initial solve by dualsimplex etc
1151    2 after preprocessing
1152    3 just before branchAndBound (so user can override)
1153    4 just after branchAndBound (before postprocessing)
1154    5 after postprocessing
1155    6 after a user called heuristic phase
1156*/
1157
1158int CbcMain1 (int argc, const char *argv[],
1159              CbcModel  & model,
1160              int callBack(CbcModel * currentSolver, int whereFrom))
1161{
1162    CbcOrClpParam * parameters_ = parameters;
1163    int numberParameters_ = numberParameters;
1164    CbcModel & model_ = model;
1165#ifdef CBC_USE_INITIAL_TIME
1166    if (model_.useElapsedTime())
1167      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1168    else
1169      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1170#endif
1171    CbcModel * babModel_ = NULL;
1172    int returnMode = 1;
1173    CbcOrClpRead_mode = 1;
1174    int statusUserFunction_[1];
1175    int numberUserFunctions_ = 1; // to allow for ampl
1176    // Statistics
1177    double statistics_seconds = 0.0, statistics_obj = 0.0;
1178    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1179    CoinWallclockTime();
1180    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1181    double statistics_cut_time = 0.0;
1182    int statistics_nodes = 0, statistics_iterations = 0;
1183    int statistics_nrows = 0, statistics_ncols = 0;
1184    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1185    std::string statistics_result;
1186    int * statistics_number_cuts = NULL;
1187    const char ** statistics_name_generators = NULL;
1188    int statistics_number_generators = 0;
1189    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1190    /* Note
1191       This is meant as a stand-alone executable to do as much of coin as possible.
1192       It should only have one solver known to it.
1193    */
1194    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1195    generalMessageHandler->setPrefix(false);
1196#ifndef CBC_OTHER_SOLVER
1197    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1198    assert (originalSolver);
1199    // Move handler across if not default
1200    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1201        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1202    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1203    char generalPrint[10000];
1204    if (originalSolver->getModelPtr()->logLevel() == 0)
1205        noPrinting = true;
1206#elif CBC_OTHER_SOLVER==1
1207    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1208    assert (originalSolver);
1209    OsiClpSolverInterface dummySolver;
1210    OsiCpxSolverInterface * clpSolver = originalSolver;
1211    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1212    char generalPrint[10000];
1213    noPrinting = true;
1214#endif
1215    bool noPrinting_ = noPrinting;
1216    // Say not in integer
1217    int integerStatus = -1;
1218    // Say no resolve after cuts
1219    model_.setResolveAfterTakeOffCuts(false);
1220    // see if log in list
1221    for (int i = 1; i < argc; i++) {
1222        if (!strncmp(argv[i], "log", 3)) {
1223            const char * equals = strchr(argv[i], '=');
1224            if (equals && atoi(equals + 1) != 0)
1225                noPrinting_ = false;
1226            else
1227                noPrinting_ = true;
1228            break;
1229        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1230            if (atoi(argv[i+1]) != 0)
1231                noPrinting_ = false;
1232            else
1233                noPrinting_ = true;
1234            break;
1235        }
1236    }
1237    double time0;
1238    double time0Elapsed = CoinGetTimeOfDay();
1239    {
1240        double time1 = CoinCpuTime(), time2;
1241        time0 = time1;
1242        double time1Elapsed = time0Elapsed;
1243        bool goodModel = (originalSolver->getNumCols()) ? true : false;
1244
1245        // register signal handler
1246        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
1247#if CBC_QUIET < 2
1248        signal(SIGINT, signal_handler);
1249#endif
1250        // Set up all non-standard stuff
1251        int cutPass = -1234567;
1252        int cutPassInTree = -1234567;
1253        int tunePreProcess = 0;
1254        int testOsiParameters = -1;
1255        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1256        int complicatedInteger = 0;
1257        OsiSolverInterface * solver = model_.solver();
1258        if (noPrinting_)
1259            setCbcOrClpPrinting(false);
1260#ifndef CBC_OTHER_SOLVER
1261        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1262        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1263        if (noPrinting_) {
1264            lpSolver->setLogLevel(0);
1265        }
1266#else
1267        ClpSimplex * lpSolver = NULL;
1268#endif
1269        // For priorities etc
1270        int * priorities = NULL;
1271        int * branchDirection = NULL;
1272        double * pseudoDown = NULL;
1273        double * pseudoUp = NULL;
1274        double * solutionIn = NULL;
1275        int * prioritiesIn = NULL;
1276        std::vector< std::pair< std::string, double > > mipStart;
1277        int numberSOS = 0;
1278        int * sosStart = NULL;
1279        int * sosIndices = NULL;
1280        char * sosType = NULL;
1281        double * sosReference = NULL;
1282        int * cut = NULL;
1283        int * sosPriority = NULL;
1284        CglStored storedAmpl;
1285        CoinModel * coinModel = NULL;
1286        CoinModel saveCoinModel;
1287        CoinModel saveTightenedModel;
1288        int * whichColumn = NULL;
1289        int * knapsackStart = NULL;
1290        int * knapsackRow = NULL;
1291        int numberKnapsack = 0;
1292#ifdef COIN_HAS_ASL
1293        ampl_info info;
1294        {
1295            memset(&info, 0, sizeof(info));
1296            if (argc > 2 && !strcmp(argv[2], "-AMPL")) {
1297                statusUserFunction_[0] = 1;
1298                // see if log in list
1299                noPrinting_ = true;
1300                for (int i = 1; i < argc; i++) {
1301                    if (!strncmp(argv[i], "log", 3)) {
1302                        const char * equals = strchr(argv[i], '=');
1303                        if (equals && atoi(equals + 1) > 0) {
1304                            noPrinting_ = false;
1305                            info.logLevel = atoi(equals + 1);
1306                            int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1307                            parameters_[log].setIntValue(info.logLevel);
1308                            // mark so won't be overWritten
1309                            info.numberRows = -1234567;
1310                            break;
1311                        }
1312                    }
1313                }
1314
1315                union {
1316                    void * voidModel;
1317                    CoinModel * model;
1318                } coinModelStart;
1319                coinModelStart.model = NULL;
1320                int returnCode = readAmpl(&info, argc, const_cast<char **>(argv), & coinModelStart.voidModel);
1321                coinModel = coinModelStart.model;
1322                if (returnCode)
1323                    return returnCode;
1324                CbcOrClpRead_mode = 2; // so will start with parameters
1325                // see if log in list (including environment)
1326                for (int i = 1; i < info.numberArguments; i++) {
1327                    if (!strcmp(info.arguments[i], "log")) {
1328                        if (i < info.numberArguments - 1 && atoi(info.arguments[i+1]) > 0)
1329                            noPrinting_ = false;
1330                        break;
1331                    }
1332                }
1333                if (noPrinting_) {
1334                    model_.messageHandler()->setLogLevel(0);
1335                    setCbcOrClpPrinting(false);
1336                }
1337                if (!noPrinting_)
1338                    printf("%d rows, %d columns and %d elements\n",
1339                           info.numberRows, info.numberColumns, info.numberElements);
1340#ifdef COIN_HAS_LINK
1341                if (!coinModel) {
1342#endif
1343                    solver->loadProblem(info.numberColumns, info.numberRows, info.starts,
1344                                        info.rows, info.elements,
1345                                        info.columnLower, info.columnUpper, info.objective,
1346                                        info.rowLower, info.rowUpper);
1347                    // take off cuts if ampl wants that
1348                    if (info.cut && 0) {
1349                        printf("AMPL CUTS OFF until global cuts fixed\n");
1350                        info.cut = NULL;
1351                    }
1352                    if (info.cut) {
1353                        int numberRows = info.numberRows;
1354                        int * whichRow = new int [numberRows];
1355                        // Row copy
1356                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1357                        const double * elementByRow = matrixByRow->getElements();
1358                        const int * column = matrixByRow->getIndices();
1359                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1360                        const int * rowLength = matrixByRow->getVectorLengths();
1361
1362                        const double * rowLower = solver->getRowLower();
1363                        const double * rowUpper = solver->getRowUpper();
1364                        int nDelete = 0;
1365                        for (int iRow = 0; iRow < numberRows; iRow++) {
1366                            if (info.cut[iRow]) {
1367                                whichRow[nDelete++] = iRow;
1368                                int start = rowStart[iRow];
1369                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1370                                                  rowLength[iRow], column + start, elementByRow + start);
1371                            }
1372                        }
1373                        solver->deleteRows(nDelete, whichRow);
1374                        delete [] whichRow;
1375                    }
1376#ifdef COIN_HAS_LINK
1377                } else {
1378#ifndef CBC_OTHER_SOLVER
1379                    // save
1380                    saveCoinModel = *coinModel;
1381                    // load from coin model
1382                    OsiSolverLink solver1;
1383                    OsiSolverInterface * solver2 = solver1.clone();
1384                    model_.assignSolver(solver2, false);
1385                    OsiSolverLink * si =
1386                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1387                    assert (si != NULL);
1388                    si->setDefaultMeshSize(0.001);
1389                    // need some relative granularity
1390                    si->setDefaultBound(100.0);
1391                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
1392                    if (dextra3)
1393                        si->setDefaultMeshSize(dextra3);
1394                    si->setDefaultBound(100000.0);
1395                    si->setIntegerPriority(1000);
1396                    si->setBiLinearPriority(10000);
1397                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
1398                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1399                    si->load(*model2, true, logLevel);
1400                    // redo
1401                    solver = model_.solver();
1402                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1403                    lpSolver = clpSolver->getModelPtr();
1404                    clpSolver->messageHandler()->setLogLevel(0) ;
1405                    testOsiParameters = 0;
1406                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
1407                    complicatedInteger = 1;
1408                    if (info.cut) {
1409                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1410                        abort();
1411                        int numberRows = info.numberRows;
1412                        int * whichRow = new int [numberRows];
1413                        // Row copy
1414                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1415                        const double * elementByRow = matrixByRow->getElements();
1416                        const int * column = matrixByRow->getIndices();
1417                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1418                        const int * rowLength = matrixByRow->getVectorLengths();
1419
1420                        const double * rowLower = solver->getRowLower();
1421                        const double * rowUpper = solver->getRowUpper();
1422                        int nDelete = 0;
1423                        for (int iRow = 0; iRow < numberRows; iRow++) {
1424                            if (info.cut[iRow]) {
1425                                whichRow[nDelete++] = iRow;
1426                                int start = rowStart[iRow];
1427                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1428                                                  rowLength[iRow], column + start, elementByRow + start);
1429                            }
1430                        }
1431                        solver->deleteRows(nDelete, whichRow);
1432                        // and special matrix
1433                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1434                        delete [] whichRow;
1435                    }
1436#endif
1437                }
1438#endif
1439                // If we had a solution use it
1440                if (info.primalSolution) {
1441                    solver->setColSolution(info.primalSolution);
1442                }
1443                // status
1444                if (info.rowStatus) {
1445                    unsigned char * statusArray = lpSolver->statusArray();
1446                    int i;
1447                    for (i = 0; i < info.numberColumns; i++)
1448                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1449                    statusArray += info.numberColumns;
1450                    for (i = 0; i < info.numberRows; i++)
1451                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1452                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1453                    solver->setWarmStart(basis);
1454                    delete basis;
1455                }
1456                freeArrays1(&info);
1457                // modify objective if necessary
1458                solver->setObjSense(info.direction);
1459                solver->setDblParam(OsiObjOffset, info.offset);
1460                if (info.offset) {
1461                    sprintf(generalPrint, "Ampl objective offset is %g",
1462                            info.offset);
1463                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1464                    << generalPrint
1465                    << CoinMessageEol;
1466                }
1467                // Set integer variables (unless nonlinear when set)
1468                if (!info.nonLinear) {
1469                    for (int i = info.numberColumns - info.numberIntegers;
1470                            i < info.numberColumns; i++)
1471                        solver->setInteger(i);
1472                }
1473                goodModel = true;
1474                // change argc etc
1475                argc = info.numberArguments;
1476                argv = const_cast<const char **>(info.arguments);
1477            }
1478        }
1479#endif
1480        // default action on import
1481        int allowImportErrors = 0;
1482        int keepImportNames = 1;
1483        int doIdiot = -1;
1484        int outputFormat = 2;
1485        int slpValue = -1;
1486        int cppValue = -1;
1487        int printOptions = 0;
1488        int printMode = 0;
1489        int presolveOptions = 0;
1490        int substitution = 3;
1491        int dualize = 3;
1492        int doCrash = 0;
1493        int doVector = 0;
1494        int doSprint = -1;
1495        int doScaling = 4;
1496        // set reasonable defaults
1497        int preSolve = 5;
1498        int preProcess = 4;
1499        bool useStrategy = false;
1500        bool preSolveFile = false;
1501        bool strongChanged = false;
1502        bool pumpChanged = false;
1503
1504        double djFix = 1.0e100;
1505        double tightenFactor = 0.0;
1506        const char dirsep =  CoinFindDirSeparator();
1507        std::string directory;
1508        std::string dirSample;
1509        std::string dirNetlib;
1510        std::string dirMiplib;
1511        if (dirsep == '/') {
1512            directory = "./";
1513            dirSample = "../../Data/Sample/";
1514            dirNetlib = "../../Data/Netlib/";
1515            dirMiplib = "../../Data/miplib3/";
1516        } else {
1517            directory = ".\\";
1518            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1519            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1520            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
1521        }
1522        std::string defaultDirectory = directory;
1523        std::string importFile = "";
1524        std::string exportFile = "default.mps";
1525        std::string importBasisFile = "";
1526        std::string importPriorityFile = "";
1527        std::string debugFile = "";
1528        std::string printMask = "";
1529        double * debugValues = NULL;
1530        int numberDebugValues = -1;
1531        int basisHasValues = 0;
1532        std::string exportBasisFile = "default.bas";
1533        std::string saveFile = "default.prob";
1534        std::string restoreFile = "default.prob";
1535        std::string solutionFile = "stdout";
1536        std::string solutionSaveFile = "solution.file";
1537        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1538        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1539#ifndef CBC_OTHER_SOLVER
1540        double normalIncrement = model_.getCutoffIncrement();;
1541#endif
1542        if (testOsiParameters >= 0) {
1543            // trying nonlinear - switch off some stuff
1544            preProcess = 0;
1545        }
1546        // Set up likely cut generators and defaults
1547        int nodeStrategy = 0;
1548        bool dominatedCuts = false;
1549        int doSOS = 1;
1550        int verbose = 0;
1551        CglGomory gomoryGen;
1552        // try larger limit
1553        gomoryGen.setLimitAtRoot(1000);
1554        gomoryGen.setLimit(50);
1555        // set default action (0=off,1=on,2=root)
1556        int gomoryAction = 3;
1557
1558        CglProbing probingGen;
1559        probingGen.setUsingObjective(1);
1560        probingGen.setMaxPass(1);
1561        probingGen.setMaxPassRoot(1);
1562        // Number of unsatisfied variables to look at
1563        probingGen.setMaxProbe(10);
1564        probingGen.setMaxProbeRoot(50);
1565        // How far to follow the consequences
1566        probingGen.setMaxLook(10);
1567        probingGen.setMaxLookRoot(50);
1568        probingGen.setMaxLookRoot(10);
1569        // Only look at rows with fewer than this number of elements
1570        probingGen.setMaxElements(200);
1571        probingGen.setMaxElementsRoot(300);
1572        probingGen.setRowCuts(3);
1573        // set default action (0=off,1=on,2=root)
1574        int probingAction = 1;
1575
1576        CglKnapsackCover knapsackGen;
1577        //knapsackGen.switchOnExpensive();
1578        //knapsackGen.setMaxInKnapsack(100);
1579        // set default action (0=off,1=on,2=root)
1580        int knapsackAction = 3;
1581
1582        CglRedSplit redsplitGen;
1583        //redsplitGen.setLimit(100);
1584        // set default action (0=off,1=on,2=root)
1585        // Off as seems to give some bad cuts
1586        int redsplitAction = 0;
1587
1588        CglFakeClique cliqueGen(NULL, false);
1589        //CglClique cliqueGen(false,true);
1590        cliqueGen.setStarCliqueReport(false);
1591        cliqueGen.setRowCliqueReport(false);
1592        cliqueGen.setMinViolation(0.1);
1593        // set default action (0=off,1=on,2=root)
1594        int cliqueAction = 3;
1595
1596        // maxaggr,multiply,criterion(1-3)
1597        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1598        // set default action (0=off,1=on,2=root)
1599        int mixedAction = 3;
1600
1601        CglFlowCover flowGen;
1602        // set default action (0=off,1=on,2=root)
1603        int flowAction = 3;
1604
1605        CglTwomir twomirGen;
1606        twomirGen.setMaxElements(250);
1607        // set default action (0=off,1=on,2=root)
1608        int twomirAction = 2;
1609#ifndef DEBUG_MALLOC
1610        CglLandP landpGen;
1611#endif
1612        // set default action (0=off,1=on,2=root)
1613        int landpAction = 0;
1614        CglResidualCapacity residualCapacityGen;
1615        // set default action (0=off,1=on,2=root)
1616        int residualCapacityAction = 0;
1617
1618#ifdef ZERO_HALF_CUTS
1619        CglZeroHalf zerohalfGen;
1620        //zerohalfGen.switchOnExpensive();
1621        // set default action (0=off,1=on,2=root)
1622        int zerohalfAction = 0;
1623#endif
1624
1625        // Stored cuts
1626        //bool storedCuts = false;
1627
1628        int useCosts = 0;
1629        // don't use input solution
1630        int useSolution = -1;
1631
1632        // total number of commands read
1633        int numberGoodCommands = 0;
1634        // Set false if user does anything advanced
1635        bool defaultSettings = true;
1636
1637        // Hidden stuff for barrier
1638        int choleskyType = 0;
1639        int gamma = 0;
1640        int scaleBarrier = 0;
1641        int doKKT = 0;
1642        int crossover = 2; // do crossover unless quadratic
1643        // For names
1644        int lengthName = 0;
1645        std::vector<std::string> rowNames;
1646        std::vector<std::string> columnNames;
1647        // Default strategy stuff
1648        {
1649            // try changing tolerance at root
1650#define MORE_CUTS
1651#ifdef MORE_CUTS
1652            gomoryGen.setAwayAtRoot(0.005);
1653            twomirGen.setAwayAtRoot(0.005);
1654            twomirGen.setAway(0.01);
1655            //twomirGen.setMirScale(1,1);
1656            //twomirGen.setTwomirScale(1,1);
1657            //twomirGen.setAMax(2);
1658#else
1659            gomoryGen.setAwayAtRoot(0.01);
1660            twomirGen.setAwayAtRoot(0.01);
1661            twomirGen.setAway(0.01);
1662#endif
1663            int iParam;
1664            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
1665            parameters_[iParam].setIntValue(3);
1666            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
1667            parameters_[iParam].setIntValue(30);
1668            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
1669            parameters_[iParam].setIntValue(1005043);
1670            initialPumpTune = 1005043;
1671            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
1672            parameters_[iParam].setIntValue(6);
1673            tunePreProcess = 6;
1674            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
1675            parameters_[iParam].setCurrentOption("on");
1676            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
1677            parameters_[iParam].setCurrentOption("on");
1678            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
1679            parameters_[iParam].setCurrentOption("on");
1680            probingAction = 1;
1681            parameters_[iParam].setCurrentOption("forceOnStrong");
1682            probingAction = 8;
1683        }
1684        std::string field;
1685#if CBC_QUIET == 0
1686        if (!noPrinting_) {
1687           sprintf(generalPrint,
1688                   "Welcome to the CBC MILP Solver \n");
1689            if (strcmp(CBC_VERSION, "trunk")){
1690               sprintf(generalPrint + strlen(generalPrint),
1691                       "Version: %s \n", CBC_VERSION);
1692            }else{
1693               sprintf(generalPrint + strlen(generalPrint),
1694                       "Version: Trunk (unstable) \n");
1695            }
1696            sprintf(generalPrint + strlen(generalPrint),
1697                    "Build Date: %s \n", __DATE__);
1698#ifdef CBC_SVN_REV
1699            sprintf(generalPrint + strlen(generalPrint),
1700                    "Revision Number: %d \n", CBC_SVN_REV);
1701#endif
1702            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1703            << generalPrint
1704            << CoinMessageEol;
1705            // Print command line
1706            if (argc > 1) {
1707                bool foundStrategy = false;
1708                sprintf(generalPrint, "command line - ");
1709                for (int i = 0; i < argc; i++) {
1710                    if (!argv[i])
1711                        break;
1712                    if (strstr(argv[i], "strat"))
1713                        foundStrategy = true;
1714                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1715                }
1716                if (!foundStrategy)
1717                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1718                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1719                << generalPrint
1720                << CoinMessageEol;
1721            }
1722        }
1723#endif
1724        while (1) {
1725            // next command
1726            field = CoinReadGetCommand(argc, argv);
1727            // Reset time
1728            time1 = CoinCpuTime();
1729            time1Elapsed = CoinGetTimeOfDay();
1730            // adjust field if has odd trailing characters
1731            char temp [200];
1732            strcpy(temp, field.c_str());
1733            int length = static_cast<int>(strlen(temp));
1734            for (int k = length - 1; k >= 0; k--) {
1735                if (temp[k] < ' ')
1736                    length--;
1737                else
1738                    break;
1739            }
1740            temp[length] = '\0';
1741            field = temp;
1742            // exit if null or similar
1743            if (!field.length()) {
1744                if (numberGoodCommands == 1 && goodModel) {
1745                    // we just had file name - do branch and bound
1746                    field = "branch";
1747                } else if (!numberGoodCommands) {
1748                    // let's give the sucker a hint
1749                    std::cout
1750                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1751                        << std::endl
1752                        << "Enter ? for list of commands or help" << std::endl;
1753                    field = "-";
1754                } else {
1755                    break;
1756                }
1757            }
1758
1759            // see if ? at end
1760            size_t numberQuery = 0;
1761            if (field != "?" && field != "???") {
1762                size_t length = field.length();
1763                size_t i;
1764                for (i = length - 1; i > 0; i--) {
1765                    if (field[i] == '?')
1766                        numberQuery++;
1767                    else
1768                        break;
1769                }
1770                field = field.substr(0, length - numberQuery);
1771            }
1772            // find out if valid command
1773            int iParam;
1774            int numberMatches = 0;
1775            int firstMatch = -1;
1776            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1777                int match = parameters_[iParam].matches(field);
1778                if (match == 1) {
1779                    numberMatches = 1;
1780                    firstMatch = iParam;
1781                    break;
1782                } else {
1783                    if (match && firstMatch < 0)
1784                        firstMatch = iParam;
1785                    numberMatches += match >> 1;
1786                }
1787            }
1788            if (iParam < numberParameters_ && !numberQuery) {
1789                // found
1790                CbcOrClpParam found = parameters_[iParam];
1791                CbcOrClpParameterType type = found.type();
1792                int valid;
1793                numberGoodCommands++;
1794                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
1795#ifndef CBC_USE_INITIAL_TIME
1796                  if (model_.useElapsedTime())
1797                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1798                  else
1799                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1800#endif
1801                    // check if any integers
1802#ifndef CBC_OTHER_SOLVER
1803#ifdef COIN_HAS_ASL
1804                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1805                        // SOS
1806                        numberSOS = info.numberSos;
1807                    }
1808#endif
1809                    lpSolver = clpSolver->getModelPtr();
1810                    if (!lpSolver->integerInformation() && !numberSOS &&
1811                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
1812                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
1813#endif
1814                }
1815                if (type == CBC_PARAM_GENERALQUERY) {
1816                    bool evenHidden = false;
1817                    int printLevel =
1818                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
1819                                               numberParameters_, parameters_)].currentOptionAsInteger();
1820                    int convertP[] = {2, 1, 0};
1821                    printLevel = convertP[printLevel];
1822                    if ((verbose&8) != 0) {
1823                        // even hidden
1824                        evenHidden = true;
1825                        verbose &= ~8;
1826                    }
1827#ifdef COIN_HAS_ASL
1828                    if (verbose < 4 && statusUserFunction_[0])
1829                        verbose += 4;
1830#endif
1831                    if (verbose < 4) {
1832                        std::cout << "In argument list keywords have leading - "
1833                                  ", -stdin or just - switches to stdin" << std::endl;
1834                        std::cout << "One command per line (and no -)" << std::endl;
1835                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
1836                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
1837                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
1838                        std::cout << "abcd value sets value" << std::endl;
1839                        std::cout << "Commands are:" << std::endl;
1840                    } else {
1841                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
1842                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
1843                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
1844                    }
1845                    int maxAcross = 10;
1846                    if ((verbose % 4) != 0)
1847                        maxAcross = 1;
1848                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
1849                    std::vector<std::string> types;
1850                    types.push_back("Double parameters:");
1851                    types.push_back("Branch and Cut double parameters:");
1852                    types.push_back("Integer parameters:");
1853                    types.push_back("Branch and Cut integer parameters:");
1854                    types.push_back("Keyword parameters:");
1855                    types.push_back("Branch and Cut keyword parameters:");
1856                    types.push_back("Actions or string parameters:");
1857                    types.push_back("Branch and Cut actions:");
1858                    int iType;
1859                    for (iType = 0; iType < 8; iType++) {
1860                        int across = 0;
1861                        int lengthLine = 0;
1862                        if ((verbose % 4) != 0)
1863                            std::cout << std::endl;
1864                        std::cout << types[iType] << std::endl;
1865                        if ((verbose&2) != 0)
1866                            std::cout << std::endl;
1867                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1868                            int type = parameters_[iParam].type();
1869                            //printf("%d type %d limits %d %d display %d\n",iParam,
1870                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
1871                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
1872                                    type >= limits[iType]
1873                                    && type < limits[iType+1]) {
1874                                // but skip if not useful for ampl (and in ampl mode)
1875                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
1876                                    continue;
1877                                if (!across) {
1878                                    if ((verbose&2) != 0)
1879                                        std::cout << "Command ";
1880                                }
1881                                int length = parameters_[iParam].lengthMatchName() + 1;
1882                                if (lengthLine + length > 80) {
1883                                    std::cout << std::endl;
1884                                    across = 0;
1885                                    lengthLine = 0;
1886                                }
1887                                std::cout << " " << parameters_[iParam].matchName();
1888                                lengthLine += length;
1889                                across++;
1890                                if (across == maxAcross) {
1891                                    across = 0;
1892                                    if ((verbose % 4) != 0) {
1893                                        // put out description as well
1894                                        if ((verbose&1) != 0)
1895                                            std::cout << " " << parameters_[iParam].shortHelp();
1896                                        std::cout << std::endl;
1897                                        if ((verbose&2) != 0) {
1898                                            std::cout << "---- description" << std::endl;
1899                                            parameters_[iParam].printLongHelp();
1900                                            std::cout << "----" << std::endl << std::endl;
1901                                        }
1902                                    } else {
1903                                        std::cout << std::endl;
1904                                    }
1905                                }
1906                            }
1907                        }
1908                        if (across)
1909                            std::cout << std::endl;
1910                    }
1911                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
1912                    std::cout << "Full list of commands is:" << std::endl;
1913                    int maxAcross = 5;
1914                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
1915                    std::vector<std::string> types;
1916                    types.push_back("Double parameters:");
1917                    types.push_back("Branch and Cut double parameters:");
1918                    types.push_back("Integer parameters:");
1919                    types.push_back("Branch and Cut integer parameters:");
1920                    types.push_back("Keyword parameters:");
1921                    types.push_back("Branch and Cut keyword parameters:");
1922                    types.push_back("Actions or string parameters:");
1923                    types.push_back("Branch and Cut actions:");
1924                    int iType;
1925                    for (iType = 0; iType < 8; iType++) {
1926                        int across = 0;
1927                        std::cout << types[iType] << "  ";
1928                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1929                            int type = parameters_[iParam].type();
1930                            if (type >= limits[iType]
1931                                    && type < limits[iType+1]) {
1932                                if (!across)
1933                                    std::cout << "  ";
1934                                std::cout << parameters_[iParam].matchName() << "  ";
1935                                across++;
1936                                if (across == maxAcross) {
1937                                    std::cout << std::endl;
1938                                    across = 0;
1939                                }
1940                            }
1941                        }
1942                        if (across)
1943                            std::cout << std::endl;
1944                    }
1945                } else if (type < 101) {
1946                    // get next field as double
1947                    double value = CoinReadGetDoubleField(argc, argv, &valid);
1948                    if (!valid) {
1949                        if (type < 51) {
1950                            int returnCode;
1951                            const char * message =
1952                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
1953                            if (!noPrinting_ && strlen(message)) {
1954                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1955                                << message
1956                                << CoinMessageEol;
1957                            }
1958                        } else if (type < 81) {
1959                            int returnCode;
1960                            const char * message =
1961                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
1962                            if (!noPrinting_ && strlen(message)) {
1963                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1964                                << message
1965                                << CoinMessageEol;
1966                            }
1967                        } else {
1968                            int returnCode;
1969                            const char * message =
1970                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
1971                            if (!noPrinting_ && strlen(message)) {
1972                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1973                                << message
1974                                << CoinMessageEol;
1975                            }
1976                            switch (type) {
1977                            case CBC_PARAM_DBL_DJFIX:
1978                                djFix = value;
1979#ifndef CBC_OTHER_SOLVER
1980                                if (goodModel && djFix < 1.0e20) {
1981                                    // do some fixing
1982                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
1983                                    clpSolver->initialSolve();
1984                                    lpSolver = clpSolver->getModelPtr();
1985                                    int numberColumns = lpSolver->numberColumns();
1986                                    int i;
1987                                    const char * type = lpSolver->integerInformation();
1988                                    double * lower = lpSolver->columnLower();
1989                                    double * upper = lpSolver->columnUpper();
1990                                    double * solution = lpSolver->primalColumnSolution();
1991                                    double * dj = lpSolver->dualColumnSolution();
1992                                    int numberFixed = 0;
1993                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
1994                                    if (dextra4)
1995                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
1996                                    for (i = 0; i < numberColumns; i++) {
1997                                        double djValue = dj[i];
1998                                        if (!type[i])
1999                                            djValue *= dextra4;
2000                                        if (type[i] || dextra4) {
2001                                            double value = solution[i];
2002                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
2003                                                solution[i] = lower[i];
2004                                                upper[i] = lower[i];
2005                                                numberFixed++;
2006                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
2007                                                solution[i] = upper[i];
2008                                                lower[i] = upper[i];
2009                                                numberFixed++;
2010                                            }
2011                                        }
2012                                    }
2013                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
2014                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2015                                    << generalPrint
2016                                    << CoinMessageEol;
2017                                }
2018#endif
2019                                break;
2020                            case CBC_PARAM_DBL_TIGHTENFACTOR:
2021                                tightenFactor = value;
2022                                if (!complicatedInteger)
2023                                    defaultSettings = false; // user knows what she is doing
2024                                break;
2025                            default:
2026                                break;
2027                            }
2028                        }
2029                    } else if (valid == 1) {
2030                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2031                                  parameters_[iParam].doubleValue() << std::endl;
2032                    } else {
2033                        std::cout << parameters_[iParam].name() << " has value " <<
2034                                  parameters_[iParam].doubleValue() << std::endl;
2035                    }
2036                } else if (type < 201) {
2037                    // get next field as int
2038                    int value = CoinReadGetIntField(argc, argv, &valid);
2039                    if (!valid) {
2040                        if (type < 151) {
2041                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
2042                                preSolve = value;
2043                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
2044                                doIdiot = value;
2045                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
2046                                doSprint = value;
2047                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
2048                                outputFormat = value;
2049                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
2050                                slpValue = value;
2051                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
2052                                cppValue = value;
2053                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
2054                                presolveOptions = value;
2055                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
2056                                printOptions = value;
2057                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
2058                                substitution = value;
2059                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
2060                                dualize = value;
2061                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
2062                                tunePreProcess = value;
2063                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
2064                                useSolution = value;
2065                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
2066                                verbose = value;
2067                            int returnCode;
2068                            const char * message =
2069                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2070                            if (!noPrinting_ && strlen(message)) {
2071                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2072                                << message
2073                                << CoinMessageEol;
2074                            }
2075                        } else {
2076                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
2077                                cutPass = value;
2078                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
2079                                cutPassInTree = value;
2080                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2081                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
2082                                strongChanged = true;
2083                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2084                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2085                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
2086                                pumpChanged = true;
2087                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
2088                                int addFlags=0;
2089                                if (value>=10) {
2090                                  addFlags = 1048576*(value/10);
2091                                  value = value % 10;
2092                                  parameters[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters, parameters)].setIntValue(value);
2093                                }
2094                                if (value >= 1) {
2095                                    int values[]={24003,280003,792003,24003,24003};
2096                                    if (value>=2&&value<=3) {
2097                                      // swap default diving
2098                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2099                                      parameters_[iParam].setCurrentOption("off");
2100                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2101                                      parameters_[iParam].setCurrentOption("on");
2102                                    }
2103                                    int extra4 = values[value-1]+addFlags;
2104                                    parameters[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters, parameters)].setIntValue(extra4);
2105                                    if (!noPrinting_) {
2106                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2107                                        << "switching on global root cuts for gomory and knapsack"
2108                                        << CoinMessageEol;
2109                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2110                                        << "using OSL factorization"
2111                                        << CoinMessageEol;
2112                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2113                                        << "extra options - -rens on -extra4 "
2114                                        <<extra4<<" -passc 1000!"
2115                                        << CoinMessageEol;
2116                                    }
2117                                    parameters[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters, parameters)].setCurrentOption("forceOnStrong");
2118                                    probingAction = 8;
2119                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2120                                    gomoryAction = 5;
2121                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2122                                    knapsackAction = 5;
2123                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
2124                                    lpSolver->factorization()->forceOtherFactorization(3);
2125                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
2126                                    parameters[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters, parameters)].setIntValue(1000);
2127                                    cutPass = 1000;
2128                                    parameters[whichParam(CBC_PARAM_STR_RENS, numberParameters, parameters)].setCurrentOption("on");
2129                                }
2130                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
2131                                if (value == 0) {
2132                                    gomoryGen.setAwayAtRoot(0.05);
2133                                    int iParam;
2134                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
2135                                    parameters_[iParam].setIntValue(-1);
2136                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
2137                                    parameters_[iParam].setIntValue(20);
2138                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
2139                                    parameters_[iParam].setIntValue(1003);
2140                                    initialPumpTune = 1003;
2141                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
2142                                    parameters_[iParam].setIntValue(-1);
2143                                    tunePreProcess = 0;
2144                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2145                                    parameters_[iParam].setCurrentOption("off");
2146                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
2147                                    parameters_[iParam].setCurrentOption("off");
2148                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
2149                                    parameters_[iParam].setCurrentOption("on");
2150                                    probingAction = 1;
2151                                }
2152                            }
2153                            int returnCode;
2154                            const char * message =
2155                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2156                            if (!noPrinting_ && strlen(message)) {
2157                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2158                                << message
2159                                << CoinMessageEol;
2160                            }
2161                        }
2162                    } else if (valid == 1) {
2163                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2164                                  parameters_[iParam].intValue() << std::endl;
2165                    } else {
2166                        std::cout << parameters_[iParam].name() << " has value " <<
2167                                  parameters_[iParam].intValue() << std::endl;
2168                    }
2169                } else if (type < 301) {
2170                    // one of several strings
2171                    std::string value = CoinReadGetString(argc, argv);
2172                    int action = parameters_[iParam].parameterOption(value);
2173                    if (action < 0) {
2174                        if (value != "EOL") {
2175                            // no match
2176                            parameters_[iParam].printOptions();
2177                        } else {
2178                            // print current value
2179                            std::cout << parameters_[iParam].name() << " has value " <<
2180                                      parameters_[iParam].currentOption() << std::endl;
2181                        }
2182                    } else {
2183                        const char * message =
2184                            parameters_[iParam].setCurrentOptionWithMessage(action);
2185                        if (!noPrinting_ && strlen(message)) {
2186                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2187                            << message
2188                            << CoinMessageEol;
2189                        }
2190                        // for now hard wired
2191                        switch (type) {
2192                        case CLP_PARAM_STR_DIRECTION:
2193                            if (action == 0)
2194                                lpSolver->setOptimizationDirection(1);
2195                            else if (action == 1)
2196                                lpSolver->setOptimizationDirection(-1);
2197                            else
2198                                lpSolver->setOptimizationDirection(0);
2199                            break;
2200                        case CLP_PARAM_STR_DUALPIVOT:
2201                            if (action == 0) {
2202                                ClpDualRowSteepest steep(3);
2203                                lpSolver->setDualRowPivotAlgorithm(steep);
2204                            } else if (action == 1) {
2205                                ClpDualRowDantzig dantzig;
2206                                //ClpDualRowSteepest dantzig(5);
2207                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2208                            } else if (action == 2) {
2209                                // partial steep
2210                                ClpDualRowSteepest steep(2);
2211                                lpSolver->setDualRowPivotAlgorithm(steep);
2212                            } else {
2213                                ClpDualRowSteepest steep;
2214                                lpSolver->setDualRowPivotAlgorithm(steep);
2215                            }
2216                            break;
2217                        case CLP_PARAM_STR_PRIMALPIVOT:
2218                            if (action == 0) {
2219                                ClpPrimalColumnSteepest steep(3);
2220                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2221                            } else if (action == 1) {
2222                                ClpPrimalColumnSteepest steep(0);
2223                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2224                            } else if (action == 2) {
2225                                ClpPrimalColumnDantzig dantzig;
2226                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2227                            } else if (action == 3) {
2228                                ClpPrimalColumnSteepest steep(4);
2229                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2230                            } else if (action == 4) {
2231                                ClpPrimalColumnSteepest steep(1);
2232                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2233                            } else if (action == 5) {
2234                                ClpPrimalColumnSteepest steep(2);
2235                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2236                            } else if (action == 6) {
2237                                ClpPrimalColumnSteepest steep(10);
2238                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2239                            }
2240                            break;
2241                        case CLP_PARAM_STR_SCALING:
2242                            lpSolver->scaling(action);
2243                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2244                            doScaling = action;
2245                            break;
2246                        case CLP_PARAM_STR_AUTOSCALE:
2247                            lpSolver->setAutomaticScaling(action != 0);
2248                            break;
2249                        case CLP_PARAM_STR_SPARSEFACTOR:
2250                            lpSolver->setSparseFactorization((1 - action) != 0);
2251                            break;
2252                        case CLP_PARAM_STR_BIASLU:
2253                            lpSolver->factorization()->setBiasLU(action);
2254                            break;
2255                        case CLP_PARAM_STR_PERTURBATION:
2256                            if (action == 0)
2257                                lpSolver->setPerturbation(50);
2258                            else
2259                                lpSolver->setPerturbation(100);
2260                            break;
2261                        case CLP_PARAM_STR_ERRORSALLOWED:
2262                            allowImportErrors = action;
2263                            break;
2264                        case CLP_PARAM_STR_INTPRINT:
2265                            printMode = action;
2266                            break;
2267                            //case CLP_PARAM_NOTUSED_ALGORITHM:
2268                            //algorithm  = action;
2269                            //defaultSettings=false; // user knows what she is doing
2270                            //abort();
2271                            //break;
2272                        case CLP_PARAM_STR_KEEPNAMES:
2273                            keepImportNames = 1 - action;
2274                            break;
2275                        case CLP_PARAM_STR_PRESOLVE:
2276                            if (action == 0)
2277                                preSolve = 5;
2278                            else if (action == 1)
2279                                preSolve = 0;
2280                            else if (action == 2)
2281                                preSolve = 10;
2282                            else
2283                                preSolveFile = true;
2284                            break;
2285                        case CLP_PARAM_STR_PFI:
2286                            lpSolver->factorization()->setForrestTomlin(action == 0);
2287                            break;
2288                        case CLP_PARAM_STR_FACTORIZATION:
2289                            lpSolver->factorization()->forceOtherFactorization(action);
2290                            break;
2291                        case CLP_PARAM_STR_CRASH:
2292                            doCrash = action;
2293                            break;
2294                        case CLP_PARAM_STR_VECTOR:
2295                            doVector = action;
2296                            break;
2297                        case CLP_PARAM_STR_MESSAGES:
2298                            lpSolver->messageHandler()->setPrefix(action != 0);
2299                            break;
2300                        case CLP_PARAM_STR_CHOLESKY:
2301                            choleskyType = action;
2302                            break;
2303                        case CLP_PARAM_STR_GAMMA:
2304                            gamma = action;
2305                            break;
2306                        case CLP_PARAM_STR_BARRIERSCALE:
2307                            scaleBarrier = action;
2308                            break;
2309                        case CLP_PARAM_STR_KKT:
2310                            doKKT = action;
2311                            break;
2312                        case CLP_PARAM_STR_CROSSOVER:
2313                            crossover = action;
2314                            break;
2315                        case CLP_PARAM_STR_TIME_MODE:
2316                            model_.setUseElapsedTime(action!=0);
2317                            break;
2318                        case CBC_PARAM_STR_SOS:
2319                            doSOS = action;
2320                            break;
2321                        case CBC_PARAM_STR_GOMORYCUTS:
2322                            defaultSettings = false; // user knows what she is doing
2323                            gomoryAction = action;
2324                            break;
2325                        case CBC_PARAM_STR_PROBINGCUTS:
2326                            defaultSettings = false; // user knows what she is doing
2327                            probingAction = action;
2328                            break;
2329                        case CBC_PARAM_STR_KNAPSACKCUTS:
2330                            defaultSettings = false; // user knows what she is doing
2331                            knapsackAction = action;
2332                            break;
2333                        case CBC_PARAM_STR_REDSPLITCUTS:
2334                            defaultSettings = false; // user knows what she is doing
2335                            redsplitAction = action;
2336                            break;
2337                        case CBC_PARAM_STR_CLIQUECUTS:
2338                            defaultSettings = false; // user knows what she is doing
2339                            cliqueAction = action;
2340                            break;
2341                        case CBC_PARAM_STR_FLOWCUTS:
2342                            defaultSettings = false; // user knows what she is doing
2343                            flowAction = action;
2344                            break;
2345                        case CBC_PARAM_STR_MIXEDCUTS:
2346                            defaultSettings = false; // user knows what she is doing
2347                            mixedAction = action;
2348                            break;
2349                        case CBC_PARAM_STR_TWOMIRCUTS:
2350                            defaultSettings = false; // user knows what she is doing
2351                            twomirAction = action;
2352                            break;
2353                        case CBC_PARAM_STR_LANDPCUTS:
2354                            defaultSettings = false; // user knows what she is doing
2355                            landpAction = action;
2356                            break;
2357                        case CBC_PARAM_STR_RESIDCUTS:
2358                            defaultSettings = false; // user knows what she is doing
2359                            residualCapacityAction = action;
2360                            break;
2361#ifdef ZERO_HALF_CUTS
2362                        case CBC_PARAM_STR_ZEROHALFCUTS:
2363                            defaultSettings = false; // user knows what she is doing
2364                            zerohalfAction = action;
2365                            break;
2366#endif
2367                        case CBC_PARAM_STR_ROUNDING:
2368                            defaultSettings = false; // user knows what she is doing
2369                            break;
2370                        case CBC_PARAM_STR_FPUMP:
2371                            defaultSettings = false; // user knows what she is doing
2372                            break;
2373                        case CBC_PARAM_STR_RINS:
2374                            break;
2375                        case CBC_PARAM_STR_DINS:
2376                            break;
2377                        case CBC_PARAM_STR_RENS:
2378                            break;
2379                        case CBC_PARAM_STR_CUTSSTRATEGY:
2380                            gomoryAction = action;
2381                            probingAction = action;
2382                            knapsackAction = action;
2383#ifdef ZERO_HALF_CUTS
2384                            zerohalfAction = action;
2385#endif
2386                            cliqueAction = action;
2387                            flowAction = action;
2388                            mixedAction = action;
2389                            twomirAction = action;
2390                            //landpAction = action;
2391                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2392                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2393                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2394                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2395                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2396                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2397                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2398#ifdef ZERO_HALF_CUTS
2399                            parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2400#endif
2401                            if (!action) {
2402                                redsplitAction = action;
2403                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2404                                landpAction = action;
2405                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2406                                residualCapacityAction = action;
2407                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2408                            }
2409                            break;
2410                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2411                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2412                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2413                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2414                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2415                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2416                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2417                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
2418                            break;
2419                        case CBC_PARAM_STR_GREEDY:
2420                        case CBC_PARAM_STR_DIVINGS:
2421                        case CBC_PARAM_STR_DIVINGC:
2422                        case CBC_PARAM_STR_DIVINGF:
2423                        case CBC_PARAM_STR_DIVINGG:
2424                        case CBC_PARAM_STR_DIVINGL:
2425                        case CBC_PARAM_STR_DIVINGP:
2426                        case CBC_PARAM_STR_DIVINGV:
2427                        case CBC_PARAM_STR_COMBINE:
2428                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2429                        case CBC_PARAM_STR_PIVOTANDFIX:
2430                        case CBC_PARAM_STR_RANDROUND:
2431                        case CBC_PARAM_STR_LOCALTREE:
2432                        case CBC_PARAM_STR_NAIVE:
2433                        case CBC_PARAM_STR_CPX:
2434                            defaultSettings = false; // user knows what she is doing
2435                            break;
2436                        case CBC_PARAM_STR_COSTSTRATEGY:
2437                            useCosts = action;
2438                            break;
2439                        case CBC_PARAM_STR_NODESTRATEGY:
2440                            nodeStrategy = action;
2441                            break;
2442                        case CBC_PARAM_STR_PREPROCESS:
2443                            preProcess = action;
2444                            break;
2445                        default:
2446                            //abort();
2447                            break;
2448                        }
2449                    }
2450                } else {
2451                    // action
2452                    if (type == CLP_PARAM_ACTION_EXIT) {
2453#ifdef COIN_HAS_ASL
2454                        if (statusUserFunction_[0]) {
2455                            if (info.numberIntegers || info.numberBinary) {
2456                                // integer
2457                            } else {
2458                                // linear
2459                            }
2460                            writeAmpl(&info);
2461                            freeArrays2(&info);
2462                            freeArgs(&info);
2463                        }
2464#endif
2465                        break; // stop all
2466                    }
2467                    switch (type) {
2468                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2469                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2470                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2471                    case CLP_PARAM_ACTION_BARRIER:
2472                        if (goodModel) {
2473                            // Say not in integer
2474                            integerStatus = -1;
2475                            double objScale =
2476                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
2477                            if (objScale != 1.0) {
2478                                int iColumn;
2479                                int numberColumns = lpSolver->numberColumns();
2480                                double * dualColumnSolution =
2481                                    lpSolver->dualColumnSolution();
2482                                ClpObjective * obj = lpSolver->objectiveAsObject();
2483                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2484                                double offset;
2485                                double * objective = obj->gradient(NULL, NULL, offset, true);
2486                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2487                                    dualColumnSolution[iColumn] *= objScale;
2488                                    objective[iColumn] *= objScale;;
2489                                }
2490                                int iRow;
2491                                int numberRows = lpSolver->numberRows();
2492                                double * dualRowSolution =
2493                                    lpSolver->dualRowSolution();
2494                                for (iRow = 0; iRow < numberRows; iRow++)
2495                                    dualRowSolution[iRow] *= objScale;
2496                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2497                            }
2498                            ClpSolve::SolveType method;
2499                            ClpSolve::PresolveType presolveType;
2500                            ClpSimplex * model2 = lpSolver;
2501                            if (dualize) {
2502                                bool tryIt = true;
2503                                double fractionColumn = 1.0;
2504                                double fractionRow = 1.0;
2505                                if (dualize == 3) {
2506                                    dualize = 1;
2507                                    int numberColumns = lpSolver->numberColumns();
2508                                    int numberRows = lpSolver->numberRows();
2509                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2510                                        tryIt = false;
2511                                    } else {
2512                                        fractionColumn = 0.1;
2513                                        fractionRow = 0.1;
2514                                    }
2515                                }
2516                                if (tryIt) {
2517                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2518                                    if (model2) {
2519                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2520                                                model2->numberRows(), model2->numberColumns());
2521                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2522                                        << generalPrint
2523                                        << CoinMessageEol;
2524                                        model2->setOptimizationDirection(1.0);
2525                                    } else {
2526                                        model2 = lpSolver;
2527                                        dualize = 0;
2528                                    }
2529                                } else {
2530                                    dualize = 0;
2531                                }
2532                            }
2533                            if (noPrinting_)
2534                                lpSolver->setLogLevel(0);
2535                            ClpSolve solveOptions;
2536                            solveOptions.setPresolveActions(presolveOptions);
2537                            solveOptions.setSubstitution(substitution);
2538                            if (preSolve != 5 && preSolve) {
2539                                presolveType = ClpSolve::presolveNumber;
2540                                if (preSolve < 0) {
2541                                    preSolve = - preSolve;
2542                                    if (preSolve <= 100) {
2543                                        presolveType = ClpSolve::presolveNumber;
2544                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2545                                                preSolve);
2546                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2547                                        << generalPrint
2548                                        << CoinMessageEol;
2549                                        solveOptions.setDoSingletonColumn(true);
2550                                    } else {
2551                                        preSolve -= 100;
2552                                        presolveType = ClpSolve::presolveNumberCost;
2553                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2554                                                preSolve);
2555                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2556                                        << generalPrint
2557                                        << CoinMessageEol;
2558                                    }
2559                                }
2560                            } else if (preSolve) {
2561                                presolveType = ClpSolve::presolveOn;
2562                            } else {
2563                                presolveType = ClpSolve::presolveOff;
2564                            }
2565                            solveOptions.setPresolveType(presolveType, preSolve);
2566                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2567                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
2568                                method = ClpSolve::useDual;
2569                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
2570                                method = ClpSolve::usePrimalorSprint;
2571                            } else {
2572                                method = ClpSolve::useBarrier;
2573                                if (crossover == 1) {
2574                                    method = ClpSolve::useBarrierNoCross;
2575                                } else if (crossover == 2) {
2576                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2577                                    if (obj->type() > 1) {
2578                                        method = ClpSolve::useBarrierNoCross;
2579                                        presolveType = ClpSolve::presolveOff;
2580                                        solveOptions.setPresolveType(presolveType, preSolve);
2581                                    }
2582                                }
2583                            }
2584                            solveOptions.setSolveType(method);
2585                            if (preSolveFile)
2586                                presolveOptions |= 0x40000000;
2587                            solveOptions.setSpecialOption(4, presolveOptions);
2588                            solveOptions.setSpecialOption(5, printOptions);
2589                            if (doVector) {
2590                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2591                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2592                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2593                                    clpMatrix->makeSpecialColumnCopy();
2594                                }
2595                            }
2596                            if (method == ClpSolve::useDual) {
2597                                // dual
2598                                if (doCrash)
2599                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2600                                else if (doIdiot)
2601                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2602                            } else if (method == ClpSolve::usePrimalorSprint) {
2603                                // primal
2604                                // if slp turn everything off
2605                                if (slpValue > 0) {
2606                                    doCrash = false;
2607                                    doSprint = 0;
2608                                    doIdiot = -1;
2609                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2610                                    method = ClpSolve::usePrimal;
2611                                }
2612                                if (doCrash) {
2613                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2614                                } else if (doSprint > 0) {
2615                                    // sprint overrides idiot
2616                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2617                                } else if (doIdiot > 0) {
2618                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2619                                } else if (slpValue <= 0) {
2620                                    if (doIdiot == 0) {
2621                                        if (doSprint == 0)
2622                                            solveOptions.setSpecialOption(1, 4); // all slack
2623                                        else
2624                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2625                                    } else {
2626                                        if (doSprint == 0)
2627                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2628                                        else
2629                                            solveOptions.setSpecialOption(1, 7); // initiative
2630                                    }
2631                                }
2632                                if (basisHasValues == -1)
2633                                    solveOptions.setSpecialOption(1, 11); // switch off values
2634                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2635                                int barrierOptions = choleskyType;
2636                                if (scaleBarrier)
2637                                    barrierOptions |= 8;
2638                                if (doKKT)
2639                                    barrierOptions |= 16;
2640                                if (gamma)
2641                                    barrierOptions |= 32 * gamma;
2642                                if (crossover == 3)
2643                                    barrierOptions |= 256; // try presolve in crossover
2644                                solveOptions.setSpecialOption(4, barrierOptions);
2645                            }
2646                            model2->setMaximumSeconds(model_.getMaximumSeconds());
2647#ifdef COIN_HAS_LINK
2648                            OsiSolverInterface * coinSolver = model_.solver();
2649                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2650                            if (!linkSolver) {
2651                                model2->initialSolve(solveOptions);
2652                            } else {
2653                                // special solver
2654                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
2655                                double * solution = NULL;
2656                                if (testOsiOptions < 10) {
2657                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2658                                } else if (testOsiOptions >= 10) {
2659                                    CoinModel coinModel = *linkSolver->coinModel();
2660                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2661                                    assert (tempModel);
2662                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2663                                    model2->setObjectiveValue(tempModel->objectiveValue());
2664                                    model2->setProblemStatus(tempModel->problemStatus());
2665                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2666                                    delete tempModel;
2667                                }
2668                                if (solution) {
2669                                    memcpy(model2->primalColumnSolution(), solution,
2670                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2671                                    delete [] solution;
2672                                } else {
2673                                    printf("No nonlinear solution\n");
2674                                }
2675                            }
2676#else
2677                            model2->initialSolve(solveOptions);
2678#endif
2679                            {
2680                                // map states
2681                                /* clp status
2682                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2683                                   0 - optimal
2684                                   1 - primal infeasible
2685                                   2 - dual infeasible
2686                                   3 - stopped on iterations or time
2687                                   4 - stopped due to errors
2688                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2689                                /* cbc status
2690                                   -1 before branchAndBound
2691                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2692                                   (or check value of best solution)
2693                                   1 stopped - on maxnodes, maxsols, maxtime
2694                                   2 difficulties so run was abandoned
2695                                   (5 event user programmed event occurred) */
2696                                /* clp secondary status of problem - may get extended
2697                                   0 - none
2698                                   1 - primal infeasible because dual limit reached OR probably primal
2699                                   infeasible but can't prove it (main status 4)
2700                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2701                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
2702                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
2703                                   5 - giving up in primal with flagged variables
2704                                   6 - failed due to empty problem check
2705                                   7 - postSolve says not optimal
2706                                   8 - failed due to bad element check
2707                                   9 - status was 3 and stopped on time
2708                                   100 up - translation of enum from ClpEventHandler
2709                                */
2710                                /* cbc secondary status of problem
2711                                   -1 unset (status_ will also be -1)
2712                                   0 search completed with solution
2713                                   1 linear relaxation not feasible (or worse than cutoff)
2714                                   2 stopped on gap
2715                                   3 stopped on nodes
2716                                   4 stopped on time
2717                                   5 stopped on user event
2718                                   6 stopped on solutions
2719                                   7 linear relaxation unbounded
2720                                   8 stopped on iterations limit
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)  // what does 9 mean ?????????????
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", "iterations limit", "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);