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

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

multiple root solvers, stronger strong branching and cutoff as constraint

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