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

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

add option to RENS

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 547.7 KB
Line 
1/* $Id: CbcSolver.cpp 2102 2014-12-15 15:45:52Z 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("off");
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#ifdef GENERAL_HANDLER_PRINTING
1292static void printGeneralMessage(CbcModel &model,const char * message);
1293#endif
1294/*
1295  Meaning of whereFrom:
1296    1 after initial solve by dualsimplex etc
1297    2 after preprocessing
1298    3 just before branchAndBound (so user can override)
1299    4 just after branchAndBound (before postprocessing)
1300    5 after postprocessing
1301    6 after a user called heuristic phase
1302*/
1303int CbcMain1 (int argc, const char *argv[],
1304              CbcModel  & model,
1305              int callBack(CbcModel * currentSolver, int whereFrom),
1306              CbcSolverUsefulData & parameterData)
1307{
1308    CbcOrClpParam * parameters_ = parameterData.parameters_;
1309    int numberParameters_ = parameterData.numberParameters_;
1310    double totalTime = parameterData.totalTime_;
1311    bool noPrinting = parameterData.noPrinting_;
1312    bool useSignalHandler = parameterData.useSignalHandler_;
1313#ifdef GENERAL_HANDLER_PRINTING
1314    //char printByHandler[1000];
1315#endif
1316    CbcModel & model_ = model;
1317#ifdef CBC_THREAD_SAFE
1318    // Initialize argument
1319    int whichArgument=1;
1320#endif
1321#ifdef CBC_USE_INITIAL_TIME
1322    if (model_.useElapsedTime())
1323      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1324    else
1325      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1326#endif
1327    CbcModel * babModel_ = NULL;
1328    int returnMode = 1;
1329    CbcOrClpRead_mode = 1;
1330    int statusUserFunction_[1];
1331    int numberUserFunctions_ = 1; // to allow for ampl
1332    // Statistics
1333    double statistics_seconds = 0.0, statistics_obj = 0.0;
1334    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1335    CoinWallclockTime();
1336    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1337    double statistics_cut_time = 0.0;
1338    int statistics_nodes = 0, statistics_iterations = 0;
1339    int statistics_nrows = 0, statistics_ncols = 0;
1340    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1341    std::string statistics_result;
1342    int * statistics_number_cuts = NULL;
1343    const char ** statistics_name_generators = NULL;
1344    int statistics_number_generators = 0;
1345    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1346    /* Note
1347       This is meant as a stand-alone executable to do as much of coin as possible.
1348       It should only have one solver known to it.
1349    */
1350    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1351    generalMessageHandler->setPrefix(false);
1352#ifndef CBC_OTHER_SOLVER
1353    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1354    assert (originalSolver);
1355    // Move handler across if not default
1356    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1357        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1358    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1359    char generalPrint[10000];
1360    if (originalSolver->getModelPtr()->logLevel() == 0)
1361        noPrinting = true;
1362#elif CBC_OTHER_SOLVER==1
1363    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1364    assert (originalSolver);
1365    OsiClpSolverInterface dummySolver;
1366    OsiCpxSolverInterface * clpSolver = originalSolver;
1367    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1368    char generalPrint[10000];
1369    noPrinting = true;
1370#endif
1371    bool noPrinting_ = noPrinting;
1372    // Say not in integer
1373    int integerStatus = -1;
1374    // Say no resolve after cuts
1375    model_.setResolveAfterTakeOffCuts(false);
1376    // see if log in list
1377    for (int i = 1; i < argc; i++) {
1378        if (!strncmp(argv[i], "log", 3)) {
1379            const char * equals = strchr(argv[i], '=');
1380            if (equals && atoi(equals + 1) != 0)
1381                noPrinting_ = false;
1382            else
1383                noPrinting_ = true;
1384            break;
1385        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1386            if (atoi(argv[i+1]) != 0)
1387                noPrinting_ = false;
1388            else
1389                noPrinting_ = true;
1390            break;
1391        }
1392    }
1393    double time0;
1394    double time0Elapsed = CoinGetTimeOfDay();
1395    {
1396        double time1 = CoinCpuTime(), time2;
1397        time0 = time1;
1398        double time1Elapsed = time0Elapsed;
1399        bool goodModel = (originalSolver->getNumCols()) ? true : false;
1400
1401        // register signal handler
1402        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
1403#if CBC_QUIET < 2
1404        if (useSignalHandler)
1405          signal(SIGINT, signal_handler);
1406#endif
1407        // Set up all non-standard stuff
1408        int cutPass = -1234567;
1409        int cutPassInTree = -1234567;
1410        int tunePreProcess = 0;
1411        int testOsiParameters = -1;
1412        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1413        int complicatedInteger = 0;
1414        OsiSolverInterface * solver = model_.solver();
1415        if (noPrinting_)
1416            setCbcOrClpPrinting(false);
1417#ifndef CBC_OTHER_SOLVER
1418        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1419        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1420        if (noPrinting_) {
1421            lpSolver->setLogLevel(0);
1422        }
1423#else
1424        ClpSimplex * lpSolver = NULL;
1425#endif
1426        // For priorities etc
1427        int * priorities = NULL;
1428        int * branchDirection = NULL;
1429        double * pseudoDown = NULL;
1430        double * pseudoUp = NULL;
1431        double * solutionIn = NULL;
1432        int * prioritiesIn = NULL;
1433        std::vector< std::pair< std::string, double > > mipStart;
1434        std::vector< std::pair< std::string, double > > mipStartBefore;
1435        int numberSOS = 0;
1436        int * sosStart = NULL;
1437        int * sosIndices = NULL;
1438        char * sosType = NULL;
1439        double * sosReference = NULL;
1440        int * cut = NULL;
1441        int * sosPriority = NULL;
1442        CglStored storedAmpl;
1443        CoinModel * coinModel = NULL;
1444        CoinModel saveCoinModel;
1445        CoinModel saveTightenedModel;
1446        int * whichColumn = NULL;
1447        int * knapsackStart = NULL;
1448        int * knapsackRow = NULL;
1449        int numberKnapsack = 0;
1450#ifdef COIN_HAS_ASL
1451        ampl_info info;
1452        {
1453            memset(&info, 0, sizeof(info));
1454            if (argc > 2 && !strcmp(argv[2], "-AMPL")) {
1455                statusUserFunction_[0] = 1;
1456                // see if log in list
1457                noPrinting_ = true;
1458                for (int i = 1; i < argc; i++) {
1459                    if (!strncmp(argv[i], "log", 3)) {
1460                        const char * equals = strchr(argv[i], '=');
1461                        if (equals && atoi(equals + 1) > 0) {
1462                            noPrinting_ = false;
1463                            info.logLevel = atoi(equals + 1);
1464                            int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1465                            parameters_[log].setIntValue(info.logLevel);
1466                            // mark so won't be overWritten
1467                            info.numberRows = -1234567;
1468                            break;
1469                        }
1470                    }
1471                }
1472
1473                union {
1474                    void * voidModel;
1475                    CoinModel * model;
1476                } coinModelStart;
1477                coinModelStart.model = NULL;
1478                int returnCode = readAmpl(&info, argc, const_cast<char **>(argv), & coinModelStart.voidModel);
1479                coinModel = coinModelStart.model;
1480                if (returnCode)
1481                    return returnCode;
1482                CbcOrClpRead_mode = 2; // so will start with parameters
1483                // see if log in list (including environment)
1484                for (int i = 1; i < info.numberArguments; i++) {
1485                    if (!strcmp(info.arguments[i], "log")) {
1486                        if (i < info.numberArguments - 1 && atoi(info.arguments[i+1]) > 0)
1487                            noPrinting_ = false;
1488                        break;
1489                    }
1490                }
1491                if (noPrinting_) {
1492                    model_.messageHandler()->setLogLevel(0);
1493                    setCbcOrClpPrinting(false);
1494                }
1495                if (!noPrinting_)
1496                    printf("%d rows, %d columns and %d elements\n",
1497                           info.numberRows, info.numberColumns, info.numberElements);
1498#ifdef COIN_HAS_LINK
1499                if (!coinModel) {
1500#endif
1501                    solver->loadProblem(info.numberColumns, info.numberRows, info.starts,
1502                                        info.rows, info.elements,
1503                                        info.columnLower, info.columnUpper, info.objective,
1504                                        info.rowLower, info.rowUpper);
1505                    // take off cuts if ampl wants that
1506                    if (info.cut && 0) {
1507                        printf("AMPL CUTS OFF until global cuts fixed\n");
1508                        info.cut = NULL;
1509                    }
1510                    if (info.cut) {
1511                        int numberRows = info.numberRows;
1512                        int * whichRow = new int [numberRows];
1513                        // Row copy
1514                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1515                        const double * elementByRow = matrixByRow->getElements();
1516                        const int * column = matrixByRow->getIndices();
1517                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1518                        const int * rowLength = matrixByRow->getVectorLengths();
1519
1520                        const double * rowLower = solver->getRowLower();
1521                        const double * rowUpper = solver->getRowUpper();
1522                        int nDelete = 0;
1523                        for (int iRow = 0; iRow < numberRows; iRow++) {
1524                            if (info.cut[iRow]) {
1525                                whichRow[nDelete++] = iRow;
1526                                int start = rowStart[iRow];
1527                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1528                                                  rowLength[iRow], column + start, elementByRow + start);
1529                            }
1530                        }
1531                        solver->deleteRows(nDelete, whichRow);
1532                        delete [] whichRow;
1533                    }
1534#ifdef COIN_HAS_LINK
1535                } else {
1536#ifndef CBC_OTHER_SOLVER
1537                    // save
1538                    saveCoinModel = *coinModel;
1539                    // load from coin model
1540                    OsiSolverLink solver1;
1541                    OsiSolverInterface * solver2 = solver1.clone();
1542                    model_.assignSolver(solver2, false);
1543                    OsiSolverLink * si =
1544                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1545                    assert (si != NULL);
1546                    si->setDefaultMeshSize(0.001);
1547                    // need some relative granularity
1548                    si->setDefaultBound(100.0);
1549                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
1550                    if (dextra3)
1551                        si->setDefaultMeshSize(dextra3);
1552                    si->setDefaultBound(100000.0);
1553                    si->setIntegerPriority(1000);
1554                    si->setBiLinearPriority(10000);
1555                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
1556                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1557                    si->load(*model2, true, logLevel);
1558                    // redo
1559                    solver = model_.solver();
1560                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1561                    lpSolver = clpSolver->getModelPtr();
1562                    clpSolver->messageHandler()->setLogLevel(0) ;
1563                    testOsiParameters = 0;
1564                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
1565                    complicatedInteger = 1;
1566                    if (info.cut) {
1567                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1568                        abort();
1569                        int numberRows = info.numberRows;
1570                        int * whichRow = new int [numberRows];
1571                        // Row copy
1572                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1573                        const double * elementByRow = matrixByRow->getElements();
1574                        const int * column = matrixByRow->getIndices();
1575                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1576                        const int * rowLength = matrixByRow->getVectorLengths();
1577
1578                        const double * rowLower = solver->getRowLower();
1579                        const double * rowUpper = solver->getRowUpper();
1580                        int nDelete = 0;
1581                        for (int iRow = 0; iRow < numberRows; iRow++) {
1582                            if (info.cut[iRow]) {
1583                                whichRow[nDelete++] = iRow;
1584                                int start = rowStart[iRow];
1585                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1586                                                  rowLength[iRow], column + start, elementByRow + start);
1587                            }
1588                        }
1589                        solver->deleteRows(nDelete, whichRow);
1590                        // and special matrix
1591                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1592                        delete [] whichRow;
1593                    }
1594#endif
1595                }
1596#endif
1597                // If we had a solution use it
1598                if (info.primalSolution) {
1599                    solver->setColSolution(info.primalSolution);
1600                }
1601                // status
1602                if (info.rowStatus) {
1603                    unsigned char * statusArray = lpSolver->statusArray();
1604                    int i;
1605                    for (i = 0; i < info.numberColumns; i++)
1606                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1607                    statusArray += info.numberColumns;
1608                    for (i = 0; i < info.numberRows; i++)
1609                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1610                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1611                    solver->setWarmStart(basis);
1612                    delete basis;
1613                }
1614                freeArrays1(&info);
1615                // modify objective if necessary
1616                solver->setObjSense(info.direction);
1617                solver->setDblParam(OsiObjOffset, -info.offset);
1618                if (info.offset) {
1619                    sprintf(generalPrint, "Ampl objective offset is %g",
1620                            info.offset);
1621                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1622                    << generalPrint
1623                    << CoinMessageEol;
1624                }
1625                // Set integer variables (unless nonlinear when set)
1626                if (!info.nonLinear) {
1627                    for (int i = info.numberColumns - info.numberIntegers;
1628                            i < info.numberColumns; i++)
1629                        solver->setInteger(i);
1630                }
1631                goodModel = true;
1632                // change argc etc
1633                argc = info.numberArguments;
1634                argv = const_cast<const char **>(info.arguments);
1635            }
1636        }
1637#endif
1638        // default action on import
1639        int allowImportErrors = 0;
1640        int keepImportNames = 1;
1641        int doIdiot = -1;
1642        int outputFormat = 2;
1643        int slpValue = -1;
1644        int cppValue = -1;
1645        int printOptions = 0;
1646        int printMode = 0;
1647        int presolveOptions = 0;
1648        int substitution = 3;
1649        int dualize = 3;
1650        int doCrash = 0;
1651        int doVector = 0;
1652        int doSprint = -1;
1653        int doScaling = 4;
1654        // set reasonable defaults
1655        int preSolve = 5;
1656        int preProcess = 4;
1657        bool useStrategy = false;
1658        bool preSolveFile = false;
1659        bool strongChanged = false;
1660        bool pumpChanged = false;
1661
1662        double djFix = 1.0e100;
1663        double tightenFactor = 0.0;
1664        const char dirsep =  CoinFindDirSeparator();
1665        std::string directory;
1666        std::string dirSample;
1667        std::string dirNetlib;
1668        std::string dirMiplib;
1669        if (dirsep == '/') {
1670            directory = "./";
1671            dirSample = "../../Data/Sample/";
1672            dirNetlib = "../../Data/Netlib/";
1673            dirMiplib = "../../Data/miplib3/";
1674        } else {
1675            directory = ".\\";
1676            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1677            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1678            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
1679        }
1680        std::string defaultDirectory = directory;
1681        std::string importFile = "";
1682        std::string exportFile = "default.mps";
1683        std::string importBasisFile = "";
1684        std::string importPriorityFile = "";
1685        std::string debugFile = "";
1686        std::string printMask = "";
1687        double * debugValues = NULL;
1688        int numberDebugValues = -1;
1689        int basisHasValues = 0;
1690        std::string exportBasisFile = "default.bas";
1691        std::string saveFile = "default.prob";
1692        std::string restoreFile = "default.prob";
1693        std::string solutionFile = "stdout";
1694        std::string solutionSaveFile = "solution.file";
1695        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1696        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1697#ifndef CBC_OTHER_SOLVER
1698        double normalIncrement = model_.getCutoffIncrement();;
1699#endif
1700        if (testOsiParameters >= 0) {
1701            // trying nonlinear - switch off some stuff
1702            preProcess = 0;
1703        }
1704        // Set up likely cut generators and defaults
1705        int nodeStrategy = 0;
1706        bool dominatedCuts = false;
1707        int doSOS = 1;
1708        int verbose = 0;
1709        CglGomory gomoryGen;
1710        // try larger limit
1711        gomoryGen.setLimitAtRoot(1000);
1712        gomoryGen.setLimit(50);
1713        // set default action (0=off,1=on,2=root)
1714        int gomoryAction = 3;
1715
1716        CglProbing probingGen;
1717        probingGen.setUsingObjective(1);
1718        probingGen.setMaxPass(1);
1719        probingGen.setMaxPassRoot(1);
1720        // Number of unsatisfied variables to look at
1721        probingGen.setMaxProbe(10);
1722        probingGen.setMaxProbeRoot(50);
1723        // How far to follow the consequences
1724        probingGen.setMaxLook(10);
1725        probingGen.setMaxLookRoot(50);
1726        probingGen.setMaxLookRoot(10);
1727        // Only look at rows with fewer than this number of elements
1728        probingGen.setMaxElements(200);
1729        probingGen.setMaxElementsRoot(300);
1730        probingGen.setRowCuts(3);
1731        // set default action (0=off,1=on,2=root)
1732        int probingAction = 1;
1733
1734        CglKnapsackCover knapsackGen;
1735        //knapsackGen.switchOnExpensive();
1736        //knapsackGen.setMaxInKnapsack(100);
1737        // set default action (0=off,1=on,2=root)
1738        int knapsackAction = 3;
1739
1740        CglRedSplit redsplitGen;
1741        //redsplitGen.setLimit(100);
1742        // set default action (0=off,1=on,2=root)
1743        // Off as seems to give some bad cuts
1744        int redsplitAction = 0;
1745
1746        CglRedSplit2 redsplit2Gen;
1747        //redsplit2Gen.setLimit(100);
1748        // set default action (0=off,1=on,2=root)
1749        // Off
1750        int redsplit2Action = 0;
1751
1752        CglGMI GMIGen;
1753        //GMIGen.setLimit(100);
1754        // set default action (0=off,1=on,2=root)
1755        // Off
1756        int GMIAction = 0;
1757
1758        CglFakeClique cliqueGen(NULL, false);
1759        //CglClique cliqueGen(false,true);
1760        cliqueGen.setStarCliqueReport(false);
1761        cliqueGen.setRowCliqueReport(false);
1762        cliqueGen.setMinViolation(0.1);
1763        // set default action (0=off,1=on,2=root)
1764        int cliqueAction = 3;
1765
1766        // maxaggr,multiply,criterion(1-3)
1767        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1768        // set default action (0=off,1=on,2=root)
1769        int mixedAction = 3;
1770        mixedGen.setDoPreproc(1); // safer (and better)
1771
1772        CglFlowCover flowGen;
1773        // set default action (0=off,1=on,2=root)
1774        int flowAction = 3;
1775
1776        CglTwomir twomirGen;
1777        twomirGen.setMaxElements(250);
1778        // set default action (0=off,1=on,2=root)
1779        int twomirAction = 3;
1780#ifndef DEBUG_MALLOC
1781        CglLandP landpGen;
1782        landpGen.validator().setMinViolation(1.0e-4);
1783#endif
1784        // set default action (0=off,1=on,2=root)
1785        int landpAction = 0;
1786        CglResidualCapacity residualCapacityGen;
1787        residualCapacityGen.setDoPreproc(1); // always preprocess
1788        // set default action (0=off,1=on,2=root)
1789        int residualCapacityAction = 0;
1790
1791        CglZeroHalf zerohalfGen;
1792        //zerohalfGen.switchOnExpensive();
1793        // set default action (0=off,1=on,2=root)
1794        int zerohalfAction = 0;
1795
1796        // Stored cuts
1797        //bool storedCuts = false;
1798
1799        int useCosts = 0;
1800        // don't use input solution
1801        int useSolution = -1;
1802
1803        // total number of commands read
1804        int numberGoodCommands = 0;
1805        // Set false if user does anything advanced
1806        bool defaultSettings = true;
1807
1808        // Hidden stuff for barrier
1809        int choleskyType = 0;
1810        int gamma = 0;
1811        int scaleBarrier = 0;
1812        int doKKT = 0;
1813        int crossover = 2; // do crossover unless quadratic
1814        bool biLinearProblem=false;
1815        // For names
1816        int lengthName = 0;
1817        std::vector<std::string> rowNames;
1818        std::vector<std::string> columnNames;
1819        // Default strategy stuff
1820        {
1821            // try changing tolerance at root
1822#define MORE_CUTS
1823#ifdef MORE_CUTS
1824            gomoryGen.setAwayAtRoot(0.005);
1825            twomirGen.setAwayAtRoot(0.005);
1826            twomirGen.setAway(0.01);
1827            //twomirGen.setMirScale(1,1);
1828            //twomirGen.setTwomirScale(1,1);
1829            //twomirGen.setAMax(2);
1830#else
1831            gomoryGen.setAwayAtRoot(0.01);
1832            twomirGen.setAwayAtRoot(0.01);
1833            twomirGen.setAway(0.01);
1834#endif
1835            int iParam;
1836            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
1837            parameters_[iParam].setIntValue(3);
1838            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
1839            parameters_[iParam].setIntValue(30);
1840            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
1841            parameters_[iParam].setIntValue(1005043);
1842            initialPumpTune = 1005043;
1843            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
1844            parameters_[iParam].setIntValue(6);
1845            tunePreProcess = 6;
1846            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
1847            parameters_[iParam].setCurrentOption("on");
1848            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
1849            parameters_[iParam].setCurrentOption("on");
1850            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
1851            parameters_[iParam].setCurrentOption("on");
1852            probingAction = 3;
1853            //parameters_[iParam].setCurrentOption("forceOnStrong");
1854            //probingAction = 8;
1855        }
1856        std::string field;
1857#if CBC_QUIET == 0
1858        if (!noPrinting_) {
1859           sprintf(generalPrint,
1860                   "Welcome to the CBC MILP Solver \n");
1861            if (strcmp(CBC_VERSION, "trunk")){
1862               sprintf(generalPrint + strlen(generalPrint),
1863                       "Version: %s \n", CBC_VERSION);
1864            }else{
1865               sprintf(generalPrint + strlen(generalPrint),
1866                       "Version: Trunk (unstable) \n");
1867            }
1868            sprintf(generalPrint + strlen(generalPrint),
1869                    "Build Date: %s \n", __DATE__);
1870#ifdef CBC_SVN_REV
1871            sprintf(generalPrint + strlen(generalPrint),
1872                    "Revision Number: %d \n", CBC_SVN_REV);
1873#endif
1874            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1875            << generalPrint
1876            << CoinMessageEol;
1877            // Print command line
1878            if (argc > 1) {
1879                bool foundStrategy = false;
1880                sprintf(generalPrint, "command line - ");
1881                for (int i = 0; i < argc; i++) {
1882                    if (!argv[i])
1883                        break;
1884                    if (strstr(argv[i], "strat"))
1885                        foundStrategy = true;
1886                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1887                }
1888                if (!foundStrategy)
1889                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1890                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1891                << generalPrint
1892                << CoinMessageEol;
1893            }
1894        }
1895#endif
1896        while (1) {
1897            // next command
1898            field = CoinReadGetCommand(argc, argv);
1899            // Reset time
1900            time1 = CoinCpuTime();
1901            time1Elapsed = CoinGetTimeOfDay();
1902            // adjust field if has odd trailing characters
1903            char temp [200];
1904            strcpy(temp, field.c_str());
1905            int length = static_cast<int>(strlen(temp));
1906            for (int k = length - 1; k >= 0; k--) {
1907                if (temp[k] < ' ')
1908                    length--;
1909                else
1910                    break;
1911            }
1912            temp[length] = '\0';
1913            field = temp;
1914            // exit if null or similar
1915            if (!field.length()) {
1916                if (numberGoodCommands == 1 && goodModel) {
1917                    // we just had file name - do branch and bound
1918                    field = "branch";
1919                } else if (!numberGoodCommands) {
1920                    // let's give the sucker a hint
1921                    std::cout
1922                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1923                        << std::endl
1924                        << "Enter ? for list of commands or help" << std::endl;
1925                    field = "-";
1926                } else {
1927                    break;
1928                }
1929            }
1930
1931            // see if ? at end
1932            size_t numberQuery = 0;
1933            if (field != "?" && field != "???") {
1934                size_t length = field.length();
1935                size_t i;
1936                for (i = length - 1; i > 0; i--) {
1937                    if (field[i] == '?')
1938                        numberQuery++;
1939                    else
1940                        break;
1941                }
1942                field = field.substr(0, length - numberQuery);
1943            }
1944            // find out if valid command
1945            int iParam;
1946            int numberMatches = 0;
1947            int firstMatch = -1;
1948            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1949                int match = parameters_[iParam].matches(field);
1950                if (match == 1) {
1951                    numberMatches = 1;
1952                    firstMatch = iParam;
1953                    break;
1954                } else {
1955                    if (match && firstMatch < 0)
1956                        firstMatch = iParam;
1957                    numberMatches += match >> 1;
1958                }
1959            }
1960            if (iParam < numberParameters_ && !numberQuery) {
1961                // found
1962                CbcOrClpParam found = parameters_[iParam];
1963                CbcOrClpParameterType type = found.type();
1964                int valid;
1965                numberGoodCommands++;
1966                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
1967#ifndef CBC_USE_INITIAL_TIME
1968                  if (model_.useElapsedTime())
1969                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1970                  else
1971                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1972#endif
1973                  biLinearProblem=false;
1974                    // check if any integers
1975#ifndef CBC_OTHER_SOLVER
1976#ifdef COIN_HAS_ASL
1977                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1978                        // SOS
1979                        numberSOS = info.numberSos;
1980                    }
1981#endif
1982                    lpSolver = clpSolver->getModelPtr();
1983                    if (!lpSolver->integerInformation() && !numberSOS &&
1984                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
1985                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
1986#endif
1987                }
1988                if (type == CBC_PARAM_GENERALQUERY) {
1989                    bool evenHidden = false;
1990                    int printLevel =
1991                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
1992                                               numberParameters_, parameters_)].currentOptionAsInteger();
1993                    int convertP[] = {2, 1, 0};
1994                    printLevel = convertP[printLevel];
1995                    if ((verbose&8) != 0) {
1996                        // even hidden
1997                        evenHidden = true;
1998                        verbose &= ~8;
1999                    }
2000#ifdef COIN_HAS_ASL
2001                    if (verbose < 4 && statusUserFunction_[0])
2002                        verbose += 4;
2003#endif
2004                    if (verbose < 4) {
2005                        std::cout << "In argument list keywords have leading - "
2006                                  ", -stdin or just - switches to stdin" << std::endl;
2007                        std::cout << "One command per line (and no -)" << std::endl;
2008                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
2009                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
2010                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
2011                        std::cout << "abcd value sets value" << std::endl;
2012                        std::cout << "Commands are:" << std::endl;
2013                    } else {
2014                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
2015                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
2016                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
2017                    }
2018                    int maxAcross = 10;
2019                    if ((verbose % 4) != 0)
2020                        maxAcross = 1;
2021                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2022                    std::vector<std::string> types;
2023                    types.push_back("Double parameters:");
2024                    types.push_back("Branch and Cut double parameters:");
2025                    types.push_back("Integer parameters:");
2026                    types.push_back("Branch and Cut integer parameters:");
2027                    types.push_back("Keyword parameters:");
2028                    types.push_back("Branch and Cut keyword parameters:");
2029                    types.push_back("Actions or string parameters:");
2030                    types.push_back("Branch and Cut actions:");
2031                    int iType;
2032                    for (iType = 0; iType < 8; iType++) {
2033                        int across = 0;
2034                        int lengthLine = 0;
2035                        if ((verbose % 4) != 0)
2036                            std::cout << std::endl;
2037                        std::cout << types[iType] << std::endl;
2038                        if ((verbose&2) != 0)
2039                            std::cout << std::endl;
2040                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2041                            int type = parameters_[iParam].type();
2042                            //printf("%d type %d limits %d %d display %d\n",iParam,
2043                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
2044                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
2045                                    type >= limits[iType]
2046                                    && type < limits[iType+1]) {
2047                                // but skip if not useful for ampl (and in ampl mode)
2048                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
2049                                    continue;
2050                                if (!across) {
2051                                    if ((verbose&2) != 0)
2052                                        std::cout << "Command ";
2053                                }
2054                                int length = parameters_[iParam].lengthMatchName() + 1;
2055                                if (lengthLine + length > 80) {
2056                                    std::cout << std::endl;
2057                                    across = 0;
2058                                    lengthLine = 0;
2059                                }
2060                                std::cout << " " << parameters_[iParam].matchName();
2061                                lengthLine += length;
2062                                across++;
2063                                if (across == maxAcross) {
2064                                    across = 0;
2065                                    if ((verbose % 4) != 0) {
2066                                        // put out description as well
2067                                        if ((verbose&1) != 0)
2068                                            std::cout << " " << parameters_[iParam].shortHelp();
2069                                        std::cout << std::endl;
2070                                        if ((verbose&2) != 0) {
2071                                            std::cout << "---- description" << std::endl;
2072                                            parameters_[iParam].printLongHelp();
2073                                            std::cout << "----" << std::endl << std::endl;
2074                                        }
2075                                    } else {
2076                                        std::cout << std::endl;
2077                                    }
2078                                }
2079                            }
2080                        }
2081                        if (across)
2082                            std::cout << std::endl;
2083                    }
2084                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
2085                    std::cout << "Full list of commands is:" << std::endl;
2086                    int maxAcross = 5;
2087                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2088                    std::vector<std::string> types;
2089                    types.push_back("Double parameters:");
2090                    types.push_back("Branch and Cut double parameters:");
2091                    types.push_back("Integer parameters:");
2092                    types.push_back("Branch and Cut integer parameters:");
2093                    types.push_back("Keyword parameters:");
2094                    types.push_back("Branch and Cut keyword parameters:");
2095                    types.push_back("Actions or string parameters:");
2096                    types.push_back("Branch and Cut actions:");
2097                    int iType;
2098                    for (iType = 0; iType < 8; iType++) {
2099                        int across = 0;
2100                        std::cout << types[iType] << "  ";
2101                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2102                            int type = parameters_[iParam].type();
2103                            if (type >= limits[iType]
2104                                    && type < limits[iType+1]) {
2105                                if (!across)
2106                                    std::cout << "  ";
2107                                std::cout << parameters_[iParam].matchName() << "  ";
2108                                across++;
2109                                if (across == maxAcross) {
2110                                    std::cout << std::endl;
2111                                    across = 0;
2112                                }
2113                            }
2114                        }
2115                        if (across)
2116                            std::cout << std::endl;
2117                    }
2118                } else if (type < 101) {
2119                    // get next field as double
2120                    double value = CoinReadGetDoubleField(argc, argv, &valid);
2121                    if (!valid) {
2122                        if (type < 51) {
2123                            int returnCode;
2124                            const char * message =
2125                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2126                            if (!noPrinting_ && strlen(message)) {
2127                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2128                                << message
2129                                << CoinMessageEol;
2130                            }
2131                        } else if (type < 81) {
2132                            int returnCode;
2133                            const char * message =
2134                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
2135                            if (!noPrinting_ && strlen(message)) {
2136                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2137                                << message
2138                                << CoinMessageEol;
2139                            }
2140                        } else {
2141                            int returnCode;
2142                            const char * message =
2143                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2144                            if (!noPrinting_ && strlen(message)) {
2145                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2146                                << message
2147                                << CoinMessageEol;
2148                            }
2149                            switch (type) {
2150                            case CBC_PARAM_DBL_DJFIX:
2151                                djFix = value;
2152#ifndef CBC_OTHER_SOLVER
2153                                if (goodModel && djFix < 1.0e20) {
2154                                    // do some fixing
2155                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
2156                                    clpSolver->initialSolve();
2157                                    lpSolver = clpSolver->getModelPtr();
2158                                    int numberColumns = lpSolver->numberColumns();
2159                                    int i;
2160                                    const char * type = lpSolver->integerInformation();
2161                                    double * lower = lpSolver->columnLower();
2162                                    double * upper = lpSolver->columnUpper();
2163                                    double * solution = lpSolver->primalColumnSolution();
2164                                    double * dj = lpSolver->dualColumnSolution();
2165                                    int numberFixed = 0;
2166                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
2167                                    if (dextra4)
2168                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
2169                                    for (i = 0; i < numberColumns; i++) {
2170                                        double djValue = dj[i];
2171                                        if (!type[i])
2172                                            djValue *= dextra4;
2173                                        if (type[i] || dextra4) {
2174                                            double value = solution[i];
2175                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
2176                                                solution[i] = lower[i];
2177                                                upper[i] = lower[i];
2178                                                numberFixed++;
2179                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
2180                                                solution[i] = upper[i];
2181                                                lower[i] = upper[i];
2182                                                numberFixed++;
2183                                            }
2184                                        }
2185                                    }
2186                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
2187                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2188                                    << generalPrint
2189                                    << CoinMessageEol;
2190                                }
2191#endif
2192                                break;
2193                            case CBC_PARAM_DBL_TIGHTENFACTOR:
2194                                tightenFactor = value;
2195                                if (!complicatedInteger)
2196                                    defaultSettings = false; // user knows what she is doing
2197                                break;
2198                            default:
2199                                break;
2200                            }
2201                        }
2202                    } else if (valid == 1) {
2203                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2204                                  parameters_[iParam].doubleValue() << std::endl;
2205                    } else {
2206                        std::cout << parameters_[iParam].name() << " has value " <<
2207                                  parameters_[iParam].doubleValue() << std::endl;
2208                    }
2209                } else if (type < 201) {
2210                    // get next field as int
2211                    int value = CoinReadGetIntField(argc, argv, &valid);
2212                    if (!valid) {
2213                        if (type < 151) {
2214                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
2215                                preSolve = value;
2216                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
2217                                doIdiot = value;
2218                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
2219                                doSprint = value;
2220                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
2221                                outputFormat = value;
2222                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
2223                                slpValue = value;
2224                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
2225                                cppValue = value;
2226                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
2227                                presolveOptions = value;
2228                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
2229                                printOptions = value;
2230                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
2231                                substitution = value;
2232                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
2233                                dualize = value;
2234                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
2235                                tunePreProcess = value;
2236                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
2237                                useSolution = value;
2238                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
2239                                verbose = value;
2240                            int returnCode;
2241                            const char * message =
2242                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2243                            if (!noPrinting_ && strlen(message)) {
2244                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2245                                << message
2246                                << CoinMessageEol;
2247                            }
2248                        } else {
2249                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
2250                                cutPass = value;
2251                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
2252                                cutPassInTree = value;
2253                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2254                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
2255                                strongChanged = true;
2256                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2257                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2258                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
2259                                pumpChanged = true;
2260                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
2261                                int addFlags=0;
2262                                if (value>=10) {
2263                                  addFlags = 1048576*(value/10);
2264                                  value = value % 10;
2265                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(value);
2266                                }
2267                                if (value >= 1) {
2268                                    int values[]={24003,280003,792003,24003,24003};
2269                                    if (value>=2&&value<=3) {
2270                                      // swap default diving
2271                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2272                                      parameters_[iParam].setCurrentOption("off");
2273                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2274                                      parameters_[iParam].setCurrentOption("on");
2275                                    }
2276                                    int extra4 = values[value-1]+addFlags;
2277                                    parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].setIntValue(extra4);
2278                                    if (!noPrinting_) {
2279                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2280                                        << "switching on global root cuts for gomory and knapsack"
2281                                        << CoinMessageEol;
2282                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2283                                        << "using OSL factorization"
2284                                        << CoinMessageEol;
2285                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2286                                        << "extra options - -rens on -extra4 "
2287                                        <<extra4<<" -passc 1000!"
2288                                        << CoinMessageEol;
2289                                    }
2290                                    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("forceOnStrong");
2291                                    probingAction = 8;
2292                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2293                                    gomoryAction = 5;
2294                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2295                                    knapsackAction = 5;
2296                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
2297                                    lpSolver->factorization()->forceOtherFactorization(3);
2298                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
2299                                    parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValue(1000);
2300                                    cutPass = 1000;
2301                                    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("on");
2302                                }
2303                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
2304                                if (value == 0) {
2305                                    gomoryGen.setAwayAtRoot(0.05);
2306                                    int iParam;
2307                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
2308                                    parameters_[iParam].setIntValue(-1);
2309                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
2310                                    parameters_[iParam].setIntValue(20);
2311                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
2312                                    parameters_[iParam].setIntValue(1003);
2313                                    initialPumpTune = 1003;
2314                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
2315                                    parameters_[iParam].setIntValue(0);
2316                                    tunePreProcess = 0;
2317                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2318                                    parameters_[iParam].setCurrentOption("off");
2319                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
2320                                    parameters_[iParam].setCurrentOption("off");
2321                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
2322                                    // but not if cuts off
2323                                    int jParam = whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_);
2324                                   
2325                                    jParam = parameters_[jParam].currentOptionAsInteger();
2326                                    if (jParam) {
2327                                      parameters_[iParam].setCurrentOption("on");
2328                                      probingAction = 1;
2329                                    } else {
2330                                      parameters_[iParam].setCurrentOption("off");
2331                                      probingAction = 0;
2332                                    }
2333                                }
2334                            }
2335                            int returnCode;
2336                            const char * message =
2337                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2338                            if (!noPrinting_ && strlen(message)) {
2339                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2340                                << message
2341                                << CoinMessageEol;
2342                            }
2343                        }
2344                    } else if (valid == 1) {
2345                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2346                                  parameters_[iParam].intValue() << std::endl;
2347                    } else {
2348                        std::cout << parameters_[iParam].name() << " has value " <<
2349                                  parameters_[iParam].intValue() << std::endl;
2350                    }
2351                } else if (type < 301) {
2352                    // one of several strings
2353                    std::string value = CoinReadGetString(argc, argv);
2354                    int action = parameters_[iParam].parameterOption(value);
2355                    if (action < 0) {
2356                        if (value != "EOL") {
2357                            // no match
2358                            parameters_[iParam].printOptions();
2359                        } else {
2360                            // print current value
2361                            std::cout << parameters_[iParam].name() << " has value " <<
2362                                      parameters_[iParam].currentOption() << std::endl;
2363                        }
2364                    } else {
2365                        const char * message =
2366                            parameters_[iParam].setCurrentOptionWithMessage(action);
2367                        if (!noPrinting_ && strlen(message)) {
2368                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2369                            << message
2370                            << CoinMessageEol;
2371                        }
2372                        // for now hard wired
2373                        switch (type) {
2374                        case CLP_PARAM_STR_DIRECTION:
2375                            if (action == 0)
2376                                lpSolver->setOptimizationDirection(1);
2377                            else if (action == 1)
2378                                lpSolver->setOptimizationDirection(-1);
2379                            else
2380                                lpSolver->setOptimizationDirection(0);
2381                            break;
2382                        case CLP_PARAM_STR_DUALPIVOT:
2383                            if (action == 0) {
2384                                ClpDualRowSteepest steep(3);
2385                                lpSolver->setDualRowPivotAlgorithm(steep);
2386                            } else if (action == 1) {
2387                                ClpDualRowDantzig dantzig;
2388                                //ClpDualRowSteepest dantzig(5);
2389                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2390                            } else if (action == 2) {
2391                                // partial steep
2392                                ClpDualRowSteepest steep(2);
2393                                lpSolver->setDualRowPivotAlgorithm(steep);
2394                            } else {
2395                                ClpDualRowSteepest steep;
2396                                lpSolver->setDualRowPivotAlgorithm(steep);
2397                            }
2398                            break;
2399                        case CLP_PARAM_STR_PRIMALPIVOT:
2400                            if (action == 0) {
2401                                ClpPrimalColumnSteepest steep(3);
2402                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2403                            } else if (action == 1) {
2404                                ClpPrimalColumnSteepest steep(0);
2405                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2406                            } else if (action == 2) {
2407                                ClpPrimalColumnDantzig dantzig;
2408                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2409                            } else if (action == 3) {
2410                                ClpPrimalColumnSteepest steep(4);
2411                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2412                            } else if (action == 4) {
2413                                ClpPrimalColumnSteepest steep(1);
2414                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2415                            } else if (action == 5) {
2416                                ClpPrimalColumnSteepest steep(2);
2417                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2418                            } else if (action == 6) {
2419                                ClpPrimalColumnSteepest steep(10);
2420                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2421                            }
2422                            break;
2423                        case CLP_PARAM_STR_SCALING:
2424                            lpSolver->scaling(action);
2425                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2426                            doScaling = action;
2427                            break;
2428                        case CLP_PARAM_STR_AUTOSCALE:
2429                            lpSolver->setAutomaticScaling(action != 0);
2430                            break;
2431                        case CLP_PARAM_STR_SPARSEFACTOR:
2432                            lpSolver->setSparseFactorization((1 - action) != 0);
2433                            break;
2434                        case CLP_PARAM_STR_BIASLU:
2435                            lpSolver->factorization()->setBiasLU(action);
2436                            break;
2437                        case CLP_PARAM_STR_PERTURBATION:
2438                            if (action == 0)
2439                                lpSolver->setPerturbation(50);
2440                            else
2441                                lpSolver->setPerturbation(100);
2442                            break;
2443                        case CLP_PARAM_STR_ERRORSALLOWED:
2444                            allowImportErrors = action;
2445                            break;
2446                        case CLP_PARAM_STR_INTPRINT:
2447                            printMode = action;
2448                            break;
2449                            //case CLP_PARAM_NOTUSED_ALGORITHM:
2450                            //algorithm  = action;
2451                            //defaultSettings=false; // user knows what she is doing
2452                            //abort();
2453                            //break;
2454                        case CLP_PARAM_STR_KEEPNAMES:
2455                            keepImportNames = 1 - action;
2456                            break;
2457                        case CLP_PARAM_STR_PRESOLVE:
2458                            if (action == 0)
2459                                preSolve = 5;
2460                            else if (action == 1)
2461                                preSolve = 0;
2462                            else if (action == 2)
2463                                preSolve = 10;
2464                            else
2465                                preSolveFile = true;
2466                            break;
2467                        case CLP_PARAM_STR_PFI:
2468                            lpSolver->factorization()->setForrestTomlin(action == 0);
2469                            break;
2470                        case CLP_PARAM_STR_FACTORIZATION:
2471                            lpSolver->factorization()->forceOtherFactorization(action);
2472                            break;
2473                        case CLP_PARAM_STR_CRASH:
2474                            doCrash = action;
2475                            break;
2476                        case CLP_PARAM_STR_VECTOR:
2477                            doVector = action;
2478                            break;
2479                        case CLP_PARAM_STR_MESSAGES:
2480                            lpSolver->messageHandler()->setPrefix(action != 0);
2481                            break;
2482                        case CLP_PARAM_STR_CHOLESKY:
2483                            choleskyType = action;
2484                            break;
2485                        case CLP_PARAM_STR_GAMMA:
2486                            gamma = action;
2487                            break;
2488                        case CLP_PARAM_STR_BARRIERSCALE:
2489                            scaleBarrier = action;
2490                            break;
2491                        case CLP_PARAM_STR_KKT:
2492                            doKKT = action;
2493                            break;
2494                        case CLP_PARAM_STR_CROSSOVER:
2495                            crossover = action;
2496                            break;
2497                        case CLP_PARAM_STR_TIME_MODE:
2498                            model_.setUseElapsedTime(action!=0);
2499                            break;
2500                        case CBC_PARAM_STR_SOS:
2501                            doSOS = action;
2502                            break;
2503                        case CBC_PARAM_STR_GOMORYCUTS:
2504                            defaultSettings = false; // user knows what she is doing
2505                            gomoryAction = action;
2506                            break;
2507                        case CBC_PARAM_STR_PROBINGCUTS:
2508                            defaultSettings = false; // user knows what she is doing
2509                            probingAction = action;
2510                            break;
2511                        case CBC_PARAM_STR_KNAPSACKCUTS:
2512                            defaultSettings = false; // user knows what she is doing
2513                            knapsackAction = action;
2514                            break;
2515                        case CBC_PARAM_STR_REDSPLITCUTS:
2516                            defaultSettings = false; // user knows what she is doing
2517                            redsplitAction = action;
2518                            break;
2519                        case CBC_PARAM_STR_REDSPLIT2CUTS:
2520                            defaultSettings = false; // user knows what she is doing
2521                            redsplit2Action = action;
2522                            break;
2523                        case CBC_PARAM_STR_GMICUTS:
2524                            defaultSettings = false; // user knows what she is doing
2525                            GMIAction = action;
2526                            break;
2527                        case CBC_PARAM_STR_CLIQUECUTS:
2528                            defaultSettings = false; // user knows what she is doing
2529                            cliqueAction = action;
2530                            break;
2531                        case CBC_PARAM_STR_FLOWCUTS:
2532                            defaultSettings = false; // user knows what she is doing
2533                            flowAction = action;
2534                            break;
2535                        case CBC_PARAM_STR_MIXEDCUTS:
2536                            defaultSettings = false; // user knows what she is doing
2537                            mixedAction = action;
2538                            break;
2539                        case CBC_PARAM_STR_TWOMIRCUTS:
2540                            defaultSettings = false; // user knows what she is doing
2541                            twomirAction = action;
2542                            break;
2543                        case CBC_PARAM_STR_LANDPCUTS:
2544                            defaultSettings = false; // user knows what she is doing
2545                            landpAction = action;
2546                            break;
2547                        case CBC_PARAM_STR_RESIDCUTS:
2548                            defaultSettings = false; // user knows what she is doing
2549                            residualCapacityAction = action;
2550                            break;
2551                        case CBC_PARAM_STR_ZEROHALFCUTS:
2552                            defaultSettings = false; // user knows what she is doing
2553                            zerohalfAction = action;
2554                            break;
2555                        case CBC_PARAM_STR_ROUNDING:
2556                            defaultSettings = false; // user knows what she is doing
2557                            break;
2558                        case CBC_PARAM_STR_FPUMP:
2559                            defaultSettings = false; // user knows what she is doing
2560                            break;
2561                        case CBC_PARAM_STR_RINS:
2562                            break;
2563                        case CBC_PARAM_STR_DINS:
2564                            break;
2565                        case CBC_PARAM_STR_RENS:
2566                            break;
2567                        case CBC_PARAM_STR_CUTSSTRATEGY:
2568                            gomoryAction = action;
2569                            probingAction = action;
2570                            knapsackAction = action;
2571                            zerohalfAction = action;
2572                            cliqueAction = action;
2573                            flowAction = action;
2574                            mixedAction = action;
2575                            twomirAction = action;
2576                            //landpAction = action;
2577                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2578                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2579                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2580                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2581                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2582                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2583                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2584                            parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2585                            if (!action) {
2586                                redsplitAction = action;
2587                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2588                                redsplit2Action = action;
2589                                parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption(action);
2590                                GMIAction = action;
2591                                parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption(action);
2592                                landpAction = action;
2593                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2594                                residualCapacityAction = action;
2595                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2596                            }
2597                            break;
2598                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2599                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2600                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2601                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2602                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2603                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2604                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2605                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
2606                            break;
2607                        case CBC_PARAM_STR_GREEDY:
2608                        case CBC_PARAM_STR_DIVINGS:
2609                        case CBC_PARAM_STR_DIVINGC:
2610                        case CBC_PARAM_STR_DIVINGF:
2611                        case CBC_PARAM_STR_DIVINGG:
2612                        case CBC_PARAM_STR_DIVINGL:
2613                        case CBC_PARAM_STR_DIVINGP:
2614                        case CBC_PARAM_STR_DIVINGV:
2615                        case CBC_PARAM_STR_COMBINE:
2616                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2617                        case CBC_PARAM_STR_PIVOTANDFIX:
2618                        case CBC_PARAM_STR_RANDROUND:
2619                        case CBC_PARAM_STR_LOCALTREE:
2620                        case CBC_PARAM_STR_NAIVE:
2621                        case CBC_PARAM_STR_CPX:
2622                            defaultSettings = false; // user knows what she is doing
2623                            break;
2624                        case CBC_PARAM_STR_COSTSTRATEGY:
2625                            useCosts = action;
2626                            break;
2627                        case CBC_PARAM_STR_NODESTRATEGY:
2628                            nodeStrategy = action;
2629                            break;
2630                        case CBC_PARAM_STR_PREPROCESS:
2631                            preProcess = action;
2632                            break;
2633                        default:
2634                            //abort();
2635                            break;
2636                        }
2637                    }
2638                } else {
2639                    // action
2640                    if (type == CLP_PARAM_ACTION_EXIT) {
2641#ifdef COIN_HAS_ASL
2642                        if (statusUserFunction_[0]) {
2643                            if (info.numberIntegers || info.numberBinary) {
2644                                // integer
2645                            } else {
2646                                // linear
2647                            }
2648                            writeAmpl(&info);
2649                            freeArrays2(&info);
2650                            freeArgs(&info);
2651                        }
2652#endif
2653                        break; // stop all
2654                    }
2655                    switch (type) {
2656                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2657                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2658                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2659                    case CLP_PARAM_ACTION_BARRIER:
2660                        if (goodModel) {
2661                            // Say not in integer
2662                            integerStatus = -1;
2663                            double objScale =
2664                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
2665                            if (objScale != 1.0) {
2666                                int iColumn;
2667                                int numberColumns = lpSolver->numberColumns();
2668                                double * dualColumnSolution =
2669                                    lpSolver->dualColumnSolution();
2670                                ClpObjective * obj = lpSolver->objectiveAsObject();
2671                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2672                                double offset;
2673                                double * objective = obj->gradient(NULL, NULL, offset, true);
2674                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2675                                    dualColumnSolution[iColumn] *= objScale;
2676                                    objective[iColumn] *= objScale;;
2677                                }
2678                                int iRow;
2679                                int numberRows = lpSolver->numberRows();
2680                                double * dualRowSolution =
2681                                    lpSolver->dualRowSolution();
2682                                for (iRow = 0; iRow < numberRows; iRow++)
2683                                    dualRowSolution[iRow] *= objScale;
2684                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2685                            }
2686                            ClpSolve::SolveType method;
2687                            ClpSolve::PresolveType presolveType;
2688                            ClpSimplex * model2 = lpSolver;
2689                            if (dualize) {
2690                                bool tryIt = true;
2691                                double fractionColumn = 1.0;
2692                                double fractionRow = 1.0;
2693                                if (dualize == 3) {
2694                                    dualize = 1;
2695                                    int numberColumns = lpSolver->numberColumns();
2696                                    int numberRows = lpSolver->numberRows();
2697                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2698                                        tryIt = false;
2699                                    } else {
2700                                        fractionColumn = 0.1;
2701                                        fractionRow = 0.1;
2702                                    }
2703                                }
2704                                if (tryIt) {
2705                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2706                                    if (model2) {
2707                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2708                                                model2->numberRows(), model2->numberColumns());
2709                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2710                                        << generalPrint
2711                                        << CoinMessageEol;
2712                                        model2->setOptimizationDirection(1.0);
2713                                    } else {
2714                                        model2 = lpSolver;
2715                                        dualize = 0;
2716                                    }
2717                                } else {
2718                                    dualize = 0;
2719                                }
2720                            }
2721                            if (noPrinting_)
2722                                lpSolver->setLogLevel(0);
2723                            ClpSolve solveOptions;
2724                            solveOptions.setPresolveActions(presolveOptions);
2725                            solveOptions.setSubstitution(substitution);
2726                            if (preSolve != 5 && preSolve) {
2727                                presolveType = ClpSolve::presolveNumber;
2728                                if (preSolve < 0) {
2729                                    preSolve = - preSolve;
2730                                    if (preSolve <= 100) {
2731                                        presolveType = ClpSolve::presolveNumber;
2732                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2733                                                preSolve);
2734                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2735                                        << generalPrint
2736                                        << CoinMessageEol;
2737                                        solveOptions.setDoSingletonColumn(true);
2738                                    } else {
2739                                        preSolve -= 100;
2740                                        presolveType = ClpSolve::presolveNumberCost;
2741                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2742                                                preSolve);
2743                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2744                                        << generalPrint
2745                                        << CoinMessageEol;
2746                                    }
2747                                }
2748                            } else if (preSolve) {
2749                                presolveType = ClpSolve::presolveOn;
2750                            } else {
2751                                presolveType = ClpSolve::presolveOff;
2752                            }
2753                            solveOptions.setPresolveType(presolveType, preSolve);
2754                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2755                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
2756                                method = ClpSolve::useDual;
2757                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
2758                                method = ClpSolve::usePrimalorSprint;
2759                            } else {
2760                                method = ClpSolve::useBarrier;
2761                                if (crossover == 1) {
2762                                    method = ClpSolve::useBarrierNoCross;
2763                                } else if (crossover == 2) {
2764                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2765                                    if (obj->type() > 1) {
2766                                        method = ClpSolve::useBarrierNoCross;
2767                                        presolveType = ClpSolve::presolveOff;
2768                                        solveOptions.setPresolveType(presolveType, preSolve);
2769                                    }
2770                                }
2771                            }
2772                            solveOptions.setSolveType(method);
2773                            if (preSolveFile)
2774                                presolveOptions |= 0x40000000;
2775                            solveOptions.setSpecialOption(4, presolveOptions);
2776                            solveOptions.setSpecialOption(5, printOptions);
2777                            if (doVector) {
2778                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2779                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2780                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2781                                    clpMatrix->makeSpecialColumnCopy();
2782                                }
2783                            }
2784                            if (method == ClpSolve::useDual) {
2785                                // dual
2786                                if (doCrash)
2787                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2788                                else if (doIdiot)
2789                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2790                            } else if (method == ClpSolve::usePrimalorSprint) {
2791                                // primal
2792                                // if slp turn everything off
2793                                if (slpValue > 0) {
2794                                    doCrash = false;
2795                                    doSprint = 0;
2796                                    doIdiot = -1;
2797                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2798                                    method = ClpSolve::usePrimal;
2799                                }
2800                                if (doCrash) {
2801                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2802                                } else if (doSprint > 0) {
2803                                    // sprint overrides idiot
2804                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2805                                } else if (doIdiot > 0) {
2806                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2807                                } else if (slpValue <= 0) {
2808                                    if (doIdiot == 0) {
2809                                        if (doSprint == 0)
2810                                            solveOptions.setSpecialOption(1, 4); // all slack
2811                                        else
2812                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2813                                    } else {
2814                                        if (doSprint == 0)
2815                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2816                                        else
2817                                            solveOptions.setSpecialOption(1, 7); // initiative
2818                                    }
2819                                }
2820                                if (basisHasValues == -1)
2821                                    solveOptions.setSpecialOption(1, 11); // switch off values
2822                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2823                                int barrierOptions = choleskyType;
2824                                if (scaleBarrier)
2825                                    barrierOptions |= 8;
2826                                if (doKKT)
2827                                    barrierOptions |= 16;
2828                                if (gamma)
2829                                    barrierOptions |= 32 * gamma;
2830                                if (crossover == 3)
2831                                    barrierOptions |= 256; // try presolve in crossover
2832                                solveOptions.setSpecialOption(4, barrierOptions);
2833                            }
2834                            model2->setMaximumSeconds(model_.getMaximumSeconds());
2835#ifdef COIN_HAS_LINK
2836                            OsiSolverInterface * coinSolver = model_.solver();
2837                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2838                            if (!linkSolver) {
2839                                model2->initialSolve(solveOptions);
2840                            } else {
2841                                // special solver
2842                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
2843                                double * solution = NULL;
2844                                if (testOsiOptions < 10) {
2845                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2846                                } else if (testOsiOptions >= 10) {
2847                                    CoinModel coinModel = *linkSolver->coinModel();
2848                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2849                                    assert (tempModel);
2850                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2851                                    model2->setObjectiveValue(tempModel->objectiveValue());
2852                                    model2->setProblemStatus(tempModel->problemStatus());
2853                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2854                                    delete tempModel;
2855                                }
2856                                if (solution) {
2857                                    memcpy(model2->primalColumnSolution(), solution,
2858                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2859                                    delete [] solution;
2860                                } else {
2861                                    printf("No nonlinear solution\n");
2862                                }
2863                            }
2864#else
2865                            model2->initialSolve(solveOptions);
2866#endif
2867                            {
2868                                // map states
2869                                /* clp status
2870                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2871                                   0 - optimal
2872                                   1 - primal infeasible
2873                                   2 - dual infeasible
2874                                   3 - stopped on iterations or time
2875                                   4 - stopped due to errors
2876                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2877                                /* cbc status
2878                                   -1 before branchAndBound
2879                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2880                                   (or check value of best solution)
2881                                   1 stopped - on maxnodes, maxsols, maxtime
2882                                   2 difficulties so run was abandoned
2883                                   (5 event user programmed event occurred) */
2884                                /* clp secondary status of problem - may get extended
2885                                   0 - none
2886                                   1 - primal infeasible because dual limit reached OR probably primal
2887                                   infeasible but can't prove it (main status 4)
2888                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2889                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
2890                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
2891                                   5 - giving up in primal with flagged variables
2892                                   6 - failed due to empty problem check
2893                                   7 - postSolve says not optimal
2894                                   8 - failed due to bad element check
2895                                   9 - status was 3 and stopped on time
2896                                   100 up - translation of enum from ClpEventHandler
2897                                */
2898                                /* cbc secondary status of problem
2899                                   -1 unset (status_ will also be -1)
2900                                   0 search completed with solution
2901                                   1 linear relaxation not feasible (or worse than cutoff)
2902                                   2 stopped on gap
2903                                   3 stopped on nodes
2904                                   4 stopped on time
2905                                   5 stopped on user event
2906                                   6 stopped on solutions
2907                                   7 linear relaxation unbounded
2908                                   8 stopped on iterations limit
2909                                */
2910                                int iStatus = model2->status();
2911                                int iStatus2 = model2->secondaryStatus();
2912                                if (iStatus == 0) {
2913                                    iStatus2 = 0;
2914                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
2915                                        // set best solution in model as no integers
2916                                        model_.setBestSolution(model2->primalColumnSolution(),
2917                                                               model2->numberColumns(),
2918                                                               model2->getObjValue()*
2919                                                               model2->getObjSense());
2920                                    }
2921                                } else if (iStatus == 1) {
2922                                    iStatus = 0;
2923                                    iStatus2 = 1; // say infeasible
2924                                } else if (iStatus == 2) {
2925                                    iStatus = 0;
2926                                    iStatus2 = 7; // say unbounded
2927                                } else if (iStatus == 3) {
2928                                    iStatus = 1;
2929                                    if (iStatus2 == 9)  // what does 9 mean ?????????????
2930                                        iStatus2 = 4;
2931                                    else
2932                                        iStatus2 = 3; // Use nodes - as closer than solutions
2933                                } else if (iStatus == 4) {
2934                                    iStatus = 2; // difficulties
2935                                    iStatus2 = 0;
2936                                }
2937                                model_.setProblemStatus(iStatus);
2938                                model_.setSecondaryStatus(iStatus2);
2939                                if ((iStatus == 2 || iStatus2 > 0) &&
2940                                    !noPrinting_) {
2941                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
2942                                   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"};
2943                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
2944                                           statusName[iStatus].c_str(), 
2945                                           minor[iStatus2].c_str());
2946                                   sprintf(generalPrint + strlen(generalPrint),
2947                                           "Enumerated nodes:           0\n");
2948                                   sprintf(generalPrint + strlen(generalPrint), 
2949                                           "Total iterations:           0\n");
2950#if CBC_QUIET == 0
2951                                   sprintf(generalPrint + strlen(generalPrint),
2952                                           "Time (CPU seconds):         %.2f\n", 
2953                                           CoinCpuTime() - time0);
2954                                   sprintf(generalPrint + strlen(generalPrint),
2955                                           "Time (Wallclock Seconds):   %.2f\n", 
2956                                           CoinGetTimeOfDay()-time0Elapsed);
2957#endif
2958                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
2959                                      << generalPrint
2960                                      << CoinMessageEol;
2961                                }
2962                                //assert (lpSolver==clpSolver->getModelPtr());
2963                                assert (clpSolver == model_.solver());
2964                                clpSolver->setWarmStart(NULL);
2965                                // and in babModel if exists
2966                                if (babModel_) {
2967                                    babModel_->setProblemStatus(iStatus);
2968                                    babModel_->setSecondaryStatus(iStatus2);
2969                                }
2970                                int returnCode = callBack(&model, 1);
2971                                if (returnCode) {
2972                                    // exit if user wants
2973                                    delete babModel_;
2974                                    babModel_ = NULL;
2975                                    return returnCode;
2976                                }
2977                            }
2978                            basisHasValues = 1;
2979                            if (dualize) {
2980                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
2981                                if (model2->status() == 3)
2982                                    returnCode = 0;
2983                                delete model2;
2984                                if (returnCode && dualize != 2)
2985                                    lpSolver->primal(1);
2986                                model2 = lpSolver;
2987                            }
2988#ifdef COIN_HAS_ASL
2989                            if (statusUserFunction_[0]) {
2990                                double value = model2->getObjValue();
2991                                char buf[300];
2992                                int pos = 0;
2993                                int iStat = model2->status();
2994                                if (iStat == 0) {
2995                                    pos += sprintf(buf + pos, "optimal," );
2996                                } else if (iStat == 1) {
2997                                    // infeasible
2998                                    pos += sprintf(buf + pos, "infeasible,");
2999                                } else if (iStat == 2) {
3000                                    // unbounded
3001                                    pos += sprintf(buf + pos, "unbounded,");
3002                                } else if (iStat == 3) {
3003                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
3004                                } else if (iStat == 4) {
3005                                    iStat = 7;
3006                                    pos += sprintf(buf + pos, "stopped on difficulties,");
3007                                } else if (iStat == 5) {
3008                                    iStat = 3;
3009                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
3010                                } else if (iStat == 6) {
3011                                    // bab infeasible
3012                                    pos += sprintf(buf + pos, "integer infeasible,");
3013                                    iStat = 1;
3014                                } else {
3015                                    pos += sprintf(buf + pos, "status unknown,");
3016                                    iStat = 6;
3017                                }
3018                                info.problemStatus = iStat;
3019                                info.objValue = value;
3020                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3021                                               value);
3022                                sprintf(buf + pos, "\n%d iterations",
3023                                        model2->getIterationCount());
3024                                free(info.primalSolution);
3025                                int numberColumns = model2->numberColumns();
3026                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3027                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
3028                                int numberRows = model2->numberRows();
3029                                free(info.dualSolution);
3030                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3031                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
3032                                CoinWarmStartBasis * basis = model2->getBasis();
3033                                free(info.rowStatus);
3034                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3035                                free(info.columnStatus);
3036                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3037                                // Put basis in
3038                                int i;
3039                                // free,basic,ub,lb are 0,1,2,3
3040                                for (i = 0; i < numberRows; i++) {
3041                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3042                                    info.rowStatus[i] = status;
3043                                }
3044                                for (i = 0; i < numberColumns; i++) {
3045                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3046                                    info.columnStatus[i] = status;
3047                                }
3048                                // put buffer into info
3049                                strcpy(info.buffer, buf);
3050                                delete basis;
3051                            }
3052#endif
3053                        } else {
3054#ifndef DISALLOW_PRINTING
3055#ifdef GENERAL_HANDLER_PRINTING
3056                          sprintf(generalPrint, "** Current model not valid");
3057                          printGeneralMessage(model_,generalPrint);
3058#else
3059                          std::cout << "** Current model not valid" << std::endl;
3060#endif
3061#endif
3062                        }
3063                        break;
3064                    case CLP_PARAM_ACTION_STATISTICS:
3065                        if (goodModel) {
3066                            // If presolve on look at presolved
3067                            bool deleteModel2 = false;
3068                            ClpSimplex * model2 = lpSolver;
3069                            if (preSolve) {
3070                                ClpPresolve pinfo;
3071                                int presolveOptions2 = presolveOptions&~0x40000000;
3072                                if ((presolveOptions2&0xffff) != 0)
3073                                    pinfo.setPresolveActions(presolveOptions2);
3074                                pinfo.setSubstitution(substitution);
3075                                if ((printOptions&1) != 0)
3076                                    pinfo.statistics();
3077                                double presolveTolerance =
3078                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
3079                                model2 =
3080                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
3081                                                         true, preSolve);
3082                                if (model2) {
3083                                    printf("Statistics for presolved model\n");
3084                                    deleteModel2 = true;
3085                                } else {
3086                                    printf("Presolved model looks infeasible - will use unpresolved\n");
3087                                    model2 = lpSolver;
3088                                }
3089                            } else {
3090                                printf("Statistics for unpresolved model\n");
3091                                model2 =  lpSolver;
3092                            }
3093                            statistics(lpSolver, model2);
3094                            if (deleteModel2)
3095                                delete model2;
3096                        } else {
3097#ifndef DISALLOW_PRINTING
3098#ifdef GENERAL_HANDLER_PRINTING
3099                          sprintf(generalPrint, "** Current model not valid");
3100                          printGeneralMessage(model_,generalPrint);
3101#else
3102                          std::cout << "** Current model not valid" << std::endl;
3103#endif
3104#endif
3105                        }
3106                        break;
3107                    case CLP_PARAM_ACTION_TIGHTEN:
3108                        if (goodModel) {
3109                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
3110                            if (numberInfeasibilities) {
3111#ifdef GENERAL_HANDLER_PRINTING
3112                              sprintf(generalPrint,"** Analysis indicates model infeasible");
3113                              printGeneralMessage(model_,generalPrint);
3114#else
3115                              std::cout << "** Analysis indicates model infeasible" << std::endl;
3116#endif
3117                            }
3118                        } else {
3119#ifndef DISALLOW_PRINTING
3120#ifdef GENERAL_HANDLER_PRINTING
3121                          sprintf(generalPrint, "** Current model not valid");
3122                          printGeneralMessage(model_,generalPrint);
3123#else
3124                          std::cout << "** Current model not valid" << std::endl;
3125#endif
3126#endif
3127                        }
3128                        break;
3129                    case CLP_PARAM_ACTION_PLUSMINUS:
3130                        if (goodModel) {
3131                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3132                            ClpPackedMatrix* clpMatrix =
3133                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3134                            if (clpMatrix) {
3135                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
3136                                if (newMatrix->getIndices()) {
3137                                    lpSolver->replaceMatrix(newMatrix);
3138                                    delete saveMatrix;
3139#ifdef GENERAL_HANDLER_PRINTING
3140                                    sprintf(generalPrint, "Matrix converted to +- one matrix");
3141                                    printGeneralMessage(model_,generalPrint);
3142#else
3143                                    std::cout << "Matrix converted to +- one matrix" << std::endl;
3144#endif
3145                                } else {
3146#ifdef GENERAL_HANDLER_PRINTING
3147                                  sprintf(generalPrint, "Matrix can not be converted to +- 1 matrix");
3148                                  printGeneralMessage(model_,generalPrint);
3149#else
3150                                    std::cout << "Matrix can not be converted to +- 1 matrix" << std::endl;
3151#endif
3152                                }
3153                            } else {
3154#ifdef GENERAL_HANDLER_PRINTING
3155                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3156                              printGeneralMessage(model_,generalPrint);
3157#else
3158                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
3159#endif
3160                            }
3161                        } else {
3162#ifndef DISALLOW_PRINTING
3163#ifdef GENERAL_HANDLER_PRINTING
3164                          sprintf(generalPrint, "** Current model not valid");
3165                          printGeneralMessage(model_,generalPrint);
3166#else
3167                            std::cout << "** Current model not valid" << std::endl;
3168#endif
3169#endif
3170                        }
3171                        break;
3172                    case CLP_PARAM_ACTION_OUTDUPROWS:
3173                        dominatedCuts = true;
3174#ifdef JJF_ZERO
3175                        if (goodModel) {
3176                            int numberRows = clpSolver->getNumRows();
3177                            //int nOut = outDupRow(clpSolver);
3178                            CglDuplicateRow dupcuts(clpSolver);
3179                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
3180                            int nOut = numberRows - clpSolver->getNumRows();
3181                            if (nOut && !noPrinting_)
3182                                sprintf(generalPrint, "%d rows eliminated", nOut);
3183                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
3184                            << generalPrint
3185                            << CoinMessageEol;
3186                        } else {
3187#ifndef DISALLOW_PRINTING
3188#ifdef GENERAL_HANDLER_PRINTING
3189                          sprintf(generalPrint, "** Current model not valid");
3190                          printGeneralMessage(model_,generalPrint);
3191#else
3192                            std::cout << "** Current model not valid" << std::endl;
3193#endif
3194#endif
3195                        }
3196#endif
3197                        break;
3198                    case CLP_PARAM_ACTION_NETWORK:
3199                        if (goodModel) {
3200                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3201                            ClpPackedMatrix* clpMatrix =
3202                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3203                            if (clpMatrix) {
3204                                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
3205                                if (newMatrix->getIndices()) {
3206                                    lpSolver->replaceMatrix(newMatrix);
3207                                    delete saveMatrix;
3208#ifdef GENERAL_HANDLER_PRINTING
3209                                    sprintf(generalPrint, "Matrix converted to network matrix");
3210                                    printGeneralMessage(model_,generalPrint);
3211#else
3212                                    std::cout << "Matrix converted to network matrix" << std::endl;
3213#endif
3214                                } else {
3215#ifdef GENERAL_HANDLER_PRINTING
3216                                  sprintf(generalPrint, "Matrix can not be converted to network matrix");
3217                                  printGeneralMessage(model_,generalPrint);
3218#else
3219                                    std::cout << "Matrix can not be converted to network matrix" << std::endl;
3220#endif
3221                                }
3222                            } else {
3223#ifdef GENERAL_HANDLER_PRINTING
3224                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3225                              printGeneralMessage(model_,generalPrint);
3226#else
3227                                std::cout << "Matrix not a ClpPackedMatrix" << std::endl;
3228#endif
3229                            }
3230                        } else {
3231#ifndef DISALLOW_PRINTING
3232#ifdef GENERAL_HANDLER_PRINTING
3233                          sprintf(generalPrint, "** Current model not valid");
3234                          printGeneralMessage(model_,generalPrint);
3235#else
3236                            std::cout << "** Current model not valid" << std::endl;
3237#endif
3238#endif
3239                        }
3240                        break;
3241                    case CBC_PARAM_ACTION_DOHEURISTIC:
3242                        if (goodModel) {
3243                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
3244                            if (vubAction != -1) {
3245                                // look at vubs
3246                                // extra1 is number of ints to leave free
3247                                // Just ones which affect >= extra3
3248                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
3249                                /* 2 is cost above which to fix if feasible
3250                                   3 is fraction of integer variables fixed if relaxing (0.97)
3251                                   4 is fraction of all variables fixed if relaxing (0.0)
3252                                */
3253                                double dextra[6];
3254                                int extra[5];
3255                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3256                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
3257                                                                  parameters_)].intValue();
3258                                if (exp1 == 4 && extra[1] == -1)
3259                                    extra[1] = 999998;
3260                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
3261                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
3262                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3263                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
3264                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
3265                                if (!dextra[3])
3266                                    dextra[3] = 0.97;
3267                                //OsiClpSolverInterface * newSolver =
3268                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
3269                                        debugValues, dextra, extra);
3270                                //assert (!newSolver);
3271                            }
3272                            // Actually do heuristics
3273                            doHeuristics(&model_, 2, parameters_,
3274                                         numberParameters_, noPrinting_, initialPumpTune);
3275                            if (model_.bestSolution()) {
3276                                model_.setProblemStatus(1);
3277                                model_.setSecondaryStatus(6);
3278#ifdef COIN_HAS_ASL
3279                                if (statusUserFunction_[0]) {
3280                                    double value = model_.getObjValue();
3281                                    char buf[300];
3282                                    int pos = 0;
3283                                    pos += sprintf(buf + pos, "feasible,");
3284                                    info.problemStatus = 0;
3285                                    info.objValue = value;
3286                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3287                                                   value);
3288                                    sprintf(buf + pos, "\n0 iterations");
3289                                    free(info.primalSolution);
3290                                    int numberColumns = lpSolver->numberColumns();
3291                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3292                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3293                                    int numberRows = lpSolver->numberRows();
3294                                    free(info.dualSolution);
3295                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3296                                    CoinZeroN(info.dualSolution, numberRows);
3297                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3298                                    free(info.rowStatus);
3299                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3300                                    free(info.columnStatus);
3301                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3302                                    // Put basis in
3303                                    int i;
3304                                    // free,basic,ub,lb are 0,1,2,3
3305                                    for (i = 0; i < numberRows; i++) {
3306                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3307                                        info.rowStatus[i] = status;
3308                                    }
3309                                    for (i = 0; i < numberColumns; i++) {
3310                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3311                                        info.columnStatus[i] = status;
3312                                    }
3313                                    // put buffer into info
3314                                    strcpy(info.buffer, buf);
3315                                    delete basis;
3316                                }
3317#endif
3318                            }
3319                            int returnCode = callBack(&model, 6);
3320                            if (returnCode) {
3321                                // exit if user wants
3322                                delete babModel_;
3323                                babModel_ = NULL;
3324                                return returnCode;
3325                            }
3326                        }
3327                        break;
3328                    case CBC_PARAM_ACTION_MIPLIB:
3329                        // User can set options - main difference is lack of model and CglPreProcess
3330                        goodModel = true;
3331                        /*
3332                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3333                          Print elapsed time at the end.
3334                        */
3335                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3336                        // obsolete case STRENGTHEN:
3337                        if (goodModel) {
3338                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3339                            int logLevel = parameters_[slog].intValue();
3340                            int truncateColumns=COIN_INT_MAX;
3341                            int * newPriorities=NULL;
3342                            // Reduce printout
3343                            if (logLevel <= 1) {
3344                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3345                            } else {
3346                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3347                            }
3348                            {
3349                                OsiSolverInterface * solver = model_.solver();
3350#ifndef CBC_OTHER_SOLVER
3351                                OsiClpSolverInterface * si =
3352                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3353                                assert (si != NULL);
3354                                si->getModelPtr()->scaling(doScaling);
3355                                ClpSimplex * lpSolver = si->getModelPtr();
3356                                if (doVector) {
3357                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3358                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3359                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3360                                        clpMatrix->makeSpecialColumnCopy();
3361                                    }
3362                                }
3363#elif CBC_OTHER_SOLVER==1
3364                                OsiCpxSolverInterface * si =
3365                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3366                                assert (si != NULL);
3367#endif
3368                                statistics_nrows = si->getNumRows();
3369                                statistics_ncols = si->getNumCols();
3370                                statistics_nprocessedrows = si->getNumRows();
3371                                statistics_nprocessedcols = si->getNumCols();
3372                                // See if quadratic
3373#ifndef CBC_OTHER_SOLVER
3374#ifdef COIN_HAS_LINK
3375                                if (!complicatedInteger) {
3376                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3377                                    if (obj) {
3378                                        preProcess = 0;
3379                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3380                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3381                                        // create coin model
3382                                        coinModel = lpSolver->createCoinModel();
3383                                        assert (coinModel);
3384                                        // load from coin model
3385                                        OsiSolverLink solver1;
3386                                        OsiSolverInterface * solver2 = solver1.clone();
3387                                        model_.assignSolver(solver2, false);
3388                                        OsiSolverLink * si =
3389                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3390                                        assert (si != NULL);
3391                                        si->setDefaultMeshSize(0.001);
3392                                        // need some relative granularity
3393                                        si->setDefaultBound(100.0);
3394                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3395                                        if (dextra3)
3396                                            si->setDefaultMeshSize(dextra3);
3397                                        si->setDefaultBound(1000.0);
3398                                        si->setIntegerPriority(1000);
3399                                        si->setBiLinearPriority(10000);
3400                                        biLinearProblem=true;
3401                                        si->setSpecialOptions2(2 + 4 + 8);
3402                                        CoinModel * model2 = coinModel;
3403                                        si->load(*model2, true, parameters_[log].intValue());
3404                                        // redo
3405                                        solver = model_.solver();
3406                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3407                                        lpSolver = clpSolver->getModelPtr();
3408                                        clpSolver->messageHandler()->setLogLevel(0) ;
3409                                        testOsiParameters = 0;
3410                                        complicatedInteger = 2;  // allow cuts
3411                                        OsiSolverInterface * coinSolver = model_.solver();
3412                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3413                                        if (linkSolver->quadraticModel()) {
3414                                            ClpSimplex * qp = linkSolver->quadraticModel();
3415                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3416                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3417                                            qp->primal(1);
3418                                            OsiSolverLinearizedQuadratic solver2(qp);
3419                                            const double * solution = NULL;
3420                                            // Reduce printout
3421                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3422                                            CbcModel model2(solver2);
3423                                            // Now do requested saves and modifications
3424                                            CbcModel * cbcModel = & model2;
3425                                            OsiSolverInterface * osiModel = model2.solver();
3426                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3427                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3428
3429                                            // Set changed values
3430
3431                                            CglProbing probing;
3432                                            probing.setMaxProbe(10);
3433                                            probing.setMaxLook(10);
3434                                            probing.setMaxElements(200);
3435                                            probing.setMaxProbeRoot(50);
3436                                            probing.setMaxLookRoot(10);
3437                                            probing.setRowCuts(3);
3438                                            probing.setUsingObjective(true);
3439                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3440                                            cbcModel->cutGenerator(0)->setTiming(true);
3441
3442                                            CglGomory gomory;
3443                                            gomory.setLimitAtRoot(512);
3444                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3445                                            cbcModel->cutGenerator(1)->setTiming(true);
3446
3447                                            CglKnapsackCover knapsackCover;
3448                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3449                                            cbcModel->cutGenerator(2)->setTiming(true);
3450
3451                                            CglRedSplit redSplit;
3452                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3453                                            cbcModel->cutGenerator(3)->setTiming(true);
3454
3455                                            CglClique clique;
3456                                            clique.setStarCliqueReport(false);
3457                                            clique.setRowCliqueReport(false);
3458                                            clique.setMinViolation(0.1);
3459                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3460                                            cbcModel->cutGenerator(4)->setTiming(true);
3461
3462                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3463                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3464                                            cbcModel->cutGenerator(5)->setTiming(true);
3465
3466                                            CglFlowCover flowCover;
3467                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3468                                            cbcModel->cutGenerator(6)->setTiming(true);
3469
3470                                            CglTwomir twomir;
3471                                            twomir.setMaxElements(250);
3472                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3473                                            cbcModel->cutGenerator(7)->setTiming(true);
3474
3475                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3476                                            heuristicFPump.setWhen(13);
3477                                            heuristicFPump.setMaximumPasses(20);
3478                                            heuristicFPump.setMaximumRetries(7);
3479                                            heuristicFPump.setHeuristicName("feasibility pump");
3480                                            heuristicFPump.setInitialWeight(1);
3481                                            heuristicFPump.setFractionSmall(0.6);
3482                                            cbcModel->addHeuristic(&heuristicFPump);
3483
3484                                            CbcRounding rounding(*cbcModel);
3485                                            rounding.setHeuristicName("rounding");
3486                                            cbcModel->addHeuristic(&rounding);
3487
3488                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3489                                            heuristicLocal.setHeuristicName("combine solutions");
3490                                            heuristicLocal.setSearchType(1);
3491                                            heuristicLocal.setFractionSmall(0.6);
3492                                            cbcModel->addHeuristic(&heuristicLocal);
3493
3494                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3495                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3496                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3497
3498                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3499                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3500                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3501
3502                                            CbcCompareDefault compare;
3503                                            cbcModel->setNodeComparison(compare);
3504                                            cbcModel->setNumberBeforeTrust(5);
3505                                            cbcModel->setSpecialOptions(2);
3506                                            cbcModel->messageHandler()->setLogLevel(1);
3507                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3508                                            cbcModel->setMaximumCutPasses(1);
3509                                            cbcModel->setMinimumDrop(0.05);
3510                                            // For branchAndBound this may help
3511                                            clpModel->defaultFactorizationFrequency();
3512                                            clpModel->setDualBound(1.0001e+08);
3513                                            clpModel->setPerturbation(50);
3514                                            osiclpModel->setSpecialOptions(193);
3515                                            osiclpModel->messageHandler()->setLogLevel(0);
3516                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3517                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3518                                            // You can save some time by switching off message building
3519                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3520
3521                                            // Solve
3522
3523                                            cbcModel->initialSolve();
3524                                            if (clpModel->tightenPrimalBounds() != 0) {
3525#ifndef DISALLOW_PRINTING
3526#ifdef GENERAL_HANDLER_PRINTING
3527                                              sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3528                                              printGeneralMessage(model_,generalPrint);
3529#else
3530                                                std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3531#endif
3532#endif
3533                                                break;
3534                                            }
3535                                            clpModel->dual();  // clean up
3536                                            cbcModel->initialSolve();
3537#ifdef CBC_THREAD
3538                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3539                                            cbcModel->setNumberThreads(numberThreads % 100);
3540                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3541#endif
3542                                            //setCutAndHeuristicOptions(*cbcModel);
3543                                            cbcModel->branchAndBound();
3544                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3545                                            assert (solver3);
3546                                            solution = solver3->bestSolution();
3547                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3548                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3549                                            if (solution) {
3550                                              linkSolver->setBestSolution(solution, solver3->getNumCols());
3551                                            }
3552                                            CbcHeuristicDynamic3 dynamic(model_);
3553                                            dynamic.setHeuristicName("dynamic pass thru");
3554                                            model_.addHeuristic(&dynamic);
3555                                            // if convex
3556                                            if ((linkSolver->specialOptions2()&4) != 0 && solution) {
3557                                                int numberColumns = coinModel->numberColumns();
3558                                                assert (linkSolver->objectiveVariable() == numberColumns);
3559                                                // add OA cut
3560                                                double offset;
3561                                                double * gradient = new double [numberColumns+1];
3562                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3563                                                       numberColumns*sizeof(double));
3564                                                double rhs = 0.0;
3565                                                int * column = new int[numberColumns+1];
3566                                                int n = 0;
3567                                                for (int i = 0; i < numberColumns; i++) {
3568                                                    double value = gradient[i];
3569                                                    if (fabs(value) > 1.0e-12) {
3570                                                        gradient[n] = value;
3571                                                        rhs += value * solution[i];
3572                                                        column[n++] = i;
3573                                                    }
3574                                                }
3575                                                gradient[n] = -1.0;
3576                                                column[n++] = numberColumns;
3577                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3578                                                delete [] gradient;
3579                                                delete [] column;
3580                                            }
3581                                            // could do three way branching round a) continuous b) best solution
3582                                            printf("obj %g\n", bestObjectiveValue);
3583                                            linkSolver->initialSolve();
3584                                        }
3585                                    }
3586                                }
3587#endif
3588#endif
3589                                if (logLevel <= 1)
3590                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3591#ifndef CBC_OTHER_SOLVER
3592                                si->setSpecialOptions(0x40000000);
3593#endif
3594                            }
3595                            if (!miplib) {
3596                                if (!preSolve) {
3597                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3598                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3599                                }
3600                                double time1a = CoinCpuTime();
3601                                OsiSolverInterface * solver = model_.solver();
3602#ifndef CBC_OTHER_SOLVER
3603                                OsiClpSolverInterface * si =
3604                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3605                                if (si)
3606                                    si->setSpecialOptions(si->specialOptions() | 1024);
3607#endif
3608                                model_.initialSolve();
3609#ifndef CBC_OTHER_SOLVER
3610                                ClpSimplex * clpSolver = si->getModelPtr();
3611                                int iStatus = clpSolver->status();
3612                                int iStatus2 = clpSolver->secondaryStatus();
3613                                if (iStatus == 0) {
3614                                    iStatus2 = 0;
3615                                } else if (iStatus == 1) {
3616                                    iStatus = 0;
3617                                    iStatus2 = 1; // say infeasible
3618                                } else if (iStatus == 2) {
3619                                    iStatus = 0;
3620                                    iStatus2 = 7; // say unbounded
3621                                } else if (iStatus == 3) {
3622                                    iStatus = 1;
3623                                    if (iStatus2 == 9)
3624                                        iStatus2 = 4;
3625                                    else
3626                                        iStatus2 = 3; // Use nodes - as closer than solutions
3627                                } else if (iStatus == 4) {
3628                                    iStatus = 2; // difficulties
3629                                    iStatus2 = 0;
3630                                }
3631                                model_.setProblemStatus(iStatus);
3632                                model_.setSecondaryStatus(iStatus2);
3633                                si->setWarmStart(NULL);
3634                                int returnCode = callBack(&model_, 1);
3635                                if (returnCode) {
3636                                    // exit if user wants
3637                                    delete babModel_;
3638                                    babModel_ = NULL;
3639                                    return returnCode;
3640                                }
3641                                if (clpSolver->status() > 0) {
3642                                    // and in babModel if exists
3643                                    if (babModel_) {
3644                                        babModel_->setProblemStatus(iStatus);
3645                                        babModel_->setSecondaryStatus(iStatus2);
3646                                    }
3647                                    if (!noPrinting_) {
3648                                        iStatus = clpSolver->status();
3649                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3650                                                              "difficulties", "other"
3651                                                             };
3652                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3653                                                msg[iStatus-1], CoinCpuTime() - time1a);
3654                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3655                                        << generalPrint
3656                                        << CoinMessageEol;
3657                                    }
3658                                    break;
3659                                }
3660                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3661#elif CBC_OTHER_SOLVER==1
3662#endif
3663                                if (!noPrinting_) {
3664                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3665                                            solver->getObjValue(), CoinCpuTime() - time1a);
3666                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3667                                    << generalPrint
3668                                    << CoinMessageEol;
3669                                }
3670                                if (model_.getMaximumNodes() == -987654321) {
3671                                    // See if No objective!
3672                                    int numberColumns = clpSolver->getNumCols();
3673                                    const double * obj = clpSolver->getObjCoefficients();
3674                                    const double * lower = clpSolver->getColLower();
3675                                    const double * upper = clpSolver->getColUpper();
3676                                    int nObj = 0;
3677                                    for (int i = 0; i < numberColumns; i++) {
3678                                        if (upper[i] > lower[i] && obj[i])
3679                                            nObj++;
3680                                    }
3681                                    if (!nObj) {
3682                                        printf("************No objective!!\n");
3683                                        model_.setMaximumSolutions(1);
3684                                        // Column copy
3685                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3686                                        //const double * element = matrixByCol.getElements();
3687                                        //const int * row = matrixByCol.getIndices();
3688                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3689                                        const int * columnLength = matrixByCol.getVectorLengths();
3690                                        for (int i = 0; i < numberColumns; i++) {
3691                                            double value = (CoinDrand48() + 0.5) * 10000;
3692                                            value = 10;
3693                                            value *= columnLength[i];
3694                                            int iValue = static_cast<int> (value) / 10;
3695                                            //iValue=1;
3696                                            clpSolver->setObjCoeff(i, iValue);
3697                                        }
3698                                    }
3699                                }
3700#ifndef CBC_OTHER_SOLVER
3701                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3702#ifndef DISALLOW_PRINTING
3703#ifdef GENERAL_HANDLER_PRINTING
3704                                  sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3705                                  printGeneralMessage(model_,generalPrint);
3706#else
3707                                    std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl;
3708#endif
3709#endif
3710                                    model_.setProblemStatus(0);
3711                                    model_.setSecondaryStatus(1);
3712                                    // and in babModel if exists
3713                                    if (babModel_) {
3714                                        babModel_->setProblemStatus(0);
3715                                        babModel_->setSecondaryStatus(1);
3716                                    }
3717                                    break;
3718                                }
3719                                if (clpSolver->dualBound() == 1.0e10) {
3720                                    ClpSimplex temp = *clpSolver;
3721                                    temp.setLogLevel(0);
3722                                    temp.dual(0, 7);
3723                                    // user did not set - so modify
3724                                    // get largest scaled away from bound
3725                                    double largest = 1.0e-12;
3726                                    double largestScaled = 1.0e-12;
3727                                    int numberRows = temp.numberRows();
3728                                    const double * rowPrimal = temp.primalRowSolution();
3729                                    const double * rowLower = temp.rowLower();
3730                                    const double * rowUpper = temp.rowUpper();
3731                                    const double * rowScale = temp.rowScale();
3732                                    int iRow;
3733                                    for (iRow = 0; iRow < numberRows; iRow++) {
3734                                        double value = rowPrimal[iRow];
3735                                        double above = value - rowLower[iRow];
3736                                        double below = rowUpper[iRow] - value;
3737                                        if (above < 1.0e12) {
3738                                            largest = CoinMax(largest, above);
3739                                        }
3740                                        if (below < 1.0e12) {
3741                                            largest = CoinMax(largest, below);
3742                                        }
3743                                        if (rowScale) {
3744                                            double multiplier = rowScale[iRow];
3745                                            above *= multiplier;
3746                                            below *= multiplier;
3747                                        }
3748                                        if (above < 1.0e12) {
3749                                            largestScaled = CoinMax(largestScaled, above);
3750                                        }
3751                                        if (below < 1.0e12) {
3752                                            largestScaled = CoinMax(largestScaled, below);
3753                                        }
3754                                    }
3755
3756                                    int numberColumns = temp.numberColumns();
3757                                    const double * columnPrimal = temp.primalColumnSolution();
3758                                    const double * columnLower = temp.columnLower();
3759                                    const double * columnUpper = temp.columnUpper();
3760                                    const double * columnScale = temp.columnScale();
3761                                    int iColumn;
3762                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3763                                        double value = columnPrimal[iColumn];
3764                                        double above = value - columnLower[iColumn];
3765                                        double below = columnUpper[iColumn] - value;
3766                                        if (above < 1.0e12) {
3767                                            largest = CoinMax(largest, above);
3768                                        }
3769                                        if (below < 1.0e12) {
3770                                            largest = CoinMax(largest, below);
3771                                        }
3772                                        if (columnScale) {
3773                                            double multiplier = 1.0 / columnScale[iColumn];
3774                                            above *= multiplier;
3775                                            below *= multiplier;
3776                                        }
3777                                        if (above < 1.0e12) {
3778                                            largestScaled = CoinMax(largestScaled, above);
3779                                        }
3780                                        if (below < 1.0e12) {
3781                                            largestScaled = CoinMax(largestScaled, below);
3782                                        }
3783                                    }
3784#ifdef COIN_DEVELOP
3785                                    if (!noPrinting_)
3786                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3787                                                  << " unscaled " << largest << std::endl;
3788#endif
3789                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3790                                }
3791                                si->resolve();  // clean up
3792#endif
3793                            }
3794                            // If user made settings then use them
3795                            if (!defaultSettings) {
3796                                OsiSolverInterface * solver = model_.solver();
3797                                if (!doScaling)
3798                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3799#ifndef CBC_OTHER_SOLVER
3800                                OsiClpSolverInterface * si =
3801                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3802                                assert (si != NULL);
3803                                // get clp itself
3804                                ClpSimplex * modelC = si->getModelPtr();
3805                                //if (modelC->tightenPrimalBounds()!=0) {
3806                                //std::cout<<"Problem is infeasible!"<<std::endl;
3807                                //break;
3808                                //}
3809                                // bounds based on continuous
3810                                if (tightenFactor && !complicatedInteger) {
3811                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3812#ifndef DISALLOW_PRINTING
3813#ifdef GENERAL_HANDLER_PRINTING
3814                                      sprintf(generalPrint, "Problem is infeasible!");
3815                                      printGeneralMessage(model_,generalPrint);
3816#else
3817                                        std::cout << "Problem is infeasible!" << std::endl;
3818#endif
3819#endif
3820                                        model_.setProblemStatus(0);
3821                                        model_.setSecondaryStatus(1);
3822                                        // and in babModel if exists
3823                                        if (babModel_) {
3824                                            babModel_->setProblemStatus(0);
3825                                            babModel_->setSecondaryStatus(1);
3826                                        }
3827                                        break;
3828                                    }
3829                                }
3830#endif
3831                            }
3832                            // See if we want preprocessing
3833                            OsiSolverInterface * saveSolver = NULL;
3834                            CglPreProcess process;
3835                            // Say integers in sync
3836                            bool integersOK = true;
3837                            delete babModel_;
3838                            babModel_ = new CbcModel(model_);
3839#ifndef CBC_OTHER_SOLVER
3840                            int numberChanged = 0;
3841                            OsiSolverInterface * solver3 = clpSolver->clone();
3842                            babModel_->assignSolver(solver3);
3843                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3844                            if (clpSolver2->messageHandler()->logLevel())
3845                                clpSolver2->messageHandler()->setLogLevel(1);
3846                            if (logLevel > -1)
3847                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3848                            lpSolver = clpSolver2->getModelPtr();
3849                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3850                                // User did not touch preset
3851                                int numberRows = lpSolver->numberRows();
3852                                const int cutoff1 = 10000;
3853                                const int cutoff2 = 100000;
3854                                const int base = 75;
3855                                const int freq0 = 50;
3856                                const int freq1 = 200;
3857                                const int freq2 = 400;
3858                                const int maximum = 1000;
3859                                int frequency;
3860                                if (numberRows < cutoff1)
3861                                    frequency = base + numberRows / freq0;
3862                                else if (numberRows < cutoff2)
3863                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3864                                else
3865                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3866                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3867                            }
3868#elif CBC_OTHER_SOLVER==1
3869                            OsiSolverInterface * solver3 = model_.solver()->clone();
3870                            babModel_->assignSolver(solver3);
3871#endif
3872                            time2 = CoinCpuTime();
3873                            totalTime += time2 - time1;
3874                            //time1 = time2;
3875                            double timeLeft = babModel_->getMaximumSeconds();
3876                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3877                            if (preProcess == 7) {
3878                                // use strategy instead
3879                                preProcess = 0;
3880                                useStrategy = true;
3881#ifdef COIN_HAS_LINK
3882                                // empty out any cuts
3883                                if (storedAmpl.sizeRowCuts()) {
3884                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3885                                    CglStored temp;
3886                                    storedAmpl = temp;
3887                                }
3888#endif
3889                            }
3890                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3891                              // see whether to switch off preprocessing
3892                              // only allow SOS and integer
3893                              OsiObject ** objects = babModel_->objects();
3894                              int numberObjects = babModel_->numberObjects();
3895                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3896                                CbcSOS * objSOS =
3897                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
3898                                CbcSimpleInteger * objSimpleInteger =
3899                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3900                                if (!objSimpleInteger&&!objSOS) {
3901                                  // find all integers anyway
3902                                  babModel_->findIntegers(true);
3903                                  preProcess=0;
3904                                  break;
3905                                }
3906                              }
3907                            }
3908                            if (type == CBC_PARAM_ACTION_BAB) {
3909                                double limit;
3910                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
3911                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
3912                                        limit*clpSolver->getObjSense())
3913                                    preProcess = 0;
3914                            }
3915                            if (mipStartBefore.size())
3916                              {
3917                                CbcModel tempModel=*babModel_;
3918                                std::vector< std::string > colNames;
3919                                for ( int i=0 ; (i<babModel_->solver()->getNumCols()) ; ++i )
3920                                  colNames.push_back( model_.solver()->getColName(i) );
3921                                std::vector< double > x( babModel_->getNumCols(), 0.0 );
3922                                double obj;
3923                                int status = computeCompleteSolution( &tempModel, colNames, mipStartBefore, &x[0], obj );
3924                                // set cutoff
3925                                if (!status)
3926                                  babModel_->setCutoff(CoinMin(babModel_->getCutoff(),obj+1.0e-4));
3927                              }
3928                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
3929#ifndef CBC_OTHER_SOLVER
3930                                // See if sos from mps file
3931                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
3932                                    // SOS
3933                                    numberSOS = clpSolver->numberSOS();
3934                                    const CoinSet * setInfo = clpSolver->setInfo();
3935                                    sosStart = new int [numberSOS+1];
3936                                    sosType = new char [numberSOS];
3937                                    int i;
3938                                    int nTotal = 0;
3939                                    sosStart[0] = 0;
3940                                    for ( i = 0; i < numberSOS; i++) {
3941                                        int type = setInfo[i].setType();
3942                                        int n = setInfo[i].numberEntries();
3943                                        sosType[i] = static_cast<char>(type);
3944                                        nTotal += n;
3945                                        sosStart[i+1] = nTotal;
3946                                    }
3947                                    sosIndices = new int[nTotal];
3948                                    sosReference = new double [nTotal];
3949                                    for (i = 0; i < numberSOS; i++) {
3950                                        int n = setInfo[i].numberEntries();
3951                                        const int * which = setInfo[i].which();
3952                                        const double * weights = setInfo[i].weights();
3953                                        int base = sosStart[i];
3954                                        for (int j = 0; j < n; j++) {
3955                                            int k = which[j];
3956                                            sosIndices[j+base] = k;
3957                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
3958                                        }
3959                                    }
3960                                }
3961#endif
3962                                saveSolver = babModel_->solver()->clone();
3963                                /* Do not try and produce equality cliques and
3964                                   do up to 10 passes */
3965                                OsiSolverInterface * solver2;
3966                                {
3967                                    // Tell solver we are in Branch and Cut
3968                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
3969                                    // Default set of cut generators
3970                                    CglProbing generator1;
3971                                    generator1.setUsingObjective(1);
3972                                    generator1.setMaxPass(1);
3973                                    generator1.setMaxPassRoot(1);
3974                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
3975                                    generator1.setMaxElements(100);
3976                                    generator1.setMaxElementsRoot(200);
3977                                    generator1.setMaxLookRoot(50);
3978                                    if (saveSolver->getNumCols() > 3000)
3979                                        generator1.setMaxProbeRoot(123);
3980                                    generator1.setRowCuts(3);
3981                                    if ((tunePreProcess&1) != 0) {
3982                                        // heavy probing
3983                                        generator1.setMaxPassRoot(2);
3984                                        generator1.setMaxElements(300);
3985                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
3986                                    }
3987                                    if ((babModel_->specialOptions()&65536) != 0)
3988                                        process.setOptions(1);
3989                                    // Add in generators
3990                                    if ((model_.moreSpecialOptions()&65536)==0)
3991                                      process.addCutGenerator(&generator1);
3992                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
3993                                    process.passInMessageHandler(babModel_->messageHandler());
3994                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
3995#ifdef COIN_HAS_ASL
3996                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
3997                                        // SOS
3998                                        numberSOS = info.numberSos;
3999                                        sosStart = info.sosStart;
4000                                        sosIndices = info.sosIndices;
4001                                    }
4002#endif
4003                                    if (numberSOS && doSOS) {
4004                                        // SOS
4005                                        int numberColumns = saveSolver->getNumCols();
4006                                        char * prohibited = new char[numberColumns];
4007                                        memset(prohibited, 0, numberColumns);
4008                                        int n = sosStart[numberSOS];
4009                                        for (int i = 0; i < n; i++) {
4010                                            int iColumn = sosIndices[i];
4011                                            prohibited[iColumn] = 1;
4012                                        }
4013                                        process.passInProhibited(prohibited, numberColumns);
4014                                        delete [] prohibited;
4015                                    }
4016                                    if (0) {
4017                                     
4018                                      // Special integers
4019                                      int numberColumns = saveSolver->getNumCols();
4020                                      char * prohibited = new char[numberColumns];
4021                                      memset(prohibited, 0, numberColumns);
4022                                      const CoinPackedMatrix * matrix = saveSolver->getMatrixByCol();
4023                                      const int * columnLength = matrix->getVectorLengths();
4024                                      int numberProhibited=0;
4025                                      for (int iColumn = numberColumns-1; iColumn >=0; iColumn--) {
4026                                        if (!saveSolver->isInteger(iColumn)||
4027                                            columnLength[iColumn]>1)
4028                                          break;
4029                                        numberProhibited++;
4030                                        prohibited[iColumn] = 1;
4031                                      }
4032                                      if (numberProhibited) {
4033                                        process.passInProhibited(prohibited, numberColumns);
4034                                        printf("**** Treating last %d integers as special - give high priority?\n",numberProhibited);
4035                                      }
4036                                      delete [] prohibited;
4037                                    }
4038                                    if (!model_.numberObjects() && true) {
4039                                        /* model may not have created objects
4040                                           If none then create
4041                                        */
4042                                        model_.findIntegers(true);
4043                                    }
4044                                    if (model_.numberObjects()) {
4045                                        OsiObject ** oldObjects = babModel_->objects();
4046                                        int numberOldObjects = babModel_->numberObjects();
4047                                        // SOS
4048                                        int numberColumns = saveSolver->getNumCols();
4049                                        char * prohibited = new char[numberColumns];
4050                                        memset(prohibited, 0, numberColumns);
4051                                        int numberProhibited = 0;
4052                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4053                                            CbcSOS * obj =
4054                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
4055                                            if (obj) {
4056                                                int n = obj->numberMembers();
4057                                                const int * which = obj->members();
4058                                                for (int i = 0; i < n; i++) {
4059                                                    int iColumn = which[i];
4060                                                    prohibited[iColumn] = 1;
4061                                                    numberProhibited++;
4062                                                }
4063                                            }
4064                                            CbcLotsize * obj2 =
4065                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
4066                                            if (obj2) {
4067                                                int iColumn = obj2->columnNumber();
4068                                                prohibited[iColumn] = 1;
4069                                                numberProhibited++;
4070                                            }
4071                                        }
4072                                        if (numberProhibited)
4073                                            process.passInProhibited(prohibited, numberColumns);
4074                                        delete [] prohibited;
4075                                    }
4076                                    int numberPasses = 10;
4077                                    if (tunePreProcess >= 1000000) {
4078                                        numberPasses = (tunePreProcess / 1000000) - 1;
4079                                        tunePreProcess = tunePreProcess % 1000000;
4080                                    } else if (tunePreProcess >= 10000) {
4081                                        numberPasses = (tunePreProcess / 10000) - 1;
4082                                        tunePreProcess = tunePreProcess % 10000;
4083                                    }
4084#ifndef CBC_OTHER_SOLVER
4085                                    if (doSprint > 0) {
4086                                        // Sprint for primal solves
4087                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
4088                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
4089                                        int numberPasses = 5;
4090                                        int options[] = {0, 3, 0, 0, 0, 0};
4091                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
4092                                        extraInfo[1] = doSprint;
4093                                        int independentOptions[] = {0, 0, 3};
4094                                        ClpSolve clpSolve(method, presolveType, numberPasses,
4095                                                          options, extraInfo, independentOptions);
4096                                        // say use in OsiClp
4097                                        clpSolve.setSpecialOption(6, 1);
4098                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4099                                        osiclp->setSolveOptions(clpSolve);
4100                                        osiclp->setHintParam(OsiDoDualInResolve, false);
4101                                        // switch off row copy
4102                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
4103                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
4104                                    }
4105#endif
4106#ifndef CBC_OTHER_SOLVER
4107                                    {
4108                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4109                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
4110                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
4111                                        //#define CBC_TEMP1
4112#ifdef CBC_TEMP1
4113                                        if (savePerturbation == 50)
4114                                            osiclp->getModelPtr()->setPerturbation(52); // try less
4115#endif
4116                                        if ((model_.moreSpecialOptions()&65536)!=0)
4117                                          process.setOptions(2+4+8); // no cuts
4118                                        cbcPreProcessPointer = & process;
4119                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4120                                                                               tunePreProcess);
4121                                        /*solver2->writeMps("after");
4122                                          saveSolver->writeMps("before");*/
4123                                        osiclp->getModelPtr()->setPerturbation(savePerturbation);
4124                                    }
4125#elif CBC_OTHER_SOLVER==1
4126                                    cbcPreProcessPointer = & process;
4127                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4128                                                                           tunePreProcess);
4129#endif
4130                                    integersOK = false; // We need to redo if CbcObjects exist
4131                                    // Tell solver we are not in Branch and Cut
4132                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4133                                    if (solver2)
4134                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4135                                }
4136#ifdef COIN_HAS_ASL
4137                                if (!solver2 && statusUserFunction_[0]) {
4138                                    // infeasible
4139                                    info.problemStatus = 1;
4140                                    info.objValue = 1.0e100;
4141                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
4142                                    info.primalSolution = NULL;
4143                                    info.dualSolution = NULL;
4144                                    break;
4145                                }
4146#endif
4147                                if (!noPrinting_) {
4148                                    if (!solver2) {
4149                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
4150                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4151                                        << generalPrint
4152                                        << CoinMessageEol;
4153                                    } else {
4154                                        //printf("processed model has %d rows, %d columns and %d elements\n",
4155                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
4156                                    }
4157                                }
4158                                if (!solver2) {
4159                                    // say infeasible for solution
4160                                    integerStatus = 6;
4161                                    model_.setProblemStatus(0);
4162                                    model_.setSecondaryStatus(1);
4163                                    babModel_->setProblemStatus(0);
4164                                    babModel_->setSecondaryStatus(1);
4165                                } else {
4166                                    statistics_nprocessedrows = solver2->getNumRows();
4167                                    statistics_nprocessedcols = solver2->getNumCols();
4168                                    model_.setProblemStatus(-1);
4169                                    babModel_->setProblemStatus(-1);
4170                                }
4171                                int returnCode = callBack(babModel_, 2);
4172                                if (returnCode) {
4173                                    // exit if user wants
4174                                    delete babModel_;
4175                                    babModel_ = NULL;
4176                                    return returnCode;
4177                                }
4178                                if (!solver2)
4179                                    break;
4180                                if (model_.bestSolution()) {
4181                                    // need to redo - in case no better found in BAB
4182                                    // just get integer part right
4183                                    const int * originalColumns = process.originalColumns();
4184                                    int numberColumns = solver2->getNumCols();
4185                                    double * bestSolution = babModel_->bestSolution();
4186                                    const double * oldBestSolution = model_.bestSolution();
4187                                    for (int i = 0; i < numberColumns; i++) {
4188                                        int jColumn = originalColumns[i];
4189                                        bestSolution[i] = oldBestSolution[jColumn];
4190                                    }
4191                                }
4192                                //solver2->resolve();
4193                                if (preProcess == 2) {
4194                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4195#if 1
4196                                    ClpSimplex * lpSolver = 
4197                                      clpSolver2->getModelPtr();
4198                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
4199#else
4200                                    // put back names
4201                                    ClpSimplex lpSolver(*clpSolver2->getModelPtr());
4202                                    //OsiClpSolverInterface * originalSolver = dynamic_cast< OsiClpSolverInterface*> (olver);
4203                                    ClpSimplex * originalLp = clpSolver->getModelPtr();
4204                                    const int * originalColumns = process.originalColumns();
4205                                    int numberColumns = lpSolver.getNumCols();
4206                                    for (int i = 0; i < numberColumns; i++) {
4207                                      int jColumn = originalColumns[i];
4208                                      std::string name = originalLp->getColumnName(jColumn);
4209                                      lpSolver.setColumnName(i,name);
4210                                    }
4211                                    lpSolver.writeMps("presolved.mps", 0, 1, lpSolver.optimizationDirection());
4212#endif
4213                                    printf("Preprocessed model (minimization) on presolved.mps\n");
4214                                }
4215                                {
4216                                    // look at new integers
4217                                    int numberOriginalColumns =
4218                                        process.originalModel()->getNumCols();
4219                                    const int * originalColumns = process.originalColumns();
4220                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4221                                    int numberColumns = osiclp2->getNumCols();
4222                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4223                                    for (int i = 0; i < numberColumns; i++) {
4224                                        int iColumn = originalColumns[i];
4225                                        if (iColumn < numberOriginalColumns) {
4226                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
4227                                                osiclp2->setOptionalInteger(i); // say optional
4228                                        }
4229                                    }
4230                                }
4231                                // we have to keep solver2 so pass clone
4232                                solver2 = solver2->clone();
4233                                // see if extra variables wanted
4234                                int threshold = 
4235                                  parameters_[whichParam(CBC_PARAM_INT_EXTRA_VARIABLES, numberParameters_, parameters_)].intValue();
4236                                if (threshold) {
4237                                  int numberColumns = solver2->getNumCols();
4238                                  int highPriority=0;
4239                                  /*
4240                                    normal - no priorities
4241                                    >10000 equal high priority
4242                                    >20000 higher priority for higher cost
4243                                  */
4244                                  if (threshold>10000) {
4245                                    highPriority=threshold/10000;
4246                                    threshold -= 10000*highPriority;
4247                                  }
4248                                  const double * columnLower = solver2->getColLower();
4249                                  const double * columnUpper = solver2->getColUpper();
4250                                  const double * objective = solver2->getObjCoefficients();
4251                                  int numberIntegers = 0;
4252                                  int numberBinary = 0;
4253                                  int numberTotalIntegers=0;
4254                                  double * obj = new double [numberColumns];
4255                                  int * which = new int [numberColumns];
4256                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4257                                    if (solver2->isInteger(iColumn)) {
4258                                      numberTotalIntegers++;
4259                                      if (columnUpper[iColumn] > columnLower[iColumn]) {
4260                                        numberIntegers++;
4261                                        if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1)
4262                                          numberBinary++;
4263                                      }
4264                                    }
4265                                  }
4266                                  int numberSort=0;
4267                                  int numberZero=0;
4268                                  int numberZeroContinuous=0;
4269                                  int numberDifferentObj=0;
4270                                  int numberContinuous=0;
4271                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4272                                    if (columnUpper[iColumn] > columnLower[iColumn]) {
4273                                      if (solver2->isInteger(iColumn)) {
4274                                        if (!objective[iColumn]) {
4275                                          numberZero++;
4276                                        } else {
4277                                          obj[numberSort]= fabs(objective[iColumn]);
4278                                          which[numberSort++]=iColumn;
4279                                        }
4280                                      } else if (objective[iColumn]) {
4281                                        numberContinuous++;
4282                                      } else {
4283                                        numberZeroContinuous++;
4284                                      }
4285                                    }
4286                                  }
4287                                  CoinSort_2(obj,obj+numberSort,which);
4288                                  double last=obj[0];
4289                                  for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4290                                    if (fabs(obj[jColumn]-last)>1.0e-12) {
4291                                      numberDifferentObj++;
4292                                      last=obj[jColumn];
4293                                    }
4294                                  }
4295                                  numberDifferentObj++;
4296                                  sprintf(generalPrint,"Problem has %d integers (%d of which binary) and %d continuous",
4297                                         numberIntegers,numberBinary,numberColumns-numberIntegers);
4298                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4299                                    << generalPrint
4300                                    << CoinMessageEol;
4301                                  if (numberColumns>numberIntegers) {
4302                                    sprintf(generalPrint,"%d continuous have nonzero objective, %d have zero objective",
4303                                            numberContinuous,numberZeroContinuous);
4304                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4305                                      << generalPrint
4306                                      << CoinMessageEol;
4307                                  }
4308                                  sprintf(generalPrint,"%d integer have nonzero objective, %d have zero objective, %d different nonzero (taking abs)",
4309                                          numberSort,numberZero,numberDifferentObj);
4310                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4311                                    << generalPrint
4312                                    << CoinMessageEol;
4313                                  if (numberDifferentObj<=threshold + (numberZero) ? 1 : 0 && numberDifferentObj) {
4314                                    int * backward=NULL;
4315                                    if (highPriority) {
4316                                      newPriorities = new int [numberTotalIntegers+numberDifferentObj+numberColumns];
4317                                      backward=newPriorities+numberTotalIntegers+numberDifferentObj;
4318                                      numberTotalIntegers=0;
4319                                      for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4320                                        if (solver2->isInteger(iColumn)) {
4321                                          backward[iColumn]=numberTotalIntegers;
4322                                          newPriorities[numberTotalIntegers++]=10000;
4323                                        }
4324                                      }
4325                                    }
4326                                    int iLast=0;
4327                                    double last=obj[0];
4328                                    for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4329                                      if (fabs(obj[jColumn]-last)>1.0e-12) {
4330                                        sprintf(generalPrint,"%d variables have objective of %g",
4331                                               jColumn-iLast,last);
4332                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4333                                          << generalPrint
4334                                          << CoinMessageEol;
4335                                        iLast=jColumn;
4336                                        last=obj[jColumn];
4337                                      }
4338                                    }
4339                                    sprintf(generalPrint,"%d variables have objective of %g",
4340                                           numberSort-iLast,last);
4341                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4342                                      << generalPrint
4343                                      << CoinMessageEol;
4344                                    int spaceNeeded=numberSort+numberDifferentObj;
4345                                    int * columnAdd = new int[spaceNeeded+numberDifferentObj+1];
4346                                    double * elementAdd = new double[spaceNeeded];
4347                                    int * rowAdd = new int[numberDifferentObj+1];
4348                                    double * objectiveNew = new double[3*numberDifferentObj];
4349                                    double * lowerNew = objectiveNew+numberDifferentObj;
4350                                    double * upperNew = lowerNew+numberDifferentObj;
4351                                    memset(columnAdd+spaceNeeded,0,
4352                                           (numberDifferentObj+1)*sizeof(int));
4353                                    iLast=0;
4354                                    last=obj[0];
4355                                    numberDifferentObj=0;
4356                                    int priorityLevel=9999;
4357                                    int numberElements=0;
4358                                    rowAdd[0]=0;
4359                                    for (int jColumn = 1; jColumn < numberSort+1; jColumn++) {
4360                                      if (jColumn==numberSort||fabs(obj[jColumn]-last)>1.0e-12) {
4361                                        // not if just one
4362                                        if (jColumn-iLast>1) {
4363                                          // do priority
4364                                          if (highPriority==1) {
4365                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4366                                              = 500;
4367                                          } else if (highPriority==2) {
4368                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4369                                              = priorityLevel;
4370                                            priorityLevel--;
4371                                          }
4372                                          int iColumn=which[iLast];
4373                                          objectiveNew[numberDifferentObj]=objective[iColumn];
4374                                          double lower=0.0;
4375                                          double upper=0.0;
4376                                          for (int kColumn=iLast;kColumn<jColumn;kColumn++) {
4377                                            iColumn=which[kColumn];
4378                                            solver2->setObjCoeff(iColumn,0.0);
4379                                            double lowerValue=columnLower[iColumn];
4380                                            double upperValue=columnUpper[iColumn];
4381                                            double elementValue=-1.0;
4382                                            if (objectiveNew[numberDifferentObj]*objective[iColumn]<0.0) {
4383                                              lowerValue=-columnUpper[iColumn];
4384                                              upperValue=-columnLower[iColumn];
4385                                              elementValue=1.0;
4386                                            }
4387                                            columnAdd[numberElements]=iColumn;
4388                                            elementAdd[numberElements++]=elementValue;
4389                                            if (lower!=-COIN_DBL_MAX) {
4390                                              if (lowerValue!=-COIN_DBL_MAX)
4391                                                lower += lowerValue;
4392                                              else
4393                                                lower=-COIN_DBL_MAX;
4394                                            }
4395                                            if (upper!=COIN_DBL_MAX) {
4396                                              if (upperValue!=COIN_DBL_MAX)
4397                                                upper += upperValue;
4398                                              else
4399                                                upper=COIN_DBL_MAX;
4400                                            }
4401                                          }
4402                                          columnAdd[numberElements]=numberColumns+numberDifferentObj;
4403                                          elementAdd[numberElements++]=1.0;
4404                                          lowerNew[numberDifferentObj]=lower;
4405                                          upperNew[numberDifferentObj]=upper;
4406                                          numberDifferentObj++;
4407                                          rowAdd[numberDifferentObj]=numberElements;
4408                                        } else if (highPriority) {
4409                                          // just one
4410                                          // do priority
4411                                          int iColumn=which[iLast];
4412                                          int iInt=backward[iColumn];
4413                                          if (highPriority==1) {
4414                                            newPriorities[iInt] = 500;
4415                                          } else {
4416                                            newPriorities[iInt] = priorityLevel;
4417                                            priorityLevel--;
4418                                          }
4419                                        }
4420                                        if (jColumn<numberSort) {
4421                                          iLast=jColumn;
4422                                          last=obj[jColumn];
4423                                        }
4424                                      }
4425                                    }
4426                                    if (numberDifferentObj) {
4427                                      // add columns
4428                                      solver2->addCols(numberDifferentObj, 
4429                                                       columnAdd+spaceNeeded, NULL, NULL,
4430                                                       lowerNew, upperNew,objectiveNew);
4431                                      // add constraints and make integer if all integer in group
4432                                      for (int iObj=0; iObj < numberDifferentObj; iObj++) {
4433                                        lowerNew[iObj]=0.0;
4434                                        upperNew[iObj]=0.0;
4435                                        solver2->setInteger(numberColumns+iObj);
4436                                      }
4437                                      solver2->addRows(numberDifferentObj, 
4438                                                       rowAdd,columnAdd,elementAdd,
4439                                                       lowerNew, upperNew);
4440                                      sprintf(generalPrint,"Replacing model - %d new variables",numberDifferentObj);
4441                                      generalMessageHandler->message(CLP_GENERAL, generalMessages)
4442                                        << generalPrint
4443                                        << CoinMessageEol;
4444                                      truncateColumns=numberColumns;
4445                                    }
4446                                    delete [] columnAdd;
4447                                    delete [] elementAdd;
4448                                    delete [] rowAdd;
4449                                    delete [] objectiveNew;
4450                                  }
4451                                  delete [] which;
4452                                  delete [] obj;
4453                                }
4454                                babModel_->assignSolver(solver2);
4455                                babModel_->setOriginalColumns(process.originalColumns(),
4456                                                              truncateColumns);
4457                                babModel_->initialSolve();
4458                                babModel_->setMaximumSeconds(timeLeft - (CoinCpuTime() - time2));
4459                            }
4460                            // now tighten bounds
4461                            if (!miplib) {
4462#ifndef CBC_OTHER_SOLVER
4463                                OsiClpSolverInterface * si =
4464                                    dynamic_cast<OsiClpSolverInterface *>(babModel_->solver()) ;
4465                                assert (si != NULL);
4466                                // get clp itself
4467                                ClpSimplex * modelC = si->getModelPtr();
4468                                //if (noPrinting_)
4469                                //modelC->setLogLevel(0);
4470                                if (!complicatedInteger && modelC->tightenPrimalBounds() != 0) {
4471#ifndef DISALLOW_PRINTING
4472#ifdef GENERAL_HANDLER_PRINTING
4473                                  sprintf(generalPrint, "Problem is infeasible!");
4474                                  printGeneralMessage(model_,generalPrint);
4475#else
4476                                    std::cout << "Problem is infeasible!" << std::endl;
4477#endif
4478#endif
4479                                    model_.setProblemStatus(0);
4480                                    model_.setSecondaryStatus(1);
4481                                    // say infeasible for solution
4482                                    integerStatus = 6;
4483                                    // and in babModel_ if exists
4484                                    if (babModel_) {
4485                                        babModel_->setProblemStatus(0);
4486                                        babModel_->setSecondaryStatus(1);
4487                                    }
4488                                    break;
4489                                }
4490                                si->resolve();
4491#elif CBC_OTHER_SOLVER==1
4492#endif
4493                            }
4494                            if (debugValues) {
4495                                // for debug
4496                                std::string problemName ;
4497                                babModel_->solver()->getStrParam(OsiProbName, problemName) ;
4498                                babModel_->solver()->activateRowCutDebugger(problemName.c_str()) ;
4499                                twomirGen.probname_ = CoinStrdup(problemName.c_str());
4500                                // checking seems odd
4501                                //redsplitGen.set_given_optsol(babModel_->solver()->getRowCutDebuggerAlways()->optimalSolution(),
4502                                //                         babModel_->getNumCols());
4503                            }
4504                            int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
4505                            //#ifdef COIN_HAS_ASL
4506#ifndef JJF_ONE
4507                            // If linked then see if expansion wanted
4508                            {
4509                                OsiSolverLink * solver3 = dynamic_cast<OsiSolverLink *> (babModel_->solver());
4510                                int options = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() / 10000;
4511                                if (solver3 || (options&16) != 0) {
4512                                    if (options) {
4513                                        /*
4514                                          1 - force mini branch and bound
4515                                          2 - set priorities high on continuous
4516                                          4 - try adding OA cuts
4517                                          8 - try doing quadratic linearization
4518                                          16 - try expanding knapsacks
4519                                        */
4520                                        if ((options&16)) {
4521                                            int numberColumns = saveCoinModel.numberColumns();
4522                                            int numberRows = saveCoinModel.numberRows();
4523                                            whichColumn = new int[numberColumns];
4524                                            knapsackStart = new int[numberRows+1];
4525                                            knapsackRow = new int[numberRows];
4526                                            numberKnapsack = 10000;
4527                                            int extra1 = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
4528                                            int extra2 = parameters_[whichParam(CBC_PARAM_INT_EXTRA2, numberParameters_, parameters_)].intValue();
4529                                            int logLevel = parameters_[log].intValue();
4530                                            OsiSolverInterface * solver = expandKnapsack(saveCoinModel, whichColumn, knapsackStart,
4531                                                                          knapsackRow, numberKnapsack,
4532                                                                          storedAmpl, logLevel, extra1, extra2,
4533                                                                          saveTightenedModel);
4534                                            if (solver) {
4535#ifndef CBC_OTHER_SOLVER
4536                                                clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
4537                                                assert (clpSolver);
4538                                                lpSolver = clpSolver->getModelPtr();
4539#endif
4540                                                babModel_->assignSolver(solver);
4541                                                testOsiOptions = 0;
4542                                                // allow gomory
4543                                                complicatedInteger = 0;
4544#ifdef COIN_HAS_ASL
4545                                                // Priorities already done
4546                                                free(info.priorities);
4547                                                info.priorities = NULL;
4548#endif
4549                                            } else {
4550                                                numberKnapsack = 0;
4551                                                delete [] whichColumn;
4552                                                delete [] knapsackStart;
4553                                                delete [] knapsackRow;
4554                                                whichColumn = NULL;
4555                                                knapsackStart = NULL;
4556                                                knapsackRow = NULL;
4557                                            }
4558                                        }
4559                                    }
4560                                }
4561                            }
4562#endif
4563                            if (useCosts && testOsiOptions < 0) {
4564                                int numberColumns = babModel_->getNumCols();
4565                                int * sort = new int[numberColumns];
4566                                double * dsort = new double[numberColumns];
4567                                int * priority = new int [numberColumns];
4568                                const double * objective = babModel_->getObjCoefficients();
4569                                const double * lower = babModel_->getColLower() ;
4570                                const double * upper = babModel_->getColUpper() ;
4571                                const CoinPackedMatrix * matrix = babModel_->solver()->getMatrixByCol();
4572                                const int * columnLength = matrix->getVectorLengths();
4573                                int iColumn;
4574                                int n = 0;
4575                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4576                                    if (babModel_->isInteger(iColumn)) {
4577                                        sort[n] = n;
4578                                        if (useCosts == 1)
4579                                            dsort[n++] = -fabs(objective[iColumn]);
4580                                        else if (useCosts == 2)
4581                                            dsort[n++] = iColumn;
4582                                        else if (useCosts == 3)
4583                                            dsort[n++] = upper[iColumn] - lower[iColumn];
4584                                        else if (useCosts == 4)
4585                                            dsort[n++] = -(upper[iColumn] - lower[iColumn]);
4586                                        else if (useCosts == 5)
4587                                            dsort[n++] = -columnLength[iColumn];
4588                                        else if (useCosts == 6)
4589                                            dsort[n++] = (columnLength[iColumn]==1) ? -1.0 : 0.0;
4590                                        else if (useCosts == 7)
4591                                            dsort[n++] = (objective[iColumn]) ? -1.0 : 0.0;
4592                                    }
4593                                }
4594                                CoinSort_2(dsort, dsort + n, sort);
4595                                int level = 0;
4596                                double last = -1.0e100;
4597                                for (int i = 0; i < n; i++) {
4598                                    int iPut = sort[i];
4599                                    if (dsort[i] != last) {
4600                                        level++;
4601                                        last = dsort[i];
4602                                    }
4603                                    priority[iPut] = level;
4604                                }
4605                                if(newPriorities ) {
4606                                  // get rid of
4607                                  delete [] newPriorities;
4608                                  newPriorities = NULL;
4609                                }
4610                                babModel_->passInPriorities( priority, false);
4611                                integersOK = true;
4612                                delete [] priority;
4613                                delete [] sort;
4614                                delete [] dsort;
4615                            }
4616                            // Set up heuristics
4617                            doHeuristics(babModel_, ((!miplib) ? 1 : 10), parameters_,
4618                                         numberParameters_, noPrinting_, initialPumpTune);
4619                            if (!miplib) {
4620                                if (parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].currentOptionAsInteger()) {
4621                                    CbcTreeLocal localTree(babModel_, NULL, 10, 0, 0, 10000, 2000);
4622                                    babModel_->passInTreeHandler(localTree);
4623                                }
4624                            }
4625                            if (type == CBC_PARAM_ACTION_MIPLIB) {
4626                                if (babModel_->numberStrong() == 5 && babModel_->numberBeforeTrust() == 5)
4627                                    babModel_->setNumberBeforeTrust(10);
4628                            }
4629                            int experimentFlag = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
4630                                                             parameters_)].intValue();
4631                            int strategyFlag = parameters_[whichParam(CBC_PARAM_INT_STRATEGY, numberParameters_,
4632                                                           parameters_)].intValue();
4633                            int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag);
4634                            // add cut generators if wanted
4635                            int switches[30];
4636                            int accuracyFlag[30];
4637                            char doAtEnd[30];
4638                            memset(doAtEnd,0,30);
4639                            int numberGenerators = 0;
4640                            int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1};
4641                            int maximumSlowPasses = 
4642                              parameters_[whichParam(CBC_PARAM_INT_MAX_SLOW_CUTS, 
4643                                                     numberParameters_, parameters_)].intValue();
4644                            if (probingAction) {
4645                                int numberColumns = babModel_->solver()->getNumCols();
4646                                if (probingAction > 7) {
4647                                    probingGen.setMaxElements(numberColumns);
4648                                    probingGen.setMaxElementsRoot(numberColumns);
4649                                }
4650                                probingGen.setMaxProbeRoot(CoinMin(2000, numberColumns));
4651                                probingGen.setMaxProbeRoot(123);
4652                                probingGen.setMaxProbe(123);
4653                                probingGen.setMaxLookRoot(20);
4654                                if (probingAction == 7 || probingAction == 9)
4655                                    probingGen.setRowCuts(-3); // strengthening etc just at root
4656                                if (probingAction == 8 || probingAction == 9) {
4657                                    // Number of unsatisfied variables to look at
4658                                    probingGen.setMaxProbeRoot(numberColumns);
4659                                    probingGen.setMaxProbe(numberColumns);
4660                                    // How far to follow the consequences
4661                                    probingGen.setMaxLook(50);
4662                                    probingGen.setMaxLookRoot(50);
4663                                }
4664                                if (probingAction == 10) {
4665                                    probingGen.setMaxPassRoot(2);
4666                                    probingGen.setMaxProbeRoot(numberColumns);
4667                                    probingGen.setMaxLookRoot(100);
4668                                }
4669                                // If 5 then force on
4670                                int iAction = translate[probingAction];
4671                                if (probingAction == 5)
4672                                    iAction = 1;
4673                                babModel_->addCutGenerator(&probingGen, iAction, "Probing");
4674                                accuracyFlag[numberGenerators] = 5;
4675                                switches[numberGenerators++] = 0;
4676                            }
4677                            if (gomoryAction && (complicatedInteger != 1 ||
4678                                                 (gomoryAction == 1 || gomoryAction >= 4))) {
4679                                // try larger limit
4680                                int numberColumns = babModel_->getNumCols();
4681                                if (gomoryAction == 7) {
4682                                    gomoryAction = 4;
4683                                    gomoryGen.setLimitAtRoot(numberColumns);
4684                                    gomoryGen.setLimit(numberColumns);
4685                                } else if (gomoryAction == 8) {
4686                                    gomoryAction = 3;
4687                                    gomoryGen.setLimitAtRoot(numberColumns);
4688                                    gomoryGen.setLimit(200);
4689                                } else if (numberColumns > 5000) {
4690                                    //#define MORE_CUTS2
4691#ifdef MORE_CUTS2
4692                                    // try larger limit
4693                                    gomoryGen.setLimitAtRoot(numberColumns);
4694                                    gomoryGen.setLimit(200);
4695#else
4696                                    gomoryGen.setLimitAtRoot(2000);
4697                                    //gomoryGen.setLimit(200);
4698#endif
4699                                } else {
4700#ifdef MORE_CUTS2
4701                                    // try larger limit
4702                                    gomoryGen.setLimitAtRoot(numberColumns);
4703                                    gomoryGen.setLimit(200);
4704#endif
4705                                }
4706                                int cutLength =
4707                                    parameters_[whichParam(CBC_PARAM_INT_CUTLENGTH, numberParameters_, parameters_)].intValue();
4708                                if (cutLength != -1) {
4709                                    gomoryGen.setLimitAtRoot(cutLength);
4710                                    if (cutLength < 10000000) {
4711                                        gomoryGen.setLimit(cutLength);
4712                                    } else {
4713                                        gomoryGen.setLimit(cutLength % 10000000);
4714                                    }
4715                                }
4716                                int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
4717                                int gType = translate[gomoryAction];
4718                                if (!laGomory) {
4719                                  // Normal
4720                                  babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory");
4721                                  accuracyFlag[numberGenerators] = 3;
4722                                  switches[numberGenerators++] = 0;
4723                                } else {
4724                                  laGomory--;
4725                                  int type = (laGomory % 3)+1;
4726                                  int when = laGomory/3;
4727                                  char atEnd = (when<2) ? 1 : 0;
4728                                  int gomoryTypeMajor = 10;
4729                                  if (when<3) {
4730                                    // normal as well
4731                                    babModel_->addCutGenerator(&gomoryGen, gType, "Gomory");
4732                                    accuracyFlag[numberGenerators] = 3;
4733                                    switches[numberGenerators++] = 0;
4734                                    if (when==2)
4735                                      gomoryTypeMajor=20;
4736                                  } else {
4737                                    when--; // so on
4738                                    gomoryTypeMajor=20;
4739                                  }
4740                                  if (!when)
4741                                    gType=-99; // root
4742                                  gomoryGen.passInOriginalSolver(babModel_->solver());
4743                                  if ((type&1) !=0) {
4744                                    // clean
4745                                    gomoryGen.setGomoryType(gomoryTypeMajor+1);
4746                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1");
4747                                    accuracyFlag[numberGenerators] = 3;
4748                                    doAtEnd[numberGenerators]=atEnd;
4749                                    if (atEnd) {
4750                                      babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4751                                      babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4752                                    }
4753                                    switches[numberGenerators++] = 0;
4754                                  }
4755                                  if ((type&2) !=0) {
4756                                    // simple
4757                                    gomoryGen.setGomoryType(gomoryTypeMajor+2);
4758                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2");
4759                                    accuracyFlag[numberGenerators] = 3;
4760                                    doAtEnd[numberGenerators]=atEnd;
4761                                    if (atEnd) {
4762                                      babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4763                                      babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4764                                    }
4765                                    switches[numberGenerators++] = 0;
4766                                  }
4767                                }
4768                            }
4769#ifdef CLIQUE_ANALYSIS
4770                            if (miplib && !storedAmpl.sizeRowCuts()) {
4771                                printf("looking at probing\n");
4772                                babModel_->addCutGenerator(&storedAmpl, 1, "Stored");
4773                            }
4774#endif
4775                            if (knapsackAction) {
4776                                babModel_->addCutGenerator(&knapsackGen, translate[knapsackAction], "Knapsack");
4777                                accuracyFlag[numberGenerators] = 1;
4778                                switches[numberGenerators++] = -2;
4779                            }
4780                            if (redsplitAction && !complicatedInteger) {
4781                                babModel_->addCutGenerator(&redsplitGen, translate[redsplitAction], "Reduce-and-split");
4782                                accuracyFlag[numberGenerators] = 5;
4783                                // slow ? - just do a few times
4784                                if (redsplitAction!=1) {
4785                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(maximumSlowPasses);
4786                                  babModel_->cutGenerator(numberGenerators)->setHowOften(10);
4787                                }
4788                                switches[numberGenerators++] = 1;
4789                            }
4790                            if (redsplit2Action && !complicatedInteger) {
4791                                int maxLength=256;
4792                                if (redsplit2Action>2) {
4793                                  redsplit2Action-=2;
4794                                  maxLength=COIN_INT_MAX;
4795                                }
4796                                CglRedSplit2Param & parameters = redsplit2Gen.getParam();
4797                                parameters.setMaxNonzeroesTab(maxLength);
4798                                babModel_->addCutGenerator(&redsplit2Gen, translate[redsplit2Action], "Reduce-and-split(2)");
4799                                accuracyFlag[numberGenerators] = 5;
4800                                // slow ? - just do a few times
4801                                if (redsplit2Action!=1) {
4802                                  babModel_->cutGenerator(numberGenerators)->setHowOften(maximumSlowPasses);
4803                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(maximumSlowPasses);
4804                                  babModel_->cutGenerator(numberGenerators)->setHowOften(5);
4805                                }
4806                               
4807                                switches[numberGenerators++] = 1;
4808                            }
4809                            if (GMIAction && !complicatedInteger) {
4810                                if (GMIAction>5) {
4811                                  // long
4812                                  GMIAction-=5;
4813                                  CglGMIParam & parameters = GMIGen.getParam();
4814                                  parameters.setMaxSupportRel(1.0);
4815                                }
4816                                babModel_->addCutGenerator(&GMIGen, translate[GMIAction], "Gomory(2)");
4817                                if (GMIAction==5) {
4818                                  // just at end and root
4819                                  GMIAction=2;
4820                                  doAtEnd[numberGenerators]=1;
4821                                  babModel_->cutGenerator(numberGenerators)->setMaximumTries(99999999);
4822                                  babModel_->cutGenerator(numberGenerators)->setHowOften(1);
4823                                }
4824                                accuracyFlag[numberGenerators] = 5;
4825                                switches[numberGenerators++] = 0;
4826                            }
4827                            if (cliqueAction) {
4828                                babModel_->addCutGenerator(&cliqueGen, translate[cliqueAction], "Clique");
4829                                accuracyFlag[numberGenerators] = 0;
4830                                switches[numberGenerators++] = 0;
4831                            }
4832                            if (mixedAction) {
4833                                babModel_->addCutGenerator(&mixedGen, translate[mixedAction], "MixedIntegerRounding2");
4834                                accuracyFlag[numberGenerators] = 2;
4835