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

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

New mipstart provided by Haroldo Santos

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