source: stable/2.8/Cbc/src/CbcSolver.cpp @ 2012

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

mipstart mods

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