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

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

more string parameters and some sos priorities

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