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

Last change on this file since 2397 was 2397, checked in by unxusr, 10 months ago

option to store names in preprocessed problem

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