source: branches/conflictgraphs/src/CbcSolver.cpp @ 2902

Last change on this file since 2902 was 2902, checked in by samuelbrito, 23 months ago

Final merge of trunk changes to conflictgraphs.

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