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

Last change on this file since 1621 was 1621, checked in by tkr, 9 years ago

Changing from CPU time limit to wallclock time limit for parallelism

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