source: branches/sandbox/Cbc/src/CbcSolver.cpp @ 1383

Last change on this file since 1383 was 1383, checked in by bjarni, 10 years ago

Extracted crunchIt, fixVubs, doHeuristics from CbcSolver?.cpp and placed it in CbcSolverHeuristics?.cpp

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