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

Last change on this file since 2333 was 2333, checked in by stefan, 22 months ago

further fix for SOS2 by JJF - some updates of SOS2 info in presolve was missing

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