source: stable/2.9/Cbc/src/CbcSolver.cpp @ 2235

Last change on this file since 2235 was 2235, checked in by unxusr, 4 years ago

proper use of mipstart

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 614.2 KB
RevLine 
[1854]1/* $Id: CbcSolver.cpp 2235 2016-01-17 00:47:43Z unxusr $ */
[640]2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
[1573]4// This code is licensed under the terms of the Eclipse Public License (EPL).
[1286]5
[1361]6/*! \file CbcSolver.cpp
7    \brief Second level routines for the cbc stand-alone solver.
8*/
9
[640]10#include "CbcConfig.h"
11#include "CoinPragma.hpp"
12
13#include <cassert>
14#include <cstdio>
[904]15#include <cstdlib>
[640]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"
[687]33#include "ClpMessage.hpp"
[640]34#include "ClpPackedMatrix.hpp"
35#include "ClpPlusMinusOneMatrix.hpp"
36#include "ClpNetworkMatrix.hpp"
37#include "ClpDualRowSteepest.hpp"
38#include "ClpDualRowDantzig.hpp"
39#include "ClpLinearObjective.hpp"
40#include "ClpPrimalColumnSteepest.hpp"
41#include "ClpPrimalColumnDantzig.hpp"
[1271]42
[640]43#include "ClpPresolve.hpp"
[1607]44#ifndef COIN_HAS_CBC
45#define COIN_HAS_CBC
46#endif
[640]47#include "CbcOrClpParam.hpp"
48#include "OsiRowCutDebugger.hpp"
49#include "OsiChooseVariable.hpp"
[750]50#include "OsiAuxInfo.hpp"
[1770]51#include "CbcMipStartIO.hpp"
[1954]52// for printing
53#ifndef CLP_OUTPUT_FORMAT
54#define CLP_OUTPUT_FORMAT %15.8g
55#endif
56#define CLP_QUOTE(s) CLP_STRING(s)
57#define CLP_STRING(s) #s
[1383]58
59#include "CbcSolverHeuristics.hpp"
[1593]60#ifdef COIN_HAS_GLPK
61#include "glpk.h"
62extern glp_tran* cbc_glp_tran;
63extern glp_prob* cbc_glp_prob;
[1594]64#else
65#define GLP_UNDEF 1
66#define GLP_FEAS 2
67#define GLP_INFEAS 3
68#define GLP_NOFEAS 4
69#define GLP_OPT 5
[1593]70#endif
[1383]71
[1735]72#ifndef CBC_QUIET
73#define CBC_QUIET 0
74#endif
75
[755]76//#define USER_HAS_FAKE_CLP
77//#define USER_HAS_FAKE_CBC
[1386]78
[840]79//#define CLP_MALLOC_STATISTICS
[1386]80
[640]81#ifdef CLP_MALLOC_STATISTICS
82#include <malloc.h>
83#include <exception>
84#include <new>
[857]85#include "stolen_from_ekk_malloc.cpp"
[1286]86static double malloc_times = 0.0;
87static double malloc_total = 0.0;
88static int malloc_amount[] = {0, 32, 128, 256, 1024, 4096, 16384, 65536, 262144, INT_MAX};
89static int malloc_n = 10;
90double malloc_counts[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
91bool malloc_counts_on = true;
[640]92void * operator new (size_t size) throw (std::bad_alloc)
93{
[1286]94    malloc_times ++;
95    malloc_total += size;
96    int i;
97    for (i = 0; i < malloc_n; i++) {
98        if ((int) size <= malloc_amount[i]) {
99            malloc_counts[i]++;
100            break;
101        }
[640]102    }
[1386]103# ifdef DEBUG_MALLOC
[1286]104    void *p;
105    if (malloc_counts_on)
106        p = stolen_from_ekk_mallocBase(size);
107    else
108        p = malloc(size);
[1386]109# else
[1286]110    void * p = malloc(size);
[1386]111# endif
[1286]112    //char * xx = (char *) p;
113    //memset(xx,0,size);
114    // Initialize random seed
115    //CoinSeedRandom(987654321);
116    return p;
[640]117}
118void operator delete (void *p) throw()
119{
[1386]120# ifdef DEBUG_MALLOC
[1286]121    if (malloc_counts_on)
122        stolen_from_ekk_freeBase(p);
123    else
124        free(p);
[1386]125# else
[857]126    free(p);
[1386]127# endif
[640]128}
129static void malloc_stats2()
130{
[1286]131    double average = malloc_total / malloc_times;
132    printf("count %g bytes %g - average %g\n", malloc_times, malloc_total, average);
133    for (int i = 0; i < malloc_n; i++)
134        printf("%g ", malloc_counts[i]);
135    printf("\n");
136    malloc_times = 0.0;
137    malloc_total = 0.0;
138    memset(malloc_counts, 0, sizeof(malloc_counts));
139    // print results
[640]140}
[1386]141#else   //CLP_MALLOC_STATISTICS
[1271]142//void stolen_from_ekk_memory(void * dummy,int type)
143//{
144//}
145//bool malloc_counts_on=false;
[1386]146#endif  //CLP_MALLOC_STATISTICS
147
[738]148//#define DMALLOC
[640]149#ifdef DMALLOC
150#include "dmalloc.h"
151#endif
[1386]152
[640]153#ifdef WSSMP_BARRIER
154#define FOREIGN_BARRIER
155#endif
[1386]156
[640]157#ifdef UFL_BARRIER
158#define FOREIGN_BARRIER
159#endif
[1386]160
[640]161#ifdef TAUCS_BARRIER
162#define FOREIGN_BARRIER
163#endif
[1386]164
[1286]165static int initialPumpTune = -1;
[640]166#include "CoinWarmStartBasis.hpp"
167
168#include "OsiSolverInterface.hpp"
169#include "OsiCuts.hpp"
170#include "OsiRowCut.hpp"
171#include "OsiColCut.hpp"
[1386]172
[640]173#ifndef COIN_HAS_LINK
174#define COIN_HAS_LINK
175#endif
176#ifdef COIN_HAS_LINK
177#include "CbcLinked.hpp"
178#endif
[1386]179
[640]180#include "CglPreProcess.hpp"
181#include "CglCutGenerator.hpp"
182#include "CglGomory.hpp"
183#include "CglProbing.hpp"
184#include "CglKnapsackCover.hpp"
185#include "CglRedSplit.hpp"
[1876]186#include "CglRedSplit2.hpp"
187#include "CglGMI.hpp"
[640]188#include "CglClique.hpp"
189#include "CglFlowCover.hpp"
190#include "CglMixedIntegerRounding2.hpp"
191#include "CglTwomir.hpp"
192#include "CglDuplicateRow.hpp"
193#include "CglStored.hpp"
194#include "CglLandP.hpp"
[687]195#include "CglResidualCapacity.hpp"
[1121]196#include "CglZeroHalf.hpp"
[1638]197//#define CGL_WRITEMPS
198#ifdef CGL_WRITEMPS
199extern double * debugSolution;
200extern int debugNumberColumns;
201#endif
[640]202#include "CbcModel.hpp"
203#include "CbcHeuristic.hpp"
204#include "CbcHeuristicLocal.hpp"
[1058]205#include "CbcHeuristicPivotAndFix.hpp"
[1271]206//#include "CbcHeuristicPivotAndComplement.hpp"
[1058]207#include "CbcHeuristicRandRound.hpp"
[640]208#include "CbcHeuristicGreedy.hpp"
209#include "CbcHeuristicFPump.hpp"
210#include "CbcHeuristicRINS.hpp"
[871]211#include "CbcHeuristicDiveCoefficient.hpp"
212#include "CbcHeuristicDiveFractional.hpp"
213#include "CbcHeuristicDiveGuided.hpp"
214#include "CbcHeuristicDiveVectorLength.hpp"
[954]215#include "CbcHeuristicDivePseudoCost.hpp"
216#include "CbcHeuristicDiveLineSearch.hpp"
[640]217#include "CbcTreeLocal.hpp"
218#include "CbcCompareActual.hpp"
219#include "CbcBranchActual.hpp"
[771]220#include "CbcBranchLotsize.hpp"
[640]221#include  "CbcOrClpParam.hpp"
222#include  "CbcCutGenerator.hpp"
223#include  "CbcStrategy.hpp"
[1121]224#include "CbcBranchCut.hpp"
[640]225
226#include "OsiClpSolverInterface.hpp"
[1386]227
[1395]228#include "CbcSolverAnalyze.hpp"
[1398]229#include "CbcSolverExpandKnapsack.hpp"
[1395]230
[1381]231#include "CbcSolver.hpp"
[1386]232
[862]233//#define IN_BRANCH_AND_BOUND (0x01000000|262144)
234#define IN_BRANCH_AND_BOUND (0x01000000|262144|128|1024|2048)
235//#define IN_BRANCH_AND_BOUND (0x01000000|262144|128)
[1386]236
237/*
238  CbcStopNow class definitions.
239*/
240
241CbcStopNow::CbcStopNow()
242{
243}
244CbcStopNow::~CbcStopNow()
245{
246}
247// Copy constructor
248CbcStopNow::CbcStopNow ( const CbcStopNow & )
249{
250}
251// Assignment operator
252CbcStopNow &
253CbcStopNow::operator=(const CbcStopNow & rhs)
254{
255    if (this != &rhs) {
256    }
257    return *this;
258}
259// Clone
260CbcStopNow *
261CbcStopNow::clone() const
262{
263    return new CbcStopNow(*this);
264}
265
266/*
267  CbcUser class definitions.
268*/
269
270// User stuff (base class)
271CbcUser::CbcUser()
272        : coinModel_(NULL),
273        userName_("null")
274{
275}
276CbcUser::~CbcUser()
277{
278    delete coinModel_;
279}
280// Copy constructor
281CbcUser::CbcUser ( const CbcUser & rhs)
282{
283    if (rhs.coinModel_)
284        coinModel_ = new CoinModel(*rhs.coinModel_);
285    else
286        coinModel_ = NULL;
287    userName_ = rhs.userName_;
288}
289// Assignment operator
290CbcUser &
291CbcUser::operator=(const CbcUser & rhs)
292{
293    if (this != &rhs) {
294        if (rhs.coinModel_)
295            coinModel_ = new CoinModel(*rhs.coinModel_);
296        else
297            coinModel_ = NULL;
298        userName_ = rhs.userName_;
299    }
300    return *this;
301}
[1826]302
[1769]303static void putBackOtherSolutions(CbcModel * presolvedModel, CbcModel * model,
304                           CglPreProcess * preProcess)
305{
306  int numberSolutions=presolvedModel->numberSavedSolutions();
307  int numberColumns=presolvedModel->getNumCols();
308  if (numberSolutions>1) {
[1832]309    model->deleteSolutions();
[1769]310    double * bestSolution = CoinCopyOfArray(presolvedModel->bestSolution(),numberColumns);
311    //double cutoff = presolvedModel->getCutoff();
312    double objectiveValue=presolvedModel->getObjValue();
313    //model->createSpaceForSavedSolutions(numberSolutions-1);
314    for (int iSolution=numberSolutions-1;iSolution>=0;iSolution--) {
315      presolvedModel->setCutoff(COIN_DBL_MAX);
316      presolvedModel->solver()->setColSolution(presolvedModel->savedSolution(iSolution));
317      //presolvedModel->savedSolutionObjective(iSolution));
318      preProcess->postProcess(*presolvedModel->solver(),false);
319      model->setBestSolution(preProcess->originalModel()->getColSolution(),model->solver()->getNumCols(),
320                             presolvedModel->savedSolutionObjective(iSolution));
321    }
322    presolvedModel->setBestObjectiveValue(objectiveValue);
323    presolvedModel->solver()->setColSolution(bestSolution);
324    //presolvedModel->setBestSolution(bestSolution,numberColumns,objectiveValue);
325  }
326}
[1386]327
328/*
329  CbcSolver class definitions
330*/
331
[1381]332CbcSolver::CbcSolver()
333        : babModel_(NULL),
334        userFunction_(NULL),
335        statusUserFunction_(NULL),
336        originalSolver_(NULL),
337        originalCoinModel_(NULL),
338        cutGenerator_(NULL),
339        numberUserFunctions_(0),
340        numberCutGenerators_(0),
341        startTime_(CoinCpuTime()),
342        parameters_(NULL),
343        numberParameters_(0),
344        doMiplib_(false),
345        noPrinting_(false),
346        readMode_(1)
347{
348    callBack_ = new CbcStopNow();
349    fillParameters();
350}
351CbcSolver::CbcSolver(const OsiClpSolverInterface & solver)
352        : babModel_(NULL),
353        userFunction_(NULL),
354        statusUserFunction_(NULL),
355        originalSolver_(NULL),
356        originalCoinModel_(NULL),
357        cutGenerator_(NULL),
358        numberUserFunctions_(0),
359        numberCutGenerators_(0),
360        startTime_(CoinCpuTime()),
361        parameters_(NULL),
362        numberParameters_(0),
363        doMiplib_(false),
364        noPrinting_(false),
365        readMode_(1)
366{
367    callBack_ = new CbcStopNow();
368    model_ = CbcModel(solver);
369    fillParameters();
370}
371CbcSolver::CbcSolver(const CbcModel & solver)
372        : babModel_(NULL),
373        userFunction_(NULL),
374        statusUserFunction_(NULL),
375        originalSolver_(NULL),
376        originalCoinModel_(NULL),
377        cutGenerator_(NULL),
378        numberUserFunctions_(0),
379        numberCutGenerators_(0),
380        startTime_(CoinCpuTime()),
381        parameters_(NULL),
382        numberParameters_(0),
383        doMiplib_(false),
384        noPrinting_(false),
385        readMode_(1)
386{
387    callBack_ = new CbcStopNow();
388    model_ = solver;
389    fillParameters();
390}
391CbcSolver::~CbcSolver()
392{
393    int i;
394    for (i = 0; i < numberUserFunctions_; i++)
395        delete userFunction_[i];
396    delete [] userFunction_;
397    for (i = 0; i < numberCutGenerators_; i++)
398        delete cutGenerator_[i];
399    delete [] cutGenerator_;
400    delete [] statusUserFunction_;
401    delete originalSolver_;
402    delete originalCoinModel_;
403    delete babModel_;
404    delete [] parameters_;
405    delete callBack_;
406}
407// Copy constructor
408CbcSolver::CbcSolver ( const CbcSolver & rhs)
409        : model_(rhs.model_),
410        babModel_(NULL),
411        userFunction_(NULL),
412        statusUserFunction_(NULL),
413        numberUserFunctions_(rhs.numberUserFunctions_),
414        startTime_(CoinCpuTime()),
415        parameters_(NULL),
416        numberParameters_(rhs.numberParameters_),
417        doMiplib_(rhs.doMiplib_),
418        noPrinting_(rhs.noPrinting_),
419        readMode_(rhs.readMode_)
420{
421    fillParameters();
422    if (rhs.babModel_)
423        babModel_ = new CbcModel(*rhs.babModel_);
424    userFunction_ = new CbcUser * [numberUserFunctions_];
425    int i;
426    for (i = 0; i < numberUserFunctions_; i++)
427        userFunction_[i] = rhs.userFunction_[i]->clone();
428    for (i = 0; i < numberParameters_; i++)
429        parameters_[i] = rhs.parameters_[i];
430    for (i = 0; i < numberCutGenerators_; i++)
431        cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
432    callBack_ = rhs.callBack_->clone();
433    originalSolver_ = NULL;
434    if (rhs.originalSolver_) {
435        OsiSolverInterface * temp = rhs.originalSolver_->clone();
436        originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
437        assert (originalSolver_);
438    }
439    originalCoinModel_ = NULL;
440    if (rhs.originalCoinModel_)
441        originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
442}
443// Assignment operator
444CbcSolver &
445CbcSolver::operator=(const CbcSolver & rhs)
446{
447    if (this != &rhs) {
448        int i;
449        for (i = 0; i < numberUserFunctions_; i++)
450            delete userFunction_[i];
451        delete [] userFunction_;
452        for (i = 0; i < numberCutGenerators_; i++)
453            delete cutGenerator_[i];
454        delete [] statusUserFunction_;
455        delete originalSolver_;
456        delete originalCoinModel_;
457        statusUserFunction_ = NULL;
458        delete babModel_;
459        delete callBack_;
460        numberUserFunctions_ = rhs.numberUserFunctions_;
461        startTime_ = rhs.startTime_;
462        numberParameters_ = rhs.numberParameters_;
463        for (i = 0; i < numberParameters_; i++)
464            parameters_[i] = rhs.parameters_[i];
465        for (i = 0; i < numberCutGenerators_; i++)
466            cutGenerator_[i] = rhs.cutGenerator_[i]->clone();
467        noPrinting_ = rhs.noPrinting_;
468        readMode_ = rhs.readMode_;
469        doMiplib_ = rhs.doMiplib_;
470        model_ = rhs.model_;
471        if (rhs.babModel_)
472            babModel_ = new CbcModel(*rhs.babModel_);
473        else
474            babModel_ = NULL;
475        userFunction_ = new CbcUser * [numberUserFunctions_];
476        for (i = 0; i < numberUserFunctions_; i++)
477            userFunction_[i] = rhs.userFunction_[i]->clone();
478        callBack_ = rhs.callBack_->clone();
479        originalSolver_ = NULL;
480        if (rhs.originalSolver_) {
481            OsiSolverInterface * temp = rhs.originalSolver_->clone();
482            originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
483            assert (originalSolver_);
484        }
485        originalCoinModel_ = NULL;
486        if (rhs.originalCoinModel_)
487            originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_);
488    }
489    return *this;
490}
491// Get int value
492int CbcSolver::intValue(CbcOrClpParameterType type) const
493{
494    return parameters_[whichParam(type, numberParameters_, parameters_)].intValue();
495}
496// Set int value
497void CbcSolver::setIntValue(CbcOrClpParameterType type, int value)
498{
499    parameters_[whichParam(type, numberParameters_, parameters_)].setIntValue(value);
500}
501// Get double value
502double CbcSolver::doubleValue(CbcOrClpParameterType type) const
503{
504    return parameters_[whichParam(type, numberParameters_, parameters_)].doubleValue();
505}
506// Set double value
507void CbcSolver::setDoubleValue(CbcOrClpParameterType type, double value)
508{
509    parameters_[whichParam(type, numberParameters_, parameters_)].setDoubleValue(value);
510}
511// User function (NULL if no match)
512CbcUser * CbcSolver::userFunction(const char * name) const
513{
514    int i;
515    for (i = 0; i < numberUserFunctions_; i++) {
516        if (!strcmp(name, userFunction_[i]->name().c_str()))
517            break;
518    }
519    if (i < numberUserFunctions_)
520        return userFunction_[i];
521    else
522        return NULL;
523}
524void CbcSolver::fillParameters()
525{
526    int maxParam = 200;
527    CbcOrClpParam * parameters = new CbcOrClpParam [maxParam];
528    numberParameters_ = 0 ;
529    establishParams(numberParameters_, parameters) ;
530    assert (numberParameters_ <= maxParam);
531    parameters_ = new CbcOrClpParam [numberParameters_];
532    int i;
533    for (i = 0; i < numberParameters_; i++)
534        parameters_[i] = parameters[i];
535    delete [] parameters;
536    const char dirsep =  CoinFindDirSeparator();
537    std::string directory;
538    std::string dirSample;
539    std::string dirNetlib;
540    std::string dirMiplib;
541    if (dirsep == '/') {
542        directory = "./";
543        dirSample = "../../Data/Sample/";
544        dirNetlib = "../../Data/Netlib/";
545        dirMiplib = "../../Data/miplib3/";
546    } else {
547        directory = ".\\";
548        dirSample = "..\\..\\..\\..\\Data\\Sample\\";
549        dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
550        dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
551    }
552    std::string defaultDirectory = directory;
553    std::string importFile = "";
554    std::string exportFile = "default.mps";
555    std::string importBasisFile = "";
556    std::string importPriorityFile = "";
[1770]557    std::string mipStartFile = "";
[1381]558    std::string debugFile = "";
559    std::string printMask = "";
560    std::string exportBasisFile = "default.bas";
561    std::string saveFile = "default.prob";
562    std::string restoreFile = "default.prob";
563    std::string solutionFile = "stdout";
564    std::string solutionSaveFile = "solution.file";
565    int doIdiot = -1;
566    int outputFormat = 2;
567    int substitution = 3;
568    int dualize = 3;
569    int preSolve = 5;
570    int doSprint = -1;
571    int testOsiParameters = -1;
572    int createSolver = 0;
573    ClpSimplex * lpSolver;
574    OsiClpSolverInterface * clpSolver;
575    if (model_.solver()) {
576        clpSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
577        assert (clpSolver);
578        lpSolver = clpSolver->getModelPtr();
579        assert (lpSolver);
580    } else {
581        lpSolver = new ClpSimplex();
582        clpSolver = new OsiClpSolverInterface(lpSolver, true);
583        createSolver = 1 ;
584    }
585    parameters_[whichParam(CLP_PARAM_ACTION_BASISIN, numberParameters_, parameters_)].setStringValue(importBasisFile);
586    parameters_[whichParam(CBC_PARAM_ACTION_PRIORITYIN, numberParameters_, parameters_)].setStringValue(importPriorityFile);
[1770]587    parameters_[whichParam(CBC_PARAM_ACTION_MIPSTART, numberParameters_, parameters_)].setStringValue(mipStartFile);
[1381]588    parameters_[whichParam(CLP_PARAM_ACTION_BASISOUT, numberParameters_, parameters_)].setStringValue(exportBasisFile);
589    parameters_[whichParam(CLP_PARAM_ACTION_DEBUG, numberParameters_, parameters_)].setStringValue(debugFile);
590    parameters_[whichParam(CLP_PARAM_ACTION_PRINTMASK, numberParameters_, parameters_)].setStringValue(printMask);
591    parameters_[whichParam(CLP_PARAM_ACTION_DIRECTORY, numberParameters_, parameters_)].setStringValue(directory);
592    parameters_[whichParam(CLP_PARAM_ACTION_DIRSAMPLE, numberParameters_, parameters_)].setStringValue(dirSample);
593    parameters_[whichParam(CLP_PARAM_ACTION_DIRNETLIB, numberParameters_, parameters_)].setStringValue(dirNetlib);
594    parameters_[whichParam(CBC_PARAM_ACTION_DIRMIPLIB, numberParameters_, parameters_)].setStringValue(dirMiplib);
595    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
596    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
597    parameters_[whichParam(CLP_PARAM_ACTION_EXPORT, numberParameters_, parameters_)].setStringValue(exportFile);
598    parameters_[whichParam(CLP_PARAM_INT_IDIOT, numberParameters_, parameters_)].setIntValue(doIdiot);
599    parameters_[whichParam(CLP_PARAM_ACTION_IMPORT, numberParameters_, parameters_)].setStringValue(importFile);
600    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].setDoubleValue(1.0e-8);
601    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
602    int value = 1;
603    clpSolver->messageHandler()->setLogLevel(1) ;
604    lpSolver->setLogLevel(1);
605    parameters_[iParam].setIntValue(value);
606    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
607    model_.messageHandler()->setLogLevel(value);
608    parameters_[iParam].setIntValue(value);
609    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
610    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
611    parameters_[whichParam(CLP_PARAM_INT_OUTPUTFORMAT, numberParameters_, parameters_)].setIntValue(outputFormat);
612    parameters_[whichParam(CLP_PARAM_INT_PRESOLVEPASS, numberParameters_, parameters_)].setIntValue(preSolve);
613    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
614    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
615    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
616    parameters_[whichParam(CLP_PARAM_ACTION_RESTORE, numberParameters_, parameters_)].setStringValue(restoreFile);
617    parameters_[whichParam(CLP_PARAM_ACTION_SAVE, numberParameters_, parameters_)].setStringValue(saveFile);
618    //parameters_[whichParam(CLP_PARAM_DBL_TIMELIMIT,numberParameters_,parameters_)].setDoubleValue(1.0e8);
619    parameters_[whichParam(CBC_PARAM_DBL_TIMELIMIT_BAB, numberParameters_, parameters_)].setDoubleValue(1.0e8);
620    parameters_[whichParam(CLP_PARAM_ACTION_SOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
[1769]621    parameters_[whichParam(CLP_PARAM_ACTION_NEXTBESTSOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile);
[1381]622    parameters_[whichParam(CLP_PARAM_ACTION_SAVESOL, numberParameters_, parameters_)].setStringValue(solutionSaveFile);
623    parameters_[whichParam(CLP_PARAM_INT_SPRINT, numberParameters_, parameters_)].setIntValue(doSprint);
624    parameters_[whichParam(CLP_PARAM_INT_SUBSTITUTION, numberParameters_, parameters_)].setIntValue(substitution);
625    parameters_[whichParam(CLP_PARAM_INT_DUALIZE, numberParameters_, parameters_)].setIntValue(dualize);
626    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
627    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
628    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
629    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
630    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
631    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
632    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(testOsiParameters);
633    parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_)].setIntValue(1003);
634    initialPumpTune = 1003;
635#ifdef CBC_THREAD
636    parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].setIntValue(0);
637#endif
638    // Set up likely cut generators and defaults
639    parameters_[whichParam(CBC_PARAM_STR_PREPROCESS, numberParameters_, parameters_)].setCurrentOption("sos");
640    parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValue(1057);
641    parameters_[whichParam(CBC_PARAM_INT_CUTPASSINTREE, numberParameters_, parameters_)].setIntValue(1);
642    parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].setIntValue(-1);
643    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
644    parameters_[whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
645    parameters_[whichParam(CBC_PARAM_STR_HEURISTICSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on");
646    parameters_[whichParam(CBC_PARAM_STR_NODESTRATEGY, numberParameters_, parameters_)].setCurrentOption("fewest");
647    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
648    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
649    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
650    parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption("off");
651    parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption("off");
[1876]652    parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption("off");
653    parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption("off");
[1381]654    parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
655    parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
656    parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
[1880]657    parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove");
[1381]658    parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption("off");
659    parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption("off");
660    parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption("on");
661    parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption("on");
662    parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption("on");
663    parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption("on");
664    parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters_, parameters_)].setCurrentOption("off");
665    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters_, parameters_)].setCurrentOption("off");
666    parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters_, parameters_)].setCurrentOption("off");
667    parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].setCurrentOption("off");
668    parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].setCurrentOption("off");
669    parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption("off");
670    parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].setCurrentOption("off");
671    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("off");
672    parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].setCurrentOption("off");
673    parameters_[whichParam(CBC_PARAM_STR_COSTSTRATEGY, numberParameters_, parameters_)].setCurrentOption("off");
674    if (createSolver)
675        delete clpSolver;
676}
[1361]677
[1381]678/*
679  Initialise a subset of the parameters prior to processing any input from
680  the user.
[1361]681
[1381]682  Why this choice of subset?
683*/
684/*!
685  \todo Guard/replace clp-specific code
686*/
687void CbcSolver::fillValuesInSolver()
688{
689    OsiSolverInterface * solver = model_.solver();
[1412]690    OsiClpSolverInterface * clpSolver =
691        dynamic_cast< OsiClpSolverInterface*> (solver);
[1381]692    assert (clpSolver);
[1412]693    ClpSimplex * lpSolver = clpSolver->getModelPtr();
[1361]694
[1381]695    /*
696      Why are we reaching into the underlying solver(s) for these settings?
697      Shouldn't CbcSolver have its own defaults, which are then imposed on the
698      underlying solver?
699
700      Coming at if from the other side, if CbcSolver had the capability to use
701      multiple solvers then it definitely makes sense to acquire the defaults from
702      the solver (on the assumption that we haven't processed command line
703      parameters yet, which can then override the defaults). But then it's more of
704      a challenge to avoid solver-specific coding here.
705    */
706    noPrinting_ = (lpSolver->logLevel() == 0);
707    CoinMessageHandler * generalMessageHandler = clpSolver->messageHandler();
708    generalMessageHandler->setPrefix(true);
709
[1412]710    lpSolver->setPerturbation(50);
[1381]711    lpSolver->messageHandler()->setPrefix(false);
712
713    parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualBound());
714    parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->dualTolerance());
715    /*
716      Why are we doing this? We read the log level from parameters_, set it into
717      the message handlers for cbc and the underlying solver. Then we read the
718      log level back from the handlers and use it to set the values in
719      parameters_!
720    */
721    int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
722    int value = parameters_[iParam].intValue();
723    clpSolver->messageHandler()->setLogLevel(value) ;
724    lpSolver->setLogLevel(value);
725    iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
726    value = parameters_[iParam].intValue();
727    model_.messageHandler()->setLogLevel(value);
728    parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].setIntValue(model_.logLevel());
729    parameters_[whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_)].setIntValue(lpSolver->logLevel());
730    parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver->factorizationFrequency());
731    parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver->maximumIterations());
732    parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver->perturbation());
733    parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver->primalTolerance());
734    parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver->infeasibilityCost());
735    parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust());
736    parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes());
737    parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong());
738    parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight));
739    parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance));
740    parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement));
741}
742// Add user function
743void
744CbcSolver::addUserFunction(CbcUser * function)
745{
746    CbcUser ** temp = new CbcUser * [numberUserFunctions_+1];
747    int i;
748    for (i = 0; i < numberUserFunctions_; i++)
749        temp[i] = userFunction_[i];
750    delete [] userFunction_;
751    userFunction_ = temp;
752    userFunction_[numberUserFunctions_++] = function->clone();
753    delete [] statusUserFunction_;
754    statusUserFunction_ = NULL;
755}
756// Set user call back
757void
758CbcSolver::setUserCallBack(CbcStopNow * function)
759{
760    delete callBack_;
761    callBack_ = function->clone();
762}
763// Copy of model on initial load (will contain output solutions)
764void
765CbcSolver::setOriginalSolver(OsiClpSolverInterface * originalSolver)
766{
767    delete originalSolver_;
768    OsiSolverInterface * temp = originalSolver->clone();
769    originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp);
770    assert (originalSolver_);
771
772}
773// Copy of model on initial load
774void
775CbcSolver::setOriginalCoinModel(CoinModel * originalCoinModel)
776{
777    delete originalCoinModel_;
778    originalCoinModel_ = new CoinModel(*originalCoinModel);
779}
780// Add cut generator
781void
782CbcSolver::addCutGenerator(CglCutGenerator * generator)
783{
784    CglCutGenerator ** temp = new CglCutGenerator * [numberCutGenerators_+1];
785    int i;
786    for (i = 0; i < numberCutGenerators_; i++)
787        temp[i] = cutGenerator_[i];
788    delete [] cutGenerator_;
789    cutGenerator_ = temp;
790    cutGenerator_[numberCutGenerators_++] = generator->clone();
791}
[1386]792
793/*
[1390]794  The only other solver that's ever been used is cplex, and the use is
[1386]795  limited -- do the root with clp and all the cbc smarts, then give the
796  problem over to cplex to finish. Although the defines can be read in some
797  places to allow other options, nothing's been tested and success is
798  unlikely.
799
800  CBC_OTHER_SOLVER == 1 is cplex.
[1381]801*/
[1386]802
[1132]803#if CBC_OTHER_SOLVER==1
[1390]804#  ifndef COIN_HAS_CPX
805#    error "Configuration did not detect cplex installation."
806#  else
807#    include "OsiCpxSolverInterface.hpp"
808#  endif
[1132]809#endif
[1386]810
[640]811#ifdef COIN_HAS_ASL
812#include "Cbc_ampl.h"
813#endif
[1386]814
[640]815static void statistics(ClpSimplex * originalModel, ClpSimplex * model);
816static bool maskMatches(const int * starts, char ** masks,
[1286]817                        std::string & check);
818static void generateCode(CbcModel * model, const char * fileName, int type, int preProcess);
[1386]819
820// dummy fake main programs for UserClp and UserCbc
[1286]821void fakeMain (ClpSimplex & model, OsiSolverInterface & osiSolver, CbcModel & babSolver);
822void fakeMain2 (ClpSimplex & model, OsiClpSolverInterface & osiSolver, int options);
[640]823
824// Allow for interrupts
[1386]825// But is this threadsafe? (so switched off by option)
[640]826
827#include "CoinSignal.hpp"
828static CbcModel * currentBranchModel = NULL;
829
830extern "C" {
[1839]831    static void signal_handler(int whichSignal) {
832      if (currentBranchModel != NULL) {
833        currentBranchModel->sayEventHappened(); // say why stopped
834        if (currentBranchModel->heuristicModel())
835          currentBranchModel->heuristicModel()->sayEventHappened();
836      }
[1286]837        return;
838    }
[640]839}
[1386]840
[738]841//#define CBC_SIG_TRAP
842#ifdef CBC_SIG_TRAP
843#include <setjmp.h>
844static sigjmp_buf cbc_seg_buffer;
845extern "C" {
[1286]846    static void signal_handler_error(int whichSignal) {
847        siglongjmp(cbc_seg_buffer, 1);
848    }
[738]849}
850#endif
[1386]851
[1391]852
[1386]853/*
854  Debug checks on special ordered sets.
[1391]855
856  This is active only for debugging. The entire body of the routine becomes
857  a noop when COIN_DEVELOP is not defined. To avoid compiler warnings, the
858  formal parameters also need to go away.
[1386]859*/
[1271]860#ifdef COIN_DEVELOP
[640]861void checkSOS(CbcModel * babModel, const OsiSolverInterface * solver)
[1271]862#else
863void checkSOS(CbcModel * /*babModel*/, const OsiSolverInterface * /*solver*/)
864#endif
[640]865{
866#ifdef COIN_DEVELOP
[1286]867    if (!babModel->ownObjects())
868        return;
[931]869#if COIN_DEVELOP>2
[1286]870    //const double *objective = solver->getObjCoefficients() ;
871    const double *columnLower = solver->getColLower() ;
872    const double * columnUpper = solver->getColUpper() ;
873    const double * solution = solver->getColSolution();
874    //int numberRows = solver->getNumRows();
875    //double direction = solver->getObjSense();
876    //int iRow,iColumn;
[931]877#endif
[640]878
[1286]879    // Row copy
880    CoinPackedMatrix matrixByRow(*solver->getMatrixByRow());
881    //const double * elementByRow = matrixByRow.getElements();
882    //const int * column = matrixByRow.getIndices();
883    //const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
884    const int * rowLength = matrixByRow.getVectorLengths();
[640]885
[1286]886    // Column copy
887    CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
888    const double * element = matrixByCol.getElements();
889    const int * row = matrixByCol.getIndices();
890    const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
891    const int * columnLength = matrixByCol.getVectorLengths();
[640]892
[1286]893    const double * rowLower = solver->getRowLower();
894    const double * rowUpper = solver->getRowUpper();
895    OsiObject ** objects = babModel->objects();
896    int numberObjects = babModel->numberObjects();
897    int numberColumns = solver->getNumCols() ;
898    for (int iObj = 0; iObj < numberObjects; iObj++) {
899        CbcSOS * objSOS =
900            dynamic_cast <CbcSOS *>(objects[iObj]) ;
901        if (objSOS) {
902            int n = objSOS->numberMembers();
903            const int * which = objSOS->members();
[931]904#if COIN_DEVELOP>2
[1286]905            const double * weight = objSOS->weights();
[931]906#endif
[1286]907            int type = objSOS->sosType();
908            // convexity row?
909            int iColumn;
910            iColumn = which[0];
911            int j;
912            int convex = -1;
913            for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {
914                int iRow = row[j];
915                double value = element[j];
916                if (rowLower[iRow] == 1.0 && rowUpper[iRow] == 1.0 &&
917                        value == 1.0) {
918                    // possible
919                    if (rowLength[iRow] == n) {
920                        if (convex == -1)
921                            convex = iRow;
922                        else
923                            convex = -2;
924                    }
925                }
926            }
927            printf ("set %d of type %d has %d members - possible convexity row %d\n",
928                    iObj, type, n, convex);
929            for (int i = 0; i < n; i++) {
930                iColumn = which[i];
931                // Column may have been added
932                if (iColumn < numberColumns) {
933                    int convex2 = -1;
934                    for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {
935                        int iRow = row[j];
936                        if (iRow == convex) {
937                            double value = element[j];
938                            if (value == 1.0) {
939                                convex2 = iRow;
940                            }
941                        }
942                    }
943                    if (convex2<0 && convex >= 0) {
944                        printf("odd convexity row\n");
945                        convex = -2;
946                    }
[931]947#if COIN_DEVELOP>2
[1286]948                    printf("col %d has weight %g and value %g, bounds %g %g\n",
949                           iColumn, weight[i], solution[iColumn], columnLower[iColumn],
950                           columnUpper[iColumn]);
[931]951#endif
[1286]952                }
953            }
954        }
[640]955    }
[1386]956#endif  // COIN_DEVELOP
[640]957}
[1386]958
959static int dummyCallBack(CbcModel * /*model*/, int /*whereFrom*/)
960{
961    return 0;
962}
[1394]963
964
[1395]965/*
966  Global parameters for command processing.
967
968  These will need to be moved into an object of some sort in order to make
969  this set of calls thread-safe.
970*/
971
[1394]972int CbcOrClpRead_mode = 1;
973FILE * CbcOrClpReadCommand = stdin;
974extern int CbcOrClpEnvironmentIndex;
975
[2013]976int callCbc1(const char * input2, CbcModel & model,
977             int callBack(CbcModel * currentSolver, int whereFrom),
978             CbcSolverUsefulData & parameterData);
979
[1391]980/*
981  Wrappers for CbcMain0, CbcMain1. The various forms of callCbc will eventually
982  resolve to a call to CbcMain0 followed by a call to callCbc1.
983*/
984/*
985  Simplest calling form: supply just a string with the command options. The
986  wrapper creates an OsiClpSolverInterface and calls the next wrapper.
987*/
988int callCbc(const std::string input2)
989{
990    char * input3 = CoinStrdup(input2.c_str());
991    OsiClpSolverInterface solver1;
992    int returnCode = callCbc(input3, solver1);
993    free(input3);
994    return returnCode;
995}
[1386]996
[1391]997int callCbc(const char * input2)
998{
999    {
1000        OsiClpSolverInterface solver1;
1001        return callCbc(input2, solver1);
1002    }
1003}
1004
[1386]1005/*
[1391]1006  Second calling form: supply the command line and an OsiClpSolverInterface.
1007  the wrapper will create a CbcModel and call the next wrapper.
[1386]1008*/
1009
[1391]1010int callCbc(const std::string input2, OsiClpSolverInterface& solver1)
1011{
1012    char * input3 = CoinStrdup(input2.c_str());
1013    int returnCode = callCbc(input3, solver1);
1014    free(input3);
1015    return returnCode;
1016}
1017
1018int callCbc(const char * input2, OsiClpSolverInterface& solver1)
1019{
1020    CbcModel model(solver1);
1021    return callCbc(input2, model);
1022}
1023
1024/*
1025  Third calling form: supply the command line and a CbcModel. This wrapper will
1026  actually call CbcMain0 and then call the next set of wrappers (callCbc1) to
1027  handle the call to CbcMain1.
1028*/
1029int callCbc(const char * input2, CbcModel & babSolver)
1030{
[2013]1031  CbcSolverUsefulData data;
1032#ifndef CBC_NO_INTERRUPT
1033    data.useSignalHandler_=true;
1034#endif
1035#ifndef CBC_NO_PRINTING
1036    data.noPrinting_ = false;
1037#endif
1038  CbcMain0(babSolver, data);
1039  return callCbc1(input2, babSolver, dummyCallBack, data);
[1391]1040}
1041
1042int callCbc(const std::string input2, CbcModel & babSolver)
1043{
1044    char * input3 = CoinStrdup(input2.c_str());
1045    CbcMain0(babSolver);
1046    int returnCode = callCbc1(input3, babSolver);
1047    free(input3);
1048    return returnCode;
1049}
1050
1051
1052/*
1053  Various overloads of callCbc1. The first pair accepts just a CbcModel and
1054  supplements it with a dummy callback routine. The second pair allows the
1055  user to supply a callback. See CbcMain1 for further explanation of the
1056  callback. The various overloads of callCbc1 resolve to the final version,
1057  which breaks the string into individual parameter strings (i.e., creates
1058  something that looks like a standard argv vector).
1059*/
1060
[1386]1061int callCbc1(const std::string input2, CbcModel & babSolver)
1062{
1063    char * input3 = CoinStrdup(input2.c_str());
1064    int returnCode = callCbc1(input3, babSolver);
1065    free(input3);
1066    return returnCode;
1067}
1068
1069int callCbc1(const char * input2, CbcModel & model)
1070{
1071    return callCbc1(input2, model, dummyCallBack);
1072}
1073
[1391]1074int callCbc1(const std::string input2, CbcModel & babSolver,
[1412]1075             int callBack(CbcModel * currentSolver, int whereFrom))
[1386]1076{
1077    char * input3 = CoinStrdup(input2.c_str());
1078    int returnCode = callCbc1(input3, babSolver, callBack);
1079    free(input3);
1080    return returnCode;
1081}
[1391]1082int callCbc1(const char * input2, CbcModel & model,
[2013]1083             int callBack(CbcModel * currentSolver, int whereFrom),
1084             CbcSolverUsefulData & parameterData)
[640]1085{
[2143]1086    char * input = CoinStrdup(input2 ? input2 : "") ;
[1644]1087    size_t length = strlen(input);
[2143]1088    bool blank = input[0] == ' ';
[1286]1089    int n = blank ? 0 : 1;
[1644]1090    for (size_t i = 0; i < length; i++) {
[1286]1091        if (blank) {
1092            // look for next non blank
1093            if (input[i] == ' ') {
1094                continue;
1095            } else {
1096                n++;
1097                blank = false;
1098            }
1099        } else {
1100            // look for next blank
1101            if (input[i] != ' ') {
1102                continue;
1103            } else {
1104                blank = true;
1105            }
1106        }
[640]1107    }
[1286]1108    char ** argv = new char * [n+2];
[1336]1109    argv[0] = CoinStrdup("cbc");
[1644]1110    size_t i = 0;
[1286]1111    while (input[i] == ' ')
1112        i++;
1113    for (int j = 0; j < n; j++) {
[1644]1114        size_t saveI = i;
[1286]1115        for (; i < length; i++) {
1116            // look for next blank
1117            if (input[i] != ' ') {
1118                continue;
1119            } else {
1120                break;
1121            }
1122        }
[1880]1123        input[i++] = '\0';
[1336]1124        argv[j+1] = CoinStrdup(input + saveI);
[1286]1125        while (input[i] == ' ')
1126            i++;
[640]1127    }
[1336]1128    argv[n+1] = CoinStrdup("-quit");
[1286]1129    free(input);
1130    currentBranchModel = NULL;
1131    CbcOrClpRead_mode = 1;
1132    CbcOrClpReadCommand = stdin;
[1391]1133    int returnCode = CbcMain1(n + 2, const_cast<const char **>(argv),
[2013]1134                              model, callBack,parameterData);
[1286]1135    for (int k = 0; k < n + 2; k++)
1136        free(argv[k]);
1137    delete [] argv;
1138    return returnCode;
[640]1139}
[2013]1140static CbcSolverUsefulData staticParameterData;
1141int callCbc1(const char * input2, CbcModel & model,
1142             int callBack(CbcModel * currentSolver, int whereFrom))
1143{
1144  // allow interrupts and printing
1145#ifndef CBC_NO_INTERRUPT
1146  staticParameterData.useSignalHandler_=true;
1147#endif
1148#ifndef CBC_NO_PRINTING
1149  staticParameterData.noPrinting_ = false;
1150#endif
1151  return callCbc1(input2,model,callBack,staticParameterData);
1152}
[1386]1153
[1482]1154CglPreProcess * cbcPreProcessPointer=NULL;
[1383]1155
[824]1156int CbcClpUnitTest (const CbcModel & saveModel,
[1622]1157                    const std::string& dirMiplib, int testSwitch,
1158                    const double * stuff);
[1386]1159
1160int CbcMain1 (int argc, const char *argv[],
1161              CbcModel  & model)
[1381]1162{
[1386]1163    return CbcMain1(argc, argv, model, dummyCallBack);
[1381]1164}
[1386]1165
[1998]1166#ifdef CBC_THREAD_SAFE
1167// Copies of some input decoding
[1386]1168
[1998]1169static std::string
1170CoinReadGetCommand(int &whichArgument, int argc, const char *argv[])
1171{
1172  std::string field;
1173  if (whichArgument < argc) 
1174    field = argv[whichArgument++];
1175  else
1176    field = "quit";
1177  if (field[0] == '-') 
1178    field = field.substr(1);
1179  return field;
1180}
1181static std::string
1182CoinReadGetString(int &whichArgument, int argc, const char *argv[])
1183{
1184  std::string field;
1185  if (whichArgument < argc) 
1186    field = argv[whichArgument++];
1187  else
1188    field = "";
1189  return field;
1190}
1191// valid 0 - okay, 1 bad, 2 not there
1192static int
1193CoinReadGetIntField(int &whichArgument, int argc, const char *argv[], int * valid)
1194{
1195  std::string field;
1196  if (whichArgument < argc) 
1197    field = argv[whichArgument++];
1198  else
1199    field = "0";
1200  long int value = 0;
1201  const char * start = field.c_str();
1202  char * endPointer = NULL;
1203  // check valid
1204  value =  strtol(start, &endPointer, 10);
1205  if (*endPointer == '\0') {
1206    *valid = 0;
1207  } else {
1208    *valid = 1;
1209    std::cout << "String of " << field;
1210  }
1211  return static_cast<int>(value);
1212}
1213static double
1214CoinReadGetDoubleField(int &whichArgument, int argc, const char *argv[], int * valid)
1215{
1216  std::string field;
1217  if (whichArgument < argc) 
1218    field = argv[whichArgument++];
1219  else
1220    field = "0.0";
1221  double value = 0.0;
1222  const char * start = field.c_str();
1223  char * endPointer = NULL;
1224  // check valid
1225  value =  strtod(start, &endPointer);
1226  if (*endPointer == '\0') {
1227    *valid = 0;
1228  } else {
1229    *valid = 1;
1230    std::cout << "String of " << field;
1231  }
1232  return value;
1233}
1234// Redefine all
1235#define CoinReadGetCommand(x,y) CoinReadGetCommand(whichArgument,x,y)
1236#define CoinReadGetString(x,y) CoinReadGetString(whichArgument,x,y)
1237#define CoinReadGetIntField(x,y,z) CoinReadGetIntField(whichArgument,x,y,z)
1238#define CoinReadGetDoubleField(x,y,z) CoinReadGetDoubleField(whichArgument,x,y,z)
1239#endif
1240// Default Constructor
1241CbcSolverUsefulData::CbcSolverUsefulData()
1242{
1243  totalTime_ = 0.0;
1244  noPrinting_ = true;
1245  useSignalHandler_ = false;
1246  establishParams(numberParameters_,parameters_);
1247}
1248
1249/* Copy constructor .
1250 */
1251CbcSolverUsefulData::CbcSolverUsefulData(const CbcSolverUsefulData & rhs)
1252{
1253  totalTime_ = rhs.totalTime_;
1254  noPrinting_ = rhs.noPrinting_;
1255  useSignalHandler_ = rhs.useSignalHandler_;
1256  numberParameters_ = rhs.numberParameters_;
1257  memcpy(parameters_,rhs.parameters_,sizeof(parameters_));
1258}
1259
1260// Assignment operator
1261CbcSolverUsefulData & CbcSolverUsefulData::operator=(const CbcSolverUsefulData& rhs)
1262{
1263  if (this != &rhs) {
1264    totalTime_ = rhs.totalTime_;
1265    noPrinting_ = rhs.noPrinting_;
1266    useSignalHandler_ = rhs.useSignalHandler_;
1267    numberParameters_ = rhs.numberParameters_;
1268    memcpy(parameters_,rhs.parameters_,sizeof(parameters_));
1269  }
1270  return *this;
1271}
1272
1273// Destructor
1274CbcSolverUsefulData::~CbcSolverUsefulData ()
1275{
1276}
1277
[1391]1278/*
1279  Meaning of whereFrom:
1280    1 after initial solve by dualsimplex etc
1281    2 after preprocessing
1282    3 just before branchAndBound (so user can override)
1283    4 just after branchAndBound (before postprocessing)
1284    5 after postprocessing
1285    6 after a user called heuristic phase
[738]1286*/
[765]1287
[696]1288int CbcMain1 (int argc, const char *argv[],
[1286]1289              CbcModel  & model,
1290              int callBack(CbcModel * currentSolver, int whereFrom))
[696]1291{
[1998]1292  // allow interrupts and printing
1293  staticParameterData.noPrinting_ = false;
1294  staticParameterData.useSignalHandler_=true;
1295  return CbcMain1(argc,argv,model,callBack,staticParameterData);
1296}
[2069]1297static void printGeneralMessage(CbcModel &model,const char * message);
[1998]1298/*
1299  Meaning of whereFrom:
1300    1 after initial solve by dualsimplex etc
1301    2 after preprocessing
1302    3 just before branchAndBound (so user can override)
1303    4 just after branchAndBound (before postprocessing)
1304    5 after postprocessing
1305    6 after a user called heuristic phase
1306*/
1307int CbcMain1 (int argc, const char *argv[],
1308              CbcModel  & model,
1309              int callBack(CbcModel * currentSolver, int whereFrom),
1310              CbcSolverUsefulData & parameterData)
1311{
1312    CbcOrClpParam * parameters_ = parameterData.parameters_;
1313    int numberParameters_ = parameterData.numberParameters_;
1314    double totalTime = parameterData.totalTime_;
1315    bool noPrinting = parameterData.noPrinting_;
1316    bool useSignalHandler = parameterData.useSignalHandler_;
[1286]1317    CbcModel & model_ = model;
[1998]1318#ifdef CBC_THREAD_SAFE
1319    // Initialize argument
1320    int whichArgument=1;
1321#endif
[1656]1322#ifdef CBC_USE_INITIAL_TIME
1323    if (model_.useElapsedTime())
1324      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
1325    else
1326      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
1327#endif
[1286]1328    CbcModel * babModel_ = NULL;
1329    int returnMode = 1;
1330    CbcOrClpRead_mode = 1;
1331    int statusUserFunction_[1];
1332    int numberUserFunctions_ = 1; // to allow for ampl
1333    // Statistics
1334    double statistics_seconds = 0.0, statistics_obj = 0.0;
1335    double statistics_sys_seconds = 0.0, statistics_elapsed_seconds = 0.0;
1336    CoinWallclockTime();
1337    double statistics_continuous = 0.0, statistics_tighter = 0.0;
1338    double statistics_cut_time = 0.0;
1339    int statistics_nodes = 0, statistics_iterations = 0;
1340    int statistics_nrows = 0, statistics_ncols = 0;
1341    int statistics_nprocessedrows = 0, statistics_nprocessedcols = 0;
1342    std::string statistics_result;
1343    int * statistics_number_cuts = NULL;
1344    const char ** statistics_name_generators = NULL;
1345    int statistics_number_generators = 0;
1346    memset(statusUserFunction_, 0, numberUserFunctions_*sizeof(int));
1347    /* Note
1348       This is meant as a stand-alone executable to do as much of coin as possible.
1349       It should only have one solver known to it.
1350    */
1351    CoinMessageHandler * generalMessageHandler = model_.messageHandler();
1352    generalMessageHandler->setPrefix(false);
[1132]1353#ifndef CBC_OTHER_SOLVER
[1286]1354    OsiClpSolverInterface * originalSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver());
1355    assert (originalSolver);
1356    // Move handler across if not default
1357    if (!originalSolver->defaultHandler() && originalSolver->getModelPtr()->defaultHandler())
1358        originalSolver->getModelPtr()->passInMessageHandler(originalSolver->messageHandler());
1359    CoinMessages generalMessages = originalSolver->getModelPtr()->messages();
1360    char generalPrint[10000];
1361    if (originalSolver->getModelPtr()->logLevel() == 0)
1362        noPrinting = true;
[1132]1363#elif CBC_OTHER_SOLVER==1
[1286]1364    OsiCpxSolverInterface * originalSolver = dynamic_cast<OsiCpxSolverInterface *> (model_.solver());
1365    assert (originalSolver);
1366    OsiClpSolverInterface dummySolver;
1367    OsiCpxSolverInterface * clpSolver = originalSolver;
1368    CoinMessages generalMessages = dummySolver.getModelPtr()->messages();
1369    char generalPrint[10000];
1370    noPrinting = true;
[1132]1371#endif
[1286]1372    bool noPrinting_ = noPrinting;
1373    // Say not in integer
1374    int integerStatus = -1;
1375    // Say no resolve after cuts
1376    model_.setResolveAfterTakeOffCuts(false);
1377    // see if log in list
1378    for (int i = 1; i < argc; i++) {
1379        if (!strncmp(argv[i], "log", 3)) {
1380            const char * equals = strchr(argv[i], '=');
1381            if (equals && atoi(equals + 1) != 0)
1382                noPrinting_ = false;
1383            else
1384                noPrinting_ = true;
1385            break;
1386        } else if (!strncmp(argv[i], "-log", 4) && i < argc - 1) {
1387            if (atoi(argv[i+1]) != 0)
1388                noPrinting_ = false;
1389            else
1390                noPrinting_ = true;
1391            break;
1392        }
[696]1393    }
[1286]1394    double time0;
[1623]1395    double time0Elapsed = CoinGetTimeOfDay();
[1286]1396    {
1397        double time1 = CoinCpuTime(), time2;
1398        time0 = time1;
[1626]1399        double time1Elapsed = time0Elapsed;
[1286]1400        bool goodModel = (originalSolver->getNumCols()) ? true : false;
[640]1401
[1286]1402        // register signal handler
1403        //CoinSighandler_t saveSignal=signal(SIGINT,signal_handler);
[1735]1404#if CBC_QUIET < 2
[1998]1405        if (useSignalHandler)
1406          signal(SIGINT, signal_handler);
[1592]1407#endif
[1286]1408        // Set up all non-standard stuff
1409        int cutPass = -1234567;
1410        int cutPassInTree = -1234567;
1411        int tunePreProcess = 0;
1412        int testOsiParameters = -1;
1413        // 0 normal, 1 from ampl or MIQP etc (2 allows cuts)
1414        int complicatedInteger = 0;
1415        OsiSolverInterface * solver = model_.solver();
1416        if (noPrinting_)
1417            setCbcOrClpPrinting(false);
[1132]1418#ifndef CBC_OTHER_SOLVER
[1286]1419        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1420        ClpSimplex * lpSolver = clpSolver->getModelPtr();
1421        if (noPrinting_) {
1422            lpSolver->setLogLevel(0);
1423        }
[1132]1424#else
[1286]1425        ClpSimplex * lpSolver = NULL;
[1132]1426#endif
[1286]1427        // For priorities etc
1428        int * priorities = NULL;
1429        int * branchDirection = NULL;
1430        double * pseudoDown = NULL;
1431        double * pseudoUp = NULL;
1432        double * solutionIn = NULL;
1433        int * prioritiesIn = NULL;
[1770]1434        std::vector< std::pair< std::string, double > > mipStart;
[1880]1435        std::vector< std::pair< std::string, double > > mipStartBefore;
[1286]1436        int numberSOS = 0;
1437        int * sosStart = NULL;
1438        int * sosIndices = NULL;
1439        char * sosType = NULL;
1440        double * sosReference = NULL;
1441        int * cut = NULL;
1442        int * sosPriority = NULL;
1443        CglStored storedAmpl;
1444        CoinModel * coinModel = NULL;
1445        CoinModel saveCoinModel;
1446        CoinModel saveTightenedModel;
1447        int * whichColumn = NULL;
1448        int * knapsackStart = NULL;
1449        int * knapsackRow = NULL;
1450        int numberKnapsack = 0;
[789]1451#ifdef COIN_HAS_ASL
[1286]1452        ampl_info info;
1453        {
1454            memset(&info, 0, sizeof(info));
1455            if (argc > 2 && !strcmp(argv[2], "-AMPL")) {
1456                statusUserFunction_[0] = 1;
1457                // see if log in list
1458                noPrinting_ = true;
1459                for (int i = 1; i < argc; i++) {
1460                    if (!strncmp(argv[i], "log", 3)) {
1461                        const char * equals = strchr(argv[i], '=');
1462                        if (equals && atoi(equals + 1) > 0) {
1463                            noPrinting_ = false;
1464                            info.logLevel = atoi(equals + 1);
[1373]1465                            int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
[1286]1466                            parameters_[log].setIntValue(info.logLevel);
1467                            // mark so won't be overWritten
1468                            info.numberRows = -1234567;
1469                            break;
1470                        }
1471                    }
1472                }
[819]1473
[1286]1474                union {
1475                    void * voidModel;
1476                    CoinModel * model;
1477                } coinModelStart;
1478                coinModelStart.model = NULL;
1479                int returnCode = readAmpl(&info, argc, const_cast<char **>(argv), & coinModelStart.voidModel);
1480                coinModel = coinModelStart.model;
1481                if (returnCode)
1482                    return returnCode;
1483                CbcOrClpRead_mode = 2; // so will start with parameters
1484                // see if log in list (including environment)
1485                for (int i = 1; i < info.numberArguments; i++) {
1486                    if (!strcmp(info.arguments[i], "log")) {
1487                        if (i < info.numberArguments - 1 && atoi(info.arguments[i+1]) > 0)
1488                            noPrinting_ = false;
1489                        break;
1490                    }
1491                }
1492                if (noPrinting_) {
1493                    model_.messageHandler()->setLogLevel(0);
1494                    setCbcOrClpPrinting(false);
1495                }
1496                if (!noPrinting_)
1497                    printf("%d rows, %d columns and %d elements\n",
1498                           info.numberRows, info.numberColumns, info.numberElements);
[640]1499#ifdef COIN_HAS_LINK
[1286]1500                if (!coinModel) {
[640]1501#endif
[1286]1502                    solver->loadProblem(info.numberColumns, info.numberRows, info.starts,
1503                                        info.rows, info.elements,
1504                                        info.columnLower, info.columnUpper, info.objective,
1505                                        info.rowLower, info.rowUpper);
1506                    // take off cuts if ampl wants that
1507                    if (info.cut && 0) {
1508                        printf("AMPL CUTS OFF until global cuts fixed\n");
1509                        info.cut = NULL;
1510                    }
1511                    if (info.cut) {
1512                        int numberRows = info.numberRows;
1513                        int * whichRow = new int [numberRows];
1514                        // Row copy
1515                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1516                        const double * elementByRow = matrixByRow->getElements();
1517                        const int * column = matrixByRow->getIndices();
1518                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1519                        const int * rowLength = matrixByRow->getVectorLengths();
1520
1521                        const double * rowLower = solver->getRowLower();
1522                        const double * rowUpper = solver->getRowUpper();
1523                        int nDelete = 0;
1524                        for (int iRow = 0; iRow < numberRows; iRow++) {
1525                            if (info.cut[iRow]) {
1526                                whichRow[nDelete++] = iRow;
1527                                int start = rowStart[iRow];
1528                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1529                                                  rowLength[iRow], column + start, elementByRow + start);
1530                            }
1531                        }
1532                        solver->deleteRows(nDelete, whichRow);
1533                        delete [] whichRow;
1534                    }
[640]1535#ifdef COIN_HAS_LINK
[1286]1536                } else {
[1132]1537#ifndef CBC_OTHER_SOLVER
[1286]1538                    // save
1539                    saveCoinModel = *coinModel;
1540                    // load from coin model
1541                    OsiSolverLink solver1;
1542                    OsiSolverInterface * solver2 = solver1.clone();
1543                    model_.assignSolver(solver2, false);
1544                    OsiSolverLink * si =
1545                        dynamic_cast<OsiSolverLink *>(model_.solver()) ;
1546                    assert (si != NULL);
1547                    si->setDefaultMeshSize(0.001);
1548                    // need some relative granularity
1549                    si->setDefaultBound(100.0);
[1373]1550                    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA3, numberParameters_, parameters_)].doubleValue();
[1286]1551                    if (dextra3)
1552                        si->setDefaultMeshSize(dextra3);
1553                    si->setDefaultBound(100000.0);
1554                    si->setIntegerPriority(1000);
1555                    si->setBiLinearPriority(10000);
1556                    CoinModel * model2 = reinterpret_cast<CoinModel *> (coinModel);
[1373]1557                    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
[1286]1558                    si->load(*model2, true, logLevel);
1559                    // redo
1560                    solver = model_.solver();
1561                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
1562                    lpSolver = clpSolver->getModelPtr();
1563                    clpSolver->messageHandler()->setLogLevel(0) ;
1564                    testOsiParameters = 0;
[1373]1565                    parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(0);
[1286]1566                    complicatedInteger = 1;
1567                    if (info.cut) {
1568                        printf("Sorry - can't do cuts with LOS as ruins delicate row order\n");
1569                        abort();
1570                        int numberRows = info.numberRows;
1571                        int * whichRow = new int [numberRows];
1572                        // Row copy
1573                        const CoinPackedMatrix * matrixByRow = solver->getMatrixByRow();
1574                        const double * elementByRow = matrixByRow->getElements();
1575                        const int * column = matrixByRow->getIndices();
1576                        const CoinBigIndex * rowStart = matrixByRow->getVectorStarts();
1577                        const int * rowLength = matrixByRow->getVectorLengths();
1578
1579                        const double * rowLower = solver->getRowLower();
1580                        const double * rowUpper = solver->getRowUpper();
1581                        int nDelete = 0;
1582                        for (int iRow = 0; iRow < numberRows; iRow++) {
1583                            if (info.cut[iRow]) {
1584                                whichRow[nDelete++] = iRow;
1585                                int start = rowStart[iRow];
1586                                storedAmpl.addCut(rowLower[iRow], rowUpper[iRow],
1587                                                  rowLength[iRow], column + start, elementByRow + start);
1588                            }
1589                        }
1590                        solver->deleteRows(nDelete, whichRow);
1591                        // and special matrix
1592                        si->cleanMatrix()->deleteRows(nDelete, whichRow);
1593                        delete [] whichRow;
1594                    }
[1132]1595#endif
[1286]1596                }
[640]1597#endif
[1286]1598                // If we had a solution use it
1599                if (info.primalSolution) {
1600                    solver->setColSolution(info.primalSolution);
1601                }
1602                // status
1603                if (info.rowStatus) {
1604                    unsigned char * statusArray = lpSolver->statusArray();
1605                    int i;
1606                    for (i = 0; i < info.numberColumns; i++)
1607                        statusArray[i] = static_cast<unsigned char>(info.columnStatus[i]);
1608                    statusArray += info.numberColumns;
1609                    for (i = 0; i < info.numberRows; i++)
1610                        statusArray[i] = static_cast<unsigned char>(info.rowStatus[i]);
1611                    CoinWarmStartBasis * basis = lpSolver->getBasis();
1612                    solver->setWarmStart(basis);
1613                    delete basis;
1614                }
1615                freeArrays1(&info);
1616                // modify objective if necessary
1617                solver->setObjSense(info.direction);
[2030]1618                solver->setDblParam(OsiObjOffset, -info.offset);
[1286]1619                if (info.offset) {
1620                    sprintf(generalPrint, "Ampl objective offset is %g",
1621                            info.offset);
1622                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
1623                    << generalPrint
1624                    << CoinMessageEol;
1625                }
1626                // Set integer variables (unless nonlinear when set)
1627                if (!info.nonLinear) {
1628                    for (int i = info.numberColumns - info.numberIntegers;
1629                            i < info.numberColumns; i++)
1630                        solver->setInteger(i);
1631                }
1632                goodModel = true;
1633                // change argc etc
1634                argc = info.numberArguments;
1635                argv = const_cast<const char **>(info.arguments);
1636            }
1637        }
1638#endif
1639        // default action on import
1640        int allowImportErrors = 0;
1641        int keepImportNames = 1;
1642        int doIdiot = -1;
1643        int outputFormat = 2;
1644        int slpValue = -1;
1645        int cppValue = -1;
1646        int printOptions = 0;
1647        int printMode = 0;
1648        int presolveOptions = 0;
1649        int substitution = 3;
1650        int dualize = 3;
1651        int doCrash = 0;
1652        int doVector = 0;
1653        int doSprint = -1;
1654        int doScaling = 4;
1655        // set reasonable defaults
1656        int preSolve = 5;
1657        int preProcess = 4;
1658        bool useStrategy = false;
1659        bool preSolveFile = false;
1660        bool strongChanged = false;
1661        bool pumpChanged = false;
1662
1663        double djFix = 1.0e100;
1664        double tightenFactor = 0.0;
1665        const char dirsep =  CoinFindDirSeparator();
1666        std::string directory;
1667        std::string dirSample;
1668        std::string dirNetlib;
1669        std::string dirMiplib;
1670        if (dirsep == '/') {
1671            directory = "./";
1672            dirSample = "../../Data/Sample/";
1673            dirNetlib = "../../Data/Netlib/";
1674            dirMiplib = "../../Data/miplib3/";
1675        } else {
1676            directory = ".\\";
[1334]1677            dirSample = "..\\..\\..\\..\\Data\\Sample\\";
1678            dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\";
1679            dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\";
[1286]1680        }
1681        std::string defaultDirectory = directory;
1682        std::string importFile = "";
1683        std::string exportFile = "default.mps";
1684        std::string importBasisFile = "";
1685        std::string importPriorityFile = "";
1686        std::string debugFile = "";
1687        std::string printMask = "";
1688        double * debugValues = NULL;
1689        int numberDebugValues = -1;
1690        int basisHasValues = 0;
1691        std::string exportBasisFile = "default.bas";
1692        std::string saveFile = "default.prob";
1693        std::string restoreFile = "default.prob";
1694        std::string solutionFile = "stdout";
1695        std::string solutionSaveFile = "solution.file";
[1373]1696        int slog = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_);
1697        int log = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_);
[1132]1698#ifndef CBC_OTHER_SOLVER
[1286]1699        double normalIncrement = model_.getCutoffIncrement();;
[1132]1700#endif
[1286]1701        if (testOsiParameters >= 0) {
1702            // trying nonlinear - switch off some stuff
1703            preProcess = 0;
1704        }
1705        // Set up likely cut generators and defaults
1706        int nodeStrategy = 0;
1707        bool dominatedCuts = false;
1708        int doSOS = 1;
1709        int verbose = 0;
1710        CglGomory gomoryGen;
1711        // try larger limit
1712        gomoryGen.setLimitAtRoot(1000);
1713        gomoryGen.setLimit(50);
1714        // set default action (0=off,1=on,2=root)
[2173]1715#ifdef SWAP_GOMORY
[2172]1716        int gomoryAction = 0;
[2173]1717#else
1718        int gomoryAction = 3;
1719#endif
[640]1720
[1286]1721        CglProbing probingGen;
1722        probingGen.setUsingObjective(1);
1723        probingGen.setMaxPass(1);
1724        probingGen.setMaxPassRoot(1);
1725        // Number of unsatisfied variables to look at
1726        probingGen.setMaxProbe(10);
1727        probingGen.setMaxProbeRoot(50);
1728        // How far to follow the consequences
1729        probingGen.setMaxLook(10);
1730        probingGen.setMaxLookRoot(50);
1731        probingGen.setMaxLookRoot(10);
1732        // Only look at rows with fewer than this number of elements
1733        probingGen.setMaxElements(200);
1734        probingGen.setMaxElementsRoot(300);
1735        probingGen.setRowCuts(3);
1736        // set default action (0=off,1=on,2=root)
1737        int probingAction = 1;
[640]1738
[1286]1739        CglKnapsackCover knapsackGen;
1740        //knapsackGen.switchOnExpensive();
1741        //knapsackGen.setMaxInKnapsack(100);
1742        // set default action (0=off,1=on,2=root)
1743        int knapsackAction = 3;
[640]1744
[1286]1745        CglRedSplit redsplitGen;
1746        //redsplitGen.setLimit(100);
1747        // set default action (0=off,1=on,2=root)
1748        // Off as seems to give some bad cuts
1749        int redsplitAction = 0;
[640]1750
[1876]1751        CglRedSplit2 redsplit2Gen;
1752        //redsplit2Gen.setLimit(100);
1753        // set default action (0=off,1=on,2=root)
1754        // Off
1755        int redsplit2Action = 0;
1756
1757        CglGMI GMIGen;
1758        //GMIGen.setLimit(100);
1759        // set default action (0=off,1=on,2=root)
[2173]1760#ifdef SWAP_GOMORY
1761        int GMIAction = 3;
1762#else
[1880]1763        // Off
[2173]1764        int GMIAction = 0;
1765#endif
[1876]1766
[1286]1767        CglFakeClique cliqueGen(NULL, false);
1768        //CglClique cliqueGen(false,true);
1769        cliqueGen.setStarCliqueReport(false);
1770        cliqueGen.setRowCliqueReport(false);
1771        cliqueGen.setMinViolation(0.1);
1772        // set default action (0=off,1=on,2=root)
1773        int cliqueAction = 3;
[640]1774
[1286]1775        // maxaggr,multiply,criterion(1-3)
1776        CglMixedIntegerRounding2 mixedGen(1, true, 1);
1777        // set default action (0=off,1=on,2=root)
1778        int mixedAction = 3;
[1852]1779        mixedGen.setDoPreproc(1); // safer (and better)
[640]1780
[1286]1781        CglFlowCover flowGen;
1782        // set default action (0=off,1=on,2=root)
1783        int flowAction = 3;
[640]1784
[1286]1785        CglTwomir twomirGen;
1786        twomirGen.setMaxElements(250);
1787        // set default action (0=off,1=on,2=root)
[1880]1788        int twomirAction = 3;
[1286]1789#ifndef DEBUG_MALLOC
1790        CglLandP landpGen;
[1880]1791        landpGen.validator().setMinViolation(1.0e-4);
[857]1792#endif
[1286]1793        // set default action (0=off,1=on,2=root)
1794        int landpAction = 0;
1795        CglResidualCapacity residualCapacityGen;
[1847]1796        residualCapacityGen.setDoPreproc(1); // always preprocess
[1286]1797        // set default action (0=off,1=on,2=root)
1798        int residualCapacityAction = 0;
[1121]1799
[1286]1800        CglZeroHalf zerohalfGen;
1801        //zerohalfGen.switchOnExpensive();
1802        // set default action (0=off,1=on,2=root)
1803        int zerohalfAction = 0;
[1121]1804
[1286]1805        // Stored cuts
1806        //bool storedCuts = false;
[640]1807
[1286]1808        int useCosts = 0;
1809        // don't use input solution
1810        int useSolution = -1;
[640]1811
[1286]1812        // total number of commands read
1813        int numberGoodCommands = 0;
1814        // Set false if user does anything advanced
1815        bool defaultSettings = true;
1816
1817        // Hidden stuff for barrier
1818        int choleskyType = 0;
1819        int gamma = 0;
1820        int scaleBarrier = 0;
1821        int doKKT = 0;
1822        int crossover = 2; // do crossover unless quadratic
[1876]1823        bool biLinearProblem=false;
[1286]1824        // For names
1825        int lengthName = 0;
1826        std::vector<std::string> rowNames;
1827        std::vector<std::string> columnNames;
1828        // Default strategy stuff
1829        {
1830            // try changing tolerance at root
[1053]1831#define MORE_CUTS
1832#ifdef MORE_CUTS
[1286]1833            gomoryGen.setAwayAtRoot(0.005);
1834            twomirGen.setAwayAtRoot(0.005);
1835            twomirGen.setAway(0.01);
1836            //twomirGen.setMirScale(1,1);
1837            //twomirGen.setTwomirScale(1,1);
1838            //twomirGen.setAMax(2);
[1053]1839#else
[1286]1840            gomoryGen.setAwayAtRoot(0.01);
1841            twomirGen.setAwayAtRoot(0.01);
1842            twomirGen.setAway(0.01);
[1053]1843#endif
[1286]1844            int iParam;
[1373]1845            iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
[2093]1846            parameters_[iParam].setIntValue(2);
[1373]1847            iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
[1286]1848            parameters_[iParam].setIntValue(30);
[1373]1849            iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
[1286]1850            parameters_[iParam].setIntValue(1005043);
1851            initialPumpTune = 1005043;
[1373]1852            iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
[1286]1853            parameters_[iParam].setIntValue(6);
1854            tunePreProcess = 6;
[1373]1855            iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
[1286]1856            parameters_[iParam].setCurrentOption("on");
[1373]1857            iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
[1286]1858            parameters_[iParam].setCurrentOption("on");
[1373]1859            iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
[1286]1860            parameters_[iParam].setCurrentOption("on");
[1880]1861            probingAction = 3;
1862            //parameters_[iParam].setCurrentOption("forceOnStrong");
1863            //probingAction = 8;
[1286]1864        }
1865        std::string field;
[1735]1866#if CBC_QUIET == 0
[1286]1867        if (!noPrinting_) {
[1539]1868           sprintf(generalPrint,
1869                   "Welcome to the CBC MILP Solver \n");
1870            if (strcmp(CBC_VERSION, "trunk")){
1871               sprintf(generalPrint + strlen(generalPrint),
1872                       "Version: %s \n", CBC_VERSION);
1873            }else{
1874               sprintf(generalPrint + strlen(generalPrint),
1875                       "Version: Trunk (unstable) \n");
1876            }
1877            sprintf(generalPrint + strlen(generalPrint),
1878                    "Build Date: %s \n", __DATE__);
1879#ifdef CBC_SVN_REV
1880            sprintf(generalPrint + strlen(generalPrint),
1881                    "Revision Number: %d \n", CBC_SVN_REV);
1882#endif
[1286]1883            generalMessageHandler->message(CLP_GENERAL, generalMessages)
1884            << generalPrint
1885            << CoinMessageEol;
1886            // Print command line
1887            if (argc > 1) {
1888                bool foundStrategy = false;
1889                sprintf(generalPrint, "command line - ");
1890                for (int i = 0; i < argc; i++) {
1891                    if (!argv[i])
1892                        break;
1893                    if (strstr(argv[i], "strat"))
1894                        foundStrategy = true;
1895                    sprintf(generalPrint + strlen(generalPrint), "%s ", argv[i]);
1896                }
1897                if (!foundStrategy)
1898                    sprintf(generalPrint + strlen(generalPrint), "(default strategy 1)");
1899                generalMessageHandler->message(CLP_GENERAL, generalMessages)
1900                << generalPrint
1901                << CoinMessageEol;
1902            }
1903        }
[1591]1904#endif
[1286]1905        while (1) {
1906            // next command
1907            field = CoinReadGetCommand(argc, argv);
1908            // Reset time
1909            time1 = CoinCpuTime();
[1626]1910            time1Elapsed = CoinGetTimeOfDay();
[1286]1911            // adjust field if has odd trailing characters
1912            char temp [200];
1913            strcpy(temp, field.c_str());
[1644]1914            int length = static_cast<int>(strlen(temp));
[1286]1915            for (int k = length - 1; k >= 0; k--) {
1916                if (temp[k] < ' ')
1917                    length--;
1918                else
1919                    break;
1920            }
1921            temp[length] = '\0';
1922            field = temp;
1923            // exit if null or similar
1924            if (!field.length()) {
1925                if (numberGoodCommands == 1 && goodModel) {
1926                    // we just had file name - do branch and bound
1927                    field = "branch";
1928                } else if (!numberGoodCommands) {
1929                    // let's give the sucker a hint
1930                    std::cout
1931                        << "CoinSolver takes input from arguments ( - switches to stdin)"
1932                        << std::endl
1933                        << "Enter ? for list of commands or help" << std::endl;
1934                    field = "-";
1935                } else {
1936                    break;
1937                }
1938            }
1939
1940            // see if ? at end
[1644]1941            size_t numberQuery = 0;
[1286]1942            if (field != "?" && field != "???") {
[1644]1943                size_t length = field.length();
1944                size_t i;
[1286]1945                for (i = length - 1; i > 0; i--) {
1946                    if (field[i] == '?')
1947                        numberQuery++;
1948                    else
1949                        break;
1950                }
1951                field = field.substr(0, length - numberQuery);
1952            }
1953            // find out if valid command
1954            int iParam;
1955            int numberMatches = 0;
1956            int firstMatch = -1;
1957            for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
1958                int match = parameters_[iParam].matches(field);
1959                if (match == 1) {
1960                    numberMatches = 1;
1961                    firstMatch = iParam;
1962                    break;
1963                } else {
1964                    if (match && firstMatch < 0)
1965                        firstMatch = iParam;
1966                    numberMatches += match >> 1;
1967                }
1968            }
1969            if (iParam < numberParameters_ && !numberQuery) {
1970                // found
1971                CbcOrClpParam found = parameters_[iParam];
1972                CbcOrClpParameterType type = found.type();
1973                int valid;
1974                numberGoodCommands++;
[1373]1975                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
[1656]1976#ifndef CBC_USE_INITIAL_TIME
[1623]1977                  if (model_.useElapsedTime())
[1621]1978                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
[1623]1979                  else
1980                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
[1656]1981#endif
[1876]1982                  biLinearProblem=false;
[1286]1983                    // check if any integers
[1132]1984#ifndef CBC_OTHER_SOLVER
[640]1985#ifdef COIN_HAS_ASL
[1286]1986                    if (info.numberSos && doSOS && statusUserFunction_[0]) {
1987                        // SOS
1988                        numberSOS = info.numberSos;
1989                    }
[640]1990#endif
[1286]1991                    lpSolver = clpSolver->getModelPtr();
1992                    if (!lpSolver->integerInformation() && !numberSOS &&
1993                            !clpSolver->numberSOS() && !model_.numberObjects() && !clpSolver->numberObjects())
[1373]1994                        type = CLP_PARAM_ACTION_DUALSIMPLEX;
[1132]1995#endif
[1286]1996                }
[1373]1997                if (type == CBC_PARAM_GENERALQUERY) {
[1286]1998                    bool evenHidden = false;
1999                    int printLevel =
[1373]2000                        parameters_[whichParam(CLP_PARAM_STR_ALLCOMMANDS,
[1286]2001                                               numberParameters_, parameters_)].currentOptionAsInteger();
2002                    int convertP[] = {2, 1, 0};
2003                    printLevel = convertP[printLevel];
2004                    if ((verbose&8) != 0) {
2005                        // even hidden
2006                        evenHidden = true;
2007                        verbose &= ~8;
2008                    }
[640]2009#ifdef COIN_HAS_ASL
[1286]2010                    if (verbose < 4 && statusUserFunction_[0])
2011                        verbose += 4;
[640]2012#endif
[1286]2013                    if (verbose < 4) {
2014                        std::cout << "In argument list keywords have leading - "
2015                                  ", -stdin or just - switches to stdin" << std::endl;
2016                        std::cout << "One command per line (and no -)" << std::endl;
2017                        std::cout << "abcd? gives list of possibilities, if only one + explanation" << std::endl;
2018                        std::cout << "abcd?? adds explanation, if only one fuller help" << std::endl;
2019                        std::cout << "abcd without value (where expected) gives current value" << std::endl;
2020                        std::cout << "abcd value sets value" << std::endl;
2021                        std::cout << "Commands are:" << std::endl;
2022                    } else {
2023                        std::cout << "Cbc options are set within AMPL with commands like:" << std::endl << std::endl;
2024                        std::cout << "         option cbc_options \"cuts=root log=2 feas=on slog=1\"" << std::endl << std::endl;
2025                        std::cout << "only maximize, dual, primal, help and quit are recognized without =" << std::endl;
[640]2026                    }
[1286]2027                    int maxAcross = 10;
2028                    if ((verbose % 4) != 0)
2029                        maxAcross = 1;
2030                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2031                    std::vector<std::string> types;
2032                    types.push_back("Double parameters:");
2033                    types.push_back("Branch and Cut double parameters:");
2034                    types.push_back("Integer parameters:");
2035                    types.push_back("Branch and Cut integer parameters:");
2036                    types.push_back("Keyword parameters:");
2037                    types.push_back("Branch and Cut keyword parameters:");
2038                    types.push_back("Actions or string parameters:");
2039                    types.push_back("Branch and Cut actions:");
2040                    int iType;
2041                    for (iType = 0; iType < 8; iType++) {
2042                        int across = 0;
2043                        int lengthLine = 0;
2044                        if ((verbose % 4) != 0)
2045                            std::cout << std::endl;
2046                        std::cout << types[iType] << std::endl;
2047                        if ((verbose&2) != 0)
2048                            std::cout << std::endl;
2049                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2050                            int type = parameters_[iParam].type();
2051                            //printf("%d type %d limits %d %d display %d\n",iParam,
2052                            //     type,limits[iType],limits[iType+1],parameters_[iParam].displayThis());
2053                            if ((parameters_[iParam].displayThis() >= printLevel || evenHidden) &&
2054                                    type >= limits[iType]
2055                                    && type < limits[iType+1]) {
2056                                // but skip if not useful for ampl (and in ampl mode)
2057                                if (verbose >= 4 && (parameters_[iParam].whereUsed()&4) == 0)
2058                                    continue;
2059                                if (!across) {
2060                                    if ((verbose&2) != 0)
2061                                        std::cout << "Command ";
2062                                }
2063                                int length = parameters_[iParam].lengthMatchName() + 1;
2064                                if (lengthLine + length > 80) {
2065                                    std::cout << std::endl;
2066                                    across = 0;
2067                                    lengthLine = 0;
2068                                }
2069                                std::cout << " " << parameters_[iParam].matchName();
2070                                lengthLine += length;
2071                                across++;
2072                                if (across == maxAcross) {
2073                                    across = 0;
2074                                    if ((verbose % 4) != 0) {
2075                                        // put out description as well
2076                                        if ((verbose&1) != 0)
2077                                            std::cout << " " << parameters_[iParam].shortHelp();
2078                                        std::cout << std::endl;
2079                                        if ((verbose&2) != 0) {
2080                                            std::cout << "---- description" << std::endl;
2081                                            parameters_[iParam].printLongHelp();
2082                                            std::cout << "----" << std::endl << std::endl;
2083                                        }
2084                                    } else {
2085                                        std::cout << std::endl;
2086                                    }
2087                                }
2088                            }
2089                        }
2090                        if (across)
2091                            std::cout << std::endl;
2092                    }
[1373]2093                } else if (type == CBC_PARAM_FULLGENERALQUERY) {
[1286]2094                    std::cout << "Full list of commands is:" << std::endl;
2095                    int maxAcross = 5;
2096                    int limits[] = {1, 51, 101, 151, 201, 251, 301, 351, 401};
2097                    std::vector<std::string> types;
2098                    types.push_back("Double parameters:");
2099                    types.push_back("Branch and Cut double parameters:");
2100                    types.push_back("Integer parameters:");
2101                    types.push_back("Branch and Cut integer parameters:");
2102                    types.push_back("Keyword parameters:");
2103                    types.push_back("Branch and Cut keyword parameters:");
2104                    types.push_back("Actions or string parameters:");
2105                    types.push_back("Branch and Cut actions:");
2106                    int iType;
2107                    for (iType = 0; iType < 8; iType++) {
2108                        int across = 0;
2109                        std::cout << types[iType] << "  ";
2110                        for ( iParam = 0; iParam < numberParameters_; iParam++ ) {
2111                            int type = parameters_[iParam].type();
2112                            if (type >= limits[iType]
2113                                    && type < limits[iType+1]) {
2114                                if (!across)
2115                                    std::cout << "  ";
2116                                std::cout << parameters_[iParam].matchName() << "  ";
2117                                across++;
2118                                if (across == maxAcross) {
2119                                    std::cout << std::endl;
2120                                    across = 0;
2121                                }
2122                            }
2123                        }
2124                        if (across)
2125                            std::cout << std::endl;
2126                    }
2127                } else if (type < 101) {
2128                    // get next field as double
2129                    double value = CoinReadGetDoubleField(argc, argv, &valid);
2130                    if (!valid) {
2131                        if (type < 51) {
2132                            int returnCode;
2133                            const char * message =
2134                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2135                            if (!noPrinting_ && strlen(message)) {
2136                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2137                                << message
2138                                << CoinMessageEol;
2139                            }
2140                        } else if (type < 81) {
2141                            int returnCode;
2142                            const char * message =
2143                                parameters_[iParam].setDoubleParameterWithMessage(model_, value, returnCode);
2144                            if (!noPrinting_ && strlen(message)) {
2145                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2146                                << message
2147                                << CoinMessageEol;
2148                            }
2149                        } else {
2150                            int returnCode;
2151                            const char * message =
2152                                parameters_[iParam].setDoubleParameterWithMessage(lpSolver, value, returnCode);
2153                            if (!noPrinting_ && strlen(message)) {
2154                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2155                                << message
2156                                << CoinMessageEol;
2157                            }
2158                            switch (type) {
[1373]2159                            case CBC_PARAM_DBL_DJFIX:
[1286]2160                                djFix = value;
[1132]2161#ifndef CBC_OTHER_SOLVER
[1286]2162                                if (goodModel && djFix < 1.0e20) {
2163                                    // do some fixing
2164                                    clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver());
2165                                    clpSolver->initialSolve();
2166                                    lpSolver = clpSolver->getModelPtr();
2167                                    int numberColumns = lpSolver->numberColumns();
2168                                    int i;
2169                                    const char * type = lpSolver->integerInformation();
2170                                    double * lower = lpSolver->columnLower();
2171                                    double * upper = lpSolver->columnUpper();
2172                                    double * solution = lpSolver->primalColumnSolution();
2173                                    double * dj = lpSolver->dualColumnSolution();
2174                                    int numberFixed = 0;
[1373]2175                                    double dextra4 = parameters_[whichParam(CBC_PARAM_DBL_DEXTRA4, numberParameters_, parameters_)].doubleValue();
[1286]2176                                    if (dextra4)
2177                                        printf("Multiple for continuous dj fixing is %g\n", dextra4);
2178                                    for (i = 0; i < numberColumns; i++) {
2179                                        double djValue = dj[i];
2180                                        if (!type[i])
2181                                            djValue *= dextra4;
2182                                        if (type[i] || dextra4) {
2183                                            double value = solution[i];
2184                                            if (value < lower[i] + 1.0e-5 && djValue > djFix) {
2185                                                solution[i] = lower[i];
2186                                                upper[i] = lower[i];
2187                                                numberFixed++;
2188                                            } else if (value > upper[i] - 1.0e-5 && djValue < -djFix) {
2189                                                solution[i] = upper[i];
2190                                                lower[i] = upper[i];
2191                                                numberFixed++;
2192                                            }
2193                                        }
2194                                    }
2195                                    sprintf(generalPrint, "%d columns fixed\n", numberFixed);
2196                                    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2197                                    << generalPrint
2198                                    << CoinMessageEol;
2199                                }
2200#endif
2201                                break;
[1373]2202                            case CBC_PARAM_DBL_TIGHTENFACTOR:
[1286]2203                                tightenFactor = value;
2204                                if (!complicatedInteger)
2205                                    defaultSettings = false; // user knows what she is doing
2206                                break;
2207                            default:
2208                                break;
2209                            }
2210                        }
2211                    } else if (valid == 1) {
2212                        std::cout << " is illegal for double parameter " << parameters_[iParam].name() << " value remains " <<
2213                                  parameters_[iParam].doubleValue() << std::endl;
2214                    } else {
2215                        std::cout << parameters_[iParam].name() << " has value " <<
2216                                  parameters_[iParam].doubleValue() << std::endl;
[753]2217                    }
[1286]2218                } else if (type < 201) {
2219                    // get next field as int
2220                    int value = CoinReadGetIntField(argc, argv, &valid);
2221                    if (!valid) {
2222                        if (type < 151) {
[1373]2223                            if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEPASS)
[1286]2224                                preSolve = value;
[1373]2225                            else if (parameters_[iParam].type() == CLP_PARAM_INT_IDIOT)
[1286]2226                                doIdiot = value;
[1373]2227                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SPRINT)
[1286]2228                                doSprint = value;
[1373]2229                            else if (parameters_[iParam].type() == CLP_PARAM_INT_OUTPUTFORMAT)
[1286]2230                                outputFormat = value;
[1373]2231                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SLPVALUE)
[1286]2232                                slpValue = value;
[1373]2233                            else if (parameters_[iParam].type() == CLP_PARAM_INT_CPP)
[1286]2234                                cppValue = value;
[1373]2235                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRESOLVEOPTIONS)
[1286]2236                                presolveOptions = value;
[1373]2237                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PRINTOPTIONS)
[1286]2238                                printOptions = value;
[1373]2239                            else if (parameters_[iParam].type() == CLP_PARAM_INT_SUBSTITUTION)
[1286]2240                                substitution = value;
[1373]2241                            else if (parameters_[iParam].type() == CLP_PARAM_INT_DUALIZE)
[1286]2242                                dualize = value;
[1373]2243                            else if (parameters_[iParam].type() == CLP_PARAM_INT_PROCESSTUNE)
[1286]2244                                tunePreProcess = value;
[1373]2245                            else if (parameters_[iParam].type() == CLP_PARAM_INT_USESOLUTION)
[1286]2246                                useSolution = value;
[1373]2247                            else if (parameters_[iParam].type() == CLP_PARAM_INT_VERBOSE)
[1286]2248                                verbose = value;
2249                            int returnCode;
2250                            const char * message =
2251                                parameters_[iParam].setIntParameterWithMessage(lpSolver, value, returnCode);
2252                            if (!noPrinting_ && strlen(message)) {
2253                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2254                                << message
2255                                << CoinMessageEol;
2256                            }
2257                        } else {
[1373]2258                            if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASS)
[1286]2259                                cutPass = value;
[1373]2260                            else if (parameters_[iParam].type() == CBC_PARAM_INT_CUTPASSINTREE)
[1286]2261                                cutPassInTree = value;
[1373]2262                            else if (parameters_[iParam].type() == CBC_PARAM_INT_STRONGBRANCHING ||
2263                                     parameters_[iParam].type() == CBC_PARAM_INT_NUMBERBEFORE)
[1286]2264                                strongChanged = true;
[1373]2265                            else if (parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE ||
2266                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPTUNE2 ||
2267                                     parameters_[iParam].type() == CBC_PARAM_INT_FPUMPITS)
[1286]2268                                pumpChanged = true;
[1373]2269                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
[1656]2270                                int addFlags=0;
[2094]2271                                // switch on some later features if >999
2272                                if (value>999) {
2273                                  int switchValue=value/1000;
2274                                  const char * message = NULL;
2275                                  value -= 1000*switchValue;
2276                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(0/*value*/);
2277                                  switch (switchValue) {
2278                                  default:
2279                                  case 4:
2280                                    // hotstart 500, -200 cut passes
2281                                    message=parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValueWithMessage(500);
2282                                    if (!noPrinting_&&message) 
2283                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2284                                        << message << CoinMessageEol;
2285                                    message=parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValueWithMessage(-200);
2286                                    if (!noPrinting_&&message) 
2287                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2288                                        << message << CoinMessageEol;
2289                                  case 3:
2290                                    // multiple 4
2291                                    message=parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValueWithMessage(4);
2292                                    if (!noPrinting_&&message) 
2293                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2294                                        << message << CoinMessageEol;
2295                                  case 2:
2296                                    // rens plus all diving at root
2297                                    message=parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].setIntValueWithMessage(16);
2298                                    if (!noPrinting_&&message) 
2299                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2300                                        << message << CoinMessageEol;
2301                                    model_.setNumberAnalyzeIterations(-value);
2302                                    // -tune 7 zero,lagomory,gmi at root - probing on
2303                                  case 1:
2304                                    tunePreProcess=7;
2305                                    message=parameters_[whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_)].setIntValueWithMessage(7);
2306                                    if (!noPrinting_&&message) 
2307                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2308                                        << message << CoinMessageEol;
2309                                    //message = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValueWithMessage(1025);
2310                                    //if (!noPrinting_&&message)
2311                                    //    generalMessageHandler->message(CLP_GENERAL, generalMessages)
2312                                    //  << message << CoinMessageEol;
2313                                    message=parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("on");
2314                                    probingAction = 1;
2315                                    if (!noPrinting_&&message) 
2316                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2317                                        << message << CoinMessageEol;
2318                                    message=parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2319                                    if (!noPrinting_&&message) 
2320                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2321                                        << message << CoinMessageEol;
2322                                    message=parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2323                                    if (!noPrinting_&&message) 
2324                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2325                                        << message << CoinMessageEol;
[2173]2326#ifdef SWAP_GOMORY
[2172]2327                                    GMIAction = 3;
2328                                    message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("ifmove");
[2173]2329#else
2330                                    GMIAction = 2;
2331                                    message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
2332#endif
[2094]2333                                    if (!noPrinting_&&message) 
2334                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2335                                        << message << CoinMessageEol;
2336                                  }
2337                                  value = 0;
2338                                }
[1656]2339                                if (value>=10) {
2340                                  addFlags = 1048576*(value/10);
2341                                  value = value % 10;
[1998]2342                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(value);
[1656]2343                                }
[1286]2344                                if (value >= 1) {
[1650]2345                                    int values[]={24003,280003,792003,24003,24003};
2346                                    if (value>=2&&value<=3) {
2347                                      // swap default diving
2348                                      int iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
2349                                      parameters_[iParam].setCurrentOption("off");
2350                                      iParam = whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_);
2351                                      parameters_[iParam].setCurrentOption("on");
2352                                    }
[1656]2353                                    int extra4 = values[value-1]+addFlags;
[1998]2354                                    parameters_[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters_, parameters_)].setIntValue(extra4);
[1286]2355                                    if (!noPrinting_) {
2356                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2357                                        << "switching on global root cuts for gomory and knapsack"
2358                                        << CoinMessageEol;
2359                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2360                                        << "using OSL factorization"
2361                                        << CoinMessageEol;
2362                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
[1650]2363                                        << "extra options - -rens on -extra4 "
2364                                        <<extra4<<" -passc 1000!"
[1286]2365                                        << CoinMessageEol;
2366                                    }
[1998]2367                                    parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("forceOnStrong");
[1286]2368                                    probingAction = 8;
[1373]2369                                    parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
[1286]2370                                    gomoryAction = 5;
[1373]2371                                    parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("onGlobal");
[1286]2372                                    knapsackAction = 5;
[1373]2373                                    parameters_[whichParam(CLP_PARAM_STR_FACTORIZATION, numberParameters_, parameters_)].setCurrentOption("osl");
[1286]2374                                    lpSolver->factorization()->forceOtherFactorization(3);
[1373]2375                                    parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100);
[1998]2376                                    parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValue(1000);
[1286]2377                                    cutPass = 1000;
[1998]2378                                    parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("on");
[1286]2379                                }
[1373]2380                            } else if (parameters_[iParam].type() == CBC_PARAM_INT_STRATEGY) {
[1286]2381                                if (value == 0) {
2382                                    gomoryGen.setAwayAtRoot(0.05);
2383                                    int iParam;
[1373]2384                                    iParam = whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_);
[1286]2385                                    parameters_[iParam].setIntValue(-1);
[1373]2386                                    iParam = whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_);
[1286]2387                                    parameters_[iParam].setIntValue(20);
[1373]2388                                    iParam = whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_);
[1286]2389                                    parameters_[iParam].setIntValue(1003);
2390                                    initialPumpTune = 1003;
[1373]2391                                    iParam = whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_);
[1864]2392                                    parameters_[iParam].setIntValue(0);
[1286]2393                                    tunePreProcess = 0;
[1373]2394                                    iParam = whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_);
[1286]2395                                    parameters_[iParam].setCurrentOption("off");
[1373]2396                                    iParam = whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_);
[1286]2397                                    parameters_[iParam].setCurrentOption("off");
[1373]2398                                    iParam = whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_);
[1864]2399                                    // but not if cuts off
2400                                    int jParam = whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_);
2401                                   
2402                                    jParam = parameters_[jParam].currentOptionAsInteger();
2403                                    if (jParam) {
2404                                      parameters_[iParam].setCurrentOption("on");
2405                                      probingAction = 1;
2406                                    } else {
2407                                      parameters_[iParam].setCurrentOption("off");
2408                                      probingAction = 0;
2409                                    }
[1286]2410                                }
2411                            }
2412                            int returnCode;
2413                            const char * message =
2414                                parameters_[iParam].setIntParameterWithMessage(model_, value, returnCode);
2415                            if (!noPrinting_ && strlen(message)) {
2416                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
2417                                << message
2418                                << CoinMessageEol;
2419                            }
2420                        }
2421                    } else if (valid == 1) {
2422                        std::cout << " is illegal for integer parameter " << parameters_[iParam].name() << " value remains " <<
2423                                  parameters_[iParam].intValue() << std::endl;
2424                    } else {
2425                        std::cout << parameters_[iParam].name() << " has value " <<
2426                                  parameters_[iParam].intValue() << std::endl;
2427                    }
2428                } else if (type < 301) {
2429                    // one of several strings
2430                    std::string value = CoinReadGetString(argc, argv);
2431                    int action = parameters_[iParam].parameterOption(value);
2432                    if (action < 0) {
2433                        if (value != "EOL") {
2434                            // no match
2435                            parameters_[iParam].printOptions();
2436                        } else {
2437                            // print current value
2438                            std::cout << parameters_[iParam].name() << " has value " <<
2439                                      parameters_[iParam].currentOption() << std::endl;
2440                        }
2441                    } else {
2442                        const char * message =
2443                            parameters_[iParam].setCurrentOptionWithMessage(action);
2444                        if (!noPrinting_ && strlen(message)) {
2445                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
2446                            << message
2447                            << CoinMessageEol;
2448                        }
2449                        // for now hard wired
2450                        switch (type) {
[1373]2451                        case CLP_PARAM_STR_DIRECTION:
[1286]2452                            if (action == 0)
2453                                lpSolver->setOptimizationDirection(1);
2454                            else if (action == 1)
2455                                lpSolver->setOptimizationDirection(-1);
2456                            else
2457                                lpSolver->setOptimizationDirection(0);
2458                            break;
[1373]2459                        case CLP_PARAM_STR_DUALPIVOT:
[1286]2460                            if (action == 0) {
2461                                ClpDualRowSteepest steep(3);
2462                                lpSolver->setDualRowPivotAlgorithm(steep);
2463                            } else if (action == 1) {
2464                                ClpDualRowDantzig dantzig;
2465                                //ClpDualRowSteepest dantzig(5);
2466                                lpSolver->setDualRowPivotAlgorithm(dantzig);
2467                            } else if (action == 2) {
2468                                // partial steep
2469                                ClpDualRowSteepest steep(2);
2470                                lpSolver->setDualRowPivotAlgorithm(steep);
2471                            } else {
2472                                ClpDualRowSteepest steep;
2473                                lpSolver->setDualRowPivotAlgorithm(steep);
2474                            }
2475                            break;
[1373]2476                        case CLP_PARAM_STR_PRIMALPIVOT:
[1286]2477                            if (action == 0) {
2478                                ClpPrimalColumnSteepest steep(3);
2479                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2480                            } else if (action == 1) {
2481                                ClpPrimalColumnSteepest steep(0);
2482                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2483                            } else if (action == 2) {
2484                                ClpPrimalColumnDantzig dantzig;
2485                                lpSolver->setPrimalColumnPivotAlgorithm(dantzig);
2486                            } else if (action == 3) {
2487                                ClpPrimalColumnSteepest steep(4);
2488                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2489                            } else if (action == 4) {
2490                                ClpPrimalColumnSteepest steep(1);
2491                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2492                            } else if (action == 5) {
2493                                ClpPrimalColumnSteepest steep(2);
2494                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2495                            } else if (action == 6) {
2496                                ClpPrimalColumnSteepest steep(10);
2497                                lpSolver->setPrimalColumnPivotAlgorithm(steep);
2498                            }
2499                            break;
[1373]2500                        case CLP_PARAM_STR_SCALING:
[1286]2501                            lpSolver->scaling(action);
2502                            solver->setHintParam(OsiDoScale, action != 0, OsiHintTry);
2503                            doScaling = action;
2504                            break;
[1373]2505                        case CLP_PARAM_STR_AUTOSCALE:
[1286]2506                            lpSolver->setAutomaticScaling(action != 0);
2507                            break;
[1373]2508                        case CLP_PARAM_STR_SPARSEFACTOR:
[1286]2509                            lpSolver->setSparseFactorization((1 - action) != 0);
2510                            break;
[1373]2511                        case CLP_PARAM_STR_BIASLU:
[1286]2512                            lpSolver->factorization()->setBiasLU(action);
2513                            break;
[1373]2514                        case CLP_PARAM_STR_PERTURBATION:
[1286]2515                            if (action == 0)
2516                                lpSolver->setPerturbation(50);
2517                            else
2518                                lpSolver->setPerturbation(100);
2519                            break;
[1373]2520                        case CLP_PARAM_STR_ERRORSALLOWED:
[1286]2521                            allowImportErrors = action;
2522                            break;
[1373]2523                        case CLP_PARAM_STR_INTPRINT:
[1286]2524                            printMode = action;
2525                            break;
[1373]2526                            //case CLP_PARAM_NOTUSED_ALGORITHM:
[1286]2527                            //algorithm  = action;
2528                            //defaultSettings=false; // user knows what she is doing
2529                            //abort();
2530                            //break;
[1373]2531                        case CLP_PARAM_STR_KEEPNAMES:
[1286]2532                            keepImportNames = 1 - action;
2533                            break;
[1373]2534                        case CLP_PARAM_STR_PRESOLVE:
[1286]2535                            if (action == 0)
2536                                preSolve = 5;
2537                            else if (action == 1)
2538                                preSolve = 0;
2539                            else if (action == 2)
2540                                preSolve = 10;
2541                            else
2542                                preSolveFile = true;
2543                            break;
[1373]2544                        case CLP_PARAM_STR_PFI:
[1286]2545                            lpSolver->factorization()->setForrestTomlin(action == 0);
2546                            break;
[1373]2547                        case CLP_PARAM_STR_FACTORIZATION:
[1286]2548                            lpSolver->factorization()->forceOtherFactorization(action);
2549                            break;
[1373]2550                        case CLP_PARAM_STR_CRASH:
[1286]2551                            doCrash = action;
2552                            break;
[1373]2553                        case CLP_PARAM_STR_VECTOR:
[1286]2554                            doVector = action;
2555                            break;
[1373]2556                        case CLP_PARAM_STR_MESSAGES:
[1286]2557                            lpSolver->messageHandler()->setPrefix(action != 0);
2558                            break;
[1373]2559                        case CLP_PARAM_STR_CHOLESKY:
[1286]2560                            choleskyType = action;
2561                            break;
[1373]2562                        case CLP_PARAM_STR_GAMMA:
[1286]2563                            gamma = action;
2564                            break;
[1373]2565                        case CLP_PARAM_STR_BARRIERSCALE:
[1286]2566                            scaleBarrier = action;
2567                            break;
[1373]2568                        case CLP_PARAM_STR_KKT:
[1286]2569                            doKKT = action;
2570                            break;
[1373]2571                        case CLP_PARAM_STR_CROSSOVER:
[1286]2572                            crossover = action;
2573                            break;
[1623]2574                        case CLP_PARAM_STR_TIME_MODE:
2575                            model_.setUseElapsedTime(action!=0);
2576                            break;
[1373]2577                        case CBC_PARAM_STR_SOS:
[1286]2578                            doSOS = action;
2579                            break;
[1373]2580                        case CBC_PARAM_STR_GOMORYCUTS:
[1286]2581                            defaultSettings = false; // user knows what she is doing
2582                            gomoryAction = action;
2583                            break;
[1373]2584                        case CBC_PARAM_STR_PROBINGCUTS:
[1286]2585                            defaultSettings = false; // user knows what she is doing
2586                            probingAction = action;
2587                            break;
[1373]2588                        case CBC_PARAM_STR_KNAPSACKCUTS:
[1286]2589                            defaultSettings = false; // user knows what she is doing
2590                            knapsackAction = action;
2591                            break;
[1373]2592                        case CBC_PARAM_STR_REDSPLITCUTS:
[1286]2593                            defaultSettings = false; // user knows what she is doing
2594                            redsplitAction = action;
2595                            break;
[1876]2596                        case CBC_PARAM_STR_REDSPLIT2CUTS:
2597                            defaultSettings = false; // user knows what she is doing
2598                            redsplit2Action = action;
2599                            break;
2600                        case CBC_PARAM_STR_GMICUTS:
2601                            defaultSettings = false; // user knows what she is doing
2602                            GMIAction = action;
2603                            break;
[1373]2604                        case CBC_PARAM_STR_CLIQUECUTS:
[1286]2605                            defaultSettings = false; // user knows what she is doing
2606                            cliqueAction = action;
2607                            break;
[1373]2608                        case CBC_PARAM_STR_FLOWCUTS:
[1286]2609                            defaultSettings = false; // user knows what she is doing
2610                            flowAction = action;
2611                            break;
[1373]2612                        case CBC_PARAM_STR_MIXEDCUTS:
[1286]2613                            defaultSettings = false; // user knows what she is doing
2614                            mixedAction = action;
2615                            break;
[1373]2616                        case CBC_PARAM_STR_TWOMIRCUTS:
[1286]2617                            defaultSettings = false; // user knows what she is doing
2618                            twomirAction = action;
2619                            break;
[1373]2620                        case CBC_PARAM_STR_LANDPCUTS:
[1286]2621                            defaultSettings = false; // user knows what she is doing
2622                            landpAction = action;
2623                            break;
[1373]2624                        case CBC_PARAM_STR_RESIDCUTS:
[1286]2625                            defaultSettings = false; // user knows what she is doing
2626                            residualCapacityAction = action;
2627                            break;
[1373]2628                        case CBC_PARAM_STR_ZEROHALFCUTS:
[1286]2629                            defaultSettings = false; // user knows what she is doing
2630                            zerohalfAction = action;
2631                            break;
[1373]2632                        case CBC_PARAM_STR_ROUNDING:
[1286]2633                            defaultSettings = false; // user knows what she is doing
2634                            break;
[1373]2635                        case CBC_PARAM_STR_FPUMP:
[1286]2636                            defaultSettings = false; // user knows what she is doing
2637                            break;
[1373]2638                        case CBC_PARAM_STR_RINS:
[1286]2639                            break;
[1373]2640                        case CBC_PARAM_STR_DINS:
[1286]2641                            break;
[1373]2642                        case CBC_PARAM_STR_RENS:
[1286]2643                            break;
[1373]2644                        case CBC_PARAM_STR_CUTSSTRATEGY:
[1286]2645                            gomoryAction = action;
2646                            probingAction = action;
2647                            knapsackAction = action;
2648                            cliqueAction = action;
2649                            flowAction = action;
2650                            mixedAction = action;
2651                            twomirAction = action;
2652                            //landpAction = action;
[1373]2653                            parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2654                            parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2655                            parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2656                            parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption(action);
2657                            parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2658                            parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
2659                            parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2660                            if (!action) {
[2043]2661                                zerohalfAction = action;
2662                                parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2663                                redsplitAction = action;
[1373]2664                                parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1876]2665                                redsplit2Action = action;
2666                                parameters_[whichParam(CBC_PARAM_STR_REDSPLIT2CUTS, numberParameters_, parameters_)].setCurrentOption(action);
2667                                GMIAction = action;
2668                                parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2669                                landpAction = action;
[1373]2670                                parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2671                                residualCapacityAction = action;
[1373]2672                                parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2673                            }
2674                            break;
[1373]2675                        case CBC_PARAM_STR_HEURISTICSTRATEGY:
2676                            parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption(action);
2677                            parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption(action);
2678                            parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption(action);
2679                            //parameters_[whichParam(CBC_PARAM_STR_LOCALTREE,numberParameters_,parameters_)].setCurrentOption(action);
2680                            parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption(action);
2681                            parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].setCurrentOption(action);
2682                            parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption(action);
[1286]2683                            break;
[1373]2684                        case CBC_PARAM_STR_GREEDY:
2685                        case CBC_PARAM_STR_DIVINGS:
2686                        case CBC_PARAM_STR_DIVINGC:
2687                        case CBC_PARAM_STR_DIVINGF:
2688                        case CBC_PARAM_STR_DIVINGG:
2689                        case CBC_PARAM_STR_DIVINGL:
2690                        case CBC_PARAM_STR_DIVINGP:
2691                        case CBC_PARAM_STR_DIVINGV:
2692                        case CBC_PARAM_STR_COMBINE:
2693                        case CBC_PARAM_STR_PIVOTANDCOMPLEMENT:
2694                        case CBC_PARAM_STR_PIVOTANDFIX:
2695                        case CBC_PARAM_STR_RANDROUND:
2696                        case CBC_PARAM_STR_LOCALTREE:
2697                        case CBC_PARAM_STR_NAIVE:
2698                        case CBC_PARAM_STR_CPX:
[1286]2699                            defaultSettings = false; // user knows what she is doing
2700                            break;
[1373]2701                        case CBC_PARAM_STR_COSTSTRATEGY:
[1286]2702                            useCosts = action;
2703                            break;
[1373]2704                        case CBC_PARAM_STR_NODESTRATEGY:
[1286]2705                            nodeStrategy = action;
2706                            break;
[1373]2707                        case CBC_PARAM_STR_PREPROCESS:
[1286]2708                            preProcess = action;
2709                            break;
2710                        default:
2711                            //abort();
2712                            break;
2713                        }
2714                    }
2715                } else {
2716                    // action
[1373]2717                    if (type == CLP_PARAM_ACTION_EXIT) {
[640]2718#ifdef COIN_HAS_ASL
[1286]2719                        if (statusUserFunction_[0]) {
2720                            if (info.numberIntegers || info.numberBinary) {
2721                                // integer
2722                            } else {
2723                                // linear
2724                            }
2725                            writeAmpl(&info);
2726                            freeArrays2(&info);
2727                            freeArgs(&info);
2728                        }
[640]2729#endif
[1286]2730                        break; // stop all
2731                    }
2732                    switch (type) {
[1373]2733                    case CLP_PARAM_ACTION_DUALSIMPLEX:
2734                    case CLP_PARAM_ACTION_PRIMALSIMPLEX:
2735                    case CLP_PARAM_ACTION_SOLVECONTINUOUS:
2736                    case CLP_PARAM_ACTION_BARRIER:
[1286]2737                        if (goodModel) {
2738                            // Say not in integer
2739                            integerStatus = -1;
2740                            double objScale =
[1373]2741                                parameters_[whichParam(CLP_PARAM_DBL_OBJSCALE2, numberParameters_, parameters_)].doubleValue();
[1286]2742                            if (objScale != 1.0) {
2743                                int iColumn;
2744                                int numberColumns = lpSolver->numberColumns();
2745                                double * dualColumnSolution =
2746                                    lpSolver->dualColumnSolution();
2747                                ClpObjective * obj = lpSolver->objectiveAsObject();
2748                                assert(dynamic_cast<ClpLinearObjective *> (obj));
2749                                double offset;
2750                                double * objective = obj->gradient(NULL, NULL, offset, true);
2751                                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2752                                    dualColumnSolution[iColumn] *= objScale;
2753                                    objective[iColumn] *= objScale;;
2754                                }
2755                                int iRow;
2756                                int numberRows = lpSolver->numberRows();
2757                                double * dualRowSolution =
2758                                    lpSolver->dualRowSolution();
2759                                for (iRow = 0; iRow < numberRows; iRow++)
2760                                    dualRowSolution[iRow] *= objScale;
2761                                lpSolver->setObjectiveOffset(objScale*lpSolver->objectiveOffset());
2762                            }
2763                            ClpSolve::SolveType method;
2764                            ClpSolve::PresolveType presolveType;
2765                            ClpSimplex * model2 = lpSolver;
2766                            if (dualize) {
2767                                bool tryIt = true;
2768                                double fractionColumn = 1.0;
2769                                double fractionRow = 1.0;
2770                                if (dualize == 3) {
2771                                    dualize = 1;
2772                                    int numberColumns = lpSolver->numberColumns();
2773                                    int numberRows = lpSolver->numberRows();
2774                                    if (numberRows < 50000 || 5*numberColumns > numberRows) {
2775                                        tryIt = false;
2776                                    } else {
2777                                        fractionColumn = 0.1;
2778                                        fractionRow = 0.1;
2779                                    }
2780                                }
2781                                if (tryIt) {
2782                                    model2 = static_cast<ClpSimplexOther *> (model2)->dualOfModel(fractionRow, fractionColumn);
2783                                    if (model2) {
2784                                        sprintf(generalPrint, "Dual of model has %d rows and %d columns",
2785                                                model2->numberRows(), model2->numberColumns());
2786                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2787                                        << generalPrint
2788                                        << CoinMessageEol;
2789                                        model2->setOptimizationDirection(1.0);
2790                                    } else {
2791                                        model2 = lpSolver;
2792                                        dualize = 0;
2793                                    }
2794                                } else {
2795                                    dualize = 0;
2796                                }
2797                            }
2798                            if (noPrinting_)
2799                                lpSolver->setLogLevel(0);
2800                            ClpSolve solveOptions;
2801                            solveOptions.setPresolveActions(presolveOptions);
2802                            solveOptions.setSubstitution(substitution);
2803                            if (preSolve != 5 && preSolve) {
2804                                presolveType = ClpSolve::presolveNumber;
2805                                if (preSolve < 0) {
2806                                    preSolve = - preSolve;
2807                                    if (preSolve <= 100) {
2808                                        presolveType = ClpSolve::presolveNumber;
2809                                        sprintf(generalPrint, "Doing %d presolve passes - picking up non-costed slacks",
2810                                                preSolve);
2811                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2812                                        << generalPrint
2813                                        << CoinMessageEol;
2814                                        solveOptions.setDoSingletonColumn(true);
2815                                    } else {
2816                                        preSolve -= 100;
2817                                        presolveType = ClpSolve::presolveNumberCost;
2818                                        sprintf(generalPrint, "Doing %d presolve passes - picking up costed slacks",
2819                                                preSolve);
2820                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
2821                                        << generalPrint
2822                                        << CoinMessageEol;
2823                                    }
2824                                }
2825                            } else if (preSolve) {
2826                                presolveType = ClpSolve::presolveOn;
2827                            } else {
2828                                presolveType = ClpSolve::presolveOff;
2829                            }
2830                            solveOptions.setPresolveType(presolveType, preSolve);
[1412]2831                            if (type == CLP_PARAM_ACTION_DUALSIMPLEX ||
2832                                    type == CLP_PARAM_ACTION_SOLVECONTINUOUS) {
[1286]2833                                method = ClpSolve::useDual;
[1373]2834                            } else if (type == CLP_PARAM_ACTION_PRIMALSIMPLEX) {
[1286]2835                                method = ClpSolve::usePrimalorSprint;
2836                            } else {
2837                                method = ClpSolve::useBarrier;
2838                                if (crossover == 1) {
2839                                    method = ClpSolve::useBarrierNoCross;
2840                                } else if (crossover == 2) {
2841                                    ClpObjective * obj = lpSolver->objectiveAsObject();
2842                                    if (obj->type() > 1) {
2843                                        method = ClpSolve::useBarrierNoCross;
2844                                        presolveType = ClpSolve::presolveOff;
2845                                        solveOptions.setPresolveType(presolveType, preSolve);
2846                                    }
2847                                }
2848                            }
2849                            solveOptions.setSolveType(method);
2850                            if (preSolveFile)
2851                                presolveOptions |= 0x40000000;
2852                            solveOptions.setSpecialOption(4, presolveOptions);
2853                            solveOptions.setSpecialOption(5, printOptions);
2854                            if (doVector) {
2855                                ClpMatrixBase * matrix = lpSolver->clpMatrix();
2856                                if (dynamic_cast< ClpPackedMatrix*>(matrix)) {
2857                                    ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
2858                                    clpMatrix->makeSpecialColumnCopy();
2859                                }
2860                            }
2861                            if (method == ClpSolve::useDual) {
2862                                // dual
2863                                if (doCrash)
2864                                    solveOptions.setSpecialOption(0, 1, doCrash); // crash
2865                                else if (doIdiot)
2866                                    solveOptions.setSpecialOption(0, 2, doIdiot); // possible idiot
2867                            } else if (method == ClpSolve::usePrimalorSprint) {
2868                                // primal
2869                                // if slp turn everything off
2870                                if (slpValue > 0) {
2871                                    doCrash = false;
2872                                    doSprint = 0;
2873                                    doIdiot = -1;
2874                                    solveOptions.setSpecialOption(1, 10, slpValue); // slp
2875                                    method = ClpSolve::usePrimal;
2876                                }
2877                                if (doCrash) {
2878                                    solveOptions.setSpecialOption(1, 1, doCrash); // crash
2879                                } else if (doSprint > 0) {
2880                                    // sprint overrides idiot
2881                                    solveOptions.setSpecialOption(1, 3, doSprint); // sprint
2882                                } else if (doIdiot > 0) {
2883                                    solveOptions.setSpecialOption(1, 2, doIdiot); // idiot
2884                                } else if (slpValue <= 0) {
2885                                    if (doIdiot == 0) {
2886                                        if (doSprint == 0)
2887                                            solveOptions.setSpecialOption(1, 4); // all slack
2888                                        else
2889                                            solveOptions.setSpecialOption(1, 9); // all slack or sprint
2890                                    } else {
2891                                        if (doSprint == 0)
2892                                            solveOptions.setSpecialOption(1, 8); // all slack or idiot
2893                                        else
2894                                            solveOptions.setSpecialOption(1, 7); // initiative
2895                                    }
2896                                }
2897                                if (basisHasValues == -1)
2898                                    solveOptions.setSpecialOption(1, 11); // switch off values
2899                            } else if (method == ClpSolve::useBarrier || method == ClpSolve::useBarrierNoCross) {
2900                                int barrierOptions = choleskyType;
2901                                if (scaleBarrier)
2902                                    barrierOptions |= 8;
2903                                if (doKKT)
2904                                    barrierOptions |= 16;
2905                                if (gamma)
2906                                    barrierOptions |= 32 * gamma;
2907                                if (crossover == 3)
2908                                    barrierOptions |= 256; // try presolve in crossover
2909                                solveOptions.setSpecialOption(4, barrierOptions);
2910                            }
2911                            model2->setMaximumSeconds(model_.getMaximumSeconds());
[640]2912#ifdef COIN_HAS_LINK
[1286]2913                            OsiSolverInterface * coinSolver = model_.solver();
2914                            OsiSolverLink * linkSolver = dynamic_cast< OsiSolverLink*> (coinSolver);
2915                            if (!linkSolver) {
2916                                model2->initialSolve(solveOptions);
2917                            } else {
2918                                // special solver
[1373]2919                                int testOsiOptions = parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].intValue();
[1286]2920                                double * solution = NULL;
2921                                if (testOsiOptions < 10) {
2922                                    solution = linkSolver->nonlinearSLP(slpValue > 0 ? slpValue : 20 , 1.0e-5);
2923                                } else if (testOsiOptions >= 10) {
2924                                    CoinModel coinModel = *linkSolver->coinModel();
2925                                    ClpSimplex * tempModel = approximateSolution(coinModel, slpValue > 0 ? slpValue : 50 , 1.0e-5, 0);
2926                                    assert (tempModel);
2927                                    solution = CoinCopyOfArray(tempModel->primalColumnSolution(), coinModel.numberColumns());
2928                                    model2->setObjectiveValue(tempModel->objectiveValue());
2929                                    model2->setProblemStatus(tempModel->problemStatus());
2930                                    model2->setSecondaryStatus(tempModel->secondaryStatus());
2931                                    delete tempModel;
2932                                }
2933                                if (solution) {
2934                                    memcpy(model2->primalColumnSolution(), solution,
2935                                           CoinMin(model2->numberColumns(), linkSolver->coinModel()->numberColumns())*sizeof(double));
2936                                    delete [] solution;
2937                                } else {
2938                                    printf("No nonlinear solution\n");
2939                                }
2940                            }
[640]2941#else
[1286]2942                            model2->initialSolve(solveOptions);
[640]2943#endif
[1286]2944                            {
2945                                // map states
2946                                /* clp status
2947                                   -1 - unknown e.g. before solve or if postSolve says not optimal
2948                                   0 - optimal
2949                                   1 - primal infeasible
2950                                   2 - dual infeasible
2951                                   3 - stopped on iterations or time
2952                                   4 - stopped due to errors
2953                                   5 - stopped by event handler (virtual int ClpEventHandler::event()) */
2954                                /* cbc status
2955                                   -1 before branchAndBound
2956                                   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
2957                                   (or check value of best solution)
2958                                   1 stopped - on maxnodes, maxsols, maxtime
2959                                   2 difficulties so run was abandoned
2960                                   (5 event user programmed event occurred) */
2961                                /* clp secondary status of problem - may get extended
2962                                   0 - none
2963                                   1 - primal infeasible because dual limit reached OR probably primal
2964                                   infeasible but can't prove it (main status 4)
2965                                   2 - scaled problem optimal - unscaled problem has primal infeasibilities
2966                                   3 - scaled problem optimal - unscaled problem has dual infeasibilities
2967                                   4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
2968                                   5 - giving up in primal with flagged variables
2969                                   6 - failed due to empty problem check
2970                                   7 - postSolve says not optimal
2971                                   8 - failed due to bad element check
2972                                   9 - status was 3 and stopped on time
2973                                   100 up - translation of enum from ClpEventHandler
2974                                */
2975                                /* cbc secondary status of problem
2976                                   -1 unset (status_ will also be -1)
2977                                   0 search completed with solution
2978                                   1 linear relaxation not feasible (or worse than cutoff)
2979                                   2 stopped on gap
2980                                   3 stopped on nodes
2981                                   4 stopped on time
2982                                   5 stopped on user event
2983                                   6 stopped on solutions
2984                                   7 linear relaxation unbounded
[1791]2985                                   8 stopped on iterations limit
[1286]2986                                */
2987                                int iStatus = model2->status();
2988                                int iStatus2 = model2->secondaryStatus();
2989                                if (iStatus == 0) {
2990                                    iStatus2 = 0;
[1373]2991                                    if (found.type() == CBC_PARAM_ACTION_BAB) {
[1286]2992                                        // set best solution in model as no integers
2993                                        model_.setBestSolution(model2->primalColumnSolution(),
2994                                                               model2->numberColumns(),
2995                                                               model2->getObjValue()*
2996                                                               model2->getObjSense());
2997                                    }
2998                                } else if (iStatus == 1) {
2999                                    iStatus = 0;
3000                                    iStatus2 = 1; // say infeasible
3001                                } else if (iStatus == 2) {
3002                                    iStatus = 0;
3003                                    iStatus2 = 7; // say unbounded
3004                                } else if (iStatus == 3) {
3005                                    iStatus = 1;
[1791]3006                                    if (iStatus2 == 9)  // what does 9 mean ?????????????
[1286]3007                                        iStatus2 = 4;
3008                                    else
3009                                        iStatus2 = 3; // Use nodes - as closer than solutions
3010                                } else if (iStatus == 4) {
3011                                    iStatus = 2; // difficulties
3012                                    iStatus2 = 0;
3013                                }
3014                                model_.setProblemStatus(iStatus);
3015                                model_.setSecondaryStatus(iStatus2);
[1539]3016                                if ((iStatus == 2 || iStatus2 > 0) &&
3017                                    !noPrinting_) {
3018                                   std::string statusName[] = {"", "Stopped on ", "Run abandoned", "", "", "User ctrl-c"};
[1791]3019                                   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"};
[1539]3020                                   sprintf(generalPrint, "\nResult - %s%s\n\n", 
3021                                           statusName[iStatus].c_str(), 
3022                                           minor[iStatus2].c_str());
3023                                   sprintf(generalPrint + strlen(generalPrint),
[1621]3024                                           "Enumerated nodes:           0\n");
[1539]3025                                   sprintf(generalPrint + strlen(generalPrint), 
[1621]3026                                           "Total iterations:           0\n");
[1735]3027#if CBC_QUIET == 0
[1539]3028                                   sprintf(generalPrint + strlen(generalPrint),
[1621]3029                                           "Time (CPU seconds):         %.2f\n", 
[1539]3030                                           CoinCpuTime() - time0);
[1621]3031                                   sprintf(generalPrint + strlen(generalPrint),
3032                                           "Time (Wallclock Seconds):   %.2f\n", 
[1623]3033                                           CoinGetTimeOfDay()-time0Elapsed);
[1591]3034#endif
[1539]3035                                   generalMessageHandler->message(CLP_GENERAL, generalMessages)
3036                                      << generalPrint
3037                                      << CoinMessageEol;
3038                                }
3039                                //assert (lpSolver==clpSolver->getModelPtr());
[1286]3040                                assert (clpSolver == model_.solver());
3041                                clpSolver->setWarmStart(NULL);
3042                                // and in babModel if exists
3043                                if (babModel_) {
3044                                    babModel_->setProblemStatus(iStatus);
3045                                    babModel_->setSecondaryStatus(iStatus2);
3046                                }
3047                                int returnCode = callBack(&model, 1);
3048                                if (returnCode) {
3049                                    // exit if user wants
3050                                    delete babModel_;
3051                                    babModel_ = NULL;
3052                                    return returnCode;
3053                                }
3054                            }
3055                            basisHasValues = 1;
3056                            if (dualize) {
3057                                int returnCode = static_cast<ClpSimplexOther *> (lpSolver)->restoreFromDual(model2);
3058                                if (model2->status() == 3)
3059                                    returnCode = 0;
3060                                delete model2;
3061                                if (returnCode && dualize != 2)
3062                                    lpSolver->primal(1);
3063                                model2 = lpSolver;
3064                            }
[640]3065#ifdef COIN_HAS_ASL
[1286]3066                            if (statusUserFunction_[0]) {
[2086]3067                                double value = model2->getObjValue();
[1286]3068                                char buf[300];
3069                                int pos = 0;
3070                                int iStat = model2->status();
3071                                if (iStat == 0) {
3072                                    pos += sprintf(buf + pos, "optimal," );
3073                                } else if (iStat == 1) {
3074                                    // infeasible
3075                                    pos += sprintf(buf + pos, "infeasible,");
3076                                } else if (iStat == 2) {
3077                                    // unbounded
3078                                    pos += sprintf(buf + pos, "unbounded,");
3079                                } else if (iStat == 3) {
3080                                    pos += sprintf(buf + pos, "stopped on iterations or time,");
3081                                } else if (iStat == 4) {
3082                                    iStat = 7;
3083                                    pos += sprintf(buf + pos, "stopped on difficulties,");
3084                                } else if (iStat == 5) {
3085                                    iStat = 3;
3086                                    pos += sprintf(buf + pos, "stopped on ctrl-c,");
3087                                } else if (iStat == 6) {
3088                                    // bab infeasible
3089                                    pos += sprintf(buf + pos, "integer infeasible,");
3090                                    iStat = 1;
3091                                } else {
3092                                    pos += sprintf(buf + pos, "status unknown,");
3093                                    iStat = 6;
3094                                }
3095                                info.problemStatus = iStat;
3096                                info.objValue = value;
3097                                pos += sprintf(buf + pos, " objective %.*g", ampl_obj_prec(),
3098                                               value);
3099                                sprintf(buf + pos, "\n%d iterations",
3100                                        model2->getIterationCount());
3101                                free(info.primalSolution);
3102                                int numberColumns = model2->numberColumns();
3103                                info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double)));
3104                                CoinCopyN(model2->primalColumnSolution(), numberColumns, info.primalSolution);
3105                                int numberRows = model2->numberRows();
3106                                free(info.dualSolution);
3107                                info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double)));
3108                                CoinCopyN(model2->dualRowSolution(), numberRows, info.dualSolution);
3109                                CoinWarmStartBasis * basis = model2->getBasis();
3110                                free(info.rowStatus);
3111                                info.rowStatus = reinterpret_cast<int *> (malloc(numberRows * sizeof(int)));
3112                                free(info.columnStatus);
3113                                info.columnStatus = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int)));
3114                                // Put basis in
3115                                int i;
3116                                // free,basic,ub,lb are 0,1,2,3
3117                                for (i = 0; i < numberRows; i++) {
3118                                    CoinWarmStartBasis::Status status = basis->getArtifStatus(i);
3119                                    info.rowStatus[i] = status;
3120                                }
3121                                for (i = 0; i < numberColumns; i++) {
3122                                    CoinWarmStartBasis::Status status = basis->getStructStatus(i);
3123                                    info.columnStatus[i] = status;
3124                                }
3125                                // put buffer into info
3126                                strcpy(info.buffer, buf);
3127                                delete basis;
3128                            }
[640]3129#endif
[1286]3130                        } else {
[2069]3131                          sprintf(generalPrint, "** Current model not valid");
3132                          printGeneralMessage(model_,generalPrint);
[1286]3133                        }
3134                        break;
[1373]3135                    case CLP_PARAM_ACTION_STATISTICS:
[1286]3136                        if (goodModel) {
3137                            // If presolve on look at presolved
3138                            bool deleteModel2 = false;
3139                            ClpSimplex * model2 = lpSolver;
3140                            if (preSolve) {
3141                                ClpPresolve pinfo;
3142                                int presolveOptions2 = presolveOptions&~0x40000000;
3143                                if ((presolveOptions2&0xffff) != 0)
3144                                    pinfo.setPresolveActions(presolveOptions2);
3145                                pinfo.setSubstitution(substitution);
3146                                if ((printOptions&1) != 0)
3147                                    pinfo.statistics();
3148                                double presolveTolerance =
[1373]3149                                    parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].doubleValue();
[1286]3150                                model2 =
3151                                    pinfo.presolvedModel(*lpSolver, presolveTolerance,
3152                                                         true, preSolve);
3153                                if (model2) {
3154                                    printf("Statistics for presolved model\n");
3155                                    deleteModel2 = true;
3156                                } else {
3157                                    printf("Presolved model looks infeasible - will use unpresolved\n");
3158                                    model2 = lpSolver;
3159                                }
3160                            } else {
3161                                printf("Statistics for unpresolved model\n");
3162                                model2 =  lpSolver;
3163                            }
3164                            statistics(lpSolver, model2);
3165                            if (deleteModel2)
3166                                delete model2;
3167                        } else {
[2069]3168                          sprintf(generalPrint, "** Current model not valid");
3169                          printGeneralMessage(model_,generalPrint);
[1286]3170                        }
3171                        break;
[1373]3172                    case CLP_PARAM_ACTION_TIGHTEN:
[1286]3173                        if (goodModel) {
3174                            int numberInfeasibilities = lpSolver->tightenPrimalBounds();
[2069]3175                            if (numberInfeasibilities) {
3176                              sprintf(generalPrint,"** Analysis indicates model infeasible");
3177                              printGeneralMessage(model_,generalPrint);
3178                            }
[1286]3179                        } else {
[2069]3180                          sprintf(generalPrint, "** Current model not valid");
3181                          printGeneralMessage(model_,generalPrint);
[1286]3182                        }
3183                        break;
[1373]3184                    case CLP_PARAM_ACTION_PLUSMINUS:
[1286]3185                        if (goodModel) {
3186                            ClpMatrixBase * saveMatrix = lpSolver->clpMatrix();
3187                            ClpPackedMatrix* clpMatrix =
3188                                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
3189                            if (clpMatrix) {
3190                                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
3191                                if (newMatrix->getIndices()) {
3192                                    lpSolver->replaceMatrix(newMatrix);
3193                                    delete saveMatrix;
[2069]3194                                    sprintf(generalPrint, "Matrix converted to +- one matrix");
3195                                    printGeneralMessage(model_,generalPrint);
[1286]3196                                } else {
[2069]3197                                  sprintf(generalPrint, "Matrix can not be converted to +- 1 matrix");
3198                                  printGeneralMessage(model_,generalPrint);
[1286]3199                                }
3200                            } else {
[2069]3201                              sprintf(generalPrint, "Matrix not a ClpPackedMatrix");
3202                              printGeneralMessage(model_,generalPrint);
[1286]3203                            }
3204                        } else {
[2069]3205                          sprintf(generalPrint, "** Current model not valid");
3206                          printGeneralMessage(model_,generalPrint);
[1286]3207                        }
3208                        break;
[1373]3209                    case CLP_PARAM_ACTION_OUTDUPROWS:
[1286]3210                        dominatedCuts = true;
[1393]3211#ifdef JJF_ZERO
[1286]3212                        if (goodModel) {
3213                            int numberRows = clpSolver->getNumRows();
3214                            //int nOut = outDupRow(clpSolver);
3215                            CglDuplicateRow dupcuts(clpSolver);
3216                            storedCuts = dupcuts.outDuplicates(clpSolver) != 0;
3217                            int nOut = numberRows - clpSolver->getNumRows();
3218                            if (nOut && !noPrinting_)
3219                                sprintf(generalPrint, "%d rows eliminated", nOut);
3220                            generalMessageHandler->message(CLP_GENERAL, generalMessages)
3221