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

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

remove ifdef ZERO_HALF_CUTS; some tabs to spaces

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