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

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

fix blank typo (and keep some extra debug in CbcHeuristic?)

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