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

Last change on this file since 2377 was 2377, checked in by unxusr, 2 years ago

leak in CbcMain1

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