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