Scippy

SCIP

Solving Constraint Integer Programs

lpi_spx2.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lpi_spx2.cpp
17  * @ingroup LPIS
18  * @brief LP interface for SoPlex version 2.0 and higher
19  * @author Matthias Miltenberger
20  * @author Ambros Gleixner
21  *
22  * This is an implementation of SCIP's LP interface for SoPlex using the extended and improved interface of SoPlex 2.0
23  *
24  * For debugging purposes, the SoPlex results can be double checked with CPLEX if SCIP_WITH_LPSCHECK is defined. This may
25  * yield false positives, since the LP is dumped to a file for transfering it to CPLEX, hence, precision may be lost.
26  */
27 
28 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
29 
30 #define STRONGBRANCH_RESTOREBASIS /**< if defined then in SCIPlpiStrongbranch() we restore the basis after the
31  * down branch and after the up branch; if false only after the end of a
32  * strong branching phase, which however seems to mostly increase strong
33  * branching time and iterations */
34 
35 /*
36  * include build configuration flags
37  */
38 #ifndef NO_CONFIG_HEADER
39 #include "scip/config.h"
40 #endif
41 
42 /* in this case the SoPlex results are double checked using CPLEX */
43 #ifdef SCIP_WITH_LPSCHECK
44 #include <cplex.h>
45 
46 #define CHECK_SPXSOLVE true /**< shall the SoPlex results in spxSolve() be double checked using CPLEX? */
47 #define CHECK_SPXSTRONGBRANCH true /**< shall the SoPlex results in SCIPlpStrongbranch() be double checked using CPLEX? */
48 #define CHECK_START 0 /**< skip first CHECK_START number of checks */
49 #define EXIT_AT_WRONG_RESULT false/**< shall program be exited if CPLEX returns different result than SoPlex? */
50 #define EXIT_AT_CPXERROR false/**< shall program be exited if CPLEX returns an error? */
51 
52 #define CPX_CALL(x) do \
53  { \
54  int _cpxstat_; \
55  if( (_cpxstat_ = (x)) != 0 ) \
56  { \
57  SCIPmessagePrintWarning(_messagehdlr, "CPLEX error <%d>; SoPlex result unchecked\n", _cpxstat_); \
58  if( EXIT_AT_CPXERROR ) \
59  { \
60  exit(1); \
61  } \
62  else \
63  { \
64  goto ENDCHECK; \
65  } \
66  } \
67  } \
68  while( false )
69 #endif
70 
71 /* check the return value of setParam methods */
72 #define CHECK_SOPLEX_PARAM(x) \
73  if( !x ) \
74  { \
75  SCIPmessagePrintWarning(_messagehdlr, "SoPlex: unsupported parameter value\n"); \
76  }
77 
78 /* remember the original value of the SCIP_DEBUG define and undefine it */
79 #ifdef SCIP_DEBUG
80 #define ___DEBUG
81 #undef SCIP_DEBUG
82 #endif
83 
84 /* compile the SoPlex header with visibility=default because the SoPlex lib has been compiled that way */
85 #pragma GCC visibility push(default)
86 
87 /* include SoPlex solver */
88 #include "soplex.h"
89 
90 /* define subversion for versions <= 1.5.0.1 */
91 #ifndef SOPLEX_SUBVERSION
92 #define SOPLEX_SUBVERSION 0
93 #endif
94 /* define API version for versions <= 3.0.0 */
95 #ifndef SOPLEX_APIVERSION
96 #define SOPLEX_APIVERSION 0
97 #endif
98 
99 /* check version */
100 #if (SOPLEX_VERSION < 200 || (SOPLEX_VERSION == 200 && SOPLEX_SUBVERSION < 2) || (SOPLEX_VERSION > 200 && SOPLEX_VERSION < 201))
101 #error "This interface is not compatible with SoPlex versions prior to 2.0.0.2"
102 #endif
103 
104 #if (SOPLEX_APIVERSION <= 5)
105 #include "spxgithash.h"
106 #endif
107 
108 /* reset the SCIP_DEBUG define to its original SCIP value */
109 #undef SCIP_DEBUG
110 #ifdef ___DEBUG
111 #define SCIP_DEBUG
112 #undef ___DEBUG
113 #endif
114 
115 /* define snprintf when using a too old MSVC version */
116 #if defined(_MSC_VER) && _MSC_VER < 1900
117 #ifndef snprintf
118 #define snprintf _snprintf
119 #endif
120 #endif
121 
122 #define SOPLEX_VERBLEVEL 5 /**< verbosity level for LPINFO */
123 
124 #include "scip/pub_message.h"
126 /********************************************************************/
127 /*----------------------------- C++ --------------------------------*/
128 /********************************************************************/
129 
130 /* in C++ we have to use "0" instead of "(void*)0" */
131 #undef NULL
132 #define NULL 0
133 
134 #include <cassert>
135 using namespace soplex;
136 
137 
138 /** Macro for a single SoPlex call for which exceptions have to be catched - return an LP error. We
139  * make no distinction between different exception types, e.g., between memory allocation and other
140  * exceptions.
141  */
142 #ifndef NDEBUG
143 #define SOPLEX_TRY(messagehdlr, x) do \
144  { \
145  try \
146  { \
147  (x); \
148  } \
149  catch( const SPxMemoryException& E ) \
150  { \
151  std::string s = E.what(); \
152  SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
153  return SCIP_ERROR; \
154  } \
155  catch( const SPxException& E ) \
156  { \
157  std::string s = E.what(); \
158  SCIPmessagePrintWarning((messagehdlr), "SoPlex threw an exception: %s\n", s.c_str()); \
159  return SCIP_LPERROR; \
160  } \
161  } \
162  while( FALSE )
163 
164 #else
165 #define SOPLEX_TRY(messagehdlr, x) do \
166  { \
167  try \
168  { \
169  (x); \
170  } \
171  catch( const SPxMemoryException& E ) \
172  { \
173  std::string s = E.what(); \
174  SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
175  return SCIP_ERROR; \
176  } \
177  catch( const SPxException& ) \
178  { \
179  return SCIP_LPERROR; \
180  } \
181  } \
182  while( FALSE )
183 #endif
184 
185 /* Macro for a single SoPlex call for which exceptions have to be catched - abort if they
186  * arise. SCIP_ABORT() is not accessible here.
187  */
188 #define SOPLEX_TRY_ABORT(x) do \
189  { \
190  try \
191  { \
192  (x); \
193  } \
194  catch( const SPxException& E ) \
195  { \
196  std::string s = E.what(); \
197  SCIPerrorMessage("SoPlex threw an exception: %s\n", s.c_str()); \
198  abort(); \
199  } \
200  } \
201  while( FALSE )
202 
203 
204 
205 /** SCIP's SoPlex class */
206 class SPxSCIP : public SoPlex
207 {/*lint !e1790*/
208  bool _lpinfo;
209  bool _fromscratch;
210  bool _interrupt;
211  char* _probname;
212  DataArray<SPxSolver::VarStatus> _colStat; /**< column basis status used for strong branching */
213  DataArray<SPxSolver::VarStatus> _rowStat; /**< row basis status used for strong branching */
214 #ifdef SCIP_WITH_LPSCHECK
215  int _checknum;
216  bool _doublecheck;
217  CPXENVptr _cpxenv; /**< CPLEX memory environment */
218  CPXLPptr _cpxlp; /**< CPLEX lp structure */
219 #endif
220  SCIP_MESSAGEHDLR* _messagehdlr; /**< messagehdlr handler for printing messages, or NULL */
221 
222 public:
223  SPxSCIP(
224  SCIP_MESSAGEHDLR* messagehdlr = NULL, /**< message handler */
225  const char* probname = NULL /**< name of problem */
226  )
227  : _lpinfo(false),
228  _fromscratch(false),
229  _probname(NULL),
230  _colStat(0),
231  _rowStat(0),
232  _messagehdlr(messagehdlr)
233  {
234  if ( probname != NULL )
235  SOPLEX_TRY_ABORT( setProbname(probname) );
236 
237 #if SOPLEX_APIVERSION >= 2
238  (void)setBoolParam(SoPlex::ENSURERAY, true);
239 #endif
240 
241 #ifdef SCIP_WITH_LPSCHECK
242  int cpxstat;
243  _checknum = 0;
244  _doublecheck = false;
245  _cpxenv = CPXopenCPLEX(&cpxstat);
246  assert(_cpxenv != NULL);
247  _cpxlp = CPXcreateprob(_cpxenv, &cpxstat, probname != NULL ? probname : "spxcheck");
248  (void) CPXsetintparam(_cpxenv, CPX_PARAM_SCRIND, 0);
249 #endif
250  }
251 
252  virtual ~SPxSCIP()
253  {
254  if( _probname != NULL )
255  spx_free(_probname); /*lint !e1551*/
256 
257  freePreStrongbranchingBasis(); /*lint !e1551*/
258 
259 #ifdef SCIP_WITH_LPSCHECK
260  (void) CPXfreeprob(_cpxenv, &_cpxlp);
261  (void) CPXcloseCPLEX(&_cpxenv);
262 #endif
263  }/*lint -e1579*/
264 
265  // we might need these methods to return the original values SCIP provided, even if they could not be set
266  /** return feastol set by SCIPlpiSetRealpar(), which might be tighter than what SoPlex accepted */
267  Real feastol() const
268  {
269  return realParam(FEASTOL);
270  }
271 
272  /** set feastol and store value in case SoPlex only accepts a larger tolerance */
273  void setFeastol(
274  const Real d
275  )
276  {
277  CHECK_SOPLEX_PARAM(setRealParam(FEASTOL, d));
278  }
279 
280  /** return opttol set by SCIPlpiSetRealpar(), which might be tighter than what SoPlex accepted */
281  Real opttol() const
282  {
283  return realParam(OPTTOL);
284  }
285 
286  /** set opttol and store value in case SoPlex only accepts a larger tolerance */
287  void setOpttol(
288  const Real d
289  )
290  {
291  CHECK_SOPLEX_PARAM(setRealParam(OPTTOL, d));
292  }
293 
294  /** get objective limit according to objective sense */
295  Real getObjLimit() const
296  {
297  return (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE)
298  ? realParam(SoPlex::OBJLIMIT_UPPER)
299  : realParam(SoPlex::OBJLIMIT_LOWER);
300  }
301 
302  // @todo realize this with a member variable as before
303  bool getFromScratch() const
304  {
305  return _fromscratch;
306  }
307 
308  void setFromScratch(bool fs)
309  {
310  _fromscratch = fs;
311  }
312 
313  void setInterrupt(bool interrupt)
314  {
315  _interrupt = interrupt;
316  }
317 
318  bool* getInterrupt()
319  {
320  return &_interrupt;
321  }
322 
323  // @todo member variable?
324  bool getLpInfo() const
325  {
326  return _lpinfo;
327  }
328 
329  void setLpInfo(bool lpinfo)
330  {
331  _lpinfo = lpinfo;
332  }
333 
334  // @todo member variable?
335  void setProbname(const char* probname)
336  {
337  size_t len;
338 
339  assert(probname != NULL);
340  if( _probname != NULL )
341  spx_free(_probname);
342 
343  len = strlen(probname);
344  spx_alloc(_probname, len + 1);
345  memcpy(_probname, probname, len + 1);
346  }
347 
348  void setRep(SPxSolver::Representation p_rep)
349  {
350  if( p_rep == SPxSolver::COLUMN && intParam(REPRESENTATION) == REPRESENTATION_ROW )
351  {
352  SCIPdebugMessage("switching to column representation of the basis\n");
353  CHECK_SOPLEX_PARAM(setIntParam(REPRESENTATION, REPRESENTATION_COLUMN));
354  }
355  else if( (p_rep == SPxSolver::ROW && intParam(REPRESENTATION) == REPRESENTATION_COLUMN) )
356  {
357  SCIPdebugMessage("switching to row representation of the basis\n");
358  CHECK_SOPLEX_PARAM(setIntParam(REPRESENTATION, REPRESENTATION_ROW));
359  }
360  }
361 
362 #ifdef SCIP_WITH_LPSCHECK
363  bool getDoubleCheck()
364  {
365  _checknum++;
366  return _doublecheck && _checknum + 1 >= CHECK_START;
367  }
368 
369  void setDoubleCheck(bool dc)
370  {
371  _doublecheck = dc;
372  }
373 
374  const char* spxStatusString(const SPxSolver::Status stat) const
375  {
376  switch( stat )
377  {
378  case SPxSolver::ABORT_TIME:
379  return "ABORT_TIME";
380  case SPxSolver::ABORT_ITER:
381  return "ABORT_ITER";
382  case SPxSolver::ABORT_VALUE:
383  return "ABORT_VALUE";
384  case SPxSolver::SINGULAR:
385  return "SINGULAR";
386  case SPxSolver::REGULAR:
387  return "REGULAR";
388  case SPxSolver::UNKNOWN:
389  return "UNKNOWN";
390  case SPxSolver::OPTIMAL:
391  return "OPTIMAL";
392 #if SOPLEX_APIVERSION >= 3
393  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
394  return "OPTIMAL_UNSCALED_VIOLATIONS";
395 #endif
396  case SPxSolver::UNBOUNDED:
397  return "UNBOUNDED";
398  case SPxSolver::INFEASIBLE:
399  return "INFEASIBLE";
400  default:
401  return "UNKNOWN";
402  } /*lint !e788*/
403  }
404 
405  const char* cpxStatusString(const int stat) const
406  {
407  switch( stat )
408  {
409  case CPX_STAT_ABORT_TIME_LIM:
410  return "ABORT_TIME";
411  case CPX_STAT_ABORT_IT_LIM:
412  return "ABORT_ITER";
413  case CPX_STAT_ABORT_OBJ_LIM:
414  return "ABORT_VALUE";
415  case CPX_STAT_OPTIMAL:
416  return "OPTIMAL";
417  case CPX_STAT_OPTIMAL_INFEAS:
418  return "CPX_STAT_OPTIMAL_INFEAS: OPT SOL INFEASIBLE AFTER UNSCALING";
419  case CPX_STAT_UNBOUNDED:
420  return "UNBOUNDED";
421  case CPX_STAT_INFEASIBLE:
422  return "INFEASIBLE";
423  case CPX_STAT_INForUNBD:
424  return "INFEASIBLE or UNBOUNDED";
425  case CPX_STAT_NUM_BEST:
426  return "CPX_STAT_NUM_BEST: SOL AVAILABLE BUT NOT PROVEN OPTIMAL DUE TO NUM TROUBLE";
427  default:
428  return "UNKNOWN";
429  } /*lint !e788*/
430  }
431 #endif
432 
433 #ifndef NDEBUG
434  bool checkConsistentBounds() const
435  {
436  for( int i = 0; i < numColsReal(); ++i )
437  {
438  if( lowerReal(i) > upperReal(i) + realParam(SoPlex::EPSILON_ZERO) )
439  {
440  SCIPerrorMessage("inconsistent bounds on column %d: lower=%.17g, upper=%.17g\n",
441  i, lowerReal(i), upperReal(i));
442  return false;
443  }
444  }
445 
446  return true;
447  }
448 
449  bool checkConsistentSides() const
450  {
451  for( int i = 0; i < numRowsReal(); ++i )
452  {
453  if( lhsReal(i) > rhsReal(i) + realParam(SoPlex::EPSILON_ZERO) )
454  {
455  SCIPerrorMessage("inconsistent sides on row %d: lhs=%.17g, rhs=%.17g\n",
456  i, lhsReal(i), rhsReal(i));
457  return false;
458  }
459  }
460 
461  return true;
462  }
463 #endif
464 
465  void trySolve(bool printwarning = true)
466  {
467  Real timespent;
468  Real timelimit;
469 
470  try
471  {
472 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
473 #if SOPLEX_APIVERSION > 11
474  (void) optimize(&_interrupt);
475 #else
476  (void) optimize();
477 #endif
478 #else
479  (void) solve();
480 #endif
481  }
482  catch(const SPxException& x)
483  {
484  std::string s = x.what();
485  if( printwarning )
486  {
487  SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
488  }
489 
490  /* since it is not clear if the status in SoPlex are set correctly
491  * we want to make sure that if an error is thrown the status is
492  * not OPTIMAL anymore.
493  */
494  assert(status() != SPxSolver::OPTIMAL);
495  }
496 
497  assert(intParam(ITERLIMIT) < 0 || numIterations() <= intParam(ITERLIMIT));
498 
499  /* update time limit */
500  timespent = solveTime();
501  if( timespent > 0 )
502  {
503  /* get current time limit */
504  timelimit = realParam(TIMELIMIT);
505  if( timelimit > timespent )
506  timelimit -= timespent;
507  else
508  timelimit = 0;
509  /* set new time limit */
510  assert(timelimit >= 0);
511  CHECK_SOPLEX_PARAM(setRealParam(TIMELIMIT, timelimit));
512  }
513  }
514 
515  SPxSolver::Status doSolve(bool printwarning = true)
516  {
517  SPxOut::Verbosity verbosity;
518 
519  SPxSolver::Status spxStatus;
520 
521  /* store and set verbosity */
522  verbosity = spxout.getVerbosity();
523  spxout.setVerbosity((SPxOut::Verbosity)(getLpInfo() ? SOPLEX_VERBLEVEL : 0));
524 
525  assert(checkConsistentBounds());
526  assert(checkConsistentSides());
527 
528 #ifdef SCIP_WITH_LPSCHECK
529  /* dump LP with current basis and settings saved in SoPlex */
530  if( getDoubleCheck() )
531  writeStateReal("spxcheck", NULL, NULL);
532 #endif
533 
534  trySolve(printwarning);
535  spxStatus = status();
536 
537  /* for safety reset iteration limit */
538 // setTerminationIter(_itlim);
539 
540 #ifdef SCIP_WITH_LPSCHECK
541  bool minimize = intParam(OBJSENSE) == OBJSENSE_MINIMIZE;
542  Real objLimitUpper = realParam(OBJLIMIT_UPPER);
543  Real objLimitLower = realParam(OBJLIMIT_LOWER);
544 
545  /* if SoPlex gave a definite answer, we double check if it is consistent with CPLEX's answer */
546  if( getDoubleCheck() && (spxStatus == SPxSolver::OPTIMAL || spxStatus == SPxSolver::UNBOUNDED || spxStatus == SPxSolver::INFEASIBLE || spxStatus == SPxSolver::ABORT_VALUE) )
547  {
548  SCIP_Real cpxobj;
549  int cpxstat;
550 
551  /* read LP with basis */
552  CPX_CALL( CPXreadcopyprob(_cpxenv, _cpxlp, "spxcheck.mps", NULL) );
553  CPX_CALL( CPXreadcopybase(_cpxenv, _cpxlp, "spxcheck.bas") );
554 
555  /* set tolerances */
556  CPX_CALL( CPXsetdblparam(_cpxenv, CPX_PARAM_EPOPT, MAX(opttol(), 1e-9)) );
557  CPX_CALL( CPXsetdblparam(_cpxenv, CPX_PARAM_EPRHS, MAX(feastol(), 1e-9)) );
558 
559  /* solve LP */
560  CPX_CALL( CPXlpopt(_cpxenv, _cpxlp) );
561 
562  /* get solution status and objective value */
563  CPX_CALL( CPXsolution(_cpxenv, _cpxlp, &cpxstat, &cpxobj, NULL, NULL, NULL, NULL) );
564  if( !minimize )
565  cpxobj *= -1.0;
566 
567  /* check for inconsistent statuses */
568  if( cpxstat == CPX_STAT_OPTIMAL_INFEAS )
569  {
570  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s)\n",
571  _probname, spxStatus, spxStatusString(spxStatus), cpxstat, cpxStatusString(cpxstat));
572  if( EXIT_AT_CPXERROR )
573  exit(1);
574  }
575  else if( (spxStatus == SPxSolver::OPTIMAL && cpxstat != CPX_STAT_OPTIMAL)
576  || (spxStatus == SPxSolver::UNBOUNDED && cpxstat != CPX_STAT_UNBOUNDED)
577  || (spxStatus == SPxSolver::INFEASIBLE && cpxstat != CPX_STAT_INFEASIBLE) )
578  {
579  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
580  _probname, spxStatus, spxStatusString(spxStatus), cpxstat, cpxStatusString(cpxstat), _checknum);
581  if( EXIT_AT_WRONG_RESULT )
582  exit(1);
583  }
584  else if( spxStatus == SPxSolver::ABORT_VALUE )
585  {
586  switch( cpxstat )
587  {
588  case CPX_STAT_OPTIMAL:
589  if( (minimize && LTrel(cpxobj, objLimitUpper, 2*opttol()))
590  || (!minimize && GTrel(cpxobj, objLimitLower, 2*opttol())) )
591  {
592  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
593  _probname, spxStatus, spxStatusString(spxStatus), cpxobj, minimize ? "<" : ">",
594  minimize ? objLimitUpper : objLimitLower, cpxStatusString(cpxstat), _checknum);
595  if( EXIT_AT_WRONG_RESULT )
596  exit(1);
597  }
598  else if( (minimize && cpxobj < objLimitUpper) || (!minimize && cpxobj > objLimitLower) )
599  {
600  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
601  _probname, spxStatus, spxStatusString(spxStatus), cpxobj, minimize? "<" : ">",
602  minimize ? objLimitUpper : objLimitLower, cpxStatusString(cpxstat), _checknum);
603  }
604  break;
605  case CPX_STAT_OPTIMAL_INFEAS:
606  case CPX_STAT_NUM_BEST:
607  if( (minimize && cpxobj < objLimitUpper) || (!minimize && cpxobj > objLimitLower) )
608  {
609  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
610  _probname, spxStatus, spxStatusString(spxStatus), cpxobj, minimize ? "<" : ">",
611  minimize ? objLimitUpper : objLimitLower, cpxStatusString(cpxstat), _checknum);
612  }
613  break;
614  case CPX_STAT_INFEASIBLE:
615  break;
616  case CPX_STAT_UNBOUNDED:
617  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
618  _probname, spxStatus, spxStatusString(spxStatus), cpxstat, cpxStatusString(cpxstat), _checknum);
619  if( EXIT_AT_WRONG_RESULT )
620  exit(1);
621  break;
622  case CPX_STAT_INForUNBD:
623  default:
624  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
625  _probname, spxStatus, spxStatusString(spxStatus), cpxstat, cpxStatusString(cpxstat), _checknum);
626  break;
627  } /*lint !e788*/
628  }
629  /* check for same objective values */
630  else if( spxStatus == SPxSolver::OPTIMAL )
631  {
632  if( (minimize && LTrel(objValueReal(), cpxobj, 2*opttol()))
633  || (!minimize && GTrel(objValueReal(), cpxobj, 2*opttol())) )
634  {
635  /* SCIPerrorMessage("In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f too good (checknum=%d)\n", value(),
636  _probname, getSense() == SPxSolver::MINIMIZE ? "<" : ">", cpxobj, _checknum); */
637  }
638  else if( (minimize && GTrel(objValueReal(), cpxobj, 2*opttol()))
639  || (!minimize && LTrel(objValueReal(), cpxobj, 2*opttol())) )
640  {
641  SCIPerrorMessage("In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f suboptimal (checknum=%d)\n", _probname, objValueReal(),
642  minimize ? ">" : "<", cpxobj, _checknum);
643  if( EXIT_AT_WRONG_RESULT )
644  exit(1);
645  }
646  }
647  }
648 
649  ENDCHECK:
650 #endif
651 
652  /* restore verbosity */
653  spxout.setVerbosity(verbosity);
654 
655  return spxStatus;
656  }
657 
658  /** save the current basis */
659  void savePreStrongbranchingBasis()
660  {
661  _rowStat.reSize(numRowsReal());
662  _colStat.reSize(numColsReal());
663 
664  try
665  {
666  getBasis(_rowStat.get_ptr(), _colStat.get_ptr());
667  }
668 #ifndef NDEBUG
669  catch(const SPxException& x)
670  {
671  std::string s = x.what();
672  SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
673 
674  /* since it is not clear if the status in SoPlex are set correctly
675  * we want to make sure that if an error is thrown the status is
676  * not OPTIMAL anymore.
677  */
678  assert(status() != SPxSolver::OPTIMAL);
679  }
680 #else
681  catch(const SPxException&)
682  { }
683 #endif
684  }
685 
686  /** restore basis */
687  void restorePreStrongbranchingBasis()
688  {
689  assert(_rowStat.size() == numRowsReal());
690  assert(_colStat.size() == numColsReal());
691 
692  try
693  {
694  setBasis(_rowStat.get_ptr(), _colStat.get_ptr());
695  }
696 #ifndef NDEBUG
697  catch(const SPxException& x)
698  {
699  std::string s = x.what();
700  SCIPmessagePrintWarning(_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
701 #else
702  catch(const SPxException&)
703  {
704 #endif
705  /* since it is not clear if the status in SoPlex are set correctly
706  * we want to make sure that if an error is thrown the status is
707  * not OPTIMAL anymore.
708  */
709  assert(status() != SPxSolver::OPTIMAL);
710  }
711  }
712 
713  /** if basis is in store, delete it without restoring it */
714  void freePreStrongbranchingBasis()
715  {
716  _rowStat.clear();
717  _colStat.clear();
718  }
719 
720  /** is pre-strong-branching basis freed? */
721  bool preStrongbranchingBasisFreed() const
722  {
723  return ((_rowStat.size() == 0 ) && (_colStat.size() == 0));
724  }
725 
726  /** provides access for temporary storage of basis status of rows */
727  DataArray<SPxSolver::VarStatus>& rowStat()
728  {
729  return _rowStat; /*lint !e1536*/
730  }
731 
732  /** provides access for temporary storage of basis status or columns */
733  DataArray<SPxSolver::VarStatus>& colStat()
734  {
735  return _colStat; /*lint !e1536*/
736  }
737 
738 }; /*lint !e1748*/
739 
740 
741 
742 
743 /********************************************************************/
744 /*----------------------------- C --------------------------------*/
745 /********************************************************************/
746 
747 #include "lpi/lpi.h"
748 #include "scip/bitencode.h"
749 
750 typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
751 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
752 typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
753 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
757 /** LP interface */
758 struct SCIP_LPi
759 {
760  SPxSCIP* spx; /**< our SoPlex implementation */
761  int* cstat; /**< array for storing column basis status */
762  int* rstat; /**< array for storing row basis status */
763  int cstatsize; /**< size of cstat array */
764  int rstatsize; /**< size of rstat array */
765  SCIP_PRICING pricing; /**< current pricing strategy */
766  SCIP_Bool solved; /**< was the current LP solved? */
767  SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
768  SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
769  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
770 };
771 
772 /** LPi state stores basis information */
773 struct SCIP_LPiState
774 {
775  int ncols; /**< number of LP columns */
776  int nrows; /**< number of LP rows */
777  COLPACKET* packcstat; /**< column basis status in compressed form */
778  ROWPACKET* packrstat; /**< row basis status in compressed form */
779 };
780 
781 /** LPi norms to store dual steepest edge */
782 struct SCIP_LPiNorms
783 {
784  int nrows; /**< number of stored norms corresponding to rows */
785  int ncols; /**< number of stored norms corresponding to cols */
786  SCIP_Real* norms; /**< norms to be (re)stored */
787 };
788 
789 
790 
791 /*
792  * dynamic memory arrays
793  */
794 
795 /** resizes cstat array to have at least num entries */
796 static
798  SCIP_LPI* lpi, /**< LP interface structure */
799  int num /**< minimal number of entries in array */
800  )
801 {
802  assert(lpi != NULL);
803 
804  if( num > lpi->cstatsize )
805  {
806  int newsize;
807 
808  newsize = MAX(2*lpi->cstatsize, num);
809  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
810  lpi->cstatsize = newsize;
811  }
812  assert(num <= lpi->cstatsize);
813 
814  return SCIP_OKAY;
815 }
816 
817 /** resizes rstat array to have at least num entries */
818 static
820  SCIP_LPI* lpi, /**< LP interface structure */
821  int num /**< minimal number of entries in array */
822  )
823 {
824  assert(lpi != NULL);
825 
826  if( num > lpi->rstatsize )
827  {
828  int newsize;
829 
830  newsize = MAX(2*lpi->rstatsize, num);
831  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
832  lpi->rstatsize = newsize;
833  }
834  assert(num <= lpi->rstatsize);
835 
836  return SCIP_OKAY;
837 }
838 
839 
840 
841 
842 /*
843  * LPi state methods
844  */
845 
846 /** returns the number of packets needed to store column packet information */
847 static
848 int colpacketNum(
849  int ncols /**< number of columns to store */
850  )
851 {
852  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
853 }
854 
855 /** returns the number of packets needed to store row packet information */
856 static
857 int rowpacketNum(
858  int nrows /**< number of rows to store */
859  )
860 {
861  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
862 }
863 
864 /** store row and column basis status in a packed LPi state object */
865 static
866 void lpistatePack(
867  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
868  const int* cstat, /**< basis status of columns in unpacked format */
869  const int* rstat /**< basis status of rows in unpacked format */
870  )
871 {
872  assert(lpistate != NULL);
873  assert(lpistate->packcstat != NULL);
874  assert(lpistate->packrstat != NULL);
875 
876  SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
877  SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
878 }
879 
880 /** unpacks row and column basis status from a packed LPi state object */
881 static
882 void lpistateUnpack(
883  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
884  int* cstat, /**< buffer for storing basis status of columns in unpacked format */
885  int* rstat /**< buffer for storing basis status of rows in unpacked format */
886  )
887 {
888  assert(lpistate != NULL);
889  assert(lpistate->packcstat != NULL);
890  assert(lpistate->packrstat != NULL);
891 
892  SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
893  SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
894 }
895 
896 /** creates LPi state information object */
897 static
899  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
900  BMS_BLKMEM* blkmem, /**< block memory */
901  int ncols, /**< number of columns to store */
902  int nrows /**< number of rows to store */
903  )
904 {
905  assert(lpistate != NULL);
906  assert(blkmem != NULL);
907  assert(ncols >= 0);
908  assert(nrows >= 0);
909 
910  int nColPackets = colpacketNum(ncols);
911  int nRowPackets = rowpacketNum(nrows);
912 
913  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
914  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets) );
915  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets) );
916 
917  return SCIP_OKAY;
918 }
919 
920 /** frees LPi state information */
921 static
922 void lpistateFree(
923  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
924  BMS_BLKMEM* blkmem /**< block memory */
925  )
926 {
927  assert(blkmem != NULL);
928  assert(lpistate != NULL);
929  assert(*lpistate != NULL);
930 
931  int nColPackets = colpacketNum((*lpistate)->ncols);
932  int nRowPackets = rowpacketNum((*lpistate)->nrows);
933 
934  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets);
935  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets);
936  BMSfreeBlockMemory(blkmem, lpistate);
937 }
938 
939 
940 
941 
942 /*
943  * local methods
944  */
945 
946 
947 /** marks the current LP to be unsolved */
948 static
949 void invalidateSolution(SCIP_LPI* lpi)
950 {
951  assert(lpi != NULL);
952  lpi->solved = FALSE;
953 }
954 
955 
956 
957 /*
958  * LP Interface Methods
959  */
960 
961 
962 /*
963  * Miscellaneous Methods
964  */
965 
966 static char spxname[100];
967 static char spxdesc[200];
968 
969 /**@name Miscellaneous Methods */
970 /**@{ */
971 
972 /** gets name and version of LP solver */
973 const char* SCIPlpiGetSolverName(
974  void
975  )
976 {
977  SCIPdebugMessage("calling SCIPlpiGetSolverName()\n");
978 
979 #if (SOPLEX_SUBVERSION > 0)
980  (void)snprintf(spxname, 100, "SoPlex %d.%d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10, SOPLEX_SUBVERSION); /*lint !e778 !e845*/
981 #else
982  (void)snprintf(spxname, 100, "SoPlex %d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10); /*lint !e778 !e845*/
983 #endif
984  return spxname;
985 }
986 
987 /** gets description of LP solver (developer, webpage, ...) */
988 const char* SCIPlpiGetSolverDesc(
989  void
990  )
991 {
992  (void)snprintf(spxdesc, 200, "%s [GitHash: %s]", "Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de)"
993 #ifdef SCIP_WITH_LPSCHECK
994  " - including CPLEX double check"
995 #endif
996  , getGitHash());
997 
998  return spxdesc;
999 }
1000 
1001 /** gets pointer for LP solver - use only with great care */
1003  SCIP_LPI* lpi /**< pointer to an LP interface structure */
1004  )
1006  return (void*) lpi->spx;
1007 }
1008 
1009 /** pass integrality information about variables to the solver */
1011  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
1012  int ncols, /**< length of integrality array */
1013  int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
1014  )
1015 {
1016  assert( lpi != NULL );
1017  assert( ncols >= 0 );
1018  assert( ncols == 0 || intInfo != NULL );
1019 
1020 #if (SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3))
1021  assert(ncols == lpi->spx->numColsReal() || (ncols == 0 && intInfo == NULL));
1022  lpi->spx->setIntegralityInformation(ncols, intInfo);
1023  return SCIP_OKAY;
1024 #else
1025  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1026  return SCIP_LPERROR;
1027 #endif
1028 }
1029 
1030 /** informs about availability of a primal simplex solving method */
1032  void
1033  )
1035  return TRUE;
1036 }
1037 
1038 /** informs about availability of a dual simplex solving method */
1040  void
1041  )
1043  return TRUE;
1044 }
1045 
1046 /** informs about availability of a barrier solving method */
1048  void
1049  )
1051  return FALSE;
1052 }
1053 
1054 /**@} */
1055 
1056 
1057 
1058 
1059 /*
1060  * LPI Creation and Destruction Methods
1061  */
1062 
1063 /**@name LPI Creation and Destruction Methods */
1064 /**@{ */
1065 
1066 /** creates an LP problem object */
1068  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1069  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1070  const char* name, /**< problem name */
1071  SCIP_OBJSEN objsen /**< objective sense */
1072  )
1073 {
1074  assert(lpi != NULL);
1075  assert(name != NULL);
1076 
1077  /* create SoPlex object */
1078  SCIP_ALLOC( BMSallocMemory(lpi) );
1079 
1080  /* we use this construction to allocate the memory for the SoPlex class also via the blockmemshell */
1081  (*lpi)->spx = static_cast<SPxSCIP*>(BMSallocMemoryCPP(sizeof(SPxSCIP)));
1082  SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxSCIP(messagehdlr, name) );
1083  (void) (*lpi)->spx->setIntParam(SoPlex::SYNCMODE, SoPlex::SYNCMODE_ONLYREAL);
1084  (void) (*lpi)->spx->setIntParam(SoPlex::SOLVEMODE, SoPlex::SOLVEMODE_REAL);
1085  (void) (*lpi)->spx->setIntParam(SoPlex::REPRESENTATION, SoPlex::REPRESENTATION_AUTO);
1086 
1087  /* disable time-measurement for statistics */
1088 #if SOPLEX_APIVERSION >= 10
1089  (void) (*lpi)->spx->setIntParam(SoPlex::STATTIMER, 0);
1090 #endif
1091 
1092  (*lpi)->cstat = NULL;
1093  (*lpi)->rstat = NULL;
1094  (*lpi)->cstatsize = 0;
1095  (*lpi)->rstatsize = 0;
1096  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1097  (*lpi)->conditionlimit = -1.0;
1098  (*lpi)->checkcondition = FALSE;
1099  (*lpi)->messagehdlr = messagehdlr;
1100 
1101  invalidateSolution(*lpi);
1102 
1103  /* set objective sense */
1104  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1105 
1106  /* set default pricing */
1107  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
1108 
1109  {
1110  (*lpi)->spx->setInterrupt(FALSE);
1111  SPxOut::Verbosity verbosity = (*lpi)->spx->spxout.getVerbosity();
1112  (*lpi)->spx->spxout.setVerbosity((SPxOut::Verbosity)((*lpi)->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
1113  (*lpi)->spx->printVersion();
1114  (*lpi)->spx->spxout.setVerbosity(verbosity);
1115  }
1116 
1117  return SCIP_OKAY;
1118 }
1119 
1120 /** deletes an LP problem object */
1122  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1123  )
1125  assert(lpi != NULL);
1126  assert(*lpi != NULL);
1127  assert((*lpi)->spx != NULL);
1128 
1129  /* free LP using destructor and free memory via blockmemshell */
1130  (*lpi)->spx->~SPxSCIP();
1131  BMSfreeMemory(&((*lpi)->spx));
1132 
1133  /* free memory */
1134  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1135  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1136  BMSfreeMemory(lpi);
1137 
1138  return SCIP_OKAY;
1139 }
1140 
1141 /**@} */
1142 
1143 
1144 
1145 
1146 /*
1147  * Modification Methods
1148  */
1149 
1150 /**@name Modification Methods */
1151 /**@{ */
1152 
1153 /** copies LP data with column matrix into LP solver */
1155  SCIP_LPI* lpi, /**< LP interface structure */
1156  SCIP_OBJSEN objsen, /**< objective sense */
1157  int ncols, /**< number of columns */
1158  const SCIP_Real* obj, /**< objective function values of columns */
1159  const SCIP_Real* lb, /**< lower bounds of columns */
1160  const SCIP_Real* ub, /**< upper bounds of columns */
1161  char** colnames, /**< column names, or NULL */
1162  int nrows, /**< number of rows */
1163  const SCIP_Real* lhs, /**< left hand sides of rows */
1164  const SCIP_Real* rhs, /**< right hand sides of rows */
1165  char** /*rownames*/, /**< row names, or NULL */
1166  int nnonz, /**< number of nonzero elements in the constraint matrix */
1167  const int* beg, /**< start index of each column in ind- and val-array */
1168  const int* ind, /**< row indices of constraint matrix entries */
1169  const SCIP_Real* val /**< values of constraint matrix entries */
1170  )
1171 {
1172 #ifndef NDEBUG
1173  {
1174  int j;
1175  for( j = 0; j < nnonz; j++ )
1176  assert( val[j] != 0 );
1177  }
1178 #endif
1179 
1180  SCIPdebugMessage("calling SCIPlpiLoadColLP()\n");
1181 
1182  assert(lpi != NULL);
1183  assert(lpi->spx != NULL);
1184  assert(lhs != NULL);
1185  assert(rhs != NULL);
1186  assert(obj != NULL);
1187  assert(lb != NULL);
1188  assert(ub != NULL);
1189  assert(beg != NULL);
1190  assert(ind != NULL);
1191  assert(val != NULL);
1192 
1193  invalidateSolution(lpi);
1194  assert(lpi->spx->preStrongbranchingBasisFreed());
1195 
1196  try
1197  {
1198  SPxSCIP* spx = lpi->spx;
1199  LPRowSet rows(nrows);
1200  DSVector emptyVector(0);
1201  int i;
1202 
1203  spx->clearLPReal();
1204 
1205  /* set objective sense */
1206  (void) spx->setIntParam(SoPlex::OBJSENSE, (objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE));
1207 
1208  /* create empty rows with given sides */
1209  for( i = 0; i < nrows; ++i )
1210  rows.add(lhs[i], emptyVector, rhs[i]);
1211  spx->addRowsReal(rows);
1212 
1213  /* create column vectors with coefficients and bounds */
1214  SCIP_CALL( SCIPlpiAddCols(lpi, ncols, obj, lb, ub, colnames, nnonz, beg, ind, val) );
1215  }
1216 #ifndef NDEBUG
1217  catch( const SPxException& x )
1218  {
1219  std::string s = x.what();
1220  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1221 #else
1222  catch( const SPxException& )
1223  {
1224 #endif
1225  return SCIP_LPERROR;
1226  }
1227 
1228  return SCIP_OKAY;
1229 }
1230 
1231 /** adds columns to the LP */
1233  SCIP_LPI* lpi, /**< LP interface structure */
1234  int ncols, /**< number of columns to be added */
1235  const SCIP_Real* obj, /**< objective function values of new columns */
1236  const SCIP_Real* lb, /**< lower bounds of new columns */
1237  const SCIP_Real* ub, /**< upper bounds of new columns */
1238  char** /*colnames*/, /**< column names, or NULL */
1239  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1240  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1241  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1242  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1243  )
1244 {
1245  SCIPdebugMessage("calling SCIPlpiAddCols()\n");
1246 
1247  assert(lpi != NULL);
1248  assert(lpi->spx != NULL);
1249  assert(obj != NULL);
1250  assert(lb != NULL);
1251  assert(ub != NULL);
1252  assert(nnonz == 0 || beg != NULL);
1253  assert(nnonz == 0 || ind != NULL);
1254  assert(nnonz == 0 || val != NULL);
1255  assert(nnonz >= 0);
1256  assert(ncols >= 0);
1257 
1258  invalidateSolution(lpi);
1259 
1260  assert( lpi->spx->preStrongbranchingBasisFreed() );
1261 
1262 #ifndef NDEBUG
1263  if ( nnonz > 0 )
1264  {
1265  /* perform check that no new rows are added - this is likely to be a mistake */
1266  int nrows = lpi->spx->numRowsReal();
1267  for (int j = 0; j < nnonz; ++j)
1268  {
1269  assert( 0 <= ind[j] && ind[j] < nrows );
1270  assert( val[j] != 0.0 );
1271  }
1272  }
1273 #endif
1274 
1275  SPxSCIP* spx = lpi->spx;
1276  try
1277  {
1278  LPColSet cols(ncols);
1279  DSVector colVector(ncols);
1280  int start;
1281  int last;
1282  int i;
1283 
1284  /* create column vectors with coefficients and bounds */
1285  for( i = 0; i < ncols; ++i )
1286  {
1287  colVector.clear();
1288  if( nnonz > 0 )
1289  {
1290  start = beg[i];
1291  last = (i == ncols-1 ? nnonz : beg[i+1]);
1292  colVector.add( last-start, &ind[start], &val[start] );
1293  }
1294  cols.add(obj[i], lb[i], colVector, ub[i]);
1295  }
1296  spx->addColsReal(cols);
1297  }
1298 #ifndef NDEBUG
1299  catch( const SPxException& x )
1300  {
1301  std::string s = x.what();
1302  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1303 #else
1304  catch( const SPxException& )
1305  {
1306 #endif
1307  return SCIP_LPERROR;
1308  }
1309 
1310  return SCIP_OKAY;
1311 }
1312 
1313 /** deletes all columns in the given range from LP */
1315  SCIP_LPI* lpi, /**< LP interface structure */
1316  int firstcol, /**< first column to be deleted */
1317  int lastcol /**< last column to be deleted */
1318  )
1319 {
1320  SCIPdebugMessage("calling SCIPlpiDelCols()\n");
1321 
1322  assert(lpi != NULL);
1323  assert(lpi->spx != NULL);
1324  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
1325 
1326  invalidateSolution(lpi);
1327 
1328  assert( lpi->spx->preStrongbranchingBasisFreed() );
1329 
1330  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColRangeReal(firstcol, lastcol) );
1331 
1332  return SCIP_OKAY;
1333 }
1334 
1335 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1337  SCIP_LPI* lpi, /**< LP interface structure */
1338  int* dstat /**< deletion status of columns
1339  * input: 1 if column should be deleted, 0 if not
1340  * output: new position of column, -1 if column was deleted */
1341  )
1342 {
1343  int ncols;
1344  int i;
1345 
1346  SCIPdebugMessage("calling SCIPlpiDelColset()\n");
1347 
1348  assert(lpi != NULL);
1349  assert(lpi->spx != NULL);
1350  assert(dstat != NULL);
1351 
1352  invalidateSolution(lpi);
1353 
1354  assert( lpi->spx->preStrongbranchingBasisFreed() );
1355 
1356  ncols = lpi->spx->numColsReal();
1357 
1358  /* SoPlex removeCols() method deletes the columns with dstat[i] < 0, so we have to negate the values */
1359  for( i = 0; i < ncols; ++i )
1360  dstat[i] *= -1;
1361 
1362  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColsReal(dstat) );
1363 
1364  return SCIP_OKAY;
1365 }
1366 
1367 /** adds rows to the LP */
1369  SCIP_LPI* lpi, /**< LP interface structure */
1370  int nrows, /**< number of rows to be added */
1371  const SCIP_Real* lhs, /**< left hand sides of new rows */
1372  const SCIP_Real* rhs, /**< right hand sides of new rows */
1373  char** /*rownames*/, /**< row names, or NULL */
1374  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1375  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1376  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1377  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1378  )
1379 {
1380  SCIPdebugMessage("calling SCIPlpiAddRows()\n");
1381 
1382  assert(lpi != NULL);
1383  assert(lpi->spx != NULL);
1384  assert(lhs != NULL);
1385  assert(rhs != NULL);
1386  assert(nnonz == 0 || beg != NULL);
1387  assert(nnonz == 0 || ind != NULL);
1388  assert(nnonz == 0 || val != NULL);
1389 
1390  invalidateSolution(lpi);
1391 
1392  assert( lpi->spx->preStrongbranchingBasisFreed() );
1393 
1394 #ifndef NDEBUG
1395  if ( nnonz > 0 )
1396  {
1397  /* perform check that no new columns are added - this is likely to be a mistake */
1398  int ncols = lpi->spx->numColsReal();
1399  for (int j = 0; j < nnonz; ++j)
1400  {
1401  assert( val[j] != 0.0 );
1402  assert( 0 <= ind[j] && ind[j] < ncols );
1403  }
1404  }
1405 #endif
1406 
1407  try
1408  {
1409  SPxSCIP* spx = lpi->spx;
1410  LPRowSet rows(nrows);
1411  DSVector rowVector;
1412  int start;
1413  int last;
1414  int i;
1415 
1416  /* create row vectors with given sides */
1417  for( i = 0; i < nrows; ++i )
1418  {
1419  rowVector.clear();
1420  if( nnonz > 0 )
1421  {
1422  start = beg[i];
1423  last = (i == nrows-1 ? nnonz : beg[i+1]);
1424  rowVector.add( last-start, &ind[start], &val[start] );
1425  }
1426  rows.add(lhs[i], rowVector, rhs[i]);
1427  }
1428  spx->addRowsReal(rows);
1429  }
1430 #ifndef NDEBUG
1431  catch( const SPxException& x )
1432  {
1433  std::string s = x.what();
1434  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1435 #else
1436  catch( const SPxException& )
1437  {
1438 #endif
1439  return SCIP_LPERROR;
1440  }
1441 
1442  return SCIP_OKAY;
1443 }
1444 
1445 /** deletes all rows in the given range from LP */
1447  SCIP_LPI* lpi, /**< LP interface structure */
1448  int firstrow, /**< first row to be deleted */
1449  int lastrow /**< last row to be deleted */
1450  )
1451 {
1452  SCIPdebugMessage("calling SCIPlpiDelRows()\n");
1453 
1454  assert(lpi != NULL);
1455  assert(lpi->spx != NULL);
1456  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
1457 
1458  invalidateSolution(lpi);
1459 
1460  assert( lpi->spx->preStrongbranchingBasisFreed() );
1461 
1462  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowRangeReal(firstrow, lastrow) );
1463 
1464  return SCIP_OKAY;
1465 }
1466 
1467 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1469  SCIP_LPI* lpi, /**< LP interface structure */
1470  int* dstat /**< deletion status of rows
1471  * input: 1 if row should be deleted, 0 if not
1472  * output: new position of row, -1 if row was deleted */
1473  )
1474 {
1475  int nrows;
1476  int i;
1477 
1478  SCIPdebugMessage("calling SCIPlpiDelRowset()\n");
1479 
1480  assert(lpi != NULL);
1481  assert(lpi->spx != NULL);
1482 
1483  invalidateSolution(lpi);
1484 
1485  assert( lpi->spx->preStrongbranchingBasisFreed() );
1486 
1487  nrows = lpi->spx->numRowsReal();
1488 
1489  /* SoPlex removeRows() method deletes the rows with dstat[i] < 0, so we have to negate the values */
1490  for( i = 0; i < nrows; ++i )
1491  dstat[i] *= -1;
1492 
1493  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowsReal(dstat) );
1494 
1495  return SCIP_OKAY;
1496 }
1497 
1498 /** clears the whole LP */
1500  SCIP_LPI* lpi /**< LP interface structure */
1501  )
1503  SCIPdebugMessage("calling SCIPlpiClear()\n");
1504 
1505  assert(lpi != NULL);
1506  assert(lpi->spx != NULL);
1507 
1508  invalidateSolution(lpi);
1509 
1510  assert( lpi->spx->preStrongbranchingBasisFreed() );
1511  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->clearLPReal() );
1512 
1513  return SCIP_OKAY;
1514 }
1515 
1516 /** changes lower and upper bounds of columns */
1518  SCIP_LPI* lpi, /**< LP interface structure */
1519  int ncols, /**< number of columns to change bounds for */
1520  const int* ind, /**< column indices or NULL if ncols is zero */
1521  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1522  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1523  )
1524 {
1525  int i;
1526 
1527  SCIPdebugMessage("calling SCIPlpiChgBounds()\n");
1528 
1529  assert(lpi != NULL);
1530  assert(lpi->spx != NULL);
1531  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1532  if( ncols <= 0 )
1533  return SCIP_OKAY;
1534 
1535  invalidateSolution(lpi);
1536 
1537  assert( lpi->spx->preStrongbranchingBasisFreed() );
1538 
1539  try
1540  {
1541  for( i = 0; i < ncols; ++i )
1542  {
1543  assert(0 <= ind[i] && ind[i] < lpi->spx->numColsReal());
1544 
1545  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
1546  {
1547  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
1548  return SCIP_LPERROR;
1549  }
1550  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
1551  {
1552  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
1553  return SCIP_LPERROR;
1554  }
1555 
1556  lpi->spx->changeBoundsReal(ind[i], lb[i], ub[i]);
1557  assert(lpi->spx->lowerReal(ind[i]) <= lpi->spx->upperReal(ind[i]) + lpi->spx->realParam(SoPlex::EPSILON_ZERO));
1558  }
1559  }
1560 #ifndef NDEBUG
1561  catch( const SPxException& x )
1562  {
1563  std::string s = x.what();
1564  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1565 #else
1566  catch( const SPxException& )
1567  {
1568 #endif
1569  return SCIP_LPERROR;
1570  }
1571 
1572  return SCIP_OKAY;
1573 }
1574 
1575 /** changes left and right hand sides of rows */
1577  SCIP_LPI* lpi, /**< LP interface structure */
1578  int nrows, /**< number of rows to change sides for */
1579  const int* ind, /**< row indices */
1580  const SCIP_Real* lhs, /**< new values for left hand sides */
1581  const SCIP_Real* rhs /**< new values for right hand sides */
1582  )
1583 {
1584  int i;
1585 
1586  SCIPdebugMessage("calling SCIPlpiChgSides()\n");
1587 
1588  assert(lpi != NULL);
1589  assert(lpi->spx != NULL);
1590  assert(ind != NULL);
1591  assert(lhs != NULL);
1592  assert(rhs != NULL);
1593  if( nrows <= 0 )
1594  return SCIP_OKAY;
1595 
1596  invalidateSolution(lpi);
1597 
1598  assert( lpi->spx->preStrongbranchingBasisFreed() );
1599 
1600  try
1601  {
1602  for( i = 0; i < nrows; ++i )
1603  {
1604  assert(0 <= ind[i] && ind[i] < lpi->spx->numRowsReal());
1605  lpi->spx->changeRangeReal(ind[i], lhs[i], rhs[i]);
1606  assert(lpi->spx->lhsReal(ind[i]) <= lpi->spx->rhsReal(ind[i]) + lpi->spx->realParam(SoPlex::EPSILON_ZERO));
1607  }
1608  }
1609 #ifndef NDEBUG
1610  catch( const SPxException& x )
1611  {
1612  std::string s = x.what();
1613  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1614 #else
1615  catch( const SPxException& )
1616  {
1617 #endif
1618  return SCIP_LPERROR;
1619  }
1620 
1621  return SCIP_OKAY;
1622 }
1623 
1624 /** changes a single coefficient */
1626  SCIP_LPI* lpi, /**< LP interface structure */
1627  int row, /**< row number of coefficient to change */
1628  int col, /**< column number of coefficient to change */
1629  SCIP_Real newval /**< new value of coefficient */
1630  )
1631 {
1632  SCIPdebugMessage("calling SCIPlpiChgCoef()\n");
1633 
1634  assert(lpi != NULL);
1635  assert(lpi->spx != NULL);
1636  assert(0 <= row && row < lpi->spx->numRowsReal());
1637  assert(0 <= col && col < lpi->spx->numColsReal());
1638 
1639  invalidateSolution(lpi);
1640 
1641  assert( lpi->spx->preStrongbranchingBasisFreed() );
1642 
1643  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->changeElementReal(row, col, newval) );
1644 
1645  return SCIP_OKAY;
1646 }
1647 
1648 /** changes the objective sense */
1650  SCIP_LPI* lpi, /**< LP interface structure */
1651  SCIP_OBJSEN objsen /**< new objective sense */
1652  )
1653 {
1654  SCIPdebugMessage("calling SCIPlpiChgObjsen()\n");
1655 
1656  assert(lpi != NULL);
1657  assert(lpi->spx != NULL);
1658 
1659  invalidateSolution(lpi);
1660 
1661  assert( lpi->spx->preStrongbranchingBasisFreed() );
1662 
1663  SOPLEX_TRY( lpi->messagehdlr, (void) lpi->spx->setIntParam(SoPlex::OBJSENSE, objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE ) );
1664 
1665  return SCIP_OKAY;
1666 }
1667 
1668 /** changes objective values of columns in the LP */
1670  SCIP_LPI* lpi, /**< LP interface structure */
1671  int ncols, /**< number of columns to change objective value for */
1672  const int* ind, /**< column indices to change objective value for */
1673  const SCIP_Real* obj /**< new objective values for columns */
1674  )
1675 {
1676  int i;
1677 
1678  SCIPdebugMessage("calling SCIPlpiChgObj()\n");
1679 
1680  assert(lpi != NULL);
1681  assert(lpi->spx != NULL);
1682  assert(ind != NULL);
1683  assert(obj != NULL);
1684 
1685  invalidateSolution(lpi);
1686 
1687  assert( lpi->spx->preStrongbranchingBasisFreed() );
1688 
1689  try
1690  {
1691  for( i = 0; i < ncols; ++i )
1692  {
1693  assert(0 <= ind[i] && ind[i] < lpi->spx->numColsReal());
1694  lpi->spx->changeObjReal(ind[i], obj[i]);
1695  }
1696  }
1697 #ifndef NDEBUG
1698  catch( const SPxException& x )
1699  {
1700  std::string s = x.what();
1701  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1702 #else
1703  catch( const SPxException& )
1704  {
1705 #endif
1706  return SCIP_LPERROR;
1707  }
1708 
1709  return SCIP_OKAY;
1710 }
1711 
1712 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1714  SCIP_LPI* lpi, /**< LP interface structure */
1715  int row, /**< row number to scale */
1716  SCIP_Real scaleval /**< scaling multiplier */
1717  )
1718 {
1719  SCIP_Real lhs;
1720  SCIP_Real rhs;
1721 
1722  SCIPdebugMessage("calling SCIPlpiScaleRow()\n");
1723 
1724  assert(lpi != NULL);
1725  assert(lpi->spx != NULL);
1726  assert(scaleval != 0.0);
1727 
1728  try
1729  {
1730  invalidateSolution(lpi);
1731 
1732  assert( lpi->spx->preStrongbranchingBasisFreed() );
1733 
1734  /* get the row vector and the row's sides */
1735 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1736  SVector rowvec = lpi->spx->rowVectorRealInternal(row);
1737 #else
1738  SVector rowvec = lpi->spx->rowVectorReal(row);
1739 #endif
1740  lhs = lpi->spx->lhsReal(row);
1741  rhs = lpi->spx->rhsReal(row);
1742 
1743  /* scale the row vector */
1744  rowvec *= scaleval;
1745 
1746  /* adjust the sides */
1747  if( lhs > -lpi->spx->realParam(SoPlex::INFTY) )
1748  lhs *= scaleval;
1749  else if( scaleval < 0.0 )
1750  lhs = lpi->spx->realParam(SoPlex::INFTY);
1751  if( rhs < lpi->spx->realParam(SoPlex::INFTY) )
1752  rhs *= scaleval;
1753  else if( scaleval < 0.0 )
1754  rhs = -lpi->spx->realParam(SoPlex::INFTY);
1755  if( scaleval < 0.0 )
1756  {
1757  SCIP_Real oldlhs = lhs;
1758  lhs = rhs;
1759  rhs = oldlhs;
1760  }
1761 
1762  /* create the new row */
1763  LPRow lprow(lhs, rowvec, rhs);
1764 
1765  /* change the row in the LP */
1766  lpi->spx->changeRowReal(row, lprow);
1767  assert(lpi->spx->lhsReal(row) <= lpi->spx->rhsReal(row));
1768  }
1769 #ifndef NDEBUG
1770  catch( const SPxException& x )
1771  {
1772  std::string s = x.what();
1773  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1774 #else
1775  catch( const SPxException& )
1776  {
1777 #endif
1778  return SCIP_LPERROR;
1779  }
1780 
1781  return SCIP_OKAY;
1782 }
1783 
1784 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1785  * are divided by the scalar; for negative scalars, the column's bounds are switched
1786  */
1788  SCIP_LPI* lpi, /**< LP interface structure */
1789  int col, /**< column number to scale */
1790  SCIP_Real scaleval /**< scaling multiplier */
1791  )
1792 {
1793  SCIP_Real obj;
1794  SCIP_Real lb;
1795  SCIP_Real ub;
1796 
1797  SCIPdebugMessage("calling SCIPlpiScaleCol()\n");
1798 
1799  assert(lpi != NULL);
1800  assert(lpi->spx != NULL);
1801  assert(scaleval != 0.0);
1802 
1803  try
1804  {
1805  invalidateSolution(lpi);
1806 
1807  assert( lpi->spx->preStrongbranchingBasisFreed() );
1808 
1809  /* get the col vector and the col's bounds and objective value */
1810 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1811  SVector colvec = lpi->spx->colVectorRealInternal(col);
1812 #else
1813  SVector colvec = lpi->spx->colVectorReal(col);
1814 #endif
1815  obj = lpi->spx->objReal(col);
1816  lb = lpi->spx->lowerReal(col);
1817  ub = lpi->spx->upperReal(col);
1818 
1819  /* scale the col vector */
1820  colvec *= scaleval;
1821 
1822  /* scale the objective value */
1823  obj *= scaleval;
1824 
1825  /* adjust the bounds */
1826  if( lb > -lpi->spx->realParam(SoPlex::INFTY) )
1827  lb /= scaleval;
1828  else if( scaleval < 0.0 )
1829  lb = lpi->spx->realParam(SoPlex::INFTY);
1830  if( ub < lpi->spx->realParam(SoPlex::INFTY) )
1831  ub /= scaleval;
1832  else if( scaleval < 0.0 )
1833  ub = -lpi->spx->realParam(SoPlex::INFTY);
1834  if( scaleval < 0.0 )
1835  {
1836  SCIP_Real oldlb = lb;
1837  lb = ub;
1838  ub = oldlb;
1839  }
1840 
1841  /* create the new col (in LPCol's constructor, the upper bound is given first!) */
1842  LPCol lpcol(obj, colvec, ub, lb);
1843 
1844  /* change the col in the LP */
1845  lpi->spx->changeColReal(col, lpcol);
1846  assert(lpi->spx->lowerReal(col) <= lpi->spx->upperReal(col));
1847  }
1848 #ifndef NDEBUG
1849  catch( const SPxException& x )
1850  {
1851  std::string s = x.what();
1852  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1853 #else
1854  catch( const SPxException& )
1855  {
1856 #endif
1857  return SCIP_LPERROR;
1858  }
1859 
1860  return SCIP_OKAY;
1861 }
1862 
1863 /**@} */
1864 
1865 
1866 
1867 
1868 /*
1869  * Data Accessing Methods
1870  */
1871 
1872 /**@name Data Accessing Methods */
1873 /**@{ */
1874 
1875 /** gets the number of rows in the LP */
1877  SCIP_LPI* lpi, /**< LP interface structure */
1878  int* nrows /**< pointer to store the number of rows */
1879  )
1880 {
1881  SCIPdebugMessage("calling SCIPlpiGetNRows()\n");
1882 
1883  assert(lpi != NULL);
1884  assert(lpi->spx != NULL);
1885  assert(nrows != NULL);
1886 
1887  *nrows = lpi->spx->numRowsReal();
1888 
1889  return SCIP_OKAY;
1890 }
1891 
1892 /** gets the number of columns in the LP */
1894  SCIP_LPI* lpi, /**< LP interface structure */
1895  int* ncols /**< pointer to store the number of cols */
1896  )
1897 {
1898  SCIPdebugMessage("calling SCIPlpiGetNCols()\n");
1899 
1900  assert(lpi != NULL);
1901  assert(lpi->spx != NULL);
1902  assert(ncols != NULL);
1903 
1904  *ncols = lpi->spx->numColsReal();
1905 
1906  return SCIP_OKAY;
1907 }
1908 
1909 /** gets the number of nonzero elements in the LP constraint matrix */
1911  SCIP_LPI* lpi, /**< LP interface structure */
1912  int* nnonz /**< pointer to store the number of nonzeros */
1913  )
1914 {
1915  int i;
1916 
1917  SCIPdebugMessage("calling SCIPlpiGetNNonz()\n");
1918 
1919  assert(lpi != NULL);
1920  assert(lpi->spx != NULL);
1921  assert(nnonz != NULL);
1922 
1923  /* SoPlex has no direct method to return the number of nonzeros, so we have to count them manually */
1924  *nnonz = 0;
1925  if( lpi->spx->numRowsReal() < lpi->spx->numColsReal() )
1926  {
1927  for( i = 0; i < lpi->spx->numRowsReal(); ++i )
1928 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1929  (*nnonz) += lpi->spx->rowVectorRealInternal(i).size();
1930 #else
1931  (*nnonz) += lpi->spx->rowVectorReal(i).size();
1932 #endif
1933  }
1934  else
1935  {
1936  for( i = 0; i < lpi->spx->numColsReal(); ++i )
1937 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1938  (*nnonz) += lpi->spx->colVectorRealInternal(i).size();
1939 #else
1940  (*nnonz) += lpi->spx->colVectorReal(i).size();
1941 #endif
1942  }
1943 
1944  return SCIP_OKAY;
1945 }
1946 
1947 /** gets columns from LP problem object; the arrays have to be large enough to store all values
1948  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1949  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1950  */
1952  SCIP_LPI* lpi, /**< LP interface structure */
1953  int firstcol, /**< first column to get from LP */
1954  int lastcol, /**< last column to get from LP */
1955  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1956  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1957  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1958  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1959  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1960  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1961  )
1962 {
1963  int i;
1964  int j;
1965 
1966  SCIPdebugMessage("calling SCIPlpiGetCols()\n");
1967 
1968  assert(lpi != NULL);
1969  assert(lpi->spx != NULL);
1970  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
1971  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1972  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1973 
1974  if( lb != NULL )
1975  {
1976 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1977  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
1978  {
1979  DVector lbvec(lpi->spx->numColsReal());
1980  DVector ubvec(lpi->spx->numColsReal());
1981  lpi->spx->getLowerReal(lbvec);
1982  lpi->spx->getUpperReal(ubvec);
1983  for( i = firstcol; i <= lastcol; ++i )
1984  {
1985  lb[i-firstcol] = lbvec[i];
1986  ub[i-firstcol] = ubvec[i];
1987  }
1988  }
1989  else
1990  {
1991  const Vector& lbvec = lpi->spx->lowerRealInternal();
1992  const Vector& ubvec = lpi->spx->upperRealInternal();
1993  for( i = firstcol; i <= lastcol; ++i )
1994  {
1995  lb[i-firstcol] = lbvec[i];
1996  ub[i-firstcol] = ubvec[i];
1997  }
1998  }
1999 #else
2000  const Vector& lbvec = lpi->spx->lowerReal();
2001  const Vector& ubvec = lpi->spx->upperReal();
2002 
2003  for( i = firstcol; i <= lastcol; ++i )
2004  {
2005  lb[i-firstcol] = lbvec[i];
2006  ub[i-firstcol] = ubvec[i];
2007  }
2008 #endif
2009  }
2010 
2011  if( nnonz != NULL )
2012  {
2013  *nnonz = 0;
2014  for( i = firstcol; i <= lastcol; ++i )
2015  {
2016  beg[i-firstcol] = *nnonz;
2017 
2018 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2019  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2020  {
2021  DSVector cvec;
2022  lpi->spx->getColVectorReal(i, cvec);
2023  for( j = 0; j < cvec.size(); ++j )
2024  {
2025  ind[*nnonz] = cvec.index(j);
2026  val[*nnonz] = cvec.value(j);
2027  (*nnonz)++;
2028  }
2029  }
2030  else
2031  {
2032  const SVector& cvec = lpi->spx->colVectorRealInternal(i);
2033  for( j = 0; j < cvec.size(); ++j )
2034  {
2035  ind[*nnonz] = cvec.index(j);
2036  val[*nnonz] = cvec.value(j);
2037  (*nnonz)++;
2038  }
2039  }
2040 #else
2041  const SVector& cvec = lpi->spx->colVectorReal(i);
2042  for( j = 0; j < cvec.size(); ++j )
2043  {
2044  ind[*nnonz] = cvec.index(j);
2045  val[*nnonz] = cvec.value(j);
2046  (*nnonz)++;
2047  }
2048 #endif
2049  }
2050  }
2051 
2052  return SCIP_OKAY;
2053 }
2054 
2055 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
2056  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
2057  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2058  */
2060  SCIP_LPI* lpi, /**< LP interface structure */
2061  int firstrow, /**< first row to get from LP */
2062  int lastrow, /**< last row to get from LP */
2063  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
2064  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
2065  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2066  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
2067  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
2068  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2069  )
2070 {
2071  int i;
2072  int j;
2073 
2074  SCIPdebugMessage("calling SCIPlpiGetRows()\n");
2075 
2076  assert(lpi != NULL);
2077  assert(lpi->spx != NULL);
2078  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
2079  assert((lhs != NULL && rhs != NULL) || (lhs == NULL && rhs == NULL));
2080  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2081 
2082  if( lhs != NULL )
2083  {
2084 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2085  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2086  {
2087  DVector lhsvec(lpi->spx->numRowsReal());
2088  DVector rhsvec(lpi->spx->numRowsReal());
2089  lpi->spx->getLhsReal(lhsvec);
2090  lpi->spx->getRhsReal(rhsvec);
2091  for( i = firstrow; i <= lastrow; ++i )
2092  {
2093  lhs[i-firstrow] = lhsvec[i];
2094  rhs[i-firstrow] = rhsvec[i];
2095  }
2096  }
2097  else
2098  {
2099  const Vector& lhsvec = lpi->spx->lhsRealInternal();
2100  const Vector& rhsvec = lpi->spx->rhsRealInternal();
2101  for( i = firstrow; i <= lastrow; ++i )
2102  {
2103  lhs[i-firstrow] = lhsvec[i];
2104  rhs[i-firstrow] = rhsvec[i];
2105  }
2106  }
2107 #else
2108  const Vector& lhsvec = lpi->spx->lhsReal();
2109  const Vector& rhsvec = lpi->spx->rhsReal();
2110  for( i = firstrow; i <= lastrow; ++i )
2111  {
2112  lhs[i-firstrow] = lhsvec[i];
2113  rhs[i-firstrow] = rhsvec[i];
2114  }
2115 #endif
2116  }
2117 
2118  if( nnonz != NULL )
2119  {
2120  *nnonz = 0;
2121  for( i = firstrow; i <= lastrow; ++i )
2122  {
2123  beg[i-firstrow] = *nnonz;
2124 
2125 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2126  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2127  {
2128  DSVector rvec;
2129  lpi->spx->getRowVectorReal(i, rvec);
2130  for( j = 0; j < rvec.size(); ++j )
2131  {
2132  ind[*nnonz] = rvec.index(j);
2133  val[*nnonz] = rvec.value(j);
2134  (*nnonz)++;
2135  }
2136  }
2137  else
2138  {
2139  const SVector& rvec = lpi->spx->rowVectorRealInternal(i);
2140  for( j = 0; j < rvec.size(); ++j )
2141  {
2142  ind[*nnonz] = rvec.index(j);
2143  val[*nnonz] = rvec.value(j);
2144  (*nnonz)++;
2145  }
2146  }
2147 #else
2148  const SVector& rvec = lpi->spx->rowVectorReal(i);
2149  for( j = 0; j < rvec.size(); ++j )
2150  {
2151  ind[*nnonz] = rvec.index(j);
2152  val[*nnonz] = rvec.value(j);
2153  (*nnonz)++;
2154  }
2155 #endif
2156  }
2157  }
2158 
2159  return SCIP_OKAY;
2160 }
2161 
2162 /** gets column names */
2164  SCIP_LPI* lpi, /**< LP interface structure */
2165  int firstcol, /**< first column to get name from LP */
2166  int lastcol, /**< last column to get name from LP */
2167  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2168  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2169  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2170  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2171  )
2172 {
2173  assert( lpi != NULL );
2174  assert( lpi->spx != NULL );
2175  assert( colnames != NULL || namestoragesize == 0 );
2176  assert( namestorage != NULL || namestoragesize == 0 );
2177  assert( namestoragesize >= 0 );
2178  assert( storageleft != NULL );
2179  assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal() );
2180 
2181  SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
2182 
2183 // lpi->spx->getColNames(firstcol, lastcol, colnames, namestorage, namestoragesize, storageleft);
2184 
2185  return SCIP_OKAY;
2186 }
2187 
2188 /** gets row names */
2190  SCIP_LPI* lpi, /**< LP interface structure */
2191  int firstrow, /**< first row to get name from LP */
2192  int lastrow, /**< last row to get name from LP */
2193  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2194  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2195  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2196  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2197  )
2198 {
2199  assert( lpi != NULL );
2200  assert( lpi->spx != NULL );
2201  assert( rownames != NULL || namestoragesize == 0 );
2202  assert( namestorage != NULL || namestoragesize == 0 );
2203  assert( namestoragesize >= 0 );
2204  assert( storageleft != NULL );
2205  assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal() );
2206 
2207  SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
2208 
2209 // lpi->spx->getRowNames(firstrow, lastrow, rownames, namestorage, namestoragesize, storageleft);
2210 
2211  return SCIP_OKAY;
2212 }
2213 
2214 /** gets objective sense of the LP */
2216  SCIP_LPI* lpi, /**< LP interface structure */
2217  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2218  )
2219 {
2220  SCIPdebugMessage("calling SCIPlpiGetObjsen()\n");
2221 
2222  assert(lpi != NULL);
2223  assert(lpi->spx != NULL);
2224  assert(objsen != NULL);
2225 
2226  *objsen = (lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2227 
2228  return SCIP_OKAY;
2229 }
2230 
2231 /** gets objective coefficients from LP problem object */
2233  SCIP_LPI* lpi, /**< LP interface structure */
2234  int firstcol, /**< first column to get objective coefficient for */
2235  int lastcol, /**< last column to get objective coefficient for */
2236  SCIP_Real* vals /**< array to store objective coefficients */
2237  )
2238 {
2239  int i;
2240 
2241  SCIPdebugMessage("calling SCIPlpiGetObj()\n");
2242 
2243  assert(lpi != NULL);
2244  assert(lpi->spx != NULL);
2245  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
2246  assert(vals != NULL);
2247 
2248  for( i = firstcol; i <= lastcol; ++i )
2249  vals[i-firstcol] = lpi->spx->objReal(i);
2250 
2251  return SCIP_OKAY;
2252 }
2253 
2254 /** gets current bounds from LP problem object */
2256  SCIP_LPI* lpi, /**< LP interface structure */
2257  int firstcol, /**< first column to get objective value for */
2258  int lastcol, /**< last column to get objective value for */
2259  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2260  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2261  )
2262 {
2263  int i;
2264 
2265  SCIPdebugMessage("calling SCIPlpiGetBounds()\n");
2266 
2267  assert(lpi != NULL);
2268  assert(lpi->spx != NULL);
2269  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
2270 
2271  for( i = firstcol; i <= lastcol; ++i )
2272  {
2273  if( lbs != NULL )
2274  lbs[i-firstcol] = lpi->spx->lowerReal(i);
2275  if( ubs != NULL )
2276  ubs[i-firstcol] = lpi->spx->upperReal(i);
2277  }
2278 
2279  return SCIP_OKAY;
2280 }
2281 
2282 /** gets current row sides from LP problem object */
2284  SCIP_LPI* lpi, /**< LP interface structure */
2285  int firstrow, /**< first row to get sides for */
2286  int lastrow, /**< last row to get sides for */
2287  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2288  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2289  )
2290 {
2291  int i;
2292 
2293  SCIPdebugMessage("calling SCIPlpiGetSides()\n");
2294 
2295  assert(lpi != NULL);
2296  assert(lpi->spx != NULL);
2297  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
2298 
2299  for( i = firstrow; i <= lastrow; ++i )
2300  {
2301  if( lhss != NULL )
2302  lhss[i-firstrow] = lpi->spx->lhsReal(i);
2303  if( rhss != NULL )
2304  rhss[i-firstrow] = lpi->spx->rhsReal(i);
2305  }
2306 
2307  return SCIP_OKAY;
2308 }
2309 
2310 /** gets a single coefficient */
2312  SCIP_LPI* lpi, /**< LP interface structure */
2313  int row, /**< row number of coefficient */
2314  int col, /**< column number of coefficient */
2315  SCIP_Real* val /**< pointer to store the value of the coefficient */
2316  )
2317 {
2318  SCIPdebugMessage("calling SCIPlpiGetCoef()\n");
2319 
2320  assert(lpi != NULL);
2321  assert(lpi->spx != NULL);
2322  assert(0 <= col && col < lpi->spx->numColsReal());
2323  assert(0 <= row && row < lpi->spx->numRowsReal());
2324  assert(val != NULL);
2325 
2326 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2327  *val = lpi->spx->coefReal(row, col);
2328 #else
2329  *val = lpi->spx->colVectorReal(col)[row];
2330 #endif
2331 
2332  return SCIP_OKAY;
2333 }
2334 
2335 /**@} */
2336 
2337 
2338 
2339 
2340 /*
2341  * Solving Methods
2342  */
2343 
2344 /**@name Solving Methods */
2345 /**@{ */
2346 
2347 /** solves LP -- used for both, primal and dual simplex, because SoPlex doesn't distinct the two cases */
2348 static
2350  SCIP_LPI* lpi /**< LP interface structure */
2351  )
2353  assert( lpi != NULL );
2354  assert( lpi->spx != NULL );
2355 
2356  SPxOut::Verbosity verbosity;
2357  /* store and set verbosity */
2358  verbosity = lpi->spx->spxout.getVerbosity();
2359  lpi->spx->spxout.setVerbosity((SPxOut::Verbosity)(lpi->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
2360 
2361  SCIPdebugMessage("calling SoPlex solve(): %d cols, %d rows\n", lpi->spx->numColsReal(), lpi->spx->numRowsReal());
2362 
2363  invalidateSolution(lpi);
2364 
2365  assert( lpi->spx->preStrongbranchingBasisFreed() );
2366 
2367 #ifdef SCIP_WITH_LPSCHECK
2368  lpi->spx->setDoubleCheck(CHECK_SPXSOLVE);
2369 #endif
2370 
2371  /* delete starting basis if solving from scratch */
2372  if( lpi->spx->getFromScratch() )
2373  {
2374  try
2375  {
2376  lpi->spx->clearBasis();
2377  }
2378 #ifndef NDEBUG
2379  catch(const SPxException& x)
2380  {
2381  std::string s = x.what();
2382  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2383 #else
2384  catch(const SPxException&)
2385  {
2386 #endif
2387  assert( lpi->spx->status() != SPxSolver::OPTIMAL );
2388  return SCIP_LPERROR;
2389  }
2390  }
2391  assert(!lpi->spx->getFromScratch() || lpi->spx->status() == SPxSolver::NO_PROBLEM);
2392 
2393  SPxSolver::Status status = lpi->spx->doSolve();
2394  SCIPdebugMessage(" -> SoPlex status: %d, basis status: %d\n", lpi->spx->status(), lpi->spx->basisStatus());
2395  lpi->solved = TRUE;
2396 
2397  /* restore verbosity */
2398  lpi->spx->spxout.setVerbosity(verbosity);
2399 
2400  switch( status )
2401  {
2402  case SPxSolver::ABORT_TIME:
2403  case SPxSolver::ABORT_ITER:
2404  case SPxSolver::ABORT_VALUE:
2405  case SPxSolver::SINGULAR:
2406  case SPxSolver::REGULAR:
2407  case SPxSolver::UNKNOWN:
2408  case SPxSolver::OPTIMAL:
2409 #if SOPLEX_APIVERSION >= 3
2410  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2411 #endif
2412  case SPxSolver::UNBOUNDED:
2413  case SPxSolver::INFEASIBLE:
2414  return SCIP_OKAY;
2415  default:
2416  return SCIP_LPERROR;
2417  } /*lint !e788*/
2418 }
2419 
2420 /** calls primal simplex to solve the LP */
2422  SCIP_LPI* lpi /**< LP interface structure */
2423  )
2425  SCIPdebugMessage("calling SCIPlpiSolvePrimal()\n");
2426 
2427  assert(lpi != NULL);
2428  assert(lpi->spx != NULL);
2429 
2430  (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_PRIMAL);
2431  return spxSolve(lpi);
2432 }
2433 
2434 /** calls dual simplex to solve the LP */
2436  SCIP_LPI* lpi /**< LP interface structure */
2437  )
2439  SCIPdebugMessage("calling SCIPlpiSolveDual()\n");
2440 
2441  assert(lpi != NULL);
2442  assert(lpi->spx != NULL);
2443 
2444  (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_DUAL);
2445  return spxSolve(lpi);
2446 }
2447 
2448 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2450  SCIP_LPI* lpi, /**< LP interface structure */
2451  SCIP_Bool crossover /**< perform crossover */
2452  )
2453 { /*lint --e{715}*/
2454  assert(lpi != NULL);
2455  assert(lpi->spx != NULL);
2456 
2457  SCIPdebugMessage("calling SCIPlpiSolveBarrier()\n");
2458 
2459  /* Since SoPlex does not support barrier we switch to DUAL */
2460  return SCIPlpiSolveDual(lpi);
2461 }
2462 
2463 /** start strong branching - call before any strongbranching */
2465  SCIP_LPI* lpi /**< LP interface structure */
2466  )
2468  assert(lpi != NULL);
2469  assert(lpi->spx != NULL);
2470 
2471  assert( lpi->spx->preStrongbranchingBasisFreed() );
2472  lpi->spx->savePreStrongbranchingBasis();
2473 
2474  return SCIP_OKAY;
2475 }
2476 
2477 /** end strong branching - call after any strongbranching */
2479  SCIP_LPI* lpi /**< LP interface structure */
2480  )
2482  assert(lpi != NULL);
2483  assert(lpi->spx != NULL);
2484 
2485  assert( ! lpi->spx->preStrongbranchingBasisFreed() );
2486  lpi->spx->restorePreStrongbranchingBasis();
2487  lpi->spx->freePreStrongbranchingBasis();
2488 
2489  return SCIP_OKAY;
2490 }
2491 
2492 /** performs strong branching iterations on one arbitrary candidate */
2493 static
2495  SCIP_LPI* lpi, /**< LP interface structure */
2496  int col, /**< column to apply strong branching on */
2497  SCIP_Real psol, /**< current primal solution value of column */
2498  int itlim, /**< iteration limit for strong branchings */
2499  SCIP_Real* down, /**< stores dual bound after branching column down */
2500  SCIP_Real* up, /**< stores dual bound after branching column up */
2501  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2502  * otherwise, it can only be used as an estimate value */
2503  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2504  * otherwise, it can only be used as an estimate value */
2505  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2506  )
2507 {
2508  assert(lpi != NULL);
2509  assert(lpi->spx != NULL);
2510 
2511  SPxSCIP* spx;
2512  SPxSolver::Status status;
2513  SCIP_Real oldlb;
2514  SCIP_Real oldub;
2515  SCIP_Real newlb;
2516  SCIP_Real newub;
2517  bool fromparentbasis;
2518  bool error;
2519  int oldItlim;
2520  SPxOut::Verbosity verbosity;
2521 
2522  /* store and set verbosity */
2523  verbosity = lpi->spx->spxout.getVerbosity();
2524  lpi->spx->spxout.setVerbosity((SPxOut::Verbosity)(lpi->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
2525 
2526  SCIPdebugMessage("calling SCIPlpiStrongbranch() on variable %d (%d iterations)\n", col, itlim);
2527 
2528  assert(lpi != NULL);
2529  assert(lpi->spx != NULL);
2530  /* assert(down != NULL);
2531  * assert(up != NULL); temporary hack for cloud branching */
2532  assert(downvalid != NULL);
2533  assert(upvalid != NULL);
2534 
2535  spx = lpi->spx;
2536 #ifndef STRONGBRANCH_RESTOREBASIS
2537  fromparentbasis = false;
2538 #endif
2539  error = false;
2540  oldItlim = spx->intParam(SoPlex::ITERLIMIT);
2541 
2542  /* get current bounds of column */
2543  oldlb = spx->lowerReal(col);
2544  oldub = spx->upperReal(col);
2545 
2546  *downvalid = FALSE;
2547  *upvalid = FALSE;
2548 
2549  if( iter != NULL )
2550  *iter = 0;
2551 
2552  /* set the algorithm type to use dual simplex */
2553  (void) spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_DUAL);
2554 
2555  /* down branch */
2556  newub = EPSCEIL(psol-1.0, lpi->spx->feastol());
2557  if( newub >= oldlb - 0.5 && down != NULL )
2558  {
2559  SCIPdebugMessage("strong branching down on x%d (%g) with %d iterations\n", col, psol, itlim);
2560 
2561  spx->changeUpperReal(col, newub);
2562  assert(spx->lowerReal(col) <= spx->upperReal(col));
2563 
2564  (void) spx->setIntParam(SoPlex::ITERLIMIT, itlim);
2565  do
2566  {
2567 #ifndef STRONGBRANCH_RESTOREBASIS
2568  SCIP_Bool repeatstrongbranching;
2569 #endif
2570 #ifdef SCIP_WITH_LPSCHECK
2571  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2572 #endif
2573 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2574 #if SOPLEX_APIVERSION > 11
2575  status = spx->optimize(spx->getInterrupt());
2576 #else
2577  status = spx->optimize();
2578 #endif
2579 #else
2580  status = spx->solve();
2581 #endif
2582  SCIPdebugMessage(" --> Terminate with status %d\n", status);
2583  switch( status )
2584  {
2585  case SPxSolver::OPTIMAL:
2586  *down = spx->objValueReal();
2587  *downvalid = TRUE;
2588  SCIPdebugMessage(" --> Terminate with value %f\n", *down);
2589  break;
2590  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
2591  case SPxSolver::ABORT_ITER:
2592  case SPxSolver::ABORT_CYCLING:
2593 #if SOPLEX_APIVERSION >= 3
2594  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2595 #endif
2596  *down = spx->objValueReal();
2597  break;
2598  case SPxSolver::ABORT_VALUE:
2599  case SPxSolver::INFEASIBLE:
2600  *down = spx->getObjLimit();
2601  *downvalid = TRUE;
2602  break;
2603  default:
2604  error = true;
2605  break;
2606  } /*lint !e788*/
2607  if( iter != NULL )
2608  (*iter) += spx->numIterations();
2609 
2610 #ifdef STRONGBRANCH_RESTOREBASIS
2611  /* we restore the pre-strong-branching basis by default (and don't solve again) */
2612  assert( ! spx->preStrongbranchingBasisFreed() );
2613  spx->restorePreStrongbranchingBasis();
2614  fromparentbasis = false;
2615 #else
2616  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
2617  * pre-strong-branching basis and try again with reduced iteration limit */
2618 #if SOPLEX_APIVERSION >= 3
2619  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS
2620  || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->numIterations() < itlim);
2621 #else
2622  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR)
2623  && !fromparentbasis && spx->numIterations() < itlim);
2624 #endif
2625  if( repeatstrongbranching )
2626  {
2627  SCIPdebugMessage(" --> Repeat strong branching down with %d iterations after restoring basis\n",
2628  itlim - spx->numIterations());
2629  spx->setIntParam(SoPlex::ITERLIMIT, itlim - spx->numIterations());
2630  spx->restorePreStrongbranchingBasis();
2631  fromparentbasis = true;
2632  error = false;
2633  }
2634  /* otherwise don't solve again */
2635  else
2636  fromparentbasis = false;
2637 #endif
2638  }
2639  while( fromparentbasis );
2640 
2641  spx->changeUpperReal(col, oldub);
2642  assert(spx->lowerReal(col) <= spx->upperReal(col));
2643  }
2644  else if( down != NULL )
2645  {
2646  *down = spx->getObjLimit();
2647  *downvalid = TRUE;
2648  }
2649  else
2650  *downvalid = TRUE;
2651 
2652  /* up branch */
2653  if( !error )
2654  {
2655  newlb = EPSFLOOR(psol+1.0, lpi->spx->feastol());
2656  if( newlb <= oldub + 0.5 && up != NULL )
2657  {
2658  SCIPdebugMessage("strong branching up on x%d (%g) with %d iterations\n", col, psol, itlim);
2659 
2660  spx->changeLowerReal(col, newlb);
2661  assert(spx->lowerReal(col) <= spx->upperReal(col));
2662 
2663  (void) spx->setIntParam(SoPlex::ITERLIMIT, itlim);
2664  do
2665  {
2666 #ifndef STRONGBRANCH_RESTOREBASIS
2667  SCIP_Bool repeatstrongbranching;
2668 #endif
2669 #ifdef SCIP_WITH_LPSCHECK
2670  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2671 #endif
2672 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2673 #if SOPLEX_APIVERSION > 11
2674  status = spx->optimize(spx->getInterrupt());
2675 #else
2676  status = spx->optimize();
2677 #endif
2678 #else
2679  status = spx->solve();
2680 #endif
2681  SCIPdebugMessage(" --> Terminate with status %d\n", status);
2682  switch( status )
2683  {
2684  case SPxSolver::OPTIMAL:
2685  *up = spx->objValueReal();
2686  *upvalid = TRUE;
2687  SCIPdebugMessage(" --> Terminate with value %f\n", spx->objValueReal());
2688  break;
2689  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
2690  case SPxSolver::ABORT_ITER:
2691  case SPxSolver::ABORT_CYCLING:
2692 #if SOPLEX_APIVERSION >= 3
2693  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2694 #endif
2695  *up = spx->objValueReal();
2696  break;
2697  case SPxSolver::ABORT_VALUE:
2698  case SPxSolver::INFEASIBLE:
2699  *up = spx->getObjLimit();
2700  *upvalid = TRUE;
2701  break;
2702  default:
2703  error = true;
2704  break;
2705  } /*lint !e788*/
2706  if( iter != NULL )
2707  (*iter) += spx->numIterations();
2708 
2709 #ifdef STRONGBRANCH_RESTOREBASIS
2710  /* we restore the pre-strong-branching basis by default (and don't solve again) */
2711  assert( ! spx->preStrongbranchingBasisFreed() );
2712  spx->restorePreStrongbranchingBasis();
2713  fromparentbasis = false;
2714 #else
2715  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
2716  * pre-strong-branching basis and try again with reduced iteration limit */
2717 #if SOPLEX_APIVERSION >= 3
2718  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS
2719  || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->numIterations() < itlim);
2720 #else
2721  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR)
2722  && !fromparentbasis && spx->numIterations() < itlim);
2723 #endif
2724  if( repeatstrongbranching )
2725  {
2726  SCIPdebugMessage(" --> Repeat strong branching up with %d iterations after restoring basis\n", itlim - spx->numIterations());
2727  spx->restorePreStrongbranchingBasis();
2728  spx->setIntParam(SoPlex::ITERLIMIT, itlim - spx->numIterations());
2729  error = false;
2730  fromparentbasis = true;
2731  }
2732  /* otherwise don't solve again */
2733  else
2734  fromparentbasis = false;
2735 #endif
2736  }
2737  while( fromparentbasis );
2738 
2739  spx->changeLowerReal(col, oldlb);
2740  assert(spx->lowerReal(col) <= spx->upperReal(col));
2741  }
2742  else if( up != NULL )
2743  {
2744  *up = spx->getObjLimit();
2745  *upvalid = TRUE;
2746  }
2747  else
2748  *upvalid = TRUE;
2749  }
2750 
2751  /* reset old iteration limit */
2752  (void) spx->setIntParam(SoPlex::ITERLIMIT, oldItlim);
2753 
2754  /* restore verbosity */
2755  lpi->spx->spxout.setVerbosity(verbosity);
2756 
2757  if( error )
2758  {
2759  SCIPdebugMessage("SCIPlpiStrongbranch() returned SoPlex status %d\n", int(status)); /*lint !e644*/
2760  return SCIP_LPERROR;
2761  }
2762 
2763  return SCIP_OKAY;
2764 }
2765 
2766 /** performs strong branching iterations on one @b fractional candidate */
2768  SCIP_LPI* lpi, /**< LP interface structure */
2769  int col, /**< column to apply strong branching on */
2770  SCIP_Real psol, /**< fractional current primal solution value of column */
2771  int itlim, /**< iteration limit for strong branchings */
2772  SCIP_Real* down, /**< stores dual bound after branching column down */
2773  SCIP_Real* up, /**< stores dual bound after branching column up */
2774  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2775  * otherwise, it can only be used as an estimate value */
2776  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2777  * otherwise, it can only be used as an estimate value */
2778  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2779  )
2780 {
2781  SCIP_RETCODE retcode;
2782 
2783  /* pass call on to lpiStrongbranch() */
2784  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
2785 
2786  /* pass SCIP_LPERROR to SCIP without a back trace */
2787  if( retcode == SCIP_LPERROR )
2788  return SCIP_LPERROR;
2789 
2790  /* evaluate retcode */
2791  SCIP_CALL( retcode );
2792 
2793  return SCIP_OKAY;
2794 }
2795 
2796 /** performs strong branching iterations on given @b fractional candidates */
2798  SCIP_LPI* lpi, /**< LP interface structure */
2799  int* cols, /**< columns to apply strong branching on */
2800  int ncols, /**< number of columns */
2801  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2802  int itlim, /**< iteration limit for strong branchings */
2803  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2804  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2805  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2806  * otherwise, they can only be used as an estimate values */
2807  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2808  * otherwise, they can only be used as an estimate values */
2809  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2810  )
2811 {
2812  SCIP_RETCODE retcode;
2813 
2814  assert( cols != NULL );
2815  assert( psols != NULL );
2816  assert( down != NULL );
2817  assert( up != NULL );
2818  assert( downvalid != NULL );
2819  assert( upvalid != NULL );
2820  assert( down != NULL );
2821 
2822  if ( iter != NULL )
2823  *iter = 0;
2824 
2825  for (int j = 0; j < ncols; ++j)
2826  {
2827  /* pass call on to lpiStrongbranch() */
2828  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
2829 
2830  /* pass SCIP_LPERROR to SCIP without a back trace */
2831  if( retcode == SCIP_LPERROR )
2832  return SCIP_LPERROR;
2833 
2834  /* evaluate retcode */
2835  SCIP_CALL( retcode );
2836  }
2837  return SCIP_OKAY;
2838 }
2839 
2840 /** performs strong branching iterations on one candidate with @b integral value */
2842  SCIP_LPI* lpi, /**< LP interface structure */
2843  int col, /**< column to apply strong branching on */
2844  SCIP_Real psol, /**< current integral primal solution value of column */
2845  int itlim, /**< iteration limit for strong branchings */
2846  SCIP_Real* down, /**< stores dual bound after branching column down */
2847  SCIP_Real* up, /**< stores dual bound after branching column up */
2848  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2849  * otherwise, it can only be used as an estimate value */
2850  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2851  * otherwise, it can only be used as an estimate value */
2852  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2853  )
2854 {
2855  SCIP_RETCODE retcode;
2856 
2857  /* pass call on to lpiStrongbranch() */
2858  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
2859 
2860  /* pass SCIP_LPERROR to SCIP without a back trace */
2861  if( retcode == SCIP_LPERROR )
2862  return SCIP_LPERROR;
2863 
2864  /* evaluate retcode */
2865  SCIP_CALL( retcode );
2866 
2867  return SCIP_OKAY;
2868 }
2869 
2870 /** performs strong branching iterations on given candidates with @b integral values */
2872  SCIP_LPI* lpi, /**< LP interface structure */
2873  int* cols, /**< columns to apply strong branching on */
2874  int ncols, /**< number of columns */
2875  SCIP_Real* psols, /**< current integral primal solution values of columns */
2876  int itlim, /**< iteration limit for strong branchings */
2877  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2878  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2879  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2880  * otherwise, they can only be used as an estimate values */
2881  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2882  * otherwise, they can only be used as an estimate values */
2883  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2884  )
2885 {
2886  SCIP_RETCODE retcode;
2887 
2888  assert( cols != NULL );
2889  assert( psols != NULL );
2890  assert( down != NULL );
2891  assert( up != NULL );
2892  assert( downvalid != NULL );
2893  assert( upvalid != NULL );
2894  assert( down != NULL );
2895 
2896  if ( iter != NULL )
2897  *iter = 0;
2898 
2899  for (int j = 0; j < ncols; ++j)
2900  {
2901  /* pass call on to lpiStrongbranch() */
2902  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
2903 
2904  /* pass SCIP_LPERROR to SCIP without a back trace */
2905  if( retcode == SCIP_LPERROR )
2906  return SCIP_LPERROR;
2907 
2908  /* evaluate retcode */
2909  SCIP_CALL( retcode );
2910  }
2911 
2912  return SCIP_OKAY;
2913 }
2914 /**@} */
2915 
2916 
2917 
2918 
2919 /*
2920  * Solution Information Methods
2921  */
2922 
2923 /**@name Solution Information Methods */
2924 /**@{ */
2925 
2926 /** returns whether a solve method was called after the last modification of the LP */
2928  SCIP_LPI* lpi /**< LP interface structure */
2929  )
2931  assert(lpi != NULL);
2932 
2933  return lpi->solved;
2934 }
2935 
2936 /** gets information about primal and dual feasibility of the current LP solution
2937  *
2938  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
2939  * returns true. If the LP is changed, this information might be invalidated.
2940  *
2941  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
2942  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
2943  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
2944  * the problem might actually be feasible).
2945  */
2947  SCIP_LPI* lpi, /**< LP interface structure */
2948  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
2949  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
2950  )
2951 {
2952  SCIPdebugMessage("calling SCIPlpiGetSolFeasibility()\n");
2953 
2954  assert(lpi != NULL);
2955  assert(primalfeasible != NULL);
2956  assert(dualfeasible != NULL);
2957 
2958  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
2959  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
2960 
2961  return SCIP_OKAY;
2962 }
2963 
2964 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2965  * this does not necessarily mean, that the solver knows and can return the primal ray
2966  */
2968  SCIP_LPI* lpi /**< LP interface structure */
2969  )
2971  SCIPdebugMessage("calling SCIPlpiExistsPrimalRay()\n");
2972 
2973  assert(lpi != NULL);
2974  assert(lpi->spx != NULL);
2975 
2976  return (lpi->spx->status() == SPxSolver::UNBOUNDED);
2977 }
2978 
2979 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2980  * and the solver knows and can return the primal ray
2981  */
2983  SCIP_LPI* lpi /**< LP interface structure */
2984  )
2986  SCIPdebugMessage("calling SCIPlpiHasPrimalRay()\n");
2987 
2988  assert(lpi != NULL);
2989  assert(lpi->spx != NULL);
2990 
2991  return lpi->spx->hasPrimalRay();
2992 }
2993 
2994 /** returns TRUE iff LP is proven to be primal unbounded */
2996  SCIP_LPI* lpi /**< LP interface structure */
2997  )
2999  SCIPdebugMessage("calling SCIPlpiIsPrimalUnbounded()\n");
3000 
3001  assert(lpi != NULL);
3002  assert(lpi->spx != NULL);
3003 
3004  assert(lpi->spx->status() != SPxSolver::UNBOUNDED || lpi->spx->basisStatus() == SPxBasis::UNBOUNDED);
3005 
3006  /* if SoPlex returns unbounded, this may only mean that an unbounded ray is available, not necessarily a primal
3007  * feasible point; hence we have to check the perturbation
3008  */
3009  return lpi->spx->status() == SPxSolver::UNBOUNDED;
3010 }
3011 
3012 /** returns TRUE iff LP is proven to be primal infeasible */
3014  SCIP_LPI* lpi /**< LP interface structure */
3015  )
3017  SCIPdebugMessage("calling SCIPlpiIsPrimalInfeasible()\n");
3018 
3019  assert(lpi != NULL);
3020  assert(lpi->spx != NULL);
3021 
3022  return (lpi->spx->status() == SPxSolver::INFEASIBLE);
3023 }
3024 
3025 /** returns TRUE iff LP is proven to be primal feasible */
3027  SCIP_LPI* lpi /**< LP interface structure */
3028  )
3030  SCIPdebugMessage("calling SCIPlpiIsPrimalFeasible()\n");
3031 
3032  assert(lpi != NULL);
3033  assert(lpi->spx != NULL);
3034 
3035  return lpi->spx->basisStatus() == SPxBasis::OPTIMAL || lpi->spx->basisStatus() == SPxBasis::PRIMAL;
3036 }
3037 
3038 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3039  * this does not necessarily mean, that the solver knows and can return the dual ray
3040  */
3042  SCIP_LPI* lpi /**< LP interface structure */
3043  )
3045  SCIPdebugMessage("calling SCIPlpiExistsDualRay()\n");
3046 
3047  assert(lpi != NULL);
3048  assert(lpi->spx != NULL);
3049 
3050  return (lpi->spx->status() == SPxSolver::INFEASIBLE);
3051 }
3052 
3053 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3054  * and the solver knows and can return the dual ray
3055  */
3057  SCIP_LPI* lpi /**< LP interface structure */
3058  )
3060  SCIPdebugMessage("calling SCIPlpiHasDualRay()\n");
3061 
3062  assert(lpi != NULL);
3063  assert(lpi->spx != NULL);
3064 
3065  return lpi->spx->hasDualFarkas();
3066 }
3067 
3068 /** returns TRUE iff LP is dual unbounded */
3070  SCIP_LPI* lpi /**< LP interface structure */
3071  )
3073  SCIPdebugMessage("calling SCIPlpiIsDualUnbounded()\n");
3074 
3075  assert(lpi != NULL);
3076  assert(lpi->spx != NULL);
3077 
3078  return lpi->spx->status() == SPxSolver::INFEASIBLE && lpi->spx->basisStatus() == SPxBasis::DUAL;
3079 }
3080 
3081 /** returns TRUE iff LP is dual infeasible */
3083  SCIP_LPI* lpi /**< LP interface structure */
3084  )
3086  SCIPdebugMessage("calling SCIPlpiIsDualInfeasible()\n");
3087 
3088  assert(lpi != NULL);
3089  assert(lpi->spx != NULL);
3090 
3091  return (lpi->spx->status() == SPxSolver::UNBOUNDED);
3092 }
3093 
3094 /** returns TRUE iff LP is proven to be dual feasible */
3096  SCIP_LPI* lpi /**< LP interface structure */
3097  )
3099  SCIPdebugMessage("calling SCIPlpiIsDualFeasible()\n");
3100 
3101  assert(lpi != NULL);
3102  assert(lpi->spx != NULL);
3103 
3104  return (lpi->spx->basisStatus() == SPxBasis::OPTIMAL) || lpi->spx->basisStatus() == SPxBasis::DUAL;
3105 }
3106 
3107 /** returns TRUE iff LP was solved to optimality */
3109  SCIP_LPI* lpi /**< LP interface structure */
3110  )
3112  SCIPdebugMessage("calling SCIPlpiIsOptimal()\n");
3113 
3114  assert(lpi != NULL);
3115  assert(lpi->spx != NULL);
3116  assert((lpi->spx->basisStatus() == SPxBasis::OPTIMAL)
3118 
3119  return (lpi->spx->status() == SPxSolver::OPTIMAL);
3120 }
3121 
3122 /** returns TRUE iff current LP solution is stable
3123  *
3124  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3125  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3126  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3127  * SCIPlpiIsStable() should return false.
3128  */
3130  SCIP_LPI* lpi /**< LP interface structure */
3131  )
3133  SCIPdebugMessage("calling SCIPlpiIsStable()\n");
3134 
3135  assert(lpi != NULL);
3136  assert(lpi->spx != NULL);
3137 
3138  if( lpi->spx->status() == SPxSolver::ERROR || lpi->spx->status() == SPxSolver::SINGULAR )
3139  return FALSE;
3140 #if SOPLEX_APIVERSION >= 3
3141  if( lpi->spx->status() == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS )
3142  return FALSE;
3143 #endif
3144  /* only if we have a regular basis and the condition limit is set, we compute the condition number of the basis;
3145  * everything above the specified threshold is then counted as instable
3146  */
3147  if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3148  {
3149  SCIP_RETCODE retcode;
3150  SCIP_Real kappa;
3151 
3153  if( retcode != SCIP_OKAY )
3154  {
3155  SCIPABORT();
3156  }
3157  assert(kappa != SCIP_INVALID); /*lint !e777*/
3158 
3159  if( kappa > lpi->conditionlimit )
3160  return FALSE;
3161  }
3162  return TRUE;
3163 }
3164 
3165 /** returns TRUE iff the objective limit was reached */
3167  SCIP_LPI* lpi /**< LP interface structure */
3168  )
3170  SCIPdebugMessage("calling SCIPlpiIsObjlimExc()\n");
3171 
3172  assert(lpi != NULL);
3173  assert(lpi->spx != NULL);
3174 
3175  return (lpi->spx->status() == SPxSolver::ABORT_VALUE);
3176 }
3177 
3178 /** returns TRUE iff the iteration limit was reached */
3180  SCIP_LPI* lpi /**< LP interface structure */
3181  )
3183  SCIPdebugMessage("calling SCIPlpiIsIterlimExc()\n");
3184 
3185  assert(lpi != NULL);
3186  assert(lpi->spx != NULL);
3187 
3188  return (lpi->spx->status() == SPxSolver::ABORT_ITER);
3189 }
3190 
3191 /** returns TRUE iff the time limit was reached */
3193  SCIP_LPI* lpi /**< LP interface structure */
3194  )
3196  SCIPdebugMessage("calling SCIPlpiIsTimelimExc()\n");
3197 
3198  assert(lpi != NULL);
3199  assert(lpi->spx != NULL);
3200 
3201  return (lpi->spx->status() == SPxSolver::ABORT_TIME);
3202 }
3203 
3204 /** returns the internal solution status of the solver */
3206  SCIP_LPI* lpi /**< LP interface structure */
3207  )
3209  SCIPdebugMessage("calling SCIPlpiGetInternalStatus()\n");
3210 
3211  assert(lpi != NULL);
3212  assert(lpi->spx != NULL);
3213 
3214  return static_cast<int>(lpi->spx->status());
3215 }
3216 
3217 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3219  SCIP_LPI* lpi, /**< LP interface structure */
3220  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3221  )
3222 { /*lint --e{715}*/
3223  SCIPdebugMessage("calling SCIPlpiIgnoreInstability()\n");
3224 
3225  assert(lpi != NULL);
3226  assert(lpi->spx != NULL);
3227  assert(success != NULL);
3228 
3229 #if SOPLEX_APIVERSION >= 4
3230  *success = lpi->spx->ignoreUnscaledViolations();
3231 #else
3232  *success = FALSE;
3233 #endif
3234 
3235  return SCIP_OKAY;
3236 }
3237 
3238 /** gets objective value of solution */
3240  SCIP_LPI* lpi, /**< LP interface structure */
3241  SCIP_Real* objval /**< stores the objective value */
3242  )
3243 {
3244  SCIPdebugMessage("calling SCIPlpiGetObjval()\n");
3245 
3246  assert(lpi != NULL);
3247  assert(lpi->spx != NULL);
3248  assert(objval != NULL);
3249 
3250  *objval = lpi->spx->objValueReal();
3251 
3252  return SCIP_OKAY;
3253 }
3254 
3255 /** gets primal and dual solution vectors for feasible LPs
3256  *
3257  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
3258  * SCIPlpiIsOptimal() returns true.
3259  */
3261  SCIP_LPI* lpi, /**< LP interface structure */
3262  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3263  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3264  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3265  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3266  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3267  )
3268 {
3269  SCIPdebugMessage("calling SCIPlpiGetSol()\n");
3270 
3271  assert(lpi != NULL);
3272  assert(lpi->spx != NULL);
3273 
3274  if( objval != NULL )
3275  *objval = lpi->spx->objValueReal();
3276 
3277  try
3278  {
3279  if( primsol != NULL )
3280  {
3281 #if SOPLEX_APIVERSION > 10
3282  (void)lpi->spx->getPrimalReal(primsol, lpi->spx->numColsReal());
3283 #else
3284  Vector tmp(lpi->spx->numColsReal(), primsol);
3285  (void)lpi->spx->getPrimalReal(tmp);
3286 #endif
3287  }
3288  if( dualsol != NULL )
3289  {
3290 #if SOPLEX_APIVERSION > 10
3291  (void)lpi->spx->getDualReal(dualsol, lpi->spx->numRowsReal());
3292 #else
3293  Vector tmp(lpi->spx->numRowsReal(), dualsol);
3294  (void)lpi->spx->getDualReal(tmp);
3295 #endif
3296  }
3297  if( activity != NULL )
3298  {
3299 #if SOPLEX_APIVERSION > 10
3300  (void)lpi->spx->getSlacksReal(activity, lpi->spx->numRowsReal()); /* in SoPlex, the activities are called "slacks" */
3301 #else
3302  Vector tmp(lpi->spx->numRowsReal(), activity);
3303  (void)lpi->spx->getSlacksReal(tmp); /* in SoPlex, the activities are called "slacks" */
3304 #endif
3305  }
3306  if( redcost != NULL )
3307  {
3308 #if SOPLEX_APIVERSION > 10
3309  (void)lpi->spx->getRedCostReal(redcost, lpi->spx->numColsReal());
3310 #else
3311  Vector tmp(lpi->spx->numColsReal(), redcost);
3312  (void)lpi->spx->getRedCostReal(tmp);
3313 #endif
3314  }
3315  }
3316 #ifndef NDEBUG
3317  catch( const SPxException& x )
3318  {
3319  std::string s = x.what();
3320  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3321 #else
3322  catch( const SPxException& )
3323  {
3324 #endif
3325  return SCIP_LPERROR;
3326  }
3327 
3328  return SCIP_OKAY;
3329 }
3330 
3331 /** gets primal ray for unbounded LPs */
3333  SCIP_LPI* lpi, /**< LP interface structure */
3334  SCIP_Real* ray /**< primal ray */
3335  )
3336 { /*lint --e{715}*/
3337  SCIPdebugMessage("calling SCIPlpiGetPrimalRay()\n");
3338 
3339  assert(lpi != NULL);
3340  assert(lpi->spx != NULL);
3341  assert(lpi->spx->hasPrimalRay());
3342  assert(ray != NULL);
3343 
3344  try
3345  {
3346 #if SOPLEX_APIVERSION > 10
3347  (void)lpi->spx->getPrimalRayReal(ray, lpi->spx->numColsReal());
3348 #else
3349  Vector tmp(lpi->spx->numColsReal(), ray);
3350  (void)lpi->spx->getPrimalRayReal(tmp);
3351 #endif
3352  }
3353 #ifndef NDEBUG
3354  catch( const SPxException& x )
3355  {
3356  std::string s = x.what();
3357  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3358 #else
3359  catch( const SPxException& )
3360  {
3361 #endif
3362  return SCIP_LPERROR;
3363  }
3364 
3365  return SCIP_OKAY;
3366 }
3367 
3368 /** gets dual farkas proof for infeasibility */
3370  SCIP_LPI* lpi, /**< LP interface structure */
3371  SCIP_Real* dualfarkas /**< dual farkas row multipliers */
3372  )
3373 {
3374  SCIPdebugMessage("calling SCIPlpiGetDualfarkas()\n");
3375 
3376  assert(lpi != NULL);
3377  assert(lpi->spx != NULL);
3378  assert(lpi->spx->hasDualFarkas());
3379  assert(dualfarkas != NULL);
3380 
3381  try
3382  {
3383 #if SOPLEX_APIVERSION > 10
3384  (void)lpi->spx->getDualFarkasReal(dualfarkas, lpi->spx->numRowsReal());
3385 #else
3386  Vector tmp(lpi->spx->numRowsReal(), dualfarkas);
3387  (void)lpi->spx->getDualFarkasReal(tmp);
3388 #endif
3389  }
3390 #ifndef NDEBUG
3391  catch( const SPxException& x )
3392  {
3393  std::string s = x.what();
3394  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3395 #else
3396  catch( const SPxException& )
3397  {
3398 #endif
3399  return SCIP_LPERROR;
3400  }
3401 
3402  return SCIP_OKAY;
3403 }
3404 
3405 /** gets the number of LP iterations of the last solve call */
3407  SCIP_LPI* lpi, /**< LP interface structure */
3408  int* iterations /**< pointer to store the number of iterations of the last solve call */
3409  )
3410 {
3411  SCIPdebugMessage("calling SCIPlpiGetIterations()\n");
3412 
3413  assert(lpi != NULL);
3414  assert(lpi->spx != NULL);
3415  assert(iterations != NULL);
3416 
3417  *iterations = lpi->spx->numIterations();
3418 
3419  return SCIP_OKAY;
3420 }
3421 
3422 /** gets information about the quality of an LP solution
3423  *
3424  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3425  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3426  */
3428  SCIP_LPI* lpi, /**< LP interface structure */
3429  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3430  SCIP_Real* quality /**< pointer to store quality number */
3431  )
3432 {
3433  SCIPdebugMessage("calling SCIPlpiGetRealSolQuality()\n");
3434 
3435  assert(lpi != NULL);
3436  assert(quality != NULL);
3437 
3438  bool success;
3439 
3440  SCIPdebugMessage("requesting solution quality from SoPlex: quality %d\n", qualityindicator);
3441 
3442  switch( qualityindicator )
3443  {
3445  success = lpi->spx->getEstimatedCondition(*quality);
3446  break;
3447 
3449  success = lpi->spx->getExactCondition(*quality);
3450  break;
3451 
3452  default:
3453  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3454  return SCIP_INVALIDDATA;
3455  }
3456 
3457  if( !success )
3458  {
3459  SCIPdebugMessage("problem computing condition number\n");
3460  *quality = SCIP_INVALID;
3461  }
3462 
3463  return SCIP_OKAY;
3464 }
3465 
3466 /**@} */
3467 
3468 
3469 
3470 
3471 /*
3472  * LP Basis Methods
3473  */
3474 
3475 /**@name LP Basis Methods */
3476 /**@{ */
3477 
3478 
3479 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3481  SCIP_LPI* lpi, /**< LP interface structure */
3482  int* cstat, /**< array to store column basis status, or NULL */
3483  int* rstat /**< array to store row basis status, or NULL */
3484  )
3485 {
3486  int i;
3487 
3488  SCIPdebugMessage("calling SCIPlpiGetBase()\n");
3489 
3490  assert(lpi != NULL);
3491  assert(lpi->spx != NULL);
3492 
3493  assert( lpi->spx->preStrongbranchingBasisFreed() );
3494 
3495  if( rstat != NULL )
3496  {
3497  for( i = 0; i < lpi->spx->numRowsReal(); ++i )
3498  {
3499  switch( lpi->spx->basisRowStatus(i) )
3500  {
3501  case SPxSolver::BASIC:
3502  rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3503  break;
3504  case SPxSolver::FIXED:
3505  case SPxSolver::ON_LOWER:
3506  rstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3507  break;
3508  case SPxSolver::ON_UPPER:
3509  rstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3510  break;
3511  case SPxSolver::ZERO:
3512  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
3513  return SCIP_LPERROR;
3514  case SPxSolver::UNDEFINED:
3515  default:
3516  SCIPerrorMessage("invalid basis status\n");
3517  SCIPABORT();
3518  return SCIP_INVALIDDATA; /*lint !e527*/
3519  }
3520  }
3521  }
3522 
3523  if( cstat != NULL )
3524  {
3525  for( i = 0; i < lpi->spx->numColsReal(); ++i )
3526  {
3527 // SCIP_Real val = 0.0;
3528  switch( lpi->spx->basisColStatus(i) )
3529  {
3530  case SPxSolver::BASIC:
3531  cstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3532  break;
3533  case SPxSolver::FIXED:
3534  /* Get reduced cost estimation. If the estimation is not correct this should not hurt:
3535  * If the basis is loaded into SoPlex again, the status is converted to FIXED again; in
3536  * this case there is no problem at all. If the basis is saved and/or used in some other
3537  * solver, it usually is very cheap to perform the pivots necessary to get an optimal
3538  * basis.
3539  * @todo implement getRedCostEst()
3540  * */
3541 // SCIP_CALL( getRedCostEst(lpi->spx, i, &val) );
3542 // if( val < 0.0 ) /* reduced costs < 0 => UPPER else => LOWER */
3543 // cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3544 // else
3545  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3546  break;
3547  case SPxSolver::ON_LOWER:
3548  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3549  break;
3550  case SPxSolver::ON_UPPER:
3551  cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3552  break;
3553  case SPxSolver::ZERO:
3554  cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
3555  break;
3556  case SPxSolver::UNDEFINED:
3557  default:
3558  SCIPerrorMessage("invalid basis status\n");
3559  SCIPABORT();
3560  return SCIP_INVALIDDATA; /*lint !e527*/
3561  }
3562  }
3563  }
3564 
3565  return SCIP_OKAY;
3566 }
3567 
3568 /** sets current basis status for columns and rows */
3570  SCIP_LPI* lpi, /**< LP interface structure */
3571  const int* cstat, /**< array with column basis status */
3572  const int* rstat /**< array with row basis status */
3573  )
3574 {
3575  int i;
3576  int ncols;
3577  int nrows;
3578 
3579  SCIPdebugMessage("calling SCIPlpiSetBase()\n");
3580 
3581  assert(lpi != NULL);
3582  assert(lpi->spx != NULL);
3583 
3584  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3585  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3586 
3587  assert(cstat != NULL || ncols == 0);
3588  assert(rstat != NULL || nrows == 0);
3589 
3590  assert( lpi->spx->preStrongbranchingBasisFreed() );
3591  invalidateSolution(lpi);
3592 
3593  DataArray<SPxSolver::VarStatus>& _colstat = lpi->spx->colStat();
3594  DataArray<SPxSolver::VarStatus>& _rowstat = lpi->spx->rowStat();
3595 
3596  _colstat.reSize(ncols);
3597  _rowstat.reSize(nrows);
3598 
3599  for( i = 0; i < nrows; ++i )
3600  {
3601  switch( rstat[i] ) /*lint !e613*/
3602  {
3603  case SCIP_BASESTAT_LOWER:
3604  _rowstat[i] = SPxSolver::ON_LOWER;
3605  break;
3606  case SCIP_BASESTAT_BASIC:
3607  _rowstat[i] = SPxSolver::BASIC;
3608  break;
3609  case SCIP_BASESTAT_UPPER:
3610  _rowstat[i] = SPxSolver::ON_UPPER;
3611  break;
3612  case SCIP_BASESTAT_ZERO:
3613  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
3614  return SCIP_LPERROR; /*lint !e429*/
3615  default:
3616  SCIPerrorMessage("invalid basis status\n");
3617  SCIPABORT();
3618  return SCIP_INVALIDDATA; /*lint !e527*/
3619  }
3620  }
3621 
3622  for( i = 0; i < ncols; ++i )
3623  {
3624  switch( cstat[i] ) /*lint !e613*/
3625  {
3626  case SCIP_BASESTAT_LOWER:
3627  _colstat[i] = SPxSolver::ON_LOWER;
3628  break;
3629  case SCIP_BASESTAT_BASIC:
3630  _colstat[i] = SPxSolver::BASIC;
3631  break;
3632  case SCIP_BASESTAT_UPPER:
3633  _colstat[i] = SPxSolver::ON_UPPER;
3634  break;
3635  case SCIP_BASESTAT_ZERO:
3636  _colstat[i] = SPxSolver::ZERO;
3637  break;
3638  default:
3639  SCIPerrorMessage("invalid basis status\n");
3640  SCIPABORT();
3641  return SCIP_INVALIDDATA; /*lint !e527*/
3642  }
3643  }
3644 
3645  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setBasis(_rowstat.get_ptr(), _colstat.get_ptr()) );
3646  lpi->spx->freePreStrongbranchingBasis();
3647 
3648  return SCIP_OKAY;
3649 }
3650 
3651 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3653  SCIP_LPI* lpi, /**< LP interface structure */
3654  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3655  )
3656 {
3657  SCIPdebugMessage("calling SCIPlpiGetBasisInd()\n");
3658 
3659  assert(lpi != NULL);
3660  assert(lpi->spx != NULL);
3661  assert(bind != NULL);
3662 
3663  assert(lpi->spx->preStrongbranchingBasisFreed());
3664 
3665  lpi->spx->getBasisInd(bind);
3666 
3667  return SCIP_OKAY;
3668 }
3669 
3670 
3671 /** get row of inverse basis matrix B^-1
3672  *
3673  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3674  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3675  * see also the explanation in lpi.h.
3676  */
3678  SCIP_LPI* lpi, /**< LP interface structure */
3679  int r, /**< row number */
3680  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3681  int* inds, /**< array to store the non-zero indices, or NULL */
3682  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3683  * (-1: if we do not store sparsity information) */
3684  )
3685 {
3686  SCIPdebugMessage("calling SCIPlpiGetBInvRow()\n");
3687 
3688  assert(lpi != NULL);
3689  assert(lpi->spx != NULL);
3690  assert(lpi->spx->preStrongbranchingBasisFreed());
3691  assert(coef != NULL);
3692 
3693  assert(r >= 0);
3694  assert(r < lpi->spx->numRowsReal());
3695 
3696  if( ! lpi->spx->getBasisInverseRowReal(r, coef, inds, ninds) )
3697  return SCIP_LPERROR;
3698 
3699  return SCIP_OKAY;
3700 }
3701 
3702 /** get column of inverse basis matrix B^-1
3703  *
3704  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3705  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3706  * see also the explanation in lpi.h.
3707  */
3709  SCIP_LPI* lpi, /**< LP interface structure */
3710  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3711  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3712  * B^-1 column numbers to the row and column numbers of the LP!
3713  * c must be between 0 and nrows-1, since the basis has the size
3714  * nrows * nrows */
3715  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3716  int* inds, /**< array to store the non-zero indices, or NULL */
3717  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3718  * (-1: if we do not store sparsity information) */
3719  )
3720 {
3721  SCIPdebugMessage("calling SCIPlpiGetBInvCol()\n");
3722 
3723  assert( lpi != NULL );
3724  assert( lpi->spx != NULL );
3725  assert( lpi->spx->preStrongbranchingBasisFreed() );
3726  assert(coef != NULL);
3727 
3728  if( ! lpi->spx->getBasisInverseColReal(c, coef, inds, ninds) )
3729  return SCIP_LPERROR;
3730 
3731  return SCIP_OKAY;
3732 }
3733 
3734 /** get row of inverse basis matrix times constraint matrix B^-1 * A
3735  *
3736  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3737  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3738  * see also the explanation in lpi.h.
3739  */
3741  SCIP_LPI* lpi, /**< LP interface structure */
3742  int r, /**< row number */
3743  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3744  SCIP_Real* coef, /**< vector to return coefficients of the row */
3745  int* inds, /**< array to store the non-zero indices, or NULL */
3746  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3747  * (-1: if we do not store sparsity information) */
3748  )
3749 {
3750  SCIP_Real* buf;
3751  SCIP_Real* binv;
3752  int nrows;
3753  int ncols;
3754  int c;
3755 
3756  SCIPdebugMessage("calling SCIPlpiGetBInvARow()\n");
3757 
3758  assert(lpi != NULL);
3759  assert(lpi->spx != NULL);
3760  assert( lpi->spx->preStrongbranchingBasisFreed() );
3761  assert(coef != NULL);
3762 
3763  nrows = lpi->spx->numRowsReal();
3764  ncols = lpi->spx->numColsReal();
3765  buf = NULL;
3766 
3767  /* get (or calculate) the row in B^-1 */
3768  if( binvrow == NULL )
3769  {
3770  SCIP_ALLOC( BMSallocMemoryArray(&buf, nrows) );
3771  SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buf, inds, ninds) );
3772  binv = buf;
3773  }
3774  else
3775  binv = const_cast<SCIP_Real*>(binvrow);
3776 
3777  assert(binv != NULL);
3778 
3779  /* mark sparsity pattern as invalid */
3780  if( ninds != NULL )
3781  *ninds = -1;
3782 
3783  // @todo exploit sparsity in binv by looping over nrows
3784  /* calculate the scalar product of the row in B^-1 and A */
3785  Vector binvvec(nrows, binv);
3786 
3787 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3788  /* temporary unscaled column of A */
3789  DSVector acol;
3790 #endif
3791 
3792  for( c = 0; c < ncols; ++c )
3793  {
3794 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3795  lpi->spx->getColVectorReal(c, acol);
3796  coef[c] = binvvec * acol; /* scalar product */ /*lint !e1702*/
3797 #else
3798  coef[c] = binvvec * lpi->spx->colVectorReal(c); /* scalar product */ /*lint !e1702*/
3799 #endif
3800  }
3801 
3802  /* free memory if it was temporarily allocated */
3803  BMSfreeMemoryArrayNull(&buf);
3804 
3805  return SCIP_OKAY;
3806 }
3807 
3808 /** get column of inverse basis matrix times constraint matrix B^-1 * A
3809  *
3810  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3811  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3812  * see also the explanation in lpi.h.
3813  */
3815  SCIP_LPI* lpi, /**< LP interface structure */
3816  int c, /**< column number */
3817  SCIP_Real* coef, /**< vector to return coefficients of the column */
3818  int* inds, /**< array to store the non-zero indices, or NULL */
3819  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3820  * (-1: if we do not store sparsity information) */
3821  )
3822 { /*lint --e{715}*/
3823  /* create a new uninitialized full vector */
3824  DVector col(lpi->spx->numRowsReal());
3825 
3826 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3827  /* temporary sparse vector used for unscaling (memory is automatically enlarged) */
3828  DSVector colsparse;
3829 #endif
3830 
3831  SCIPdebugMessage("calling SCIPlpiGetBInvACol()\n");
3832 
3833  assert( lpi != NULL );
3834  assert( lpi->spx != NULL );
3835  assert( lpi->spx->preStrongbranchingBasisFreed() );
3836  assert(coef != NULL);
3837 
3838  /* extract column c of A */
3839  assert(c >= 0);
3840  assert(c < lpi->spx->numColsReal());
3841 
3842  /* @todo implement this with sparse vectors */
3843  /* mark sparsity pattern as invalid */
3844  if( ninds != NULL )
3845  *ninds = -1;
3846 
3847  /* col needs to be cleared because copying colVectorReal only regards nonzeros */
3848  col.clear();
3849 
3850 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3851  lpi->spx->getColVectorReal(c, colsparse);
3852  /* the copy is necessary to transform the sparse column into a dense vector */
3853  col = colsparse;
3854 #else
3855  col = lpi->spx->colVectorReal(c);
3856 #endif
3857 
3858  /* solve */
3859  if( ! lpi->spx->getBasisInverseTimesVecReal(col.get_ptr(), coef) )
3860  return SCIP_LPERROR;
3861 
3862  return SCIP_OKAY;
3863 }
3864 
3865 /**@} */
3866 
3867 
3868 
3869 
3870 /*
3871  * LP State Methods
3872  */
3873 
3874 /**@name LP State Methods */
3875 /**@{ */
3876 
3877 /** stores LPi state (like basis information) into lpistate object */
3879  SCIP_LPI* lpi, /**< LP interface structure */
3880  BMS_BLKMEM* blkmem, /**< block memory */
3881  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3882  )
3883 {
3884  int ncols;
3885  int nrows;
3886 
3887  SCIPdebugMessage("calling SCIPlpiGetState()\n");
3888 
3889  assert(blkmem != NULL);
3890  assert(lpi != NULL);
3891  assert(lpi->spx != NULL);
3892  assert(lpistate != NULL);
3893 
3894  assert( lpi->spx->preStrongbranchingBasisFreed() );
3895 
3896  ncols = lpi->spx->numColsReal();
3897  nrows = lpi->spx->numRowsReal();
3898  assert(ncols >= 0);
3899  assert(nrows >= 0);
3900 
3901  /* allocate lpistate data */
3902  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3903 
3904  /* allocate enough memory for storing uncompressed basis information */
3905  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3906  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3907 
3908  /* get unpacked basis information */
3909  SCIP_CALL( SCIPlpiGetBase(lpi, lpi->cstat, lpi->rstat) );
3910 
3911  /* pack LPi state data */
3912  (*lpistate)->ncols = ncols;
3913  (*lpistate)->nrows = nrows;
3914  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3915 
3916  return SCIP_OKAY;
3917 }
3918 
3919 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3920  * columns and rows since the state was stored with SCIPlpiGetState()
3921  */
3923  SCIP_LPI* lpi, /**< LP interface structure */
3924  BMS_BLKMEM* /*blkmem*/, /**< block memory */
3925  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
3926  )
3927 {
3928  int lpncols;
3929  int lpnrows;
3930  int i;
3931 
3932  SCIPdebugMessage("calling SCIPlpiSetState()\n");
3933 
3934  assert(lpi != NULL);
3935  assert(lpi->spx != NULL);
3936  assert(lpistate != NULL);
3937  /* assert(blkmem != NULL); */
3938 
3939  assert( lpi->spx->preStrongbranchingBasisFreed() );
3940 
3941  lpncols = lpi->spx->numColsReal();
3942  lpnrows = lpi->spx->numRowsReal();
3943  assert(lpistate->ncols <= lpncols);
3944  assert(lpistate->nrows <= lpnrows);
3945 
3946  /* allocate enough memory for storing uncompressed basis information */
3947  SCIP_CALL( ensureCstatMem(lpi, lpncols) );
3948  SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
3949 
3950  /* unpack LPi state data */
3951  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3952 
3953  /* extend the basis to the current LP beyond the previously existing columns */
3954  for( i = lpistate->ncols; i < lpncols; ++i )
3955  {
3956  SCIP_Real bnd = lpi->spx->lowerReal(i);
3957  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3958  {
3959  /* if lower bound is +/- infinity -> try upper bound */
3960  bnd = lpi->spx->lowerReal(i);
3961  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3962  /* variable is free */
3963  lpi->cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
3964  else
3965  /* use finite upper bound */
3966  lpi->cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3967  }
3968  else
3969  /* use finite lower bound */
3970  lpi->cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3971  }
3972  for( i = lpistate->nrows; i < lpnrows; ++i )
3973  lpi->rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3974 
3975  /* load basis information */
3976  SCIP_CALL( SCIPlpiSetBase(lpi, lpi->cstat, lpi->rstat) );
3977 
3978  return SCIP_OKAY;
3979 }
3980 
3981 /** clears current LPi state (like basis information) of the solver */
3983  SCIP_LPI* lpi /**< LP interface structure */
3984  )
3985 { /*lint --e{715}*/
3986  SCIPdebugMessage("calling SCIPlpiClearState()\n");
3987 
3988  assert(lpi != NULL);
3989  assert(lpi->spx != NULL);
3990 
3991  try
3992  {
3993  lpi->spx->clearBasis();
3994  }
3995 #ifndef NDEBUG
3996  catch( const SPxException& x )
3997  {
3998  std::string s = x.what();
3999  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4000 #else
4001  catch( const SPxException& )
4002  {
4003 #endif
4004  assert( lpi->spx->status() != SPxSolver::OPTIMAL );
4005  return SCIP_LPERROR;
4006  }
4007 
4008  return SCIP_OKAY;
4009 }
4010 
4011 /** frees LPi state information */
4013  SCIP_LPI* lpi, /**< LP interface structure */
4014  BMS_BLKMEM* blkmem, /**< block memory */
4015  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4016  )
4017 { /*lint --e{715}*/
4018  SCIPdebugMessage("calling SCIPlpiFreeState()\n");
4019 
4020  assert(lpi != NULL);
4021  assert(lpistate != NULL);
4022  assert(blkmem != NULL);
4023 
4024  if ( *lpistate != NULL )
4025  lpistateFree(lpistate, blkmem);
4026 
4027  return SCIP_OKAY;
4028 }
4029 
4030 /** checks, whether the given LP state contains simplex basis information */
4032  SCIP_LPI* lpi, /**< LP interface structure */
4033  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4034  )
4035 { /*lint --e{715}*/
4036  assert(lpi != NULL);
4037  return TRUE;
4038 }
4039 
4040 /** reads LP state (like basis information from a file */
4042  SCIP_LPI* lpi, /**< LP interface structure */
4043  const char* fname /**< file name */
4044  )
4045 {
4046  SCIPdebugMessage("calling SCIPlpiReadState()\n");
4047  assert(lpi != NULL);
4048  assert(lpi->spx != NULL);
4049  assert(fname != NULL);
4050 
4051  assert( lpi->spx->preStrongbranchingBasisFreed() );
4052 
4053  bool success;
4054  SOPLEX_TRY( lpi->messagehdlr, success = lpi->spx->readBasisFile(fname, 0, 0) );
4055 
4056  return success ? SCIP_OKAY : SCIP_LPERROR;
4057 }
4058 
4059 /** writes LPi state (i.e. basis information) to a file */
4061  SCIP_LPI* lpi, /**< LP interface structure */
4062  const char* fname /**< file name */
4063  )
4064 {
4065  assert(lpi != NULL);
4066  assert(lpi->spx != NULL);
4067  assert(fname != NULL);
4068  SCIPdebugMessage("calling SCIPlpiWriteState()\n");
4069 
4070  assert( lpi->spx->preStrongbranchingBasisFreed() );
4071 
4072  bool res;
4073  SOPLEX_TRY( lpi->messagehdlr, res = lpi->spx->writeBasisFile(fname, 0, 0) );
4074 
4075  if ( ! res )
4076  return SCIP_LPERROR;
4077 
4078  return SCIP_OKAY;
4079 }
4080 
4081 /**@} */
4082 
4083 
4084 
4085 
4086 /*
4087  * LP Pricing Norms Methods
4088  */
4089 
4090 /**@name LP Pricing Norms Methods */
4091 /**@{ */
4092 
4093 /** stores LPi pricing norms information
4094  * @todo should we store norm information?
4095  */
4097  SCIP_LPI* lpi, /**< LP interface structure */
4098  BMS_BLKMEM* blkmem, /**< block memory */
4099  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4100  )
4101 { /*lint --e{715}*/
4102 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4103  int nrows;
4104  int ncols;
4105 
4106  assert(blkmem != NULL);
4107  assert(lpi != NULL);
4108  assert(lpi->spx != NULL);
4109  assert(lpinorms != NULL);
4110 
4111  lpi->spx->getNdualNorms(nrows, ncols);
4112 
4113  if( nrows == 0 && ncols == 0)
4114  {
4115  (*lpinorms = NULL);
4116  return SCIP_OKAY;
4117  }
4118 
4119  /* allocate lpinorms data */
4120  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4121  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols) );
4122  (*lpinorms)->nrows = 0;
4123  (*lpinorms)->ncols = 0;
4124 
4125  SCIPdebugMessage("storing SoPlex LPi pricing norms in %p (%d rows, %d cols)\n", (void *) *lpinorms, nrows, ncols);
4126 
4127  if( !lpi->spx->getDualNorms((*lpinorms)->nrows, (*lpinorms)->ncols, (*lpinorms)->norms) )
4128  {
4129  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
4130  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols);
4131  BMSfreeBlockMemory(blkmem, lpinorms);
4132  assert(*lpinorms == NULL);
4133  }
4134 #ifndef NDEBUG
4135  else
4136  {
4137  assert(nrows == (*lpinorms)->nrows);
4138  assert(ncols == (*lpinorms)->ncols);
4139  }
4140 #endif
4141 #else
4142  (*lpinorms) = NULL;
4143 #endif
4144 
4145  return SCIP_OKAY;
4146 }
4147 
4148 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4149  * columns and rows since the state was stored with SCIPlpiGetNorms()
4150  */
4152  SCIP_LPI* lpi, /**< LP interface structure */
4153  BMS_BLKMEM* blkmem, /**< block memory */
4154  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
4155  )
4156 { /*lint --e{715}*/
4157 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4158  assert(blkmem != NULL);
4159  assert(lpi != NULL);
4160  assert(lpi->spx != NULL);
4161 
4162  /* if there was no pricing norms information available, the LPi norms were not stored */
4163  if( lpinorms == NULL )
4164  return SCIP_OKAY;
4165 
4166  assert(lpinorms->nrows <= lpi->spx->numRowsReal());
4167  assert(lpinorms->ncols <= lpi->spx->numColsReal());
4168 
4169  if( lpinorms->nrows == 0 )
4170  return SCIP_OKAY;
4171 
4172  SCIPdebugMessage("loading LPi simplex norms %p (%d rows, %d cols) into SoPlex LP with %d rows and %d cols\n",
4173  (const void *) lpinorms, lpinorms->nrows, lpinorms->ncols, lpi->spx->numRowsReal(), lpi->spx->numColsReal());
4174 
4175  (void) lpi->spx->setDualNorms(lpinorms->nrows, lpinorms->ncols, lpinorms->norms);
4176 #endif
4177 
4178  return SCIP_OKAY;
4179 }
4180 
4181 /** frees pricing norms information */
4183  SCIP_LPI* lpi, /**< LP interface structure */
4184  BMS_BLKMEM* blkmem, /**< block memory */
4185  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
4186  )
4187 { /*lint --e{715}*/
4188 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4189  assert(lpi != NULL);
4190  assert(lpinorms != NULL);
4191 
4192  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
4193 
4194  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, (*lpinorms)->nrows + (*lpinorms)->ncols);
4195  BMSfreeBlockMemory(blkmem, lpinorms);
4196  assert(*lpinorms == NULL);
4197 #endif
4198 
4199  return SCIP_OKAY;
4200 }
4201 
4202 /**@} */
4203 
4204 
4205 
4206 
4207 /*
4208  * Parameter Methods
4209  */
4210 
4211 /**@name Parameter Methods */
4212 /**@{ */
4213 
4214 /** gets integer parameter of LP */
4216  SCIP_LPI* lpi, /**< LP interface structure */
4217  SCIP_LPPARAM type, /**< parameter number */
4218  int* ival /**< buffer to store the parameter value */
4219  )
4220 {
4221  int scaleparam;
4222 
4223  SCIPdebugMessage("calling SCIPlpiGetIntpar()\n");
4224 
4225  assert(lpi != NULL);
4226  assert(lpi->spx != NULL);
4227  assert(ival != NULL);
4228 
4229  switch( type )
4230  {
4232  *ival = lpi->spx->getFromScratch();
4233  break;
4234  case SCIP_LPPAR_LPINFO:
4235  *ival = lpi->spx->getLpInfo();
4236  break;
4237  case SCIP_LPPAR_LPITLIM:
4238  *ival = lpi->spx->intParam(SoPlex::ITERLIMIT);
4239  if( *ival == -1 )
4240  *ival = INT_MAX;
4241  break;
4242  case SCIP_LPPAR_PRESOLVING:
4243  *ival = lpi->spx->intParam(SoPlex::SIMPLIFIER);
4244  break;
4245  case SCIP_LPPAR_PRICING:
4246  *ival = (int) lpi->pricing;
4247  break;
4248  case SCIP_LPPAR_SCALING:
4249  scaleparam = lpi->spx->intParam(SoPlex::SCALER);
4250 
4251  if( scaleparam == SoPlex::SCALER_OFF )
4252  *ival = 0;
4253  else if( scaleparam == SoPlex::SCALER_BIEQUI )
4254  *ival = 1;
4255 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
4256  else
4257  {
4258  assert(scaleparam == SoPlex::SCALER_LEASTSQ);
4259  *ival = 2;
4260  }
4261 #else
4262  else
4263  {
4264  assert(scaleparam == SoPlex::SCALER_GEO8);
4265  *ival = 2;
4266  }
4267 #endif
4268  break;
4269 #if SOPLEX_VERSION >= 201
4270  case SCIP_LPPAR_TIMING:
4271  *ival = (int) (lpi->spx->intParam(SoPlex::TIMER));
4272  break;
4273 #endif
4274 #if SOPLEX_VERSION >= 230 || (SOPLEX_VERSION == 220 && SOPLEX_SUBVERSION >= 3)
4275  case SCIP_LPPAR_RANDOMSEED:
4276  *ival = (int) lpi->spx->randomSeed();
4277  break;
4278 #endif
4279 #if SOPLEX_APIVERSION >= 1
4280  case SCIP_LPPAR_REFACTOR:
4281  *ival = (int) lpi->spx->intParam(SoPlex::FACTOR_UPDATE_MAX);
4282  break;
4283 #endif
4284  default:
4285  return SCIP_PARAMETERUNKNOWN;
4286  } /*lint !e788*/
4287 
4288  return SCIP_OKAY;
4289 }
4290 
4291 /** sets integer parameter of LP */
4293  SCIP_LPI* lpi, /**< LP interface structure */
4294  SCIP_LPPARAM type, /**< parameter number */
4295  int ival /**< parameter value */
4296  )
4297 {
4298  SCIPdebugMessage("calling SCIPlpiSetIntpar()\n");
4299 
4300  assert(lpi != NULL);
4301  assert(lpi->spx != NULL);
4302 
4303  switch( type )
4304  {
4306  assert(ival == TRUE || ival == FALSE);
4307  lpi->spx->setFromScratch(bool(ival));
4308  break;
4309  case SCIP_LPPAR_LPINFO:
4310  assert(ival == TRUE || ival == FALSE);
4311  lpi->spx->setLpInfo(bool(ival));
4312  break;
4313  case SCIP_LPPAR_LPITLIM:
4314  assert( ival >= 0 );
4315  /* -1 <= ival, -1 meaning no time limit, 0 stopping immediately */
4316  if( ival >= INT_MAX )
4317  ival = -1;
4318  (void) lpi->spx->setIntParam(SoPlex::ITERLIMIT, ival);
4319  break;
4320  case SCIP_LPPAR_PRESOLVING:
4321  assert(ival == TRUE || ival == FALSE);
4322 #if SOPLEX_APIVERSION < 13
4323  assert(ival == TRUE || ival == FALSE);
4324 #else
4325  assert(ival == 1 || ival == 0 || ival == 2);
4326 #endif
4327  (void) lpi->spx->setIntParam(SoPlex::SIMPLIFIER, ival);
4328  break;
4329  case SCIP_LPPAR_PRICING:
4330  lpi->pricing = (SCIP_PRICING)ival;
4331  switch( lpi->pricing )
4332  {
4334  case SCIP_PRICING_AUTO:
4335  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_AUTO);
4336  break;
4337  case SCIP_PRICING_FULL:
4338  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_STEEP);
4339  break;
4340  case SCIP_PRICING_PARTIAL:
4341  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_PARMULT);
4342  break;
4343  case SCIP_PRICING_STEEP:
4344  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_STEEP);
4345  break;
4347  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_QUICKSTEEP);
4348  break;
4349  case SCIP_PRICING_DEVEX:
4350  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_DEVEX);
4351  break;
4352  default:
4353  return SCIP_LPERROR;
4354  }
4355  break;
4356  case SCIP_LPPAR_SCALING:
4357  assert(ival >= 0 && ival <= 2);
4358  if( ival == 0 )
4359  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_OFF);
4360  else if( ival == 1 )
4361  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_BIEQUI);
4362  else
4363 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
4364  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_LEASTSQ);
4365 #else
4366  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_GEO8);
4367 #endif
4368 
4369  break;
4370 #if SOPLEX_VERSION >= 201
4371  case SCIP_LPPAR_TIMING:
4372  assert(ival >= 0 && ival < 3);
4373  (void) lpi->spx->setIntParam(SoPlex::TIMER, ival);
4374  break;
4375 #endif
4376 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3)
4377  case SCIP_LPPAR_RANDOMSEED:
4378  lpi->spx->setRandomSeed((unsigned long)(long)ival);
4379  break;
4380 #endif
4381 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION >= 221 && SOPLEX_SUBVERSION >= 3)
4382  case SCIP_LPPAR_POLISHING:
4383  assert(ival >= 0 && ival < 3);
4384  (void) lpi->spx->setIntParam(SoPlex::SOLUTION_POLISHING, ival);
4385  break;
4386 #endif
4387 #if SOPLEX_APIVERSION >= 1
4388  case SCIP_LPPAR_REFACTOR:
4389  assert(ival >= 0);
4390  (void) lpi->spx->setIntParam(SoPlex::FACTOR_UPDATE_MAX, ival);
4391  break;
4392 #endif
4393 
4394  default:
4395  return SCIP_PARAMETERUNKNOWN;
4396  } /*lint !e788*/
4397 
4398  return SCIP_OKAY;
4399 }
4400 
4401 /** gets floating point parameter of LP */
4403  SCIP_LPI* lpi, /**< LP interface structure */
4404  SCIP_LPPARAM type, /**< parameter number */
4405  SCIP_Real* dval /**< buffer to store the parameter value */
4406  )
4407 {
4408  SCIPdebugMessage("calling SCIPlpiGetRealpar()\n");
4409 
4410  assert(lpi != NULL);
4411  assert(lpi->spx != NULL);
4412  assert(dval != NULL);
4413 
4414  switch( type )
4415  {
4416  case SCIP_LPPAR_FEASTOL:
4417  *dval = lpi->spx->feastol();
4418  break;
4420  *dval = lpi->spx->opttol();
4421  break;
4422  case SCIP_LPPAR_OBJLIM:
4423  if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
4424  *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_UPPER);
4425  else
4426  *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_LOWER);
4427  break;
4428  case SCIP_LPPAR_LPTILIM:
4429  *dval = lpi->spx->realParam(SoPlex::TIMELIMIT);
4430  break;
4432  *dval = lpi->spx->realParam(SoPlex::REPRESENTATION_SWITCH);
4433  if( *dval >= SCIPlpiInfinity(lpi) )
4434  *dval = -1.0;
4435  break;
4437  *dval = lpi->conditionlimit;
4438  break;
4439  case SCIP_LPPAR_MARKOWITZ:
4440 #if (SOPLEX_APIVERSION >= 9)
4441  *dval = lpi->spx->realParam(SoPlex::MIN_MARKOWITZ);
4442  break;
4443 #endif
4444  default:
4445  return SCIP_PARAMETERUNKNOWN;
4446  } /*lint !e788*/
4447 
4448  return SCIP_OKAY;
4449 }
4450 
4451 /** sets floating point parameter of LP */
4453  SCIP_LPI* lpi, /**< LP interface structure */
4454  SCIP_LPPARAM type, /**< parameter number */
4455  SCIP_Real dval /**< parameter value */
4456  )
4457 {
4458  SCIPdebugMessage("calling SCIPlpiSetRealpar()\n");
4459 
4460  assert(lpi != NULL);
4461  assert(lpi->spx != NULL);
4462 
4463  switch( type )
4464  {
4465  case SCIP_LPPAR_FEASTOL:
4466  /* 0 < dval */
4467  assert( dval > 0.0 );
4468  lpi->spx->setFeastol(dval);
4469  break;
4471  /* 0 < dval */
4472  assert( dval > 0.0 );
4473  lpi->spx->setOpttol(dval);
4474  break;
4475  case SCIP_LPPAR_OBJLIM:
4476  /* no restrictions on dval */
4477  if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
4478  (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_UPPER, dval);
4479  else
4480  (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_LOWER, dval);
4481  break;
4482  case SCIP_LPPAR_LPTILIM:
4483  assert( dval > 0.0 );
4484  /* soplex requires 0 < dval < DEFAULT_INFINITY (= 1e100), -1 means unlimited */
4485  (void) lpi->spx->setRealParam(SoPlex::TIMELIMIT, dval);
4486  break;
4488  /* 0 <= dval <= inf */
4489  assert( dval >= 0.0 || dval == -1.0 );
4490  if( dval == -1 )
4491  (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, SCIPlpiInfinity(lpi));
4492  else
4493  (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, dval);
4494  break;
4496  lpi->conditionlimit = dval;
4497  lpi->checkcondition = (dval >= 0.0);
4498  break;
4499  case SCIP_LPPAR_MARKOWITZ:
4500 #if (SOPLEX_APIVERSION >= 9)
4501  /* 1e-4 <= dval <= 0.999 */
4502  if( dval < 1e-4 )
4503  dval = 1e-4;
4504  else if( dval > 0.9999 )
4505  dval = 0.9999;
4506 
4507  (void) lpi->spx->setRealParam(SoPlex::MIN_MARKOWITZ, dval);
4508  break;
4509 #endif
4510  default:
4511  return SCIP_PARAMETERUNKNOWN;
4512  } /*lint !e788*/
4513 
4514  return SCIP_OKAY;
4515 }
4516 
4517 /** interrupts the currently ongoing lp solve or disables the interrupt */
4519  SCIP_LPI* lpi, /**< LP interface structure */
4520  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
4521  )
4522 {
4523  assert(lpi != NULL);
4524  assert(lpi->spx != NULL);
4525 
4526  lpi->spx->setInterrupt(interrupt);
4527 
4528  return SCIP_OKAY;
4529 }
4530 
4531 /**@} */
4532 
4533 
4534 
4535 
4536 /*
4537  * Numerical Methods
4538  */
4539 
4540 /**@name Numerical Methods */
4541 /**@{ */
4542 
4543 /** returns value treated as infinity in the LP solver */
4545  SCIP_LPI* lpi /**< LP interface structure */
4546  )
4548  assert(lpi != NULL);
4549  SCIPdebugMessage("calling SCIPlpiInfinity()\n");
4550 
4551  return lpi->spx->realParam(SoPlex::INFTY);
4552 }
4553 
4554 /** checks if given value is treated as infinity in the LP solver */
4556  SCIP_LPI* lpi, /**< LP interface structure */
4557  SCIP_Real val
4558  )
4559 {
4560  assert(lpi != NULL);
4561  SCIPdebugMessage("calling SCIPlpiIsInfinity()\n");
4562 
4563  return (val >= lpi->spx->realParam(SoPlex::INFTY));
4564 }
4565 
4566 /**@} */
4567 
4568 
4569 
4570 
4571 /*
4572  * File Interface Methods
4573  */
4574 
4575 /**@name File Interface Methods */
4576 /**@{ */
4577 
4578 /** returns, whether the given file exists */
4579 static
4581  const char* filename /**< file name */
4582  )
4584  FILE* f;
4585 
4586  f = fopen(filename, "r");
4587  if( f == NULL )
4588  return FALSE;
4589 
4590  fclose(f);
4591 
4592  return TRUE;
4593 }
4594 
4595 /** reads LP from a file */
4597  SCIP_LPI* lpi, /**< LP interface structure */
4598  const char* fname /**< file name */
4599  )
4600 {
4601  SCIPdebugMessage("calling SCIPlpiReadLP()\n");
4602 
4603  assert(lpi != NULL);
4604  assert(lpi->spx != NULL);
4605  assert(fname != NULL);
4606 
4607  assert( lpi->spx->preStrongbranchingBasisFreed() );
4608 
4609  if( !fileExists(fname) )
4610  return SCIP_NOFILE;
4611 
4612  try
4613  {
4614  assert(lpi->spx->intParam(SoPlex::READMODE) == SoPlex::READMODE_REAL);
4615  if( !lpi->spx->readFile(fname) )
4616  return SCIP_READERROR;
4617  }
4618 #ifndef NDEBUG
4619  catch( const SPxException& x )
4620  {
4621  std::string s = x.what();
4622  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4623 #else
4624  catch( const SPxException& )
4625  {
4626 #endif
4627  return SCIP_READERROR;
4628  }
4629 
4630  return SCIP_OKAY;
4631 }
4632 
4633 /** writes LP to a file */
4635  SCIP_LPI* lpi, /**< LP interface structure */
4636  const char* fname /**< file name */
4637  )
4638 {
4639  SCIPdebugMessage("calling SCIPlpiWriteLP()\n");
4640 
4641  assert(lpi != NULL);
4642  assert(lpi->spx != NULL);
4643  assert(fname != NULL);
4644 
4645  try
4646  {
4647  (void) lpi->spx->writeFileReal(fname);
4648  }
4649 #ifndef NDEBUG
4650  catch( const SPxException& x )
4651  {
4652  std::string s = x.what();
4653  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4654 #else
4655  catch( const SPxException& )
4656  {
4657 #endif
4658  return SCIP_WRITEERROR;
4659  }
4660 
4661  return SCIP_OKAY;
4662 }
4663 
4664 /**@} */
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3711
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_spx2.cpp:1879
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:95
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_spx2.cpp:1124
SCIP_Real conditionlimit
Definition: lpi_cpx.c:164
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *, const SCIP_LPISTATE *lpistate)
Definition: lpi_spx2.cpp:3925
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_spx2.cpp:4558
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3072
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_spx2.cpp:4154
ROWPACKET * packrstat
Definition: lpi_clp.cpp:128
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_spx2.cpp:3372
SCIP_PRICING pricing
Definition: lpi_clp.cpp:103
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2467
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_spx2.cpp:3263
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_spx2.cpp:4295
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2424
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:1005
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_spx2.cpp:3483
SCIP_Bool solved
Definition: lpi_clp.cpp:105
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:299
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_spx2.cpp:1579
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_spx2.cpp:4218
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_spx2.cpp:3409
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_spx2.cpp:901
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_spx2.cpp:1913
#define FALSE
Definition: def.h:87
static int rowpacketNum(int nrows)
Definition: lpi_spx2.cpp:860
static SCIP_RETCODE optimize(SCIP *scip, SCIP_SOL *worksol, SCIP_VAR **vars, int *blockstart, int *blockend, int nblocks, OPTTYPE opttype, SCIP_Real *activities, int nrows, SCIP_Bool *improvement, SCIP_Bool *varboundserr, SCIP_HEURDATA *heurdata)
Definition: heur_twoopt.c:914
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:952
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
int rstatsize
Definition: lpi_clp.cpp:101
SCIP_Bool checkcondition
Definition: lpi_cpx.c:165
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_spx2.cpp:4455
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2985
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx2.cpp:4099
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_spx2.cpp:1896
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4044
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_spx2.cpp:1042
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_spx2.cpp:2258
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:1502
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_spx2.cpp:3430
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_spx2.cpp:1790
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_spx2.cpp:2218
#define SOPLEX_VERBLEVEL
Definition: lpi_spx2.cpp:125
#define BMSfreeMemory(ptr)
Definition: memory.h:138
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_spx2.cpp:1013
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_spx2.cpp:925
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3985
SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_spx2.cpp:1954
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_spx2.cpp:1070
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_spx2.cpp:822
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3743
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_spx2.cpp:1235
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2998
#define ROWS_PER_PACKET
Definition: lpi_spx2.cpp:756
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3208
#define SOPLEX_TRY(messagehdlr, x)
Definition: lpi_spx2.cpp:146
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2438
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3132
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_spx2.cpp:1371
polyscip::Polyscip::PolyscipStatus Status
abbreviation
Definition: main.cpp:29
#define COLS_PER_PACKET
Definition: lpi_spx2.cpp:754
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4637
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_spx2.cpp:800
packing single and dual bit values
static int colpacketNum(int ncols)
Definition: lpi_spx2.cpp:851
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_spx2.cpp:3655
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_spx2.cpp:2800
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx2.cpp:4015
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3016
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_spx2.cpp:2166
static char spxname[100]
Definition: lpi_spx2.cpp:969
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_spx2.cpp:2770
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
SCIP_Real * norms
Definition: lpi_qso.c:76
#define NULL
Definition: lpi_spx2.cpp:135
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_spx2.cpp:2874
int * rstat
Definition: lpi_clp.cpp:99
#define REALABS(x)
Definition: def.h:201
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_spx2.cpp:991
int cstatsize
Definition: lpi_clp.cpp:100
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_spx2.cpp:1050
static void setIntParam(SCIP_LPI *lpi, int const param, int const parval)
Definition: lpi_cpx.c:644
static SCIP_RETCODE lpiStrongbranch(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_spx2.cpp:2497
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_spx2.cpp:2949
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx2.cpp:4185
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_spx2.cpp:1449
static SCIP_Bool fileExists(const char *filename)
Definition: lpi_spx2.cpp:4583
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:229
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4599
#define EPSCEIL(x, eps)
Definition: def.h:211
#define CHECK_SOPLEX_PARAM(x)
Definition: lpi_spx2.cpp:75
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2930
#define SOPLEX_SUBVERSION
Definition: lpi_spx2.cpp:95
COLPACKET * packcstat
Definition: lpi_clp.cpp:127
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2970
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_spx2.cpp:3242
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx2.cpp:1471
#define SCIP_Bool
Definition: def.h:84
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_spx2.cpp:4034
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_spx2.cpp:1317
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4063
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:4547
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_spx2.cpp:1628
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3098
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx2.cpp:3881
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3085
#define BMSallocMemoryCPP(size)
Definition: memory.h:114
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:460
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_spx2.cpp:2192
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_spx2.cpp:869
static SCIP_RETCODE spxSolve(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2352
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_spx2.cpp:3572
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3111
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_spx2.cpp:1034
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_spx2.cpp:1520
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3195
SCIP_Real * r
Definition: circlepacking.c:50
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_spx2.cpp:2062
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_spx2.cpp:2844
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_spx2.cpp:2452
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_spx2.cpp:3335
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2481
SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_spx2.cpp:1157
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_spx2.cpp:1716
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_spx2.cpp:2286
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_spx2.cpp:885
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3059
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3817
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_spx2.cpp:2235
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3169
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3029
SCIP_DUALPACKET COLPACKET
Definition: lpi_spx2.cpp:753
SPxSCIP * spx
Definition: lpi_spx1.cpp:1398
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:197
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:120
SCIP_DUALPACKET ROWPACKET
Definition: lpi_spx2.cpp:755
#define SOPLEX_TRY_ABORT(x)
Definition: lpi_spx2.cpp:191
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_spx2.cpp:1672
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3044
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
static char spxdesc[200]
Definition: lpi_spx2.cpp:970
#define UNKNOWN
Definition: sepa_mcf.c:4095
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_spx2.cpp:4521
struct fixed_graph_components FIXED
Definition: graphdefs.h:119
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3182
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_spx2.cpp:2314
#define EPSFLOOR(x, eps)
Definition: def.h:210
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_spx2.cpp:1652
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3680
#define SCIP_ALLOC(x)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:356
const char * SCIPlpiGetSolverName(void)
Definition: lpi_spx2.cpp:976
int * cstat
Definition: lpi_clp.cpp:98
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_spx2.cpp:3221
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_spx2.cpp:4405
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx2.cpp:1339
#define FEASTOL
Definition: lpi_qso.c:90