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 char* initSpxDesc( );
967 
968 #if (SOPLEX_SUBVERSION > 0)
969  const static char spxname[20] = {'S', 'o', 'p', 'l', 'e', 'x', ' ', SOPLEX_VERSION/100 + '0', '.', (SOPLEX_VERSION % 100)/10 + '0', '.', SOPLEX_VERSION % 10 + '0', '.', SOPLEX_SUBVERSION + '0'};
970 #else
971  const static char spxname[20] = {'S', 'o', 'p', 'l', 'e', 'x', ' ', SOPLEX_VERSION/100 + '0', '.', (SOPLEX_VERSION % 100)/10 + '0', '.', SOPLEX_VERSION % 10 + '0'};
972 #endif
973 static char* spxdesc = initSpxDesc();
975 char* initSpxDesc( )
976 {
977  spxdesc = new char[200];
978  (void)snprintf(spxdesc, 200, "%s [GitHash: %s]", "Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de)"
979 #ifdef SCIP_WITH_LPSCHECK
980  " - including CPLEX double check"
981 #endif
982  , getGitHash());
983  return spxdesc;
984 }
985 
986 /**@name Miscellaneous Methods */
987 /**@{ */
988 
989 /** gets name and version of LP solver */
990 const char* SCIPlpiGetSolverName(
991  void
992  )
993 {
994  SCIPdebugMessage("calling SCIPlpiGetSolverName()\n");
995  return spxname;
996 }
997 
998 /** gets description of LP solver (developer, webpage, ...) */
999 const char* SCIPlpiGetSolverDesc(
1000  void
1001  )
1003  return spxdesc;
1004 }
1005 
1006 /** gets pointer for LP solver - use only with great care */
1008  SCIP_LPI* lpi /**< pointer to an LP interface structure */
1009  )
1011  return (void*) lpi->spx;
1012 }
1013 
1014 /** pass integrality information about variables to the solver */
1016  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
1017  int ncols, /**< length of integrality array */
1018  int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
1019  )
1020 {
1021  assert( lpi != NULL );
1022  assert( ncols >= 0 );
1023  assert( ncols == 0 || intInfo != NULL );
1024 
1025 #if (SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3))
1026  assert(ncols == lpi->spx->numColsReal() || (ncols == 0 && intInfo == NULL));
1027  lpi->spx->setIntegralityInformation(ncols, intInfo);
1028  return SCIP_OKAY;
1029 #else
1030  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1031  return SCIP_LPERROR;
1032 #endif
1033 }
1034 
1035 /** informs about availability of a primal simplex solving method */
1037  void
1038  )
1040  return TRUE;
1041 }
1042 
1043 /** informs about availability of a dual simplex solving method */
1045  void
1046  )
1048  return TRUE;
1049 }
1050 
1051 /** informs about availability of a barrier solving method */
1053  void
1054  )
1056  return FALSE;
1057 }
1058 
1059 /**@} */
1060 
1061 
1062 
1063 
1064 /*
1065  * LPI Creation and Destruction Methods
1066  */
1067 
1068 /**@name LPI Creation and Destruction Methods */
1069 /**@{ */
1070 
1071 /** creates an LP problem object */
1073  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1074  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1075  const char* name, /**< problem name */
1076  SCIP_OBJSEN objsen /**< objective sense */
1077  )
1078 {
1079  assert(lpi != NULL);
1080  assert(name != NULL);
1081 
1082  /* create SoPlex object */
1083  SCIP_ALLOC( BMSallocMemory(lpi) );
1084 
1085  /* we use this construction to allocate the memory for the SoPlex class also via the blockmemshell */
1086  (*lpi)->spx = static_cast<SPxSCIP*>(BMSallocMemoryCPP(sizeof(SPxSCIP)));
1087  SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxSCIP(messagehdlr, name) );
1088  (void) (*lpi)->spx->setIntParam(SoPlex::SYNCMODE, SoPlex::SYNCMODE_ONLYREAL);
1089  (void) (*lpi)->spx->setIntParam(SoPlex::SOLVEMODE, SoPlex::SOLVEMODE_REAL);
1090  (void) (*lpi)->spx->setIntParam(SoPlex::REPRESENTATION, SoPlex::REPRESENTATION_AUTO);
1091 
1092  /* disable time-measurement for statistics */
1093 #if SOPLEX_APIVERSION >= 10
1094  (void) (*lpi)->spx->setIntParam(SoPlex::STATTIMER, 0);
1095 #endif
1096 
1097  (*lpi)->cstat = NULL;
1098  (*lpi)->rstat = NULL;
1099  (*lpi)->cstatsize = 0;
1100  (*lpi)->rstatsize = 0;
1101  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1102  (*lpi)->conditionlimit = -1.0;
1103  (*lpi)->checkcondition = FALSE;
1104  (*lpi)->messagehdlr = messagehdlr;
1105 
1106  invalidateSolution(*lpi);
1107 
1108  /* set objective sense */
1109  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1110 
1111  /* set default pricing */
1112  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
1113 
1114  {
1115  (*lpi)->spx->setInterrupt(FALSE);
1116  SPxOut::Verbosity verbosity = (*lpi)->spx->spxout.getVerbosity();
1117  (*lpi)->spx->spxout.setVerbosity((SPxOut::Verbosity)((*lpi)->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
1118  (*lpi)->spx->printVersion();
1119  (*lpi)->spx->spxout.setVerbosity(verbosity);
1120  }
1121 
1122  return SCIP_OKAY;
1123 }
1124 
1125 /** deletes an LP problem object */
1127  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1128  )
1130  assert(lpi != NULL);
1131  assert(*lpi != NULL);
1132  assert((*lpi)->spx != NULL);
1133 
1134  /* free LP using destructor and free memory via blockmemshell */
1135  (*lpi)->spx->~SPxSCIP();
1136  BMSfreeMemory(&((*lpi)->spx));
1137 
1138  /* free memory */
1139  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1140  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1141  BMSfreeMemory(lpi);
1142 
1143  return SCIP_OKAY;
1144 }
1145 
1146 /**@} */
1147 
1148 
1149 
1150 
1151 /*
1152  * Modification Methods
1153  */
1154 
1155 /**@name Modification Methods */
1156 /**@{ */
1157 
1158 /** copies LP data with column matrix into LP solver */
1160  SCIP_LPI* lpi, /**< LP interface structure */
1161  SCIP_OBJSEN objsen, /**< objective sense */
1162  int ncols, /**< number of columns */
1163  const SCIP_Real* obj, /**< objective function values of columns */
1164  const SCIP_Real* lb, /**< lower bounds of columns */
1165  const SCIP_Real* ub, /**< upper bounds of columns */
1166  char** colnames, /**< column names, or NULL */
1167  int nrows, /**< number of rows */
1168  const SCIP_Real* lhs, /**< left hand sides of rows */
1169  const SCIP_Real* rhs, /**< right hand sides of rows */
1170  char** /*rownames*/, /**< row names, or NULL */
1171  int nnonz, /**< number of nonzero elements in the constraint matrix */
1172  const int* beg, /**< start index of each column in ind- and val-array */
1173  const int* ind, /**< row indices of constraint matrix entries */
1174  const SCIP_Real* val /**< values of constraint matrix entries */
1175  )
1176 {
1177 #ifndef NDEBUG
1178  {
1179  int j;
1180  for( j = 0; j < nnonz; j++ )
1181  assert( val[j] != 0 );
1182  }
1183 #endif
1184 
1185  SCIPdebugMessage("calling SCIPlpiLoadColLP()\n");
1186 
1187  assert(lpi != NULL);
1188  assert(lpi->spx != NULL);
1189  assert(lhs != NULL);
1190  assert(rhs != NULL);
1191  assert(obj != NULL);
1192  assert(lb != NULL);
1193  assert(ub != NULL);
1194  assert(beg != NULL);
1195  assert(ind != NULL);
1196  assert(val != NULL);
1197 
1198  invalidateSolution(lpi);
1199  assert(lpi->spx->preStrongbranchingBasisFreed());
1200 
1201  try
1202  {
1203  SPxSCIP* spx = lpi->spx;
1204  LPRowSet rows(nrows);
1205  DSVector emptyVector(0);
1206  int i;
1207 
1208  spx->clearLPReal();
1209 
1210  /* set objective sense */
1211  (void) spx->setIntParam(SoPlex::OBJSENSE, (objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE));
1212 
1213  /* create empty rows with given sides */
1214  for( i = 0; i < nrows; ++i )
1215  rows.add(lhs[i], emptyVector, rhs[i]);
1216  spx->addRowsReal(rows);
1217 
1218  /* create column vectors with coefficients and bounds */
1219  SCIP_CALL( SCIPlpiAddCols(lpi, ncols, obj, lb, ub, colnames, nnonz, beg, ind, val) );
1220  }
1221 #ifndef NDEBUG
1222  catch( const SPxException& x )
1223  {
1224  std::string s = x.what();
1225  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1226 #else
1227  catch( const SPxException& )
1228  {
1229 #endif
1230  return SCIP_LPERROR;
1231  }
1232 
1233  return SCIP_OKAY;
1234 }
1235 
1236 /** adds columns to the LP */
1238  SCIP_LPI* lpi, /**< LP interface structure */
1239  int ncols, /**< number of columns to be added */
1240  const SCIP_Real* obj, /**< objective function values of new columns */
1241  const SCIP_Real* lb, /**< lower bounds of new columns */
1242  const SCIP_Real* ub, /**< upper bounds of new columns */
1243  char** /*colnames*/, /**< column names, or NULL */
1244  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1245  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1246  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1247  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1248  )
1249 {
1250  SCIPdebugMessage("calling SCIPlpiAddCols()\n");
1251 
1252  assert(lpi != NULL);
1253  assert(lpi->spx != NULL);
1254  assert(obj != NULL);
1255  assert(lb != NULL);
1256  assert(ub != NULL);
1257  assert(nnonz == 0 || beg != NULL);
1258  assert(nnonz == 0 || ind != NULL);
1259  assert(nnonz == 0 || val != NULL);
1260  assert(nnonz >= 0);
1261  assert(ncols >= 0);
1262 
1263  invalidateSolution(lpi);
1264 
1265  assert( lpi->spx->preStrongbranchingBasisFreed() );
1266 
1267 #ifndef NDEBUG
1268  if ( nnonz > 0 )
1269  {
1270  /* perform check that no new rows are added - this is likely to be a mistake */
1271  int nrows = lpi->spx->numRowsReal();
1272  for (int j = 0; j < nnonz; ++j)
1273  {
1274  assert( 0 <= ind[j] && ind[j] < nrows );
1275  assert( val[j] != 0.0 );
1276  }
1277  }
1278 #endif
1279 
1280  SPxSCIP* spx = lpi->spx;
1281  try
1282  {
1283  LPColSet cols(ncols);
1284  DSVector colVector(ncols);
1285  int start;
1286  int last;
1287  int i;
1288 
1289  /* create column vectors with coefficients and bounds */
1290  for( i = 0; i < ncols; ++i )
1291  {
1292  colVector.clear();
1293  if( nnonz > 0 )
1294  {
1295  start = beg[i];
1296  last = (i == ncols-1 ? nnonz : beg[i+1]);
1297  colVector.add( last-start, &ind[start], &val[start] );
1298  }
1299  cols.add(obj[i], lb[i], colVector, ub[i]);
1300  }
1301  spx->addColsReal(cols);
1302  }
1303 #ifndef NDEBUG
1304  catch( const SPxException& x )
1305  {
1306  std::string s = x.what();
1307  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1308 #else
1309  catch( const SPxException& )
1310  {
1311 #endif
1312  return SCIP_LPERROR;
1313  }
1314 
1315  return SCIP_OKAY;
1316 }
1317 
1318 /** deletes all columns in the given range from LP */
1320  SCIP_LPI* lpi, /**< LP interface structure */
1321  int firstcol, /**< first column to be deleted */
1322  int lastcol /**< last column to be deleted */
1323  )
1324 {
1325  SCIPdebugMessage("calling SCIPlpiDelCols()\n");
1326 
1327  assert(lpi != NULL);
1328  assert(lpi->spx != NULL);
1329  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
1330 
1331  invalidateSolution(lpi);
1332 
1333  assert( lpi->spx->preStrongbranchingBasisFreed() );
1334 
1335  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColRangeReal(firstcol, lastcol) );
1336 
1337  return SCIP_OKAY;
1338 }
1339 
1340 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1342  SCIP_LPI* lpi, /**< LP interface structure */
1343  int* dstat /**< deletion status of columns
1344  * input: 1 if column should be deleted, 0 if not
1345  * output: new position of column, -1 if column was deleted */
1346  )
1347 {
1348  int ncols;
1349  int i;
1350 
1351  SCIPdebugMessage("calling SCIPlpiDelColset()\n");
1352 
1353  assert(lpi != NULL);
1354  assert(lpi->spx != NULL);
1355  assert(dstat != NULL);
1356 
1357  invalidateSolution(lpi);
1358 
1359  assert( lpi->spx->preStrongbranchingBasisFreed() );
1360 
1361  ncols = lpi->spx->numColsReal();
1362 
1363  /* SoPlex removeCols() method deletes the columns with dstat[i] < 0, so we have to negate the values */
1364  for( i = 0; i < ncols; ++i )
1365  dstat[i] *= -1;
1366 
1367  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColsReal(dstat) );
1368 
1369  return SCIP_OKAY;
1370 }
1371 
1372 /** adds rows to the LP */
1374  SCIP_LPI* lpi, /**< LP interface structure */
1375  int nrows, /**< number of rows to be added */
1376  const SCIP_Real* lhs, /**< left hand sides of new rows */
1377  const SCIP_Real* rhs, /**< right hand sides of new rows */
1378  char** /*rownames*/, /**< row names, or NULL */
1379  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1380  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1381  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1382  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1383  )
1384 {
1385  SCIPdebugMessage("calling SCIPlpiAddRows()\n");
1386 
1387  assert(lpi != NULL);
1388  assert(lpi->spx != NULL);
1389  assert(lhs != NULL);
1390  assert(rhs != NULL);
1391  assert(nnonz == 0 || beg != NULL);
1392  assert(nnonz == 0 || ind != NULL);
1393  assert(nnonz == 0 || val != NULL);
1394 
1395  invalidateSolution(lpi);
1396 
1397  assert( lpi->spx->preStrongbranchingBasisFreed() );
1398 
1399 #ifndef NDEBUG
1400  if ( nnonz > 0 )
1401  {
1402  /* perform check that no new columns are added - this is likely to be a mistake */
1403  int ncols = lpi->spx->numColsReal();
1404  for (int j = 0; j < nnonz; ++j)
1405  {
1406  assert( val[j] != 0.0 );
1407  assert( 0 <= ind[j] && ind[j] < ncols );
1408  }
1409  }
1410 #endif
1411 
1412  try
1413  {
1414  SPxSCIP* spx = lpi->spx;
1415  LPRowSet rows(nrows);
1416  DSVector rowVector;
1417  int start;
1418  int last;
1419  int i;
1420 
1421  /* create row vectors with given sides */
1422  for( i = 0; i < nrows; ++i )
1423  {
1424  rowVector.clear();
1425  if( nnonz > 0 )
1426  {
1427  start = beg[i];
1428  last = (i == nrows-1 ? nnonz : beg[i+1]);
1429  rowVector.add( last-start, &ind[start], &val[start] );
1430  }
1431  rows.add(lhs[i], rowVector, rhs[i]);
1432  }
1433  spx->addRowsReal(rows);
1434  }
1435 #ifndef NDEBUG
1436  catch( const SPxException& x )
1437  {
1438  std::string s = x.what();
1439  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1440 #else
1441  catch( const SPxException& )
1442  {
1443 #endif
1444  return SCIP_LPERROR;
1445  }
1446 
1447  return SCIP_OKAY;
1448 }
1449 
1450 /** deletes all rows in the given range from LP */
1452  SCIP_LPI* lpi, /**< LP interface structure */
1453  int firstrow, /**< first row to be deleted */
1454  int lastrow /**< last row to be deleted */
1455  )
1456 {
1457  SCIPdebugMessage("calling SCIPlpiDelRows()\n");
1458 
1459  assert(lpi != NULL);
1460  assert(lpi->spx != NULL);
1461  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
1462 
1463  invalidateSolution(lpi);
1464 
1465  assert( lpi->spx->preStrongbranchingBasisFreed() );
1466 
1467  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowRangeReal(firstrow, lastrow) );
1468 
1469  return SCIP_OKAY;
1470 }
1471 
1472 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1474  SCIP_LPI* lpi, /**< LP interface structure */
1475  int* dstat /**< deletion status of rows
1476  * input: 1 if row should be deleted, 0 if not
1477  * output: new position of row, -1 if row was deleted */
1478  )
1479 {
1480  int nrows;
1481  int i;
1482 
1483  SCIPdebugMessage("calling SCIPlpiDelRowset()\n");
1484 
1485  assert(lpi != NULL);
1486  assert(lpi->spx != NULL);
1487 
1488  invalidateSolution(lpi);
1489 
1490  assert( lpi->spx->preStrongbranchingBasisFreed() );
1491 
1492  nrows = lpi->spx->numRowsReal();
1493 
1494  /* SoPlex removeRows() method deletes the rows with dstat[i] < 0, so we have to negate the values */
1495  for( i = 0; i < nrows; ++i )
1496  dstat[i] *= -1;
1497 
1498  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowsReal(dstat) );
1499 
1500  return SCIP_OKAY;
1501 }
1502 
1503 /** clears the whole LP */
1505  SCIP_LPI* lpi /**< LP interface structure */
1506  )
1508  SCIPdebugMessage("calling SCIPlpiClear()\n");
1509 
1510  assert(lpi != NULL);
1511  assert(lpi->spx != NULL);
1512 
1513  invalidateSolution(lpi);
1514 
1515  assert( lpi->spx->preStrongbranchingBasisFreed() );
1516  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->clearLPReal() );
1517 
1518  return SCIP_OKAY;
1519 }
1520 
1521 /** changes lower and upper bounds of columns */
1523  SCIP_LPI* lpi, /**< LP interface structure */
1524  int ncols, /**< number of columns to change bounds for */
1525  const int* ind, /**< column indices or NULL if ncols is zero */
1526  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1527  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1528  )
1529 {
1530  int i;
1531 
1532  SCIPdebugMessage("calling SCIPlpiChgBounds()\n");
1533 
1534  assert(lpi != NULL);
1535  assert(lpi->spx != NULL);
1536  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1537  if( ncols <= 0 )
1538  return SCIP_OKAY;
1539 
1540  invalidateSolution(lpi);
1541 
1542  assert( lpi->spx->preStrongbranchingBasisFreed() );
1543 
1544  try
1545  {
1546  for( i = 0; i < ncols; ++i )
1547  {
1548  assert(0 <= ind[i] && ind[i] < lpi->spx->numColsReal());
1549 
1550  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
1551  {
1552  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
1553  return SCIP_LPERROR;
1554  }
1555  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
1556  {
1557  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
1558  return SCIP_LPERROR;
1559  }
1560 
1561  lpi->spx->changeBoundsReal(ind[i], lb[i], ub[i]);
1562  assert(lpi->spx->lowerReal(ind[i]) <= lpi->spx->upperReal(ind[i]) + lpi->spx->realParam(SoPlex::EPSILON_ZERO));
1563  }
1564  }
1565 #ifndef NDEBUG
1566  catch( const SPxException& x )
1567  {
1568  std::string s = x.what();
1569  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1570 #else
1571  catch( const SPxException& )
1572  {
1573 #endif
1574  return SCIP_LPERROR;
1575  }
1576 
1577  return SCIP_OKAY;
1578 }
1579 
1580 /** changes left and right hand sides of rows */
1582  SCIP_LPI* lpi, /**< LP interface structure */
1583  int nrows, /**< number of rows to change sides for */
1584  const int* ind, /**< row indices */
1585  const SCIP_Real* lhs, /**< new values for left hand sides */
1586  const SCIP_Real* rhs /**< new values for right hand sides */
1587  )
1588 {
1589  int i;
1590 
1591  SCIPdebugMessage("calling SCIPlpiChgSides()\n");
1592 
1593  assert(lpi != NULL);
1594  assert(lpi->spx != NULL);
1595  assert(ind != NULL);
1596  assert(lhs != NULL);
1597  assert(rhs != NULL);
1598  if( nrows <= 0 )
1599  return SCIP_OKAY;
1600 
1601  invalidateSolution(lpi);
1602 
1603  assert( lpi->spx->preStrongbranchingBasisFreed() );
1604 
1605  try
1606  {
1607  for( i = 0; i < nrows; ++i )
1608  {
1609  assert(0 <= ind[i] && ind[i] < lpi->spx->numRowsReal());
1610  lpi->spx->changeRangeReal(ind[i], lhs[i], rhs[i]);
1611  assert(lpi->spx->lhsReal(ind[i]) <= lpi->spx->rhsReal(ind[i]) + lpi->spx->realParam(SoPlex::EPSILON_ZERO));
1612  }
1613  }
1614 #ifndef NDEBUG
1615  catch( const SPxException& x )
1616  {
1617  std::string s = x.what();
1618  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1619 #else
1620  catch( const SPxException& )
1621  {
1622 #endif
1623  return SCIP_LPERROR;
1624  }
1625 
1626  return SCIP_OKAY;
1627 }
1628 
1629 /** changes a single coefficient */
1631  SCIP_LPI* lpi, /**< LP interface structure */
1632  int row, /**< row number of coefficient to change */
1633  int col, /**< column number of coefficient to change */
1634  SCIP_Real newval /**< new value of coefficient */
1635  )
1636 {
1637  SCIPdebugMessage("calling SCIPlpiChgCoef()\n");
1638 
1639  assert(lpi != NULL);
1640  assert(lpi->spx != NULL);
1641  assert(0 <= row && row < lpi->spx->numRowsReal());
1642  assert(0 <= col && col < lpi->spx->numColsReal());
1643 
1644  invalidateSolution(lpi);
1645 
1646  assert( lpi->spx->preStrongbranchingBasisFreed() );
1647 
1648  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->changeElementReal(row, col, newval) );
1649 
1650  return SCIP_OKAY;
1651 }
1652 
1653 /** changes the objective sense */
1655  SCIP_LPI* lpi, /**< LP interface structure */
1656  SCIP_OBJSEN objsen /**< new objective sense */
1657  )
1658 {
1659  SCIPdebugMessage("calling SCIPlpiChgObjsen()\n");
1660 
1661  assert(lpi != NULL);
1662  assert(lpi->spx != NULL);
1663 
1664  invalidateSolution(lpi);
1665 
1666  assert( lpi->spx->preStrongbranchingBasisFreed() );
1667 
1668  SOPLEX_TRY( lpi->messagehdlr, (void) lpi->spx->setIntParam(SoPlex::OBJSENSE, objsen == SCIP_OBJSEN_MINIMIZE ? SoPlex::OBJSENSE_MINIMIZE : SoPlex::OBJSENSE_MAXIMIZE ) );
1669 
1670  return SCIP_OKAY;
1671 }
1672 
1673 /** changes objective values of columns in the LP */
1675  SCIP_LPI* lpi, /**< LP interface structure */
1676  int ncols, /**< number of columns to change objective value for */
1677  const int* ind, /**< column indices to change objective value for */
1678  const SCIP_Real* obj /**< new objective values for columns */
1679  )
1680 {
1681  int i;
1682 
1683  SCIPdebugMessage("calling SCIPlpiChgObj()\n");
1684 
1685  assert(lpi != NULL);
1686  assert(lpi->spx != NULL);
1687  assert(ind != NULL);
1688  assert(obj != NULL);
1689 
1690  invalidateSolution(lpi);
1691 
1692  assert( lpi->spx->preStrongbranchingBasisFreed() );
1693 
1694  try
1695  {
1696  for( i = 0; i < ncols; ++i )
1697  {
1698  assert(0 <= ind[i] && ind[i] < lpi->spx->numColsReal());
1699  lpi->spx->changeObjReal(ind[i], obj[i]);
1700  }
1701  }
1702 #ifndef NDEBUG
1703  catch( const SPxException& x )
1704  {
1705  std::string s = x.what();
1706  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1707 #else
1708  catch( const SPxException& )
1709  {
1710 #endif
1711  return SCIP_LPERROR;
1712  }
1713 
1714  return SCIP_OKAY;
1715 }
1716 
1717 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1719  SCIP_LPI* lpi, /**< LP interface structure */
1720  int row, /**< row number to scale */
1721  SCIP_Real scaleval /**< scaling multiplier */
1722  )
1723 {
1724  SCIP_Real lhs;
1725  SCIP_Real rhs;
1726 
1727  SCIPdebugMessage("calling SCIPlpiScaleRow()\n");
1728 
1729  assert(lpi != NULL);
1730  assert(lpi->spx != NULL);
1731  assert(scaleval != 0.0);
1732 
1733  try
1734  {
1735  invalidateSolution(lpi);
1736 
1737  assert( lpi->spx->preStrongbranchingBasisFreed() );
1738 
1739  /* get the row vector and the row's sides */
1740 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1741  SVector rowvec = lpi->spx->rowVectorRealInternal(row);
1742 #else
1743  SVector rowvec = lpi->spx->rowVectorReal(row);
1744 #endif
1745  lhs = lpi->spx->lhsReal(row);
1746  rhs = lpi->spx->rhsReal(row);
1747 
1748  /* scale the row vector */
1749  rowvec *= scaleval;
1750 
1751  /* adjust the sides */
1752  if( lhs > -lpi->spx->realParam(SoPlex::INFTY) )
1753  lhs *= scaleval;
1754  else if( scaleval < 0.0 )
1755  lhs = lpi->spx->realParam(SoPlex::INFTY);
1756  if( rhs < lpi->spx->realParam(SoPlex::INFTY) )
1757  rhs *= scaleval;
1758  else if( scaleval < 0.0 )
1759  rhs = -lpi->spx->realParam(SoPlex::INFTY);
1760  if( scaleval < 0.0 )
1761  {
1762  SCIP_Real oldlhs = lhs;
1763  lhs = rhs;
1764  rhs = oldlhs;
1765  }
1766 
1767  /* create the new row */
1768  LPRow lprow(lhs, rowvec, rhs);
1769 
1770  /* change the row in the LP */
1771  lpi->spx->changeRowReal(row, lprow);
1772  assert(lpi->spx->lhsReal(row) <= lpi->spx->rhsReal(row));
1773  }
1774 #ifndef NDEBUG
1775  catch( const SPxException& x )
1776  {
1777  std::string s = x.what();
1778  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1779 #else
1780  catch( const SPxException& )
1781  {
1782 #endif
1783  return SCIP_LPERROR;
1784  }
1785 
1786  return SCIP_OKAY;
1787 }
1788 
1789 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1790  * are divided by the scalar; for negative scalars, the column's bounds are switched
1791  */
1793  SCIP_LPI* lpi, /**< LP interface structure */
1794  int col, /**< column number to scale */
1795  SCIP_Real scaleval /**< scaling multiplier */
1796  )
1797 {
1798  SCIP_Real obj;
1799  SCIP_Real lb;
1800  SCIP_Real ub;
1801 
1802  SCIPdebugMessage("calling SCIPlpiScaleCol()\n");
1803 
1804  assert(lpi != NULL);
1805  assert(lpi->spx != NULL);
1806  assert(scaleval != 0.0);
1807 
1808  try
1809  {
1810  invalidateSolution(lpi);
1811 
1812  assert( lpi->spx->preStrongbranchingBasisFreed() );
1813 
1814  /* get the col vector and the col's bounds and objective value */
1815 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1816  SVector colvec = lpi->spx->colVectorRealInternal(col);
1817 #else
1818  SVector colvec = lpi->spx->colVectorReal(col);
1819 #endif
1820  obj = lpi->spx->objReal(col);
1821  lb = lpi->spx->lowerReal(col);
1822  ub = lpi->spx->upperReal(col);
1823 
1824  /* scale the col vector */
1825  colvec *= scaleval;
1826 
1827  /* scale the objective value */
1828  obj *= scaleval;
1829 
1830  /* adjust the bounds */
1831  if( lb > -lpi->spx->realParam(SoPlex::INFTY) )
1832  lb /= scaleval;
1833  else if( scaleval < 0.0 )
1834  lb = lpi->spx->realParam(SoPlex::INFTY);
1835  if( ub < lpi->spx->realParam(SoPlex::INFTY) )
1836  ub /= scaleval;
1837  else if( scaleval < 0.0 )
1838  ub = -lpi->spx->realParam(SoPlex::INFTY);
1839  if( scaleval < 0.0 )
1840  {
1841  SCIP_Real oldlb = lb;
1842  lb = ub;
1843  ub = oldlb;
1844  }
1845 
1846  /* create the new col (in LPCol's constructor, the upper bound is given first!) */
1847  LPCol lpcol(obj, colvec, ub, lb);
1848 
1849  /* change the col in the LP */
1850  lpi->spx->changeColReal(col, lpcol);
1851  assert(lpi->spx->lowerReal(col) <= lpi->spx->upperReal(col));
1852  }
1853 #ifndef NDEBUG
1854  catch( const SPxException& x )
1855  {
1856  std::string s = x.what();
1857  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1858 #else
1859  catch( const SPxException& )
1860  {
1861 #endif
1862  return SCIP_LPERROR;
1863  }
1864 
1865  return SCIP_OKAY;
1866 }
1867 
1868 /**@} */
1869 
1870 
1871 
1872 
1873 /*
1874  * Data Accessing Methods
1875  */
1876 
1877 /**@name Data Accessing Methods */
1878 /**@{ */
1879 
1880 /** gets the number of rows in the LP */
1882  SCIP_LPI* lpi, /**< LP interface structure */
1883  int* nrows /**< pointer to store the number of rows */
1884  )
1885 {
1886  SCIPdebugMessage("calling SCIPlpiGetNRows()\n");
1887 
1888  assert(lpi != NULL);
1889  assert(lpi->spx != NULL);
1890  assert(nrows != NULL);
1891 
1892  *nrows = lpi->spx->numRowsReal();
1893 
1894  return SCIP_OKAY;
1895 }
1896 
1897 /** gets the number of columns in the LP */
1899  SCIP_LPI* lpi, /**< LP interface structure */
1900  int* ncols /**< pointer to store the number of cols */
1901  )
1902 {
1903  SCIPdebugMessage("calling SCIPlpiGetNCols()\n");
1904 
1905  assert(lpi != NULL);
1906  assert(lpi->spx != NULL);
1907  assert(ncols != NULL);
1908 
1909  *ncols = lpi->spx->numColsReal();
1910 
1911  return SCIP_OKAY;
1912 }
1913 
1914 /** gets the number of nonzero elements in the LP constraint matrix */
1916  SCIP_LPI* lpi, /**< LP interface structure */
1917  int* nnonz /**< pointer to store the number of nonzeros */
1918  )
1919 {
1920  int i;
1921 
1922  SCIPdebugMessage("calling SCIPlpiGetNNonz()\n");
1923 
1924  assert(lpi != NULL);
1925  assert(lpi->spx != NULL);
1926  assert(nnonz != NULL);
1927 
1928  /* SoPlex has no direct method to return the number of nonzeros, so we have to count them manually */
1929  *nnonz = 0;
1930  if( lpi->spx->numRowsReal() < lpi->spx->numColsReal() )
1931  {
1932  for( i = 0; i < lpi->spx->numRowsReal(); ++i )
1933 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1934  (*nnonz) += lpi->spx->rowVectorRealInternal(i).size();
1935 #else
1936  (*nnonz) += lpi->spx->rowVectorReal(i).size();
1937 #endif
1938  }
1939  else
1940  {
1941  for( i = 0; i < lpi->spx->numColsReal(); ++i )
1942 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1943  (*nnonz) += lpi->spx->colVectorRealInternal(i).size();
1944 #else
1945  (*nnonz) += lpi->spx->colVectorReal(i).size();
1946 #endif
1947  }
1948 
1949  return SCIP_OKAY;
1950 }
1951 
1952 /** gets columns from LP problem object; the arrays have to be large enough to store all values
1953  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1954  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1955  */
1957  SCIP_LPI* lpi, /**< LP interface structure */
1958  int firstcol, /**< first column to get from LP */
1959  int lastcol, /**< last column to get from LP */
1960  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1961  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1962  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1963  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1964  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1965  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1966  )
1967 {
1968  int i;
1969  int j;
1970 
1971  SCIPdebugMessage("calling SCIPlpiGetCols()\n");
1972 
1973  assert(lpi != NULL);
1974  assert(lpi->spx != NULL);
1975  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
1976  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1977  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1978 
1979  if( lb != NULL )
1980  {
1981 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
1982  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
1983  {
1984  DVector lbvec(lpi->spx->numColsReal());
1985  DVector ubvec(lpi->spx->numColsReal());
1986  lpi->spx->getLowerReal(lbvec);
1987  lpi->spx->getUpperReal(ubvec);
1988  for( i = firstcol; i <= lastcol; ++i )
1989  {
1990  lb[i-firstcol] = lbvec[i];
1991  ub[i-firstcol] = ubvec[i];
1992  }
1993  }
1994  else
1995  {
1996  const Vector& lbvec = lpi->spx->lowerRealInternal();
1997  const Vector& ubvec = lpi->spx->upperRealInternal();
1998  for( i = firstcol; i <= lastcol; ++i )
1999  {
2000  lb[i-firstcol] = lbvec[i];
2001  ub[i-firstcol] = ubvec[i];
2002  }
2003  }
2004 #else
2005  const Vector& lbvec = lpi->spx->lowerReal();
2006  const Vector& ubvec = lpi->spx->upperReal();
2007 
2008  for( i = firstcol; i <= lastcol; ++i )
2009  {
2010  lb[i-firstcol] = lbvec[i];
2011  ub[i-firstcol] = ubvec[i];
2012  }
2013 #endif
2014  }
2015 
2016  if( nnonz != NULL )
2017  {
2018  *nnonz = 0;
2019  for( i = firstcol; i <= lastcol; ++i )
2020  {
2021  beg[i-firstcol] = *nnonz;
2022 
2023 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2024  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2025  {
2026  DSVector cvec;
2027  lpi->spx->getColVectorReal(i, cvec);
2028  for( j = 0; j < cvec.size(); ++j )
2029  {
2030  ind[*nnonz] = cvec.index(j);
2031  val[*nnonz] = cvec.value(j);
2032  (*nnonz)++;
2033  }
2034  }
2035  else
2036  {
2037  const SVector& cvec = lpi->spx->colVectorRealInternal(i);
2038  for( j = 0; j < cvec.size(); ++j )
2039  {
2040  ind[*nnonz] = cvec.index(j);
2041  val[*nnonz] = cvec.value(j);
2042  (*nnonz)++;
2043  }
2044  }
2045 #else
2046  const SVector& cvec = lpi->spx->colVectorReal(i);
2047  for( j = 0; j < cvec.size(); ++j )
2048  {
2049  ind[*nnonz] = cvec.index(j);
2050  val[*nnonz] = cvec.value(j);
2051  (*nnonz)++;
2052  }
2053 #endif
2054  }
2055  }
2056 
2057  return SCIP_OKAY;
2058 }
2059 
2060 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
2061  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
2062  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2063  */
2065  SCIP_LPI* lpi, /**< LP interface structure */
2066  int firstrow, /**< first row to get from LP */
2067  int lastrow, /**< last row to get from LP */
2068  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
2069  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
2070  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2071  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
2072  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
2073  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2074  )
2075 {
2076  int i;
2077  int j;
2078 
2079  SCIPdebugMessage("calling SCIPlpiGetRows()\n");
2080 
2081  assert(lpi != NULL);
2082  assert(lpi->spx != NULL);
2083  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
2084  assert((lhs != NULL && rhs != NULL) || (lhs == NULL && rhs == NULL));
2085  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2086 
2087  if( lhs != NULL )
2088  {
2089 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2090  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2091  {
2092  DVector lhsvec(lpi->spx->numRowsReal());
2093  DVector rhsvec(lpi->spx->numRowsReal());
2094  lpi->spx->getLhsReal(lhsvec);
2095  lpi->spx->getRhsReal(rhsvec);
2096  for( i = firstrow; i <= lastrow; ++i )
2097  {
2098  lhs[i-firstrow] = lhsvec[i];
2099  rhs[i-firstrow] = rhsvec[i];
2100  }
2101  }
2102  else
2103  {
2104  const Vector& lhsvec = lpi->spx->lhsRealInternal();
2105  const Vector& rhsvec = lpi->spx->rhsRealInternal();
2106  for( i = firstrow; i <= lastrow; ++i )
2107  {
2108  lhs[i-firstrow] = lhsvec[i];
2109  rhs[i-firstrow] = rhsvec[i];
2110  }
2111  }
2112 #else
2113  const Vector& lhsvec = lpi->spx->lhsReal();
2114  const Vector& rhsvec = lpi->spx->rhsReal();
2115  for( i = firstrow; i <= lastrow; ++i )
2116  {
2117  lhs[i-firstrow] = lhsvec[i];
2118  rhs[i-firstrow] = rhsvec[i];
2119  }
2120 #endif
2121  }
2122 
2123  if( nnonz != NULL )
2124  {
2125  *nnonz = 0;
2126  for( i = firstrow; i <= lastrow; ++i )
2127  {
2128  beg[i-firstrow] = *nnonz;
2129 
2130 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2131  if( lpi->spx->boolParam(SoPlex::PERSISTENTSCALING) )
2132  {
2133  DSVector rvec;
2134  lpi->spx->getRowVectorReal(i, rvec);
2135  for( j = 0; j < rvec.size(); ++j )
2136  {
2137  ind[*nnonz] = rvec.index(j);
2138  val[*nnonz] = rvec.value(j);
2139  (*nnonz)++;
2140  }
2141  }
2142  else
2143  {
2144  const SVector& rvec = lpi->spx->rowVectorRealInternal(i);
2145  for( j = 0; j < rvec.size(); ++j )
2146  {
2147  ind[*nnonz] = rvec.index(j);
2148  val[*nnonz] = rvec.value(j);
2149  (*nnonz)++;
2150  }
2151  }
2152 #else
2153  const SVector& rvec = lpi->spx->rowVectorReal(i);
2154  for( j = 0; j < rvec.size(); ++j )
2155  {
2156  ind[*nnonz] = rvec.index(j);
2157  val[*nnonz] = rvec.value(j);
2158  (*nnonz)++;
2159  }
2160 #endif
2161  }
2162  }
2163 
2164  return SCIP_OKAY;
2165 }
2166 
2167 /** gets column names */
2169  SCIP_LPI* lpi, /**< LP interface structure */
2170  int firstcol, /**< first column to get name from LP */
2171  int lastcol, /**< last column to get name from LP */
2172  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2173  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2174  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2175  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2176  )
2177 {
2178  assert( lpi != NULL );
2179  assert( lpi->spx != NULL );
2180  assert( colnames != NULL || namestoragesize == 0 );
2181  assert( namestorage != NULL || namestoragesize == 0 );
2182  assert( namestoragesize >= 0 );
2183  assert( storageleft != NULL );
2184  assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal() );
2185 
2186  SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
2187 
2188 // lpi->spx->getColNames(firstcol, lastcol, colnames, namestorage, namestoragesize, storageleft);
2189 
2190  return SCIP_OKAY;
2191 }
2192 
2193 /** gets row names */
2195  SCIP_LPI* lpi, /**< LP interface structure */
2196  int firstrow, /**< first row to get name from LP */
2197  int lastrow, /**< last row to get name from LP */
2198  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2199  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2200  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2201  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2202  )
2203 {
2204  assert( lpi != NULL );
2205  assert( lpi->spx != NULL );
2206  assert( rownames != NULL || namestoragesize == 0 );
2207  assert( namestorage != NULL || namestoragesize == 0 );
2208  assert( namestoragesize >= 0 );
2209  assert( storageleft != NULL );
2210  assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal() );
2211 
2212  SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
2213 
2214 // lpi->spx->getRowNames(firstrow, lastrow, rownames, namestorage, namestoragesize, storageleft);
2215 
2216  return SCIP_OKAY;
2217 }
2218 
2219 /** gets objective sense of the LP */
2221  SCIP_LPI* lpi, /**< LP interface structure */
2222  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2223  )
2224 {
2225  SCIPdebugMessage("calling SCIPlpiGetObjsen()\n");
2226 
2227  assert(lpi != NULL);
2228  assert(lpi->spx != NULL);
2229  assert(objsen != NULL);
2230 
2231  *objsen = (lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2232 
2233  return SCIP_OKAY;
2234 }
2235 
2236 /** gets objective coefficients from LP problem object */
2238  SCIP_LPI* lpi, /**< LP interface structure */
2239  int firstcol, /**< first column to get objective coefficient for */
2240  int lastcol, /**< last column to get objective coefficient for */
2241  SCIP_Real* vals /**< array to store objective coefficients */
2242  )
2243 {
2244  int i;
2245 
2246  SCIPdebugMessage("calling SCIPlpiGetObj()\n");
2247 
2248  assert(lpi != NULL);
2249  assert(lpi->spx != NULL);
2250  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
2251  assert(vals != NULL);
2252 
2253  for( i = firstcol; i <= lastcol; ++i )
2254  vals[i-firstcol] = lpi->spx->objReal(i);
2255 
2256  return SCIP_OKAY;
2257 }
2258 
2259 /** gets current bounds from LP problem object */
2261  SCIP_LPI* lpi, /**< LP interface structure */
2262  int firstcol, /**< first column to get objective value for */
2263  int lastcol, /**< last column to get objective value for */
2264  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2265  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2266  )
2267 {
2268  int i;
2269 
2270  SCIPdebugMessage("calling SCIPlpiGetBounds()\n");
2271 
2272  assert(lpi != NULL);
2273  assert(lpi->spx != NULL);
2274  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->numColsReal());
2275 
2276  for( i = firstcol; i <= lastcol; ++i )
2277  {
2278  if( lbs != NULL )
2279  lbs[i-firstcol] = lpi->spx->lowerReal(i);
2280  if( ubs != NULL )
2281  ubs[i-firstcol] = lpi->spx->upperReal(i);
2282  }
2283 
2284  return SCIP_OKAY;
2285 }
2286 
2287 /** gets current row sides from LP problem object */
2289  SCIP_LPI* lpi, /**< LP interface structure */
2290  int firstrow, /**< first row to get sides for */
2291  int lastrow, /**< last row to get sides for */
2292  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2293  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2294  )
2295 {
2296  int i;
2297 
2298  SCIPdebugMessage("calling SCIPlpiGetSides()\n");
2299 
2300  assert(lpi != NULL);
2301  assert(lpi->spx != NULL);
2302  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->numRowsReal());
2303 
2304  for( i = firstrow; i <= lastrow; ++i )
2305  {
2306  if( lhss != NULL )
2307  lhss[i-firstrow] = lpi->spx->lhsReal(i);
2308  if( rhss != NULL )
2309  rhss[i-firstrow] = lpi->spx->rhsReal(i);
2310  }
2311 
2312  return SCIP_OKAY;
2313 }
2314 
2315 /** gets a single coefficient */
2317  SCIP_LPI* lpi, /**< LP interface structure */
2318  int row, /**< row number of coefficient */
2319  int col, /**< column number of coefficient */
2320  SCIP_Real* val /**< pointer to store the value of the coefficient */
2321  )
2322 {
2323  SCIPdebugMessage("calling SCIPlpiGetCoef()\n");
2324 
2325  assert(lpi != NULL);
2326  assert(lpi->spx != NULL);
2327  assert(0 <= col && col < lpi->spx->numColsReal());
2328  assert(0 <= row && row < lpi->spx->numRowsReal());
2329  assert(val != NULL);
2330 
2331 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2332  *val = lpi->spx->coefReal(row, col);
2333 #else
2334  *val = lpi->spx->colVectorReal(col)[row];
2335 #endif
2336 
2337  return SCIP_OKAY;
2338 }
2339 
2340 /**@} */
2341 
2342 
2343 
2344 
2345 /*
2346  * Solving Methods
2347  */
2348 
2349 /**@name Solving Methods */
2350 /**@{ */
2351 
2352 /** solves LP -- used for both, primal and dual simplex, because SoPlex doesn't distinct the two cases */
2353 static
2355  SCIP_LPI* lpi /**< LP interface structure */
2356  )
2358  assert( lpi != NULL );
2359  assert( lpi->spx != NULL );
2360 
2361  SPxOut::Verbosity verbosity;
2362  /* store and set verbosity */
2363  verbosity = lpi->spx->spxout.getVerbosity();
2364  lpi->spx->spxout.setVerbosity((SPxOut::Verbosity)(lpi->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
2365 
2366  SCIPdebugMessage("calling SoPlex solve(): %d cols, %d rows\n", lpi->spx->numColsReal(), lpi->spx->numRowsReal());
2367 
2368  invalidateSolution(lpi);
2369 
2370  assert( lpi->spx->preStrongbranchingBasisFreed() );
2371 
2372 #ifdef SCIP_WITH_LPSCHECK
2373  lpi->spx->setDoubleCheck(CHECK_SPXSOLVE);
2374 #endif
2375 
2376  /* delete starting basis if solving from scratch */
2377  if( lpi->spx->getFromScratch() )
2378  {
2379  try
2380  {
2381  lpi->spx->clearBasis();
2382  }
2383 #ifndef NDEBUG
2384  catch(const SPxException& x)
2385  {
2386  std::string s = x.what();
2387  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2388 #else
2389  catch(const SPxException&)
2390  {
2391 #endif
2392  assert( lpi->spx->status() != SPxSolver::OPTIMAL );
2393  return SCIP_LPERROR;
2394  }
2395  }
2396  assert(!lpi->spx->getFromScratch() || lpi->spx->status() == SPxSolver::NO_PROBLEM);
2397 
2398  SPxSolver::Status status = lpi->spx->doSolve();
2399  SCIPdebugMessage(" -> SoPlex status: %d, basis status: %d\n", lpi->spx->status(), lpi->spx->basisStatus());
2400  lpi->solved = TRUE;
2401 
2402  /* restore verbosity */
2403  lpi->spx->spxout.setVerbosity(verbosity);
2404 
2405  switch( status )
2406  {
2407  case SPxSolver::ABORT_TIME:
2408  case SPxSolver::ABORT_ITER:
2409  case SPxSolver::ABORT_VALUE:
2410  case SPxSolver::SINGULAR:
2411  case SPxSolver::REGULAR:
2412  case SPxSolver::UNKNOWN:
2413  case SPxSolver::OPTIMAL:
2414 #if SOPLEX_APIVERSION >= 3
2415  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2416 #endif
2417  case SPxSolver::UNBOUNDED:
2418  case SPxSolver::INFEASIBLE:
2419  return SCIP_OKAY;
2420  default:
2421  return SCIP_LPERROR;
2422  } /*lint !e788*/
2423 }
2424 
2425 /** calls primal simplex to solve the LP */
2427  SCIP_LPI* lpi /**< LP interface structure */
2428  )
2430  SCIPdebugMessage("calling SCIPlpiSolvePrimal()\n");
2431 
2432  assert(lpi != NULL);
2433  assert(lpi->spx != NULL);
2434 
2435  (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_PRIMAL);
2436  return spxSolve(lpi);
2437 }
2438 
2439 /** calls dual simplex to solve the LP */
2441  SCIP_LPI* lpi /**< LP interface structure */
2442  )
2444  SCIPdebugMessage("calling SCIPlpiSolveDual()\n");
2445 
2446  assert(lpi != NULL);
2447  assert(lpi->spx != NULL);
2448 
2449  (void) lpi->spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_DUAL);
2450  return spxSolve(lpi);
2451 }
2452 
2453 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2455  SCIP_LPI* lpi, /**< LP interface structure */
2456  SCIP_Bool crossover /**< perform crossover */
2457  )
2458 { /*lint --e{715}*/
2459  assert(lpi != NULL);
2460  assert(lpi->spx != NULL);
2461 
2462  SCIPdebugMessage("calling SCIPlpiSolveBarrier()\n");
2463 
2464  /* Since SoPlex does not support barrier we switch to DUAL */
2465  return SCIPlpiSolveDual(lpi);
2466 }
2467 
2468 /** start strong branching - call before any strongbranching */
2470  SCIP_LPI* lpi /**< LP interface structure */
2471  )
2473  assert(lpi != NULL);
2474  assert(lpi->spx != NULL);
2475 
2476  assert( lpi->spx->preStrongbranchingBasisFreed() );
2477  lpi->spx->savePreStrongbranchingBasis();
2478 
2479  return SCIP_OKAY;
2480 }
2481 
2482 /** end strong branching - call after any strongbranching */
2484  SCIP_LPI* lpi /**< LP interface structure */
2485  )
2487  assert(lpi != NULL);
2488  assert(lpi->spx != NULL);
2489 
2490  assert( ! lpi->spx->preStrongbranchingBasisFreed() );
2491  lpi->spx->restorePreStrongbranchingBasis();
2492  lpi->spx->freePreStrongbranchingBasis();
2493 
2494  return SCIP_OKAY;
2495 }
2496 
2497 /** performs strong branching iterations on one arbitrary candidate */
2498 static
2500  SCIP_LPI* lpi, /**< LP interface structure */
2501  int col, /**< column to apply strong branching on */
2502  SCIP_Real psol, /**< current primal solution value of column */
2503  int itlim, /**< iteration limit for strong branchings */
2504  SCIP_Real* down, /**< stores dual bound after branching column down */
2505  SCIP_Real* up, /**< stores dual bound after branching column up */
2506  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2507  * otherwise, it can only be used as an estimate value */
2508  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2509  * otherwise, it can only be used as an estimate value */
2510  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2511  )
2512 {
2513  assert(lpi != NULL);
2514  assert(lpi->spx != NULL);
2515 
2516  SPxSCIP* spx;
2517  SPxSolver::Status status;
2518  SCIP_Real oldlb;
2519  SCIP_Real oldub;
2520  SCIP_Real newlb;
2521  SCIP_Real newub;
2522  bool fromparentbasis;
2523  bool error;
2524  int oldItlim;
2525  SPxOut::Verbosity verbosity;
2526 
2527  /* store and set verbosity */
2528  verbosity = lpi->spx->spxout.getVerbosity();
2529  lpi->spx->spxout.setVerbosity((SPxOut::Verbosity)(lpi->spx->getLpInfo() ? SOPLEX_VERBLEVEL : 0));
2530 
2531  SCIPdebugMessage("calling SCIPlpiStrongbranch() on variable %d (%d iterations)\n", col, itlim);
2532 
2533  assert(lpi != NULL);
2534  assert(lpi->spx != NULL);
2535  /* assert(down != NULL);
2536  * assert(up != NULL); temporary hack for cloud branching */
2537  assert(downvalid != NULL);
2538  assert(upvalid != NULL);
2539 
2540  spx = lpi->spx;
2541 #ifndef STRONGBRANCH_RESTOREBASIS
2542  fromparentbasis = false;
2543 #endif
2544  error = false;
2545  oldItlim = spx->intParam(SoPlex::ITERLIMIT);
2546 
2547  /* get current bounds of column */
2548  oldlb = spx->lowerReal(col);
2549  oldub = spx->upperReal(col);
2550 
2551  *downvalid = FALSE;
2552  *upvalid = FALSE;
2553 
2554  if( iter != NULL )
2555  *iter = 0;
2556 
2557  /* set the algorithm type to use dual simplex */
2558  (void) spx->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_DUAL);
2559 
2560  /* down branch */
2561  newub = EPSCEIL(psol-1.0, lpi->spx->feastol());
2562  if( newub >= oldlb - 0.5 && down != NULL )
2563  {
2564  SCIPdebugMessage("strong branching down on x%d (%g) with %d iterations\n", col, psol, itlim);
2565 
2566  spx->changeUpperReal(col, newub);
2567  assert(spx->lowerReal(col) <= spx->upperReal(col));
2568 
2569  (void) spx->setIntParam(SoPlex::ITERLIMIT, itlim);
2570  do
2571  {
2572 #ifndef STRONGBRANCH_RESTOREBASIS
2573  SCIP_Bool repeatstrongbranching;
2574 #endif
2575 #ifdef SCIP_WITH_LPSCHECK
2576  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2577 #endif
2578 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2579 #if SOPLEX_APIVERSION > 11
2580  status = spx->optimize(spx->getInterrupt());
2581 #else
2582  status = spx->optimize();
2583 #endif
2584 #else
2585  status = spx->solve();
2586 #endif
2587  SCIPdebugMessage(" --> Terminate with status %d\n", status);
2588  switch( status )
2589  {
2590  case SPxSolver::OPTIMAL:
2591  *down = spx->objValueReal();
2592  *downvalid = TRUE;
2593  SCIPdebugMessage(" --> Terminate with value %f\n", *down);
2594  break;
2595  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
2596  case SPxSolver::ABORT_ITER:
2597  case SPxSolver::ABORT_CYCLING:
2598 #if SOPLEX_APIVERSION >= 3
2599  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2600 #endif
2601  *down = spx->objValueReal();
2602  break;
2603  case SPxSolver::ABORT_VALUE:
2604  case SPxSolver::INFEASIBLE:
2605  *down = spx->getObjLimit();
2606  *downvalid = TRUE;
2607  break;
2608  default:
2609  error = true;
2610  break;
2611  } /*lint !e788*/
2612  if( iter != NULL )
2613  (*iter) += spx->numIterations();
2614 
2615 #ifdef STRONGBRANCH_RESTOREBASIS
2616  /* we restore the pre-strong-branching basis by default (and don't solve again) */
2617  assert( ! spx->preStrongbranchingBasisFreed() );
2618  spx->restorePreStrongbranchingBasis();
2619  fromparentbasis = false;
2620 #else
2621  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
2622  * pre-strong-branching basis and try again with reduced iteration limit */
2623 #if SOPLEX_APIVERSION >= 3
2624  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS
2625  || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->numIterations() < itlim);
2626 #else
2627  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR)
2628  && !fromparentbasis && spx->numIterations() < itlim);
2629 #endif
2630  if( repeatstrongbranching )
2631  {
2632  SCIPdebugMessage(" --> Repeat strong branching down with %d iterations after restoring basis\n",
2633  itlim - spx->numIterations());
2634  spx->setIntParam(SoPlex::ITERLIMIT, itlim - spx->numIterations());
2635  spx->restorePreStrongbranchingBasis();
2636  fromparentbasis = true;
2637  error = false;
2638  }
2639  /* otherwise don't solve again */
2640  else
2641  fromparentbasis = false;
2642 #endif
2643  }
2644  while( fromparentbasis );
2645 
2646  spx->changeUpperReal(col, oldub);
2647  assert(spx->lowerReal(col) <= spx->upperReal(col));
2648  }
2649  else if( down != NULL )
2650  {
2651  *down = spx->getObjLimit();
2652  *downvalid = TRUE;
2653  }
2654  else
2655  *downvalid = TRUE;
2656 
2657  /* up branch */
2658  if( !error )
2659  {
2660  newlb = EPSFLOOR(psol+1.0, lpi->spx->feastol());
2661  if( newlb <= oldub + 0.5 && up != NULL )
2662  {
2663  SCIPdebugMessage("strong branching up on x%d (%g) with %d iterations\n", col, psol, itlim);
2664 
2665  spx->changeLowerReal(col, newlb);
2666  assert(spx->lowerReal(col) <= spx->upperReal(col));
2667 
2668  (void) spx->setIntParam(SoPlex::ITERLIMIT, itlim);
2669  do
2670  {
2671 #ifndef STRONGBRANCH_RESTOREBASIS
2672  SCIP_Bool repeatstrongbranching;
2673 #endif
2674 #ifdef SCIP_WITH_LPSCHECK
2675  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2676 #endif
2677 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
2678 #if SOPLEX_APIVERSION > 11
2679  status = spx->optimize(spx->getInterrupt());
2680 #else
2681  status = spx->optimize();
2682 #endif
2683 #else
2684  status = spx->solve();
2685 #endif
2686  SCIPdebugMessage(" --> Terminate with status %d\n", status);
2687  switch( status )
2688  {
2689  case SPxSolver::OPTIMAL:
2690  *up = spx->objValueReal();
2691  *upvalid = TRUE;
2692  SCIPdebugMessage(" --> Terminate with value %f\n", spx->objValueReal());
2693  break;
2694  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
2695  case SPxSolver::ABORT_ITER:
2696  case SPxSolver::ABORT_CYCLING:
2697 #if SOPLEX_APIVERSION >= 3
2698  case SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS:
2699 #endif
2700  *up = spx->objValueReal();
2701  break;
2702  case SPxSolver::ABORT_VALUE:
2703  case SPxSolver::INFEASIBLE:
2704  *up = spx->getObjLimit();
2705  *upvalid = TRUE;
2706  break;
2707  default:
2708  error = true;
2709  break;
2710  } /*lint !e788*/
2711  if( iter != NULL )
2712  (*iter) += spx->numIterations();
2713 
2714 #ifdef STRONGBRANCH_RESTOREBASIS
2715  /* we restore the pre-strong-branching basis by default (and don't solve again) */
2716  assert( ! spx->preStrongbranchingBasisFreed() );
2717  spx->restorePreStrongbranchingBasis();
2718  fromparentbasis = false;
2719 #else
2720  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
2721  * pre-strong-branching basis and try again with reduced iteration limit */
2722 #if SOPLEX_APIVERSION >= 3
2723  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS
2724  || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->numIterations() < itlim);
2725 #else
2726  repeatstrongbranching = ((status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR)
2727  && !fromparentbasis && spx->numIterations() < itlim);
2728 #endif
2729  if( repeatstrongbranching )
2730  {
2731  SCIPdebugMessage(" --> Repeat strong branching up with %d iterations after restoring basis\n", itlim - spx->numIterations());
2732  spx->restorePreStrongbranchingBasis();
2733  spx->setIntParam(SoPlex::ITERLIMIT, itlim - spx->numIterations());
2734  error = false;
2735  fromparentbasis = true;
2736  }
2737  /* otherwise don't solve again */
2738  else
2739  fromparentbasis = false;
2740 #endif
2741  }
2742  while( fromparentbasis );
2743 
2744  spx->changeLowerReal(col, oldlb);
2745  assert(spx->lowerReal(col) <= spx->upperReal(col));
2746  }
2747  else if( up != NULL )
2748  {
2749  *up = spx->getObjLimit();
2750  *upvalid = TRUE;
2751  }
2752  else
2753  *upvalid = TRUE;
2754  }
2755 
2756  /* reset old iteration limit */
2757  (void) spx->setIntParam(SoPlex::ITERLIMIT, oldItlim);
2758 
2759  /* restore verbosity */
2760  lpi->spx->spxout.setVerbosity(verbosity);
2761 
2762  if( error )
2763  {
2764  SCIPdebugMessage("SCIPlpiStrongbranch() returned SoPlex status %d\n", int(status)); /*lint !e644*/
2765  return SCIP_LPERROR;
2766  }
2767 
2768  return SCIP_OKAY;
2769 }
2770 
2771 /** performs strong branching iterations on one @b fractional candidate */
2773  SCIP_LPI* lpi, /**< LP interface structure */
2774  int col, /**< column to apply strong branching on */
2775  SCIP_Real psol, /**< fractional current primal solution value of column */
2776  int itlim, /**< iteration limit for strong branchings */
2777  SCIP_Real* down, /**< stores dual bound after branching column down */
2778  SCIP_Real* up, /**< stores dual bound after branching column up */
2779  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2780  * otherwise, it can only be used as an estimate value */
2781  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2782  * otherwise, it can only be used as an estimate value */
2783  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2784  )
2785 {
2786  SCIP_RETCODE retcode;
2787 
2788  /* pass call on to lpiStrongbranch() */
2789  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
2790 
2791  /* pass SCIP_LPERROR to SCIP without a back trace */
2792  if( retcode == SCIP_LPERROR )
2793  return SCIP_LPERROR;
2794 
2795  /* evaluate retcode */
2796  SCIP_CALL( retcode );
2797 
2798  return SCIP_OKAY;
2799 }
2800 
2801 /** performs strong branching iterations on given @b fractional candidates */
2803  SCIP_LPI* lpi, /**< LP interface structure */
2804  int* cols, /**< columns to apply strong branching on */
2805  int ncols, /**< number of columns */
2806  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2807  int itlim, /**< iteration limit for strong branchings */
2808  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2809  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2810  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2811  * otherwise, they can only be used as an estimate values */
2812  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2813  * otherwise, they can only be used as an estimate values */
2814  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2815  )
2816 {
2817  SCIP_RETCODE retcode;
2818 
2819  assert( cols != NULL );
2820  assert( psols != NULL );
2821  assert( down != NULL );
2822  assert( up != NULL );
2823  assert( downvalid != NULL );
2824  assert( upvalid != NULL );
2825  assert( down != NULL );
2826 
2827  if ( iter != NULL )
2828  *iter = 0;
2829 
2830  for (int j = 0; j < ncols; ++j)
2831  {
2832  /* pass call on to lpiStrongbranch() */
2833  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
2834 
2835  /* pass SCIP_LPERROR to SCIP without a back trace */
2836  if( retcode == SCIP_LPERROR )
2837  return SCIP_LPERROR;
2838 
2839  /* evaluate retcode */
2840  SCIP_CALL( retcode );
2841  }
2842  return SCIP_OKAY;
2843 }
2844 
2845 /** performs strong branching iterations on one candidate with @b integral value */
2847  SCIP_LPI* lpi, /**< LP interface structure */
2848  int col, /**< column to apply strong branching on */
2849  SCIP_Real psol, /**< current integral primal solution value of column */
2850  int itlim, /**< iteration limit for strong branchings */
2851  SCIP_Real* down, /**< stores dual bound after branching column down */
2852  SCIP_Real* up, /**< stores dual bound after branching column up */
2853  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2854  * otherwise, it can only be used as an estimate value */
2855  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2856  * otherwise, it can only be used as an estimate value */
2857  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2858  )
2859 {
2860  SCIP_RETCODE retcode;
2861 
2862  /* pass call on to lpiStrongbranch() */
2863  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
2864 
2865  /* pass SCIP_LPERROR to SCIP without a back trace */
2866  if( retcode == SCIP_LPERROR )
2867  return SCIP_LPERROR;
2868 
2869  /* evaluate retcode */
2870  SCIP_CALL( retcode );
2871 
2872  return SCIP_OKAY;
2873 }
2874 
2875 /** performs strong branching iterations on given candidates with @b integral values */
2877  SCIP_LPI* lpi, /**< LP interface structure */
2878  int* cols, /**< columns to apply strong branching on */
2879  int ncols, /**< number of columns */
2880  SCIP_Real* psols, /**< current integral primal solution values of columns */
2881  int itlim, /**< iteration limit for strong branchings */
2882  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2883  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2884  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2885  * otherwise, they can only be used as an estimate values */
2886  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2887  * otherwise, they can only be used as an estimate values */
2888  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2889  )
2890 {
2891  SCIP_RETCODE retcode;
2892 
2893  assert( cols != NULL );
2894  assert( psols != NULL );
2895  assert( down != NULL );
2896  assert( up != NULL );
2897  assert( downvalid != NULL );
2898  assert( upvalid != NULL );
2899  assert( down != NULL );
2900 
2901  if ( iter != NULL )
2902  *iter = 0;
2903 
2904  for (int j = 0; j < ncols; ++j)
2905  {
2906  /* pass call on to lpiStrongbranch() */
2907  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
2908 
2909  /* pass SCIP_LPERROR to SCIP without a back trace */
2910  if( retcode == SCIP_LPERROR )
2911  return SCIP_LPERROR;
2912 
2913  /* evaluate retcode */
2914  SCIP_CALL( retcode );
2915  }
2916 
2917  return SCIP_OKAY;
2918 }
2919 /**@} */
2920 
2921 
2922 
2923 
2924 /*
2925  * Solution Information Methods
2926  */
2927 
2928 /**@name Solution Information Methods */
2929 /**@{ */
2930 
2931 /** returns whether a solve method was called after the last modification of the LP */
2933  SCIP_LPI* lpi /**< LP interface structure */
2934  )
2936  assert(lpi != NULL);
2937 
2938  return lpi->solved;
2939 }
2940 
2941 /** gets information about primal and dual feasibility of the current LP solution
2942  *
2943  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
2944  * returns true. If the LP is changed, this information might be invalidated.
2945  *
2946  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
2947  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
2948  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
2949  * the problem might actually be feasible).
2950  */
2952  SCIP_LPI* lpi, /**< LP interface structure */
2953  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
2954  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
2955  )
2956 {
2957  SCIPdebugMessage("calling SCIPlpiGetSolFeasibility()\n");
2958 
2959  assert(lpi != NULL);
2960  assert(primalfeasible != NULL);
2961  assert(dualfeasible != NULL);
2962 
2963  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
2964  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
2965 
2966  return SCIP_OKAY;
2967 }
2968 
2969 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2970  * this does not necessarily mean, that the solver knows and can return the primal ray
2971  */
2973  SCIP_LPI* lpi /**< LP interface structure */
2974  )
2976  SCIPdebugMessage("calling SCIPlpiExistsPrimalRay()\n");
2977 
2978  assert(lpi != NULL);
2979  assert(lpi->spx != NULL);
2980 
2981  return (lpi->spx->status() == SPxSolver::UNBOUNDED);
2982 }
2983 
2984 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2985  * and the solver knows and can return the primal ray
2986  */
2988  SCIP_LPI* lpi /**< LP interface structure */
2989  )
2991  SCIPdebugMessage("calling SCIPlpiHasPrimalRay()\n");
2992 
2993  assert(lpi != NULL);
2994  assert(lpi->spx != NULL);
2995 
2996  return lpi->spx->hasPrimalRay();
2997 }
2998 
2999 /** returns TRUE iff LP is proven to be primal unbounded */
3001  SCIP_LPI* lpi /**< LP interface structure */
3002  )
3004  SCIPdebugMessage("calling SCIPlpiIsPrimalUnbounded()\n");
3005 
3006  assert(lpi != NULL);
3007  assert(lpi->spx != NULL);
3008 
3009  assert(lpi->spx->status() != SPxSolver::UNBOUNDED || lpi->spx->basisStatus() == SPxBasis::UNBOUNDED);
3010 
3011  /* if SoPlex returns unbounded, this may only mean that an unbounded ray is available, not necessarily a primal
3012  * feasible point; hence we have to check the perturbation
3013  */
3014  return lpi->spx->status() == SPxSolver::UNBOUNDED;
3015 }
3016 
3017 /** returns TRUE iff LP is proven to be primal infeasible */
3019  SCIP_LPI* lpi /**< LP interface structure */
3020  )
3022  SCIPdebugMessage("calling SCIPlpiIsPrimalInfeasible()\n");
3023 
3024  assert(lpi != NULL);
3025  assert(lpi->spx != NULL);
3026 
3027  return (lpi->spx->status() == SPxSolver::INFEASIBLE);
3028 }
3029 
3030 /** returns TRUE iff LP is proven to be primal feasible */
3032  SCIP_LPI* lpi /**< LP interface structure */
3033  )
3035  SCIPdebugMessage("calling SCIPlpiIsPrimalFeasible()\n");
3036 
3037  assert(lpi != NULL);
3038  assert(lpi->spx != NULL);
3039 
3040  return lpi->spx->basisStatus() == SPxBasis::OPTIMAL || lpi->spx->basisStatus() == SPxBasis::PRIMAL;
3041 }
3042 
3043 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3044  * this does not necessarily mean, that the solver knows and can return the dual ray
3045  */
3047  SCIP_LPI* lpi /**< LP interface structure */
3048  )
3050  SCIPdebugMessage("calling SCIPlpiExistsDualRay()\n");
3051 
3052  assert(lpi != NULL);
3053  assert(lpi->spx != NULL);
3054 
3055  return (lpi->spx->status() == SPxSolver::INFEASIBLE);
3056 }
3057 
3058 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3059  * and the solver knows and can return the dual ray
3060  */
3062  SCIP_LPI* lpi /**< LP interface structure */
3063  )
3065  SCIPdebugMessage("calling SCIPlpiHasDualRay()\n");
3066 
3067  assert(lpi != NULL);
3068  assert(lpi->spx != NULL);
3069 
3070  return lpi->spx->hasDualFarkas();
3071 }
3072 
3073 /** returns TRUE iff LP is dual unbounded */
3075  SCIP_LPI* lpi /**< LP interface structure */
3076  )
3078  SCIPdebugMessage("calling SCIPlpiIsDualUnbounded()\n");
3079 
3080  assert(lpi != NULL);
3081  assert(lpi->spx != NULL);
3082 
3083  return lpi->spx->status() == SPxSolver::INFEASIBLE && lpi->spx->basisStatus() == SPxBasis::DUAL;
3084 }
3085 
3086 /** returns TRUE iff LP is dual infeasible */
3088  SCIP_LPI* lpi /**< LP interface structure */
3089  )
3091  SCIPdebugMessage("calling SCIPlpiIsDualInfeasible()\n");
3092 
3093  assert(lpi != NULL);
3094  assert(lpi->spx != NULL);
3095 
3096  return (lpi->spx->status() == SPxSolver::UNBOUNDED);
3097 }
3098 
3099 /** returns TRUE iff LP is proven to be dual feasible */
3101  SCIP_LPI* lpi /**< LP interface structure */
3102  )
3104  SCIPdebugMessage("calling SCIPlpiIsDualFeasible()\n");
3105 
3106  assert(lpi != NULL);
3107  assert(lpi->spx != NULL);
3108 
3109  return (lpi->spx->basisStatus() == SPxBasis::OPTIMAL) || lpi->spx->basisStatus() == SPxBasis::DUAL;
3110 }
3111 
3112 /** returns TRUE iff LP was solved to optimality */
3114  SCIP_LPI* lpi /**< LP interface structure */
3115  )
3117  SCIPdebugMessage("calling SCIPlpiIsOptimal()\n");
3118 
3119  assert(lpi != NULL);
3120  assert(lpi->spx != NULL);
3121  assert((lpi->spx->basisStatus() == SPxBasis::OPTIMAL)
3123 
3124  return (lpi->spx->status() == SPxSolver::OPTIMAL);
3125 }
3126 
3127 /** returns TRUE iff current LP solution is stable
3128  *
3129  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3130  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3131  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3132  * SCIPlpiIsStable() should return false.
3133  */
3135  SCIP_LPI* lpi /**< LP interface structure */
3136  )
3138  SCIPdebugMessage("calling SCIPlpiIsStable()\n");
3139 
3140  assert(lpi != NULL);
3141  assert(lpi->spx != NULL);
3142 
3143  if( lpi->spx->status() == SPxSolver::ERROR || lpi->spx->status() == SPxSolver::SINGULAR )
3144  return FALSE;
3145 #if SOPLEX_APIVERSION >= 3
3146  if( lpi->spx->status() == SPxSolver::OPTIMAL_UNSCALED_VIOLATIONS )
3147  return FALSE;
3148 #endif
3149  /* only if we have a regular basis and the condition limit is set, we compute the condition number of the basis;
3150  * everything above the specified threshold is then counted as instable
3151  */
3152  if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3153  {
3154  SCIP_RETCODE retcode;
3155  SCIP_Real kappa;
3156 
3158  if( retcode != SCIP_OKAY )
3159  {
3160  SCIPABORT();
3161  }
3162  assert(kappa != SCIP_INVALID); /*lint !e777*/
3163 
3164  if( kappa > lpi->conditionlimit )
3165  return FALSE;
3166  }
3167  return TRUE;
3168 }
3169 
3170 /** returns TRUE iff the objective limit was reached */
3172  SCIP_LPI* lpi /**< LP interface structure */
3173  )
3175  SCIPdebugMessage("calling SCIPlpiIsObjlimExc()\n");
3176 
3177  assert(lpi != NULL);
3178  assert(lpi->spx != NULL);
3179 
3180  return (lpi->spx->status() == SPxSolver::ABORT_VALUE);
3181 }
3182 
3183 /** returns TRUE iff the iteration limit was reached */
3185  SCIP_LPI* lpi /**< LP interface structure */
3186  )
3188  SCIPdebugMessage("calling SCIPlpiIsIterlimExc()\n");
3189 
3190  assert(lpi != NULL);
3191  assert(lpi->spx != NULL);
3192 
3193  return (lpi->spx->status() == SPxSolver::ABORT_ITER);
3194 }
3195 
3196 /** returns TRUE iff the time limit was reached */
3198  SCIP_LPI* lpi /**< LP interface structure */
3199  )
3201  SCIPdebugMessage("calling SCIPlpiIsTimelimExc()\n");
3202 
3203  assert(lpi != NULL);
3204  assert(lpi->spx != NULL);
3205 
3206  return (lpi->spx->status() == SPxSolver::ABORT_TIME);
3207 }
3208 
3209 /** returns the internal solution status of the solver */
3211  SCIP_LPI* lpi /**< LP interface structure */
3212  )
3214  SCIPdebugMessage("calling SCIPlpiGetInternalStatus()\n");
3215 
3216  assert(lpi != NULL);
3217  assert(lpi->spx != NULL);
3218 
3219  return static_cast<int>(lpi->spx->status());
3220 }
3221 
3222 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3224  SCIP_LPI* lpi, /**< LP interface structure */
3225  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3226  )
3227 { /*lint --e{715}*/
3228  SCIPdebugMessage("calling SCIPlpiIgnoreInstability()\n");
3229 
3230  assert(lpi != NULL);
3231  assert(lpi->spx != NULL);
3232  assert(success != NULL);
3233 
3234 #if SOPLEX_APIVERSION >= 4
3235  *success = lpi->spx->ignoreUnscaledViolations();
3236 #else
3237  *success = FALSE;
3238 #endif
3239 
3240  return SCIP_OKAY;
3241 }
3242 
3243 /** gets objective value of solution */
3245  SCIP_LPI* lpi, /**< LP interface structure */
3246  SCIP_Real* objval /**< stores the objective value */
3247  )
3248 {
3249  SCIPdebugMessage("calling SCIPlpiGetObjval()\n");
3250 
3251  assert(lpi != NULL);
3252  assert(lpi->spx != NULL);
3253  assert(objval != NULL);
3254 
3255  *objval = lpi->spx->objValueReal();
3256 
3257  return SCIP_OKAY;
3258 }
3259 
3260 /** gets primal and dual solution vectors for feasible LPs
3261  *
3262  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
3263  * SCIPlpiIsOptimal() returns true.
3264  */
3266  SCIP_LPI* lpi, /**< LP interface structure */
3267  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3268  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3269  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3270  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3271  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3272  )
3273 {
3274  SCIPdebugMessage("calling SCIPlpiGetSol()\n");
3275 
3276  assert(lpi != NULL);
3277  assert(lpi->spx != NULL);
3278 
3279  if( objval != NULL )
3280  *objval = lpi->spx->objValueReal();
3281 
3282  try
3283  {
3284  if( primsol != NULL )
3285  {
3286 #if SOPLEX_APIVERSION > 10
3287  (void)lpi->spx->getPrimalReal(primsol, lpi->spx->numColsReal());
3288 #else
3289  Vector tmp(lpi->spx->numColsReal(), primsol);
3290  (void)lpi->spx->getPrimalReal(tmp);
3291 #endif
3292  }
3293  if( dualsol != NULL )
3294  {
3295 #if SOPLEX_APIVERSION > 10
3296  (void)lpi->spx->getDualReal(dualsol, lpi->spx->numRowsReal());
3297 #else
3298  Vector tmp(lpi->spx->numRowsReal(), dualsol);
3299  (void)lpi->spx->getDualReal(tmp);
3300 #endif
3301  }
3302  if( activity != NULL )
3303  {
3304 #if SOPLEX_APIVERSION > 10
3305  (void)lpi->spx->getSlacksReal(activity, lpi->spx->numRowsReal()); /* in SoPlex, the activities are called "slacks" */
3306 #else
3307  Vector tmp(lpi->spx->numRowsReal(), activity);
3308  (void)lpi->spx->getSlacksReal(tmp); /* in SoPlex, the activities are called "slacks" */
3309 #endif
3310  }
3311  if( redcost != NULL )
3312  {
3313 #if SOPLEX_APIVERSION > 10
3314  (void)lpi->spx->getRedCostReal(redcost, lpi->spx->numColsReal());
3315 #else
3316  Vector tmp(lpi->spx->numColsReal(), redcost);
3317  (void)lpi->spx->getRedCostReal(tmp);
3318 #endif
3319  }
3320  }
3321 #ifndef NDEBUG
3322  catch( const SPxException& x )
3323  {
3324  std::string s = x.what();
3325  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3326 #else
3327  catch( const SPxException& )
3328  {
3329 #endif
3330  return SCIP_LPERROR;
3331  }
3332 
3333  return SCIP_OKAY;
3334 }
3335 
3336 /** gets primal ray for unbounded LPs */
3338  SCIP_LPI* lpi, /**< LP interface structure */
3339  SCIP_Real* ray /**< primal ray */
3340  )
3341 { /*lint --e{715}*/
3342  SCIPdebugMessage("calling SCIPlpiGetPrimalRay()\n");
3343 
3344  assert(lpi != NULL);
3345  assert(lpi->spx != NULL);
3346  assert(lpi->spx->hasPrimalRay());
3347  assert(ray != NULL);
3348 
3349  try
3350  {
3351 #if SOPLEX_APIVERSION > 10
3352  (void)lpi->spx->getPrimalRayReal(ray, lpi->spx->numColsReal());
3353 #else
3354  Vector tmp(lpi->spx->numColsReal(), ray);
3355  (void)lpi->spx->getPrimalRayReal(tmp);
3356 #endif
3357  }
3358 #ifndef NDEBUG
3359  catch( const SPxException& x )
3360  {
3361  std::string s = x.what();
3362  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3363 #else
3364  catch( const SPxException& )
3365  {
3366 #endif
3367  return SCIP_LPERROR;
3368  }
3369 
3370  return SCIP_OKAY;
3371 }
3372 
3373 /** gets dual farkas proof for infeasibility */
3375  SCIP_LPI* lpi, /**< LP interface structure */
3376  SCIP_Real* dualfarkas /**< dual farkas row multipliers */
3377  )
3378 {
3379  SCIPdebugMessage("calling SCIPlpiGetDualfarkas()\n");
3380 
3381  assert(lpi != NULL);
3382  assert(lpi->spx != NULL);
3383  assert(lpi->spx->hasDualFarkas());
3384  assert(dualfarkas != NULL);
3385 
3386  try
3387  {
3388 #if SOPLEX_APIVERSION > 10
3389  (void)lpi->spx->getDualFarkasReal(dualfarkas, lpi->spx->numRowsReal());
3390 #else
3391  Vector tmp(lpi->spx->numRowsReal(), dualfarkas);
3392  (void)lpi->spx->getDualFarkasReal(tmp);
3393 #endif
3394  }
3395 #ifndef NDEBUG
3396  catch( const SPxException& x )
3397  {
3398  std::string s = x.what();
3399  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3400 #else
3401  catch( const SPxException& )
3402  {
3403 #endif
3404  return SCIP_LPERROR;
3405  }
3406 
3407  return SCIP_OKAY;
3408 }
3409 
3410 /** gets the number of LP iterations of the last solve call */
3412  SCIP_LPI* lpi, /**< LP interface structure */
3413  int* iterations /**< pointer to store the number of iterations of the last solve call */
3414  )
3415 {
3416  SCIPdebugMessage("calling SCIPlpiGetIterations()\n");
3417 
3418  assert(lpi != NULL);
3419  assert(lpi->spx != NULL);
3420  assert(iterations != NULL);
3421 
3422  *iterations = lpi->spx->numIterations();
3423 
3424  return SCIP_OKAY;
3425 }
3426 
3427 /** gets information about the quality of an LP solution
3428  *
3429  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3430  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3431  */
3433  SCIP_LPI* lpi, /**< LP interface structure */
3434  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3435  SCIP_Real* quality /**< pointer to store quality number */
3436  )
3437 {
3438  SCIPdebugMessage("calling SCIPlpiGetRealSolQuality()\n");
3439 
3440  assert(lpi != NULL);
3441  assert(quality != NULL);
3442 
3443  bool success;
3444 
3445  SCIPdebugMessage("requesting solution quality from SoPlex: quality %d\n", qualityindicator);
3446 
3447  switch( qualityindicator )
3448  {
3450  success = lpi->spx->getEstimatedCondition(*quality);
3451  break;
3452 
3454  success = lpi->spx->getExactCondition(*quality);
3455  break;
3456 
3457  default:
3458  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3459  return SCIP_INVALIDDATA;
3460  }
3461 
3462  if( !success )
3463  {
3464  SCIPdebugMessage("problem computing condition number\n");
3465  *quality = SCIP_INVALID;
3466  }
3467 
3468  return SCIP_OKAY;
3469 }
3470 
3471 /**@} */
3472 
3473 
3474 
3475 
3476 /*
3477  * LP Basis Methods
3478  */
3479 
3480 /**@name LP Basis Methods */
3481 /**@{ */
3482 
3483 
3484 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3486  SCIP_LPI* lpi, /**< LP interface structure */
3487  int* cstat, /**< array to store column basis status, or NULL */
3488  int* rstat /**< array to store row basis status, or NULL */
3489  )
3490 {
3491  int i;
3492 
3493  SCIPdebugMessage("calling SCIPlpiGetBase()\n");
3494 
3495  assert(lpi != NULL);
3496  assert(lpi->spx != NULL);
3497 
3498  assert( lpi->spx->preStrongbranchingBasisFreed() );
3499 
3500  if( rstat != NULL )
3501  {
3502  for( i = 0; i < lpi->spx->numRowsReal(); ++i )
3503  {
3504  switch( lpi->spx->basisRowStatus(i) )
3505  {
3506  case SPxSolver::BASIC:
3507  rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3508  break;
3509  case SPxSolver::FIXED:
3510  case SPxSolver::ON_LOWER:
3511  rstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3512  break;
3513  case SPxSolver::ON_UPPER:
3514  rstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3515  break;
3516  case SPxSolver::ZERO:
3517  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
3518  return SCIP_LPERROR;
3519  case SPxSolver::UNDEFINED:
3520  default:
3521  SCIPerrorMessage("invalid basis status\n");
3522  SCIPABORT();
3523  return SCIP_INVALIDDATA; /*lint !e527*/
3524  }
3525  }
3526  }
3527 
3528  if( cstat != NULL )
3529  {
3530  for( i = 0; i < lpi->spx->numColsReal(); ++i )
3531  {
3532 // SCIP_Real val = 0.0;
3533  switch( lpi->spx->basisColStatus(i) )
3534  {
3535  case SPxSolver::BASIC:
3536  cstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3537  break;
3538  case SPxSolver::FIXED:
3539  /* Get reduced cost estimation. If the estimation is not correct this should not hurt:
3540  * If the basis is loaded into SoPlex again, the status is converted to FIXED again; in
3541  * this case there is no problem at all. If the basis is saved and/or used in some other
3542  * solver, it usually is very cheap to perform the pivots necessary to get an optimal
3543  * basis.
3544  * @todo implement getRedCostEst()
3545  * */
3546 // SCIP_CALL( getRedCostEst(lpi->spx, i, &val) );
3547 // if( val < 0.0 ) /* reduced costs < 0 => UPPER else => LOWER */
3548 // cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3549 // else
3550  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3551  break;
3552  case SPxSolver::ON_LOWER:
3553  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3554  break;
3555  case SPxSolver::ON_UPPER:
3556  cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3557  break;
3558  case SPxSolver::ZERO:
3559  cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
3560  break;
3561  case SPxSolver::UNDEFINED:
3562  default:
3563  SCIPerrorMessage("invalid basis status\n");
3564  SCIPABORT();
3565  return SCIP_INVALIDDATA; /*lint !e527*/
3566  }
3567  }
3568  }
3569 
3570  return SCIP_OKAY;
3571 }
3572 
3573 /** sets current basis status for columns and rows */
3575  SCIP_LPI* lpi, /**< LP interface structure */
3576  const int* cstat, /**< array with column basis status */
3577  const int* rstat /**< array with row basis status */
3578  )
3579 {
3580  int i;
3581  int ncols;
3582  int nrows;
3583 
3584  SCIPdebugMessage("calling SCIPlpiSetBase()\n");
3585 
3586  assert(lpi != NULL);
3587  assert(lpi->spx != NULL);
3588 
3589  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3590  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3591 
3592  assert(cstat != NULL || ncols == 0);
3593  assert(rstat != NULL || nrows == 0);
3594 
3595  assert( lpi->spx->preStrongbranchingBasisFreed() );
3596  invalidateSolution(lpi);
3597 
3598  DataArray<SPxSolver::VarStatus>& _colstat = lpi->spx->colStat();
3599  DataArray<SPxSolver::VarStatus>& _rowstat = lpi->spx->rowStat();
3600 
3601  _colstat.reSize(ncols);
3602  _rowstat.reSize(nrows);
3603 
3604  for( i = 0; i < nrows; ++i )
3605  {
3606  switch( rstat[i] ) /*lint !e613*/
3607  {
3608  case SCIP_BASESTAT_LOWER:
3609  _rowstat[i] = SPxSolver::ON_LOWER;
3610  break;
3611  case SCIP_BASESTAT_BASIC:
3612  _rowstat[i] = SPxSolver::BASIC;
3613  break;
3614  case SCIP_BASESTAT_UPPER:
3615  _rowstat[i] = SPxSolver::ON_UPPER;
3616  break;
3617  case SCIP_BASESTAT_ZERO:
3618  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
3619  return SCIP_LPERROR; /*lint !e429*/
3620  default:
3621  SCIPerrorMessage("invalid basis status\n");
3622  SCIPABORT();
3623  return SCIP_INVALIDDATA; /*lint !e527*/
3624  }
3625  }
3626 
3627  for( i = 0; i < ncols; ++i )
3628  {
3629  switch( cstat[i] ) /*lint !e613*/
3630  {
3631  case SCIP_BASESTAT_LOWER:
3632  _colstat[i] = SPxSolver::ON_LOWER;
3633  break;
3634  case SCIP_BASESTAT_BASIC:
3635  _colstat[i] = SPxSolver::BASIC;
3636  break;
3637  case SCIP_BASESTAT_UPPER:
3638  _colstat[i] = SPxSolver::ON_UPPER;
3639  break;
3640  case SCIP_BASESTAT_ZERO:
3641  _colstat[i] = SPxSolver::ZERO;
3642  break;
3643  default:
3644  SCIPerrorMessage("invalid basis status\n");
3645  SCIPABORT();
3646  return SCIP_INVALIDDATA; /*lint !e527*/
3647  }
3648  }
3649 
3650  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setBasis(_rowstat.get_ptr(), _colstat.get_ptr()) );
3651  lpi->spx->freePreStrongbranchingBasis();
3652 
3653  return SCIP_OKAY;
3654 }
3655 
3656 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3658  SCIP_LPI* lpi, /**< LP interface structure */
3659  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3660  )
3661 {
3662  SCIPdebugMessage("calling SCIPlpiGetBasisInd()\n");
3663 
3664  assert(lpi != NULL);
3665  assert(lpi->spx != NULL);
3666  assert(bind != NULL);
3667 
3668  assert(lpi->spx->preStrongbranchingBasisFreed());
3669 
3670  lpi->spx->getBasisInd(bind);
3671 
3672  return SCIP_OKAY;
3673 }
3674 
3675 
3676 /** get row of inverse basis matrix B^-1
3677  *
3678  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3679  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3680  * see also the explanation in lpi.h.
3681  */
3683  SCIP_LPI* lpi, /**< LP interface structure */
3684  int r, /**< row number */
3685  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3686  int* inds, /**< array to store the non-zero indices, or NULL */
3687  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3688  * (-1: if we do not store sparsity information) */
3689  )
3690 {
3691  SCIPdebugMessage("calling SCIPlpiGetBInvRow()\n");
3692 
3693  assert(lpi != NULL);
3694  assert(lpi->spx != NULL);
3695  assert(lpi->spx->preStrongbranchingBasisFreed());
3696  assert(coef != NULL);
3697 
3698  assert(r >= 0);
3699  assert(r < lpi->spx->numRowsReal());
3700 
3701  if( ! lpi->spx->getBasisInverseRowReal(r, coef, inds, ninds) )
3702  return SCIP_LPERROR;
3703 
3704  return SCIP_OKAY;
3705 }
3706 
3707 /** get column of inverse basis matrix B^-1
3708  *
3709  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3710  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3711  * see also the explanation in lpi.h.
3712  */
3714  SCIP_LPI* lpi, /**< LP interface structure */
3715  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3716  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3717  * B^-1 column numbers to the row and column numbers of the LP!
3718  * c must be between 0 and nrows-1, since the basis has the size
3719  * nrows * nrows */
3720  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3721  int* inds, /**< array to store the non-zero indices, or NULL */
3722  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3723  * (-1: if we do not store sparsity information) */
3724  )
3725 {
3726  SCIPdebugMessage("calling SCIPlpiGetBInvCol()\n");
3727 
3728  assert( lpi != NULL );
3729  assert( lpi->spx != NULL );
3730  assert( lpi->spx->preStrongbranchingBasisFreed() );
3731  assert(coef != NULL);
3732 
3733  if( ! lpi->spx->getBasisInverseColReal(c, coef, inds, ninds) )
3734  return SCIP_LPERROR;
3735 
3736  return SCIP_OKAY;
3737 }
3738 
3739 /** get row of inverse basis matrix times constraint matrix B^-1 * A
3740  *
3741  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3742  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3743  * see also the explanation in lpi.h.
3744  */
3746  SCIP_LPI* lpi, /**< LP interface structure */
3747  int r, /**< row number */
3748  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3749  SCIP_Real* coef, /**< vector to return coefficients of the row */
3750  int* inds, /**< array to store the non-zero indices, or NULL */
3751  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3752  * (-1: if we do not store sparsity information) */
3753  )
3754 {
3755  SCIP_Real* buf;
3756  SCIP_Real* binv;
3757  int nrows;
3758  int ncols;
3759  int c;
3760 
3761  SCIPdebugMessage("calling SCIPlpiGetBInvARow()\n");
3762 
3763  assert(lpi != NULL);
3764  assert(lpi->spx != NULL);
3765  assert( lpi->spx->preStrongbranchingBasisFreed() );
3766  assert(coef != NULL);
3767 
3768  nrows = lpi->spx->numRowsReal();
3769  ncols = lpi->spx->numColsReal();
3770  buf = NULL;
3771 
3772  /* get (or calculate) the row in B^-1 */
3773  if( binvrow == NULL )
3774  {
3775  SCIP_ALLOC( BMSallocMemoryArray(&buf, nrows) );
3776  SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buf, inds, ninds) );
3777  binv = buf;
3778  }
3779  else
3780  binv = const_cast<SCIP_Real*>(binvrow);
3781 
3782  assert(binv != NULL);
3783 
3784  /* mark sparsity pattern as invalid */
3785  if( ninds != NULL )
3786  *ninds = -1;
3787 
3788  // @todo exploit sparsity in binv by looping over nrows
3789  /* calculate the scalar product of the row in B^-1 and A */
3790  Vector binvvec(nrows, binv);
3791 
3792 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3793  /* temporary unscaled column of A */
3794  DSVector acol;
3795 #endif
3796 
3797  for( c = 0; c < ncols; ++c )
3798  {
3799 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3800  lpi->spx->getColVectorReal(c, acol);
3801  coef[c] = binvvec * acol; /* scalar product */ /*lint !e1702*/
3802 #else
3803  coef[c] = binvvec * lpi->spx->colVectorReal(c); /* scalar product */ /*lint !e1702*/
3804 #endif
3805  }
3806 
3807  /* free memory if it was temporarily allocated */
3808  BMSfreeMemoryArrayNull(&buf);
3809 
3810  return SCIP_OKAY;
3811 }
3812 
3813 /** get column of inverse basis matrix times constraint matrix B^-1 * A
3814  *
3815  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3816  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3817  * see also the explanation in lpi.h.
3818  */
3820  SCIP_LPI* lpi, /**< LP interface structure */
3821  int c, /**< column number */
3822  SCIP_Real* coef, /**< vector to return coefficients of the column */
3823  int* inds, /**< array to store the non-zero indices, or NULL */
3824  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3825  * (-1: if we do not store sparsity information) */
3826  )
3827 { /*lint --e{715}*/
3828  /* create a new uninitialized full vector */
3829  DVector col(lpi->spx->numRowsReal());
3830 
3831 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3832  /* temporary sparse vector used for unscaling (memory is automatically enlarged) */
3833  DSVector colsparse;
3834 #endif
3835 
3836  SCIPdebugMessage("calling SCIPlpiGetBInvACol()\n");
3837 
3838  assert( lpi != NULL );
3839  assert( lpi->spx != NULL );
3840  assert( lpi->spx->preStrongbranchingBasisFreed() );
3841  assert(coef != NULL);
3842 
3843  /* extract column c of A */
3844  assert(c >= 0);
3845  assert(c < lpi->spx->numColsReal());
3846 
3847  /* @todo implement this with sparse vectors */
3848  /* mark sparsity pattern as invalid */
3849  if( ninds != NULL )
3850  *ninds = -1;
3851 
3852  /* col needs to be cleared because copying colVectorReal only regards nonzeros */
3853  col.clear();
3854 
3855 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 4)
3856  lpi->spx->getColVectorReal(c, colsparse);
3857  /* the copy is necessary to transform the sparse column into a dense vector */
3858  col = colsparse;
3859 #else
3860  col = lpi->spx->colVectorReal(c);
3861 #endif
3862 
3863  /* solve */
3864  if( ! lpi->spx->getBasisInverseTimesVecReal(col.get_ptr(), coef) )
3865  return SCIP_LPERROR;
3866 
3867  return SCIP_OKAY;
3868 }
3869 
3870 /**@} */
3871 
3872 
3873 
3874 
3875 /*
3876  * LP State Methods
3877  */
3878 
3879 /**@name LP State Methods */
3880 /**@{ */
3881 
3882 /** stores LPi state (like basis information) into lpistate object */
3884  SCIP_LPI* lpi, /**< LP interface structure */
3885  BMS_BLKMEM* blkmem, /**< block memory */
3886  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3887  )
3888 {
3889  int ncols;
3890  int nrows;
3891 
3892  SCIPdebugMessage("calling SCIPlpiGetState()\n");
3893 
3894  assert(blkmem != NULL);
3895  assert(lpi != NULL);
3896  assert(lpi->spx != NULL);
3897  assert(lpistate != NULL);
3898 
3899  assert( lpi->spx->preStrongbranchingBasisFreed() );
3900 
3901  ncols = lpi->spx->numColsReal();
3902  nrows = lpi->spx->numRowsReal();
3903  assert(ncols >= 0);
3904  assert(nrows >= 0);
3905 
3906  /* allocate lpistate data */
3907  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3908 
3909  /* allocate enough memory for storing uncompressed basis information */
3910  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3911  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3912 
3913  /* get unpacked basis information */
3914  SCIP_CALL( SCIPlpiGetBase(lpi, lpi->cstat, lpi->rstat) );
3915 
3916  /* pack LPi state data */
3917  (*lpistate)->ncols = ncols;
3918  (*lpistate)->nrows = nrows;
3919  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3920 
3921  return SCIP_OKAY;
3922 }
3923 
3924 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3925  * columns and rows since the state was stored with SCIPlpiGetState()
3926  */
3928  SCIP_LPI* lpi, /**< LP interface structure */
3929  BMS_BLKMEM* /*blkmem*/, /**< block memory */
3930  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
3931  )
3932 {
3933  int lpncols;
3934  int lpnrows;
3935  int i;
3936 
3937  SCIPdebugMessage("calling SCIPlpiSetState()\n");
3938 
3939  assert(lpi != NULL);
3940  assert(lpi->spx != NULL);
3941  assert(lpistate != NULL);
3942  /* assert(blkmem != NULL); */
3943 
3944  assert( lpi->spx->preStrongbranchingBasisFreed() );
3945 
3946  lpncols = lpi->spx->numColsReal();
3947  lpnrows = lpi->spx->numRowsReal();
3948  assert(lpistate->ncols <= lpncols);
3949  assert(lpistate->nrows <= lpnrows);
3950 
3951  /* allocate enough memory for storing uncompressed basis information */
3952  SCIP_CALL( ensureCstatMem(lpi, lpncols) );
3953  SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
3954 
3955  /* unpack LPi state data */
3956  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3957 
3958  /* extend the basis to the current LP beyond the previously existing columns */
3959  for( i = lpistate->ncols; i < lpncols; ++i )
3960  {
3961  SCIP_Real bnd = lpi->spx->lowerReal(i);
3962  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3963  {
3964  /* if lower bound is +/- infinity -> try upper bound */
3965  bnd = lpi->spx->lowerReal(i);
3966  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3967  /* variable is free */
3968  lpi->cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
3969  else
3970  /* use finite upper bound */
3971  lpi->cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3972  }
3973  else
3974  /* use finite lower bound */
3975  lpi->cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3976  }
3977  for( i = lpistate->nrows; i < lpnrows; ++i )
3978  lpi->rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3979 
3980  /* load basis information */
3981  SCIP_CALL( SCIPlpiSetBase(lpi, lpi->cstat, lpi->rstat) );
3982 
3983  return SCIP_OKAY;
3984 }
3985 
3986 /** clears current LPi state (like basis information) of the solver */
3988  SCIP_LPI* lpi /**< LP interface structure */
3989  )
3990 { /*lint --e{715}*/
3991  SCIPdebugMessage("calling SCIPlpiClearState()\n");
3992 
3993  assert(lpi != NULL);
3994  assert(lpi->spx != NULL);
3995 
3996  try
3997  {
3998  lpi->spx->clearBasis();
3999  }
4000 #ifndef NDEBUG
4001  catch( const SPxException& x )
4002  {
4003  std::string s = x.what();
4004  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4005 #else
4006  catch( const SPxException& )
4007  {
4008 #endif
4009  assert( lpi->spx->status() != SPxSolver::OPTIMAL );
4010  return SCIP_LPERROR;
4011  }
4012 
4013  return SCIP_OKAY;
4014 }
4015 
4016 /** frees LPi state information */
4018  SCIP_LPI* lpi, /**< LP interface structure */
4019  BMS_BLKMEM* blkmem, /**< block memory */
4020  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4021  )
4022 { /*lint --e{715}*/
4023  SCIPdebugMessage("calling SCIPlpiFreeState()\n");
4024 
4025  assert(lpi != NULL);
4026  assert(lpistate != NULL);
4027  assert(blkmem != NULL);
4028 
4029  if ( *lpistate != NULL )
4030  lpistateFree(lpistate, blkmem);
4031 
4032  return SCIP_OKAY;
4033 }
4034 
4035 /** checks, whether the given LP state contains simplex basis information */
4037  SCIP_LPI* lpi, /**< LP interface structure */
4038  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4039  )
4040 { /*lint --e{715}*/
4041  assert(lpi != NULL);
4042  return TRUE;
4043 }
4044 
4045 /** reads LP state (like basis information from a file */
4047  SCIP_LPI* lpi, /**< LP interface structure */
4048  const char* fname /**< file name */
4049  )
4050 {
4051  SCIPdebugMessage("calling SCIPlpiReadState()\n");
4052  assert(lpi != NULL);
4053  assert(lpi->spx != NULL);
4054  assert(fname != NULL);
4055 
4056  assert( lpi->spx->preStrongbranchingBasisFreed() );
4057 
4058  bool success;
4059  SOPLEX_TRY( lpi->messagehdlr, success = lpi->spx->readBasisFile(fname, 0, 0) );
4060 
4061  return success ? SCIP_OKAY : SCIP_LPERROR;
4062 }
4063 
4064 /** writes LPi state (i.e. basis information) to a file */
4066  SCIP_LPI* lpi, /**< LP interface structure */
4067  const char* fname /**< file name */
4068  )
4069 {
4070  assert(lpi != NULL);
4071  assert(lpi->spx != NULL);
4072  assert(fname != NULL);
4073  SCIPdebugMessage("calling SCIPlpiWriteState()\n");
4074 
4075  assert( lpi->spx->preStrongbranchingBasisFreed() );
4076 
4077  bool res;
4078  SOPLEX_TRY( lpi->messagehdlr, res = lpi->spx->writeBasisFile(fname, 0, 0) );
4079 
4080  if ( ! res )
4081  return SCIP_LPERROR;
4082 
4083  return SCIP_OKAY;
4084 }
4085 
4086 /**@} */
4087 
4088 
4089 
4090 
4091 /*
4092  * LP Pricing Norms Methods
4093  */
4094 
4095 /**@name LP Pricing Norms Methods */
4096 /**@{ */
4097 
4098 /** stores LPi pricing norms information
4099  * @todo should we store norm information?
4100  */
4102  SCIP_LPI* lpi, /**< LP interface structure */
4103  BMS_BLKMEM* blkmem, /**< block memory */
4104  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4105  )
4106 { /*lint --e{715}*/
4107 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4108  int nrows;
4109  int ncols;
4110 
4111  assert(blkmem != NULL);
4112  assert(lpi != NULL);
4113  assert(lpi->spx != NULL);
4114  assert(lpinorms != NULL);
4115 
4116  lpi->spx->getNdualNorms(nrows, ncols);
4117 
4118  if( nrows == 0 && ncols == 0)
4119  {
4120  (*lpinorms = NULL);
4121  return SCIP_OKAY;
4122  }
4123 
4124  /* allocate lpinorms data */
4125  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4126  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols) );
4127  (*lpinorms)->nrows = 0;
4128  (*lpinorms)->ncols = 0;
4129 
4130  SCIPdebugMessage("storing SoPlex LPi pricing norms in %p (%d rows, %d cols)\n", (void *) *lpinorms, nrows, ncols);
4131 
4132  if( !lpi->spx->getDualNorms((*lpinorms)->nrows, (*lpinorms)->ncols, (*lpinorms)->norms) )
4133  {
4134  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
4135  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols);
4136  BMSfreeBlockMemory(blkmem, lpinorms);
4137  assert(*lpinorms == NULL);
4138  }
4139 #ifndef NDEBUG
4140  else
4141  {
4142  assert(nrows == (*lpinorms)->nrows);
4143  assert(ncols == (*lpinorms)->ncols);
4144  }
4145 #endif
4146 #else
4147  (*lpinorms) = NULL;
4148 #endif
4149 
4150  return SCIP_OKAY;
4151 }
4152 
4153 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4154  * columns and rows since the state was stored with SCIPlpiGetNorms()
4155  */
4157  SCIP_LPI* lpi, /**< LP interface structure */
4158  BMS_BLKMEM* blkmem, /**< block memory */
4159  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
4160  )
4161 { /*lint --e{715}*/
4162 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4163  assert(blkmem != NULL);
4164  assert(lpi != NULL);
4165  assert(lpi->spx != NULL);
4166 
4167  /* if there was no pricing norms information available, the LPi norms were not stored */
4168  if( lpinorms == NULL )
4169  return SCIP_OKAY;
4170 
4171  assert(lpinorms->nrows <= lpi->spx->numRowsReal());
4172  assert(lpinorms->ncols <= lpi->spx->numColsReal());
4173 
4174  if( lpinorms->nrows == 0 )
4175  return SCIP_OKAY;
4176 
4177  SCIPdebugMessage("loading LPi simplex norms %p (%d rows, %d cols) into SoPlex LP with %d rows and %d cols\n",
4178  (const void *) lpinorms, lpinorms->nrows, lpinorms->ncols, lpi->spx->numRowsReal(), lpi->spx->numColsReal());
4179 
4180  (void) lpi->spx->setDualNorms(lpinorms->nrows, lpinorms->ncols, lpinorms->norms);
4181 #endif
4182 
4183  return SCIP_OKAY;
4184 }
4185 
4186 /** frees pricing norms information */
4188  SCIP_LPI* lpi, /**< LP interface structure */
4189  BMS_BLKMEM* blkmem, /**< block memory */
4190  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
4191  )
4192 { /*lint --e{715}*/
4193 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4194  assert(lpi != NULL);
4195  assert(lpinorms != NULL);
4196 
4197  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
4198 
4199  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, (*lpinorms)->nrows + (*lpinorms)->ncols);
4200  BMSfreeBlockMemory(blkmem, lpinorms);
4201  assert(*lpinorms == NULL);
4202 #endif
4203 
4204  return SCIP_OKAY;
4205 }
4206 
4207 /**@} */
4208 
4209 
4210 
4211 
4212 /*
4213  * Parameter Methods
4214  */
4215 
4216 /**@name Parameter Methods */
4217 /**@{ */
4218 
4219 /** gets integer parameter of LP */
4221  SCIP_LPI* lpi, /**< LP interface structure */
4222  SCIP_LPPARAM type, /**< parameter number */
4223  int* ival /**< buffer to store the parameter value */
4224  )
4225 {
4226  int scaleparam;
4227 
4228  SCIPdebugMessage("calling SCIPlpiGetIntpar()\n");
4229 
4230  assert(lpi != NULL);
4231  assert(lpi->spx != NULL);
4232  assert(ival != NULL);
4233 
4234  switch( type )
4235  {
4237  *ival = lpi->spx->getFromScratch();
4238  break;
4239  case SCIP_LPPAR_LPINFO:
4240  *ival = lpi->spx->getLpInfo();
4241  break;
4242  case SCIP_LPPAR_LPITLIM:
4243  *ival = lpi->spx->intParam(SoPlex::ITERLIMIT);
4244  if( *ival == -1 )
4245  *ival = INT_MAX;
4246  break;
4247  case SCIP_LPPAR_PRESOLVING:
4248  *ival = lpi->spx->intParam(SoPlex::SIMPLIFIER);
4249  break;
4250  case SCIP_LPPAR_PRICING:
4251  *ival = (int) lpi->pricing;
4252  break;
4253  case SCIP_LPPAR_SCALING:
4254  scaleparam = lpi->spx->intParam(SoPlex::SCALER);
4255 
4256  if( scaleparam == SoPlex::SCALER_OFF )
4257  *ival = 0;
4258  else if( scaleparam == SoPlex::SCALER_BIEQUI )
4259  *ival = 1;
4260 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
4261  else
4262  {
4263  assert(scaleparam == SoPlex::SCALER_LEASTSQ);
4264  *ival = 2;
4265  }
4266 #else
4267  else
4268  {
4269  assert(scaleparam == SoPlex::SCALER_GEO8);
4270  *ival = 2;
4271  }
4272 #endif
4273  break;
4274 #if SOPLEX_VERSION >= 201
4275  case SCIP_LPPAR_TIMING:
4276  *ival = (int) (lpi->spx->intParam(SoPlex::TIMER));
4277  break;
4278 #endif
4279 #if SOPLEX_VERSION >= 230 || (SOPLEX_VERSION == 220 && SOPLEX_SUBVERSION >= 3)
4280  case SCIP_LPPAR_RANDOMSEED:
4281  *ival = (int) lpi->spx->randomSeed();
4282  break;
4283 #endif
4284 #if SOPLEX_APIVERSION >= 1
4285  case SCIP_LPPAR_REFACTOR:
4286  *ival = (int) lpi->spx->intParam(SoPlex::FACTOR_UPDATE_MAX);
4287  break;
4288 #endif
4289  default:
4290  return SCIP_PARAMETERUNKNOWN;
4291  } /*lint !e788*/
4292 
4293  return SCIP_OKAY;
4294 }
4295 
4296 /** sets integer parameter of LP */
4298  SCIP_LPI* lpi, /**< LP interface structure */
4299  SCIP_LPPARAM type, /**< parameter number */
4300  int ival /**< parameter value */
4301  )
4302 {
4303  SCIPdebugMessage("calling SCIPlpiSetIntpar()\n");
4304 
4305  assert(lpi != NULL);
4306  assert(lpi->spx != NULL);
4307 
4308  switch( type )
4309  {
4311  assert(ival == TRUE || ival == FALSE);
4312  lpi->spx->setFromScratch(bool(ival));
4313  break;
4314  case SCIP_LPPAR_LPINFO:
4315  assert(ival == TRUE || ival == FALSE);
4316  lpi->spx->setLpInfo(bool(ival));
4317  break;
4318  case SCIP_LPPAR_LPITLIM:
4319  assert( ival >= 0 );
4320  /* -1 <= ival, -1 meaning no time limit, 0 stopping immediately */
4321  if( ival >= INT_MAX )
4322  ival = -1;
4323  (void) lpi->spx->setIntParam(SoPlex::ITERLIMIT, ival);
4324  break;
4325  case SCIP_LPPAR_PRESOLVING:
4326  assert(ival == TRUE || ival == FALSE);
4327 #if SOPLEX_APIVERSION < 13
4328  assert(ival == TRUE || ival == FALSE);
4329 #else
4330  assert(ival == 1 || ival == 0 || ival == 2);
4331 #endif
4332  (void) lpi->spx->setIntParam(SoPlex::SIMPLIFIER, ival);
4333  break;
4334  case SCIP_LPPAR_PRICING:
4335  lpi->pricing = (SCIP_PRICING)ival;
4336  switch( lpi->pricing )
4337  {
4339  case SCIP_PRICING_AUTO:
4340  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_AUTO);
4341  break;
4342  case SCIP_PRICING_FULL:
4343  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_STEEP);
4344  break;
4345  case SCIP_PRICING_PARTIAL:
4346  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_PARMULT);
4347  break;
4348  case SCIP_PRICING_STEEP:
4349  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_STEEP);
4350  break;
4352  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_QUICKSTEEP);
4353  break;
4354  case SCIP_PRICING_DEVEX:
4355  (void) lpi->spx->setIntParam(SoPlex::PRICER, SoPlex::PRICER_DEVEX);
4356  break;
4357  default:
4358  return SCIP_LPERROR;
4359  }
4360  break;
4361  case SCIP_LPPAR_SCALING:
4362  assert(ival >= 0 && ival <= 2);
4363  if( ival == 0 )
4364  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_OFF);
4365  else if( ival == 1 )
4366  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_BIEQUI);
4367  else
4368 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 2)
4369  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_LEASTSQ);
4370 #else
4371  (void) lpi->spx->setIntParam(SoPlex::SCALER, SoPlex::SCALER_GEO8);
4372 #endif
4373 
4374  break;
4375 #if SOPLEX_VERSION >= 201
4376  case SCIP_LPPAR_TIMING:
4377  assert(ival >= 0 && ival < 3);
4378  (void) lpi->spx->setIntParam(SoPlex::TIMER, ival);
4379  break;
4380 #endif
4381 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3)
4382  case SCIP_LPPAR_RANDOMSEED:
4383  lpi->spx->setRandomSeed((unsigned long)(long)ival);
4384  break;
4385 #endif
4386 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION >= 221 && SOPLEX_SUBVERSION >= 3)
4387  case SCIP_LPPAR_POLISHING:
4388  assert(ival >= 0 && ival < 3);
4389  (void) lpi->spx->setIntParam(SoPlex::SOLUTION_POLISHING, ival);
4390  break;
4391 #endif
4392 #if SOPLEX_APIVERSION >= 1
4393  case SCIP_LPPAR_REFACTOR:
4394  assert(ival >= 0);
4395  (void) lpi->spx->setIntParam(SoPlex::FACTOR_UPDATE_MAX, ival);
4396  break;
4397 #endif
4398 
4399  default:
4400  return SCIP_PARAMETERUNKNOWN;
4401  } /*lint !e788*/
4402 
4403  return SCIP_OKAY;
4404 }
4405 
4406 /** gets floating point parameter of LP */
4408  SCIP_LPI* lpi, /**< LP interface structure */
4409  SCIP_LPPARAM type, /**< parameter number */
4410  SCIP_Real* dval /**< buffer to store the parameter value */
4411  )
4412 {
4413  SCIPdebugMessage("calling SCIPlpiGetRealpar()\n");
4414 
4415  assert(lpi != NULL);
4416  assert(lpi->spx != NULL);
4417  assert(dval != NULL);
4418 
4419  switch( type )
4420  {
4421  case SCIP_LPPAR_FEASTOL:
4422  *dval = lpi->spx->feastol();
4423  break;
4425  *dval = lpi->spx->opttol();
4426  break;
4427  case SCIP_LPPAR_OBJLIM:
4428  if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
4429  *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_UPPER);
4430  else
4431  *dval = lpi->spx->realParam(SoPlex::OBJLIMIT_LOWER);
4432  break;
4433  case SCIP_LPPAR_LPTILIM:
4434  *dval = lpi->spx->realParam(SoPlex::TIMELIMIT);
4435  break;
4437  *dval = lpi->spx->realParam(SoPlex::REPRESENTATION_SWITCH);
4438  if( *dval >= SCIPlpiInfinity(lpi) )
4439  *dval = -1.0;
4440  break;
4442  *dval = lpi->conditionlimit;
4443  break;
4444  case SCIP_LPPAR_MARKOWITZ:
4445 #if (SOPLEX_APIVERSION >= 9)
4446  *dval = lpi->spx->realParam(SoPlex::MIN_MARKOWITZ);
4447  break;
4448 #endif
4449  default:
4450  return SCIP_PARAMETERUNKNOWN;
4451  } /*lint !e788*/
4452 
4453  return SCIP_OKAY;
4454 }
4455 
4456 /** sets floating point parameter of LP */
4458  SCIP_LPI* lpi, /**< LP interface structure */
4459  SCIP_LPPARAM type, /**< parameter number */
4460  SCIP_Real dval /**< parameter value */
4461  )
4462 {
4463  SCIPdebugMessage("calling SCIPlpiSetRealpar()\n");
4464 
4465  assert(lpi != NULL);
4466  assert(lpi->spx != NULL);
4467 
4468  switch( type )
4469  {
4470  case SCIP_LPPAR_FEASTOL:
4471  /* 0 < dval */
4472  assert( dval > 0.0 );
4473  lpi->spx->setFeastol(dval);
4474  break;
4476  /* 0 < dval */
4477  assert( dval > 0.0 );
4478  lpi->spx->setOpttol(dval);
4479  break;
4480  case SCIP_LPPAR_OBJLIM:
4481  /* no restrictions on dval */
4482  if ( lpi->spx->intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE )
4483  (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_UPPER, dval);
4484  else
4485  (void) lpi->spx->setRealParam(SoPlex::OBJLIMIT_LOWER, dval);
4486  break;
4487  case SCIP_LPPAR_LPTILIM:
4488  assert( dval > 0.0 );
4489  /* soplex requires 0 < dval < DEFAULT_INFINITY (= 1e100), -1 means unlimited */
4490  (void) lpi->spx->setRealParam(SoPlex::TIMELIMIT, dval);
4491  break;
4493  /* 0 <= dval <= inf */
4494  assert( dval >= 0.0 || dval == -1.0 );
4495  if( dval == -1 )
4496  (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, SCIPlpiInfinity(lpi));
4497  else
4498  (void) lpi->spx->setRealParam(SoPlex::REPRESENTATION_SWITCH, dval);
4499  break;
4501  lpi->conditionlimit = dval;
4502  lpi->checkcondition = (dval >= 0.0);
4503  break;
4504  case SCIP_LPPAR_MARKOWITZ:
4505 #if (SOPLEX_APIVERSION >= 9)
4506  /* 1e-4 <= dval <= 0.999 */
4507  if( dval < 1e-4 )
4508  dval = 1e-4;
4509  else if( dval > 0.9999 )
4510  dval = 0.9999;
4511 
4512  (void) lpi->spx->setRealParam(SoPlex::MIN_MARKOWITZ, dval);
4513  break;
4514 #endif
4515  default:
4516  return SCIP_PARAMETERUNKNOWN;
4517  } /*lint !e788*/
4518 
4519  return SCIP_OKAY;
4520 }
4521 
4522 /** interrupts the currently ongoing lp solve or disables the interrupt */
4524  SCIP_LPI* lpi, /**< LP interface structure */
4525  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
4526  )
4527 {
4528  assert(lpi != NULL);
4529  assert(lpi->spx != NULL);
4530 
4531  lpi->spx->setInterrupt(interrupt);
4532 
4533  return SCIP_OKAY;
4534 }
4535 
4536 /**@} */
4537 
4538 
4539 
4540 
4541 /*
4542  * Numerical Methods
4543  */
4544 
4545 /**@name Numerical Methods */
4546 /**@{ */
4547 
4548 /** returns value treated as infinity in the LP solver */
4550  SCIP_LPI* lpi /**< LP interface structure */
4551  )
4553  assert(lpi != NULL);
4554  SCIPdebugMessage("calling SCIPlpiInfinity()\n");
4555 
4556  return lpi->spx->realParam(SoPlex::INFTY);
4557 }
4558 
4559 /** checks if given value is treated as infinity in the LP solver */
4561  SCIP_LPI* lpi, /**< LP interface structure */
4562  SCIP_Real val
4563  )
4564 {
4565  assert(lpi != NULL);
4566  SCIPdebugMessage("calling SCIPlpiIsInfinity()\n");
4567 
4568  return (val >= lpi->spx->realParam(SoPlex::INFTY));
4569 }
4570 
4571 /**@} */
4572 
4573 
4574 
4575 
4576 /*
4577  * File Interface Methods
4578  */
4579 
4580 /**@name File Interface Methods */
4581 /**@{ */
4582 
4583 /** returns, whether the given file exists */
4584 static
4586  const char* filename /**< file name */
4587  )
4589  FILE* f;
4590 
4591  f = fopen(filename, "r");
4592  if( f == NULL )
4593  return FALSE;
4594 
4595  fclose(f);
4596 
4597  return TRUE;
4598 }
4599 
4600 /** reads LP from a file */
4602  SCIP_LPI* lpi, /**< LP interface structure */
4603  const char* fname /**< file name */
4604  )
4605 {
4606  SCIPdebugMessage("calling SCIPlpiReadLP()\n");
4607 
4608  assert(lpi != NULL);
4609  assert(lpi->spx != NULL);
4610  assert(fname != NULL);
4611 
4612  assert( lpi->spx->preStrongbranchingBasisFreed() );
4613 
4614  if( !fileExists(fname) )
4615  return SCIP_NOFILE;
4616 
4617  try
4618  {
4619  assert(lpi->spx->intParam(SoPlex::READMODE) == SoPlex::READMODE_REAL);
4620  if( !lpi->spx->readFile(fname) )
4621  return SCIP_READERROR;
4622  }
4623 #ifndef NDEBUG
4624  catch( const SPxException& x )
4625  {
4626  std::string s = x.what();
4627  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4628 #else
4629  catch( const SPxException& )
4630  {
4631 #endif
4632  return SCIP_READERROR;
4633  }
4634 
4635  return SCIP_OKAY;
4636 }
4637 
4638 /** writes LP to a file */
4640  SCIP_LPI* lpi, /**< LP interface structure */
4641  const char* fname /**< file name */
4642  )
4643 {
4644  SCIPdebugMessage("calling SCIPlpiWriteLP()\n");
4645 
4646  assert(lpi != NULL);
4647  assert(lpi->spx != NULL);
4648  assert(fname != NULL);
4649 
4650  try
4651  {
4652  (void) lpi->spx->writeFileReal(fname);
4653  }
4654 #ifndef NDEBUG
4655  catch( const SPxException& x )
4656  {
4657  std::string s = x.what();
4658  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4659 #else
4660  catch( const SPxException& )
4661  {
4662 #endif
4663  return SCIP_WRITEERROR;
4664  }
4665 
4666  return SCIP_OKAY;
4667 }
4668 
4669 /**@} */
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3716
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_spx2.cpp:1884
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:95
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_spx2.cpp:1129
SCIP_Real conditionlimit
Definition: lpi_cpx.c:164
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *, const SCIP_LPISTATE *lpistate)
Definition: lpi_spx2.cpp:3930
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_spx2.cpp:4563
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3077
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_spx2.cpp:4159
ROWPACKET * packrstat
Definition: lpi_clp.cpp:128
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_spx2.cpp:3377
SCIP_PRICING pricing
Definition: lpi_clp.cpp:103
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2472
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:3268
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_spx2.cpp:4300
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2429
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:1010
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_spx2.cpp:3488
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:1584
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_spx2.cpp:4223
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_spx2.cpp:3414
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:1918
#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:4460
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2990
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx2.cpp:4104
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_spx2.cpp:1901
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4049
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_spx2.cpp:1047
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_spx2.cpp:2263
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:1507
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_spx2.cpp:3435
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_spx2.cpp:1795
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_spx2.cpp:2223
#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:1018
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:3990
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:1959
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:1075
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:3748
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:1240
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3003
#define ROWS_PER_PACKET
Definition: lpi_spx2.cpp:756
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3213
#define SOPLEX_TRY(messagehdlr, x)
Definition: lpi_spx2.cpp:146
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2443
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3137
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:1376
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:4642
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:3660
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:2805
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx2.cpp:4020
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
static char * spxdesc
Definition: lpi_spx2.cpp:976
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3021
static const char spxname[20]
Definition: lpi_spx2.cpp:974
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_spx2.cpp:2171
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:2775
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:2879
int * rstat
Definition: lpi_clp.cpp:99
#define REALABS(x)
Definition: def.h:201
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_spx2.cpp:1002
int cstatsize
Definition: lpi_clp.cpp:100
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_spx2.cpp:1055
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:2502
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_spx2.cpp:2954
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx2.cpp:4190
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_spx2.cpp:1454
static SCIP_Bool fileExists(const char *filename)
Definition: lpi_spx2.cpp:4588
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:4604
#define EPSCEIL(x, eps)
Definition: def.h:211
#define CHECK_SOPLEX_PARAM(x)
Definition: lpi_spx2.cpp:75
char * initSpxDesc()
Definition: lpi_spx2.cpp:978
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2935
#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:2975
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_spx2.cpp:3247
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx2.cpp:1476
#define SCIP_Bool
Definition: def.h:84
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_spx2.cpp:4039
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_spx2.cpp:1322
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx2.cpp:4068
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:4552
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_spx2.cpp:1633
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3103
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx2.cpp:3886
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3090
#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:2197
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:2357
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_spx2.cpp:3577
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3116
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_spx2.cpp:1039
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_spx2.cpp:1525
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3200
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:2067
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:2849
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_spx2.cpp:2457
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_spx2.cpp:3340
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:2486
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:1162
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_spx2.cpp:1721
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_spx2.cpp:2291
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:3064
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3822
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_spx2.cpp:2240
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3174
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3034
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:1677
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3049
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
#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:4526
struct fixed_graph_components FIXED
Definition: graphdefs.h:119
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_spx2.cpp:3187
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_spx2.cpp:2319
#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:1657
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx2.cpp:3685
#define SCIP_ALLOC(x)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:356
const char * SCIPlpiGetSolverName(void)
Definition: lpi_spx2.cpp:993
int * cstat
Definition: lpi_clp.cpp:98
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_spx2.cpp:3226
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_spx2.cpp:4410
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx2.cpp:1344
#define FEASTOL
Definition: lpi_qso.c:90