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

Last change on this file since 1591 was 1591, checked in by forrest, 9 years ago

modifications to heuristics and allow missing out some printout

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