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

Last change on this file since 2387 was 2387, checked in by forrest, 11 months ago

improve mipstart for SOS

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