source: trunk/Cbc/src/CbcSolver.cpp

Last change on this file was 2657, checked in by stefan, 2 weeks ago

remove CbcOrClpRead_mode,Command and access those in CbcOrClpParam? instead

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