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

Last change on this file since 1865 was 1865, checked in by forrest, 6 years ago

cuts off when user asks for them off

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