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

Last change on this file since 2358 was 2358, checked in by forrest, 23 months ago

changes for SOS

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