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

Last change on this file since 1592 was 1592, checked in by forrest, 10 years ago

allow taking out signal

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