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

Last change on this file since 2495 was 2495, checked in by unxusr, 4 months ago

time limit in C interface

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