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

Last change on this file since 1852 was 1852, checked in by forrest, 6 years ago

minor change to improve MIR

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