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

Last change on this file since 2107 was 2107, checked in by forrest, 4 years ago

somehow blas can go paralllel - I think this fixes

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