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

Last change on this file since 2526 was 2526, checked in by forrest, 8 months ago

safer mipstart

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