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

Last change on this file since 2345 was 2345, checked in by forrest, 2 years ago

ampl with COIN_BIG_INDEX

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 623.2 KB
Line 
1/* $Id: CbcSolver.cpp 2345 2017-10-03 11:36:45Z forrest $ */
2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6/*! \file CbcSolver.cpp
7    \brief Second level routines for the cbc stand-alone solver.
8*/
9
10#include "CbcConfig.h"
11#include "CoinPragma.hpp"
12
13#include <cassert>
14#include <cstdio>
15#include <cstdlib>
16#include <cmath>
17#include <cfloat>
18#include <cstring>
19#include <iostream>
20
21#include "CoinPragma.hpp"
22#include "CoinHelperFunctions.hpp"
23
24#include "CoinMpsIO.hpp"
25#include "CoinModel.hpp"
26
27#include "ClpFactorization.hpp"
28#include "ClpQuadraticObjective.hpp"
29#include "CoinTime.hpp"
30#include "ClpSimplex.hpp"
31#include "ClpSimplexOther.hpp"
32#include "ClpSolve.hpp"
33#include "ClpMessage.hpp"
34#include "ClpPackedMatrix.hpp"
35#include "ClpPlusMinusOneMatrix.hpp"
36#include "ClpNetworkMatrix.hpp"
37#include "ClpDualRowSteepest.hpp"
38#include "ClpDualRowDantzig.hpp"
39#include "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,
1508                                        reinterpret_cast<const CoinBigIndex *>(info.starts),
1509                                        info.rows, info.elements,
1510                                        info.columnLower, info.columnUpper, info.objective,
1511                                        info.rowLower, info.rowUpper);
1512                    // take off cuts if ampl wants that
1513                    if (info.cut && 0) {
1514                        printf("AMPL CUTS OFF until global cuts fixed\n");
1515                        info.cut = NULL;
1516                    }
1517                    if (info.cut) {
1518                        int numberRows = info.numberRows;
1519                        int * whichRow = new int [numberRows];
1520                        // Row copy
1521                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1522                        const double * elementByRow = matrixByRow->getElements();
1523                        const int * column = matrixByRow->getIndices();
1524                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1525                        const int * rowLength = matrixByRow->getVectorLengths();
1526
1527                        const double * rowLower = solver->getRowLower();
1528                        const double * rowUpper = solver->getRowUpper();
1529                        int nDelete = 0;
1530                        for (int iRow = 0; iRow < numberRows; iRow++) {
1531                            if (info.cut[iRow]) {
1532                                whichRow[nDelete++] = iRow;
1533                                int start = rowStart[iRow];
1534                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1535                                                  rowLength[iRow], column + start, elementByRow + start);
1536                            }
1537                        }
1538                        solver->deleteRows(nDelete, whichRow);
1539                        delete [] whichRow;
1540                    }
1541#ifdef COIN_HAS_LINK
1542                } else {
1543#ifndef CBC_OTHER_SOLVER
1544                    // save
1545                    saveCoinModel = *coinModel;
1546                    // load from coin model
1547                    OsiSolverLink solver1;
1548                    OsiSolverInterface * solver2 = solver1.clone();
1549                    model_.assignSolver(solver2, false);
1550                    OsiSolverLink * si =
1551                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1552                    assert (si != NULL);
1553                    si->setDefaultMeshSize(0.001);
1554                    // need some relative granularity
1555                    si->setDefaultBound(100.0);
1556                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
1557                    if (dextra3)
1558                        si->setDefaultMeshSize(dextra3);
1559                    si->setDefaultBound(100000.0);
1560                    si->setIntegerPriority(1000);
1561                    si->setBiLinearPriority(10000);
1562                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
1563                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1564                    si->load(*model2, true, logLevel);
1565                    // redo
1566                    solver = model_.solver();
1567                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1568                    lpSolver = clpSolver->getModelPtr();
1569                    clpSolver->messageHandler()->setLogLevel(0) ;
1570                    testOsiParameters = 0;
1571                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
1572                    complicatedInteger = 1;
1573                    if (info.cut) {
1574                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1575                        abort();
1576                        int numberRows = info.numberRows;
1577                        int * whichRow = new int [numberRows];
1578                        // Row copy
1579                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1580                        const double * elementByRow = matrixByRow->getElements();
1581                        const int * column = matrixByRow->getIndices();
1582                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1583                        const int * rowLength = matrixByRow->getVectorLengths();
1584
1585                        const double * rowLower = solver->getRowLower();
1586                        const double * rowUpper = solver->getRowUpper();
1587                        int nDelete = 0;
1588                        for (int iRow = 0; iRow < numberRows; iRow++) {
1589                            if (info.cut[iRow]) {
1590                                whichRow[nDelete++] = iRow;
1591                                int start = rowStart[iRow];
1592                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1593                                                  rowLength[iRow], column + start, elementByRow + start);
1594                            }
1595                        }
1596                        solver->deleteRows(nDelete, whichRow);
1597                        // and special matrix
1598                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1599                        delete [] whichRow;
1600                    }
1601#endif
1602                }
1603#endif
1604                // If we had a solution use it
1605                if (info.primalSolution) {
1606                    solver->setColSolution(info.primalSolution);
1607                }
1608                // status
1609                if (info.rowStatus) {
1610                    unsigned char * statusArray = lpSolver->statusArray();
1611                    int i;
1612                    for (i = 0; i < info.numberColumns; i++)
1613                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1614                    statusArray += info.numberColumns;
1615                    for (i = 0; i < info.numberRows; i++)
1616                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1617                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1618                    solver->setWarmStart(basis);
1619                    delete basis;
1620                }
1621                freeArrays1(&info);
1622                // modify objective if necessary
1623                solver->setObjSense(info.direction);
1624                solver->setDblParam(OsiObjOffset, -info.offset);
1625                if (info.offset) {
1626                    sprintf(generalPrint, "Ampl objective offset is %g",
1627                            info.offset);
1628                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1629                    << generalPrint
1630                    << CoinMessageEol;
1631                }
1632                // Set integer variables (unless nonlinear when set)
1633                if (!info.nonLinear) {
1634                    for (int i = info.numberColumns - info.numberIntegers;
1635                            i < info.numberColumns; i++)
1636                        solver->setInteger(i);
1637                }
1638                goodModel = true;
1639                // change argc etc
1640                argc = info.numberArguments;
1641                argv = const_cast<const char **>(info.arguments);
1642            }
1643        }
1644#endif
1645        // default action on import
1646        int allowImportErrors = 0;
1647        int keepImportNames = 1;
1648        int doIdiot = -1;
1649        int outputFormat = 2;
1650        int slpValue = -1;
1651        int cppValue = -1;
1652        int printOptions = 0;
1653        int printMode = 0;
1654        int presolveOptions = 0;
1655        int substitution = 3;
1656        int dualize = 3;
1657        int doCrash = 0;
1658        int doVector = 0;
1659        int doSprint = -1;
1660        int doScaling = 4;
1661        // set reasonable defaults
1662        int preSolve = 5;
1663        int preProcess = 4;
1664        bool useStrategy = false;
1665        bool preSolveFile = false;
1666        bool strongChanged = false;
1667        bool pumpChanged = false;
1668
1669        double djFix = 1.0e100;
1670        double tightenFactor = 0.0;
1671        const char dirsep =  CoinFindDirSeparator();
1672        std::string directory;
1673        std::string dirSample;
1674        std::string dirNetlib;
1675        std::string dirMiplib;
1676        if (dirsep == '/') {
1677            directory = "./";
1678            dirSample = "../../Data/Sample/";
1679            dirNetlib = "../../Data/Netlib/";
1680            dirMiplib = "../../Data/miplib3/";
1681        } else {
1682            directory = ".\\";
1683            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1684            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1685            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
1686        }
1687        std::string defaultDirectory = directory;
1688        std::string importFile = "";
1689        std::string exportFile = "default.mps";
1690        std::string importBasisFile = "";
1691        std::string importPriorityFile = "";
1692        std::string debugFile = "";
1693        std::string printMask = "";
1694        double * debugValues = NULL;
1695        int numberDebugValues = -1;
1696        int basisHasValues = 0;
1697        std::string exportBasisFile = "default.bas";
1698        std::string saveFile = "default.prob";
1699        std::string restoreFile = "default.prob";
1700        std::string solutionFile = "stdout";
1701        std::string solutionSaveFile = "solution.file";
1702        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1703        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
1704#ifndef CBC_OTHER_SOLVER
1705        double normalIncrement = model_.getCutoffIncrement();;
1706#endif
1707        if (testOsiParameters >= 0) {
1708            // trying nonlinear - switch off some stuff
1709            preProcess = 0;
1710        }
1711        // Set up likely cut generators and defaults
1712        int nodeStrategy = 0;
1713        bool dominatedCuts = false;
1714        int doSOS = 1;
1715        int verbose = 0;
1716        CglGomory gomoryGen;
1717        // try larger limit
1718        gomoryGen.setLimitAtRoot(1000);
1719        gomoryGen.setLimit(50);
1720        // set default action (0=off,1=on,2=root)
1721        int gomoryAction = 3;
1722
1723        CglProbing probingGen;
1724        probingGen.setUsingObjective(1);
1725        probingGen.setMaxPass(1);
1726        probingGen.setMaxPassRoot(1);
1727        // Number of unsatisfied variables to look at
1728        probingGen.setMaxProbe(10);
1729        probingGen.setMaxProbeRoot(50);
1730        // How far to follow the consequences
1731        probingGen.setMaxLook(10);
1732        probingGen.setMaxLookRoot(50);
1733        probingGen.setMaxLookRoot(10);
1734        // Only look at rows with fewer than this number of elements
1735        probingGen.setMaxElements(200);
1736        probingGen.setMaxElementsRoot(300);
1737        probingGen.setRowCuts(3);
1738        // set default action (0=off,1=on,2=root)
1739        int probingAction = 1;
1740
1741        CglKnapsackCover knapsackGen;
1742        //knapsackGen.switchOnExpensive();
1743        //knapsackGen.setMaxInKnapsack(100);
1744        // set default action (0=off,1=on,2=root)
1745        int knapsackAction = 3;
1746
1747        CglRedSplit redsplitGen;
1748        //redsplitGen.setLimit(100);
1749        // set default action (0=off,1=on,2=root)
1750        // Off as seems to give some bad cuts
1751        int redsplitAction = 0;
1752
1753        CglRedSplit2 redsplit2Gen;
1754        //redsplit2Gen.setLimit(100);
1755        // set default action (0=off,1=on,2=root)
1756        // Off
1757        int redsplit2Action = 0;
1758
1759        CglGMI GMIGen;
1760        //GMIGen.setLimit(100);
1761        // set default action (0=off,1=on,2=root)
1762        // Off
1763        int GMIAction = 0;
1764
1765        CglFakeClique cliqueGen(NULL, false);
1766        //CglClique cliqueGen(false,true);
1767        cliqueGen.setStarCliqueReport(false);
1768        cliqueGen.setRowCliqueReport(false);
1769        cliqueGen.setMinViolation(0.1);
1770        // set default action (0=off,1=on,2=root)
1771        int cliqueAction = 3;
1772
1773        // maxaggr,multiply,criterion(1-3)
1774        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1775        // set default action (0=off,1=on,2=root)
1776        int mixedAction = 3;
1777        mixedGen.setDoPreproc(1); // safer (and better)
1778
1779        CglFlowCover flowGen;
1780        // set default action (0=off,1=on,2=root)
1781        int flowAction = 3;
1782
1783        CglTwomir twomirGen;
1784        twomirGen.setMaxElements(250);
1785        // set default action (0=off,1=on,2=root)
1786        int twomirAction = 3;
1787#ifndef DEBUG_MALLOC
1788        CglLandP landpGen;
1789        landpGen.validator().setMinViolation(1.0e-4);
1790#endif
1791        // set default action (0=off,1=on,2=root)
1792        int landpAction = 0;
1793        CglResidualCapacity residualCapacityGen;
1794        residualCapacityGen.setDoPreproc(1); // always preprocess
1795        // set default action (0=off,1=on,2=root)
1796        int residualCapacityAction = 0;
1797
1798        CglZeroHalf zerohalfGen;
1799        //zerohalfGen.switchOnExpensive();
1800        // set default action (0=off,1=on,2=root)
1801        int zerohalfAction = 0;
1802
1803        // Stored cuts
1804        //bool storedCuts = false;
1805
1806        int useCosts = 0;
1807        // don't use input solution
1808        int useSolution = -1;
1809
1810        // total number of commands read
1811        int numberGoodCommands = 0;
1812        // Set false if user does anything advanced
1813        bool defaultSettings = true;
1814
1815        // Hidden stuff for barrier
1816        int choleskyType = 0;
1817        int gamma = 0;
1818        int scaleBarrier = 0;
1819        int doKKT = 0;
1820        int crossover = 2; // do crossover unless quadratic
1821        bool biLinearProblem=false;
1822        // For names
1823        int lengthName = 0;
1824        std::vector<std::string> rowNames;
1825        std::vector<std::string> columnNames;
1826        // Default strategy stuff
1827        {
1828            // try changing tolerance at root
1829#define MORE_CUTS
1830#ifdef MORE_CUTS
1831            gomoryGen.setAwayAtRoot(0.005);
1832            twomirGen.setAwayAtRoot(0.005);
1833            twomirGen.setAway(0.01);
1834            //twomirGen.setMirScale(1,1);
1835            //twomirGen.setTwomirScale(1,1);
1836            //twomirGen.setAMax(2);
1837#else
1838            gomoryGen.setAwayAtRoot(0.01);
1839            twomirGen.setAwayAtRoot(0.01);
1840            twomirGen.setAway(0.01);
1841#endif
1842            int iParam;
1843            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
1844            parameters_[iParam].setIntValue(2);
1845            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
1846            parameters_[iParam].setIntValue(30);
1847            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
1848            parameters_[iParam].setIntValue(1005043);
1849            initialPumpTune = 1005043;
1850            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
1851            parameters_[iParam].setIntValue(6);
1852            tunePreProcess = 6;
1853            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
1854            parameters_[iParam].setCurrentOption("on");
1855            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
1856            parameters_[iParam].setCurrentOption("on");
1857            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
1858            parameters_[iParam].setCurrentOption("on");
1859            probingAction = 3;
1860            //parameters_[iParam].setCurrentOption("forceOnStrong");
1861            //probingAction = 8;
1862        }
1863        std::string field;
1864#if CBC_QUIET == 0
1865        if (!noPrinting_) {
1866           sprintf(generalPrint,
1867                   "Welcome to the CBC MILP Solver \n");
1868            if (strcmp(CBC_VERSION, "trunk")){
1869               sprintf(generalPrint + strlen(generalPrint),
1870                       "Version: %s \n", CBC_VERSION);
1871            }else{
1872               sprintf(generalPrint + strlen(generalPrint),
1873                       "Version: Trunk (unstable) \n");
1874            }
1875            sprintf(generalPrint + strlen(generalPrint),
1876                    "Build Date: %s \n", __DATE__);
1877#ifdef CBC_SVN_REV
1878            sprintf(generalPrint + strlen(generalPrint),
1879                    "Revision Number: %d \n", CBC_SVN_REV);
1880#endif
1881            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1882            << generalPrint
1883            << CoinMessageEol;
1884            // Print command line
1885            if (argc > 1) {
1886                bool foundStrategy = false;
1887                sprintf(generalPrint, "command line - ");
1888                for (int i = 0; i < argc; i++) {
1889                    if (!argv[i])
1890                        break;
1891                    if (strstr(argv[i], "strat"))
1892                        foundStrategy = true;
1893                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1894                }
1895                if (!foundStrategy)
1896                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1897                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1898                << generalPrint
1899                << CoinMessageEol;
1900            }
1901        }
1902#endif
1903        while (1) {
1904            // next command
1905            field = CoinReadGetCommand(argc, argv);
1906            // Reset time
1907            time1 = CoinCpuTime();
1908            time1Elapsed = CoinGetTimeOfDay();
1909            // adjust field if has odd trailing characters
1910            char temp [200];
1911            strcpy(temp, field.c_str());
1912            int length = static_cast<int>(strlen(temp));
1913            for (int k = length - 1; k >= 0; k--) {
1914                if (temp[k] < ' ')
1915                    length--;
1916                else
1917                    break;
1918            }
1919            temp[length] = '\0';
1920            field = temp;
1921            // exit if null or similar
1922            if (!field.length()) {
1923                if (numberGoodCommands == 1 && goodModel) {
1924                    // we just had file name - do branch and bound
1925                    field = "branch";
1926                } else if (!numberGoodCommands) {
1927                    // let's give the sucker a hint
1928                    std::cout
1929                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1930                        << std::endl
1931                        << "Enter ? for list of commands or help" << std::endl;
1932                    field = "-";
1933                } else {
1934                    break;
1935                }
1936            }
1937
1938            // see if ? at end
1939            size_t numberQuery = 0;
1940            if (field != "?" && field != "???") {
1941                size_t length = field.length();
1942                size_t i;
1943                for (i = length - 1; i > 0; i--) {
1944                    if (field[i] == '?')
1945                        numberQuery++;
1946                    else
1947                        break;
1948                }
1949                field = field.substr(0, length - numberQuery);
1950            }
1951            // find out if valid command
1952            int iParam;
1953            int numberMatches = 0;
1954            int firstMatch = -1;
1955            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1956                int match = parameters_[iParam].matches(field);
1957                if (match == 1) {
1958                    numberMatches = 1;
1959                    firstMatch = iParam;
1960                    break;
1961                } else {
1962                    if (match && firstMatch < 0)
1963                        firstMatch = iParam;
1964                    numberMatches += match >> 1;
1965                }
1966            }
1967            if (iParam < numberParameters_ && !numberQuery) {
1968                // found
1969                CbcOrClpParam found = parameters_[iParam];
1970                CbcOrClpParameterType type = found.type();
1971                int valid;
1972                numberGoodCommands++;
1973                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
1974#ifndef CBC_USE_INITIAL_TIME
1975                  if (model_.useElapsedTime())
1976                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1977                  else
1978                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1979#endif
1980                  biLinearProblem=false;
1981                    // check if any integers
1982#ifndef CBC_OTHER_SOLVER
1983#ifdef COIN_HAS_ASL
1984                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1985                        // SOS
1986                        numberSOS = info.numberSos;
1987                    }
1988#endif
1989                    lpSolver = clpSolver->getModelPtr();
1990                    if (!lpSolver->integerInformation() && !numberSOS &&
1991                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
1992                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
1993#endif
1994                }
1995                if (type == CBC_PARAM_GENERALQUERY) {
1996                    bool evenHidden = false;
1997                    int printLevel =
1998                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
1999                                               numberParameters_, parameters_)].currentOptionAsInteger();
2000                    int convertP[] = {2, 1, 0};
2001                    printLevel = convertP[printLevel];
2002                    if ((verbose&8) != 0) {
2003                        // even hidden
2004                        evenHidden = true;
2005                        verbose &= ~8;
2006                    }
2007#ifdef COIN_HAS_ASL
2008                    if (verbose < 4 && statusUserFunction_[0])
2009                        verbose += 4;
2010#endif
2011                    if (verbose < 4) {
2012                        std::cout << "In argument list keywords have leading - "
2013                                  ", -stdin or just - switches to stdin" << std::endl;
2014                        std::cout << "One command per line (and no -)" << std::endl;
2015                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
2016                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
2017                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
2018                        std::cout << "abcd value sets value" << std::endl;
2019                        std::cout << "Commands are:" << std::endl;
2020                    } else {
2021                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
2022                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
2023                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
2024                    }
2025                    int maxAcross = 10;
2026                    if ((verbose % 4) != 0)
2027                        maxAcross = 1;
2028                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2029                    std::vector<std::string> types;
2030                    types.push_back("Double parameters:");
2031                    types.push_back("Branch and Cut double parameters:");
2032                    types.push_back("Integer parameters:");
2033                    types.push_back("Branch and Cut integer parameters:");
2034                    types.push_back("Keyword parameters:");
2035                    types.push_back("Branch and Cut keyword parameters:");
2036                    types.push_back("Actions or string parameters:");
2037                    types.push_back("Branch and Cut actions:");
2038                    int iType;
2039                    for (iType = 0; iType < 8; iType++) {
2040                        int across = 0;
2041                        int lengthLine = 0;
2042                        if ((verbose % 4) != 0)
2043                            std::cout << std::endl;
2044                        std::cout << types[iType] << std::endl;
2045                        if ((verbose&2) != 0)
2046                            std::cout << std::endl;
2047                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2048                            int type = parameters_[iParam].type();
2049                            //printf("%d type %d limits %d %d display %d\n",iParam,
2050                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
2051                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
2052                                    type >= limits[iType]
2053                                    && type < limits[iType+1]) {
2054                                // but skip if not useful for ampl (and in ampl mode)
2055                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
2056                                    continue;
2057                                if (!across) {
2058                                    if ((verbose&2) != 0)
2059                                        std::cout << "Command ";
2060                                }
2061                                int length = parameters_[iParam].lengthMatchName() + 1;
2062                                if (lengthLine + length > 80) {
2063                                    std::cout << std::endl;
2064                                    across = 0;
2065                                    lengthLine = 0;
2066                                }
2067                                std::cout << " " << parameters_[iParam].matchName();
2068                                lengthLine += length;
2069                                across++;
2070                                if (across == maxAcross) {
2071                                    across = 0;
2072                                    if ((verbose % 4) != 0) {
2073                                        // put out description as well
2074                                        if ((verbose&1) != 0)
2075                                            std::cout << " " << parameters_[iParam].shortHelp();
2076                                        std::cout << std::endl;
2077                                        if ((verbose&2) != 0) {
2078                                            std::cout << "---- description" << std::endl;
2079                                            parameters_[iParam].printLongHelp();
2080                                            std::cout << "----" << std::endl << std::endl;
2081                                        }
2082                                    } else {
2083                                        std::cout << std::endl;
2084                                    }
2085                                }
2086                            }
2087                        }
2088                        if (across)
2089                            std::cout << std::endl;
2090                    }
2091                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
2092                    std::cout << "Full list of commands is:" << std::endl;
2093                    int maxAcross = 5;
2094                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2095                    std::vector<std::string> types;
2096                    types.push_back("Double parameters:");
2097                    types.push_back("Branch and Cut double parameters:");
2098                    types.push_back("Integer parameters:");
2099                    types.push_back("Branch and Cut integer parameters:");
2100                    types.push_back("Keyword parameters:");
2101                    types.push_back("Branch and Cut keyword parameters:");
2102                    types.push_back("Actions or string parameters:");
2103                    types.push_back("Branch and Cut actions:");
2104                    int iType;
2105                    for (iType = 0; iType < 8; iType++) {
2106                        int across = 0;
2107                        std::cout << types[iType] << "  ";
2108                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2109                            int type = parameters_[iParam].type();
2110                            if (type >= limits[iType]
2111                                    && type < limits[iType+1]) {
2112                                if (!across)
2113                                    std::cout << "  ";
2114                                std::cout << parameters_[iParam].matchName() << "  ";
2115                                across++;
2116                                if (across == maxAcross) {
2117                                    std::cout << std::endl;
2118                                    across = 0;
2119                                }
2120                            }
2121                        }
2122                        if (across)
2123                            std::cout << std::endl;
2124                    }
2125                } else if (type < 101) {
2126                    // get next field as double
2127                    double value = CoinReadGetDoubleField(argc, argv, &valid);
2128                    if (!valid) {
2129                        if (type < 51) {
2130                            int returnCode;
2131                            const char * message =
2132                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2133                            if (!noPrinting_ && strlen(message)) {
2134                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2135                                << message
2136                                << CoinMessageEol;
2137                            }
2138                        } else if (type < 81) {
2139                            int returnCode;
2140                            const char * message =
2141                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
2142                            if (!noPrinting_ && strlen(message)) {
2143                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2144                                << message
2145                                << CoinMessageEol;
2146                            }
2147                        } else {
2148                            int returnCode;
2149                            const char * message =
2150                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2151                            if (!noPrinting_ && strlen(message)) {
2152                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2153                                << message
2154                                << CoinMessageEol;
2155                            }
2156                            switch (type) {
2157                            case CBC_PARAM_DBL_DJFIX:
2158                                djFix = value;
2159#ifndef CBC_OTHER_SOLVER
2160                                if (goodModel && djFix < 1.0e20) {
2161                                    // do some fixing
2162                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
2163                                    clpSolver->initialSolve();
2164                                    lpSolver = clpSolver->getModelPtr();
2165                                    int numberColumns = lpSolver->numberColumns();
2166                                    int i;
2167                                    const char * type = lpSolver->integerInformation();
2168                                    double * lower = lpSolver->columnLower();
2169                                    double * upper = lpSolver->columnUpper();
2170                                    double * solution = lpSolver->primalColumnSolution();
2171                                    double * dj = lpSolver->dualColumnSolution();
2172                                    int numberFixed = 0;
2173                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
2174                                    if (dextra4)
2175                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
2176                                    for (i = 0; i < numberColumns; i++) {
2177                                        double djValue = dj[i];
2178                                        if (!type[i])
2179                                            djValue *= dextra4;
2180                                        if (type[i] || dextra4) {
2181                                            double value = solution[i];
2182                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
2183                                                solution[i] = lower[i];
2184                                                upper[i] = lower[i];
2185                                                numberFixed++;
2186                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
2187                                                solution[i] = upper[i];
2188                                                lower[i] = upper[i];
2189                                                numberFixed++;
2190                                            }
2191                                        }
2192                                    }
2193                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
2194                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2195                                    << generalPrint
2196                                    << CoinMessageEol;
2197                                }
2198#endif
2199                                break;
2200                            case CBC_PARAM_DBL_TIGHTENFACTOR:
2201                                tightenFactor = value;
2202                                if (!complicatedInteger)
2203                                    defaultSettings = false; // user knows what she is doing
2204                                break;
2205                            default:
2206                                break;
2207                            }
2208                        }
2209                    } else if (valid == 1) {
2210                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2211                                  parameters_[iParam].doubleValue() << std::endl;
2212                    } else {
2213                        std::cout << parameters_[iParam].name() << " has value " <<
2214                                  parameters_[iParam].doubleValue() << std::endl;
2215                    }
2216                } else if (type < 201) {
2217                    // get next field as int
2218                    int value = CoinReadGetIntField(argc, argv, &valid);
2219                    if (!valid) {
2220                        if (type < 151) {
2221                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
2222                                preSolve = value;
2223                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
2224                                doIdiot = value;
2225                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
2226                                doSprint = value;
2227                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
2228                                outputFormat = value;
2229                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
2230                                slpValue = value;
2231                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
2232                                cppValue = value;
2233                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
2234                                presolveOptions = value;
2235                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
2236                                printOptions = value;
2237                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
2238                                substitution = value;
2239                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
2240                                dualize = value;
2241                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
2242                                tunePreProcess = value;
2243                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
2244                                useSolution = value;
2245                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
2246                                verbose = value;
2247                            int returnCode;
2248                            const char * message =
2249                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2250                            if (!noPrinting_ && strlen(message)) {
2251                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2252                                << message
2253                                << CoinMessageEol;
2254                            }
2255                        } else {
2256                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
2257                                cutPass = value;
2258                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
2259                                cutPassInTree = value;
2260                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2261                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
2262                                strongChanged = true;
2263                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2264                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2265                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
2266                                pumpChanged = true;
2267                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
2268                                int addFlags=0;
2269                                // switch on some later features if >999
2270                                if (value>999) {
2271                                  int switchValue=value/1000;
2272                                  const char * message = NULL;
2273                                  value -= 1000*switchValue;
2274                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(0/*value*/);
2275                                  switch (switchValue) {
2276                                  default:
2277                                  case 4:
2278                                    // hotstart 500, -200 cut passes
2279                                    message=parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValueWithMessage(500);
2280                                    if (!noPrinting_&&message) 
2281                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2282                                        << message << CoinMessageEol;
2283                                    message=parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValueWithMessage(-200);
2284                                    if (!noPrinting_&&message) 
2285                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2286                                        << message << CoinMessageEol;
2287                                  case 3:
2288                                    // multiple 4
2289                                    message=parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValueWithMessage(4);
2290                                    if (!noPrinting_&&message) 
2291                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2292                                        << message << CoinMessageEol;
2293                                  case 2:
2294                                    // rens plus all diving at root
2295                                    message=parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].setIntValueWithMessage(16);
2296                                    if (!noPrinting_&&message) 
2297                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2298                                        << message << CoinMessageEol;
2299                                    model_.setNumberAnalyzeIterations(-value);
2300                                    // -tune 7 zero,lagomory,gmi at root - probing on
2301                                  case 1:
2302                                    tunePreProcess=7;
2303                                    message=parameters_[whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_)].setIntValueWithMessage(7);
2304                                    if (!noPrinting_&&message) 
2305                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2306                                        << message << CoinMessageEol;
2307                                    //message = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValueWithMessage(1025);
2308                                    //if (!noPrinting_&&message)
2309                                    //    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2310                                    //  << message << CoinMessageEol;
2311                                    message=parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("on");
2312                                    probingAction = 1;
2313                                    if (!noPrinting_&&message) 
2314                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2315                                        << message << CoinMessageEol;
2316                                    message=parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2317                                    if (!noPrinting_&&message) 
2318                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2319                                        << message << CoinMessageEol;
2320                                    message=parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2321                                    if (!noPrinting_&&message) 
2322                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2323                                        << message << CoinMessageEol;
2324                                    GMIAction = 2;
2325                                    message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2326                                    if (!noPrinting_&&message) 
2327                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2328                                        << message << CoinMessageEol;
2329                                  }
2330                                  value = 0;
2331                                }
2332                                if (value>=10) {
2333                                  addFlags = 1048576*(value/10);
2334                                  value = value % 10;
2335                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(value);
2336                                }
2337                                if (value >= 1) {
2338                                    int values[]={24003,280003,792003,24003,24003};
2339                                    if (value>=2&&value<=3) {
2340                                      // swap default diving
2341                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2342                                      parameters_[iParam].setCurrentOption("off");
2343                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2344                                      parameters_[iParam].setCurrentOption("on");
2345                                    }
2346                                    int extra4 = values[value-1]+addFlags;
2347                                    parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].setIntValue(extra4);
2348                                    if (!noPrinting_) {
2349                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2350                                        << "switching on global root cuts for gomory and knapsack"
2351                                        << CoinMessageEol;
2352                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2353                                        << "using OSL factorization"
2354                                        << CoinMessageEol;
2355                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2356                                        << "extra options - -rens on -extra4 "
2357                                        <<extra4<<" -passc 1000!"
2358                                        << CoinMessageEol;
2359                                    }
2360                                    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("forceOnStrong");
2361                                    probingAction = 8;
2362                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2363                                    gomoryAction = 5;
2364                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
2365                                    knapsackAction = 5;
2366                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
2367                                    lpSolver->factorization()->forceOtherFactorization(3);
2368                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
2369                                    parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValue(1000);
2370                                    cutPass = 1000;
2371                                    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("on");
2372                                }
2373                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
2374                                if (value == 0) {
2375                                    gomoryGen.setAwayAtRoot(0.05);
2376                                    int iParam;
2377                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
2378                                    parameters_[iParam].setIntValue(-1);
2379                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
2380                                    parameters_[iParam].setIntValue(20);
2381                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
2382                                    parameters_[iParam].setIntValue(1003);
2383                                    initialPumpTune = 1003;
2384                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
2385                                    parameters_[iParam].setIntValue(0);
2386                                    tunePreProcess = 0;
2387                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2388                                    parameters_[iParam].setCurrentOption("off");
2389                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
2390                                    parameters_[iParam].setCurrentOption("off");
2391                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
2392                                    // but not if cuts off
2393                                    int jParam = whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_);
2394                                   
2395                                    jParam = parameters_[jParam].currentOptionAsInteger();
2396                                    if (jParam) {
2397                                      parameters_[iParam].setCurrentOption("on");
2398                                      probingAction = 1;
2399                                    } else {
2400                                      parameters_[iParam].setCurrentOption("off");
2401                                      probingAction = 0;
2402                                    }
2403                                }
2404                            }
2405                            int returnCode;
2406                            const char * message =
2407                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2408                            if (!noPrinting_ && strlen(message)) {
2409                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2410                                << message
2411                                << CoinMessageEol;
2412                            }
2413                        }
2414                    } else if (valid == 1) {
2415                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2416                                  parameters_[iParam].intValue() << std::endl;
2417                    } else {
2418                        std::cout << parameters_[iParam].name() << " has value " <<
2419                                  parameters_[iParam].intValue() << std::endl;
2420                    }
2421                } else if (type < 301) {
2422                    // one of several strings
2423                    std::string value = CoinReadGetString(argc, argv);
2424                    int action = parameters_[iParam].parameterOption(value);
2425                    if (action < 0) {
2426                        if (value != "EOL") {
2427                            // no match
2428                            parameters_[iParam].printOptions();
2429                        } else {
2430                            // print current value
2431                            std::cout << parameters_[iParam].name() << " has value " <<
2432                                      parameters_[iParam].currentOption() << std::endl;
2433                        }
2434                    } else {
2435                        const char * message =
2436                            parameters_[iParam].setCurrentOptionWithMessage(action);
2437                        if (!noPrinting_ && strlen(message)) {
2438                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2439                            << message
2440                            << CoinMessageEol;
2441                        }
2442                        // for now hard wired
2443                        switch (type) {
2444                        case CLP_PARAM_STR_DIRECTION:
2445                            if (action == 0)
2446                                lpSolver->setOptimizationDirection(1);
2447                            else if (action == 1)
2448                                lpSolver->setOptimizationDirection(-1);
2449                            else
2450                                lpSolver->setOptimizationDirection(0);
2451                            break;
2452                        case CLP_PARAM_STR_DUALPIVOT:
2453                            if (action == 0) {
2454                                ClpDualRowSteepest steep(3);
2455                                lpSolver->setDualRowPivotAlgorithm(steep);
2456                            } else if (action == 1) {
2457                                ClpDualRowDantzig dantzig;
2458                                //ClpDualRowSteepest dantzig(5);
2459                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2460                            } else if (action == 2) {
2461                                // partial steep
2462                                ClpDualRowSteepest steep(2);
2463                                lpSolver->setDualRowPivotAlgorithm(steep);
2464                            } else if (action == 3) {
2465                                ClpDualRowSteepest steep;
2466                                lpSolver->setDualRowPivotAlgorithm(steep);
2467                            } else if (action == 4) {
2468                              // Positive edge steepest
2469                              ClpPEDualRowSteepest p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2470                              lpSolver->setDualRowPivotAlgorithm(p);
2471                            } else if (action == 5) {
2472                              // Positive edge Dantzig
2473                              ClpPEDualRowDantzig p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2474                              lpSolver->setDualRowPivotAlgorithm(p);
2475                            }
2476                            break;
2477                        case CLP_PARAM_STR_PRIMALPIVOT:
2478                            if (action == 0) {
2479                                ClpPrimalColumnSteepest steep(3);
2480                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2481                            } else if (action == 1) {
2482                                ClpPrimalColumnSteepest steep(0);
2483                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2484                            } else if (action == 2) {
2485                                ClpPrimalColumnDantzig dantzig;
2486                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2487                            } else if (action == 3) {
2488                                ClpPrimalColumnSteepest steep(4);
2489                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2490                            } else if (action == 4) {
2491                                ClpPrimalColumnSteepest steep(1);
2492                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2493                            } else if (action == 5) {
2494                                ClpPrimalColumnSteepest steep(2);
2495                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2496                            } else if (action == 6) {
2497                                ClpPrimalColumnSteepest steep(10);
2498                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2499                            } else if (action == 7) {
2500                              // Positive edge steepest
2501                              ClpPEPrimalColumnSteepest p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2502                              lpSolver->setPrimalColumnPivotAlgorithm(p);
2503                            } else if (action == 8) {
2504                              // Positive edge Dantzig
2505                              ClpPEPrimalColumnDantzig p(fabs(parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue()));
2506                              lpSolver->setPrimalColumnPivotAlgorithm(p);
2507                            }
2508                            break;
2509                        case CLP_PARAM_STR_SCALING:
2510                            lpSolver->scaling(action);
2511                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2512                            doScaling = action;
2513                            break;
2514                        case CLP_PARAM_STR_AUTOSCALE:
2515                            lpSolver->setAutomaticScaling(action != 0);
2516                            break;
2517                        case CLP_PARAM_STR_SPARSEFACTOR:
2518                            lpSolver->setSparseFactorization((1 - action) != 0);
2519                            break;
2520                        case CLP_PARAM_STR_BIASLU:
2521                            lpSolver->factorization()->setBiasLU(action);
2522                            break;
2523                        case CLP_PARAM_STR_PERTURBATION:
2524                            if (action == 0)
2525                                lpSolver->setPerturbation(50);
2526                            else
2527                                lpSolver->setPerturbation(100);
2528                            break;
2529                        case CLP_PARAM_STR_ERRORSALLOWED:
2530                            allowImportErrors = action;
2531                            break;
2532                        case CLP_PARAM_STR_INTPRINT:
2533                            printMode = action;
2534                            break;
2535                            //case CLP_PARAM_NOTUSED_ALGORITHM:
2536                            //algorithm  = action;
2537                            //defaultSettings=false; // user knows what she is doing
2538                            //abort();
2539                            //break;
2540                        case CLP_PARAM_STR_KEEPNAMES:
2541                            keepImportNames = 1 - action;
2542                            break;
2543                        case CLP_PARAM_STR_PRESOLVE:
2544                            if (action == 0)
2545                                preSolve = 5;
2546                            else if (action == 1)
2547                                preSolve = 0;
2548                            else if (action == 2)
2549                                preSolve = 10;
2550                            else
2551                                preSolveFile = true;
2552                            break;
2553                        case CLP_PARAM_STR_PFI:
2554                            lpSolver->factorization()->setForrestTomlin(action == 0);
2555                            break;
2556                        case CLP_PARAM_STR_FACTORIZATION:
2557                            lpSolver->factorization()->forceOtherFactorization(action);
2558                            break;
2559                        case CLP_PARAM_STR_CRASH:
2560                            doCrash = action;
2561                            break;
2562                        case CLP_PARAM_STR_VECTOR:
2563                            doVector = action;
2564                            break;
2565                        case CLP_PARAM_STR_MESSAGES:
2566                            lpSolver->messageHandler()->setPrefix(action != 0);
2567                            break;
2568                        case CLP_PARAM_STR_CHOLESKY:
2569                            choleskyType = action;
2570                            break;
2571                        case CLP_PARAM_STR_GAMMA:
2572                            gamma = action;
2573                            break;
2574                        case CLP_PARAM_STR_BARRIERSCALE:
2575                            scaleBarrier = action;
2576                            break;
2577                        case CLP_PARAM_STR_KKT:
2578                            doKKT = action;
2579                            break;
2580                        case CLP_PARAM_STR_CROSSOVER:
2581                            crossover = action;
2582                            break;
2583                        case CLP_PARAM_STR_TIME_MODE:
2584                            model_.setUseElapsedTime(action!=0);
2585                            break;
2586                        case CBC_PARAM_STR_SOS:
2587                            doSOS = action;
2588                            break;
2589                        case CBC_PARAM_STR_GOMORYCUTS:
2590                            defaultSettings = false; // user knows what she is doing
2591                            gomoryAction = action;
2592                            break;
2593                        case CBC_PARAM_STR_PROBINGCUTS:
2594                            defaultSettings = false; // user knows what she is doing
2595                            probingAction = action;
2596                            break;
2597                        case CBC_PARAM_STR_KNAPSACKCUTS:
2598                            defaultSettings = false; // user knows what she is doing
2599                            knapsackAction = action;
2600                            break;
2601                        case CBC_PARAM_STR_REDSPLITCUTS:
2602                            defaultSettings = false; // user knows what she is doing
2603                            redsplitAction = action;
2604                            break;
2605                        case CBC_PARAM_STR_REDSPLIT2CUTS:
2606                            defaultSettings = false; // user knows what she is doing
2607                            redsplit2Action = action;
2608                            break;
2609                        case CBC_PARAM_STR_GMICUTS:
2610                            defaultSettings = false; // user knows what she is doing
2611                            GMIAction = action;
2612                            break;
2613                        case CBC_PARAM_STR_CLIQUECUTS:
2614                            defaultSettings = false; // user knows what she is doing
2615                            cliqueAction = action;
2616                            break;
2617                        case CBC_PARAM_STR_FLOWCUTS:
2618                            defaultSettings = false; // user knows what she is doing
2619                            flowAction = action;
2620                            break;
2621                        case CBC_PARAM_STR_MIXEDCUTS:
2622                            defaultSettings = false; // user knows what she is doing
2623                            mixedAction = action;
2624                            break;
2625                        case CBC_PARAM_STR_TWOMIRCUTS:
2626                            defaultSettings = false; // user knows what she is doing
2627                            twomirAction = action;
2628                            break;
2629                        case CBC_PARAM_STR_LANDPCUTS:
2630                            defaultSettings = false; // user knows what she is doing
2631                            landpAction = action;
2632                            break;
2633                        case CBC_PARAM_STR_RESIDCUTS:
2634                            defaultSettings = false; // user knows what she is doing
2635                            residualCapacityAction = action;
2636                            break;
2637                        case CBC_PARAM_STR_ZEROHALFCUTS:
2638                            defaultSettings = false; // user knows what she is doing
2639                            zerohalfAction = action;
2640                            break;
2641                        case CBC_PARAM_STR_ROUNDING:
2642                            defaultSettings = false; // user knows what she is doing
2643                            break;
2644                        case CBC_PARAM_STR_FPUMP:
2645                            defaultSettings = false; // user knows what she is doing
2646                            break;
2647                        case CBC_PARAM_STR_RINS:
2648                            break;
2649                        case CBC_PARAM_STR_DINS:
2650                            break;
2651                        case CBC_PARAM_STR_RENS:
2652                            break;
2653                        case CBC_PARAM_STR_CUTSSTRATEGY:
2654                            gomoryAction = action;
2655                            probingAction = action;
2656                            knapsackAction = action;
2657                            cliqueAction = action;
2658                            flowAction = action;
2659                            mixedAction = action;
2660                            twomirAction = action;
2661                            //landpAction = action;
2662                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2663                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2664                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2665                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2666                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2667                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2668                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2669                            if (!action) {
2670                                zerohalfAction = action;
2671                                parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2672                                redsplitAction = action;
2673                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2674                                redsplit2Action = action;
2675                                parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption(action);
2676                                GMIAction = action;
2677                                parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption(action);
2678                                landpAction = action;
2679                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2680                                residualCapacityAction = action;
2681                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2682                            }
2683                            break;
2684                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2685                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2686                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2687                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2688                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2689                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2690                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2691                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
2692                            break;
2693                        case CBC_PARAM_STR_GREEDY:
2694                        case CBC_PARAM_STR_DIVINGS:
2695                        case CBC_PARAM_STR_DIVINGC:
2696                        case CBC_PARAM_STR_DIVINGF:
2697                        case CBC_PARAM_STR_DIVINGG:
2698                        case CBC_PARAM_STR_DIVINGL:
2699                        case CBC_PARAM_STR_DIVINGP:
2700                        case CBC_PARAM_STR_DIVINGV:
2701                        case CBC_PARAM_STR_COMBINE:
2702                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2703                        case CBC_PARAM_STR_PIVOTANDFIX:
2704                        case CBC_PARAM_STR_RANDROUND:
2705                        case CBC_PARAM_STR_LOCALTREE:
2706                        case CBC_PARAM_STR_NAIVE:
2707                        case CBC_PARAM_STR_CPX:
2708                            defaultSettings = false; // user knows what she is doing
2709                            break;
2710                        case CBC_PARAM_STR_COSTSTRATEGY:
2711                            useCosts = action;
2712                            break;
2713                        case CBC_PARAM_STR_NODESTRATEGY:
2714                            nodeStrategy = action;
2715                            break;
2716                        case CBC_PARAM_STR_PREPROCESS:
2717                            preProcess = action;
2718                            break;
2719                        default:
2720                            //abort();
2721                            break;
2722                        }
2723                    }
2724                } else {
2725                    // action
2726                    if (type == CLP_PARAM_ACTION_EXIT) {
2727#ifdef COIN_HAS_ASL
2728                        if (statusUserFunction_[0]) {
2729                            if (info.numberIntegers || info.numberBinary) {
2730                                // integer
2731                            } else {
2732                                // linear
2733                            }
2734                            writeAmpl(&info);
2735                            freeArrays2(&info);
2736                            freeArgs(&info);
2737                        }
2738#endif
2739                        break; // stop all
2740                    }
2741                    switch (type) {
2742                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2743                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2744                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2745                    case CLP_PARAM_ACTION_BARRIER:
2746                        if (goodModel) {
2747                            // Say not in integer
2748                            integerStatus = -1;
2749                            double objScale =
2750                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
2751                            // deal with positive edge
2752                            double psi = parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue();
2753                            if (psi>0.0) {
2754                              ClpDualRowPivot * dualp = lpSolver->dualRowPivot();
2755                              ClpDualRowSteepest * d1 = dynamic_cast<ClpDualRowSteepest *>(dualp);
2756                              ClpDualRowDantzig * d2 = dynamic_cast<ClpDualRowDantzig *>(dualp);
2757                              if (d1) {
2758                                ClpPEDualRowSteepest p(psi,d1->mode());
2759                                lpSolver->setDualRowPivotAlgorithm(p);
2760                              } else if (d2) {
2761                                ClpPEDualRowDantzig p(psi);
2762                                lpSolver->setDualRowPivotAlgorithm(p);
2763                              }
2764                              ClpPrimalColumnPivot * primalp = lpSolver->primalColumnPivot();
2765                              ClpPrimalColumnSteepest * p1 = dynamic_cast<ClpPrimalColumnSteepest *>(primalp);
2766                              ClpPrimalColumnDantzig * p2 = dynamic_cast<ClpPrimalColumnDantzig *>(primalp);
2767                              if (p1) {
2768                                ClpPEPrimalColumnSteepest p(psi,p1->mode());
2769                                lpSolver->setPrimalColumnPivotAlgorithm(p);
2770                              } else if (p2) {
2771                                ClpPEPrimalColumnDantzig p(psi);
2772                                lpSolver->setPrimalColumnPivotAlgorithm(p);
2773                              }
2774                            }
2775                            if (objScale != 1.0) {
2776                                int iColumn;
2777                                int numberColumns = lpSolver->numberColumns();
2778                                double * dualColumnSolution =
2779                                    lpSolver->dualColumnSolution();
2780                                ClpObjective * obj = lpSolver->objectiveAsObject();
2781                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2782                                double offset;
2783                                double * objective = obj->gradient(NULL, NULL, offset, true);
2784                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2785                                    dualColumnSolution[iColumn] *= objScale;
2786                                    objective[iColumn] *= objScale;;
2787                                }
2788                                int iRow;
2789                                int numberRows = lpSolver->numberRows();
2790                                double * dualRowSolution =
2791                                    lpSolver->dualRowSolution();
2792                                for (iRow = 0; iRow < numberRows; iRow++)
2793                                    dualRowSolution[iRow] *= objScale;
2794                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2795                            }
2796                            ClpSolve::SolveType method;
2797                            ClpSolve::PresolveType presolveType;
2798                            ClpSimplex * model2 = lpSolver;
2799                            if (dualize) {
2800                                bool tryIt = true;
2801                                double fractionColumn = 1.0;
2802                                double fractionRow = 1.0;
2803                                if (dualize == 3) {
2804                                    dualize = 1;
2805                                    int numberColumns = lpSolver->numberColumns();
2806                                    int numberRows = lpSolver->numberRows();
2807                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2808                                        tryIt = false;
2809                                    } else {
2810                                        fractionColumn = 0.1;
2811                                        fractionRow = 0.1;
2812                                    }
2813                                }
2814                                if (tryIt) {
2815                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2816                                    if (model2) {
2817                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2818                                                model2->numberRows(), model2->numberColumns());
2819                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2820                                        << generalPrint
2821                                        << CoinMessageEol;
2822                                        model2->setOptimizationDirection(1.0);
2823                                    } else {
2824                                        model2 = lpSolver;
2825                                        dualize = 0;
2826                                    }
2827                                } else {
2828                                    dualize = 0;
2829                                }
2830                            }
2831                            if (noPrinting_)
2832                                lpSolver->setLogLevel(0);
2833                            ClpSolve solveOptions;
2834                            solveOptions.setPresolveActions(presolveOptions);
2835                            solveOptions.setSubstitution(substitution);
2836                            if (preSolve != 5 && preSolve) {
2837                                presolveType = ClpSolve::presolveNumber;
2838                                if (preSolve < 0) {
2839                                    preSolve = - preSolve;
2840                                    if (preSolve <= 100) {
2841                                        presolveType = ClpSolve::presolveNumber;
2842                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2843                                                preSolve);
2844                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2845                                        << generalPrint
2846                                        << CoinMessageEol;
2847                                        solveOptions.setDoSingletonColumn(true);
2848                                    } else {
2849                                        preSolve -= 100;
2850                                        presolveType = ClpSolve::presolveNumberCost;
2851                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2852                                                preSolve);
2853                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2854                                        << generalPrint
2855                                        << CoinMessageEol;
2856                                    }
2857                                }
2858                            } else if (preSolve) {
2859                                presolveType = ClpSolve::presolveOn;
2860                            } else {
2861                                presolveType = ClpSolve::presolveOff;
2862                            }
2863                            solveOptions.setPresolveType(presolveType, preSolve);
2864                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2865                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
2866                                method = ClpSolve::useDual;
2867                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
2868                                method = ClpSolve::usePrimalorSprint;
2869                            } else {
2870                                method = ClpSolve::useBarrier;
2871                                if (crossover == 1) {
2872                                    method = ClpSolve::useBarrierNoCross;
2873                                } else if (crossover == 2) {
2874                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2875                                    if (obj->type() > 1) {
2876                                        method = ClpSolve::useBarrierNoCross;
2877                                        presolveType = ClpSolve::presolveOff;
2878                                        solveOptions.setPresolveType(presolveType, preSolve);
2879                                    }
2880                                }
2881                            }
2882                            solveOptions.setSolveType(method);
2883                            if (preSolveFile)
2884                                presolveOptions |= 0x40000000;
2885                            solveOptions.setSpecialOption(4, presolveOptions);
2886                            solveOptions.setSpecialOption(5, printOptions);
2887                            if (doVector) {
2888                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2889                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2890                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2891                                    clpMatrix->makeSpecialColumnCopy();
2892                                }
2893                            }
2894                            if (method == ClpSolve::useDual) {
2895                                // dual
2896                                if (doCrash)
2897                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2898                                else if (doIdiot)
2899                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2900                            } else if (method == ClpSolve::usePrimalorSprint) {
2901                                // primal
2902                                // if slp turn everything off
2903                                if (slpValue > 0) {
2904                                    doCrash = false;
2905                                    doSprint = 0;
2906                                    doIdiot = -1;
2907                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2908                                    method = ClpSolve::usePrimal;
2909                                }
2910                                if (doCrash) {
2911                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2912                                } else if (doSprint > 0) {
2913                                    // sprint overrides idiot
2914                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2915                                } else if (doIdiot > 0) {
2916                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2917                                } else if (slpValue <= 0) {
2918                                    if (doIdiot == 0) {
2919                                        if (doSprint == 0)
2920                                            solveOptions.setSpecialOption(1, 4); // all slack
2921                                        else
2922                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2923                                    } else {
2924                                        if (doSprint == 0)
2925                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2926                                        else
2927                                            solveOptions.setSpecialOption(1, 7); // initiative
2928                                    }
2929                                }
2930                                if (basisHasValues == -1)
2931                                    solveOptions.setSpecialOption(1, 11); // switch off values
2932                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2933                                int barrierOptions = choleskyType;
2934                                if (scaleBarrier)
2935                                    barrierOptions |= 8;
2936                                if (doKKT)
2937                                    barrierOptions |= 16;
2938                                if (gamma)
2939                                    barrierOptions |= 32 * gamma;
2940                                if (crossover == 3)
2941                                    barrierOptions |= 256; // try presolve in crossover
2942                                solveOptions.setSpecialOption(4, barrierOptions);
2943                            }
2944                            model2->setMaximumSeconds(model_.getMaximumSeconds());
2945#ifdef COIN_HAS_LINK
2946                            OsiSolverInterface * coinSolver = model_.solver();
2947                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2948                            if (!linkSolver) {
2949                                model2->initialSolve(solveOptions);
2950                            } else {
2951                                // special solver
2952                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
2953                                double * solution = NULL;
2954                                if (testOsiOptions < 10) {
2955                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2956                                } else if (testOsiOptions >= 10) {
2957                                    CoinModel coinModel = *linkSolver->coinModel();
2958                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2959                                    assert (tempModel);
2960                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2961                                    model2->setObjectiveValue(tempModel->objectiveValue());
2962                                    model2->setProblemStatus(tempModel->problemStatus());
2963                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2964                                    delete tempModel;
2965                                }
2966                                if (solution) {
2967                                    memcpy(model2->primalColumnSolution(), solution,
2968                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2969                                    delete [] solution;
2970                                } else {
2971                                    printf("No nonlinear solution\n");
2972                                }
2973                            }
2974#else
2975                            model2->initialSolve(solveOptions);
2976#endif
2977                            {
2978                                // map states
2979                                /* clp status
2980                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2981                                   0 - optimal
2982                                   1 - primal infeasible
2983                                   2 - dual infeasible
2984                                   3 - stopped on iterations or time
2985                                   4 - stopped due to errors
2986                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2987                                /* cbc status
2988                                   -1 before branchAndBound
2989                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2990                                   (or check value of best solution)
2991                                   1 stopped - on maxnodes, maxsols, maxtime
2992                                   2 difficulties so run was abandoned
2993                                   (5 event user programmed event occurred) */
2994                                /* clp secondary status of problem - may get extended
2995                                   0 - none
2996                                   1 - primal infeasible because dual limit reached OR probably primal
2997                                   infeasible but can't prove it (main status 4)
2998                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2999                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
3000                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
3001                                   5 - giving up in primal with flagged variables
3002                                   6 - failed due to empty problem check
3003                                   7 - postSolve says not optimal
3004                                   8 - failed due to bad element check
3005                                   9 - status was 3 and stopped on time
3006                                   100 up - translation of enum from ClpEventHandler
3007                                */
3008                                /* cbc secondary status of problem
3009                                   -1 unset (status_ will also be -1)
3010                                   0 search completed with solution
3011                                   1 linear relaxation not feasible (or worse than cutoff)
3012                                   2 stopped on gap
3013                                   3 stopped on nodes
3014                                   4 stopped on time
3015                                   5 stopped on user event
3016                                   6 stopped on solutions
3017                                   7 linear relaxation unbounded
3018                                   8 stopped on iterations limit
3019                                */
3020                                int iStatus = model2->status();
3021                                int iStatus2 = model2->secondaryStatus();
3022                                if (iStatus == 0) {
3023                                    iStatus2 = 0;
3024                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
3025                                        // set best solution in model as no integers
3026                                        model_.setBestSolution(model2->primalColumnSolution(),
3027                                                               model2->numberColumns(),
3028                                                               model2->getObjValue()*
3029                                                               model2->getObjSense());
3030                                    }
3031                                } else if (iStatus == 1) {
3032                                    iStatus = 0;
3033                                    iStatus2 = 1; // say infeasible
3034                                } else if (iStatus == 2) {
3035                                    iStatus = 0;
3036                                    iStatus2 = 7; // say unbounded
3037                                } else if (iStatus == 3) {
3038                                    iStatus = 1;
3039                                    if (iStatus2 == 9)  // what does 9 mean ?????????????
3040                                        iStatus2 = 4;
3041                                    else
3042                                        iStatus2 = 3; // Use nodes - as closer than solutions
3043                                } else if (iStatus == 4) {
3044                                    iStatus = 2; // difficulties
3045                                    iStatus2 = 0;
3046                                }
3047                                model_.setProblemStatus(iStatus);
3048                                model_.setSecondaryStatus(iStatus2);
3049                                if ((iStatus == 2 || iStatus2 > 0) &&
3050                                    !noPrinting_) {
3051                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
3052                                   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"};
3053                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
3054                                           statusName[iStatus].c_str(), 
3055                                           minor[iStatus2].c_str());
3056                                   sprintf(generalPrint + strlen(generalPrint),
3057                                           "Enumerated nodes:           0\n");
3058                                   sprintf(generalPrint + strlen(generalPrint), 
3059                                           "Total iterations:           0\n");
3060#if CBC_QUIET == 0
3061                                   sprintf(generalPrint + strlen(generalPrint),
3062                                           "Time (CPU seconds):         %.2f\n", 
3063                                           CoinCpuTime() - time0);
3064                                   sprintf(generalPrint + strlen(generalPrint),
3065                                           "Time (Wallclock Seconds):   %.2f\n", 
3066                                           CoinGetTimeOfDay()-time0Elapsed);
3067#endif
3068                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
3069                                      << generalPrint
3070                                      << CoinMessageEol;
3071                                }
3072                                //assert (lpSolver==clpSolver->getModelPtr());
3073                                assert (clpSolver == model_.solver());
3074                                clpSolver->setWarmStart(NULL);
3075                                // and in babModel if exists
3076                                if (babModel_) {
3077                                    babModel_->setProblemStatus(iStatus);
3078                                    babModel_->setSecondaryStatus(iStatus2);
3079                                }
3080                                int returnCode = callBack(&model, 1);
3081                                if (returnCode) {
3082                                    // exit if user wants
3083                                    delete babModel_;
3084                                    babModel_ = NULL;
3085                                    return returnCode;
3086                                }
3087                            }
3088                            basisHasValues = 1;
3089                            if (dualize) {
3090                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
3091                                if (model2->status() == 3)
3092                                    returnCode = 0;
3093                                delete model2;
3094                                if (returnCode && dualize != 2)
3095                                    lpSolver->primal(1);
3096                                model2 = lpSolver;
3097                            }
3098#ifdef COIN_HAS_ASL
3099                            if (statusUserFunction_[0]) {
3100                                double value = model2->getObjValue();
3101                                char buf[300];
3102                                int pos = 0;
3103                                int iStat = model2->status();
3104                                if (iStat == 0) {
3105                                    pos += sprintf(buf + pos, "optimal," );
3106                                } else if (iStat == 1) {
3107                                    // infeasible
3108                                    pos += sprintf(buf + pos, "infeasible,");
3109                                } else if (iStat == 2) {
3110                                    // unbounded
3111                                    pos += sprintf(buf + pos, "unbounded,");
3112                                } else if (iStat == 3) {
3113                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
3114                                } else if (iStat == 4) {
3115                                    iStat = 7;
3116                                    pos += sprintf(buf + pos, "stopped on difficulties,");
3117                                } else if (iStat == 5) {
3118                                    iStat = 3;
3119                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
3120                                } else if (iStat == 6) {
3121                                    // bab infeasible
3122                                    pos += sprintf(buf + pos, "integer infeasible,");
3123                                    iStat = 1;
3124                                } else {
3125                                    pos += sprintf(buf + pos, "status unknown,");
3126                                    iStat = 6;
3127                                }
3128                                info.problemStatus = iStat;
3129                                info.objValue = value;
3130                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3131                                               value);
3132                                sprintf(buf + pos, "\n%d iterations",
3133                                        model2->getIterationCount());
3134                                free(info.primalSolution);
3135                                int numberColumns = model2->numberColumns();
3136                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3137                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
3138                                int numberRows = model2->numberRows();
3139                                free(info.dualSolution);
3140                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3141                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
3142                                CoinWarmStartBasis * basis = model2->getBasis();
3143                                free(info.rowStatus);
3144                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3145                                free(info.columnStatus);
3146                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3147                                // Put basis in
3148                                int i;
3149                                // free,basic,ub,lb are 0,1,2,3
3150                                for (i = 0; i < numberRows; i++) {
3151                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3152                                    info.rowStatus[i] = status;
3153                                }
3154                                for (i = 0; i < numberColumns; i++) {
3155                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3156                                    info.columnStatus[i] = status;
3157                                }
3158                                // put buffer into info
3159                                strcpy(info.buffer, buf);
3160                                delete basis;
3161                            }
3162#endif
3163                        } else {
3164                          sprintf(generalPrint, "** Current model not valid");
3165                          printGeneralMessage(model_,generalPrint);
3166                        }
3167                        break;
3168                    case CLP_PARAM_ACTION_STATISTICS:
3169                        if (goodModel) {
3170                            // If presolve on look at presolved
3171                            bool deleteModel2 = false;
3172                            ClpSimplex * model2 = lpSolver;
3173                            if (preSolve) {
3174                                ClpPresolve pinfo;
3175                                int presolveOptions2 = presolveOptions&~0x40000000;
3176                                if ((presolveOptions2&0xffff) != 0)
3177                                    pinfo.setPresolveActions(presolveOptions2);
3178                                pinfo.setSubstitution(substitution);
3179                                if ((printOptions&1) != 0)
3180                                    pinfo.statistics();
3181                                double presolveTolerance =
3182                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
3183                                model2 =
3184                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
3185                                                         true, preSolve);
3186                                if (model2) {
3187                                    printf("Statistics for presolved model\n");
3188                                    deleteModel2 = true;
3189                                } else {
3190                                    printf("Presolved model looks infeasible - will use unpresolved\n");
3191                                    model2 = lpSolver;
3192                                }
3193                            } else {
3194                                printf("Statistics for unpresolved model\n");
3195                                model2 =  lpSolver;
3196                            }
3197                            statistics(lpSolver, model2);
3198                            if (deleteModel2)
3199                                delete model2;
3200                        } else {
3201                          sprintf(generalPrint, "** Current model not valid");
3202                          printGeneralMessage(model_,generalPrint);
3203                        }
3204                        break;
3205                    case CLP_PARAM_ACTION_TIGHTEN:
3206                        if (goodModel) {
3207                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
3208                            if (numberInfeasibilities) {
3209                              sprintf(generalPrint,"** Analysis indicates model infeasible");
3210                              printGeneralMessage(model_,generalPrint);
3211                            }
3212                        } else {
3213                          sprintf(generalPrint, "** Current model not valid");
3214                          printGeneralMessage(model_,generalPrint);
3215                        }
3216                        break;
3217                    case CLP_PARAM_ACTION_PLUSMINUS:
3218                        if (goodModel) {
3219                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3220                            ClpPackedMatrix* clpMatrix =
3221                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3222                            if (clpMatrix) {
3223                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
3224                                if (newMatrix->getIndices()) {
3225                                    lpSolver->replaceMatrix(newMatrix);
3226                                    delete saveMatrix;
3227                                    sprintf(generalPrint, "Matrix converted to +- one matrix");
3228                                    printGeneralMessage(model_,generalPrint);
3229                                } else {
3230                                  sprintf(generalPrint, "Matrix can not be converted to +- 1 matrix");
3231                                  printGeneralMessage(model_,generalPrint);
3232                                }
3233                            } else {
3234                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3235                              printGeneralMessage(model_,generalPrint);
3236                            }
3237                        } else {
3238                          sprintf(generalPrint, "** Current model not valid");
3239                          printGeneralMessage(model_,generalPrint);
3240                        }
3241                        break;
3242                    case CLP_PARAM_ACTION_OUTDUPROWS:
3243                        dominatedCuts = true;
3244#ifdef JJF_ZERO
3245                        if (goodModel) {
3246                            int numberRows = clpSolver->getNumRows();
3247                            //int nOut = outDupRow(clpSolver);
3248                            CglDuplicateRow dupcuts(clpSolver);
3249                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
3250                            int nOut = numberRows - clpSolver->getNumRows();
3251                            if (nOut && !noPrinting_)
3252                                sprintf(generalPrint, "%d rows eliminated", nOut);
3253                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
3254                            << generalPrint
3255                            << CoinMessageEol;
3256                        } else {
3257                          sprintf(generalPrint, "** Current model not valid");
3258                          printGeneralMessage(model_,generalPrint);
3259                        }
3260#endif
3261                        break;
3262                    case CLP_PARAM_ACTION_NETWORK:
3263                        if (goodModel) {
3264                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3265                            ClpPackedMatrix* clpMatrix =
3266                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3267                            if (clpMatrix) {
3268                                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
3269                                if (newMatrix->getIndices()) {
3270                                    lpSolver->replaceMatrix(newMatrix);
3271                                    delete saveMatrix;
3272                                    sprintf(generalPrint, "Matrix converted to network matrix");
3273                                    printGeneralMessage(model_,generalPrint);
3274                                } else {
3275                                  sprintf(generalPrint, "Matrix can not be converted to network matrix");
3276                                  printGeneralMessage(model_,generalPrint);
3277                                }
3278                            } else {
3279                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3280                              printGeneralMessage(model_,generalPrint);
3281                            }
3282                        } else {
3283                          sprintf(generalPrint, "** Current model not valid");
3284                          printGeneralMessage(model_,generalPrint);
3285                        }
3286                        break;
3287                    case CBC_PARAM_ACTION_DOHEURISTIC:
3288                        if (goodModel) {
3289#ifndef CBC_USE_INITIAL_TIME
3290                          if (model_.useElapsedTime())
3291                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
3292                          else
3293                            model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
3294#endif
3295                            int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue();
3296                            if (vubAction != -1) {
3297                                // look at vubs
3298                                // extra1 is number of ints to leave free
3299                                // Just ones which affect >= extra3
3300                                int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
3301                                /* 2 is cost above which to fix if feasible
3302                                   3 is fraction of integer variables fixed if relaxing (0.97)
3303                                   4 is fraction of all variables fixed if relaxing (0.0)
3304                                */
3305                                double dextra[6];
3306                                int extra[5];
3307                                extra[1] = parameters_[whichParam(CBC_PARAM_INT_EXTRA1, numberParameters_, parameters_)].intValue();
3308                                int exp1 = parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_,
3309                                                                  parameters_)].intValue();
3310                                if (exp1 == 4 && extra[1] == -1)
3311                                    extra[1] = 999998;
3312                                dextra[1] = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
3313                                dextra[2] = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
3314                                dextra[3] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3315                                dextra[4] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
3316                                dextra[5] = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA5, numberParameters_, parameters_)].doubleValue();
3317                                if (!dextra[3])
3318                                    dextra[3] = 0.97;
3319                                //OsiClpSolverInterface * newSolver =
3320                                fixVubs(model_, extra3, vubAction, generalMessageHandler,
3321                                        debugValues, dextra, extra);
3322                                //assert (!newSolver);
3323                            }
3324                            // Actually do heuristics
3325                            // may need to flip objective
3326                            bool needFlip = model_.solver()->getObjSense()<0.0;
3327                            if (needFlip)
3328                              model_.flipModel(); 
3329                            //if we do then - fix priorities in clonebutmodel_.convertToDynamic();
3330                            bool objectsExist = model_.objects() != NULL;
3331                            if (!objectsExist) {
3332                              model_.findIntegers(false);
3333                              model_.convertToDynamic();
3334                            }
3335                            // set priorities etc
3336                            if (priorities) {
3337                              OsiObject ** objects = model_.objects();
3338                              int numberObjects = model_.numberObjects();
3339                              for (int iObj = 0; iObj < numberObjects; iObj++) {
3340                                CbcSimpleInteger * obj =
3341                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
3342                                if (!obj)
3343                                  continue;
3344                                int iColumn = obj->columnNumber();
3345                                if (branchDirection) {
3346                                  obj->setPreferredWay(branchDirection[iColumn]);
3347                                }
3348                                if (priorities) {
3349                                  int iPriority = priorities[iColumn];
3350                                  if (iPriority > 0)
3351                                    obj->setPriority(iPriority);
3352                                }
3353                                if (pseudoUp && pseudoUp[iColumn]) {
3354                                  CbcSimpleIntegerPseudoCost * obj1a =
3355                                    dynamic_cast <CbcSimpleIntegerPseudoCost *>(objects[iObj]) ;
3356                                  assert (obj1a);
3357                                  if (pseudoDown[iColumn] > 0.0)
3358                                    obj1a->setDownPseudoCost(pseudoDown[iColumn]);
3359                                  if (pseudoUp[iColumn] > 0.0)
3360                                    obj1a->setUpPseudoCost(pseudoUp[iColumn]);
3361                                }
3362                              }
3363                            }
3364                            doHeuristics(&model_, 2, parameters_,
3365                                         numberParameters_, noPrinting_, initialPumpTune);
3366                            if (!objectsExist) {
3367                              model_.deleteObjects(false);
3368                            }
3369                            if (needFlip)
3370                              model_.flipModel();
3371                            if (model_.bestSolution()) {
3372                                model_.setProblemStatus(1);
3373                                model_.setSecondaryStatus(6);
3374#ifdef COIN_HAS_ASL
3375                                if (statusUserFunction_[0]) {
3376                                    double value = model_.getObjValue();
3377                                    char buf[300];
3378                                    int pos = 0;
3379                                    pos += sprintf(buf + pos, "feasible,");
3380                                    info.problemStatus = 0;
3381                                    info.objValue = value;
3382                                    pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3383                                                   value);
3384                                    sprintf(buf + pos, "\n0 iterations");
3385                                    free(info.primalSolution);
3386                                    int numberColumns = lpSolver->numberColumns();
3387                                    info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3388                                    CoinCopyN(model_.bestSolution(), numberColumns, info.primalSolution);
3389                                    int numberRows = lpSolver->numberRows();
3390                                    free(info.dualSolution);
3391                                    info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3392                                    CoinZeroN(info.dualSolution, numberRows);
3393                                    CoinWarmStartBasis * basis = lpSolver->getBasis();
3394                                    free(info.rowStatus);
3395                                    info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3396                                    free(info.columnStatus);
3397                                    info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3398                                    // Put basis in
3399                                    int i;
3400                                    // free,basic,ub,lb are 0,1,2,3
3401                                    for (i = 0; i < numberRows; i++) {
3402                                        CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3403                                        info.rowStatus[i] = status;
3404                                    }
3405                                    for (i = 0; i < numberColumns; i++) {
3406                                        CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3407                                        info.columnStatus[i] = status;
3408                                    }
3409                                    // put buffer into info
3410                                    strcpy(info.buffer, buf);
3411                                    delete basis;
3412                                }
3413#endif
3414                            }
3415                            int returnCode = callBack(&model, 6);
3416                            if (returnCode) {
3417                                // exit if user wants
3418                                delete babModel_;
3419                                babModel_ = NULL;
3420                                return returnCode;
3421                            }
3422                        }
3423                        break;
3424                    case CBC_PARAM_ACTION_MIPLIB:
3425                        // User can set options - main difference is lack of model and CglPreProcess
3426                        goodModel = true;
3427                        parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValue(0);
3428                        /*
3429                          Run branch-and-cut. First set a few options -- node comparison, scaling.
3430                          Print elapsed time at the end.
3431                        */
3432                    case CBC_PARAM_ACTION_BAB: // branchAndBound
3433                        // obsolete case STRENGTHEN:
3434                        if (goodModel) {
3435                            bool miplib = type == CBC_PARAM_ACTION_MIPLIB;
3436                            int logLevel = parameters_[slog].intValue();
3437                            int truncateColumns=COIN_INT_MAX;
3438                            int truncateRows=-1;
3439                            bool redoSOS=false;
3440                            double * truncatedRhsLower=NULL;
3441                            double * truncatedRhsUpper=NULL;
3442                            int * newPriorities=NULL;
3443                            // Reduce printout
3444                            if (logLevel <= 1) {
3445                                model_.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3446                            } else {
3447                                model_.solver()->setHintParam(OsiDoReducePrint, false, OsiHintTry);
3448                            }
3449                            {
3450                                OsiSolverInterface * solver = model_.solver();
3451#ifndef CBC_OTHER_SOLVER
3452                                OsiClpSolverInterface * si =
3453                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3454                                assert (si != NULL);
3455                                si->getModelPtr()->scaling(doScaling);
3456                                ClpSimplex * lpSolver = si->getModelPtr();
3457                                // deal with positive edge
3458                                double psi = parameters_[whichParam(CLP_PARAM_DBL_PSI, numberParameters_, parameters_)].doubleValue();
3459                                if (psi>0.0) {
3460                                  ClpDualRowPivot * dualp = lpSolver->dualRowPivot();
3461                                  ClpDualRowSteepest * d1 = dynamic_cast<ClpDualRowSteepest *>(dualp);
3462                                  ClpDualRowDantzig * d2 = dynamic_cast<ClpDualRowDantzig *>(dualp);
3463                                  if (d1) {
3464                                    ClpPEDualRowSteepest p(psi,d1->mode());
3465                                    lpSolver->setDualRowPivotAlgorithm(p);
3466                                  } else if (d2) {
3467                                    ClpPEDualRowDantzig p(psi);
3468                                    lpSolver->setDualRowPivotAlgorithm(p);
3469                                  }
3470                                  ClpPrimalColumnPivot * primalp = lpSolver->primalColumnPivot();
3471                                  ClpPrimalColumnSteepest * p1 = dynamic_cast<ClpPrimalColumnSteepest *>(primalp);
3472                                  ClpPrimalColumnDantzig * p2 = dynamic_cast<ClpPrimalColumnDantzig *>(primalp);
3473                                  if (p1) {
3474                                    ClpPEPrimalColumnSteepest p(psi,p1->mode());
3475                                    lpSolver->setPrimalColumnPivotAlgorithm(p);
3476                                  } else if (p2) {
3477                                    ClpPEPrimalColumnDantzig p(psi);
3478                                    lpSolver->setPrimalColumnPivotAlgorithm(p);
3479                                  }
3480                                }
3481                                if (doVector) {
3482                                    ClpMatrixBase * matrix = lpSolver->clpMatrix();
3483                                    if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
3484                                        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
3485                                        clpMatrix->makeSpecialColumnCopy();
3486                                    }
3487                                }
3488#elif CBC_OTHER_SOLVER==1
3489                                OsiCpxSolverInterface * si =
3490                                    dynamic_cast<OsiCpxSolverInterface *>(solver) ;
3491                                assert (si != NULL);
3492#endif
3493                                statistics_nrows = si->getNumRows();
3494                                statistics_ncols = si->getNumCols();
3495                                statistics_nprocessedrows = si->getNumRows();
3496                                statistics_nprocessedcols = si->getNumCols();
3497                                // See if quadratic
3498#ifndef CBC_OTHER_SOLVER
3499#ifdef COIN_HAS_LINK
3500                                if (!complicatedInteger) {
3501                                    ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(lpSolver->objectiveAsObject()));
3502                                    if (obj) {
3503                                        preProcess = 0;
3504                                        int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
3505                                        parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(CoinMax(0, testOsiOptions));
3506                                        // create coin model
3507                                        coinModel = lpSolver->createCoinModel();
3508                                        assert (coinModel);
3509                                        // load from coin model
3510                                        OsiSolverLink solver1;
3511                                        OsiSolverInterface * solver2 = solver1.clone();
3512                                        model_.assignSolver(solver2, false);
3513                                        OsiSolverLink * si =
3514                                            dynamic_cast<OsiSolverLink *>(model_.solver()) ;
3515                                        assert (si != NULL);
3516                                        si->setDefaultMeshSize(0.001);
3517                                        // need some relative granularity
3518                                        si->setDefaultBound(100.0);
3519                                        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
3520                                        if (dextra3)
3521                                            si->setDefaultMeshSize(dextra3);
3522                                        si->setDefaultBound(1000.0);
3523                                        si->setIntegerPriority(1000);
3524                                        si->setBiLinearPriority(10000);
3525                                        biLinearProblem=true;
3526                                        si->setSpecialOptions2(2 + 4 + 8);
3527                                        CoinModel * model2 = coinModel;
3528                                        si->load(*model2, true, parameters_[log].intValue());
3529                                        // redo
3530                                        solver = model_.solver();
3531                                        clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
3532                                        lpSolver = clpSolver->getModelPtr();
3533                                        clpSolver->messageHandler()->setLogLevel(0) ;
3534                                        testOsiParameters = 0;
3535                                        complicatedInteger = 2;  // allow cuts
3536                                        OsiSolverInterface * coinSolver = model_.solver();
3537                                        OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
3538                                        if (linkSolver->quadraticModel()) {
3539                                            ClpSimplex * qp = linkSolver->quadraticModel();
3540                                            //linkSolver->nonlinearSLP(CoinMax(slpValue,10),1.0e-5);
3541                                            qp->nonlinearSLP(CoinMax(slpValue, 40), 1.0e-5);
3542                                            qp->primal(1);
3543                                            OsiSolverLinearizedQuadratic solver2(qp);
3544                                            const double * solution = NULL;
3545                                            // Reduce printout
3546                                            solver2.setHintParam(OsiDoReducePrint, true, OsiHintTry);
3547                                            CbcModel model2(solver2);
3548                                            // Now do requested saves and modifications
3549                                            CbcModel * cbcModel = & model2;
3550                                            OsiSolverInterface * osiModel = model2.solver();
3551                                            OsiClpSolverInterface * osiclpModel = dynamic_cast< OsiClpSolverInterface*> (osiModel);
3552                                            ClpSimplex * clpModel = osiclpModel->getModelPtr();
3553
3554                                            // Set changed values
3555
3556                                            CglProbing probing;
3557                                            probing.setMaxProbe(10);
3558                                            probing.setMaxLook(10);
3559                                            probing.setMaxElements(200);
3560                                            probing.setMaxProbeRoot(50);
3561                                            probing.setMaxLookRoot(10);
3562                                            probing.setRowCuts(3);
3563                                            probing.setUsingObjective(true);
3564                                            cbcModel->addCutGenerator(&probing, -1, "Probing", true, false, false, -100, -1, -1);
3565                                            cbcModel->cutGenerator(0)->setTiming(true);
3566
3567                                            CglGomory gomory;
3568                                            gomory.setLimitAtRoot(512);
3569                                            cbcModel->addCutGenerator(&gomory, -98, "Gomory", true, false, false, -100, -1, -1);
3570                                            cbcModel->cutGenerator(1)->setTiming(true);
3571
3572                                            CglKnapsackCover knapsackCover;
3573                                            cbcModel->addCutGenerator(&knapsackCover, -98, "KnapsackCover", true, false, false, -100, -1, -1);
3574                                            cbcModel->cutGenerator(2)->setTiming(true);
3575
3576                                            CglRedSplit redSplit;
3577                                            cbcModel->addCutGenerator(&redSplit, -99, "RedSplit", true, false, false, -100, -1, -1);
3578                                            cbcModel->cutGenerator(3)->setTiming(true);
3579
3580                                            CglClique clique;
3581                                            clique.setStarCliqueReport(false);
3582                                            clique.setRowCliqueReport(false);
3583                                            clique.setMinViolation(0.1);
3584                                            cbcModel->addCutGenerator(&clique, -98, "Clique", true, false, false, -100, -1, -1);
3585                                            cbcModel->cutGenerator(4)->setTiming(true);
3586
3587                                            CglMixedIntegerRounding2 mixedIntegerRounding2;
3588                                            cbcModel->addCutGenerator(&mixedIntegerRounding2, -98, "MixedIntegerRounding2", true, false, false, -100, -1, -1);
3589                                            cbcModel->cutGenerator(5)->setTiming(true);
3590
3591                                            CglFlowCover flowCover;
3592                                            cbcModel->addCutGenerator(&flowCover, -98, "FlowCover", true, false, false, -100, -1, -1);
3593                                            cbcModel->cutGenerator(6)->setTiming(true);
3594
3595                                            CglTwomir twomir;
3596                                            twomir.setMaxElements(250);
3597                                            cbcModel->addCutGenerator(&twomir, -99, "Twomir", true, false, false, -100, -1, -1);
3598                                            cbcModel->cutGenerator(7)->setTiming(true);
3599
3600                                            CbcHeuristicFPump heuristicFPump(*cbcModel);
3601                                            heuristicFPump.setWhen(13);
3602                                            heuristicFPump.setMaximumPasses(20);
3603                                            heuristicFPump.setMaximumRetries(7);
3604                                            heuristicFPump.setHeuristicName("feasibility pump");
3605                                            heuristicFPump.setInitialWeight(1);
3606                                            heuristicFPump.setFractionSmall(0.6);
3607                                            cbcModel->addHeuristic(&heuristicFPump);
3608
3609                                            CbcRounding rounding(*cbcModel);
3610                                            rounding.setHeuristicName("rounding");
3611                                            cbcModel->addHeuristic(&rounding);
3612
3613                                            CbcHeuristicLocal heuristicLocal(*cbcModel);
3614                                            heuristicLocal.setHeuristicName("combine solutions");
3615                                            heuristicLocal.setSearchType(1);
3616                                            heuristicLocal.setFractionSmall(0.6);
3617                                            cbcModel->addHeuristic(&heuristicLocal);
3618
3619                                            CbcHeuristicGreedyCover heuristicGreedyCover(*cbcModel);
3620                                            heuristicGreedyCover.setHeuristicName("greedy cover");
3621                                            cbcModel->addHeuristic(&heuristicGreedyCover);
3622
3623                                            CbcHeuristicGreedyEquality heuristicGreedyEquality(*cbcModel);
3624                                            heuristicGreedyEquality.setHeuristicName("greedy equality");
3625                                            cbcModel->addHeuristic(&heuristicGreedyEquality);
3626
3627                                            CbcCompareDefault compare;
3628                                            cbcModel->setNodeComparison(compare);
3629                                            cbcModel->setNumberBeforeTrust(5);
3630                                            cbcModel->setSpecialOptions(2);
3631                                            cbcModel->messageHandler()->setLogLevel(1);
3632                                            cbcModel->setMaximumCutPassesAtRoot(-100);
3633                                            cbcModel->setMaximumCutPasses(1);
3634                                            cbcModel->setMinimumDrop(0.05);
3635                                            // For branchAndBound this may help
3636                                            clpModel->defaultFactorizationFrequency();
3637                                            clpModel->setDualBound(1.0001e+08);
3638                                            clpModel->setPerturbation(50);
3639                                            osiclpModel->setSpecialOptions(193);
3640                                            osiclpModel->messageHandler()->setLogLevel(0);
3641                                            osiclpModel->setIntParam(OsiMaxNumIterationHotStart, 100);
3642                                            osiclpModel->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3643                                            // You can save some time by switching off message building
3644                                            // clpModel->messagesPointer()->setDetailMessages(100,10000,(int *) NULL);
3645
3646                                            // Solve
3647
3648                                            cbcModel->initialSolve();
3649                                            if (clpModel->tightenPrimalBounds() != 0) {
3650                                              sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3651                                              printGeneralMessage(model_,generalPrint);
3652                                                break;
3653                                            }
3654                                            clpModel->dual();  // clean up
3655                                            cbcModel->initialSolve();
3656#ifdef CBC_THREAD
3657                                            int numberThreads = parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].intValue();
3658                                            cbcModel->setNumberThreads(numberThreads % 100);
3659                                            cbcModel->setThreadMode(CoinMin(numberThreads / 100, 7));
3660#endif
3661                                            //setCutAndHeuristicOptions(*cbcModel);
3662                                            cbcModel->branchAndBound();
3663                                            OsiSolverLinearizedQuadratic * solver3 = dynamic_cast<OsiSolverLinearizedQuadratic *> (model2.solver());
3664                                            assert (solver3);
3665                                            solution = solver3->bestSolution();
3666                                            double bestObjectiveValue = solver3->bestObjectiveValue();
3667                                            linkSolver->setBestObjectiveValue(bestObjectiveValue);
3668                                            if (solution) {
3669                                              linkSolver->setBestSolution(solution, solver3->getNumCols());
3670                                            }
3671                                            CbcHeuristicDynamic3 dynamic(model_);
3672                                            dynamic.setHeuristicName("dynamic pass thru");
3673                                            model_.addHeuristic(&dynamic);
3674                                            // if convex
3675                                            if ((linkSolver->specialOptions2()&4) != 0 && solution) {
3676                                                int numberColumns = coinModel->numberColumns();
3677                                                assert (linkSolver->objectiveVariable() == numberColumns);
3678                                                // add OA cut
3679                                                double offset;
3680                                                double * gradient = new double [numberColumns+1];
3681                                                memcpy(gradient, qp->objectiveAsObject()->gradient(qp, solution, offset, true, 2),
3682                                                       numberColumns*sizeof(double));
3683                                                double rhs = 0.0;
3684                                                int * column = new int[numberColumns+1];
3685                                                int n = 0;
3686                                                for (int i = 0; i < numberColumns; i++) {
3687                                                    double value = gradient[i];
3688                                                    if (fabs(value) > 1.0e-12) {
3689                                                        gradient[n] = value;
3690                                                        rhs += value * solution[i];
3691                                                        column[n++] = i;
3692                                                    }
3693                                                }
3694                                                gradient[n] = -1.0;
3695                                                column[n++] = numberColumns;
3696                                                storedAmpl.addCut(-COIN_DBL_MAX, offset + 1.0e-7, n, column, gradient);
3697                                                delete [] gradient;
3698                                                delete [] column;
3699                                            }
3700                                            // could do three way branching round a) continuous b) best solution
3701                                            printf("obj %g\n", bestObjectiveValue);
3702                                            linkSolver->initialSolve();
3703                                        }
3704                                    }
3705                                }
3706#endif
3707#endif
3708                                if (logLevel <= 1)
3709                                    si->setHintParam(OsiDoReducePrint, true, OsiHintTry);
3710#ifndef CBC_OTHER_SOLVER
3711                                si->setSpecialOptions(0x40000000);
3712#endif
3713                            }
3714                            if (!miplib) {
3715                                if (!preSolve) {
3716                                    model_.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintTry);
3717                                    model_.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintTry);
3718                                }
3719                                double time1a = CoinCpuTime();
3720                                OsiSolverInterface * solver = model_.solver();
3721#ifndef CBC_OTHER_SOLVER
3722                                OsiClpSolverInterface * si =
3723                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3724                                if (si)
3725                                    si->setSpecialOptions(si->specialOptions() | 1024);
3726#endif
3727                                model_.initialSolve();
3728#ifndef CBC_OTHER_SOLVER
3729                                ClpSimplex * clpSolver = si->getModelPtr();
3730                                int iStatus = clpSolver->status();
3731                                int iStatus2 = clpSolver->secondaryStatus();
3732                                if (iStatus == 0) {
3733                                    iStatus2 = 0;
3734                                } else if (iStatus == 1) {
3735                                    iStatus = 0;
3736                                    iStatus2 = 1; // say infeasible
3737                                } else if (iStatus == 2) {
3738                                    iStatus = 0;
3739                                    iStatus2 = 7; // say unbounded
3740                                } else if (iStatus == 3) {
3741                                    iStatus = 1;
3742                                    if (iStatus2 == 9)
3743                                        iStatus2 = 4;
3744                                    else
3745                                        iStatus2 = 3; // Use nodes - as closer than solutions
3746                                } else if (iStatus == 4) {
3747                                    iStatus = 2; // difficulties
3748                                    iStatus2 = 0;
3749                                }
3750                                model_.setProblemStatus(iStatus);
3751                                model_.setSecondaryStatus(iStatus2);
3752                                si->setWarmStart(NULL);
3753                                int returnCode = callBack(&model_, 1);
3754                                if (returnCode) {
3755                                    // exit if user wants
3756                                    delete babModel_;
3757                                    babModel_ = NULL;
3758                                    return returnCode;
3759                                }
3760                                if (clpSolver->status() > 0) {
3761                                    // and in babModel if exists
3762                                    if (babModel_) {
3763                                        babModel_->setProblemStatus(iStatus);
3764                                        babModel_->setSecondaryStatus(iStatus2);
3765                                    }
3766                                    if (!noPrinting_) {
3767                                        iStatus = clpSolver->status();
3768                                        const char * msg[] = {"infeasible", "unbounded", "stopped",
3769                                                              "difficulties", "other"
3770                                                             };
3771                                        sprintf(generalPrint, "Problem is %s - %.2f seconds",
3772                                                msg[iStatus-1], CoinCpuTime() - time1a);
3773                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
3774                                        << generalPrint
3775                                        << CoinMessageEol;
3776                                    }
3777                                    break;
3778                                }
3779                                clpSolver->setSpecialOptions(clpSolver->specialOptions() | IN_BRANCH_AND_BOUND); // say is Cbc (and in branch and bound)
3780#elif CBC_OTHER_SOLVER==1
3781#endif
3782                                if (!noPrinting_) {
3783                                    sprintf(generalPrint, "Continuous objective value is %g - %.2f seconds",
3784                                            solver->getObjValue(), CoinCpuTime() - time1a);
3785                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
3786                                    << generalPrint
3787                                    << CoinMessageEol;
3788                                }
3789                                if (model_.getMaximumNodes() == -987654321) {
3790                                    // See if No objective!
3791                                    int numberColumns = clpSolver->getNumCols();
3792                                    const double * obj = clpSolver->getObjCoefficients();
3793                                    const double * lower = clpSolver->getColLower();
3794                                    const double * upper = clpSolver->getColUpper();
3795                                    int nObj = 0;
3796                                    for (int i = 0; i < numberColumns; i++) {
3797                                        if (upper[i] > lower[i] && obj[i])
3798                                            nObj++;
3799                                    }
3800                                    if (!nObj) {
3801                                        printf("************No objective!!\n");
3802                                        model_.setMaximumSolutions(1);
3803                                        // Column copy
3804                                        CoinPackedMatrix  matrixByCol(*model_.solver()->getMatrixByCol());
3805                                        //const double * element = matrixByCol.getElements();
3806                                        //const int * row = matrixByCol.getIndices();
3807                                        //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
3808                                        const int * columnLength = matrixByCol.getVectorLengths();
3809                                        for (int i = 0; i < numberColumns; i++) {
3810                                            double value = (CoinDrand48() + 0.5) * 10000;
3811                                            value = 10;
3812                                            value *= columnLength[i];
3813                                            int iValue = static_cast<int> (value) / 10;
3814                                            //iValue=1;
3815                                            clpSolver->setObjCoeff(i, iValue);
3816                                        }
3817                                    }
3818                                }
3819#ifndef CBC_OTHER_SOLVER
3820                                if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) {
3821                                  sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!");
3822                                  printGeneralMessage(model_,generalPrint);
3823                                    model_.setProblemStatus(0);
3824                                    model_.setSecondaryStatus(1);
3825                                    // say infeasible for solution
3826                                    integerStatus = 6;
3827                                    // and in babModel if exists
3828                                    if (babModel_) {
3829                                        babModel_->setProblemStatus(0);
3830                                        babModel_->setSecondaryStatus(1);
3831                                    }
3832                                    break;
3833                                }
3834                                if (clpSolver->dualBound() == 1.0e10) {
3835                                    ClpSimplex temp = *clpSolver;
3836                                    temp.setLogLevel(0);
3837                                    temp.dual(0, 7);
3838                                    // user did not set - so modify
3839                                    // get largest scaled away from bound
3840                                    double largest = 1.0e-12;
3841                                    double largestScaled = 1.0e-12;
3842                                    int numberRows = temp.numberRows();
3843                                    const double * rowPrimal = temp.primalRowSolution();
3844                                    const double * rowLower = temp.rowLower();
3845                                    const double * rowUpper = temp.rowUpper();
3846                                    const double * rowScale = temp.rowScale();
3847                                    int iRow;
3848                                    for (iRow = 0; iRow < numberRows; iRow++) {
3849                                        double value = rowPrimal[iRow];
3850                                        double above = value - rowLower[iRow];
3851                                        double below = rowUpper[iRow] - value;
3852                                        if (above < 1.0e12) {
3853                                            largest = CoinMax(largest, above);
3854                                        }
3855                                        if (below < 1.0e12) {
3856                                            largest = CoinMax(largest, below);
3857                                        }
3858                                        if (rowScale) {
3859                                            double multiplier = rowScale[iRow];
3860                                            above *= multiplier;
3861                                            below *= multiplier;
3862                                        }
3863                                        if (above < 1.0e12) {
3864                                            largestScaled = CoinMax(largestScaled, above);
3865                                        }
3866                                        if (below < 1.0e12) {
3867                                            largestScaled = CoinMax(largestScaled, below);
3868                                        }
3869                                    }
3870
3871                                    int numberColumns = temp.numberColumns();
3872                                    const double * columnPrimal = temp.primalColumnSolution();
3873                                    const double * columnLower = temp.columnLower();
3874                                    const double * columnUpper = temp.columnUpper();
3875                                    const double * columnScale = temp.columnScale();
3876                                    int iColumn;
3877                                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3878                                        double value = columnPrimal[iColumn];
3879                                        double above = value - columnLower[iColumn];
3880                                        double below = columnUpper[iColumn] - value;
3881                                        if (above < 1.0e12) {
3882                                            largest = CoinMax(largest, above);
3883                                        }
3884                                        if (below < 1.0e12) {
3885                                            largest = CoinMax(largest, below);
3886                                        }
3887                                        if (columnScale) {
3888                                            double multiplier = 1.0 / columnScale[iColumn];
3889                                            above *= multiplier;
3890                                            below *= multiplier;
3891                                        }
3892                                        if (above < 1.0e12) {
3893                                            largestScaled = CoinMax(largestScaled, above);
3894                                        }
3895                                        if (below < 1.0e12) {
3896                                            largestScaled = CoinMax(largestScaled, below);
3897                                        }
3898                                    }
3899#ifdef COIN_DEVELOP
3900                                    if (!noPrinting_)
3901                                        std::cout << "Largest (scaled) away from bound " << largestScaled
3902                                                  << " unscaled " << largest << std::endl;
3903#endif
3904                                    clpSolver->setDualBound(CoinMax(1.0001e8, CoinMin(100.0*largest, 1.00001e10)));
3905                                }
3906                                si->resolve();  // clean up
3907#endif
3908                            }
3909                            // If user made settings then use them
3910                            if (!defaultSettings) {
3911                                OsiSolverInterface * solver = model_.solver();
3912                                if (!doScaling)
3913                                    solver->setHintParam(OsiDoScale, false, OsiHintTry);
3914#ifndef CBC_OTHER_SOLVER
3915                                OsiClpSolverInterface * si =
3916                                    dynamic_cast<OsiClpSolverInterface *>(solver) ;
3917                                assert (si != NULL);
3918                                // get clp itself
3919                                ClpSimplex * modelC = si->getModelPtr();
3920                                //if (modelC->tightenPrimalBounds()!=0) {
3921                                //std::cout<<"Problem is infeasible!"<<std::endl;
3922                                //break;
3923                                //}
3924                                // bounds based on continuous
3925                                if (tightenFactor && !complicatedInteger) {
3926                                    if (modelC->tightenPrimalBounds(tightenFactor) != 0) {
3927                                      sprintf(generalPrint, "Problem is infeasible!");
3928                                      printGeneralMessage(model_,generalPrint);
3929                                        model_.setProblemStatus(0);
3930                                        model_.setSecondaryStatus(1);
3931                                        // and in babModel if exists
3932                                        if (babModel_) {
3933                                            babModel_->setProblemStatus(0);
3934                                            babModel_->setSecondaryStatus(1);
3935                                        }
3936                                        break;
3937                                    }
3938                                }
3939#endif
3940                            }
3941                            // See if we want preprocessing
3942                            OsiSolverInterface * saveSolver = NULL;
3943                            CglPreProcess process;
3944                            // Say integers in sync
3945                            bool integersOK = true;
3946                            delete babModel_;
3947                            babModel_ = new CbcModel(model_);
3948#ifndef CBC_OTHER_SOLVER
3949                            int numberChanged = 0;
3950                            OsiSolverInterface * solver3 = clpSolver->clone();
3951                            babModel_->assignSolver(solver3);
3952                            OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
3953                            if (clpSolver2->messageHandler()->logLevel())
3954                                clpSolver2->messageHandler()->setLogLevel(1);
3955                            if (logLevel > -1)
3956                                clpSolver2->messageHandler()->setLogLevel(logLevel);
3957                            lpSolver = clpSolver2->getModelPtr();
3958                            if (lpSolver->factorizationFrequency() == 200 && !miplib) {
3959                                // User did not touch preset
3960                                int numberRows = lpSolver->numberRows();
3961                                const int cutoff1 = 10000;
3962                                const int cutoff2 = 100000;
3963                                const int base = 75;
3964                                const int freq0 = 50;
3965                                const int freq1 = 200;
3966                                const int freq2 = 400;
3967                                const int maximum = 1000;
3968                                int frequency;
3969                                if (numberRows < cutoff1)
3970                                    frequency = base + numberRows / freq0;
3971                                else if (numberRows < cutoff2)
3972                                    frequency = base + cutoff1 / freq0 + (numberRows - cutoff1) / freq1;
3973                                else
3974                                    frequency = base + cutoff1 / freq0 + (cutoff2 - cutoff1) / freq1 + (numberRows - cutoff2) / freq2;
3975                                lpSolver->setFactorizationFrequency(CoinMin(maximum, frequency));
3976                            }
3977#elif CBC_OTHER_SOLVER==1
3978                            OsiSolverInterface * solver3 = model_.solver()->clone();
3979                            babModel_->assignSolver(solver3);
3980#endif
3981                            time2 = CoinCpuTime();
3982                            totalTime += time2 - time1;
3983                            //time1 = time2;
3984                            double timeLeft = babModel_->getMaximumSeconds();
3985                            int numberOriginalColumns = babModel_->solver()->getNumCols();
3986                            if (preProcess == 7) {
3987                                // use strategy instead
3988                                preProcess = 0;
3989                                useStrategy = true;
3990#ifdef COIN_HAS_LINK
3991                                // empty out any cuts
3992                                if (storedAmpl.sizeRowCuts()) {
3993                                    printf("Emptying ampl stored cuts as internal preprocessing\n");
3994                                    CglStored temp;
3995                                    storedAmpl = temp;
3996                                }
3997#endif
3998                            }
3999                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
4000                              // see whether to switch off preprocessing
4001                              // only allow SOS and integer
4002                              OsiObject ** objects = babModel_->objects();
4003                              int numberObjects = babModel_->numberObjects();
4004                              for (int iObj = 0; iObj < numberObjects; iObj++) {
4005                                CbcSOS * objSOS =
4006                                  dynamic_cast <CbcSOS *>(objects[iObj]) ;
4007                                CbcSimpleInteger * objSimpleInteger =
4008                                  dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
4009                                if (!objSimpleInteger&&!objSOS) {
4010                                  // find all integers anyway
4011                                  babModel_->findIntegers(true);
4012                                  preProcess=0;
4013                                  break;
4014                                }
4015                              }
4016                            }
4017                            if (type == CBC_PARAM_ACTION_BAB) {
4018                                double limit;
4019                                clpSolver->getDblParam(OsiDualObjectiveLimit, limit);
4020                                if (clpSolver->getObjValue()*clpSolver->getObjSense() >=
4021                                        limit*clpSolver->getObjSense())
4022                                    preProcess = 0;
4023                            }
4024                            if (mipStartBefore.size())
4025                              {
4026                                CbcModel tempModel=*babModel_;
4027                                assert (babModel_->getNumCols()==model_.getNumCols());
4028                                std::vector< std::string > colNames;
4029                                for ( int i=0 ; (i<model_.solver()->getNumCols()) ; ++i )
4030                                  colNames.push_back( model_.solver()->getColName(i) );
4031                                std::vector< double > x( model_.getNumCols(), 0.0 );
4032                                double obj;
4033                                int status = computeCompleteSolution( &tempModel, colNames, mipStartBefore, &x[0], obj );
4034                                // set cutoff ( a trifle high)
4035                                if (!status) {
4036                                  double newCutoff = CoinMin(babModel_->getCutoff(),obj+1.0e-4);
4037                                  babModel_->setBestSolution( &x[0], static_cast<int>(x.size()), obj, false );
4038                                  babModel_->setCutoff(newCutoff);
4039                                  babModel_->setSolutionCount(1);
4040                                  model_.setBestSolution( &x[0], static_cast<int>(x.size()), obj, false );
4041                                  model_.setCutoff(newCutoff);
4042                                  model_.setSolutionCount(1);
4043                                }
4044                              }
4045                            if (preProcess && type == CBC_PARAM_ACTION_BAB) {
4046#ifndef CBC_OTHER_SOLVER
4047                                // See if sos from mps file
4048                                if (numberSOS == 0 && clpSolver->numberSOS() && doSOS) {
4049                                    // SOS
4050                                    numberSOS = clpSolver->numberSOS();
4051                                    const CoinSet * setInfo = clpSolver->setInfo();
4052                                    sosStart = new int [numberSOS+1];
4053                                    sosType = new char [numberSOS];
4054                                    int i;
4055                                    int nTotal = 0;
4056                                    sosStart[0] = 0;
4057                                    for ( i = 0; i < numberSOS; i++) {
4058                                        int type = setInfo[i].setType();
4059                                        int n = setInfo[i].numberEntries();
4060                                        sosType[i] = static_cast<char>(type);
4061                                        nTotal += n;
4062                                        sosStart[i+1] = nTotal;
4063                                    }
4064                                    sosIndices = new int[nTotal];
4065                                    sosReference = new double [nTotal];
4066                                    for (i = 0; i < numberSOS; i++) {
4067                                        int n = setInfo[i].numberEntries();
4068                                        const int * which = setInfo[i].which();
4069                                        const double * weights = setInfo[i].weights();
4070                                        int base = sosStart[i];
4071                                        for (int j = 0; j < n; j++) {
4072                                            int k = which[j];
4073                                            sosIndices[j+base] = k;
4074                                            sosReference[j+base] = weights ? weights[j] : static_cast<double> (j);
4075                                        }
4076                                    }
4077                                }
4078#endif
4079                                saveSolver = babModel_->solver()->clone();
4080                                /* Do not try and produce equality cliques and
4081                                   do up to 10 passes */
4082                                OsiSolverInterface * solver2;
4083                                {
4084                                    // Tell solver we are in Branch and Cut
4085                                    saveSolver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo) ;
4086                                    // Default set of cut generators
4087                                    CglProbing generator1;
4088                                    generator1.setUsingObjective(1);
4089                                    generator1.setMaxPass(1);
4090                                    generator1.setMaxPassRoot(1);
4091                                    generator1.setMaxProbeRoot(CoinMin(3000, saveSolver->getNumCols()));
4092                                    generator1.setMaxElements(100);
4093                                    generator1.setMaxElementsRoot(200);
4094                                    generator1.setMaxLookRoot(50);
4095                                    if (saveSolver->getNumCols() > 3000)
4096                                        generator1.setMaxProbeRoot(123);
4097                                    generator1.setRowCuts(3);
4098                                    // switch off duplicate columns if we have a solution
4099                                    if (model_.bestSolution()/*||debugValues*/)
4100                                      tunePreProcess |= 4096;
4101                                    if ((tunePreProcess&1) != 0) {
4102                                        // heavy probing
4103                                        generator1.setMaxPassRoot(2);
4104                                        generator1.setMaxElements(1000);
4105                                        generator1.setMaxProbeRoot(saveSolver->getNumCols());
4106                                        generator1.setMaxLookRoot(saveSolver->getNumCols());
4107                                    }
4108                                    if ((babModel_->specialOptions()&65536) != 0)
4109                                        process.setOptions(1);
4110                                    // Add in generators
4111                                    if ((model_.moreSpecialOptions()&65536)==0)
4112                                      process.addCutGenerator(&generator1);
4113                                    int translate[] = {9999, 0, 0, -3, 2, 3, -2, 9999, 4, 5};
4114                                    process.passInMessageHandler(babModel_->messageHandler());
4115                                    //process.messageHandler()->setLogLevel(babModel_->logLevel());
4116#ifdef COIN_HAS_ASL
4117                                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
4118                                        // SOS
4119                                        numberSOS = info.numberSos;
4120                                        sosStart = info.sosStart;
4121                                        sosIndices = info.sosIndices;
4122                                    }
4123#endif
4124                                    if (numberSOS && doSOS) {
4125                                        // SOS
4126                                        int numberColumns = saveSolver->getNumCols();
4127                                        char * prohibited = new char[numberColumns];
4128                                        memset(prohibited, 0, numberColumns);
4129                                        int n = sosStart[numberSOS];
4130                                        for (int i = 0; i < n; i++) {
4131                                            int iColumn = sosIndices[i];
4132                                            prohibited[iColumn] = 1;
4133                                        }
4134                                        process.passInProhibited(prohibited, numberColumns);
4135                                        delete [] prohibited;
4136                                    }
4137                                    if (0) {
4138                                     
4139                                      // Special integers
4140                                      int numberColumns = saveSolver->getNumCols();
4141                                      char * prohibited = new char[numberColumns];
4142                                      memset(prohibited, 0, numberColumns);
4143                                      const CoinPackedMatrix * matrix = saveSolver->getMatrixByCol();
4144                                      const int * columnLength = matrix->getVectorLengths();
4145                                      int numberProhibited=0;
4146                                      for (int iColumn = numberColumns-1; iColumn >=0; iColumn--) {
4147                                        if (!saveSolver->isInteger(iColumn)||
4148                                            columnLength[iColumn]>1)
4149                                          break;
4150                                        numberProhibited++;
4151                                        prohibited[iColumn] = 1;
4152                                      }
4153                                      if (numberProhibited) {
4154                                        process.passInProhibited(prohibited, numberColumns);
4155                                        printf("**** Treating last %d integers as special - give high priority?\n",numberProhibited);
4156                                      }
4157                                      delete [] prohibited;
4158                                    }
4159                                    if (!model_.numberObjects() && true) {
4160                                        /* model may not have created objects
4161                                           If none then create
4162                                        */
4163                                        model_.findIntegers(true);
4164                                    }
4165                                    if (model_.numberObjects()) {
4166                                        OsiObject ** oldObjects = babModel_->objects();
4167                                        int numberOldObjects = babModel_->numberObjects();
4168                                        if (!numberOldObjects) {
4169                                          oldObjects = model_.objects();
4170                                          numberOldObjects = model_.numberObjects();
4171                                        }
4172                                        // SOS
4173                                        int numberColumns = saveSolver->getNumCols();
4174                                        char * prohibited = new char[numberColumns];
4175                                        memset(prohibited, 0, numberColumns);
4176                                        int numberProhibited = 0;
4177                                        for (int iObj = 0; iObj < numberOldObjects; iObj++) {
4178                                            CbcSOS * obj =
4179                                                dynamic_cast <CbcSOS *>(oldObjects[iObj]) ;
4180                                            if (obj) {
4181                                                int n = obj->numberMembers();
4182                                                const int * which = obj->members();
4183                                                for (int i = 0; i < n; i++) {
4184                                                    int iColumn = which[i];
4185                                                    prohibited[iColumn] = 1;
4186                                                    numberProhibited++;
4187                                                }
4188                                            }
4189                                            CbcLotsize * obj2 =
4190                                                dynamic_cast <CbcLotsize *>(oldObjects[iObj]) ;
4191                                            if (obj2) {
4192                                                int iColumn = obj2->columnNumber();
4193                                                prohibited[iColumn] = 1;
4194                                                numberProhibited++;
4195                                            }
4196                                        }
4197                                        if (numberProhibited)
4198                                            process.passInProhibited(prohibited, numberColumns);
4199                                        delete [] prohibited;
4200                                    }
4201                                    int numberPasses = 10;
4202#ifndef CBC_OTHER_SOLVER
4203                                    if (doSprint > 0) {
4204                                        // Sprint for primal solves
4205                                        ClpSolve::SolveType method = ClpSolve::usePrimalorSprint;
4206                                        ClpSolve::PresolveType presolveType = ClpSolve::presolveOff;
4207                                        int numberPasses = 5;
4208                                        int options[] = {0, 3, 0, 0, 0, 0};
4209                                        int extraInfo[] = { -1, 20, -1, -1, -1, -1};
4210                                        extraInfo[1] = doSprint;
4211                                        int independentOptions[] = {0, 0, 3};
4212                                        ClpSolve clpSolve(method, presolveType, numberPasses,
4213                                                          options, extraInfo, independentOptions);
4214                                        // say use in OsiClp
4215                                        clpSolve.setSpecialOption(6, 1);
4216                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4217                                        osiclp->setSolveOptions(clpSolve);
4218                                        osiclp->setHintParam(OsiDoDualInResolve, false);
4219                                        // switch off row copy
4220                                        osiclp->getModelPtr()->setSpecialOptions(osiclp->getModelPtr()->specialOptions() | 256);
4221                                        osiclp->getModelPtr()->setInfeasibilityCost(1.0e11);
4222                                    }
4223#endif
4224#ifndef CBC_OTHER_SOLVER
4225                                    {
4226                                        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4227                                        osiclp->setSpecialOptions(osiclp->specialOptions() | 1024);
4228                                        int savePerturbation = osiclp->getModelPtr()->perturbation();
4229                                        //#define CBC_TEMP1
4230#ifdef CBC_TEMP1
4231                                        if (savePerturbation == 50)
4232                                            osiclp->getModelPtr()->setPerturbation(52); // try less
4233#endif
4234                                        if ((model_.moreSpecialOptions()&65536)!=0)
4235                                          process.setOptions(2+4+8); // no cuts
4236                                        cbcPreProcessPointer = & process;
4237                                        int saveOptions = osiclp->getModelPtr()->moreSpecialOptions();
4238                                        if ((model_.specialOptions()&16777216)!=0&&
4239                                            model_.getCutoff()>1.0e30) {
4240                                          osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions|262144);
4241                                        }
4242#ifdef CGL_WRITEMPS
4243                                        if (debugValues) {
4244                                          process.setApplicationData(const_cast<double *>(debugValues));
4245                                        }
4246#endif
4247                                        redoSOS=true;
4248                                        solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4249                                                                               tunePreProcess);
4250                                        if (solver2) {
4251                                          model_.setOriginalColumns( process.originalColumns(), solver2->getNumCols() );
4252                                         
4253                                          osiclp->getModelPtr()->setPerturbation(savePerturbation);
4254                                          osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions);
4255                                        }
4256                                    }
4257#elif CBC_OTHER_SOLVER==1
4258                                    cbcPreProcessPointer = & process;
4259                                    redoSOS=true;
4260                                    solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses,
4261                                                                           tunePreProcess);
4262#endif
4263                                    integersOK = false; // We need to redo if CbcObjects exist
4264                                    // Tell solver we are not in Branch and Cut
4265                                    saveSolver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4266                                    if (solver2)
4267                                        solver2->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ;
4268                                }
4269#ifdef COIN_HAS_ASL
4270                                if (!solver2 && statusUserFunction_[0]) {
4271                                    // infeasible
4272                                    info.problemStatus = 1;
4273                                    info.objValue = 1.0e100;
4274                                    sprintf(info.buffer, "infeasible/unbounded by pre-processing");
4275                                    info.primalSolution = NULL;
4276                                    info.dualSolution = NULL;
4277                                    break;
4278                                }
4279#endif
4280                                if (!noPrinting_) {
4281                                    if (!solver2) {
4282                                        sprintf(generalPrint, "Pre-processing says infeasible or unbounded");
4283                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4284                                        << generalPrint
4285                                        << CoinMessageEol;
4286                                    } else {
4287                                        //printf("processed model has %d rows, %d columns and %d elements\n",
4288                                        //     solver2->getNumRows(),solver2->getNumCols(),solver2->getNumElements());
4289                                    }
4290                                }
4291                                if (!solver2) {
4292                                    // say infeasible for solution
4293                                    integerStatus = 6;
4294                                    delete saveSolver;
4295                                    saveSolver=NULL;
4296                                    model_.setProblemStatus(0);
4297                                    model_.setSecondaryStatus(1);
4298                                    babModel_->setProblemStatus(0);
4299                                    babModel_->setSecondaryStatus(1);
4300                                } else {
4301                                    statistics_nprocessedrows = solver2->getNumRows();
4302                                    statistics_nprocessedcols = solver2->getNumCols();
4303                                    model_.setProblemStatus(-1);
4304                                    babModel_->setProblemStatus(-1);
4305                                }
4306                                int returnCode = callBack(babModel_, 2);
4307                                if (returnCode) {
4308                                    // exit if user wants
4309                                    delete babModel_;
4310                                    babModel_ = NULL;
4311                                    return returnCode;
4312                                }
4313                                if (!solver2)
4314                                    break;
4315                                if (model_.bestSolution()) {
4316                                    // need to redo - in case no better found in BAB
4317                                    // just get integer part right
4318                                    const int * originalColumns = process.originalColumns();
4319                                    int numberColumns = solver2->getNumCols();
4320                                    double * bestSolution = babModel_->bestSolution();
4321                                    const double * oldBestSolution = model_.bestSolution();
4322                                    for (int i = 0; i < numberColumns; i++) {
4323                                        int jColumn = originalColumns[i];
4324                                        bestSolution[i] = oldBestSolution[jColumn];
4325                                    }
4326                                }
4327                                //solver2->resolve();
4328                                if (preProcess == 2) {
4329                                    OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4330                                    ClpSimplex * lpSolver = clpSolver2->getModelPtr();
4331                                    lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection());
4332                                    printf("Preprocessed model (minimization) on presolved.mps\n");
4333                                }
4334                                {
4335                                    // look at new integers
4336                                    int numberOriginalColumns =
4337                                        process.originalModel()->getNumCols();
4338                                    const int * originalColumns = process.originalColumns();
4339                                    OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (solver2);
4340                                    int numberColumns = osiclp2->getNumCols();
4341                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (saveSolver);
4342                                    for (int i = 0; i < numberColumns; i++) {
4343                                        int iColumn = originalColumns[i];
4344                                        if (iColumn < numberOriginalColumns) {
4345                                            if (osiclp2->isInteger(i) && !osiclp->isInteger(iColumn))
4346                                                osiclp2->setOptionalInteger(i); // say optional
4347                                        }
4348                                    }
4349                                    // redo existing SOS
4350                                    if (osiclp->numberSOS()) {
4351                                      redoSOS=false;
4352                                      int * back = new int[numberOriginalColumns];
4353                                      for (int i = 0; i < numberOriginalColumns; i++)
4354                                        back[i]=-1;
4355                                      for (int i = 0; i < numberColumns; i++) {
4356                                        int iColumn = originalColumns[i];
4357                                        back[iColumn]=i;
4358                                      }
4359                                      int numberSOSOld=osiclp->numberSOS();
4360                                      int numberSOS=osiclp2->numberSOS();
4361                                      assert (numberSOS==numberSOSOld);
4362                                      CoinSet * setInfo = const_cast<CoinSet *>(osiclp2->setInfo());
4363                                      for (int i = 0; i < numberSOS; i++) {
4364                                        //int type = setInfo[i].setType();
4365                                        int n = setInfo[i].numberEntries();
4366                                        int * which = const_cast<int *>(setInfo[i].which());
4367                                        for (int j=0;j<n;j++) {
4368                                          int iColumn = which[j];
4369                                          iColumn=back[iColumn];
4370                                          assert(iColumn>=0);
4371                                          which[j]=iColumn;
4372                                        }
4373                                      }
4374                                      delete [] back;
4375                                    }
4376                                }
4377                                // we have to keep solver2 so pass clone
4378                                solver2 = solver2->clone();
4379                                // see if extra variables wanted
4380                                int threshold = 
4381                                  parameters_[whichParam(CBC_PARAM_INT_EXTRA_VARIABLES, numberParameters_, parameters_)].intValue();
4382                                int more2 = parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].intValue();
4383                                if (threshold || (more2&(512|1024)) != 0) {
4384                                  int numberColumns = solver2->getNumCols();
4385                                  truncateRows = solver2->getNumRows();
4386                                  bool modifiedModel=false;
4387                                  int highPriority=0;
4388                                  /*
4389                                    normal - no priorities
4390                                    >10000 equal high priority
4391                                    >20000 higher priority for higher cost
4392                                  */
4393                                  if (threshold>10000) {
4394                                    highPriority=threshold/10000;
4395                                    threshold -= 10000*highPriority;
4396                                  }
4397                                  // If 1000 set then don't put obj on ne variables
4398                                  bool moveObjective=true;
4399                                  if (threshold>1000) {
4400                                    moveObjective=false;
4401                                    threshold -= 1000;
4402                                  }
4403                                  const double * columnLower = solver2->getColLower();
4404                                  const double * columnUpper = solver2->getColUpper();
4405                                  const double * objective = solver2->getObjCoefficients();
4406                                  int numberIntegers = 0;
4407                                  int numberBinary = 0;
4408                                  int numberTotalIntegers=0;
4409                                  double * obj = new double [numberColumns];
4410                                  int * which = new int [numberColumns];
4411                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4412                                    if (solver2->isInteger(iColumn)) {
4413                                      numberTotalIntegers++;
4414                                      if (columnUpper[iColumn] > columnLower[iColumn]) {
4415                                        numberIntegers++;
4416                                        if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1)
4417                                          numberBinary++;
4418                                      }
4419                                    }
4420                                  }
4421                                  int numberSort=0;
4422                                  int numberZero=0;
4423                                  int numberZeroContinuous=0;
4424                                  int numberDifferentObj=0;
4425                                  int numberContinuous=0;
4426                                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4427                                    if (columnUpper[iColumn] > columnLower[iColumn]) {
4428                                      if (solver2->isInteger(iColumn)) {
4429                                        if (!objective[iColumn]) {
4430                                          numberZero++;
4431                                        } else {
4432                                          obj[numberSort]= fabs(objective[iColumn]);
4433                                          which[numberSort++]=iColumn;
4434                                        }
4435                                      } else if (objective[iColumn]) {
4436                                        numberContinuous++;
4437                                      } else {
4438                                        numberZeroContinuous++;
4439                                      }
4440                                    }
4441                                  }
4442                                  CoinSort_2(obj,obj+numberSort,which);
4443                                  double last=obj[0];
4444                                  for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4445                                    if (fabs(obj[jColumn]-last)>1.0e-12) {
4446                                      numberDifferentObj++;
4447                                      last=obj[jColumn];
4448                                    }
4449                                  }
4450                                  numberDifferentObj++;
4451                                  sprintf(generalPrint,"Problem has %d integers (%d of which binary) and %d continuous",
4452                                         numberIntegers,numberBinary,numberColumns-numberIntegers);
4453                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4454                                    << generalPrint
4455                                    << CoinMessageEol;
4456                                  if (numberColumns>numberIntegers) {
4457                                    sprintf(generalPrint,"%d continuous have nonzero objective, %d have zero objective",
4458                                            numberContinuous,numberZeroContinuous);
4459                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4460                                      << generalPrint
4461                                      << CoinMessageEol;
4462                                  }
4463                                  sprintf(generalPrint,"%d integer have nonzero objective, %d have zero objective, %d different nonzero (taking abs)",
4464                                          numberSort,numberZero,numberDifferentObj);
4465                                  generalMessageHandler->message(CLP_GENERAL, generalMessages)
4466                                    << generalPrint
4467                                    << CoinMessageEol;
4468                                  if (numberDifferentObj<=threshold + (numberZero) ? 1 : 0 && numberDifferentObj) {
4469                                    int * backward=NULL;
4470                                    if (highPriority) {
4471                                      newPriorities = new int [numberTotalIntegers+numberDifferentObj+numberColumns];
4472                                      backward=newPriorities+numberTotalIntegers+numberDifferentObj;
4473                                      numberTotalIntegers=0;
4474                                      for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
4475                                        if (solver2->isInteger(iColumn)) {
4476                                          backward[iColumn]=numberTotalIntegers;
4477                                          newPriorities[numberTotalIntegers++]=10000;
4478                                        }
4479                                      }
4480                                    }
4481                                    int iLast=0;
4482                                    double last=obj[0];
4483                                    for (int jColumn = 1; jColumn < numberSort; jColumn++) {
4484                                      if (fabs(obj[jColumn]-last)>1.0e-12) {
4485                                        sprintf(generalPrint,"%d variables have objective of %g",
4486                                               jColumn-iLast,last);
4487                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
4488                                          << generalPrint
4489                                          << CoinMessageEol;
4490                                        iLast=jColumn;
4491                                        last=obj[jColumn];
4492                                      }
4493                                    }
4494                                    sprintf(generalPrint,"%d variables have objective of %g",
4495                                           numberSort-iLast,last);
4496                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
4497                                      << generalPrint
4498                                      << CoinMessageEol;
4499                                    int spaceNeeded=numberSort+numberDifferentObj;
4500                                    CoinBigIndex * columnAddDummy = new CoinBigIndex[numberDifferentObj+1];
4501                                    int * columnAdd = new int[spaceNeeded];
4502                                    double * elementAdd = new double[spaceNeeded];
4503                                    CoinBigIndex * rowAdd = new CoinBigIndex[numberDifferentObj+1];
4504                                    double * objectiveNew = new double[3*numberDifferentObj];
4505                                    double * lowerNew = objectiveNew+numberDifferentObj;
4506                                    double * upperNew = lowerNew+numberDifferentObj;
4507                                    memset(columnAddDummy,0,
4508                                           (numberDifferentObj+1)*sizeof(CoinBigIndex));
4509                                    iLast=0;
4510                                    last=obj[0];
4511                                    numberDifferentObj=0;
4512                                    int priorityLevel=9999;
4513                                    int numberElements=0;
4514                                    rowAdd[0]=0;
4515                                    for (int jColumn = 1; jColumn < numberSort+1; jColumn++) {
4516                                      if (jColumn==numberSort||fabs(obj[jColumn]-last)>1.0e-12) {
4517                                        // not if just one
4518                                        if (jColumn-iLast>1) {
4519                                          // do priority
4520                                          if (highPriority==1) {
4521                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4522                                              = 500;
4523                                          } else if (highPriority==2) {
4524                                            newPriorities[numberTotalIntegers+numberDifferentObj]
4525                                              = priorityLevel;
4526                                            priorityLevel--;
4527                                          }
4528                                          int iColumn=which[iLast];
4529                                          objectiveNew[numberDifferentObj]=objective[iColumn];
4530                                          double lower=0.0;
4531                                          double upper=0.0;
4532                                          for (int kColumn=iLast;kColumn<jColumn;kColumn++) {
4533                                            iColumn=which[kColumn];
4534                                            if (moveObjective)
4535                                              solver2->setObjCoeff(iColumn,0.0);
4536                                            double lowerValue=columnLower[iColumn];
4537                                            double upperValue=columnUpper[iColumn];
4538                                            double elementValue=-1.0;
4539                                            if (objectiveNew[numberDifferentObj]*objective[iColumn]<0.0) {
4540                                              lowerValue=-columnUpper[iColumn];
4541                                              upperValue=-columnLower[iColumn];
4542                                              elementValue=1.0;
4543                                            }
4544                                            if (!moveObjective)
4545                                              objectiveNew[numberDifferentObj]=0.0;
4546                                            columnAdd[numberElements]=iColumn;
4547                                            elementAdd[numberElements++]=elementValue;
4548                                            if (lower!=-COIN_DBL_MAX) {
4549                                              if (lowerValue!=-COIN_DBL_MAX)
4550                                                lower += lowerValue;
4551                                              else
4552                                                lower=-COIN_DBL_MAX;
4553                                            }
4554                                            if (upper!=COIN_DBL_MAX) {
4555                                              if (upperValue!=COIN_DBL_MAX)
4556                                                upper += upperValue;
4557                                              else
4558                                                upper=COIN_DBL_MAX;
4559                                            }
4560                                          }
4561                                          columnAdd[numberElements]=numberColumns+numberDifferentObj;
4562                                          elementAdd[numberElements++]=1.0;
4563                                          lowerNew[numberDifferentObj]=lower;
4564                                          upperNew[numberDifferentObj]=upper;
4565                                          numberDifferentObj++;
4566                                          rowAdd[numberDifferentObj]=numberElements;
4567                                        } else if (highPriority) {
4568                                          // just one
4569                                          // do priority
4570                                          int iColumn=which[iLast];
4571                                          int iInt=backward[iColumn];
4572                                          if (highPriority==1) {
4573                                            newPriorities[iInt] = 500;
4574                                          } else {
4575                                            newPriorities[iInt] = priorityLevel;
4576                                            priorityLevel--;
4577                                          }
4578                                        }
4579                                        if (jColumn<numberSort) {
4580                                          iLast=jColumn;
4581                                          last=obj[jColumn];
4582                                        }
4583                                      }
4584                                    }
4585                                    if (numberDifferentObj) {
4586                                      // add columns
4587                                      solver2->addCols(numberDifferentObj, 
4588                                                       columnAddDummy, NULL, NULL,
4589                                                       lowerNew, upperNew,objectiveNew);
4590                                      // add constraints and make integer if all integer in group
4591#ifdef COIN_HAS_CLP
4592                                      OsiClpSolverInterface * clpSolver2
4593                                        = dynamic_cast<OsiClpSolverInterface *> (solver2);
4594#endif
4595                                      for (int iObj=0; iObj < numberDifferentObj; iObj++) {
4596                                        lowerNew[iObj]=0.0;
4597                                        upperNew[iObj]=0.0;
4598                                        solver2->setInteger(numberColumns+iObj);
4599#ifdef COIN_HAS_CLP
4600                                        if (clpSolver2)
4601                                          clpSolver2->setOptionalInteger(numberColumns+iObj);
4602#endif
4603                                      }
4604                                      solver2->addRows(numberDifferentObj, 
4605                                                       rowAdd,columnAdd,elementAdd,
4606                                                       lowerNew, upperNew);
4607                                      sprintf(generalPrint,"Replacing model - %d new variables",numberDifferentObj);
4608                                      modifiedModel=true;
4609                                    }
4610                                    delete [] columnAdd;
4611                                    delete [] columnAddDummy;
4612                                    delete [] elementAdd;
4613                                    delete [] rowAdd;
4614                                    delete [] objectiveNew;
4615                                  }
4616                                  delete [] which;
4617                                  delete [] obj;
4618                                  if ((more2&(512|1024)) != 0) {
4619                                    // try for row slacks etc
4620                                    // later do row branching
4621                                    int iRow, iColumn;
4622                                    int numberColumns = solver2->getNumCols();
4623                                    int numberRows = solver2->getNumRows();
4624                                    int fudgeObjective = more2&512;
4625                                    int addSlacks = more2&1024;
4626                                    if (fudgeObjective) {
4627                                      bool moveObj = false;
4628                                      fudgeObjective = 0;
4629                                      const double * objective = solver2->getObjCoefficients();
4630                                      const double * columnLower = solver2->getColLower();
4631                                      const double * columnUpper = solver2->getColUpper();
4632                                      double * newValues = new double [numberColumns+1];
4633                                      int * newColumn = new int [numberColumns+1];
4634                                      bool allInteger=true;
4635                                      int n=0;
4636                                      double newLower = 0.0;
4637                                      double newUpper = 0.0;
4638                                      for (iColumn=0;iColumn<numberColumns;iColumn++) {
4639                                        if (objective[iColumn]) {
4640                                          if (!solver2->isInteger(iColumn)) {
4641                                            allInteger=false;
4642                                            break;
4643                                          } else {
4644                                            double value = objective[iColumn];
4645                                            double nearest = floor(value+0.5);
4646                                            if (fabs(value-nearest)>1.0e-8) {
4647                                              allInteger=false;
4648                                              break;
4649                                            } else {
4650                                              newValues[n]=nearest;
4651                                              newColumn[n++]=iColumn;
4652                                              if (nearest>0.0) {
4653                                                newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4654                                                newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4655                                              } else {
4656                                                newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4657                                                newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4658                                              }
4659                                            }
4660                                          }
4661                                        }
4662                                      }
4663                                      if (allInteger && n) {
4664                                        fudgeObjective = n;
4665                                        solver2->addCol(0,NULL,NULL,newLower,newUpper,0.0,"obj_col");
4666                                        solver2->setInteger(numberColumns);
4667                                        newValues[n]=-1.0;
4668                                        newColumn[n++]=numberColumns;
4669                                        solver2->addRow(n,newColumn,newValues,0.0,0.0);
4670                                        if (moveObj) {
4671                                          memset(newValues,0,numberColumns*sizeof(double));
4672                                          newValues[numberColumns]=1.0;
4673                                          solver2->setObjective(newValues);
4674                                        }
4675                                        numberRows++;
4676                                        numberColumns++;
4677                                      }
4678                                      delete [] newValues;
4679                                      delete [] newColumn;
4680                                    }
4681                                    if (addSlacks) {
4682                                      bool moveObj = false;
4683                                      addSlacks=0;
4684                                      // get row copy
4685                                      const CoinPackedMatrix * matrix = solver2->getMatrixByRow();
4686                                      const double * element = matrix->getElements();
4687                                      const int * column = matrix->getIndices();
4688                                      const CoinBigIndex * rowStart = matrix->getVectorStarts();
4689                                      const int * rowLength = matrix->getVectorLengths();
4690                                      const double * rowLower = solver2->getRowLower();
4691                                      const double * rowUpper = solver2->getRowUpper();
4692                                      const double * columnLower = solver2->getColLower();
4693                                      const double * columnUpper = solver2->getColUpper();
4694                                     
4695                                      // maximum space for additional columns
4696                                      CoinBigIndex * newColumnStart = new CoinBigIndex[numberRows+1];
4697                                      newColumnStart[0]=0;
4698                                      int * newRow = new int [numberRows];
4699                                      double * newElement = new double [numberRows]; 
4700                                      double * newObjective = new double [numberRows]; 
4701                                      double * newColumnLower = new double [numberRows]; 
4702                                      double * newColumnUpper = new double [numberRows];
4703                                      double * oldObjective = CoinCopyOfArray(solver2->getObjCoefficients(),
4704                                                                              numberColumns);
4705                                      for (iRow=0;iRow<numberRows;iRow++) {
4706                                        if (rowLower[iRow]!=rowUpper[iRow]) {
4707                                          bool allInteger=true;
4708                                          double newLower = 0.0;
4709                                          double newUpper = 0.0;
4710                                          double constantObjective=0.0;
4711                                          for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
4712                                            int iColumn = column[j];
4713                                            if (!solver2->isInteger(iColumn)) {
4714                                              allInteger=false;
4715                                              break;
4716                                            } else {
4717                                              double value = element[j];
4718                                              double nearest = floor(value+0.5);
4719                                              if (fabs(value-nearest)>1.0e-8) {
4720                                                allInteger=false;
4721                                                break;
4722                                              } else {
4723                                                if (!oldObjective[iColumn])
4724                                                  constantObjective=COIN_DBL_MAX;
4725                                                if (!constantObjective) {
4726                                                  constantObjective=oldObjective[iColumn]/nearest;
4727                                                } else if (constantObjective!=COIN_DBL_MAX) {
4728                                                  double newConstant=oldObjective[iColumn]/nearest;
4729                                                  if (constantObjective>0.0) {
4730                                                    if (newConstant<=0.0)
4731                                                      constantObjective=COIN_DBL_MAX;
4732                                                    else
4733                                                      constantObjective=CoinMin(constantObjective,newConstant);
4734                                                  } else {
4735                                                    if (newConstant>=0.0)
4736                                                      constantObjective=COIN_DBL_MAX;
4737                                                    else
4738                                                      constantObjective=CoinMax(constantObjective,newConstant);
4739                                                  }
4740                                                }
4741                                                if (nearest>0.0) {
4742                                                  newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4743                                                  newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4744                                                } else {
4745                                                  newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest;
4746                                                  newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest;
4747                                                }
4748                                              }
4749                                            }
4750                                          }
4751                                          if (allInteger) {
4752                                            newColumnStart[addSlacks+1]=addSlacks+1;
4753                                            newRow[addSlacks]=iRow;
4754                                            newElement[addSlacks]=-1.0;
4755                                            newObjective[addSlacks] = 0.0;
4756                                            if (moveObj && constantObjective != COIN_DBL_MAX) {
4757                                              // move some of objective here if looks constant
4758                                              newObjective[addSlacks]=constantObjective;
4759                                              for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
4760                                                int iColumn = column[j];
4761                                                double value = element[j];
4762                                                double nearest = floor(value+0.5);
4763                                                oldObjective[iColumn] -= nearest*constantObjective;
4764                                              }
4765                                            }
4766                                            newColumnLower[addSlacks] = CoinMax(newLower,ceil(rowLower[iRow]));;
4767                                            newColumnUpper[addSlacks] = CoinMin(newUpper,floor(rowUpper[iRow]));
4768                                            addSlacks++;
4769                                          }
4770                                        }
4771                                      }
4772                                      if (addSlacks) {
4773                                        solver2->setObjective(oldObjective);
4774                                        solver2->addCols(addSlacks,newColumnStart,newRow,newElement,
4775                                                         newColumnLower,newColumnUpper,newObjective);
4776                                        truncatedRhsLower = CoinCopyOfArray(solver2->getRowLower(),numberRows);
4777                                        truncatedRhsUpper = CoinCopyOfArray(solver2->getRowUpper(),numberRows);
4778                                        for (int j=0;j<addSlacks;j++) {
4779                                          int iRow = newRow[j];
4780                                          solver2->setRowLower(iRow,0.0);
4781                                          solver2->setRowUpper(iRow,0.0);
4782                                          int iColumn = j+numberColumns;
4783                                          solver2->setInteger(iColumn);
4784                                          std::string name