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

Last change on this file since 2237 was 2237, checked in by unxusr, 4 years ago

store originalColumns info in CbcModel? after preprocess

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