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

Last change on this file since 2402 was 2402, checked in by unxusr, 2 years ago

include needed on some gcc versions

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