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

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

try and improve nauty

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