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

Last change on this file since 2093 was 2093, checked in by forrest, 5 years ago

changes for diving heuristic

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