source: stable/2.9/Cbc/src/CbcSolver.cpp @ 2180

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

mipstart when sos added

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