Scippy

SCIP

Solving Constraint Integer Programs

lpi_spx1.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_spx1.cpp
17  * @ingroup LPIS
18  * @brief LP interface for SoPlex version 1.4 and higher
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Ambros Gleixner
22  * @author Marc Pfetsch
23  *
24  * This is an implementation of SCIP's LP interface for SoPlex. While the ratio test is fixed to SoPlex's standard,
25  * different pricing methods can be chosen and an autopricing strategy (start with devex and switch to steepest edge
26  * after too many iterations) is implemented directly. Scaler and simplifier may be applied if solving from scratch.
27  *
28  * For debugging purposes, the SoPlex results can be double checked with CPLEX if WITH_LPSCHECK is defined. This may
29  * yield false positives, since the LP is dumped to a file for transfering it to CPLEX, hence, precision may be lost.
30  */
31 
32 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33 
34 #define AUTOPRICING_ITERSWITCH 10000/**< start with devex and switch to steepest edge after this many iterations */
35 #define STRONGBRANCH_RESTOREBASIS /**< if defined then in SCIPlpiStrongbranch() we restore the basis after the
36  * down branch and after the up branch; if false only after the end of a
37  * strong branching phase, which however seems to mostly increase strong
38  * branching time and iterations */
39 
40 /* in this case the SoPlex results are double checked using CPLEX */
41 #ifdef WITH_LPSCHECK
42 #include <cplex.h>
43 
44 #define CHECK_SPXSOLVE true /**< shall the SoPlex results in spxSolve() be double checked using CPLEX? */
45 #define CHECK_SPXSTRONGBRANCH true /**< shall the SoPlex results in SCIPlpStrongbranch() be double checked using CPLEX? */
46 #define CHECK_START 0 /**< skip first CHECK_START number of checks */
47 #define EXIT_AT_WRONG_RESULT false/**< shall program be exited if CPLEX returns different result than SoPlex? */
48 #define EXIT_AT_CPXERROR false/**< shall program be exited if CPLEX returns an error? */
49 
50 #define CPX_CALL(x) do \
51  { \
52  int _cpxstat_; \
53  if( (_cpxstat_ = (x)) != 0 ) \
54  { \
55  SCIPmessagePrintWarning(m_messagehdlr, "CPLEX error <%d>; SoPlex result unchecked\n", _cpxstat_); \
56  if( EXIT_AT_CPXERROR ) \
57  { \
58  exit(1); \
59  } \
60  else \
61  { \
62  goto ENDCHECK; \
63  } \
64  } \
65  } \
66  while( false )
67 #endif
68 
69 /* remember the original value of the SCIP_DEBUG define and undefine it */
70 #ifdef SCIP_DEBUG
71 #define ___DEBUG
72 #undef SCIP_DEBUG
73 #endif
74 
75 /* include SoPlex solver */
76 #include "spxsolver.h"
77 
78 /* define subversion for versions <= 1.5.0.1 */
79 #ifndef SOPLEX_SUBVERSION
80 #define SOPLEX_SUBVERSION 0
81 #endif
82 
83 /* check version */
84 #if (SOPLEX_VERSION < 133)
85 #error "This interface is not compatible with SoPlex versions prior to 1.4"
86 #endif
87 
88 /* get githash of SoPlex */
89 #if (SOPLEX_VERSION >= 160)
90 #include "spxgithash.h"
91 #endif
92 
93 /* include SoPlex components */
94 #include "slufactor.h"
95 #include "spxsteeppr.h"
96 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 6) || SOPLEX_VERSION > 160)
97 #include "spxsteepexpr.h"
98 #endif
99 #include "spxparmultpr.h"
100 #include "spxdevexpr.h"
101 #include "spxfastrt.h"
102 #include "spxmainsm.h"
103 #include "spxequilisc.h"
104 
105 #define WITH_BOUNDFLIPPING
106 #ifdef WITH_BOUNDFLIPPING
107 #include "spxboundflippingrt.h"
108 #endif
109 
110 /* reset the SCIP_DEBUG define to its original SCIP value */
111 #undef SCIP_DEBUG
112 #ifdef ___DEBUG
113 #define SCIP_DEBUG
114 #undef ___DEBUG
115 #endif
116 
117 /* define snprintf when using a too old MSVC version */
118 #if defined(_MSC_VER) && _MSC_VER < 1900
119 #ifndef snprintf
120 #define snprintf _snprintf
121 #endif
122 #endif
123 
124 #define SOPLEX_VERBLEVEL 5 /**< verbosity level for LPINFO */
125 
126 #include "scip/pub_message.h"
128 /********************************************************************/
129 /*----------------------------- C++ --------------------------------*/
130 /********************************************************************/
131 
132 /* in C++ we have to use "0" instead of "(void*)0" */
133 #undef NULL
134 #define NULL 0
135 
136 #include <cassert>
137 using namespace soplex;
138 
139 
140 /** Macro for a single SoPlex call for which exceptions have to be catched - return an LP error. We
141  * make no distinction between different exception types, e.g., between memory allocation and other
142  * exceptions.
143  */
144 #ifndef NDEBUG
145 #define SOPLEX_TRY(messagehdlr, x) do \
146  { \
147  try \
148  { \
149  (x); \
150  } \
151  catch( const SPxMemoryException& E ) \
152  { \
153  std::string s = E.what(); \
154  SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
155  return SCIP_ERROR; \
156  } \
157  catch( const SPxException& E ) \
158  { \
159  std::string s = E.what(); \
160  SCIPmessagePrintWarning((messagehdlr), "SoPlex threw an exception: %s\n", s.c_str()); \
161  return SCIP_LPERROR; \
162  } \
163  } \
164  while( FALSE )
165 
166 #else
167 #define SOPLEX_TRY(messagehdlr, x) do \
168  { \
169  try \
170  { \
171  (x); \
172  } \
173  catch( const SPxMemoryException& E ) \
174  { \
175  std::string s = E.what(); \
176  SCIPerrorMessage("SoPlex threw a memory exception: %s\n", s.c_str()); \
177  return SCIP_ERROR; \
178  } \
179  catch( const SPxException& ) \
180  { \
181  return SCIP_LPERROR; \
182  } \
183  } \
184  while( FALSE )
185 #endif
186 
187 /* Macro for a single SoPlex call for which exceptions have to be catched - abort if they
188  * arise. SCIP_ABORT() is not accessible here.
189  */
190 #define SOPLEX_TRY_ABORT(x) do \
191  { \
192  try \
193  { \
194  (x); \
195  } \
196  catch( const SPxException& E ) \
197  { \
198  std::string s = E.what(); \
199  SCIPerrorMessage("SoPlex threw an exception: %s\n", s.c_str()); \
200  abort(); \
201  } \
202  } \
203  while( FALSE )
204 
205 
206 
207 /** SCIP's SoPlex class */
208 class SPxSCIP : public SPxSolver
209 {
210  SPxLP::SPxSense m_sense; /**< optimization sense */
211  SLUFactor m_slu; /**< sparse LU factorization */
212  SPxSteepPR m_price_steep; /**< steepest edge pricer */
213 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 6) || SOPLEX_VERSION > 160)
214  SPxSteepExPR m_price_steep_ex; /**< steepest edge with exact weight initialization */
215 #else
216  SPxSteepPR m_price_steep_ex; /**< fallback to quick start pricer */
217 #endif
218  SPxParMultPR m_price_parmult; /**< partial multiple pricer */
219  SPxDevexPR m_price_devex; /**< devex pricer */
220 #ifdef WITH_BOUNDFLIPPING
221  SPxBoundFlippingRT m_ratio; /**< Long step dual ratio tester */
222 #else
223  SPxFastRT m_ratio; /**< Harris fast ratio tester */
224 #endif
225  char* m_probname; /**< problem name */
226  bool m_fromscratch; /**< use old basis indicator */
227  bool m_presolving; /**< use lp presolving */
228  Real m_lpifeastol; /**< feastol set by SCIPlpiSetRealpar() */
229  Real m_lpiopttol; /**< opttol set by SCIPlpiSetRealpar() */
230  Real m_objLoLimit; /**< lower objective limit */
231  Real m_objUpLimit; /**< upper objective limit */
232  Status m_stat; /**< solving status */
233  bool m_lpinfo; /**< storing whether output is turned on */
234  bool m_autopricing; /**< is automatic pricing selected? */
235  int m_itlim; /**< iteration limit (-1 for unbounded) */
236  int m_itused; /**< number of iterations spent in phase one of auto pricing */
237  int m_scaling; /**< LP scaling (0: none, 1: normal, 2: aggressive) */
238  DataArray<SPxSolver::VarStatus> m_rowstat; /**< basis status of rows before starting strong branching (if available, 0 otherwise) */
239  DataArray<SPxSolver::VarStatus> m_colstat; /**< basis status of columns before starting strong branching (if available, 0 otherwise) */
240  NameSet* m_rownames; /**< row names */
241  NameSet* m_colnames; /**< column names */
242 
243 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
244  SPxOut m_spxout;
245 #endif
246 
247 #ifdef WITH_LPSCHECK
248  int m_checknum;
249  bool m_doublecheck;
250  CPXENVptr m_cpxenv; /**< CPLEX memory environment */
251  CPXLPptr m_cpxlp; /**< CPLEX lp structure */
252 #endif
253  SCIP_MESSAGEHDLR* m_messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
254 
255 public:
256  SPxSCIP(
257  SCIP_MESSAGEHDLR* messagehdlr = NULL, /**< message handler */
258  const char* probname = NULL /**< name of problem */
259  )
260  : SPxSolver(LEAVE, COLUMN),
261  m_probname(0),
262  m_fromscratch(false),
263  m_presolving(true),
264  m_objLoLimit(-soplex::infinity),
265  m_objUpLimit(soplex::infinity),
266  m_stat(NO_PROBLEM),
267  m_lpinfo(false),
268  m_autopricing(true),
269  m_itlim(-1),
270  m_itused(0),
271  m_scaling(1),
272  m_rowstat(0),
273  m_colstat(0),
274  m_rownames(0),
275  m_colnames(0),
276  m_messagehdlr(messagehdlr)
277  {
278 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
279  setOutstream(m_spxout);
280 #endif
281  m_sense = sense();
282  setSense(SPxLP::MINIMIZE);
283 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION == 4)
284  setBasisSolver(&m_slu); /*lint !e1506*/
285 #else
286  setSolver(&m_slu); /*lint !e1506*/
287 #endif
288  setTester(&m_ratio); /*lint !e1506*/
289  setPricer(&m_price_steep); /*lint !e1506*/
290  /* no starter */
291 
292  if ( probname != NULL )
293  SOPLEX_TRY_ABORT( setProbname(probname) );
294 
295 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
296  m_lpifeastol = SPxSolver::feastol();
297  m_lpiopttol = SPxSolver::opttol();
298 #else
299  m_lpifeastol = SPxSolver::delta();
300  m_lpiopttol = SPxSolver::delta();
301 #endif
302 
303 #ifdef WITH_LPSCHECK
304  int cpxstat;
305  m_cpxenv = CPXopenCPLEX(&cpxstat);
306  assert(m_cpxenv != NULL);
307  m_cpxlp = CPXcreateprob(m_cpxenv, &cpxstat, probname != NULL ? probname : "spxcheck");
308  (void) CPXsetintparam(m_cpxenv, CPX_PARAM_SCRIND, 0);
309  m_checknum = 0;
310  m_doublecheck = false;
311 #endif
312  }
313 
314  virtual ~SPxSCIP()
315  {
316  if( m_probname != NULL )
317  spx_free(m_probname); /*lint !e1551*/
318 
319  freePreStrongbranchingBasis(); /*lint !e1551*/
320 
321  if( m_rownames != NULL )
322  {
323  m_rownames->~NameSet(); /*lint !e1551*/
324  spx_free(m_rownames); /*lint !e1551*/
325  }
326  if( m_colnames != NULL )
327  {
328  m_colnames->~NameSet(); /*lint !e1551*/
329  spx_free(m_colnames); /*lint !e1551*/
330  }
331 
332 #ifdef WITH_LPSCHECK
333  (void) CPXfreeprob(m_cpxenv, &m_cpxlp);
334  (void) CPXcloseCPLEX(&m_cpxenv);
335 #endif
336  } /*lint !e1579*/
337 
338  /**< return feastol set by SCIPlpiSetRealpar(), which might be tighter than what SoPlex accepted */
339  Real feastol() const
340  {/*lint !e1511*/
341  return m_lpifeastol;
342  }
343 
344  /**< set feastol and store value in case SoPlex only accepts a larger tolerance */
345  void setFeastol(
346  const Real d
347  )
348  {/*lint !e1511*/
349  m_lpifeastol = d;
350 
351 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
353 #else
354  SPxSolver::setDelta(d);
355 #endif
356  }
357 
358  /**< return opttol set by SCIPlpiSetRealpar(), which might be tighter than what SoPlex accepted */
359  Real opttol() const
360  {/*lint !e1511*/
361  return m_lpiopttol;
362  }
363 
364  /**< set opttol and store value in case SoPlex only accepts a larger tolerance */
365  void setOpttol(
366  const Real d
367  )
368  {/*lint !e1511*/
369  m_lpiopttol = d;
370 
371 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
372  SPxSolver::setOpttol(d);
373 #else
374  SPxSolver::setDelta(d);
375 #endif
376  }
377 
378  bool isPerturbed() const
379  {
380  /* the epsilon is 1e-16; we add a factor of ten to account for numerics */
381  return (shift() >= 10.0 * epsilon());
382  }
383 
384  /** set iteration limit (-1 = unbounded) */
385  void setIterationLimit(
386  const int itlim
387  )
388  {
389  m_itlim = itlim;
390  }
391 
392  void setAutoPricer()
393  {
394  setPricer(&m_price_devex);
395  m_autopricing = true;
396  }
397 
398  void setFullPricer()
399  {
400  setPricer(&m_price_steep);
401  m_autopricing = false;
402  }
403 
404  void setSteepPricer()
405  {
406  setPricer(&m_price_steep_ex);
407  m_autopricing = false;
408  }
409 
410  void setSteepQStartPricer()
411  {
412  setPricer(&m_price_steep);
413  m_autopricing = false;
414  }
415 
416  void setParmultPricer()
417  {
418  setPricer(&m_price_parmult);
419  m_autopricing = false;
420  }
421 
422  void setDevexPricer()
423  {
424  setPricer(&m_price_devex);
425  m_autopricing = false;
426  }
427 
428  /** get iteration limit (-1 = unbounded) */
429  int getIterationLimit() const
430  {
431  return m_itlim;
432  }
433 
434  bool getFromScratch() const
435  {
436  return m_fromscratch;
437  }
438 
439  void setFromScratch(bool fs)
440  {
441  m_fromscratch = fs;
442  }
443 
444  int getScaling() const
445  {
446  return m_scaling;
447  }
448 
449  void setScaling(int s)
450  {
451  m_scaling = s;
452  }
453 
454  bool getPresolving() const
455  {
456  return m_presolving;
457  }
458 
459  void setPresolving(bool p)
460  {
461  m_presolving = p;
462  }
463 
464  bool getLpInfo() const
465  {
466  return m_lpinfo;
467  }
468 
469  void setLpInfo(bool li)
470  {
471  m_lpinfo = li;
472  }
473 
474  SPxLP::SPxSense getSense() const
475  {
476  assert(m_sense == sense());
477 
478  return m_sense;
479  }
480 
481  void setSense(const SPxLP::SPxSense sen)
482  {
483  assert(m_sense == sense());
484 
485  if( m_sense != sen )
486  {
487  m_sense = sen;
488  changeSense(sen);
489 
490  /* if objective limit was set for the new sense previously, we have to apply it now */
491  if( m_sense == SPxLP::MINIMIZE && getObjUpLimit() < soplex::infinity )
492  {
493  SCIPdebugMessage("setting termination value to <%g>\n", getObjUpLimit());
494  SPxSolver::setTerminationValue(getObjUpLimit());
495  }
496  else if( m_sense == SPxLP::MAXIMIZE && getObjLoLimit() > -soplex::infinity )
497  {
498  SCIPdebugMessage("setting termination value to <%g>\n", getObjLoLimit());
499  SPxSolver::setTerminationValue(getObjLoLimit());
500  }
501  }
502  }
503 
504  void setProbname(const char* probname)
505  {
506  int len;
507 
508  assert(probname != NULL);
509  if( m_probname != NULL )
510  spx_free(m_probname);
511  len = (int) strlen(probname);
512  spx_alloc(m_probname, len + 1);
513  strncpy(m_probname, probname, len); /*lint !e732*/
514  m_probname[len] = '\0';
515  }
516 
517  Real getObjLoLimit() const
518  {
519  return m_objLoLimit;
520  }
521 
522  void setObjLoLimit(Real limit)
523  {
524  if( getSense() == SPxLP::MAXIMIZE )
525  {
526  SCIPdebugMessage("setting termination value from <%g> to <%g>\n", m_objLoLimit, limit);
527  SPxSolver::setTerminationValue(limit);
528  }
529  m_objLoLimit = limit;
530  }
531 
532  Real getObjUpLimit() const
533  {
534  return m_objUpLimit;
535  }
536 
537  void setObjUpLimit(Real limit)
538  {
539  if( getSense() == SPxLP::MINIMIZE )
540  {
541  SCIPdebugMessage("setting termination value from <%g> to <%g>\n", m_objUpLimit, limit);
542  SPxSolver::setTerminationValue(limit);
543  }
544  m_objUpLimit = limit;
545  }
546 
547  void setRep(SPxSolver::Representation p_rep)
548  {/*lint !e1511*/
549  if( p_rep != rep() )
550  {
551  SCIPdebugMessage("switching to %s representation of the basis\n", p_rep == SPxSolver::ROW ? "row" : "column");
552  SPxSolver::setRep(p_rep);
553  }
554  }
555 
556 #ifdef WITH_LPSCHECK
557  bool getDoubleCheck()
558  {
559  m_checknum++;
560  return m_doublecheck && m_checknum + 1 >= CHECK_START;
561  }
562 
563  void setDoubleCheck(bool dc)
564  {
565  m_doublecheck = dc;
566  }
567 
568  const char* spxStatusString(const SPxSolver::Status stat)
569  {
570  switch( stat )
571  {
572  case SPxSolver::ABORT_TIME:
573  return "ABORT_TIME";
574  case SPxSolver::ABORT_ITER:
575  return "ABORT_ITER";
576  case SPxSolver::ABORT_VALUE:
577  return "ABORT_VALUE";
578  case SPxSolver::SINGULAR:
579  return "SINGULAR";
580  case SPxSolver::REGULAR:
581  return "REGULAR";
582  case SPxSolver::UNKNOWN:
583  return "UNKNOWN";
584  case SPxSolver::OPTIMAL:
585  return "OPTIMAL";
586  case SPxSolver::UNBOUNDED:
587  return "UNBOUNDED";
588  case SPxSolver::INFEASIBLE:
589  return "INFEASIBLE";
590  default:
591  return "UNKNOWN";
592  } /*lint !e788*/
593 
594  return "UNKNOWN";
595  }
596 
597  const char* cpxStatusString(const int stat)
598  {
599  switch( stat )
600  {
601  case CPX_STAT_ABORT_TIME_LIM:
602  return "ABORT_TIME";
603  case CPX_STAT_ABORT_IT_LIM:
604  return "ABORT_ITER";
605  case CPX_STAT_ABORT_OBJ_LIM:
606  return "ABORT_VALUE";
607  case CPX_STAT_OPTIMAL:
608  return "OPTIMAL";
609  case CPX_STAT_OPTIMAL_INFEAS:
610  return "CPX_STAT_OPTIMAL_INFEAS: OPT SOL INFEASIBLE AFTER UNSCALING";
611  case CPX_STAT_UNBOUNDED:
612  return "UNBOUNDED";
613  case CPX_STAT_INFEASIBLE:
614  return "INFEASIBLE";
615  case CPX_STAT_INForUNBD:
616  return "INFEASIBLE or UNBOUNDED";
617  case CPX_STAT_NUM_BEST:
618  return "CPX_STAT_NUM_BEST: SOL AVAILABLE BUT NOT PROVEN OPTIMAL DUE TO NUM TROUBLE";
619  default:
620  return "UNKNOWN";
621  } /*lint !e788*/
622 
623  return "UNKNOWN";
624  }
625 #endif
626 
627 #ifndef NDEBUG
628  bool checkConsistentBounds() const
629  {
630  for( int i = 0; i < nCols(); ++i )
631  {
632  if( lower(i) > upper(i) + Param::epsilon() )
633  {
634  SCIPerrorMessage("inconsistent bounds on column %d: lower=%.17g, upper=%.17g\n",
635  i, lower(i), upper(i));
636  return false;
637  }
638  }
639 
640  return true;
641  }
642 
643  bool checkConsistentSides() const
644  {
645  for( int i = 0; i < nRows(); ++i )
646  {
647  if( lhs(i) > rhs(i) + Param::epsilon() )
648  {
649  SCIPerrorMessage("inconsistent sides on row %d: lhs=%.17g, rhs=%.17g\n",
650  i, lhs(i), rhs(i));
651  return false;
652  }
653  }
654 
655  return true;
656  }
657 #endif
658 
659  void trySolve(bool printwarning = true)
660  {
661  Real timespent;
662  Real timelimit;
663  try
664  {
665  m_stat = SPxSolver::solve();
666  }
667  catch( const SPxException& x )
668  {
669  std::string s = x.what();
670  if( printwarning )
671  {
672  SCIPmessagePrintWarning(m_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
673  }
674  m_stat = SPxSolver::status();
675 
676  /* since it is not clear if the status in SoPlex are set correctly
677  * we want to make sure that if an error is thrown the status is
678  * not OPTIMAL anymore.
679  */
680  assert( m_stat != SPxSolver::OPTIMAL );
681  }
682 
683  /* save iteration count */
684  m_itused += SPxSolver::iterations();
685  assert(m_itlim < 0 || m_itused <= m_itlim);
686 
687  /* update time limit */
688  timespent = SPxSolver::time();
689  if( timespent > 0 )
690  {
691  /* get current time limit */
692  timelimit = SPxSolver::terminationTime();
693  if( timelimit > timespent )
694  timelimit -= timespent;
695  else
696  timelimit = 0;
697  /* set new time limit */
698  assert(timelimit >= 0);
699  SPxSolver::setTerminationTime(timelimit);
700  }
701  }
702 
703  void doSolve(bool printwarning = true)
704  {
705  /* store and set verbosity */
706 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
707  SPxOut::Verbosity verbosity;
708  verbosity = m_spxout.getVerbosity();
709  m_spxout.setVerbosity(getLpInfo() ? (SPxOut::Verbosity) SOPLEX_VERBLEVEL : (SPxOut::Verbosity) 0);
710 #else
711  int verbosity;
712  verbosity = Param::verbose();
713  Param::setVerbose(getLpInfo() ? SOPLEX_VERBLEVEL : 0);
714 #endif
715 
716  assert(checkConsistentBounds());
717  assert(checkConsistentSides());
718 
719 #ifdef WITH_LPSCHECK
720  /* dump LP with current basis and settings saved in SoPlex */
721  if( getDoubleCheck() )
722  writeState("spxcheck", NULL, NULL);
723 #endif
724 
725  /* in auto pricing, do the first iterations with devex, then switch to steepest edge */
726  setTerminationIter(m_autopricing && (m_itlim < 0 || m_itlim - m_itused > AUTOPRICING_ITERSWITCH) ? AUTOPRICING_ITERSWITCH : m_itlim - m_itused);
727 
728  trySolve(printwarning);
729 
730  if( m_autopricing && m_stat == SPxSolver::ABORT_ITER && (m_itlim < 0 || m_itlim - m_itused > 0) )
731  {
732  setTerminationIter(m_itlim - m_itused);
733  setPricer(&m_price_steep_ex);
734 
735  trySolve(printwarning);
736 
737  setPricer(&m_price_devex);
738  }
739 
740  /* for safety reset iteration limit */
741  setTerminationIter(m_itlim);
742 
743  if( m_stat == OPTIMAL )
744  {
745  Real objval = value();
746 
747  if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
748  m_stat = ABORT_VALUE;
749  }
750 
751 #ifdef WITH_LPSCHECK
752  /* if SoPlex gave a definite answer, we double check if it is consistent with CPLEX's answer */
753  if( getDoubleCheck() && (m_stat == SPxSolver::OPTIMAL || m_stat == SPxSolver::UNBOUNDED || m_stat == SPxSolver::INFEASIBLE || m_stat == SPxSolver::ABORT_VALUE) )
754  {
755  SCIP_Real cpxobj;
756  int cpxstat;
757 
758  /* read LP with basis */
759  CPX_CALL( CPXreadcopyprob(m_cpxenv, m_cpxlp, "spxcheck.mps", NULL) );
760  CPX_CALL( CPXreadcopybase(m_cpxenv, m_cpxlp, "spxcheck.bas") );
761 
762  /* set tolerances */
763  CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPOPT, MAX(opttol(), 1e-9)) );
764  CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPRHS, MAX(feastol(), 1e-9)) );
765 
766  /* solve LP */
767  CPX_CALL( CPXlpopt(m_cpxenv, m_cpxlp) );
768 
769  /* get solution status and objective value */
770  CPX_CALL( CPXsolution(m_cpxenv, m_cpxlp, &cpxstat, &cpxobj, NULL, NULL, NULL, NULL) );
771  if( getSense() == SPxLP::MAXIMIZE )
772  cpxobj *= -1.0;
773 
774  /* check for inconsistent statuses */
775  if( cpxstat == CPX_STAT_OPTIMAL_INFEAS )
776  {
777  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s)\n",
778  m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat));
779  if( EXIT_AT_CPXERROR )
780  exit(1);
781  }
782  else if( (m_stat == SPxSolver::OPTIMAL && cpxstat != CPX_STAT_OPTIMAL)
783  || (m_stat == SPxSolver::UNBOUNDED && cpxstat != CPX_STAT_UNBOUNDED)
784  || (m_stat == SPxSolver::INFEASIBLE && cpxstat != CPX_STAT_INFEASIBLE) )
785  {
786  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
787  m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
788  if( EXIT_AT_WRONG_RESULT )
789  exit(1);
790  }
791  else if( m_stat == SPxSolver::ABORT_VALUE )
792  {
793  switch( cpxstat )
794  {
795  case CPX_STAT_OPTIMAL:
796  if( (getSense() == SPxSolver::MINIMIZE && LTrel(cpxobj, getObjUpLimit(), 2*opttol()))
797  || (getSense() == SPxSolver::MAXIMIZE && GTrel(cpxobj, getObjLoLimit(), 2*opttol())) )
798  {
799  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
800  m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ? "<" : ">",
801  getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
802  if( EXIT_AT_WRONG_RESULT )
803  exit(1);
804  }
805  else if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
806  || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
807  {
808  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
809  m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ? "<" : ">",
810  getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
811  }
812  break;
813  case CPX_STAT_OPTIMAL_INFEAS:
814  case CPX_STAT_NUM_BEST:
815  if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
816  || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
817  {
818  SCIPerrorMessage("In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
819  m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ? "<" : ">",
820  getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
821  }
822  break;
823  case CPX_STAT_INFEASIBLE:
824  break;
825  case CPX_STAT_UNBOUNDED:
826  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
827  m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
828  if( EXIT_AT_WRONG_RESULT )
829  exit(1);
830  break;
831  case CPX_STAT_INForUNBD:
832  default:
833  SCIPerrorMessage("In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
834  m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
835  break;
836  } /*lint !e788*/
837  }
838  /* check for same objective values */
839  else if( m_stat == SPxSolver::OPTIMAL )
840  {
841  if( (getSense() == SPxSolver::MINIMIZE && LTrel(value(), cpxobj, 2*opttol()))
842  || (getSense() == SPxSolver::MAXIMIZE && GTrel(value(), cpxobj, 2*opttol())) )
843  {
844  /* SCIPerrorMessage("In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f too good (checknum=%d)\n", value(),
845  m_probname, getSense() == SPxSolver::MINIMIZE ? "<" : ">", cpxobj, m_checknum); */
846  }
847  else if( (getSense() == SPxSolver::MINIMIZE && GTrel(value(), cpxobj, 2*opttol()))
848  || (getSense() == SPxSolver::MAXIMIZE && LTrel(value(), cpxobj, 2*opttol())) )
849  {
850  SCIPerrorMessage("In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f suboptimal (checknum=%d)\n", value(),
851  m_probname, getSense() == SPxSolver::MINIMIZE ? ">" : "<", cpxobj, m_checknum);
852  if( EXIT_AT_WRONG_RESULT )
853  exit(1);
854  }
855  }
856  }
857 
858  ENDCHECK:
859 #endif
860 
861  /* restore verbosity */
862 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
863  m_spxout.setVerbosity(verbosity);
864 #else
865  Param::setVerbose(verbosity);
866 #endif
867 
868  }
869 
870  virtual Status solve()
871  {
872  assert(m_sense == sense());
873  SPxEquiliSC* scaler = NULL;
874  SPxMainSM* simplifier = NULL;
875  SPxLP origlp;
876  SPxSimplifier::Result result = SPxSimplifier::OKAY;
877 
878  /* delete starting basis if solving from scratch */
879  if ( getFromScratch() )
880  {
881  try
882  {
883  SPxSolver::reLoad();
884  }
885  catch( const SPxException& x )
886  {
887  std::string s = x.what();
888  SCIPmessagePrintWarning(m_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
889  m_stat = SPxSolver::status();
890  assert( m_stat != SPxSolver::OPTIMAL );
891  return m_stat;
892  }
893  }
894  assert(!getFromScratch() || getBasisStatus() == SPxBasis::NO_PROBLEM);
895 
896  /* use scaler and simplifier if no basis is loaded, i.e., if solving for the first time or from scratch */
897  if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && (getScaling() > 0) && nCols() > 0 && nRows() > 0 )
898  {
899  spx_alloc(scaler, 1);
900  scaler = new (scaler) SPxEquiliSC();
901  assert(scaler != NULL);
902 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
903  scaler->setOutstream(m_spxout);
904 #endif
905  }
906 
907  if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && getPresolving() && nCols() > 0 && nRows() > 0 )
908  {
909  spx_alloc(simplifier, 1);
910  simplifier = new (simplifier) SPxMainSM();
911  assert(simplifier != NULL);
912  }
913 
914  /* store original lp */
915  if( scaler != NULL || simplifier != NULL )
916  origlp = SPxLP(*this);
917 
918  m_itused = 0;
919 
920  SOLVEAGAIN:
921  /* perform scaling and presolving */
922  if( scaler != NULL )
923  {
924  SCIPdebugMessage("scaling LP\n");
925  scaler->scale(*this);
926  }
927 
928  if( simplifier != NULL )
929  {
930  /* store and set verbosity */
931 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
932  SPxOut::Verbosity verbosity;
933  verbosity = m_spxout.getVerbosity();
934  m_spxout.setVerbosity(getLpInfo() ? (SPxOut::Verbosity) SOPLEX_VERBLEVEL : (SPxOut::Verbosity) 0);
935 #else
936  int verbosity;
937  verbosity = Param::verbose();
938  Param::setVerbose(getLpInfo() ? SOPLEX_VERBLEVEL : 0);
939 #endif
940  SCIPdebugMessage("simplifying LP\n");
941 #ifdef WITH_BOUNDFLIPPING
942  result = simplifier->simplify(*this, epsilon(), feastol(), opttol(), true);
943 #else
944 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
945  result = simplifier->simplify(*this, epsilon(), feastol(), opttol());
946 #else
947  result = simplifier->simplify(*this, epsilon(), delta());
948 #endif
949 #endif
950  SCIPdebugMessage("simplifier ended with status %u (0: OKAY, 1: INFEASIBLE, 2: DUAL_INFEASIBLE, 3: UNBOUNDED, 4: VANISHED)\n", result);
951 
952  /* unsimplification is not designed for these cases, thus reload original/scaled lp */
953  if( result == SPxSimplifier::INFEASIBLE || result == SPxSimplifier::DUAL_INFEASIBLE )
954  {
955  SCIPdebugMessage("simplifier detected primal or dual infeasibility - reloading and solving unsimplified LP\n");
956 
957  simplifier->~SPxMainSM();
958  spx_free(simplifier);
959 
960  SPxSolver::loadLP(origlp);
961  m_sense = sense();
962 
963  goto SOLVEAGAIN;
964  }
965  /* reset verbosity */
966 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
967  m_spxout.setVerbosity(verbosity);
968 #else
969  Param::setVerbose(verbosity);
970 #endif
971  }
972 
973  /* solve */
974  if( result != SPxSimplifier::VANISHED )
975  {
976  /* we have to deactivate the objective limit, since we do not know the transformed value */
977  Real objlolimit = getObjLoLimit();
978  Real objuplimit = getObjUpLimit();
979 
980  if( simplifier != NULL || scaler != NULL )
981  {
982  setObjLoLimit(-soplex::infinity);
983  setObjUpLimit(soplex::infinity);
984  }
985 
986 #ifndef NDEBUG
987  doSolve();
988 #else
989  doSolve(false);
990 #endif
991 
992  if( simplifier != NULL || scaler != NULL )
993  {
994  setObjLoLimit(objlolimit);
995  setObjUpLimit(objuplimit);
996  }
997  }
998 
999  /* unsimplification only stable for optimal basis */
1000  if( m_stat != SPxSolver::OPTIMAL && simplifier != NULL )
1001  {
1002  SCIPdebugMessage("presolved LP not optimal - reloading and solving original LP\n");
1003 
1004  simplifier->~SPxMainSM();
1005  spx_free(simplifier);
1006 
1007  SPxSolver::loadLP(origlp);
1008  m_sense = sense();
1009 
1010  goto SOLVEAGAIN;
1011  }
1012 
1013  /* if scaling or presolving was applied, restore original lp */
1014  if( scaler != NULL || simplifier != NULL )
1015  {
1016  SPxSolver::VarStatus* cstat = NULL;
1017  SPxSolver::VarStatus* rstat = NULL;
1018 
1019  /* get basis if at least regular */
1020  if( (simplifier == NULL || result != SPxSimplifier::VANISHED) && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
1021  {
1022  SCIPdebugMessage("get basis of presolved LP\n");
1023  spx_alloc(rstat, nRows());
1024  spx_alloc(cstat, nCols());
1025  (void) SPxSolver::getBasis(rstat, cstat);
1026  }
1027 
1028  /* unsimplify */
1029  if( simplifier != NULL && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
1030  {
1031  assert((result == SPxSimplifier::VANISHED) == (cstat == NULL));
1032  assert((result == SPxSimplifier::VANISHED) == (rstat == NULL));
1033 
1034  /* dimension of presolved lp */
1035  int ncols = result == SPxSimplifier::VANISHED ? 0 : nCols();
1036  int nrows = result == SPxSimplifier::VANISHED ? 0 : nRows();
1037 
1038  /* get solution of presolved lp */
1039  DVector primals(ncols);
1040  DVector duals(nrows);
1041  DVector slacks(nrows);
1042  DVector redcosts(ncols);
1043  if( result != SPxSimplifier::VANISHED )
1044  {
1045  (void) SPxSolver::getPrimal(primals);
1046  (void) SPxSolver::getDual(duals);
1047  (void) SPxSolver::getSlacks(slacks);
1048  (void) SPxSolver::getRedCost(redcosts);
1049  }
1050 
1051  /* perform unsimplification */
1052  SCIPdebugMessage("unsimplify\n");
1053  try
1054  {
1055  simplifier->unsimplify(primals, duals, slacks, redcosts, rstat, cstat);
1056  }
1057  catch( const SPxException& x )
1058  {
1059  std::string s = x.what();
1060  SCIPmessagePrintWarning(m_messagehdlr, "SoPlex unsimplification unsuccessful; solving again without LP presolving (SoPlex says %s)\n",
1061  s.c_str());
1062  }
1063 
1064  if( cstat != NULL )
1065  spx_free(cstat);
1066  if( rstat != NULL )
1067  spx_free(rstat);
1068 
1069  if( simplifier->isUnsimplified() )
1070  {
1071  /* get basis for original lp */
1072  rstat = NULL;
1073  cstat = NULL;
1074  spx_alloc(rstat, origlp.nRows());
1075  spx_alloc(cstat, origlp.nCols());
1076  simplifier->getBasis(rstat, cstat);
1077  }
1078  }
1079 
1080  /* reload original lp */
1081  SCIPdebugMessage("reload original LP\n");
1082  SPxSolver::loadLP(origlp);
1083  m_sense = sense();
1084 
1085  /* set basis from preprocessed lp and reoptimize */
1086  if( rstat != NULL && cstat != NULL )
1087  {
1088  SCIPdebugMessage("load unsimplified basis into original LP\n");
1089  SPxSolver::setBasis(rstat, cstat);
1090  }
1091 
1092  SCIPdebugMessage("solve original LP\n");
1093 #ifndef NDEBUG
1094  doSolve();
1095 #else
1096  doSolve(false);
1097 #endif
1098 
1099  /* free allocated memory */
1100  if( cstat != NULL )
1101  spx_free(cstat);
1102  if( rstat != NULL )
1103  spx_free(rstat);
1104  if( scaler != NULL )
1105  {
1106  scaler->~SPxEquiliSC();
1107  spx_free(scaler);
1108  }
1109  if( simplifier != NULL )
1110  {
1111  simplifier->~SPxMainSM();
1112  spx_free(simplifier);
1113  }
1114  }
1115 
1116  if( m_stat == OPTIMAL )
1117  {
1118  Real objval = value();
1119 
1120  if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
1121  m_stat = ABORT_VALUE;
1122  }
1123 
1124  return m_stat;
1125  }
1126 
1127  /** save the current basis */
1128  void savePreStrongbranchingBasis()
1129  {
1130  m_rowstat.reSize(nRows());
1131  m_colstat.reSize(nCols());
1132 
1133  try
1134  {
1135  m_stat = getBasis(m_rowstat.get_ptr(), m_colstat.get_ptr());
1136  }
1137 #ifndef NDEBUG
1138  catch( const SPxException& x )
1139  {
1140  std::string s = x.what();
1141  SCIPmessagePrintWarning(m_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1142 
1143  /* since it is not clear if the status in SoPlex are set correctly
1144  * we want to make sure that if an error is thrown the status is
1145  * not OPTIMAL anymore.
1146  */
1147  assert(m_stat != SPxSolver::OPTIMAL);
1148  }
1149 #else
1150  catch( const SPxException& )
1151  { }
1152 #endif
1153 
1154  }
1155 
1156  /** restore basis */
1157  void restorePreStrongbranchingBasis()
1158  {
1159  assert(m_rowstat.size() == nRows());
1160  assert(m_colstat.size() == nCols());
1161 
1162  try
1163  {
1164  setBasis(m_rowstat.get_const_ptr(), m_colstat.get_const_ptr());
1165  }
1166 #ifndef NDEBUG
1167  catch( const SPxException& x )
1168  {
1169  std::string s = x.what();
1170  SCIPmessagePrintWarning(m_messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1171 #else
1172  catch( const SPxException& )
1173  {
1174 #endif
1175  m_stat = SPxSolver::status();
1176 
1177  /* since it is not clear if the status in SoPlex are set correctly
1178  * we want to make sure that if an error is thrown the status is
1179  * not OPTIMAL anymore.
1180  */
1181  assert(m_stat != SPxSolver::OPTIMAL);
1182  }
1183  }
1184 
1185  /** if basis is in store, delete it without restoring it */
1186  void freePreStrongbranchingBasis()
1187  {
1188  m_rowstat.clear();
1189  m_colstat.clear();
1190  }
1191 
1192  /** is pre-strong-branching basis freed? */
1193  bool preStrongbranchingBasisFreed() const
1194  {
1195  return ((m_rowstat.size() == 0 ) && (m_colstat.size() == 0));
1196  }
1197 
1198  /** provides access for temporary storage of basis status of rows */
1199  DataArray<SPxSolver::VarStatus>& rowStat()
1200  {
1201  return m_rowstat;
1202  }
1203 
1204  /** provides access for temporary storage of basis status or columns */
1205  DataArray<SPxSolver::VarStatus>& colStat()
1206  {
1207  return m_colstat;
1208  }
1209 
1210  Status getStatus() const
1211  {
1212  return m_stat;
1213  }
1214 
1215  Status updateStatus()
1216  {
1217  m_stat = SPxSolver::status();
1218  return m_stat;
1219  }
1220 
1221  bool isInitialized() const
1222  {/*lint !e1511*/
1223  return SPxSolver::isInitialized();
1224  }
1225 
1226  int iterations() const
1227  {/*lint !e1511*/
1228  return m_itused;
1229  }
1230 
1231  virtual void clear()
1232  {
1233  SPxSolver::clear();
1234  freePreStrongbranchingBasis();
1235  m_stat = NO_PROBLEM;
1236  m_sense = sense();
1237  }
1238 
1239  bool readLP(const char* fname)
1240  {
1241  clear();
1242 
1243  if ( m_rownames != 0 )
1244  m_rownames->~NameSet();
1245  else
1246  spx_alloc(m_colnames, 1);
1247 
1248  if ( m_colnames != 0 )
1249  m_colnames->~NameSet();
1250  else
1251  spx_alloc(m_rownames, 1);
1252 
1253  m_rownames = new (m_rownames) NameSet();
1254  m_colnames = new (m_colnames) NameSet();
1255 
1256  if( SPxSolver::readFile(fname, m_rownames, m_colnames) )
1257  {
1258  m_stat = NO_PROBLEM;
1259  m_sense = sense();
1260  return true;
1261  }
1262 
1263  return false;
1264  }
1265 
1266  /** copy column names into namestorage with access via colnames */
1267  void getColNames(
1268  int firstcol, /**< first column to get name from LP */
1269  int lastcol, /**< last column to get name from LP */
1270  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) */
1271  char* namestorage, /**< storage for col names */
1272  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1273  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1274  )
1275  {
1276  assert( m_colnames != NULL );
1277 
1278  // compute size
1279  if ( namestoragesize == 0 )
1280  {
1281  // the following may overestimate the space requirements
1282  *storageleft = -m_colnames->memSize();
1283  }
1284  else
1285  {
1286  NameSet* names = m_colnames;
1287  assert( names != 0 );
1288  int sizeleft = namestoragesize;
1289  char* s = namestorage;
1290  for (int j = firstcol; j <= lastcol; ++j)
1291  {
1292  const char* t = (*names)[j];
1293  colnames[j-firstcol] = s;
1294  while( *t != '\0' && sizeleft >= 0 )
1295  {
1296  *(s++) = *(t++);
1297  --sizeleft;
1298  }
1299  *(s++) = '\0';
1300  }
1301  if ( sizeleft == 0 )
1302  {
1303  *storageleft = namestoragesize - m_colnames->memSize();
1304  assert( *storageleft <= 0 );
1305  }
1306  else
1307  *storageleft = sizeleft;
1308  }
1309  }
1310 
1311  /** copy row names into namestorage with access via row */
1312  void getRowNames(
1313  int firstrow, /**< first row to get name from LP */
1314  int lastrow, /**< last row to get name from LP */
1315  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) */
1316  char* namestorage, /**< storage for row names */
1317  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1318  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1319  )
1320  {
1321  assert( m_rownames != NULL );
1322 
1323  // compute size
1324  if ( namestoragesize == 0 )
1325  {
1326  // the following may overestimate the space requirements
1327  *storageleft = -m_rownames->memSize();
1328  }
1329  else
1330  {
1331  NameSet* names = m_rownames;
1332  assert( names != 0 );
1333  int sizeleft = namestoragesize;
1334  char* s = namestorage;
1335  for (int i = firstrow; i <= lastrow; ++i)
1336  {
1337  const char* t = (*names)[i];
1338  rownames[i-firstrow] = s;
1339  while( *t != '\0' && sizeleft >= 0 )
1340  {
1341  *(s++) = *(t++);
1342  --sizeleft;
1343  }
1344  *(s++) = '\0';
1345  }
1346  if ( sizeleft == 0 )
1347  {
1348  *storageleft = m_rownames->memSize() - namestoragesize;
1349  assert( *storageleft <= 0 );
1350  }
1351  else
1352  *storageleft = sizeleft;
1353  }
1354  }
1355 }; /*lint !e1748*/
1356 
1357 
1358 
1359 
1360 /********************************************************************/
1361 /*----------------------------- C --------------------------------*/
1362 /********************************************************************/
1363 
1364 #include "lpi/lpi.h"
1365 #include "scip/bitencode.h"
1366 
1367 typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
1368 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
1369 typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
1370 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
1374 /** LP interface */
1375 struct SCIP_LPi
1376 {
1377  SPxSCIP* spx; /**< our SPxSolver implementation */
1378  int* cstat; /**< array for storing column basis status */
1379  int* rstat; /**< array for storing row basis status */
1380  int cstatsize; /**< size of cstat array */
1381  int rstatsize; /**< size of rstat array */
1382  SCIP_PRICING pricing; /**< current pricing strategy */
1383  SCIP_Bool solved; /**< was the current LP solved? */
1384  SLUFactor* factorization; /**< factorization possibly needed for basis inverse */
1385  SCIP_Real rowrepswitch; /**< use row representation if number of rows divided by number of columns exceeds this value */
1386  SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
1387  SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
1388  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
1389 };
1390 
1391 /** LPi state stores basis information */
1392 struct SCIP_LPiState
1393 {
1394  int ncols; /**< number of LP columns */
1395  int nrows; /**< number of LP rows */
1396  COLPACKET* packcstat; /**< column basis status in compressed form */
1397  ROWPACKET* packrstat; /**< row basis status in compressed form */
1398 };
1399 
1400 /** LPi norms to store dual steepest edge */
1401 struct SCIP_LPiNorms
1402 {
1403  int nrows; /**< number of stored norms corresponding to rows */
1404  int ncols; /**< number of stored norms corresponding to cols */
1405  SCIP_Real* norms; /**< norms to be (re)stored */
1406 };
1407 
1408 
1409 /*
1410  * dynamic memory arrays
1411  */
1412 
1413 /** resizes cstat array to have at least num entries */
1414 static
1416  SCIP_LPI* lpi, /**< LP interface structure */
1417  int num /**< minimal number of entries in array */
1418  )
1419 {
1420  assert(lpi != NULL);
1421 
1422  if( num > lpi->cstatsize )
1423  {
1424  int newsize;
1425 
1426  newsize = MAX(2*lpi->cstatsize, num);
1427  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
1428  lpi->cstatsize = newsize;
1429  }
1430  assert(num <= lpi->cstatsize);
1431 
1432  return SCIP_OKAY;
1433 }
1434 
1435 /** resizes rstat array to have at least num entries */
1436 static
1438  SCIP_LPI* lpi, /**< LP interface structure */
1439  int num /**< minimal number of entries in array */
1440  )
1441 {
1442  assert(lpi != NULL);
1443 
1444  if( num > lpi->rstatsize )
1445  {
1446  int newsize;
1447 
1448  newsize = MAX(2*lpi->rstatsize, num);
1449  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
1450  lpi->rstatsize = newsize;
1451  }
1452  assert(num <= lpi->rstatsize);
1453 
1454  return SCIP_OKAY;
1455 }
1456 
1457 
1458 
1459 
1460 /*
1461  * LPi state methods
1462  */
1463 
1464 /** returns the number of packets needed to store column packet information */
1465 static
1466 int colpacketNum(
1467  int ncols /**< number of columns to store */
1468  )
1470  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
1471 }
1472 
1473 /** returns the number of packets needed to store row packet information */
1474 static
1475 int rowpacketNum(
1476  int nrows /**< number of rows to store */
1477  )
1479  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
1480 }
1481 
1482 /** store row and column basis status in a packed LPi state object */
1483 static
1484 void lpistatePack(
1485  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
1486  const int* cstat, /**< basis status of columns in unpacked format */
1487  const int* rstat /**< basis status of rows in unpacked format */
1488  )
1489 {
1490  assert(lpistate != NULL);
1491  assert(lpistate->packcstat != NULL);
1492  assert(lpistate->packrstat != NULL);
1493 
1494  SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
1495  SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
1496 }
1497 
1498 /** unpacks row and column basis status from a packed LPi state object */
1499 static
1500 void lpistateUnpack(
1501  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
1502  int* cstat, /**< buffer for storing basis status of columns in unpacked format */
1503  int* rstat /**< buffer for storing basis status of rows in unpacked format */
1504  )
1505 {
1506  assert(lpistate != NULL);
1507  assert(lpistate->packcstat != NULL);
1508  assert(lpistate->packrstat != NULL);
1509 
1510  SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
1511  SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
1512 }
1513 
1514 /** creates LPi state information object */
1515 static
1517  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
1518  BMS_BLKMEM* blkmem, /**< block memory */
1519  int ncols, /**< number of columns to store */
1520  int nrows /**< number of rows to store */
1521  )
1522 {
1523  assert(lpistate != NULL);
1524  assert(blkmem != NULL);
1525  assert(ncols >= 0);
1526  assert(nrows >= 0);
1527 
1528  int nColPackets = colpacketNum(ncols);
1529  int nRowPackets = rowpacketNum(nrows);
1530 
1531  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
1532  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets) );
1533  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets) );
1534 
1535  return SCIP_OKAY;
1536 }
1537 
1538 /** frees LPi state information */
1539 static
1540 void lpistateFree(
1541  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
1542  BMS_BLKMEM* blkmem /**< block memory */
1543  )
1544 {
1545  assert(blkmem != NULL);
1546  assert(lpistate != NULL);
1547  assert(*lpistate != NULL);
1548 
1549  int nColPackets = colpacketNum((*lpistate)->ncols);
1550  int nRowPackets = rowpacketNum((*lpistate)->nrows);
1551 
1552  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets);
1553  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets);
1554  BMSfreeBlockMemory(blkmem, lpistate);
1555 }
1556 
1557 
1558 
1559 
1560 /*
1561  * local methods
1562  */
1563 
1564 /** converts SCIP's objective sense into SoPlex's objective sense */
1565 static
1566 SPxLP::SPxSense spxObjsen(
1567  SCIP_OBJSEN objsen /**< SCIP's objective sense value */
1568  )
1570  switch( objsen )
1571  {
1572  case SCIP_OBJSEN_MAXIMIZE:
1573  return SPxLP::MAXIMIZE;
1574  case SCIP_OBJSEN_MINIMIZE:
1575  return SPxLP::MINIMIZE;
1576  default:
1577  SCIPerrorMessage("invalid objective sense\n");
1578  SCIPABORT();
1579  return SPxLP::MINIMIZE; /*lint !e527 */
1580  }
1581 }
1582 
1583 /** marks the current LP to be unsolved */
1584 static
1585 void invalidateSolution(SCIP_LPI* lpi)
1586 {
1587  assert(lpi != NULL);
1588  lpi->solved = FALSE;
1589  if ( lpi->factorization != 0 )
1590  {
1591  delete lpi->factorization;
1592  lpi->factorization = 0;
1593  }
1594 }
1595 
1596 
1597 
1598 /*
1599  * LP Interface Methods
1600  */
1601 
1602 
1603 /*
1604  * Miscellaneous Methods
1605  */
1606 
1607 static char spxname[100];
1608 static char spxdesc[200];
1609 
1610 /**@name Miscellaneous Methods */
1611 /**@{ */
1612 
1613 /** gets name and version of LP solver */
1614 const char* SCIPlpiGetSolverName(
1615  void
1616  )
1618  SCIPdebugMessage("calling SCIPlpiGetSolverName()\n");
1619 
1620 #if (SOPLEX_SUBVERSION > 0)
1621  snprintf(spxname, 100, "SoPlex1 %d.%d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10, SOPLEX_SUBVERSION); /*lint !e778*/
1622 #else
1623  snprintf(spxname, 100, "SoPlex1 %d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10); /*lint !e778*/
1624 #endif
1625  return spxname;
1626 }
1627 
1628 /** gets description of LP solver (developer, webpage, ...) */
1629 const char* SCIPlpiGetSolverDesc(
1630  void
1631  )
1633 #if (SOPLEX_VERSION >= 160)
1634  snprintf(spxdesc, 200, "Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de) [GitHash: %s]"
1635 #ifdef WITH_LPSCHECK
1636  " - including CPLEX double check"
1637 #endif
1638  , getGitHash());
1639 #else
1640  snprintf(spxdesc, 200, "Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de)"
1641 #ifdef WITH_LPSCHECK
1642  " - including CPLEX double check"
1643 #endif
1644  );
1645 #endif
1646  return spxdesc;
1647 }
1648 
1649 /** gets pointer for LP solver - use only with great care */
1651  SCIP_LPI* lpi /**< pointer to an LP interface structure */
1652  )
1654  return (void*) lpi->spx;
1655 }
1656 
1657 /** pass integrality information about variables to the solver */
1659  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
1660  int ncols, /**< length of integrality array */
1661  int* intInfo /**< integrality array (0: continuous, 1: integer) */
1662  )
1663 {
1664 #if (SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3))
1665  assert(ncols == lpi->spx->nCols() || (ncols == 0 && intInfo == NULL));
1666  lpi->spx->setIntegralityInformation(ncols, intInfo);
1667  return SCIP_OKAY;
1668 #else
1669  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1670  return SCIP_LPERROR;
1671 #endif
1672 }
1673 
1674 /**@} */
1675 
1676 
1677 
1678 
1679 /*
1680  * LPI Creation and Destruction Methods
1681  */
1682 
1683 /**@name LPI Creation and Destruction Methods */
1684 /**@{ */
1685 
1686 /** creates an LP problem object */
1688  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1689  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1690  const char* name, /**< problem name */
1691  SCIP_OBJSEN objsen /**< objective sense */
1692  )
1693 {
1694  assert(lpi != NULL);
1695 
1696  /* create SoPlex object */
1697  SCIP_ALLOC( BMSallocMemory(lpi) );
1698 
1699  /* we use this construction to allocate the memory for the SoPlex class also via the blockmemshell */
1700  (*lpi)->spx = static_cast<SPxSCIP*>(BMSallocMemoryCPP(sizeof(SPxSCIP)));
1701  SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxSCIP(messagehdlr, name) );
1702  (*lpi)->cstat = NULL;
1703  (*lpi)->rstat = NULL;
1704  (*lpi)->cstatsize = 0;
1705  (*lpi)->rstatsize = 0;
1706  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1707  (*lpi)->factorization = 0;
1708  (*lpi)->rowrepswitch = SCIPlpiInfinity(*lpi);
1709  (*lpi)->conditionlimit = -1.0;
1710  (*lpi)->checkcondition = FALSE;
1711  (*lpi)->messagehdlr = messagehdlr;
1712 
1713  invalidateSolution(*lpi);
1714 
1715  /* set objective sense */
1716  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1717 
1718  /* set default pricing */
1719  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
1720 
1721  return SCIP_OKAY;
1722 }
1723 
1724 /** deletes an LP problem object */
1726  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1727  )
1729  assert(lpi != NULL);
1730  assert(*lpi != NULL);
1731  assert((*lpi)->spx != NULL);
1732 
1733  /* free LP using destructor and free memory via blockmemshell */
1734  (*lpi)->spx->~SPxSCIP();
1735  BMSfreeMemory(&((*lpi)->spx));
1736 
1737  /* free memory */
1738  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1739  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1740  BMSfreeMemory(lpi);
1741 
1742  return SCIP_OKAY;
1743 }
1744 
1745 /**@} */
1746 
1747 
1748 
1749 
1750 /*
1751  * Modification Methods
1752  */
1753 
1754 /**@name Modification Methods */
1755 /**@{ */
1756 
1757 /** copies LP data with column matrix into LP solver */
1759  SCIP_LPI* lpi, /**< LP interface structure */
1760  SCIP_OBJSEN objsen, /**< objective sense */
1761  int ncols, /**< number of columns */
1762  const SCIP_Real* obj, /**< objective function values of columns */
1763  const SCIP_Real* lb, /**< lower bounds of columns */
1764  const SCIP_Real* ub, /**< upper bounds of columns */
1765  char** colnames, /**< column names, or NULL */
1766  int nrows, /**< number of rows */
1767  const SCIP_Real* lhs, /**< left hand sides of rows */
1768  const SCIP_Real* rhs, /**< right hand sides of rows */
1769  char** /*rownames*/, /**< row names, or NULL */
1770  int nnonz, /**< number of nonzero elements in the constraint matrix */
1771  const int* beg, /**< start index of each column in ind- and val-array */
1772  const int* ind, /**< row indices of constraint matrix entries */
1773  const SCIP_Real* val /**< values of constraint matrix entries */
1774  )
1775 {
1776  SCIPdebugMessage("calling SCIPlpiLoadColLP()\n");
1777 
1778  assert(lpi != NULL);
1779  assert(lpi->spx != NULL);
1780  assert(lhs != NULL);
1781  assert(rhs != NULL);
1782 
1783  invalidateSolution(lpi);
1784  assert( lpi->spx->preStrongbranchingBasisFreed() );
1785 
1786  try
1787  {
1788  SPxSCIP* spx = lpi->spx;
1789  LPRowSet rows(nrows);
1790  DSVector emptyVector(0);
1791  int i;
1792 
1793  spx->clear();
1794 
1795  /* set objective sense */
1796  spx->setSense(spxObjsen(objsen));
1797 
1798  /* create empty rows with given sides */
1799  for( i = 0; i < nrows; ++i )
1800  rows.add(lhs[i], emptyVector, rhs[i]);
1801  spx->addRows(rows);
1802 
1803  /* create column vectors with coefficients and bounds */
1804  SCIP_CALL( SCIPlpiAddCols(lpi, ncols, obj, lb, ub, colnames, nnonz, beg, ind, val) );
1805  }
1806 #ifndef NDEBUG
1807  catch( const SPxException& x )
1808  {
1809  std::string s = x.what();
1810  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1811 #else
1812  catch( const SPxException& )
1813  {
1814 #endif
1815  return SCIP_LPERROR;
1816  }
1817 
1818  return SCIP_OKAY;
1819 }
1820 
1821 /** adds columns to the LP */
1823  SCIP_LPI* lpi, /**< LP interface structure */
1824  int ncols, /**< number of columns to be added */
1825  const SCIP_Real* obj, /**< objective function values of new columns */
1826  const SCIP_Real* lb, /**< lower bounds of new columns */
1827  const SCIP_Real* ub, /**< upper bounds of new columns */
1828  char** /*colnames*/, /**< column names, or NULL */
1829  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1830  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1831  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1832  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1833  )
1834 {
1835  SCIPdebugMessage("calling SCIPlpiAddCols()\n");
1836 
1837  assert(lpi != NULL);
1838  assert(lpi->spx != NULL);
1839  assert(obj != NULL);
1840  assert(lb != NULL);
1841  assert(ub != NULL);
1842  assert(nnonz == 0 || beg != NULL);
1843  assert(nnonz == 0 || ind != NULL);
1844  assert(nnonz == 0 || val != NULL);
1845  assert(nnonz >= 0);
1846  assert(ncols >= 0);
1847 
1848  invalidateSolution(lpi);
1849 
1850  assert( lpi->spx->preStrongbranchingBasisFreed() );
1851 
1852 #ifndef NDEBUG
1853  if ( nnonz > 0 )
1854  {
1855  /* perform check that no new rows are added - this is likely to be a mistake */
1856  int nrows = lpi->spx->nRows();
1857  for (int j = 0; j < nnonz; ++j)
1858  assert( 0 <= ind[j] && ind[j] < nrows );
1859  }
1860 #endif
1861 
1862  SPxSCIP* spx = lpi->spx;
1863  try
1864  {
1865  LPColSet cols(ncols);
1866  DSVector colVector(ncols);
1867  int start;
1868  int last;
1869  int i;
1870 
1871  /* create column vectors with coefficients and bounds */
1872  for( i = 0; i < ncols; ++i )
1873  {
1874  colVector.clear();
1875  if( nnonz > 0 )
1876  {
1877  start = beg[i];
1878  last = (i == ncols-1 ? nnonz : beg[i+1]);
1879  colVector.add( last-start, &ind[start], &val[start] );
1880  }
1881  cols.add(obj[i], lb[i], colVector, ub[i]);
1882  }
1883  spx->addCols(cols);
1884  }
1885 #ifndef NDEBUG
1886  catch( const SPxException& x )
1887  {
1888  std::string s = x.what();
1889  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
1890 #else
1891  catch( const SPxException& )
1892  {
1893 #endif
1894  return SCIP_LPERROR;
1895  }
1896 
1897  return SCIP_OKAY;
1898 }
1899 
1900 /** deletes all columns in the given range from LP */
1902  SCIP_LPI* lpi, /**< LP interface structure */
1903  int firstcol, /**< first column to be deleted */
1904  int lastcol /**< last column to be deleted */
1905  )
1906 {
1907  SCIPdebugMessage("calling SCIPlpiDelCols()\n");
1908 
1909  assert(lpi != NULL);
1910  assert(lpi->spx != NULL);
1911  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
1912 
1913  invalidateSolution(lpi);
1914 
1915  assert( lpi->spx->preStrongbranchingBasisFreed() );
1916 
1917  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColRange(firstcol, lastcol) );
1918 
1919  return SCIP_OKAY;
1920 }
1921 
1922 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1924  SCIP_LPI* lpi, /**< LP interface structure */
1925  int* dstat /**< deletion status of columns
1926  * input: 1 if column should be deleted, 0 if not
1927  * output: new position of column, -1 if column was deleted */
1928  )
1929 {
1930  int ncols;
1931  int i;
1932 
1933  SCIPdebugMessage("calling SCIPlpiDelColset()\n");
1934 
1935  assert(lpi != NULL);
1936  assert(lpi->spx != NULL);
1937 
1938  invalidateSolution(lpi);
1939 
1940  assert( lpi->spx->preStrongbranchingBasisFreed() );
1941 
1942  ncols = lpi->spx->nCols();
1943 
1944  /* SoPlex removeCols() method deletes the columns with dstat[i] < 0, so we have to negate the values */
1945  for( i = 0; i < ncols; ++i )
1946  dstat[i] *= -1;
1947 
1948  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeCols(dstat) );
1949 
1950  return SCIP_OKAY;
1951 }
1952 
1953 /** adds rows to the LP */
1955  SCIP_LPI* lpi, /**< LP interface structure */
1956  int nrows, /**< number of rows to be added */
1957  const SCIP_Real* lhs, /**< left hand sides of new rows */
1958  const SCIP_Real* rhs, /**< right hand sides of new rows */
1959  char** /*rownames*/, /**< row names, or NULL */
1960  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1961  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1962  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1963  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1964  )
1965 {
1966  SCIPdebugMessage("calling SCIPlpiAddRows()\n");
1967 
1968  assert(lpi != NULL);
1969  assert(lpi->spx != NULL);
1970  assert(lhs != NULL);
1971  assert(rhs != NULL);
1972  assert(nnonz == 0 || beg != NULL);
1973  assert(nnonz == 0 || ind != NULL);
1974  assert(nnonz == 0 || val != NULL);
1975 
1976  invalidateSolution(lpi);
1977 
1978  assert( lpi->spx->preStrongbranchingBasisFreed() );
1979 
1980 #ifndef NDEBUG
1981  if ( nnonz > 0 )
1982  {
1983  /* perform check that no new columns are added - this is likely to be a mistake */
1984  int ncols = lpi->spx->nCols();
1985  for (int j = 0; j < nnonz; ++j)
1986  assert( 0 <= ind[j] && ind[j] < ncols );
1987  }
1988 #endif
1989 
1990  try
1991  {
1992  SPxSCIP* spx = lpi->spx;
1993  LPRowSet rows(nrows);
1994  DSVector rowVector;
1995  int start;
1996  int last;
1997  int i;
1998 
1999  /* create row vectors with given sides */
2000  for( i = 0; i < nrows; ++i )
2001  {
2002  rowVector.clear();
2003  if( nnonz > 0 )
2004  {
2005  start = beg[i];
2006  last = (i == nrows-1 ? nnonz : beg[i+1]);
2007  rowVector.add( last-start, &ind[start], &val[start] );
2008  }
2009  rows.add(lhs[i], rowVector, rhs[i]);
2010  }
2011  spx->addRows(rows);
2012  }
2013 #ifndef NDEBUG
2014  catch( const SPxException& x )
2015  {
2016  std::string s = x.what();
2017  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2018 #else
2019  catch( const SPxException& )
2020  {
2021 #endif
2022  return SCIP_LPERROR;
2023  }
2024 
2025  return SCIP_OKAY;
2026 }
2027 
2028 /** deletes all rows in the given range from LP */
2030  SCIP_LPI* lpi, /**< LP interface structure */
2031  int firstrow, /**< first row to be deleted */
2032  int lastrow /**< last row to be deleted */
2033  )
2034 {
2035  SCIPdebugMessage("calling SCIPlpiDelRows()\n");
2036 
2037  assert(lpi != NULL);
2038  assert(lpi->spx != NULL);
2039  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2040 
2041  invalidateSolution(lpi);
2042 
2043  assert( lpi->spx->preStrongbranchingBasisFreed() );
2044 
2045  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowRange(firstrow, lastrow) );
2046 
2047  return SCIP_OKAY;
2048 }
2049 
2050 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
2052  SCIP_LPI* lpi, /**< LP interface structure */
2053  int* dstat /**< deletion status of rows
2054  * input: 1 if row should be deleted, 0 if not
2055  * output: new position of row, -1 if row was deleted */
2056  )
2057 {
2058  int nrows;
2059  int i;
2060 
2061  SCIPdebugMessage("calling SCIPlpiDelRowset()\n");
2062 
2063  assert(lpi != NULL);
2064  assert(lpi->spx != NULL);
2065 
2066  invalidateSolution(lpi);
2067 
2068  assert( lpi->spx->preStrongbranchingBasisFreed() );
2069 
2070  nrows = lpi->spx->nRows();
2071 
2072  /* SoPlex removeRows() method deletes the rows with dstat[i] < 0, so we have to negate the values */
2073  for( i = 0; i < nrows; ++i )
2074  dstat[i] *= -1;
2075 
2076  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRows(dstat) );
2077 
2078  return SCIP_OKAY;
2079 }
2080 
2081 /** clears the whole LP */
2083  SCIP_LPI* lpi /**< LP interface structure */
2084  )
2086  SCIPdebugMessage("calling SCIPlpiClear()\n");
2087 
2088  assert(lpi != NULL);
2089  assert(lpi->spx != NULL);
2090 
2091  invalidateSolution(lpi);
2092 
2093  assert( lpi->spx->preStrongbranchingBasisFreed() );
2094  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->clear() );
2095 
2096  return SCIP_OKAY;
2097 }
2098 
2099 /** changes lower and upper bounds of columns */
2101  SCIP_LPI* lpi, /**< LP interface structure */
2102  int ncols, /**< number of columns to change bounds for */
2103  const int* ind, /**< column indices */
2104  const SCIP_Real* lb, /**< values for the new lower bounds */
2105  const SCIP_Real* ub /**< values for the new upper bounds */
2106  )
2107 {
2108  int i;
2109 
2110  SCIPdebugMessage("calling SCIPlpiChgBounds()\n");
2111 
2112  assert(lpi != NULL);
2113  assert(lpi->spx != NULL);
2114  assert(ind != NULL);
2115  assert(lb != NULL);
2116  assert(ub != NULL);
2117 
2118  invalidateSolution(lpi);
2119 
2120  assert( lpi->spx->preStrongbranchingBasisFreed() );
2121 
2122  try
2123  {
2124  for( i = 0; i < ncols; ++i )
2125  {
2126  assert(0 <= ind[i] && ind[i] < lpi->spx->nCols());
2127 
2128  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
2129  {
2130  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
2131  return SCIP_LPERROR;
2132  }
2133  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
2134  {
2135  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
2136  return SCIP_LPERROR;
2137  }
2138 
2139  lpi->spx->changeBounds(ind[i], lb[i], ub[i]);
2140  assert(lpi->spx->lower(ind[i]) <= lpi->spx->upper(ind[i]) + Param::epsilon());
2141  }
2142  }
2143 #ifndef NDEBUG
2144  catch( const SPxException& x )
2145  {
2146  std::string s = x.what();
2147  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2148 #else
2149  catch( const SPxException& )
2150  {
2151 #endif
2152  return SCIP_LPERROR;
2153  }
2154 
2155  return SCIP_OKAY;
2156 }
2157 
2158 /** changes left and right hand sides of rows */
2160  SCIP_LPI* lpi, /**< LP interface structure */
2161  int nrows, /**< number of rows to change sides for */
2162  const int* ind, /**< row indices */
2163  const SCIP_Real* lhs, /**< new values for left hand sides */
2164  const SCIP_Real* rhs /**< new values for right hand sides */
2165  )
2166 {
2167  int i;
2168 
2169  SCIPdebugMessage("calling SCIPlpiChgSides()\n");
2170 
2171  assert(lpi != NULL);
2172  assert(lpi->spx != NULL);
2173  assert(ind != NULL);
2174  assert(lhs != NULL);
2175  assert(rhs != NULL);
2176 
2177  invalidateSolution(lpi);
2178 
2179  assert( lpi->spx->preStrongbranchingBasisFreed() );
2180 
2181  try
2182  {
2183  for( i = 0; i < nrows; ++i )
2184  {
2185  assert(0 <= ind[i] && ind[i] < lpi->spx->nRows());
2186  lpi->spx->changeRange(ind[i], lhs[i], rhs[i]);
2187  assert(lpi->spx->lhs(ind[i]) <= lpi->spx->rhs(ind[i]) + Param::epsilon());
2188  }
2189  }
2190 #ifndef NDEBUG
2191  catch( const SPxException& x )
2192  {
2193  std::string s = x.what();
2194  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2195 #else
2196  catch( const SPxException& )
2197  {
2198 #endif
2199  return SCIP_LPERROR;
2200  }
2201 
2202  return SCIP_OKAY;
2203 }
2204 
2205 /** changes a single coefficient */
2207  SCIP_LPI* lpi, /**< LP interface structure */
2208  int row, /**< row number of coefficient to change */
2209  int col, /**< column number of coefficient to change */
2210  SCIP_Real newval /**< new value of coefficient */
2211  )
2212 {
2213  SCIPdebugMessage("calling SCIPlpiChgCoef()\n");
2214 
2215  assert(lpi != NULL);
2216  assert(lpi->spx != NULL);
2217  assert(0 <= row && row < lpi->spx->nRows());
2218  assert(0 <= col && col < lpi->spx->nCols());
2219 
2220  invalidateSolution(lpi);
2221 
2222  assert( lpi->spx->preStrongbranchingBasisFreed() );
2223 
2224  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->changeElement(row, col, newval) );
2225 
2226  return SCIP_OKAY;
2227 }
2228 
2229 /** changes the objective sense */
2231  SCIP_LPI* lpi, /**< LP interface structure */
2232  SCIP_OBJSEN objsen /**< new objective sense */
2233  )
2234 {
2235  SCIPdebugMessage("calling SCIPlpiChgObjsen()\n");
2236 
2237  assert(lpi != NULL);
2238  assert(lpi->spx != NULL);
2239 
2240  invalidateSolution(lpi);
2241 
2242  assert( lpi->spx->preStrongbranchingBasisFreed() );
2243 
2244  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setSense(spxObjsen(objsen)) );
2245 
2246  return SCIP_OKAY;
2247 }
2248 
2249 /** changes objective values of columns in the LP */
2251  SCIP_LPI* lpi, /**< LP interface structure */
2252  int ncols, /**< number of columns to change objective value for */
2253  const int* ind, /**< column indices to change objective value for */
2254  const SCIP_Real* obj /**< new objective values for columns */
2255  )
2256 {
2257  int i;
2258 
2259  SCIPdebugMessage("calling SCIPlpiChgObj()\n");
2260 
2261  assert(lpi != NULL);
2262  assert(lpi->spx != NULL);
2263  assert(ind != NULL);
2264  assert(obj != NULL);
2265 
2266  invalidateSolution(lpi);
2267 
2268  assert( lpi->spx->preStrongbranchingBasisFreed() );
2269 
2270  try
2271  {
2272  for( i = 0; i < ncols; ++i )
2273  {
2274  assert(0 <= ind[i] && ind[i] < lpi->spx->nCols());
2275  lpi->spx->changeObj(ind[i], obj[i]);
2276  }
2277  }
2278 #ifndef NDEBUG
2279  catch( const SPxException& x )
2280  {
2281  std::string s = x.what();
2282  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2283 #else
2284  catch( const SPxException& )
2285  {
2286 #endif
2287  return SCIP_LPERROR;
2288  }
2289 
2290  return SCIP_OKAY;
2291 }
2292 
2293 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
2295  SCIP_LPI* lpi, /**< LP interface structure */
2296  int row, /**< row number to scale */
2297  SCIP_Real scaleval /**< scaling multiplier */
2298  )
2299 {
2300  SCIP_Real lhs;
2301  SCIP_Real rhs;
2302 
2303  SCIPdebugMessage("calling SCIPlpiScaleRow()\n");
2304 
2305  assert(lpi != NULL);
2306  assert(lpi->spx != NULL);
2307  assert(scaleval != 0.0);
2308 
2309  try
2310  {
2311  invalidateSolution(lpi);
2312 
2313  assert( lpi->spx->preStrongbranchingBasisFreed() );
2314 
2315  /* get the row vector and the row's sides */
2316  SVector rowvec = lpi->spx->rowVector(row);
2317  lhs = lpi->spx->lhs(row);
2318  rhs = lpi->spx->rhs(row);
2319 
2320  /* scale the row vector */
2321  rowvec *= scaleval;
2322 
2323  /* adjust the sides */
2324  if( lhs > -soplex::infinity )
2325  lhs *= scaleval;
2326  else if( scaleval < 0.0 )
2327  lhs = soplex::infinity;
2328  if( rhs < soplex::infinity )
2329  rhs *= scaleval;
2330  else if( scaleval < 0.0 )
2331  rhs = -soplex::infinity;
2332  if( scaleval < 0.0 )
2333  {
2334  SCIP_Real oldlhs = lhs;
2335  lhs = rhs;
2336  rhs = oldlhs;
2337  }
2338 
2339  /* create the new row */
2340  LPRow lprow(lhs, rowvec, rhs);
2341 
2342  /* change the row in the LP */
2343  lpi->spx->changeRow(row, lprow);
2344  assert(lpi->spx->lhs(row) <= lpi->spx->rhs(row));
2345  }
2346 #ifndef NDEBUG
2347  catch( const SPxException& x )
2348  {
2349  std::string s = x.what();
2350  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2351 #else
2352  catch( const SPxException& )
2353  {
2354 #endif
2355  return SCIP_LPERROR;
2356  }
2357 
2358  return SCIP_OKAY;
2359 }
2360 
2361 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
2362  * are divided by the scalar; for negative scalars, the column's bounds are switched
2363  */
2365  SCIP_LPI* lpi, /**< LP interface structure */
2366  int col, /**< column number to scale */
2367  SCIP_Real scaleval /**< scaling multiplier */
2368  )
2369 {
2370  SCIP_Real obj;
2371  SCIP_Real lb;
2372  SCIP_Real ub;
2373 
2374  SCIPdebugMessage("calling SCIPlpiScaleCol()\n");
2375 
2376  assert(lpi != NULL);
2377  assert(lpi->spx != NULL);
2378  assert(scaleval != 0.0);
2379 
2380  try
2381  {
2382  invalidateSolution(lpi);
2383 
2384  assert( lpi->spx->preStrongbranchingBasisFreed() );
2385 
2386  /* get the col vector and the col's bounds and objective value */
2387  SVector colvec = lpi->spx->colVector(col);
2388  obj = lpi->spx->obj(col);
2389  lb = lpi->spx->lower(col);
2390  ub = lpi->spx->upper(col);
2391 
2392  /* scale the col vector */
2393  colvec *= scaleval;
2394 
2395  /* scale the objective value */
2396  obj *= scaleval;
2397 
2398  /* adjust the bounds */
2399  if( lb > -soplex::infinity )
2400  lb /= scaleval;
2401  else if( scaleval < 0.0 )
2402  lb = soplex::infinity;
2403  if( ub < soplex::infinity )
2404  ub /= scaleval;
2405  else if( scaleval < 0.0 )
2406  ub = -soplex::infinity;
2407  if( scaleval < 0.0 )
2408  {
2409  SCIP_Real oldlb = lb;
2410  lb = ub;
2411  ub = oldlb;
2412  }
2413 
2414  /* create the new col (in LPCol's constructor, the upper bound is given first!) */
2415  LPCol lpcol(obj, colvec, ub, lb);
2416 
2417  /* change the col in the LP */
2418  lpi->spx->changeCol(col, lpcol);
2419  assert(lpi->spx->lower(col) <= lpi->spx->upper(col));
2420  }
2421 #ifndef NDEBUG
2422  catch( const SPxException& x )
2423  {
2424  std::string s = x.what();
2425  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
2426 #else
2427  catch( const SPxException& )
2428  {
2429 #endif
2430  return SCIP_LPERROR;
2431  }
2432 
2433  return SCIP_OKAY;
2434 }
2435 
2436 /**@} */
2437 
2438 
2439 
2440 
2441 /*
2442  * Data Accessing Methods
2443  */
2444 
2445 /**@name Data Accessing Methods */
2446 /**@{ */
2447 
2448 /** gets the number of rows in the LP */
2450  SCIP_LPI* lpi, /**< LP interface structure */
2451  int* nrows /**< pointer to store the number of rows */
2452  )
2453 {
2454  SCIPdebugMessage("calling SCIPlpiGetNRows()\n");
2455 
2456  assert(lpi != NULL);
2457  assert(lpi->spx != NULL);
2458  assert(nrows != NULL);
2459 
2460  *nrows = lpi->spx->nRows();
2461 
2462  return SCIP_OKAY;
2463 }
2464 
2465 /** gets the number of columns in the LP */
2467  SCIP_LPI* lpi, /**< LP interface structure */
2468  int* ncols /**< pointer to store the number of cols */
2469  )
2470 {
2471  SCIPdebugMessage("calling SCIPlpiGetNCols()\n");
2472 
2473  assert(lpi != NULL);
2474  assert(lpi->spx != NULL);
2475  assert(ncols != NULL);
2476 
2477  *ncols = lpi->spx->nCols();
2478 
2479  return SCIP_OKAY;
2480 }
2481 
2482 /** gets the number of nonzero elements in the LP constraint matrix */
2484  SCIP_LPI* lpi, /**< LP interface structure */
2485  int* nnonz /**< pointer to store the number of nonzeros */
2486  )
2487 {
2488  int i;
2489 
2490  SCIPdebugMessage("calling SCIPlpiGetNNonz()\n");
2491 
2492  assert(lpi != NULL);
2493  assert(lpi->spx != NULL);
2494  assert(nnonz != NULL);
2495 
2496  /* SoPlex has no direct method to return the number of nonzeros, so we have to count them manually */
2497  *nnonz = 0;
2498  if( lpi->spx->nRows() < lpi->spx->nCols() )
2499  {
2500  for( i = 0; i < lpi->spx->nRows(); ++i )
2501  (*nnonz) += lpi->spx->rowVector(i).size();
2502  }
2503  else
2504  {
2505  for( i = 0; i < lpi->spx->nCols(); ++i )
2506  (*nnonz) += lpi->spx->colVector(i).size();
2507  }
2508 
2509  return SCIP_OKAY;
2510 }
2511 
2512 /** gets columns from LP problem object; the arrays have to be large enough to store all values
2513  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
2514  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2515  */
2517  SCIP_LPI* lpi, /**< LP interface structure */
2518  int firstcol, /**< first column to get from LP */
2519  int lastcol, /**< last column to get from LP */
2520  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
2521  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
2522  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2523  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
2524  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
2525  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2526  )
2527 {
2528  int i;
2529  int j;
2530 
2531  SCIPdebugMessage("calling SCIPlpiGetCols()\n");
2532 
2533  assert(lpi != NULL);
2534  assert(lpi->spx != NULL);
2535  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2536 
2537  if( lb != NULL )
2538  {
2539  assert(ub != NULL);
2540 
2541  const Vector& lbvec = lpi->spx->lower();
2542  const Vector& ubvec = lpi->spx->upper();
2543  for( i = firstcol; i <= lastcol; ++i )
2544  {
2545  lb[i-firstcol] = lbvec[i];
2546  ub[i-firstcol] = ubvec[i];
2547  }
2548  }
2549  else
2550  assert(ub == NULL);
2551 
2552  if( nnonz != NULL )
2553  {
2554  *nnonz = 0;
2555  for( i = firstcol; i <= lastcol; ++i )
2556  {
2557  beg[i-firstcol] = *nnonz;
2558  const SVector& cvec = lpi->spx->colVector(i);
2559  for( j = 0; j < cvec.size(); ++j )
2560  {
2561  ind[*nnonz] = cvec.index(j);
2562  val[*nnonz] = cvec.value(j);
2563  (*nnonz)++;
2564  }
2565  }
2566  }
2567  else
2568  {
2569  assert(beg == NULL);
2570  assert(ind == NULL);
2571  assert(val == NULL);
2572  }
2573 
2574  return SCIP_OKAY;
2575 }
2576 
2577 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
2578  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
2579  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2580  */
2582  SCIP_LPI* lpi, /**< LP interface structure */
2583  int firstrow, /**< first row to get from LP */
2584  int lastrow, /**< last row to get from LP */
2585  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
2586  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
2587  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2588  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
2589  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
2590  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2591  )
2592 {
2593  int i;
2594  int j;
2595 
2596  SCIPdebugMessage("calling SCIPlpiGetRows()\n");
2597 
2598  assert(lpi != NULL);
2599  assert(lpi->spx != NULL);
2600  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2601 
2602  if( lhs != NULL )
2603  {
2604  assert(rhs != NULL);
2605 
2606  const Vector& lhsvec = lpi->spx->lhs();
2607  const Vector& rhsvec = lpi->spx->rhs();
2608  for( i = firstrow; i <= lastrow; ++i )
2609  {
2610  lhs[i-firstrow] = lhsvec[i];
2611  rhs[i-firstrow] = rhsvec[i];
2612  }
2613  }
2614  else
2615  assert(rhs == NULL);
2616 
2617  if( nnonz != NULL )
2618  {
2619  *nnonz = 0;
2620  for( i = firstrow; i <= lastrow; ++i )
2621  {
2622  beg[i-firstrow] = *nnonz;
2623  const SVector& rvec = lpi->spx->rowVector(i);
2624  for( j = 0; j < rvec.size(); ++j )
2625  {
2626  ind[*nnonz] = rvec.index(j);
2627  val[*nnonz] = rvec.value(j);
2628  (*nnonz)++;
2629  }
2630  }
2631  }
2632  else
2633  {
2634  assert(beg == NULL);
2635  assert(ind == NULL);
2636  assert(val == NULL);
2637  }
2638 
2639  return SCIP_OKAY;
2640 }
2641 
2642 /** gets column names */
2644  SCIP_LPI* lpi, /**< LP interface structure */
2645  int firstcol, /**< first column to get name from LP */
2646  int lastcol, /**< last column to get name from LP */
2647  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) */
2648  char* namestorage, /**< storage for col names */
2649  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2650  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
2651  )
2652 {
2653  assert( lpi != NULL );
2654  assert( lpi->spx != NULL );
2655  assert( colnames != NULL || namestoragesize == 0 );
2656  assert( namestorage != NULL || namestoragesize == 0 );
2657  assert( namestoragesize >= 0 );
2658  assert( storageleft != NULL );
2659  assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols() );
2660 
2661  SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
2662 
2663  lpi->spx->getColNames(firstcol, lastcol, colnames, namestorage, namestoragesize, storageleft);
2664 
2665  return SCIP_OKAY;
2666 }
2667 
2668 /** gets row names */
2670  SCIP_LPI* lpi, /**< LP interface structure */
2671  int firstrow, /**< first row to get name from LP */
2672  int lastrow, /**< last row to get name from LP */
2673  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) */
2674  char* namestorage, /**< storage for row names */
2675  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2676  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
2677  )
2678 {
2679  assert( lpi != NULL );
2680  assert( lpi->spx != NULL );
2681  assert( rownames != NULL || namestoragesize == 0 );
2682  assert( namestorage != NULL || namestoragesize == 0 );
2683  assert( namestoragesize >= 0 );
2684  assert( storageleft != NULL );
2685  assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows() );
2686 
2687  SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
2688 
2689  lpi->spx->getRowNames(firstrow, lastrow, rownames, namestorage, namestoragesize, storageleft);
2690 
2691  return SCIP_OKAY;
2692 }
2693 
2694 /** gets objective sense of the LP */
2696  SCIP_LPI* lpi, /**< LP interface structure */
2697  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2698  )
2699 {
2700  SCIPdebugMessage("calling SCIPlpiGetObjsen()\n");
2701 
2702  assert(lpi != NULL);
2703  assert(lpi->spx != NULL);
2704  assert(objsen != NULL);
2705 
2706  *objsen = (lpi->spx->getSense() == SPxLP::MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2707 
2708  return SCIP_OKAY;
2709 }
2710 
2711 /** gets objective coefficients from LP problem object */
2713  SCIP_LPI* lpi, /**< LP interface structure */
2714  int firstcol, /**< first column to get objective coefficient for */
2715  int lastcol, /**< last column to get objective coefficient for */
2716  SCIP_Real* vals /**< array to store objective coefficients */
2717  )
2718 {
2719  int i;
2720 
2721  SCIPdebugMessage("calling SCIPlpiGetObj()\n");
2722 
2723  assert(lpi != NULL);
2724  assert(lpi->spx != NULL);
2725  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2726  assert(vals != NULL);
2727 
2728  for( i = firstcol; i <= lastcol; ++i )
2729  vals[i-firstcol] = lpi->spx->obj(i);
2730 
2731  return SCIP_OKAY;
2732 }
2733 
2734 /** gets current bounds from LP problem object */
2736  SCIP_LPI* lpi, /**< LP interface structure */
2737  int firstcol, /**< first column to get objective value for */
2738  int lastcol, /**< last column to get objective value for */
2739  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2740  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2741  )
2742 {
2743  int i;
2744 
2745  SCIPdebugMessage("calling SCIPlpiGetBounds()\n");
2746 
2747  assert(lpi != NULL);
2748  assert(lpi->spx != NULL);
2749  assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2750 
2751  for( i = firstcol; i <= lastcol; ++i )
2752  {
2753  if( lbs != NULL )
2754  lbs[i-firstcol] = lpi->spx->lower(i);
2755  if( ubs != NULL )
2756  ubs[i-firstcol] = lpi->spx->upper(i);
2757  }
2758 
2759  return SCIP_OKAY;
2760 }
2761 
2762 /** gets current row sides from LP problem object */
2764  SCIP_LPI* lpi, /**< LP interface structure */
2765  int firstrow, /**< first row to get sides for */
2766  int lastrow, /**< last row to get sides for */
2767  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2768  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2769  )
2770 {
2771  int i;
2772 
2773  SCIPdebugMessage("calling SCIPlpiGetSides()\n");
2774 
2775  assert(lpi != NULL);
2776  assert(lpi->spx != NULL);
2777  assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2778 
2779  for( i = firstrow; i <= lastrow; ++i )
2780  {
2781  if( lhss != NULL )
2782  lhss[i-firstrow] = lpi->spx->lhs(i);
2783  if( rhss != NULL )
2784  rhss[i-firstrow] = lpi->spx->rhs(i);
2785  }
2786 
2787  return SCIP_OKAY;
2788 }
2789 
2790 /** gets a single coefficient */
2792  SCIP_LPI* lpi, /**< LP interface structure */
2793  int row, /**< row number of coefficient */
2794  int col, /**< column number of coefficient */
2795  SCIP_Real* val /**< pointer to store the value of the coefficient */
2796  )
2797 {
2798  SCIPdebugMessage("calling SCIPlpiGetCoef()\n");
2799 
2800  assert(lpi != NULL);
2801  assert(lpi->spx != NULL);
2802  assert(0 <= col && col < lpi->spx->nCols());
2803  assert(0 <= row && row < lpi->spx->nRows());
2804  assert(val != NULL);
2805 
2806  *val = lpi->spx->colVector(col)[row];
2807 
2808  return SCIP_OKAY;
2809 }
2810 
2811 /**@} */
2812 
2813 
2814 
2815 
2816 /*
2817  * Solving Methods
2818  */
2819 
2820 /**@name Solving Methods */
2821 /**@{ */
2822 
2823 /** solves LP -- used for both, primal and dual simplex, because SoPlex doesn't distinct the two cases */
2824 static
2826  SCIP_LPI* lpi, /**< LP interface structure */
2827  SPxSolver::Representation rep, /**< basis representation */
2828  SPxSolver::Type type /**< algorithm type */
2829  )
2830 {
2831  assert( lpi != NULL );
2832  assert( lpi->spx != NULL );
2833  assert( rep == SPxSolver::ROW || rep == SPxSolver::COLUMN );
2834  assert( type == SPxSolver::ENTER || type == SPxSolver::LEAVE );
2835 
2836  SCIPdebugMessage("calling SoPlex solve(): %d cols, %d rows, rep=%s\n", lpi->spx->nCols(), lpi->spx->nRows(),
2837  rep == SPxSolver::COLUMN ? "column" : "row");
2838 
2839  invalidateSolution(lpi);
2840 
2841  assert( lpi->spx->preStrongbranchingBasisFreed() );
2842 
2843  /* set basis representation and algorithm type */
2844  lpi->spx->setRep(rep);
2845  lpi->spx->setType(type);
2846 
2847 #ifdef WITH_LPSCHECK
2848  lpi->spx->setDoubleCheck(CHECK_SPXSOLVE);
2849 #endif
2850 
2851  SPxSolver::Status status = lpi->spx->solve();
2852  SCIPdebugMessage(" -> SoPlex status: %d, basis status: %d\n", lpi->spx->getStatus(), lpi->spx->basis().status());
2853  lpi->solved = TRUE;
2854 
2855  switch( status )
2856  {
2857  case SPxSolver::ABORT_TIME:
2858  case SPxSolver::ABORT_ITER:
2859  case SPxSolver::ABORT_VALUE:
2860  case SPxSolver::SINGULAR:
2861  case SPxSolver::REGULAR:
2862  case SPxSolver::UNKNOWN:
2863  case SPxSolver::OPTIMAL:
2864  case SPxSolver::UNBOUNDED:
2865  case SPxSolver::INFEASIBLE:
2866  return SCIP_OKAY;
2867  default:
2868  return SCIP_LPERROR;
2869  } /*lint !e788*/
2870 }
2871 
2872 /** calls primal simplex to solve the LP */
2874  SCIP_LPI* lpi /**< LP interface structure */
2875  )
2877  SCIPdebugMessage("calling SCIPlpiSolvePrimal()\n");
2878 
2879  SCIP_RETCODE retcode;
2880  SCIP_Bool rowrep;
2881 
2882  assert(lpi != NULL);
2883  assert(lpi->spx != NULL);
2884 
2885  /* first decide if we want to switch the basis representation; in order to avoid oscillatory behaviour, we add the
2886  factor 1.1 for switching back to column representation */
2887  if( lpi->rowrepswitch >= 0 )
2888  {
2889  rowrep = lpi->spx->rep() == SPxSolver::ROW;
2890 
2891  if( !rowrep )
2892  rowrep = lpi->spx->nRows() > lpi->spx->nCols() * (lpi->rowrepswitch);
2893  else
2894  rowrep = lpi->spx->nRows() * 1.1 > lpi->spx->nCols() * (lpi->rowrepswitch);
2895  }
2896  else
2897  rowrep = FALSE;
2898 
2899  /* SoPlex doesn't distinct between the primal and dual simplex; however
2900  * we can force SoPlex to start with the desired method:
2901  * If the representation is COLUMN:
2902  * - ENTER = PRIMAL
2903  * - LEAVE = DUAL
2904  *
2905  * If the representation is ROW:
2906  * - ENTER = DUAL
2907  * - LEAVE = PRIMAL
2908  */
2909  retcode = rowrep ? spxSolve(lpi, SPxSolver::ROW, SPxSolver::LEAVE) : spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::ENTER);
2910  assert(!rowrep || lpi->spx->rep() == SPxSolver::ROW);
2911  assert(rowrep || lpi->spx->rep() == SPxSolver::COLUMN);
2912 
2913  return retcode;
2914 }
2915 
2916 /** calls dual simplex to solve the LP */
2918  SCIP_LPI* lpi /**< LP interface structure */
2919  )
2921  SCIPdebugMessage("calling SCIPlpiSolveDual()\n");
2922 
2923  SCIP_RETCODE retcode;
2924  SCIP_Bool rowrep;
2925 
2926  assert(lpi != NULL);
2927  assert(lpi->spx != NULL);
2928 
2929  /* first decide if we want to switch the basis representation; in order to avoid oscillatory behaviour, we add the
2930  factor 1.1 for switching back to column representation */
2931  if( lpi->rowrepswitch >= 0 )
2932  {
2933  rowrep = lpi->spx->rep() == SPxSolver::ROW;
2934 
2935  if( !rowrep )
2936  rowrep = lpi->spx->nRows() > lpi->spx->nCols() * (lpi->rowrepswitch);
2937  else
2938  rowrep = lpi->spx->nRows() * 1.1 > lpi->spx->nCols() * (lpi->rowrepswitch);
2939  }
2940  else
2941  rowrep = FALSE;
2942 
2943  /* SoPlex doesn't distinct between the primal and dual simplex; however
2944  * we can force SoPlex to start with the desired method:
2945  * If the representation is COLUMN:
2946  * - ENTER = PRIMAL
2947  * - LEAVE = DUAL
2948  *
2949  * If the representation is ROW:
2950  * - ENTER = DUAL
2951  * - LEAVE = PRIMAL
2952  */
2953  retcode = rowrep ? spxSolve(lpi, SPxSolver::ROW, SPxSolver::ENTER) : spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::LEAVE);
2954  assert(!rowrep || lpi->spx->rep() == SPxSolver::ROW);
2955  assert(rowrep || lpi->spx->rep() == SPxSolver::COLUMN);
2956 
2957  return retcode;
2958 }
2959 
2960 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2962  SCIP_LPI* lpi, /**< LP interface structure */
2963  SCIP_Bool crossover /**< perform crossover */
2964  )
2965 { /*lint --e{715}*/
2966  SCIPdebugMessage("calling SCIPlpiSolveBarrier()\n");
2967 
2968  /* SoPlex does not support barrier (yet) */
2969  SCIPerrorMessage("SCIPlpiSolveBarrier() not supported by SoPlex\n");
2970  return SCIP_INVALIDCALL;
2971 }
2972 
2973 /** start strong branching - call before any strongbranching */
2975  SCIP_LPI* lpi /**< LP interface structure */
2976  )
2978  assert( lpi->spx->preStrongbranchingBasisFreed() );
2979  lpi->spx->savePreStrongbranchingBasis();
2980 
2981  return SCIP_OKAY;
2982 }
2983 
2984 /** end strong branching - call after any strongbranching */
2986  SCIP_LPI* lpi /**< LP interface structure */
2987  )
2989  assert( ! lpi->spx->preStrongbranchingBasisFreed() );
2990  lpi->spx->restorePreStrongbranchingBasis();
2991  lpi->spx->freePreStrongbranchingBasis();
2992 
2993  return SCIP_OKAY;
2994 }
2995 
2996 /** performs strong branching iterations on one arbitrary candidate */
2997 static
2999  SCIP_LPI* lpi, /**< LP interface structure */
3000  int col, /**< column to apply strong branching on */
3001  SCIP_Real psol, /**< current primal solution value of column */
3002  int itlim, /**< iteration limit for strong branchings */
3003  SCIP_Real* down, /**< stores dual bound after branching column down */
3004  SCIP_Real* up, /**< stores dual bound after branching column up */
3005  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3006  * otherwise, it can only be used as an estimate value */
3007  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3008  * otherwise, it can only be used as an estimate value */
3009  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3010  )
3011 {
3012  SPxSCIP* spx;
3013  SPxSolver::Status status;
3014  SCIP_Real oldlb;
3015  SCIP_Real oldub;
3016  SCIP_Real newlb;
3017  SCIP_Real newub;
3018  bool fromparentbasis;
3019  bool error;
3020  int oldItlim;
3021 
3022  SCIPdebugMessage("calling SCIPlpiStrongbranch() on variable %d (%d iterations)\n", col, itlim);
3023 
3024  assert(lpi != NULL);
3025  assert(lpi->spx != NULL);
3026  /* assert(down != NULL);
3027  * assert(up != NULL); temporary hack for cloud branching */
3028  assert(downvalid != NULL);
3029  assert(upvalid != NULL);
3030 
3031  spx = lpi->spx;
3032  status = SPxSolver::UNKNOWN;
3033  fromparentbasis = false;
3034  error = false;
3035  oldItlim = spx->getIterationLimit();
3036 
3037  /* get current bounds of column */
3038  oldlb = spx->lower(col);
3039  oldub = spx->upper(col);
3040 
3041  *downvalid = FALSE;
3042  *upvalid = FALSE;
3043 
3044  if( iter != NULL )
3045  *iter = 0;
3046 
3047  /* set the algorithm type to use dual simplex */
3048  lpi->spx->setType( lpi->spx->rep() == SPxSolver::ROW ? SPxSolver::ENTER : SPxSolver::LEAVE);
3049 
3050  /* down branch */
3051  newub = EPSCEIL(psol-1.0, lpi->spx->feastol());
3052  if( newub >= oldlb - 0.5 && down != NULL )
3053  {
3054  SCIPdebugMessage("strong branching down on x%d (%g) with %d iterations\n", col, psol, itlim);
3055 
3056  spx->changeUpper(col, newub);
3057  assert(spx->lower(col) <= spx->upper(col));
3058 
3059  spx->setIterationLimit(itlim);
3060  do
3061  {
3062 #ifdef WITH_LPSCHECK
3063  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
3064 #endif
3065  status = spx->solve();
3066  SCIPdebugMessage(" --> Terminate with status %d\n", status);
3067  switch( status )
3068  {
3069  case SPxSolver::OPTIMAL:
3070  *down = spx->value();
3071  *downvalid = TRUE;
3072  SCIPdebugMessage(" --> Terminate with value %f\n", spx->value());
3073  break;
3074  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
3075  case SPxSolver::ABORT_ITER:
3076  case SPxSolver::ABORT_CYCLING:
3077  *down = spx->value();
3078  break;
3079  case SPxSolver::ABORT_VALUE:
3080  case SPxSolver::INFEASIBLE:
3081  *down = spx->terminationValue();
3082  *downvalid = TRUE;
3083  break;
3084  default:
3085  error = true;
3086  break;
3087  } /*lint !e788*/
3088  if( iter != NULL )
3089  (*iter) += spx->iterations();
3090 
3091 #ifdef STRONGBRANCH_RESTOREBASIS
3092  /* we restore the pre-strong-branching basis by default (and don't solve again) */
3093  assert( ! spx->preStrongbranchingBasisFreed() );
3094  spx->restorePreStrongbranchingBasis();
3095  fromparentbasis = false;
3096 #else
3097  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
3098  * pre-strong-branching basis and try again with reduced iteration limit */
3099  if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
3100  {
3101  SCIPdebugMessage(" --> Repeat strong branching down with %d iterations after restoring basis\n", itlim - spx->iterations());
3102  spx->setIterationLimit(itlim - spx->iterations());
3103  assert( ! spx->hasPreStrongbranchingBasis() );
3104  spx->restorePreStrongbranchingBasis();
3105  fromparentbasis = true;
3106  error = false;
3107  }
3108  /* otherwise don't solve again */
3109  else
3110  fromparentbasis = false;
3111 #endif
3112  }
3113  while( fromparentbasis );
3114 
3115  spx->changeUpper(col, oldub);
3116  assert(spx->lower(col) <= spx->upper(col));
3117  }
3118  else if( down != NULL )
3119  {
3120  *down = spx->terminationValue();
3121  *downvalid = TRUE;
3122  }
3123  else
3124  *downvalid = TRUE;
3125 
3126  /* up branch */
3127  if( !error )
3128  {
3129  newlb = EPSFLOOR(psol+1.0, lpi->spx->feastol());
3130  if( newlb <= oldub + 0.5 && up != NULL )
3131  {
3132  SCIPdebugMessage("strong branching up on x%d (%g) with %d iterations\n", col, psol, itlim);
3133 
3134  spx->changeLower(col, newlb);
3135  assert(spx->lower(col) <= spx->upper(col));
3136 
3137  spx->setIterationLimit(itlim);
3138  do
3139  {
3140 #ifdef WITH_LPSCHECK
3141  spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
3142 #endif
3143  status = spx->solve();
3144  SCIPdebugMessage(" --> Terminate with status %d\n", status);
3145  switch( status )
3146  {
3147  case SPxSolver::OPTIMAL:
3148  *up = spx->value();
3149  *upvalid = TRUE;
3150  SCIPdebugMessage(" --> Terminate with value %f\n", spx->value());
3151  break;
3152  case SPxSolver::ABORT_TIME: /* SoPlex does not return a proven dual bound, if it is aborted */
3153  case SPxSolver::ABORT_ITER:
3154  case SPxSolver::ABORT_CYCLING:
3155  *up = spx->value();
3156  break;
3157  case SPxSolver::ABORT_VALUE:
3158  case SPxSolver::INFEASIBLE:
3159  *up = spx->terminationValue();
3160  *upvalid = TRUE;
3161  break;
3162  default:
3163  error = true;
3164  break;
3165  } /*lint !e788*/
3166  if( iter != NULL )
3167  (*iter) += spx->iterations();
3168 
3169 #ifdef STRONGBRANCH_RESTOREBASIS
3170  /* we restore the pre-strong-branching basis by default (and don't solve again) */
3171  assert( ! spx->preStrongbranchingBasisFreed() );
3172  spx->restorePreStrongbranchingBasis();
3173  fromparentbasis = false;
3174 #else
3175  /* if cycling or singular basis occured and we started not from the pre-strong-branching basis, then we restore the
3176  * pre-strong-branching basis and try again with reduced iteration limit */
3177  else if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
3178  {
3179  SCIPdebugMessage(" --> Repeat strong branching up with %d iterations after restoring basis\n", itlim - spx->iterations());
3180  assert( ! spx->hasPreStrongbranchingBasis() );
3181  spx->restorePreStrongbranchingBasis();
3182  spx->setIterationLimit(itlim - spx->iterations());
3183  error = false;
3184  fromparentbasis = true;
3185  }
3186  /* otherwise don't solve again */
3187  else
3188  fromparentbasis = false;
3189 #endif
3190  }
3191  while( fromparentbasis );
3192 
3193  spx->changeLower(col, oldlb);
3194  assert(spx->lower(col) <= spx->upper(col));
3195  }
3196  else if( up != NULL )
3197  {
3198  *up = spx->terminationValue();
3199  *upvalid = TRUE;
3200  }
3201  else
3202  *upvalid = TRUE;
3203  }
3204 
3205  /* reset old iteration limit */
3206  spx->setIterationLimit(oldItlim);
3207 
3208  if( error )
3209  {
3210  SCIPdebugMessage("SCIPlpiStrongbranch() returned SoPlex status %d\n", int(status));
3211  return SCIP_LPERROR;
3212  }
3213 
3214  return SCIP_OKAY;
3215 }
3216 
3217 /** performs strong branching iterations on one @b fractional candidate */
3219  SCIP_LPI* lpi, /**< LP interface structure */
3220  int col, /**< column to apply strong branching on */
3221  SCIP_Real psol, /**< fractional current primal solution value of column */
3222  int itlim, /**< iteration limit for strong branchings */
3223  SCIP_Real* down, /**< stores dual bound after branching column down */
3224  SCIP_Real* up, /**< stores dual bound after branching column up */
3225  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3226  * otherwise, it can only be used as an estimate value */
3227  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3228  * otherwise, it can only be used as an estimate value */
3229  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3230  )
3231 {
3232  SCIP_RETCODE retcode;
3233 
3234  /* pass call on to lpiStrongbranch() */
3235  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3236 
3237  /* pass SCIP_LPERROR to SCIP without a back trace */
3238  if( retcode == SCIP_LPERROR )
3239  return SCIP_LPERROR;
3240 
3241  /* evaluate retcode */
3242  SCIP_CALL( retcode );
3243 
3244  return SCIP_OKAY;
3245 }
3246 
3247 /** performs strong branching iterations on given @b fractional candidates */
3249  SCIP_LPI* lpi, /**< LP interface structure */
3250  int* cols, /**< columns to apply strong branching on */
3251  int ncols, /**< number of columns */
3252  SCIP_Real* psols, /**< fractional current primal solution values of columns */
3253  int itlim, /**< iteration limit for strong branchings */
3254  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3255  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3256  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3257  * otherwise, they can only be used as an estimate values */
3258  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3259  * otherwise, they can only be used as an estimate values */
3260  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3261  )
3262 {
3263  SCIP_RETCODE retcode;
3264 
3265  assert( cols != NULL );
3266  assert( psols != NULL );
3267  assert( down != NULL );
3268  assert( up != NULL );
3269  assert( downvalid != NULL );
3270  assert( upvalid != NULL );
3271  assert( down != NULL );
3272 
3273  if ( iter != NULL )
3274  *iter = 0;
3275 
3276  for (int j = 0; j < ncols; ++j)
3277  {
3278  /* pass call on to lpiStrongbranch() */
3279  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3280 
3281  /* pass SCIP_LPERROR to SCIP without a back trace */
3282  if( retcode == SCIP_LPERROR )
3283  return SCIP_LPERROR;
3284 
3285  /* evaluate retcode */
3286  SCIP_CALL( retcode );
3287  }
3288  return SCIP_OKAY;
3289 }
3290 
3291 /** performs strong branching iterations on one candidate with @b integral value */
3293  SCIP_LPI* lpi, /**< LP interface structure */
3294  int col, /**< column to apply strong branching on */
3295  SCIP_Real psol, /**< current integral primal solution value of column */
3296  int itlim, /**< iteration limit for strong branchings */
3297  SCIP_Real* down, /**< stores dual bound after branching column down */
3298  SCIP_Real* up, /**< stores dual bound after branching column up */
3299  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3300  * otherwise, it can only be used as an estimate value */
3301  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3302  * otherwise, it can only be used as an estimate value */
3303  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3304  )
3305 {
3306  SCIP_RETCODE retcode;
3307 
3308  /* pass call on to lpiStrongbranch() */
3309  retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3310 
3311  /* pass SCIP_LPERROR to SCIP without a back trace */
3312  if( retcode == SCIP_LPERROR )
3313  return SCIP_LPERROR;
3314 
3315  /* evaluate retcode */
3316  SCIP_CALL( retcode );
3317 
3318  return SCIP_OKAY;
3319 }
3320 
3321 /** performs strong branching iterations on given candidates with @b integral values */
3323  SCIP_LPI* lpi, /**< LP interface structure */
3324  int* cols, /**< columns to apply strong branching on */
3325  int ncols, /**< number of columns */
3326  SCIP_Real* psols, /**< current integral primal solution values of columns */
3327  int itlim, /**< iteration limit for strong branchings */
3328  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3329  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3330  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3331  * otherwise, they can only be used as an estimate values */
3332  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3333  * otherwise, they can only be used as an estimate values */
3334  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3335  )
3336 {
3337  SCIP_RETCODE retcode;
3338 
3339  assert( cols != NULL );
3340  assert( psols != NULL );
3341  assert( down != NULL );
3342  assert( up != NULL );
3343  assert( downvalid != NULL );
3344  assert( upvalid != NULL );
3345  assert( down != NULL );
3346 
3347  if ( iter != NULL )
3348  *iter = 0;
3349 
3350  for (int j = 0; j < ncols; ++j)
3351  {
3352  /* pass call on to lpiStrongbranch() */
3353  retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3354 
3355  /* pass SCIP_LPERROR to SCIP without a back trace */
3356  if( retcode == SCIP_LPERROR )
3357  return SCIP_LPERROR;
3358 
3359  /* evaluate retcode */
3360  SCIP_CALL( retcode );
3361  }
3362 
3363  return SCIP_OKAY;
3364 }
3365 /**@} */
3366 
3367 
3368 
3369 
3370 /*
3371  * Solution Information Methods
3372  */
3373 
3374 /**@name Solution Information Methods */
3375 /**@{ */
3376 
3377 /** returns whether a solve method was called after the last modification of the LP */
3379  SCIP_LPI* lpi /**< LP interface structure */
3380  )
3382  assert(lpi != NULL);
3383 
3384  return lpi->solved;
3385 }
3386 
3387 /** gets information about primal and dual feasibility of the current LP solution */
3389  SCIP_LPI* lpi, /**< LP interface structure */
3390  SCIP_Bool* primalfeasible, /**< stores primal feasibility status */
3391  SCIP_Bool* dualfeasible /**< stores dual feasibility status */
3392  )
3393 {
3394  SCIPdebugMessage("calling SCIPlpiGetSolFeasibility()\n");
3395 
3396  assert(lpi != NULL);
3397  assert(primalfeasible != NULL);
3398  assert(dualfeasible != NULL);
3399 
3400  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
3401  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
3402 
3403  return SCIP_OKAY;
3404 }
3405 
3406 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3407  * this does not necessarily mean, that the solver knows and can return the primal ray
3408  */
3410  SCIP_LPI* lpi /**< LP interface structure */
3411  )
3413  SCIPdebugMessage("calling SCIPlpiExistsPrimalRay()\n");
3414 
3415  assert(lpi != NULL);
3416  assert(lpi->spx != NULL);
3417 
3418  return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3419 }
3420 
3421 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3422  * and the solver knows and can return the primal ray
3423  */
3425  SCIP_LPI* lpi /**< LP interface structure */
3426  )
3428  SCIPdebugMessage("calling SCIPlpiHasPrimalRay()\n");
3429 
3430  assert(lpi != NULL);
3431  assert(lpi->spx != NULL);
3432 
3433 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3434  return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3435 #else
3436  return FALSE;
3437 #endif
3438 }
3439 
3440 /** returns TRUE iff LP is proven to be primal unbounded */
3442  SCIP_LPI* lpi /**< LP interface structure */
3443  )
3445  SCIPdebugMessage("calling SCIPlpiIsPrimalUnbounded()\n");
3446 
3447  assert(lpi != NULL);
3448  assert(lpi->spx != NULL);
3449 
3450  assert(lpi->spx->getStatus() != SPxSolver::UNBOUNDED || lpi->spx->basis().status() == SPxBasis::UNBOUNDED);
3451 
3452  /* if SoPlex returns unbounded, this may only mean that an unbounded ray is available, not necessarily a primal
3453  * feasible point; hence we have to check the perturbation
3454  */
3455  return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED && !lpi->spx->isPerturbed());
3456 }
3457 
3458 /** returns TRUE iff LP is proven to be primal infeasible */
3460  SCIP_LPI* lpi /**< LP interface structure */
3461  )
3463  SCIPdebugMessage("calling SCIPlpiIsPrimalInfeasible()\n");
3464 
3465  assert(lpi != NULL);
3466  assert(lpi->spx != NULL);
3467 
3468  return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3469 }
3470 
3471 /** returns TRUE iff LP is proven to be primal feasible */
3473  SCIP_LPI* lpi /**< LP interface structure */
3474  )
3476  SPxBasis::SPxStatus basestatus;
3477 
3478  SCIPdebugMessage("calling SCIPlpiIsPrimalFeasible()\n");
3479 
3480  assert(lpi != NULL);
3481  assert(lpi->spx != NULL);
3482 
3483  basestatus = lpi->spx->basis().status();
3484 
3485  /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
3486  * still return true as long as perturbation plus violation is within tolerances
3487  */
3488  assert(basestatus == SPxBasis::OPTIMAL || lpi->spx->getStatus() != SPxSolver::OPTIMAL);
3489 
3490  return basestatus == SPxBasis::OPTIMAL ||
3491  ((basestatus == SPxBasis::PRIMAL || basestatus == SPxBasis::UNBOUNDED) && !lpi->spx->isPerturbed());
3492 }
3493 
3494 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3495  * this does not necessarily mean, that the solver knows and can return the dual ray
3496  */
3498  SCIP_LPI* lpi /**< LP interface structure */
3499  )
3501  SCIPdebugMessage("calling SCIPlpiExistsDualRay()\n");
3502 
3503  assert(lpi != NULL);
3504  assert(lpi->spx != NULL);
3505 
3506  return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3507 }
3508 
3509 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3510  * and the solver knows and can return the dual ray
3511  */
3513  SCIP_LPI* lpi /**< LP interface structure */
3514  )
3516  SCIPdebugMessage("calling SCIPlpiHasDualRay()\n");
3517 
3518  assert(lpi != NULL);
3519  assert(lpi->spx != NULL);
3520 
3521  return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3522 }
3523 
3524 /** returns TRUE iff LP is dual unbounded */
3526  SCIP_LPI* lpi /**< LP interface structure */
3527  )
3529  SCIPdebugMessage("calling SCIPlpiIsDualUnbounded()\n");
3530 
3531  assert(lpi != NULL);
3532  assert(lpi->spx != NULL);
3533 
3534  return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE && lpi->spx->basis().status() == SPxBasis::DUAL
3535  && !lpi->spx->isPerturbed());
3536 }
3537 
3538 /** returns TRUE iff LP is dual infeasible */
3540  SCIP_LPI* lpi /**< LP interface structure */
3541  )
3543  SCIPdebugMessage("calling SCIPlpiIsDualInfeasible()\n");
3544 
3545  assert(lpi != NULL);
3546  assert(lpi->spx != NULL);
3547 
3548  return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3549 }
3550 
3551 /** returns TRUE iff LP is proven to be dual feasible */
3553  SCIP_LPI* lpi /**< LP interface structure */
3554  )
3556  SCIPdebugMessage("calling SCIPlpiIsDualFeasible()\n");
3557 
3558  assert(lpi != NULL);
3559  assert(lpi->spx != NULL);
3560 
3561  /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
3562  * still return true as long as perturbation plus violation is within tolerances
3563  */
3564  assert(lpi->spx->basis().status() == SPxBasis::OPTIMAL || lpi->spx->getStatus() != SPxSolver::OPTIMAL);
3565 
3566  return (lpi->spx->basis().status() == SPxBasis::OPTIMAL) ||
3567  (lpi->spx->basis().status() == SPxBasis::DUAL && !lpi->spx->isPerturbed());
3568 }
3569 
3570 /** returns TRUE iff LP was solved to optimality */
3572  SCIP_LPI* lpi /**< LP interface structure */
3573  )
3575  SCIPdebugMessage("calling SCIPlpiIsOptimal()\n");
3576 
3577  assert(lpi != NULL);
3578  assert((lpi->spx->basis().status() == SPxBasis::OPTIMAL)
3580 
3581  /* note that the solver status may be ABORT_VALUE and the basis status optimal; if we are optimal, isPerturbed() may
3582  * still return true as long as perturbation plus violation is within tolerances
3583  */
3584  return (lpi->spx->basis().status() == SPxBasis::OPTIMAL);
3585 }
3586 
3587 /** returns TRUE iff current LP basis is stable */
3589  SCIP_LPI* lpi /**< LP interface structure */
3590  )
3592  SCIPdebugMessage("calling SCIPlpiIsStable()\n");
3593 
3594  assert(lpi != NULL);
3595  assert(lpi->spx != NULL);
3596 
3597 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3598  /* If the condition number of the basis should be checked, everything above the specified threshold is counted
3599  * as instable.
3600  */
3601  if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3602  {
3603 #ifndef NDEBUG
3604  SCIP_RETCODE retcode;
3605 #endif
3606  SCIP_Real kappa;
3607 
3608 #ifndef NDEBUG
3609  retcode =
3610 #endif
3612  assert(kappa != SCIP_INVALID); /*lint !e777*/
3613  assert(retcode == SCIP_OKAY);
3614 
3615  if( kappa > lpi->conditionlimit )
3616  return FALSE;
3617  }
3618 #endif
3619 
3620  return (lpi->spx->getStatus() != SPxSolver::ERROR && lpi->spx->getStatus() != SPxSolver::SINGULAR);
3621 }
3622 
3623 /** returns TRUE iff the objective limit was reached */
3625  SCIP_LPI* lpi /**< LP interface structure */
3626  )
3628  SCIPdebugMessage("calling SCIPlpiIsObjlimExc()\n");
3629 
3630  assert(lpi != NULL);
3631  assert(lpi->spx != NULL);
3632 
3633  return (lpi->spx->getStatus() == SPxSolver::ABORT_VALUE);
3634 }
3635 
3636 /** returns TRUE iff the iteration limit was reached */
3638  SCIP_LPI* lpi /**< LP interface structure */
3639  )
3641  SCIPdebugMessage("calling SCIPlpiIsIterlimExc()\n");
3642 
3643  assert(lpi != NULL);
3644  assert(lpi->spx != NULL);
3645 
3646  return (lpi->spx->getStatus() == SPxSolver::ABORT_ITER);
3647 }
3648 
3649 /** returns TRUE iff the time limit was reached */
3651  SCIP_LPI* lpi /**< LP interface structure */
3652  )
3654  SCIPdebugMessage("calling SCIPlpiIsTimelimExc()\n");
3655 
3656  assert(lpi != NULL);
3657  assert(lpi->spx != NULL);
3658 
3659  return (lpi->spx->getStatus() == SPxSolver::ABORT_TIME);
3660 }
3661 
3662 /** returns the internal solution status of the solver */
3664  SCIP_LPI* lpi /**< LP interface structure */
3665  )
3667  SCIPdebugMessage("calling SCIPlpiIsTimelimExc()\n");
3668 
3669  assert(lpi != NULL);
3670  assert(lpi->spx != NULL);
3671 
3672  return static_cast<int>(lpi->spx->getStatus());
3673 }
3674 
3675 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3677  SCIP_LPI* lpi, /**< LP interface structure */
3678  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3679  )
3680 { /*lint --e{715}*/
3681  SCIPdebugMessage("calling SCIPlpiIgnoreInstability()\n");
3682 
3683  assert(lpi != NULL);
3684  assert(lpi->spx != NULL);
3685 
3686  /* instable situations cannot be ignored */
3687  *success = FALSE;
3688 
3689  return SCIP_OKAY;
3690 }
3691 
3692 /** gets objective value of solution */
3694  SCIP_LPI* lpi, /**< LP interface structure */
3695  SCIP_Real* objval /**< stores the objective value */
3696  )
3697 {
3698  SCIPdebugMessage("calling SCIPlpiGetObjval()\n");
3699 
3700  assert(lpi != NULL);
3701  assert(lpi->spx != NULL);
3702  assert(objval != NULL);
3703 
3704  *objval = lpi->spx->value();
3705 
3706  return SCIP_OKAY;
3707 }
3708 
3709 /** gets primal and dual solution vectors */
3711  SCIP_LPI* lpi, /**< LP interface structure */
3712  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3713  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3714  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3715  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3716  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3717  )
3718 {
3719  SCIPdebugMessage("calling SCIPlpiGetSol()\n");
3720 
3721  assert(lpi != NULL);
3722  assert(lpi->spx != NULL);
3723 
3724  if( objval != NULL )
3725  *objval = lpi->spx->value();
3726 
3727  try
3728  {
3729  if( primsol != NULL )
3730  {
3731  Vector tmp(lpi->spx->nCols(), primsol);
3732  (void)lpi->spx->getPrimal(tmp);
3733  }
3734  if( dualsol != NULL )
3735  {
3736  Vector tmp(lpi->spx->nRows(), dualsol);
3737  (void)lpi->spx->getDual(tmp);
3738  }
3739  if( activity != NULL )
3740  {
3741  Vector tmp(lpi->spx->nRows(), activity);
3742  (void)lpi->spx->getSlacks(tmp); /* in SoPlex, the activities are called "slacks" */
3743  }
3744  if( redcost != NULL )
3745  {
3746  Vector tmp(lpi->spx->nCols(), redcost);
3747  (void)lpi->spx->getRedCost(tmp);
3748  }
3749  }
3750 #ifndef NDEBUG
3751  catch( const SPxException& x )
3752  {
3753  std::string s = x.what();
3754  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3755 #else
3756  catch( const SPxException& )
3757  {
3758 #endif
3759  return SCIP_LPERROR;
3760  }
3761 
3762  return SCIP_OKAY;
3763 }
3764 
3765 /** gets primal ray for unbounded LPs */
3767  SCIP_LPI* lpi, /**< LP interface structure */
3768  SCIP_Real* ray /**< primal ray */
3769  )
3770 { /*lint --e{715}*/
3771  SCIPdebugMessage("calling SCIPlpiGetPrimalRay()\n");
3772 
3773  assert(lpi != NULL);
3774  assert(lpi->spx != NULL);
3775 
3776 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3777  try
3778  {
3779  Vector tmp(lpi->spx->nCols(), ray);
3780  (void)lpi->spx->getPrimalray(tmp);
3781  }
3782 #ifndef NDEBUG
3783  catch( const SPxException& x )
3784  {
3785  std::string s = x.what();
3786  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3787 #else
3788  catch( const SPxException& )
3789  {
3790 #endif
3791  return SCIP_LPERROR;
3792  }
3793 
3794  return SCIP_OKAY;
3795 #else
3796  SCIPerrorMessage("SCIPlpiGetPrimalRay() not supported by SoPlex versions <= 1.5.0\n");
3797  return SCIP_LPERROR;
3798 #endif
3799 }
3800 
3801 /** gets dual farkas proof for infeasibility */
3803  SCIP_LPI* lpi, /**< LP interface structure */
3804  SCIP_Real* dualfarkas /**< dual farkas row multipliers */
3805  )
3806 {
3807  SCIPdebugMessage("calling SCIPlpiGetDualfarkas()\n");
3808 
3809  assert(lpi != NULL);
3810  assert(lpi->spx != NULL);
3811 
3812  try
3813  {
3814  Vector tmp(lpi->spx->nRows(), dualfarkas);
3815  (void)lpi->spx->getDualfarkas(tmp);
3816  }
3817 #ifndef NDEBUG
3818  catch( const SPxException& x )
3819  {
3820  std::string s = x.what();
3821  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
3822 #else
3823  catch( const SPxException& )
3824  {
3825 #endif
3826  return SCIP_LPERROR;
3827  }
3828 
3829  return SCIP_OKAY;
3830 }
3831 
3832 /** gets the number of LP iterations of the last solve call */
3834  SCIP_LPI* lpi, /**< LP interface structure */
3835  int* iterations /**< pointer to store the number of iterations of the last solve call */
3836  )
3837 {
3838  SCIPdebugMessage("calling SCIPlpiGetIterations()\n");
3839 
3840  assert(lpi != NULL);
3841  assert(lpi->spx != NULL);
3842 
3843  *iterations = lpi->spx->iterations();
3844 
3845  return SCIP_OKAY;
3846 }
3847 
3848 /** gets information about the quality of an LP solution
3849  *
3850  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3851  * The LPI should return SCIP_INVALID for @p quality, if the requested quality is not available.
3852  */
3854  SCIP_LPI* lpi, /**< LP interface structure */
3855  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3856  SCIP_Real* quality /**< pointer to store quality number */
3857  )
3858 {
3859  SCIPdebugMessage("calling SCIPlpiGetRealSolQuality()\n");
3860 
3861  assert(lpi != NULL);
3862  assert(quality != NULL);
3863 
3864 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3865  int maxiter;
3866  Real tolerance;
3867 
3868  assert(lpi != NULL);
3869  assert(quality != NULL);
3870 
3871  SCIPdebugMessage("requesting solution quality from SoPlex: quality %d\n", qualityindicator);
3872 
3873  switch( qualityindicator )
3874  {
3876  maxiter = 20;
3877  tolerance = 1e-6;
3878  break;
3879 
3881  maxiter = 10000;
3882  tolerance = 1e-9;
3883  break;
3884 
3885  default:
3886  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3887  return SCIP_INVALIDDATA;
3888  }
3889 
3890  *quality = lpi->spx->basis().condition(maxiter, tolerance);
3891 #else
3892  *quality = SCIP_INVALID;
3893 #endif
3894  return SCIP_OKAY;
3895 }
3896 
3897 /**@} */
3898 
3899 
3900 
3901 
3902 /*
3903  * LP Basis Methods
3904  */
3905 
3906 /**@name LP Basis Methods */
3907 /**@{ */
3908 
3909 /** Return reduced cost of column @c col if this is readily available, otherwise return 0.0 */
3910 static
3911 SCIP_RETCODE getRedCostEst(SPxSCIP* spx, int col, SCIP_Real* val)
3912 {
3913  assert( spx != NULL );
3914  assert( val != NULL );
3915 
3916  *val = 0.0;
3917 
3918  /* Return if the vectors are not set up. The vectors are not set up if for instance we preformed
3919  * strong branching before. */
3920  if (! spx->isInitialized() )
3921  return SCIP_OKAY;
3922 
3923  assert( 0 <= col && col < spx->nCols() );
3924 
3925  if( spx->rep() == SPxSolver::COLUMN )
3926  {
3927  /* in column case the reduced costs are available: */
3928  if (spx->getSense() == SPxLP::MINIMIZE)
3929  *val = spx->pVec()[col] - spx->maxObj()[col];
3930  else
3931  *val = spx->maxObj()[col] - spx->pVec()[col];
3932  }
3933  else
3934  {
3935  assert( spx->rep() == SPxSolver::ROW );
3936 
3937  /* In row case for computing the reduced costs one needs to pass through the basis. We skip this expensive part. */
3938 #ifdef SCIP_DISABLED_CODE
3939  /* Here is the code necessary to compute the reduced costs for row representation: */
3940  SCIP_Real sign = 1.0;
3941  if ( spx->getSense() == SPxLP::MINIMIZE )
3942  sign = -1.0;
3943 
3944  if ( spx->isColBasic(col) )
3945  {
3946  /* It seems necessary to search through the basis in order to find the correct position */
3947  for (int i = spx->dim() - 1; i >= 0; --i)
3948  {
3949  SPxId id = spx->basis().baseId(i);
3950  if ( id.isSPxColId() && col == spx->number(SPxColId(id)) )
3951  {
3952  *val = sign * spx->fVec()[i];
3953  break;
3954  }
3955  }
3956  }
3957 #endif
3958  }
3959 
3960  return SCIP_OKAY;
3961 }
3962 
3963 
3964 
3965 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3967  SCIP_LPI* lpi, /**< LP interface structure */
3968  int* cstat, /**< array to store column basis status, or NULL */
3969  int* rstat /**< array to store row basis status, or NULL */
3970  )
3971 {
3972  int i;
3973 
3974  SCIPdebugMessage("calling SCIPlpiGetBase()\n");
3975 
3976  assert(lpi != NULL);
3977  assert(lpi->spx != NULL);
3978 
3979  assert( lpi->spx->preStrongbranchingBasisFreed() );
3980 
3981  if( rstat != NULL )
3982  {
3983  for( i = 0; i < lpi->spx->nRows(); ++i )
3984  {
3985  switch( lpi->spx->getBasisRowStatus(i) )
3986  {
3987  case SPxSolver::BASIC:
3988  rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
3989  break;
3990  case SPxSolver::FIXED:
3991  case SPxSolver::ON_LOWER:
3992  rstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
3993  break;
3994  case SPxSolver::ON_UPPER:
3995  rstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
3996  break;
3997  case SPxSolver::ZERO:
3998  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
3999  return SCIP_LPERROR;
4000  case SPxSolver::UNDEFINED:
4001  default:
4002  SCIPerrorMessage("invalid basis status\n");
4003  SCIPABORT();
4004  return SCIP_INVALIDDATA; /*lint !e527*/
4005  }
4006  }
4007  }
4008 
4009  if( cstat != NULL )
4010  {
4011  for( i = 0; i < lpi->spx->nCols(); ++i )
4012  {
4013  SCIP_Real val = 0.0;
4014  switch( lpi->spx->getBasisColStatus(i) )
4015  {
4016  case SPxSolver::BASIC:
4017  cstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
4018  break;
4019  case SPxSolver::FIXED:
4020  /* Get reduced cost estimation. If the estimation is not correct this should not hurt:
4021  * If the basis is loaded into SoPlex again, the status is converted to FIXED again; in
4022  * this case there is no problem at all. If the basis is saved and/or used in some other
4023  * solver, it usually is very cheap to perform the pivots necessary to get an optimal
4024  * basis. */
4025  SCIP_CALL( getRedCostEst(lpi->spx, i, &val) );
4026  if( val < 0.0 ) /* reduced costs < 0 => UPPER else => LOWER */
4027  cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
4028  else
4029  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
4030  break;
4031  case SPxSolver::ON_LOWER:
4032  cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
4033  break;
4034  case SPxSolver::ON_UPPER:
4035  cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
4036  break;
4037  case SPxSolver::ZERO:
4038  cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
4039  break;
4040  case SPxSolver::UNDEFINED:
4041  default:
4042  SCIPerrorMessage("invalid basis status\n");
4043  SCIPABORT();
4044  return SCIP_INVALIDDATA; /*lint !e527*/
4045  }
4046  }
4047  }
4048 
4049  return SCIP_OKAY;
4050 }
4051 
4052 /** sets current basis status for columns and rows */
4054  SCIP_LPI* lpi, /**< LP interface structure */
4055  const int* cstat, /**< array with column basis status */
4056  const int* rstat /**< array with row basis status */
4057  )
4058 {
4059  int i;
4060  int nCols = lpi->spx->nCols();
4061  int nRows = lpi->spx->nRows();
4062 
4063  SCIPdebugMessage("calling SCIPlpiSetBase()\n");
4064 
4065  assert(lpi != NULL);
4066  assert(lpi->spx != NULL);
4067  assert(cstat != NULL || nCols == 0);
4068  assert(rstat != NULL || nRows == 0);
4069 
4070  assert( lpi->spx->preStrongbranchingBasisFreed() );
4071  invalidateSolution(lpi);
4072 
4073  DataArray<SPxSolver::VarStatus>& m_colstat = lpi->spx->colStat();
4074  DataArray<SPxSolver::VarStatus>& m_rowstat = lpi->spx->rowStat();
4075 
4076  m_colstat.reSize(nCols);
4077  m_rowstat.reSize(nRows);
4078 
4079  for( i = 0; i < nRows; ++i )
4080  {
4081  assert( rstat != 0 ); /* for lint */
4082  switch( rstat[i] )
4083  {
4084  case SCIP_BASESTAT_LOWER:
4085  m_rowstat[i] = SPxSolver::ON_LOWER;
4086  break;
4087  case SCIP_BASESTAT_BASIC:
4088  m_rowstat[i] = SPxSolver::BASIC;
4089  break;
4090  case SCIP_BASESTAT_UPPER:
4091  m_rowstat[i] = SPxSolver::ON_UPPER;
4092  break;
4093  case SCIP_BASESTAT_ZERO:
4094  SCIPerrorMessage("slack variable has basis status ZERO (should not occur)\n");
4095  return SCIP_LPERROR; /*lint !e429*/
4096  default:
4097  SCIPerrorMessage("invalid basis status\n");
4098  SCIPABORT();
4099  return SCIP_INVALIDDATA; /*lint !e527*/
4100  }
4101  }
4102 
4103  for( i = 0; i < nCols; ++i )
4104  {
4105  assert( cstat != 0 ); /* for lint */
4106  switch( cstat[i] )
4107  {
4108  case SCIP_BASESTAT_LOWER:
4109  m_colstat[i] = SPxSolver::ON_LOWER;
4110  break;
4111  case SCIP_BASESTAT_BASIC:
4112  m_colstat[i] = SPxSolver::BASIC;
4113  break;
4114  case SCIP_BASESTAT_UPPER:
4115  m_colstat[i] = SPxSolver::ON_UPPER;
4116  break;
4117  case SCIP_BASESTAT_ZERO:
4118  m_colstat[i] = SPxSolver::ZERO;
4119  break;
4120  default:
4121  SCIPerrorMessage("invalid basis status\n");
4122  SCIPABORT();
4123  return SCIP_INVALIDDATA; /*lint !e527*/
4124  }
4125  }
4126 
4127  SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setBasis(m_rowstat.get_const_ptr(), m_colstat.get_const_ptr()) );
4128  (void) lpi->spx->updateStatus();
4129 
4130  lpi->spx->freePreStrongbranchingBasis();
4131 
4132  return SCIP_OKAY;
4133 }
4134 
4135 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
4137  SCIP_LPI* lpi, /**< LP interface structure */
4138  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
4139  )
4140 {
4141  SCIPdebugMessage("calling SCIPlpiGetBasisInd()\n");
4142 
4143  SPxSolver* spx;
4144 
4145  assert(lpi != NULL);
4146  assert(lpi->spx != NULL);
4147 
4148  assert( lpi->spx->preStrongbranchingBasisFreed() );
4149 
4150  /* the LPi defines the basis as column basis, i.e., as the set of (indices of) non-fixed columns and rows; if SoPlex
4151  * uses row representation, this is just the complement of the basis
4152  */
4153  spx = lpi->spx;
4154 
4155  /* for column representation, return the basis */
4156  if( spx->rep() == SPxSolver::COLUMN )
4157  {
4158  for( int i = 0; i < spx->nRows(); ++i )
4159  {
4160  SPxId id = spx->basis().baseId(i);
4161 
4162  bind[i] = (id.isSPxColId() ? spx->number(id) : - 1 - spx->number(id));
4163  }
4164  }
4165  /* for row representation, return the complement of the basis; for this, we need to loop through all rows and columns */
4166  else
4167  {
4168  int k = 0;
4169  int nrows = spx->nRows();
4170  int ncols = spx->nCols();
4171 
4172  assert( spx->rep() == SPxSolver::ROW );
4173 
4174  for( int i = 0; i < nrows; ++i )
4175  {
4176  if( !spx->isRowBasic(i) )
4177  {
4178  bind[k++] = -1 - i;
4179  if( k >= nrows )
4180  break;
4181  }
4182  }
4183 
4184  for( int j = 0; j < ncols && k < nrows; ++j )
4185  {
4186  if( !spx->isColBasic(j) )
4187  bind[k++] = j;
4188  }
4189 
4190  assert(k == nrows);
4191  }
4192 
4193  return SCIP_OKAY;
4194 }
4195 
4196 #ifdef OLD_BINV
4197 /* prepare a factorization of the basis matrix in column representation */
4198 static
4199 SCIP_RETCODE prepareFactorization(
4200  SCIP_LPI* lpi
4201  )
4202 {
4203  SCIPdebugMessage("Preparing factorization for computation of basis inverse.\n");
4204 
4205  try
4206  {
4207  /* if the factorization has not been set up, we compute a new factorization */
4208  if ( lpi->factorization == 0 )
4209  {
4210  SPxSolver* spx = lpi->spx;
4211 
4212  /* matrix to store columns */
4213  DataArray <const SVector*> matrix(spx->nRows());
4214 
4215  int k = 0;
4216  for (int i = 0; i < spx->nRows(); ++i)
4217  {
4218  if ( ! spx->isRowBasic(i) )
4219  matrix[k++] = new UnitVector(i);
4220  }
4221  for (int j = 0; j < spx->nCols(); ++j)
4222  {
4223  if ( ! spx->isColBasic(j) )
4224  matrix[k++] = &spx->colVector(j);
4225  }
4226  assert( k == spx->nRows() );
4227  assert( k == matrix.size() );
4228 
4229  /* compute factorization */
4230  lpi->factorization = new SLUFactor;
4231 #ifndef NDEBUG
4232  SLinSolver::Status status = lpi->factorization->load(matrix.get_ptr(), k);
4233 #else
4234  (void) lpi->factorization->load(matrix.get_ptr(), k);
4235 #endif
4236  assert( status == SLinSolver::OK );
4237  assert( k == lpi->factorization->dim() );
4238 
4239  /* delete matrix columns corresponding to unit vectors */
4240  k = 0;
4241  for (int i = 0; i < spx->nRows(); ++i)
4242  {
4243  if ( ! spx->isRowBasic(i) )
4244  delete matrix[k++];
4245  }
4246  }
4247  }
4248 #ifndef NDEBUG
4249  catch( const SPxException& x )
4250  {
4251  std::string s = x.what();
4252  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4253 #else
4254  catch( const SPxException& )
4255  {
4256 #endif
4257  return SCIP_LPERROR;
4258  }
4259 
4260  return SCIP_OKAY;
4261 }
4262 #endif
4263 
4264 /** get dense row of inverse basis matrix B^-1
4265  *
4266  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4267  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4268  * see also the explanation in lpi.h.
4269  */
4271  SCIP_LPI* lpi, /**< LP interface structure */
4272  int r, /**< row number */
4273  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
4274  int* inds, /**< array to store the non-zero indices, or NULL */
4275  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4276  * (-1: if we do not store sparsity informations) */
4277  )
4278 {
4279  SCIPdebugMessage("calling SCIPlpiGetBInvRow()\n");
4280 
4281  assert( lpi != NULL );
4282  assert( lpi->spx != NULL );
4283  assert( lpi->spx->preStrongbranchingBasisFreed() );
4284 
4285  int nCols = lpi->spx->nCols();
4286  int nRows = lpi->spx->nRows();
4287 
4288  assert(r >= 0);
4289  assert(r < nRows);
4290 
4291  try
4292  {
4293  SPxSolver* spx = lpi->spx;
4294 
4295  /* in the column case use the existing factorization */
4296  if ( spx->rep() == SPxSolver::COLUMN )
4297  {
4298  SSVector x(nRows);
4299  spx->basis().coSolve(x, spx->unitVector(r));
4300 
4301  /* copy sparse data to dense result vector based on coef array */
4302  if( ninds != NULL && inds != NULL )
4303  {
4304  int idx;
4305  /* during solving SoPlex may have destroyed the sparsity structure so we need to restore it */
4306  x.setup();
4307  *ninds = x.size();
4308  for( int i = 0; i < *ninds; ++i )
4309  {
4310  idx = x.index(i);
4311  coef[idx] = x[idx];
4312  /* set sparsity pattern of coef array */
4313  inds[i] = idx;
4314  }
4315  }
4316  else
4317  {
4318  /* @todo check whether we only need to copy nonzeros to coef - is coef cleared? */
4319  Vector y(nRows, coef);
4320  y = x;
4321  if( ninds != NULL )
4322  *ninds = -1;
4323  }
4324  }
4325  else
4326  {
4327  assert(spx->rep() == SPxSolver::ROW);
4328 
4329 #ifdef OLD_BINV
4330  DVector e(nRows);
4331 
4332  /* prepare unit vector */
4333  e.clear();
4334  e[r] = 1.0;
4335 
4336  /* factorization is deleted in invalidateSolution() */
4337  SCIP_CALL( prepareFactorization(lpi) );
4338  assert( lpi->factorization != 0 );
4339  assert( lpi->factorization->dim() == nRows );
4340 
4341  /* solve system "x = e_r^T * B^-1" to get r'th row of B^-1 */
4342  lpi->factorization->solveLeft(x, e);
4343 #else
4344  Vector x(nRows, coef); /* row of B^-1 has nrows entries - note that x is based on coef */
4345  /**@todo should rhs be a reference? */
4346  DSVector rhs(nCols);
4347  SSVector y(nCols);
4348  int* bind;
4349  int idx;
4350 
4351  bind = NULL;
4352 
4353  /**@todo should bind be stored globally in lpi? */
4354  /* get ordering of column basis matrix */
4355  SCIP_ALLOC( BMSallocMemoryArray(&bind, nRows) ); /*lint !e530*/
4356  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4357 
4358  /* get vector corresponding to requested index r */
4359  idx = bind[r];
4360 
4361  /* r corresponds to a row vector */
4362  if( idx < 0 )
4363  {
4364  idx = -idx-1;
4365 
4366  /* should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation */
4367  assert(idx >= 0);
4368  assert(idx < nRows);
4369  assert(!spx->isRowBasic(idx));
4370 
4371  /* get row vector */
4372  rhs = spx->rowVector(idx);
4373  rhs *= -1.0;
4374  }
4375  /* r corresponds to a column vector */
4376  else
4377  {
4378  /* should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation */
4379  assert(idx < nCols);
4380  assert(!spx->isColBasic(idx));
4381 
4382  /* get unit vector */
4383  rhs = spx->unitVector(idx);
4384  }
4385 
4386  /* solve system "y B = rhs", where B is the row basis matrix */
4387  spx->basis().solve(y, rhs);
4388 
4389  /* initialize result vector x as zero */
4390  BMSclearMemoryArray(coef, nRows);
4391 
4392  /* add nonzero entries */
4393  for( int i = 0; i < nCols; ++i )
4394  {
4395  SPxId id = spx->basis().baseId(i);
4396 
4397  if( id.isSPxRowId() )
4398  {
4399  assert(spx->number(id) >= 0);
4400  assert(spx->number(id) < nRows);
4401  assert(bind[r] >= 0 || spx->number(id) != idx);
4402 
4403  x[spx->number(id)] = y[i];
4404  }
4405  }
4406 
4407  /* if r corresponds to a row vector, we have to add a 1 at position r */
4408  if( bind[r] < 0 )
4409  {
4410  assert(x[idx] == 0.0);
4411  x[idx] = 1.0;
4412  }
4413 
4414  /* @todo implement returning of sparsity information like in column wise case */
4415  if( ninds != NULL )
4416  *ninds = -1;
4417 
4418  /* free memory */
4419  BMSfreeMemoryArray(&bind);
4420 #endif
4421  }
4422  }
4423 #ifndef NDEBUG
4424  catch( const SPxException& x )
4425  {
4426  std::string s = x.what();
4427  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4428 #else
4429  catch( const SPxException& )
4430  {
4431 #endif
4432  return SCIP_LPERROR;
4433  }
4434 
4435  return SCIP_OKAY;
4436 }
4437 
4438 /** get dense solution of basis matrix B * coef = rhs */
4439 static
4441  SCIP_LPI* lpi, /**< LP interface structure */
4442  SCIP_Real* rhs, /**< right-hand side vector */
4443  SCIP_Real* coef /**< vector to return coefficients */
4444  )
4445 {
4446  SCIPdebugMessage("calling SCIPlpiGetBInvVec()\n");
4447 
4448  assert(lpi != NULL);
4449  assert(lpi->spx != NULL);
4450  assert(lpi->spx->preStrongbranchingBasisFreed());
4451  assert(rhs != NULL);
4452  assert(coef != NULL);
4453 
4454  int nCols = lpi->spx->nCols();
4455  int nRows = lpi->spx->nRows();
4456 
4457  try
4458  {
4459  SPxSolver* spx = lpi->spx;
4460  Vector v(nRows, rhs);
4461  Vector x(nRows, coef);
4462 
4463  /* in the column case use the existing factorization */
4464  if( spx->rep() == SPxSolver::COLUMN )
4465  {
4466  /* solve system "x = B^-1 * A_c" to get c'th column of B^-1 * A */
4467  spx->basis().solve(x, v);
4468  }
4469  else
4470  {
4471  assert(spx->rep() == SPxSolver::ROW);
4472 
4473 #ifdef OLD_BINV
4474  /* factorization is deleted in invalidateSolution() */
4475  SCIP_CALL( prepareFactorization(lpi) );
4476  assert(lpi->factorization != 0);
4477  assert(lpi->factorization->dim() == spx->nRows());
4478 
4479  /* solve system B * x = v */
4480  lpi->factorization->solveRight(x, v);
4481 #else
4482  DSVector rowrhs(nCols);
4483  SSVector y(nCols);
4484  int* bind;
4485 
4486  bind = NULL;
4487 
4488  /**@todo should bind be stored globally in lpi? */
4489  /* get ordering of column basis matrix */
4490  SCIP_ALLOC( BMSallocMemoryArray(&bind, nRows) ); /*lint !e530*/
4491  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4492 
4493  /* fill right-hand side for row-based system */
4494  for( int i = 0; i < nCols; ++i )
4495  {
4496  SPxId id = spx->basis().baseId(i);
4497 
4498  if( id.isSPxRowId() )
4499  {
4500  assert(spx->number(id) >= 0);
4501  assert(spx->number(id) < nRows);
4502 
4503  rowrhs.add(i, v[spx->number(id)]);
4504  }
4505  else
4506  {
4507  assert(rowrhs[i] == 0.0);
4508  }
4509  }
4510 
4511  /* solve system "B y = rowrhs", where B is the row basis matrix */
4512  spx->basis().coSolve(y, rowrhs);
4513 
4514  /* fill result w.r.t. order given by bind */
4515  for( int i = 0; i < nRows; ++i )
4516  {
4517  int idx;
4518 
4519  idx = bind[i];
4520 
4521  if( idx < 0 )
4522  {
4523  idx = -idx-1;
4524 
4525  /* should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation */
4526  assert(idx >= 0);
4527  assert(idx < nRows);
4528  assert(!spx->isRowBasic(idx));
4529 
4530  x[i] = v[idx] - (spx->rowVector(idx) * Vector(nCols, y.get_ptr())); /*lint !e1702*/
4531  }
4532  else
4533  {
4534  /* should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation */
4535  assert(idx >= 0);
4536  assert(idx < nCols);
4537  assert(!spx->isColBasic(idx));
4538 
4539  x[i] = y[idx];
4540  }
4541  }
4542 
4543  /* free memory */
4544  BMSfreeMemoryArray(&bind);
4545 #endif
4546  }
4547  }
4548 #ifndef NDEBUG
4549  catch( const SPxException& x )
4550  {
4551  std::string s = x.what();
4552  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4553 #else
4554  catch( const SPxException& )
4555  {
4556 #endif
4557  return SCIP_LPERROR;
4558  }
4559 
4560  return SCIP_OKAY;
4561 }
4562 
4563 /** get dense column of inverse basis matrix B^-1
4564  *
4565  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4566  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4567  * see also the explanation in lpi.h.
4568  */
4570  SCIP_LPI* lpi, /**< LP interface structure */
4571  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
4572  * you have to call SCIPlpiGetBasisInd() to get the array which links the
4573  * B^-1 column numbers to the row and column numbers of the LP!
4574  * c must be between 0 and nrows-1, since the basis has the size
4575  * nrows * nrows */
4576  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
4577  int* inds, /**< array to store the non-zero indices, or NULL */
4578  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4579  * (-1: if we do not store sparsity informations) */
4580  )
4581 { /*lint --e{715}*/
4582  SCIPdebugMessage("calling SCIPlpiGetBInvCol()\n");
4583 
4584  assert( lpi != NULL );
4585  assert( lpi->spx != NULL );
4586  assert( lpi->spx->preStrongbranchingBasisFreed() );
4587 
4588  /* mark sparsity pattern as invalid */
4589  if( ninds != NULL )
4590  *ninds = -1;
4591 
4592  /* prepare unit vector */
4593  DVector e(lpi->spx->nRows());
4594 
4595  e.clear();
4596 
4597  assert(c >= 0);
4598  assert(c < lpi->spx->nRows());
4599  e[c] = 1.0;
4600 
4601  /* solve */
4602  SCIP_CALL( lpiGetBInvVec(lpi, e.get_ptr(), coef) );
4603 
4604  return SCIP_OKAY;
4605 }
4606 
4607 /** get dense row of inverse basis matrix times constraint matrix B^-1 * A
4608  *
4609  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4610  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4611  * see also the explanation in lpi.h.
4612  */
4614  SCIP_LPI* lpi, /**< LP interface structure */
4615  int r, /**< row number */
4616  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
4617  SCIP_Real* coef, /**< vector to return coefficients */
4618  int* inds, /**< array to store the non-zero indices, or NULL */
4619  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4620  * (-1: if we do not store sparsity informations) */
4621  )
4622 {
4623  SCIP_Real* buf;
4624  SCIP_Real* binv;
4625  int nrows;
4626  int ncols;
4627  int c;
4628 
4629  SCIPdebugMessage("calling SCIPlpiGetBInvARow()\n");
4630 
4631  assert(lpi != NULL);
4632  assert(lpi->spx != NULL);
4633  assert( lpi->spx->preStrongbranchingBasisFreed() );
4634 
4635  nrows = lpi->spx->nRows();
4636  ncols = lpi->spx->nCols();
4637  buf = NULL;
4638 
4639  /* get (or calculate) the row in B^-1 */
4640  if( binvrow == NULL )
4641  {
4642  SCIP_ALLOC( BMSallocMemoryArray(&buf, nrows) );
4643  SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buf, inds, ninds) );
4644  binv = buf;
4645  }
4646  else
4647  binv = const_cast<SCIP_Real*>(binvrow);
4648 
4649  assert(binv != NULL);
4650 
4651  /* mark sparsity pattern as invalid */
4652  if( ninds != NULL )
4653  *ninds = -1;
4654 
4655  /* calculate the scalar product of the row in B^-1 and A */
4656  soplex::Vector binvvec(nrows, binv);
4657  for( c = 0; c < ncols; ++c )
4658  coef[c] = binvvec * lpi->spx->colVector(c); /* scalar product */ /*lint !e1702*/
4659 
4660  /* free memory if it was temporarily allocated */
4661  BMSfreeMemoryArrayNull(&buf);
4662 
4663  return SCIP_OKAY;
4664 }
4665 
4666 /** get dense column of inverse basis matrix times constraint matrix B^-1 * A
4667  *
4668  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4669  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4670  * see also the explanation in lpi.h.
4671  */
4673  SCIP_LPI* lpi, /**< LP interface structure */
4674  int c, /**< column number */
4675  SCIP_Real* coef, /**< vector to return coefficients */
4676  int* inds, /**< array to store the non-zero indices, or NULL */
4677  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4678  * (-1: if we do not store sparsity informations) */
4679  )
4680 { /*lint --e{715}*/
4681  DVector col(lpi->spx->nRows());
4682 
4683  SCIPdebugMessage("calling SCIPlpiGetBInvACol()\n");
4684 
4685  assert( lpi != NULL );
4686  assert( lpi->spx != NULL );
4687  assert( lpi->spx->preStrongbranchingBasisFreed() );
4688 
4689  /* extract column c of A */
4690  assert(c >= 0);
4691  assert(c < lpi->spx->nCols());
4692 
4693  /* mark sparsity pattern as invalid */
4694  if( ninds != NULL )
4695  *ninds = -1;
4696 
4697  col.clear();
4698  col = lpi->spx->colVector(c);
4699  col.reDim(lpi->spx->nRows());
4700 
4701  /* solve */
4702  SCIP_CALL( lpiGetBInvVec(lpi, col.get_ptr(), coef) );
4703 
4704  return SCIP_OKAY;
4705 }
4706 
4707 /**@} */
4708 
4709 
4710 
4711 
4712 /*
4713  * LP State Methods
4714  */
4715 
4716 /**@name LP State Methods */
4717 /**@{ */
4718 
4719 /** stores LPi state (like basis information) into lpistate object */
4721  SCIP_LPI* lpi, /**< LP interface structure */
4722  BMS_BLKMEM* blkmem, /**< block memory */
4723  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4724  )
4725 {
4726  int ncols;
4727  int nrows;
4728 
4729  SCIPdebugMessage("calling SCIPlpiGetState()\n");
4730 
4731  assert(blkmem != NULL);
4732  assert(lpi != NULL);
4733  assert(lpi->spx != NULL);
4734  assert(lpistate != NULL);
4735 
4736  assert( lpi->spx->preStrongbranchingBasisFreed() );
4737 
4738  ncols = lpi->spx->nCols();
4739  nrows = lpi->spx->nRows();
4740  assert(ncols >= 0);
4741  assert(nrows >= 0);
4742 
4743  /* allocate lpistate data */
4744  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4745 
4746  /* allocate enough memory for storing uncompressed basis information */
4747  SCIP_CALL( ensureCstatMem(lpi, ncols) );
4748  SCIP_CALL( ensureRstatMem(lpi, nrows) );
4749 
4750  /* get unpacked basis information */
4751  SCIP_CALL( SCIPlpiGetBase(lpi, lpi->cstat, lpi->rstat) );
4752 
4753  /* pack LPi state data */
4754  (*lpistate)->ncols = ncols;
4755  (*lpistate)->nrows = nrows;
4756  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
4757 
4758  return SCIP_OKAY;
4759 }
4760 
4761 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
4762  * columns and rows since the state was stored with SCIPlpiGetState()
4763  */
4765  SCIP_LPI* lpi, /**< LP interface structure */
4766  BMS_BLKMEM* /*blkmem*/, /**< block memory */
4767  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information) */
4768  )
4769 {
4770  int lpncols;
4771  int lpnrows;
4772  int i;
4773 
4774  SCIPdebugMessage("calling SCIPlpiSetState()\n");
4775 
4776  assert(lpi != NULL);
4777  assert(lpi->spx != NULL);
4778  assert(lpistate != NULL);
4779 
4780  assert( lpi->spx->preStrongbranchingBasisFreed() );
4781 
4782  lpncols = lpi->spx->nCols();
4783  lpnrows = lpi->spx->nRows();
4784  assert(lpistate->ncols <= lpncols);
4785  assert(lpistate->nrows <= lpnrows);
4786 
4787  /* allocate enough memory for storing uncompressed basis information */
4788  SCIP_CALL( ensureCstatMem(lpi, lpncols) );
4789  SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
4790 
4791  /* unpack LPi state data */
4792  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
4793 
4794  /* extend the basis to the current LP beyond the previously existing columns */
4795  for( i = lpistate->ncols; i < lpncols; ++i )
4796  {
4797  SCIP_Real bnd = lpi->spx->lower(i);
4798  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4799  {
4800  /* if lower bound is +/- infinity -> try upper bound */
4801  bnd = lpi->spx->lower(i);
4802  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4803  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
4804  else
4805  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
4806  }
4807  else
4808  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
4809  }
4810  for( i = lpistate->nrows; i < lpnrows; ++i )
4811  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC; /*lint !e641*/
4812 
4813  /* load basis information */
4814  SCIP_CALL( SCIPlpiSetBase(lpi, lpi->cstat, lpi->rstat) );
4815 
4816  return SCIP_OKAY;
4817 }
4818 
4819 /** clears current LPi state (like basis information) of the solver */
4821  SCIP_LPI* lpi /**< LP interface structure */
4822  )
4823 { /*lint --e{715}*/
4824  SCIPdebugMessage("calling SCIPlpiClearState()\n");
4825 
4826  assert(lpi != NULL);
4827  assert(lpi->spx != NULL);
4828 
4829  try
4830  {
4831  lpi->spx->reLoad();
4832  }
4833 #ifndef NDEBUG
4834  catch( const SPxException& x )
4835  {
4836  std::string s = x.what();
4837  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
4838 #else
4839  catch( const SPxException& )
4840  {
4841 #endif
4842  assert( lpi->spx->getStatus() != SPxSolver::OPTIMAL );
4843  return SCIP_LPERROR;
4844  }
4845 
4846  return SCIP_OKAY;
4847 }
4848 
4849 /** frees LPi state information */
4851  SCIP_LPI* lpi, /**< LP interface structure */
4852  BMS_BLKMEM* blkmem, /**< block memory */
4853  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4854  )
4855 { /*lint --e{715}*/
4856  SCIPdebugMessage("calling SCIPlpiFreeState()\n");
4857 
4858  assert(lpi != NULL);
4859  assert(lpistate != NULL);
4860 
4861  if ( *lpistate != NULL )
4862  lpistateFree(lpistate, blkmem);
4863 
4864  return SCIP_OKAY;
4865 }
4866 
4867 /** checks, whether the given LP state contains simplex basis information */
4869  SCIP_LPI* lpi, /**< LP interface structure */
4870  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
4871  )
4872 { /*lint --e{715}*/
4873  return TRUE;
4874 }
4875 
4876 /** reads LP state (like basis information from a file */
4878  SCIP_LPI* lpi, /**< LP interface structure */
4879  const char* fname /**< file name */
4880  )
4881 {
4882  SCIPdebugMessage("calling SCIPlpiReadState()\n");
4883 
4884  assert( lpi->spx->preStrongbranchingBasisFreed() );
4885 
4886  bool success;
4887  SOPLEX_TRY( lpi->messagehdlr, success = lpi->spx->readBasisFile(fname, 0, 0) );
4888 
4889  return success ? SCIP_OKAY : SCIP_LPERROR;
4890 }
4891 
4892 /** writes LP state (like basis information) to a file */
4894  SCIP_LPI* lpi, /**< LP interface structure */
4895  const char* fname /**< file name */
4896  )
4897 {
4898  SCIPdebugMessage("calling SCIPlpiWriteState()\n");
4899 
4900  assert( lpi->spx->preStrongbranchingBasisFreed() );
4901 
4902  bool res;
4903  SOPLEX_TRY( lpi->messagehdlr, res = lpi->spx->writeBasisFile(fname, 0, 0) );
4904 
4905  if ( ! res )
4906  return SCIP_LPERROR;
4907 
4908  return SCIP_OKAY;
4909 }
4910 
4911 /**@} */
4912 
4913 
4914 
4915 
4916 /*
4917  * LP Pricing Norms Methods
4918  */
4919 
4920 /**@name LP Pricing Norms Methods */
4921 /**@{ */
4922 
4923 /** stores LPi pricing norms information
4924  * @todo should we store norm information?
4925  */
4927  SCIP_LPI* lpi, /**< LP interface structure */
4928  BMS_BLKMEM* blkmem, /**< block memory */
4929  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4930  )
4931 {
4932 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4933  int nrows;
4934  int ncols;
4935 
4936  assert(blkmem != NULL);
4937  assert(lpi != NULL);
4938  assert(lpi->spx != NULL);
4939  assert(lpinorms != NULL);
4940 
4941  lpi->spx->getNdualNorms(nrows, ncols);
4942 
4943  if( nrows == 0 && ncols == 0)
4944  {
4945  (*lpinorms = NULL);
4946  return SCIP_OKAY;
4947  }
4948 
4949  /* allocate lpinorms data */
4950  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4951  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols) );
4952  (*lpinorms)->nrows = 0;
4953  (*lpinorms)->ncols = 0;
4954 
4955  SCIPdebugMessage("storing SoPlex LPi pricing norms in %p (%d rows, %d cols)\n", (void *) *lpinorms, nrows, ncols);
4956 
4957  if( !lpi->spx->getDualNorms((*lpinorms)->nrows, (*lpinorms)->ncols, (*lpinorms)->norms) )
4958  {
4959  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
4960  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols);
4961  BMSfreeBlockMemory(blkmem, lpinorms);
4962  assert(*lpinorms == NULL);
4963  }
4964 #ifndef NDEBUG
4965  else
4966  {
4967  assert(nrows == (*lpinorms)->nrows);
4968  assert(ncols == (*lpinorms)->ncols);
4969  }
4970 #endif
4971 #else
4972  (*lpinorms) = NULL;
4973 #endif
4974 
4975  return SCIP_OKAY;
4976 }
4977 
4978 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4979  * columns and rows since the state was stored with SCIPlpiGetNorms()
4980  */
4982  SCIP_LPI* lpi, /**< LP interface structure */
4983  BMS_BLKMEM* blkmem, /**< block memory */
4984  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information */
4985  )
4986 {
4987 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4988  assert(blkmem != NULL);
4989  assert(lpi != NULL);
4990  assert(lpi->spx != NULL);
4991 
4992  /* if there was no pricing norms information available, the LPi norms were not stored */
4993  if( lpinorms == NULL )
4994  return SCIP_OKAY;
4995 
4996  assert(lpinorms->nrows <= lpi->spx->nRows());
4997  assert(lpinorms->ncols <= lpi->spx->nCols());
4998 
4999  if( lpinorms->nrows == 0 )
5000  return SCIP_OKAY;
5001 
5002  SCIPdebugMessage("loading LPi simplex norms %p (%d rows, %d cols) into SoPlex LP with %d rows and %d cols\n",
5003  (const void *) lpinorms, lpinorms->nrows, lpinorms->ncols, lpi->spx->nRows(), lpi->spx->nCols());
5004 
5005  if( !lpi->spx->setDualNorms(lpinorms->nrows, lpinorms->ncols, lpinorms->norms) )
5006  SCIPdebugMessage("loading of LPi norms failed\n");
5007 #endif
5008 
5009  return SCIP_OKAY;
5010 }
5011 
5012 /** frees pricing norms information */
5014  SCIP_LPI* lpi, /**< LP interface structure */
5015  BMS_BLKMEM* blkmem, /**< block memory */
5016  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
5017  )
5018 {
5019 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
5020  assert(lpi != NULL);
5021  assert(lpinorms != NULL);
5022 
5023  SCIPdebugMessage("freeing norms at %p\n", (void *) *lpinorms);
5024 
5025  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, (*lpinorms)->nrows + (*lpinorms)->ncols);
5026  BMSfreeBlockMemory(blkmem, lpinorms);
5027  assert(*lpinorms == NULL);
5028 #endif
5029 
5030  return SCIP_OKAY;
5031 }
5032 
5033 /**@} */
5034 
5035 
5036 
5037 
5038 /*
5039  * Parameter Methods
5040  */
5041 
5042 /**@name Parameter Methods */
5043 /**@{ */
5044 
5045 /** gets integer parameter of LP */
5047  SCIP_LPI* lpi, /**< LP interface structure */
5048  SCIP_LPPARAM type, /**< parameter number */
5049  int* ival /**< buffer to store the parameter value */
5050  )
5051 {
5052  SCIPdebugMessage("calling SCIPlpiGetIntpar()\n");
5053 
5054  assert(lpi != NULL);
5055  assert(lpi->spx != NULL);
5056  assert(ival != NULL);
5057 
5058  switch( type )
5059  {
5061  *ival = lpi->spx->getFromScratch();
5062  break;
5063  case SCIP_LPPAR_LPINFO:
5064  *ival = lpi->spx->getLpInfo();
5065  break;
5066  case SCIP_LPPAR_LPITLIM:
5067  *ival = lpi->spx->getIterationLimit();
5068  break;
5069  case SCIP_LPPAR_PRESOLVING:
5070  *ival = lpi->spx->getPresolving();
5071  break;
5072  case SCIP_LPPAR_PRICING:
5073  *ival = (int)lpi->pricing;
5074  break;
5075  case SCIP_LPPAR_SCALING:
5076  *ival = lpi->spx->getScaling();
5077  break;
5078 #if SOPLEX_VERSION >= 201
5079  case SCIP_LPPAR_TIMING:
5080  *ival = (int) lpi->spx->getTiming();
5081  break;
5082 #endif
5083 #if SOPLEX_VERSION >= 230 || (SOPLEX_VERSION == 220 && SOPLEX_SUBVERSION >= 3)
5084  case SCIP_LPPAR_RANDOMSEED:
5085  *ival = (int) lpi->spx->random.getSeed();
5086  break;
5087 #endif
5088  default:
5089  return SCIP_PARAMETERUNKNOWN;
5090  } /*lint !e788*/
5091 
5092  return SCIP_OKAY;
5093 }
5094 
5095 /** sets integer parameter of LP */
5097  SCIP_LPI* lpi, /**< LP interface structure */
5098  SCIP_LPPARAM type, /**< parameter number */
5099  int ival /**< parameter value */
5100  )
5101 {
5102  SCIPdebugMessage("calling SCIPlpiSetIntpar()\n");
5103 
5104  assert(lpi != NULL);
5105  assert(lpi->spx != NULL);
5106 
5107  switch( type )
5108  {
5110  assert(ival == TRUE || ival == FALSE);
5111  lpi->spx->setFromScratch(bool(ival));
5112  break;
5113  case SCIP_LPPAR_LPINFO:
5114  assert(ival == TRUE || ival == FALSE);
5115  lpi->spx->setLpInfo(bool(ival));
5116  break;
5117  case SCIP_LPPAR_LPITLIM:
5118  assert(ival >= -1);
5119  lpi->spx->setIterationLimit(ival);
5120  break;
5121  case SCIP_LPPAR_PRESOLVING:
5122  assert(ival == TRUE || ival == FALSE);
5123  lpi->spx->setPresolving(bool(ival));
5124  break;
5125  case SCIP_LPPAR_PRICING:
5126  lpi->pricing = (SCIP_PRICING)ival;
5127  switch( lpi->pricing )
5128  {
5130  case SCIP_PRICING_AUTO:
5131  lpi->spx->setAutoPricer();
5132  break;
5133  case SCIP_PRICING_FULL:
5134  lpi->spx->setFullPricer();
5135  break;
5136  case SCIP_PRICING_PARTIAL:
5137  lpi->spx->setParmultPricer();
5138  break;
5139  case SCIP_PRICING_STEEP:
5140  lpi->spx->setSteepPricer();
5141  break;
5143  lpi->spx->setSteepQStartPricer();
5144  break;
5145  case SCIP_PRICING_DEVEX:
5146  lpi->spx->setDevexPricer();
5147  break;
5148  default:
5149  return SCIP_LPERROR;
5150  }
5151  break;
5152  case SCIP_LPPAR_SCALING:
5153  assert(ival == TRUE || ival == FALSE);
5154  lpi->spx->setScaling(ival);
5155  break;
5156 #if SOPLEX_VERSION >= 201
5157  case SCIP_LPPAR_TIMING:
5158  assert(ival >= 0 && ival < 3);
5159  lpi->spx->setTiming((Timer::TYPE) ival);
5160  break;
5161 #endif
5162 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 220 && SOPLEX_SUBVERSION >= 2)
5163  case SCIP_LPPAR_RANDOMSEED:
5164  lpi->spx->random.setSeed((unsigned int) ival);
5165  break;
5166 #endif
5167 #if SOPLEX_VERSION > 221 || (SOPLEX_VERSION == 221 && SOPLEX_SUBVERSION >= 3)
5168  case SCIP_LPPAR_POLISHING:
5169  assert(ival >= 0 && ival < 3);
5170  lpi->spx->setSolutionPolishing((SPxSolver::SolutionPolish) ival);
5171  break;
5172 #endif
5173 
5174  default:
5175  return SCIP_PARAMETERUNKNOWN;
5176  } /*lint !e788*/
5177 
5178  return SCIP_OKAY;
5179 }
5180 
5181 /** gets floating point parameter of LP */
5183  SCIP_LPI* lpi, /**< LP interface structure */
5184  SCIP_LPPARAM type, /**< parameter number */
5185  SCIP_Real* dval /**< buffer to store the parameter value */
5186  )
5187 {
5188  SCIPdebugMessage("calling SCIPlpiGetRealpar()\n");
5189 
5190  assert(lpi != NULL);
5191  assert(lpi->spx != NULL);
5192  assert(dval != NULL);
5193 
5194  switch( type )
5195  {
5196  case SCIP_LPPAR_FEASTOL:
5197  *dval = lpi->spx->feastol();
5198  break;
5199 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
5201  *dval = lpi->spx->opttol();
5202  break;
5203 #endif
5204  case SCIP_LPPAR_LOBJLIM:
5205  *dval = lpi->spx->getObjLoLimit();
5206  break;
5207  case SCIP_LPPAR_UOBJLIM:
5208  *dval = lpi->spx->getObjUpLimit();
5209  break;
5210  case SCIP_LPPAR_LPTILIM:
5211  *dval = lpi->spx->terminationTime();
5212  break;
5214  *dval = lpi->rowrepswitch;
5215  break;
5217  *dval = lpi->conditionlimit;
5218  break;
5219  default:
5220  return SCIP_PARAMETERUNKNOWN;
5221  } /*lint !e788*/
5222 
5223  return SCIP_OKAY;
5224 }
5225 
5226 /** sets floating point parameter of LP */
5228  SCIP_LPI* lpi, /**< LP interface structure */
5229  SCIP_LPPARAM type, /**< parameter number */
5230  SCIP_Real dval /**< parameter value */
5231  )
5232 {
5233  SCIPdebugMessage("calling SCIPlpiSetRealpar()\n");
5234 
5235  assert(lpi != NULL);
5236  assert(lpi->spx != NULL);
5237 
5238  switch( type )
5239  {
5240  case SCIP_LPPAR_FEASTOL:
5241  lpi->spx->setFeastol(dval);
5242  break;
5243 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
5245  lpi->spx->setOpttol(dval);
5246  break;
5247 #endif
5248  case SCIP_LPPAR_LOBJLIM:
5249  lpi->spx->setObjLoLimit(dval);
5250  break;
5251  case SCIP_LPPAR_UOBJLIM:
5252  lpi->spx->setObjUpLimit(dval);
5253  break;
5254  case SCIP_LPPAR_LPTILIM:
5255  lpi->spx->setTerminationTime(dval);
5256  break;
5258  assert(dval >= -1.5);
5259  lpi->rowrepswitch = dval;
5260  break;
5262  lpi->conditionlimit = dval;
5263  lpi->checkcondition = (dval >= 0);
5264  break;
5265  default:
5266  return SCIP_PARAMETERUNKNOWN;
5267  } /*lint !e788*/
5268 
5269  return SCIP_OKAY;
5270 }
5271 
5272 /**@} */
5273 
5274 
5275 
5276 
5277 /*
5278  * Numerical Methods
5279  */
5280 
5281 /**@name Numerical Methods */
5282 /**@{ */
5283 
5284 /** returns value treated as infinity in the LP solver */
5286  SCIP_LPI* /*lpi*/ /**< LP interface structure */
5287  )
5289  SCIPdebugMessage("calling SCIPlpiInfinity()\n");
5290 
5291  return soplex::infinity;
5292 }
5293 
5294 /** checks if given value is treated as infinity in the LP solver */
5296  SCIP_LPI* /*lpi*/, /**< LP interface structure */
5297  SCIP_Real val
5298  )
5299 {
5300  SCIPdebugMessage("calling SCIPlpiIsInfinity()\n");
5301 
5302  return (val >= soplex::infinity);
5303 }
5304 
5305 /**@} */
5306 
5307 
5308 
5309 
5310 /*
5311  * File Interface Methods
5312  */
5313 
5314 /**@name File Interface Methods */
5315 /**@{ */
5316 
5317 /** returns, whether the given file exists */
5318 static
5320  const char* filename /**< file name */
5321  )
5323  FILE* f;
5324 
5325  f = fopen(filename, "r");
5326  if( f == NULL )
5327  return FALSE;
5328 
5329  fclose(f);
5330 
5331  return TRUE;
5332 }
5333 
5334 /** reads LP from a file */
5336  SCIP_LPI* lpi, /**< LP interface structure */
5337  const char* fname /**< file name */
5338  )
5339 {
5340  SCIPdebugMessage("calling SCIPlpiReadLP()\n");
5341 
5342  assert(lpi != NULL);
5343  assert(lpi->spx != NULL);
5344 
5345  assert( lpi->spx->preStrongbranchingBasisFreed() );
5346 
5347  if( !fileExists(fname) )
5348  return SCIP_NOFILE;
5349 
5350  try
5351  {
5352  if( !lpi->spx->readLP(fname) )
5353  return SCIP_READERROR;
5354  }
5355 #ifndef NDEBUG
5356  catch( const SPxException& x )
5357  {
5358  std::string s = x.what();
5359  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
5360 #else
5361  catch( const SPxException& )
5362  {
5363 #endif
5364  return SCIP_READERROR;
5365  }
5366 
5367  return SCIP_OKAY;
5368 }
5369 
5370 /** writes LP to a file */
5372  SCIP_LPI* lpi, /**< LP interface structure */
5373  const char* fname /**< file name */
5374  )
5375 {
5376  SCIPdebugMessage("calling SCIPlpiWriteLP()\n");
5377 
5378  assert(lpi != NULL);
5379  assert(lpi->spx != NULL);
5380 
5381  try
5382  {
5383  lpi->spx->writeFile(fname);
5384  }
5385 #ifndef NDEBUG
5386  catch( const SPxException& x )
5387  {
5388  std::string s = x.what();
5389  SCIPmessagePrintWarning(lpi->messagehdlr, "SoPlex threw an exception: %s\n", s.c_str());
5390 #else
5391  catch( const SPxException& )
5392  {
5393 #endif
5394  return SCIP_WRITEERROR;
5395  }
5396 
5397  return SCIP_OKAY;
5398 }
5399 
5400 /**@} */
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3555
static SCIP_RETCODE lpiGetBInvVec(SCIP_LPI *lpi, SCIP_Real *rhs, SCIP_Real *coef)
Definition: lpi_spx1.cpp:4443
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx1.cpp:1926
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx1.cpp:4273
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3412
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_spx1.cpp:5338
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_spx1.cpp:3221
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:107
ROWPACKET * packrstat
Definition: lpi_clp.cpp:125
SCIP_PRICING pricing
Definition: lpi_clp.cpp:101
#define infinity
Definition: gastrans.c:71
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_spx1.cpp:2469
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_spx1.cpp:5099
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:2876
SCIP_Bool solved
Definition: lpi_clp.cpp:103
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:298
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_spx1.cpp:2032
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_spx1.cpp:1519
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3666
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3462
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_spx1.cpp:2054
SCIP_Real rowrepswitch
Definition: lpi_spx1.cpp:1388
#define FALSE
Definition: def.h:64
#define AUTOPRICING_ITERSWITCH
Definition: lpi_spx1.cpp:34
static int rowpacketNum(int nrows)
Definition: lpi_spx1.cpp:1478
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:1588
static SCIP_RETCODE getRedCostEst(SPxSCIP *spx, int col, SCIP_Real *val)
Definition: lpi_spx1.cpp:3914
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
int rstatsize
Definition: lpi_clp.cpp:99
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:2920
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3475
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *, const SCIP_LPISTATE *lpistate)
Definition: lpi_spx1.cpp:4767
SCIP_Bool checkcondition
Definition: lpi_cpx.c:165
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:2988
static SCIP_RETCODE spxSolve(SCIP_LPI *lpi, SPxSolver::Representation rep, SPxSolver::Type type)
Definition: lpi_spx1.cpp:2828
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_spx1.cpp:1825
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:63
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_spx1.cpp:5049
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:82
const char * SCIPlpiGetSolverName(void)
Definition: lpi_spx1.cpp:1617
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx1.cpp:5016
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_spx1.cpp:2452
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_spx1.cpp:4984
#define SOPLEX_VERBLEVEL
Definition: lpi_spx1.cpp:127
#define BMSfreeMemory(ptr)
Definition: memory.h:104
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:76
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_spx1.cpp:1543
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_spx1.cpp:2698
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_spx1.cpp:1440
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_spx1.cpp:3769
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_spx1.cpp:3679
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_spx1.cpp:2794
#define ROWS_PER_PACKET
Definition: lpi_spx1.cpp:1373
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx1.cpp:4880
#define SOPLEX_TRY(messagehdlr, x)
Definition: lpi_spx1.cpp:148
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx1.cpp:4616
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_spx1.cpp:3696
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:1653
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3427
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_spx1.cpp:2253
#define COLS_PER_PACKET
Definition: lpi_spx1.cpp:1371
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_spx1.cpp:1761
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_spx1.cpp:1418
packing single and dual bit values
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:106
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_spx1.cpp:2486
static int colpacketNum(int ncols)
Definition: lpi_spx1.cpp:1469
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_spx1.cpp:2297
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *, SCIP_Real val)
Definition: lpi_spx1.cpp:5298
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_spx1.cpp:1728
static SPxLP::SPxSense spxObjsen(SCIP_OBJSEN objsen)
Definition: lpi_spx1.cpp:1569
SCIPInterval sign(const SCIPInterval &x)
static char spxname[100]
Definition: lpi_spx1.cpp:1610
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3653
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:2085
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_spx1.cpp:2367
int * rstat
Definition: lpi_clp.cpp:97
#define REALABS(x)
Definition: def.h:169
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3500
int cstatsize
Definition: lpi_clp.cpp:98
#define SCIP_CALL(x)
Definition: def.h:316
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_spx1.cpp:3001
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_spx1.cpp:1661
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_spx1.cpp:4056
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3444
static SCIP_Bool fileExists(const char *filename)
Definition: lpi_spx1.cpp:5322
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_spx1.cpp:3295
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:228
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_spx1.cpp:1632
#define EPSCEIL(x, eps)
Definition: def.h:179
#define SOPLEX_SUBVERSION
Definition: lpi_spx1.cpp:83
COLPACKET * packcstat
Definition: lpi_clp.cpp:124
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_spx1.cpp:1690
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:423
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_spx1.cpp:3805
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx1.cpp:5374
#define SCIP_Bool
Definition: def.h:61
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3381
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:412
SCIP_Real SCIPlpiInfinity(SCIP_LPI *)
Definition: lpi_spx1.cpp:5288
static void setFeastol(SCIP_NLPIPROBLEM *nlpiproblem, SCIP_Real feastol)
Definition: nlpi_ipopt.cpp:448
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_spx1.cpp:2738
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_spx1.cpp:2209
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3627
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_spx1.cpp:2766
#define BMSallocMemoryCPP(size)
Definition: memory.h:80
unsigned short Type
Definition: cons_xor.c:91
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:425
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_spx1.cpp:3391
#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_spx1.cpp:3251
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_spx1.cpp:3836
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_spx1.cpp:1487
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_spx1.cpp:3713
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_spx1.cpp:3325
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_spx1.cpp:3856
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_spx1.cpp:1904
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_spx1.cpp:4929
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_spx1.cpp:2672
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_spx1.cpp:2233
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3542
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_spx1.cpp:1957
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx1.cpp:4723
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_spx1.cpp:2103
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_spx1.cpp:4871
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3574
SLUFactor * factorization
Definition: lpi_spx1.cpp:1387
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_spx1.cpp:2519
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_spx1.cpp:1503
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_spx1.cpp:3969
public methods for message output
SCIP_DUALPACKET COLPACKET
Definition: lpi_spx1.cpp:1370
#define SCIP_Real
Definition: def.h:145
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3515
SPxSCIP * spx
Definition: lpi_spx1.cpp:1380
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_spx1.cpp:2646
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_spx1.cpp:4853
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_spx1.cpp:4139
#define BMSallocMemory(ptr)
Definition: memory.h:78
#define SCIP_INVALID
Definition: def.h:165
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:86
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3528
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3591
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_spx1.cpp:2715
SCIP_DUALPACKET ROWPACKET
Definition: lpi_spx1.cpp:1372
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_spx1.cpp:2964
#define SOPLEX_TRY_ABORT(x)
Definition: lpi_spx1.cpp:193
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
#define UNKNOWN
Definition: sepa_mcf.c:4067
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_spx1.cpp:2584
static char spxdesc[200]
Definition: lpi_spx1.cpp:1611
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:410
#define EPSFLOOR(x, eps)
Definition: def.h:178
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:89
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:2977
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_spx1.cpp:5230
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_spx1.cpp:4896
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:3640
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_spx1.cpp:4823
#define SCIP_ALLOC(x)
Definition: def.h:327
#define SCIPABORT()
Definition: def.h:288
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_spx1.cpp:2162
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx1.cpp:4572
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_spx1.cpp:4675
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_spx1.cpp:5185
int * cstat
Definition: lpi_clp.cpp:96