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

Last change on this file since 1642 was 1642, checked in by forrest, 8 years ago

allow for killing small elements in raedLp

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