34 #define AUTOPRICING_ITERSWITCH 10000
35 #define STRONGBRANCH_RESTOREBASIS
44 #define CHECK_SPXSOLVE true
45 #define CHECK_SPXSTRONGBRANCH true
47 #define EXIT_AT_WRONG_RESULT false
48 #define EXIT_AT_CPXERROR false
50 #define CPX_CALL(x) do \
53 if( (_cpxstat_ = (x)) != 0 ) \
55 SCIPmessagePrintWarning(m_messagehdlr, "CPLEX error <%d>; SoPlex result unchecked\n", _cpxstat_); \
56 if( EXIT_AT_CPXERROR ) \
76 #include "spxsolver.h"
79 #ifndef SOPLEX_SUBVERSION
80 #define SOPLEX_SUBVERSION 0
84 #if (SOPLEX_VERSION < 133)
85 #error "This interface is not compatible with SoPlex versions prior to 1.4"
89 #if (SOPLEX_VERSION >= 160)
90 #include "spxgithash.h"
94 #include "slufactor.h"
95 #include "spxsteeppr.h"
96 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 6) || SOPLEX_VERSION > 160)
97 #include "spxsteepexpr.h"
99 #include "spxparmultpr.h"
100 #include "spxdevexpr.h"
101 #include "spxfastrt.h"
102 #include "spxmainsm.h"
103 #include "spxequilisc.h"
105 #ifdef WITH_BOUNDFLIPPING
106 #include "spxboundflippingrt.h"
116 #define SOPLEX_VERBLEVEL 5
129 using namespace soplex;
137 #define SOPLEX_TRY(messagehdlr, x) do \
143 catch(SPxException E) \
145 std::string s = E.what(); \
146 SCIPmessagePrintWarning((messagehdlr), "SoPlex threw an exception: %s\n", s.c_str()); \
147 return SCIP_LPERROR; \
153 #define SOPLEX_TRY(messagehdlr, x) do \
159 catch(SPxException E) \
161 return SCIP_LPERROR; \
167 #define SOPLEX_TRYLPI(x) SOPLEX_TRY(lpi->messagehdlr, x)
168 #define SOPLEX_TRYLPIPTR(x) SOPLEX_TRY((*lpi)->messagehdlr, x)
173 #define SOPLEX_TRY_ABORT(x) do \
179 catch(SPxException E) \
181 std::string s = E.what(); \
182 SCIPerrorMessage("SoPlex threw an exception: %s\n", s.c_str()); \
191 class SPxSCIP :
public SPxSolver
193 SPxLP::SPxSense m_sense;
195 SPxSteepPR m_price_steep;
196 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 6) || SOPLEX_VERSION > 160)
197 SPxSteepExPR m_price_steep_ex;
199 SPxSteepPR m_price_steep_ex;
201 SPxParMultPR m_price_parmult;
202 SPxDevexPR m_price_devex;
203 #ifdef WITH_BOUNDFLIPPING
204 SPxBoundFlippingRT m_ratio;
221 SPxSolver::VarStatus* m_rowstat;
222 SPxSolver::VarStatus* m_colstat;
237 const char* probname =
NULL
239 : SPxSolver(LEAVE, COLUMN),
241 m_fromscratch(
false),
244 m_objLoLimit(-soplex::infinity),
245 m_objUpLimit(soplex::infinity),
255 m_messagehdlr(messagehdlr)
258 setSense(SPxLP::MINIMIZE);
261 setPricer(&m_price_steep);
264 if ( probname !=
NULL )
267 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
268 m_lpifeastol = SPxSolver::feastol();
269 m_lpiopttol = SPxSolver::opttol();
271 m_lpifeastol = SPxSolver::delta();
272 m_lpiopttol = SPxSolver::delta();
277 m_cpxenv = CPXopenCPLEX(&cpxstat);
278 assert(m_cpxenv !=
NULL);
279 m_cpxlp = CPXcreateprob(m_cpxenv, &cpxstat, probname !=
NULL ? probname :
"spxcheck");
280 (void) CPXsetintparam(m_cpxenv, CPX_PARAM_SCRIND, 0);
282 m_doublecheck =
false;
288 if( m_probname !=
NULL )
289 spx_free(m_probname);
291 freePreStrongbranchingBasis();
293 if( m_rownames !=
NULL )
295 m_rownames->~NameSet();
296 spx_free(m_rownames);
298 if( m_colnames !=
NULL )
300 m_colnames->~NameSet();
301 spx_free(m_colnames);
305 (void) CPXfreeprob(m_cpxenv, &m_cpxlp);
306 (void) CPXcloseCPLEX(&m_cpxenv);
323 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
326 SPxSolver::setDelta(d);
343 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
344 SPxSolver::setOpttol(d);
346 SPxSolver::setDelta(d);
353 return (shift() >= 10.0 * epsilon());
357 void setIterationLimit(
366 setPricer(&m_price_devex);
367 m_autopricing =
true;
372 setPricer(&m_price_steep);
373 m_autopricing =
false;
376 void setSteepPricer()
378 setPricer(&m_price_steep_ex);
379 m_autopricing =
false;
382 void setSteepQStartPricer()
384 setPricer(&m_price_steep);
385 m_autopricing =
false;
388 void setParmultPricer()
390 setPricer(&m_price_parmult);
391 m_autopricing =
false;
394 void setDevexPricer()
396 setPricer(&m_price_devex);
397 m_autopricing =
false;
401 int getIterationLimit()
406 bool getFromScratch()
const
408 return m_fromscratch;
411 void setFromScratch(
bool fs)
416 bool getScaling()
const
421 void setScaling(
bool s)
426 bool getPresolving()
const
431 void setPresolving(
bool p)
436 bool getLpInfo()
const
441 void setLpInfo(
bool li)
446 SPxLP::SPxSense getSense()
const
448 assert(m_sense == sense());
453 void setSense(
const SPxLP::SPxSense sen)
455 assert(m_sense == sense());
463 if( m_sense == SPxLP::MINIMIZE && getObjUpLimit() < soplex::infinity )
466 SPxSolver::setTerminationValue(getObjUpLimit());
468 else if( m_sense == SPxLP::MAXIMIZE && getObjLoLimit() > -soplex::infinity )
471 SPxSolver::setTerminationValue(getObjLoLimit());
476 void setProbname(
const char* probname)
480 assert(probname !=
NULL);
481 if( m_probname !=
NULL )
482 spx_free(m_probname);
483 len = (int)strlen(probname);
484 spx_alloc(m_probname, len + 1);
485 strncpy(m_probname, probname, len);
486 m_probname[len] =
'\0';
489 Real getObjLoLimit()
const
494 void setObjLoLimit(Real limit)
496 if( getSense() == SPxLP::MAXIMIZE )
498 SCIPdebugMessage(
"setting termination value from <%g> to <%g>\n", m_objLoLimit, limit);
499 SPxSolver::setTerminationValue(limit);
501 m_objLoLimit = limit;
504 Real getObjUpLimit()
const
509 void setObjUpLimit(Real limit)
511 if( getSense() == SPxLP::MINIMIZE )
513 SCIPdebugMessage(
"setting termination value from <%g> to <%g>\n", m_objUpLimit, limit);
514 SPxSolver::setTerminationValue(limit);
516 m_objUpLimit = limit;
519 void setRep(SPxSolver::Representation p_rep)
523 SCIPdebugMessage(
"switching to %s representation of the basis\n", p_rep == SPxSolver::ROW ?
"row" :
"column");
524 SPxSolver::setRep(p_rep);
529 bool getDoubleCheck()
532 return m_doublecheck && m_checknum + 1 >= CHECK_START;
535 void setDoubleCheck(
bool dc)
540 const char* spxStatusString(
const SPxSolver::Status stat)
544 case SPxSolver::ABORT_TIME:
546 case SPxSolver::ABORT_ITER:
548 case SPxSolver::ABORT_VALUE:
549 return "ABORT_VALUE";
550 case SPxSolver::SINGULAR:
552 case SPxSolver::REGULAR:
556 case SPxSolver::OPTIMAL:
558 case SPxSolver::UNBOUNDED:
560 case SPxSolver::INFEASIBLE:
569 const char* cpxStatusString(
const int stat)
573 case CPX_STAT_ABORT_TIME_LIM:
575 case CPX_STAT_ABORT_IT_LIM:
577 case CPX_STAT_ABORT_OBJ_LIM:
578 return "ABORT_VALUE";
579 case CPX_STAT_OPTIMAL:
581 case CPX_STAT_OPTIMAL_INFEAS:
582 return "CPX_STAT_OPTIMAL_INFEAS: OPT SOL INFEASIBLE AFTER UNSCALING";
583 case CPX_STAT_UNBOUNDED:
585 case CPX_STAT_INFEASIBLE:
587 case CPX_STAT_INForUNBD:
588 return "INFEASIBLE or UNBOUNDED";
589 case CPX_STAT_NUM_BEST:
590 return "CPX_STAT_NUM_BEST: SOL AVAILABLE BUT NOT PROVEN OPTIMAL DUE TO NUM TROUBLE";
600 bool checkConsistentBounds()
602 for(
int i = 0; i < nCols(); ++i )
604 if( lower(i) > upper(i) )
606 SCIPerrorMessage(
"inconsistent bounds on column %d: lower=%.17g, upper=%.17g\n",
607 i, lower(i), upper(i));
615 bool checkConsistentSides()
617 for(
int i = 0; i < nRows(); ++i )
619 if( lhs(i) > rhs(i) )
631 void trySolve(
bool printwarning =
true)
637 m_stat = SPxSolver::solve();
639 catch(SPxException x)
641 std::string s = x.what();
646 m_stat = SPxSolver::status();
652 assert( m_stat != SPxSolver::OPTIMAL );
656 m_itused += SPxSolver::iterations();
657 assert(m_itlim < 0 || m_itused <= m_itlim);
660 timespent = SPxSolver::time();
664 timelimit = SPxSolver::terminationTime();
665 if( timelimit > timespent )
666 timelimit -= timespent;
670 assert(timelimit >= 0);
671 SPxSolver::setTerminationTime(timelimit);
675 virtual Status doSolve(
bool printwarning =
true)
680 verbosity = Param::verbose();
683 assert(checkConsistentBounds());
684 assert(checkConsistentSides());
688 if( getDoubleCheck() )
693 setTerminationIter(m_autopricing && (m_itlim < 0 || m_itlim - m_itused >
AUTOPRICING_ITERSWITCH) ? AUTOPRICING_ITERSWITCH : m_itlim - m_itused);
695 trySolve(printwarning);
697 if( m_autopricing && m_stat == SPxSolver::ABORT_ITER && (m_itlim < 0 || m_itlim - m_itused > 0) )
699 setTerminationIter(m_itlim - m_itused);
700 setPricer(&m_price_steep_ex);
702 trySolve(printwarning);
704 setPricer(&m_price_devex);
708 setTerminationIter(m_itlim);
710 if( m_stat == OPTIMAL )
712 Real objval = value();
714 if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
715 m_stat = ABORT_VALUE;
720 if( getDoubleCheck() && (m_stat == SPxSolver::OPTIMAL || m_stat == SPxSolver::UNBOUNDED || m_stat == SPxSolver::INFEASIBLE || m_stat == SPxSolver::ABORT_VALUE) )
726 CPX_CALL( CPXreadcopyprob(m_cpxenv, m_cpxlp,
"spxcheck.mps",
NULL) );
727 CPX_CALL( CPXreadcopybase(m_cpxenv, m_cpxlp,
"spxcheck.bas") );
730 CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPOPT,
MAX(opttol(), 1e-9)) );
731 CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPRHS,
MAX(feastol(), 1e-9)) );
734 CPX_CALL( CPXlpopt(m_cpxenv, m_cpxlp) );
737 CPX_CALL( CPXsolution(m_cpxenv, m_cpxlp, &cpxstat, &cpxobj,
NULL,
NULL,
NULL,
NULL) );
738 if( getSense() == SPxLP::MAXIMIZE )
742 if( cpxstat == CPX_STAT_OPTIMAL_INFEAS )
744 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s)\n",
745 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat));
746 if( EXIT_AT_CPXERROR )
749 else if( (m_stat == SPxSolver::OPTIMAL && cpxstat != CPX_STAT_OPTIMAL)
750 || (m_stat == SPxSolver::UNBOUNDED && cpxstat != CPX_STAT_UNBOUNDED)
751 || (m_stat == SPxSolver::INFEASIBLE && cpxstat != CPX_STAT_INFEASIBLE) )
753 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
754 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
755 if( EXIT_AT_WRONG_RESULT )
758 else if( m_stat == SPxSolver::ABORT_VALUE )
762 case CPX_STAT_OPTIMAL:
763 if( (getSense() == SPxSolver::MINIMIZE && LTrel(cpxobj, getObjUpLimit(), 2*opttol()))
764 || (getSense() == SPxSolver::MAXIMIZE && GTrel(cpxobj, getObjLoLimit(), 2*opttol())) )
766 SCIPerrorMessage(
"In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
767 m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ?
"<" :
">",
768 getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
769 if( EXIT_AT_WRONG_RESULT )
772 else if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
773 || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
775 SCIPerrorMessage(
"In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
776 m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ?
"<" :
">",
777 getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
780 case CPX_STAT_OPTIMAL_INFEAS:
781 case CPX_STAT_NUM_BEST:
782 if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
783 || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
785 SCIPerrorMessage(
"In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
786 m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ?
"<" :
">",
787 getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
790 case CPX_STAT_INFEASIBLE:
792 case CPX_STAT_UNBOUNDED:
793 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
794 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
795 if( EXIT_AT_WRONG_RESULT )
798 case CPX_STAT_INForUNBD:
800 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
801 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
806 else if( m_stat == SPxSolver::OPTIMAL )
808 if( (getSense() == SPxSolver::MINIMIZE && LTrel(value(), cpxobj, 2*opttol()))
809 || (getSense() == SPxSolver::MAXIMIZE && GTrel(value(), cpxobj, 2*opttol())) )
814 else if( (getSense() == SPxSolver::MINIMIZE && GTrel(value(), cpxobj, 2*opttol()))
815 || (getSense() == SPxSolver::MAXIMIZE && LTrel(value(), cpxobj, 2*opttol())) )
817 SCIPerrorMessage(
"In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f suboptimal (checknum=%d)\n", value(),
818 m_probname, getSense() == SPxSolver::MINIMIZE ?
">" :
"<", cpxobj, m_checknum);
819 if( EXIT_AT_WRONG_RESULT )
829 Param::setVerbose(verbosity);
834 virtual Status solve()
836 assert(m_sense == sense());
838 SPxEquiliSC* scaler =
NULL;
839 SPxMainSM* simplifier =
NULL;
841 SPxSimplifier::Result result = SPxSimplifier::OKAY;
844 if ( getFromScratch() )
850 catch(SPxException x)
852 std::string s = x.what();
854 m_stat = SPxSolver::status();
855 assert( m_stat != SPxSolver::OPTIMAL );
859 assert(!getFromScratch() || getBasisStatus() == SPxBasis::NO_PROBLEM);
862 if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && getScaling() && nCols() > 0 && nRows() > 0 )
864 spx_alloc(scaler, 1);
865 scaler =
new (scaler) SPxEquiliSC();
866 assert(scaler !=
NULL);
869 if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && getPresolving() && nCols() > 0 && nRows() > 0 )
871 spx_alloc(simplifier, 1);
872 simplifier =
new (simplifier) SPxMainSM();
873 assert(simplifier !=
NULL);
877 if( scaler !=
NULL || simplifier !=
NULL )
878 origlp = SPxLP(*
this);
885 scaler->scale(*
this);
888 if( simplifier !=
NULL )
893 verbosity = Param::verbose();
896 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
897 result = simplifier->simplify(*
this, epsilon(), feastol(), opttol());
899 result = simplifier->simplify(*
this, epsilon(), delta());
901 SCIPdebugMessage(
"simplifier ended with status %u (0: OKAY, 1: INFEASIBLE, 2: DUAL_INFEASIBLE, 3: UNBOUNDED, 4: VANISHED)\n", result);
904 if( result == SPxSimplifier::INFEASIBLE || result == SPxSimplifier::DUAL_INFEASIBLE )
906 SCIPdebugMessage(
"simplifier detected primal or dual infeasibility - reloading and solving unsimplified LP\n");
908 simplifier->~SPxMainSM();
909 spx_free(simplifier);
911 SPxSolver::loadLP(origlp);
917 Param::setVerbose(verbosity);
922 if( result != SPxSimplifier::VANISHED )
925 Real objlolimit = getObjLoLimit();
926 Real objuplimit = getObjUpLimit();
928 if( simplifier !=
NULL || scaler !=
NULL )
930 setObjLoLimit(-soplex::infinity);
931 setObjUpLimit(soplex::infinity);
940 if( simplifier !=
NULL || scaler !=
NULL )
942 setObjLoLimit(objlolimit);
943 setObjUpLimit(objuplimit);
948 if( m_stat != SPxSolver::OPTIMAL && simplifier !=
NULL )
950 SCIPdebugMessage(
"presolved LP not optimal - reloading and solving original LP\n");
952 simplifier->~SPxMainSM();
953 spx_free(simplifier);
955 SPxSolver::loadLP(origlp);
962 if( scaler !=
NULL || simplifier !=
NULL )
964 SPxSolver::VarStatus* cstat =
NULL;
965 SPxSolver::VarStatus* rstat =
NULL;
968 if( (simplifier ==
NULL || result != SPxSimplifier::VANISHED) && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
971 spx_alloc(rstat, nRows());
972 spx_alloc(cstat, nCols());
973 SPxSolver::getBasis(rstat, cstat);
977 if( simplifier !=
NULL && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
979 assert((result == SPxSimplifier::VANISHED) == (cstat ==
NULL));
980 assert((result == SPxSimplifier::VANISHED) == (rstat ==
NULL));
983 int ncols = result == SPxSimplifier::VANISHED ? 0 : nCols();
984 int nrows = result == SPxSimplifier::VANISHED ? 0 : nRows();
987 DVector primals(ncols);
988 DVector duals(nrows);
989 DVector slacks(nrows);
990 DVector redcosts(ncols);
991 if( result != SPxSimplifier::VANISHED )
993 SPxSolver::getPrimal(primals);
994 SPxSolver::getDual(duals);
995 SPxSolver::getSlacks(slacks);
996 SPxSolver::getRedCost(redcosts);
1003 simplifier->unsimplify(primals, duals, slacks, redcosts, rstat, cstat);
1005 catch(SPxException x)
1007 std::string s = x.what();
1008 SCIPmessagePrintWarning(m_messagehdlr,
"SoPlex unsimplification unsuccessful; solving again without LP presolving (SoPlex says %s)\n",
1017 if( simplifier->isUnsimplified() )
1022 spx_alloc(rstat, origlp.nRows());
1023 spx_alloc(cstat, origlp.nCols());
1024 simplifier->getBasis(rstat, cstat);
1030 SPxSolver::loadLP(origlp);
1034 if( rstat !=
NULL && cstat !=
NULL )
1037 SPxSolver::setBasis(rstat, cstat);
1052 if( scaler !=
NULL )
1054 scaler->~SPxEquiliSC();
1057 if( simplifier !=
NULL )
1059 simplifier->~SPxMainSM();
1060 spx_free(simplifier);
1064 if( m_stat == OPTIMAL )
1066 Real objval = value();
1068 if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
1069 m_stat = ABORT_VALUE;
1076 void savePreStrongbranchingBasis()
1078 assert(m_rowstat ==
NULL);
1079 assert(m_colstat ==
NULL);
1081 spx_alloc(m_rowstat, nRows());
1082 spx_alloc(m_colstat, nCols());
1086 m_stat = getBasis(m_rowstat, m_colstat);
1088 catch(SPxException x)
1091 std::string s = x.what();
1098 assert(m_stat != SPxSolver::OPTIMAL);
1104 void restorePreStrongbranchingBasis()
1106 assert(m_rowstat !=
NULL);
1107 assert(m_colstat !=
NULL);
1111 setBasis(m_rowstat, m_colstat);
1113 catch(SPxException x)
1116 std::string s = x.what();
1119 m_stat = SPxSolver::status();
1125 assert(m_stat != SPxSolver::OPTIMAL);
1130 void freePreStrongbranchingBasis()
1132 if( m_rowstat !=
NULL )
1133 spx_free(m_rowstat);
1134 if( m_colstat !=
NULL )
1135 spx_free(m_colstat);
1139 bool preStrongbranchingBasisFreed()
1141 return ((m_rowstat ==
NULL ) && (m_colstat ==
NULL));
1144 Status getStatus()
const
1149 Status updateStatus()
1151 m_stat = SPxSolver::status();
1155 bool isInitialized()
const
1157 return SPxSolver::isInitialized();
1160 int iterations()
const
1165 virtual void clear()
1168 freePreStrongbranchingBasis();
1169 m_stat = NO_PROBLEM;
1173 bool readLP(
const char* fname)
1177 if ( m_rownames != 0 )
1178 m_rownames->~NameSet();
1180 spx_alloc(m_colnames, 1);
1182 if ( m_colnames != 0 )
1183 m_colnames->~NameSet();
1185 spx_alloc(m_rownames, 1);
1187 m_rownames =
new (m_rownames) NameSet();
1188 m_colnames =
new (m_colnames) NameSet();
1190 if( SPxSolver::readFile(fname, m_rownames, m_colnames) )
1192 m_stat = NO_PROBLEM;
1206 int namestoragesize,
1210 assert( m_colnames !=
NULL );
1213 if ( namestoragesize == 0 )
1216 *storageleft = -m_colnames->memSize();
1220 NameSet* names = m_colnames;
1221 assert( names != 0 );
1222 int sizeleft = namestoragesize;
1223 char* s = namestorage;
1224 for (
int j = firstcol; j <= lastcol; ++j)
1226 const char* t = (*names)[j];
1227 colnames[j-firstcol] = s;
1228 while( *t !=
'\0' && sizeleft >= 0 )
1235 if ( sizeleft == 0 )
1237 *storageleft = namestoragesize - m_colnames->memSize();
1238 assert( *storageleft <= 0 );
1241 *storageleft = sizeleft;
1251 int namestoragesize,
1255 assert( m_rownames !=
NULL );
1258 if ( namestoragesize == 0 )
1261 *storageleft = -m_rownames->memSize();
1265 NameSet* names = m_rownames;
1266 assert( names != 0 );
1267 int sizeleft = namestoragesize;
1268 char* s = namestorage;
1269 for (
int i = firstrow; i <= lastrow; ++i)
1271 const char* t = (*names)[i];
1272 rownames[i-firstrow] = s;
1273 while( *t !=
'\0' && sizeleft >= 0 )
1280 if ( sizeleft == 0 )
1282 *storageleft = m_rownames->memSize() - namestoragesize;
1283 assert( *storageleft <= 0 );
1286 *storageleft = sizeleft;
1302 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
1304 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
1348 assert(lpi !=
NULL);
1358 assert(num <= lpi->cstatsize);
1370 assert(lpi !=
NULL);
1380 assert(num <= lpi->rstatsize);
1418 assert(lpistate !=
NULL);
1434 assert(lpistate !=
NULL);
1451 assert(lpistate !=
NULL);
1452 assert(blkmem !=
NULL);
1470 assert(blkmem !=
NULL);
1471 assert(lpistate !=
NULL);
1472 assert(*lpistate !=
NULL);
1495 return SPxLP::MAXIMIZE;
1497 return SPxLP::MINIMIZE;
1501 return SPxLP::MINIMIZE;
1509 assert(lpi !=
NULL);
1542 #if (SOPLEX_SUBVERSION > 0)
1543 sprintf(
spxname,
"SoPlex %d.%d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10,
SOPLEX_SUBVERSION);
1545 sprintf(
spxname,
"SoPlex %d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10);
1555 sprintf(
spxdesc,
"%s",
"Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de)");
1556 #if (SOPLEX_VERSION >= 160)
1559 #ifdef WITH_LPSCHECK
1560 sprintf(
spxdesc,
"%s %s",
spxdesc,
"- including CPLEX double check");
1570 return (
void*) lpi->
spx;
1592 assert(lpi !=
NULL);
1599 SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxSCIP(messagehdlr, name) );
1600 (*lpi)->cstat =
NULL;
1601 (*lpi)->rstat =
NULL;
1602 (*lpi)->cstatsize = 0;
1603 (*lpi)->rstatsize = 0;
1605 (*lpi)->factorization = 0;
1607 (*lpi)->conditionlimit = -1.0;
1608 (*lpi)->checkcondition =
FALSE;
1609 (*lpi)->messagehdlr = messagehdlr;
1627 assert(lpi !=
NULL);
1628 assert(*lpi !=
NULL);
1629 assert((*lpi)->spx !=
NULL);
1632 (*lpi)->spx->~SPxSCIP();
1676 assert(lpi !=
NULL);
1678 assert(lhs !=
NULL);
1679 assert(rhs !=
NULL);
1682 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1686 SPxSCIP* spx = lpi->
spx;
1687 LPRowSet rows(nrows);
1688 DSVector emptyVector(0);
1697 for( i = 0; i < nrows; ++i )
1698 rows.add(lhs[i], emptyVector, rhs[i]);
1704 catch(SPxException x)
1707 std::string s = x.what();
1732 assert(lpi !=
NULL);
1734 assert(obj !=
NULL);
1737 assert(nnonz == 0 || beg !=
NULL);
1738 assert(nnonz == 0 || ind !=
NULL);
1739 assert(nnonz == 0 || val !=
NULL);
1743 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1745 SPxSCIP* spx = lpi->
spx;
1748 LPColSet cols(ncols);
1749 DSVector colVector(ncols);
1755 for( i = 0; i < ncols; ++i )
1761 last = (i == ncols-1 ? nnonz : beg[i+1]);
1762 colVector.add( last-start, &ind[start], &val[start] );
1764 cols.add(obj[i], lb[i], colVector, ub[i]);
1768 catch(SPxException x)
1771 std::string s = x.what();
1789 assert(lpi !=
NULL);
1791 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
1795 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1815 assert(lpi !=
NULL);
1820 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1822 ncols = lpi->
spx->nCols();
1825 for( i = 0; i < ncols; ++i )
1848 assert(lpi !=
NULL);
1850 assert(lhs !=
NULL);
1851 assert(rhs !=
NULL);
1852 assert(nnonz == 0 || beg !=
NULL);
1853 assert(nnonz == 0 || ind !=
NULL);
1854 assert(nnonz == 0 || val !=
NULL);
1858 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1862 SPxSCIP* spx = lpi->
spx;
1863 LPRowSet rows(nrows);
1870 for( i = 0; i < nrows; ++i )
1876 last = (i == nrows-1 ? nnonz : beg[i+1]);
1877 rowVector.add( last-start, &ind[start], &val[start] );
1879 rows.add(lhs[i], rowVector, rhs[i]);
1883 catch(SPxException x)
1886 std::string s = x.what();
1904 assert(lpi !=
NULL);
1906 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
1910 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1930 assert(lpi !=
NULL);
1935 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1937 nrows = lpi->
spx->nRows();
1940 for( i = 0; i < nrows; ++i )
1955 assert(lpi !=
NULL);
1960 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1979 assert(lpi !=
NULL);
1981 assert(ind !=
NULL);
1987 assert( lpi->
spx->preStrongbranchingBasisFreed() );
1991 for( i = 0; i < ncols; ++i )
1993 assert(0 <= ind[i] && ind[i] < lpi->
spx->nCols());
1994 lpi->
spx->changeBounds(ind[i], lb[i], ub[i]);
1995 assert(lpi->
spx->lower(ind[i]) <= lpi->
spx->upper(ind[i]));
1998 catch(SPxException x)
2001 std::string s = x.what();
2023 assert(lpi !=
NULL);
2025 assert(ind !=
NULL);
2026 assert(lhs !=
NULL);
2027 assert(rhs !=
NULL);
2031 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2035 for( i = 0; i < nrows; ++i )
2037 assert(0 <= ind[i] && ind[i] < lpi->
spx->nRows());
2038 lpi->
spx->changeRange(ind[i], lhs[i], rhs[i]);
2039 assert(lpi->
spx->lhs(ind[i]) <= lpi->
spx->rhs(ind[i]));
2042 catch(SPxException x)
2045 std::string s = x.what();
2064 assert(lpi !=
NULL);
2066 assert(0 <= row && row < lpi->spx->nRows());
2067 assert(0 <= col && col < lpi->spx->nCols());
2071 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2086 assert(lpi !=
NULL);
2091 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2110 assert(lpi !=
NULL);
2112 assert(ind !=
NULL);
2113 assert(obj !=
NULL);
2117 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2121 for( i = 0; i < ncols; ++i )
2123 assert(0 <= ind[i] && ind[i] < lpi->
spx->nCols());
2124 lpi->
spx->changeObj(ind[i], obj[i]);
2127 catch(SPxException x)
2130 std::string s = x.what();
2151 assert(lpi !=
NULL);
2153 assert(scaleval != 0.0);
2159 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2162 SVector rowvec = lpi->
spx->rowVector(row);
2163 lhs = lpi->
spx->lhs(row);
2164 rhs = lpi->
spx->rhs(row);
2170 if( lhs > -soplex::infinity )
2172 else if( scaleval < 0.0 )
2173 lhs = soplex::infinity;
2174 if( rhs < soplex::infinity )
2176 else if( scaleval < 0.0 )
2177 rhs = -soplex::infinity;
2178 if( scaleval < 0.0 )
2186 LPRow lprow(lhs, rowvec, rhs);
2189 lpi->
spx->changeRow(row, lprow);
2190 assert(lpi->
spx->lhs(row) <= lpi->
spx->rhs(row));
2192 catch(SPxException x)
2195 std::string s = x.what();
2219 assert(lpi !=
NULL);
2221 assert(scaleval != 0.0);
2227 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2230 SVector colvec = lpi->
spx->colVector(col);
2231 obj = lpi->
spx->obj(col);
2232 lb = lpi->
spx->lower(col);
2233 ub = lpi->
spx->upper(col);
2242 if( lb > -soplex::infinity )
2244 else if( scaleval < 0.0 )
2245 lb = soplex::infinity;
2246 if( ub < soplex::infinity )
2248 else if( scaleval < 0.0 )
2249 ub = -soplex::infinity;
2250 if( scaleval < 0.0 )
2258 LPCol lpcol(obj, colvec, ub, lb);
2261 lpi->
spx->changeCol(col, lpcol);
2262 assert(lpi->
spx->lower(col) <= lpi->
spx->upper(col));
2264 catch(SPxException x)
2267 std::string s = x.what();
2296 assert(lpi !=
NULL);
2298 assert(nrows !=
NULL);
2300 *nrows = lpi->
spx->nRows();
2313 assert(lpi !=
NULL);
2315 assert(ncols !=
NULL);
2317 *ncols = lpi->
spx->nCols();
2332 assert(lpi !=
NULL);
2334 assert(nnonz !=
NULL);
2338 if( lpi->
spx->nRows() < lpi->
spx->nCols() )
2340 for( i = 0; i < lpi->
spx->nRows(); ++i )
2341 (*nnonz) += lpi->
spx->rowVector(i).size();
2345 for( i = 0; i < lpi->
spx->nCols(); ++i )
2346 (*nnonz) += lpi->
spx->colVector(i).size();
2373 assert(lpi !=
NULL);
2375 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2381 const Vector& lbvec = lpi->
spx->lower();
2382 const Vector& ubvec = lpi->
spx->upper();
2383 for( i = firstcol; i <= lastcol; ++i )
2385 lb[i-firstcol] = lbvec[i];
2386 ub[i-firstcol] = ubvec[i];
2395 for( i = firstcol; i <= lastcol; ++i )
2397 beg[i-firstcol] = *nnonz;
2398 const SVector& cvec = lpi->
spx->colVector(i);
2399 for( j = 0; j < cvec.size(); ++j )
2401 ind[*nnonz] = cvec.index(j);
2402 val[*nnonz] = cvec.value(j);
2409 assert(beg ==
NULL);
2410 assert(ind ==
NULL);
2411 assert(val ==
NULL);
2438 assert(lpi !=
NULL);
2440 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2444 assert(rhs !=
NULL);
2446 const Vector& lhsvec = lpi->
spx->lhs();
2447 const Vector& rhsvec = lpi->
spx->rhs();
2448 for( i = firstrow; i <= lastrow; ++i )
2450 lhs[i-firstrow] = lhsvec[i];
2451 rhs[i-firstrow] = rhsvec[i];
2455 assert(rhs ==
NULL);
2460 for( i = firstrow; i <= lastrow; ++i )
2462 beg[i-firstrow] = *nnonz;
2463 const SVector& rvec = lpi->
spx->rowVector(i);
2464 for( j = 0; j < rvec.size(); ++j )
2466 ind[*nnonz] = rvec.index(j);
2467 val[*nnonz] = rvec.value(j);
2474 assert(beg ==
NULL);
2475 assert(ind ==
NULL);
2476 assert(val ==
NULL);
2489 int namestoragesize,
2493 assert( lpi !=
NULL );
2495 assert( colnames !=
NULL || namestoragesize == 0 );
2496 assert( namestorage !=
NULL || namestoragesize == 0 );
2497 assert( namestoragesize >= 0 );
2498 assert( storageleft !=
NULL );
2499 assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols() );
2503 lpi->
spx->getColNames(firstcol, lastcol, colnames, namestorage, namestoragesize, storageleft);
2515 int namestoragesize,
2519 assert( lpi !=
NULL );
2521 assert( rownames !=
NULL || namestoragesize == 0 );
2522 assert( namestorage !=
NULL || namestoragesize == 0 );
2523 assert( namestoragesize >= 0 );
2524 assert( storageleft !=
NULL );
2525 assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows() );
2529 lpi->
spx->getRowNames(firstrow, lastrow, rownames, namestorage, namestoragesize, storageleft);
2542 assert(lpi !=
NULL);
2544 assert(objsen !=
NULL);
2563 assert(lpi !=
NULL);
2565 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2566 assert(vals !=
NULL);
2568 for( i = firstcol; i <= lastcol; ++i )
2569 vals[i-firstcol] = lpi->
spx->obj(i);
2587 assert(lpi !=
NULL);
2589 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2591 for( i = firstcol; i <= lastcol; ++i )
2594 lbs[i-firstcol] = lpi->
spx->lower(i);
2596 ubs[i-firstcol] = lpi->
spx->upper(i);
2615 assert(lpi !=
NULL);
2617 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2619 for( i = firstrow; i <= lastrow; ++i )
2622 lhss[i-firstrow] = lpi->
spx->lhs(i);
2624 rhss[i-firstrow] = lpi->
spx->rhs(i);
2640 assert(lpi !=
NULL);
2642 assert(0 <= col && col < lpi->spx->nCols());
2643 assert(0 <= row && row < lpi->spx->nRows());
2644 assert(val !=
NULL);
2646 *val = lpi->
spx->colVector(col)[row];
2667 SPxSolver::Representation rep,
2671 assert( lpi !=
NULL );
2673 assert( rep == SPxSolver::ROW || rep == SPxSolver::COLUMN );
2674 assert( type == SPxSolver::ENTER || type == SPxSolver::LEAVE );
2680 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2683 lpi->
spx->setRep(rep);
2684 lpi->
spx->setType(type);
2686 #ifdef WITH_LPSCHECK
2687 lpi->
spx->setDoubleCheck(CHECK_SPXSOLVE);
2690 SPxSolver::Status status = lpi->
spx->solve();
2691 SCIPdebugMessage(
" -> SoPlex status: %d, basis status: %d\n", lpi->
spx->getStatus(), lpi->
spx->basis().status());
2696 case SPxSolver::ABORT_TIME:
2697 case SPxSolver::ABORT_ITER:
2698 case SPxSolver::ABORT_VALUE:
2699 case SPxSolver::SINGULAR:
2700 case SPxSolver::REGULAR:
2702 case SPxSolver::OPTIMAL:
2703 case SPxSolver::UNBOUNDED:
2704 case SPxSolver::INFEASIBLE:
2721 assert(lpi !=
NULL);
2728 rowrep = lpi->
spx->rep() == SPxSolver::ROW;
2748 retcode = rowrep ?
spxSolve(lpi, SPxSolver::ROW, SPxSolver::LEAVE) :
spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::ENTER);
2749 assert(!rowrep || lpi->
spx->rep() == SPxSolver::ROW);
2750 assert(rowrep || lpi->
spx->rep() == SPxSolver::COLUMN);
2765 assert(lpi !=
NULL);
2772 rowrep = lpi->
spx->rep() == SPxSolver::ROW;
2792 retcode = rowrep ?
spxSolve(lpi, SPxSolver::ROW, SPxSolver::ENTER) :
spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::LEAVE);
2793 assert(!rowrep || lpi->
spx->rep() == SPxSolver::ROW);
2794 assert(rowrep || lpi->
spx->rep() == SPxSolver::COLUMN);
2817 assert( lpi->
spx->preStrongbranchingBasisFreed() );
2818 lpi->
spx->savePreStrongbranchingBasis();
2828 assert( ! lpi->
spx->preStrongbranchingBasisFreed() );
2829 lpi->
spx->restorePreStrongbranchingBasis();
2830 lpi->
spx->freePreStrongbranchingBasis();
2852 SPxSolver::Status status;
2857 bool fromparentbasis;
2861 SCIPdebugMessage(
"calling SCIPlpiStrongbranch() on variable %d (%d iterations)\n", col, itlim);
2863 assert(lpi !=
NULL);
2867 assert(downvalid !=
NULL);
2868 assert(upvalid !=
NULL);
2872 fromparentbasis =
false;
2874 oldItlim = spx->getIterationLimit();
2877 oldlb = spx->lower(col);
2878 oldub = spx->upper(col);
2887 lpi->
spx->setType( lpi->
spx->rep() == SPxSolver::ROW ? SPxSolver::ENTER : SPxSolver::LEAVE);
2890 newub =
EPSCEIL(psol-1.0, lpi->
spx->feastol());
2891 if( newub >= oldlb - 0.5 && down !=
NULL )
2893 SCIPdebugMessage(
"strong branching down on x%d (%g) with %d iterations\n", col, psol, itlim);
2895 spx->changeUpper(col, newub);
2896 assert(spx->lower(col) <= spx->upper(col));
2898 spx->setIterationLimit(itlim);
2901 #ifdef WITH_LPSCHECK
2902 spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2904 status = spx->solve();
2908 case SPxSolver::OPTIMAL:
2909 *down = spx->value();
2913 case SPxSolver::ABORT_TIME:
2914 case SPxSolver::ABORT_ITER:
2915 case SPxSolver::ABORT_CYCLING:
2916 *down = spx->value();
2918 case SPxSolver::ABORT_VALUE:
2919 case SPxSolver::INFEASIBLE:
2920 *down = spx->terminationValue();
2928 (*iter) += spx->iterations();
2930 #ifdef STRONGBRANCH_RESTOREBASIS
2932 assert( ! spx->preStrongbranchingBasisFreed() );
2933 spx->restorePreStrongbranchingBasis();
2934 fromparentbasis =
false;
2938 if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
2940 SCIPdebugMessage(
" --> Repeat strong branching down with %d iterations after restoring basis\n", itlim - spx->iterations());
2941 spx->setIterationLimit(itlim - spx->iterations());
2942 assert( ! spx->hasPreStrongbranchingBasis() );
2943 spx->restorePreStrongbranchingBasis();
2944 fromparentbasis =
true;
2949 fromparentbasis =
false;
2952 while( fromparentbasis );
2954 spx->changeUpper(col, oldub);
2955 assert(spx->lower(col) <= spx->upper(col));
2957 else if( down !=
NULL )
2959 *down = spx->terminationValue();
2969 if( newlb <= oldub + 0.5 && up !=
NULL )
2971 SCIPdebugMessage(
"strong branching up on x%d (%g) with %d iterations\n", col, psol, itlim);
2973 spx->changeLower(col, newlb);
2974 assert(spx->lower(col) <= spx->upper(col));
2976 spx->setIterationLimit(itlim);
2979 #ifdef WITH_LPSCHECK
2980 spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2982 status = spx->solve();
2986 case SPxSolver::OPTIMAL:
2991 case SPxSolver::ABORT_TIME:
2992 case SPxSolver::ABORT_ITER:
2993 case SPxSolver::ABORT_CYCLING:
2996 case SPxSolver::ABORT_VALUE:
2997 case SPxSolver::INFEASIBLE:
2998 *up = spx->terminationValue();
3006 (*iter) += spx->iterations();
3008 #ifdef STRONGBRANCH_RESTOREBASIS
3010 assert( ! spx->preStrongbranchingBasisFreed() );
3011 spx->restorePreStrongbranchingBasis();
3012 fromparentbasis =
false;
3016 else if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
3018 SCIPdebugMessage(
" --> Repeat strong branching up with %d iterations after restoring basis\n", itlim - spx->iterations());
3019 assert( ! spx->hasPreStrongbranchingBasis() );
3020 spx->restorePreStrongbranchingBasis();
3021 spx->setIterationLimit(itlim - spx->iterations());
3023 fromparentbasis =
true;
3027 fromparentbasis =
false;
3030 while( fromparentbasis );
3032 spx->changeLower(col, oldlb);
3033 assert(spx->lower(col) <= spx->upper(col));
3035 else if( up !=
NULL )
3037 *up = spx->terminationValue();
3045 spx->setIterationLimit(oldItlim);
3049 SCIPdebugMessage(
"SCIPlpiStrongbranch() returned SoPlex status %d\n",
int(status));
3074 retcode =
lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3104 assert( iter !=
NULL );
3105 assert( cols !=
NULL );
3106 assert( psols !=
NULL );
3107 assert( down !=
NULL );
3108 assert( up !=
NULL );
3109 assert( downvalid !=
NULL );
3110 assert( upvalid !=
NULL );
3111 assert( down !=
NULL );
3116 for (
int j = 0; j < ncols; ++j)
3119 retcode =
lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3149 retcode =
lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3179 assert( iter !=
NULL );
3180 assert( cols !=
NULL );
3181 assert( psols !=
NULL );
3182 assert( down !=
NULL );
3183 assert( up !=
NULL );
3184 assert( downvalid !=
NULL );
3185 assert( upvalid !=
NULL );
3186 assert( down !=
NULL );
3191 for (
int j = 0; j < ncols; ++j)
3194 retcode =
lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3223 assert(lpi !=
NULL);
3237 assert(lpi !=
NULL);
3238 assert(primalfeasible !=
NULL);
3239 assert(dualfeasible !=
NULL);
3256 assert(lpi !=
NULL);
3259 return (lpi->
spx->getStatus() == SPxSolver::UNBOUNDED);
3271 assert(lpi !=
NULL);
3274 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3275 return (lpi->
spx->getStatus() == SPxSolver::UNBOUNDED);
3288 assert(lpi !=
NULL);
3291 assert(lpi->
spx->getStatus() != SPxSolver::UNBOUNDED || lpi->
spx->basis().status() == SPxBasis::UNBOUNDED);
3296 return (lpi->
spx->getStatus() == SPxSolver::UNBOUNDED && !lpi->
spx->isPerturbed());
3306 assert(lpi !=
NULL);
3309 return (lpi->
spx->getStatus() == SPxSolver::INFEASIBLE);
3317 SPxBasis::SPxStatus basestatus;
3321 assert(lpi !=
NULL);
3324 basestatus = lpi->
spx->basis().status();
3329 assert(basestatus == SPxBasis::OPTIMAL || lpi->
spx->getStatus() != SPxSolver::OPTIMAL);
3331 return basestatus == SPxBasis::OPTIMAL ||
3332 ((basestatus == SPxBasis::PRIMAL || basestatus == SPxBasis::UNBOUNDED) && !lpi->
spx->isPerturbed());
3344 assert(lpi !=
NULL);
3347 return (lpi->
spx->getStatus() == SPxSolver::INFEASIBLE);
3359 assert(lpi !=
NULL);
3362 return (lpi->
spx->getStatus() == SPxSolver::INFEASIBLE);
3372 assert(lpi !=
NULL);
3375 return (lpi->
spx->getStatus() == SPxSolver::INFEASIBLE && lpi->
spx->basis().status() == SPxBasis::DUAL
3376 && !lpi->
spx->isPerturbed());
3386 assert(lpi !=
NULL);
3389 return (lpi->
spx->getStatus() == SPxSolver::UNBOUNDED);
3399 assert(lpi !=
NULL);
3405 assert(lpi->
spx->basis().status() == SPxBasis::OPTIMAL || lpi->
spx->getStatus() != SPxSolver::OPTIMAL);
3407 return (lpi->
spx->basis().status() == SPxBasis::OPTIMAL) ||
3408 (lpi->
spx->basis().status() == SPxBasis::DUAL && !lpi->
spx->isPerturbed());
3418 assert(lpi !=
NULL);
3419 assert((lpi->
spx->basis().status() == SPxBasis::OPTIMAL)
3425 return (lpi->
spx->basis().status() == SPxBasis::OPTIMAL);
3435 assert(lpi !=
NULL);
3438 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3461 return (lpi->
spx->getStatus() != SPxSolver::ERROR && lpi->
spx->getStatus() != SPxSolver::SINGULAR);
3471 assert(lpi !=
NULL);
3474 return (lpi->
spx->getStatus() == SPxSolver::ABORT_VALUE);
3484 assert(lpi !=
NULL);
3487 return (lpi->
spx->getStatus() == SPxSolver::ABORT_ITER);
3497 assert(lpi !=
NULL);
3500 return (lpi->
spx->getStatus() == SPxSolver::ABORT_TIME);
3510 assert(lpi !=
NULL);
3513 return static_cast<int>(lpi->
spx->getStatus());
3524 assert(lpi !=
NULL);
3541 assert(lpi !=
NULL);
3543 assert(objval !=
NULL);
3545 *objval = lpi->
spx->value();
3562 assert(lpi !=
NULL);
3565 if( objval !=
NULL )
3566 *objval = lpi->
spx->value();
3570 if( primsol !=
NULL )
3572 Vector tmp(lpi->
spx->nCols(), primsol);
3573 (void)lpi->
spx->getPrimal(tmp);
3575 if( dualsol !=
NULL )
3577 Vector tmp(lpi->
spx->nRows(), dualsol);
3578 (void)lpi->
spx->getDual(tmp);
3580 if( activity !=
NULL )
3582 Vector tmp(lpi->
spx->nRows(), activity);
3583 (void)lpi->
spx->getSlacks(tmp);
3585 if( redcost !=
NULL )
3587 Vector tmp(lpi->
spx->nCols(), redcost);
3588 (void)lpi->
spx->getRedCost(tmp);
3591 catch(SPxException x)
3594 std::string s = x.what();
3611 assert(lpi !=
NULL);
3614 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3617 Vector tmp(lpi->
spx->nCols(), ray);
3618 (void)lpi->
spx->getPrimalray(tmp);
3620 catch(SPxException x)
3623 std::string s = x.what();
3631 SCIPerrorMessage(
"SCIPlpiGetPrimalRay() not supported by SoPlex versions <= 1.5.0\n");
3644 assert(lpi !=
NULL);
3649 Vector tmp(lpi->
spx->nRows(), dualfarkas);
3650 (void)lpi->
spx->getDualfarkas(tmp);
3652 catch(SPxException x)
3655 std::string s = x.what();
3672 assert(lpi !=
NULL);
3675 *iterations = lpi->
spx->iterations();
3693 assert(lpi !=
NULL);
3694 assert(quality !=
NULL);
3696 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3700 assert(lpi !=
NULL);
3701 assert(quality !=
NULL);
3703 SCIPdebugMessage(
"requesting solution quality from SoPlex: quality %d\n", qualityindicator);
3705 switch( qualityindicator )
3722 *quality = lpi->
spx->basis().condition(maxiter, tolerance);
3745 assert( spx !=
NULL );
3746 assert( val !=
NULL );
3752 if (! spx->isInitialized() )
3755 assert( 0 <= col && col < spx->nCols() );
3757 if( spx->rep() == SPxSolver::COLUMN )
3760 if (spx->getSense() == SPxLP::MINIMIZE)
3761 *val = spx->pVec()[col] - spx->maxObj()[col];
3763 *val = spx->maxObj()[col] - spx->pVec()[col];
3767 assert( spx->rep() == SPxSolver::ROW );
3773 if ( spx->getSense() == SPxLP::MINIMIZE )
3776 if ( spx->isColBasic(col) )
3779 for (
int i = spx->dim() - 1; i >= 0; --i)
3781 SPxId
id = spx->basis().baseId(i);
3782 if (
id.isSPxColId() && col == spx->number(SPxColId(
id)) )
3784 *val = sign * spx->fVec()[i];
3808 assert(lpi !=
NULL);
3811 assert( lpi->
spx->preStrongbranchingBasisFreed() );
3815 for( i = 0; i < lpi->
spx->nRows(); ++i )
3817 switch( lpi->
spx->getBasisRowStatus(i) )
3819 case SPxSolver::BASIC:
3822 case SPxSolver::FIXED:
3823 case SPxSolver::ON_LOWER:
3826 case SPxSolver::ON_UPPER:
3829 case SPxSolver::ZERO:
3830 SCIPerrorMessage(
"slack variable has basis status ZERO (should not occur)\n");
3842 for( i = 0; i < lpi->
spx->nCols(); ++i )
3845 switch( lpi->
spx->getBasisColStatus(i) )
3847 case SPxSolver::BASIC:
3850 case SPxSolver::FIXED:
3862 case SPxSolver::ON_LOWER:
3865 case SPxSolver::ON_UPPER:
3868 case SPxSolver::ZERO:
3893 assert(lpi !=
NULL);
3895 assert(cstat !=
NULL || lpi->
spx->nCols() == 0);
3896 assert(rstat !=
NULL || lpi->
spx->nRows() == 0);
3898 assert( lpi->
spx->preStrongbranchingBasisFreed() );
3901 SPxSolver::VarStatus* spxcstat =
NULL;
3902 SPxSolver::VarStatus* spxrstat =
NULL;
3906 for( i = 0; i < lpi->
spx->nRows(); ++i )
3911 spxrstat[i] = SPxSolver::ON_LOWER;
3914 spxrstat[i] = SPxSolver::BASIC;
3917 spxrstat[i] = SPxSolver::ON_UPPER;
3920 SCIPerrorMessage(
"slack variable has basis status ZERO (should not occur)\n");
3931 for( i = 0; i < lpi->
spx->nCols(); ++i )
3936 spxcstat[i] = SPxSolver::ON_LOWER;
3939 spxcstat[i] = SPxSolver::BASIC;
3942 spxcstat[i] = SPxSolver::ON_UPPER;
3945 spxcstat[i] = SPxSolver::ZERO;
3955 lpi->
spx->updateStatus();
3973 assert(lpi !=
NULL);
3976 assert( lpi->
spx->preStrongbranchingBasisFreed() );
3984 if( spx->rep() == SPxSolver::COLUMN )
3986 for(
int i = 0; i < spx->nRows(); ++i )
3988 SPxId
id = spx->basis().baseId(i);
3990 bind[i] = (
id.isSPxColId() ? spx->number(
id) : - 1 - spx->number(
id));
3998 assert( spx->rep() == SPxSolver::ROW );
4000 for(
int i = 0; i < spx->nRows(); ++i )
4002 if( !spx->isRowBasic(i) )
4006 for(
int j = 0; j < spx->nCols(); ++j )
4008 if( !spx->isColBasic(j) )
4012 assert(k == spx->nRows());
4025 SCIPdebugMessage(
"Preparing factorization for computation of basis inverse.\n");
4032 SPxSolver* spx = lpi->
spx;
4035 DataArray <const SVector*> matrix(spx->nRows());
4038 for (
int i = 0; i < spx->nRows(); ++i)
4040 if ( ! spx->isRowBasic(i) )
4041 matrix[k++] =
new UnitVector(i);
4043 for (
int j = 0; j < spx->nCols(); ++j)
4045 if ( ! spx->isColBasic(j) )
4046 matrix[k++] = &spx->colVector(j);
4048 assert( k == spx->nRows() );
4049 assert( k == matrix.size() );
4054 SLinSolver::Status status = lpi->
factorization->load(matrix.get_ptr(), k);
4058 assert( status == SLinSolver::OK );
4063 for (
int i = 0; i < spx->nRows(); ++i)
4065 if ( ! spx->isRowBasic(i) )
4070 catch(SPxException x)
4073 std::string s = x.what();
4092 assert( lpi !=
NULL );
4094 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4097 assert(r < lpi->spx->nRows());
4101 SPxSolver* spx = lpi->
spx;
4103 Vector x(spx->nRows(), coef);
4106 if ( spx->rep() == SPxSolver::COLUMN )
4108 DVector e(spx->nRows());
4115 spx->basis().coSolve(x, e);
4119 assert(spx->rep() == SPxSolver::ROW);
4122 DVector e(spx->nRows());
4137 DSVector rhs(spx->nCols());
4138 SSVector y(spx->nCols());
4157 assert(index < spx->nRows());
4158 assert(!spx->isRowBasic(index));
4161 rhs = spx->rowVector(index);
4168 assert(index < spx->nCols());
4169 assert(!spx->isColBasic(index));
4172 rhs = spx->unitVector(index);
4176 spx->basis().solve(y, rhs);
4182 for(
int i = 0; i < spx->nCols(); ++i )
4184 SPxId
id = spx->basis().baseId(i);
4186 if(
id.isSPxRowId() )
4188 assert(spx->number(
id) >= 0);
4189 assert(spx->number(
id) < spx->nRows());
4190 assert(bind[r] >= 0 || spx->number(
id) != index);
4192 x[spx->number(
id)] = y[i];
4199 assert(x[index] == 0.0);
4208 catch(SPxException x)
4211 std::string s = x.what();
4230 assert(lpi !=
NULL);
4232 assert(lpi->
spx->preStrongbranchingBasisFreed());
4233 assert(rhs !=
NULL);
4234 assert(coef !=
NULL);
4238 SPxSolver* spx = lpi->
spx;
4239 Vector v(spx->nRows(), rhs);
4240 Vector x(spx->nRows(), coef);
4243 if( spx->rep() == SPxSolver::COLUMN )
4246 spx->basis().solve(x, v);
4250 assert(spx->rep() == SPxSolver::ROW);
4261 DSVector rowrhs(spx->nCols());
4262 SSVector y(spx->nCols());
4271 for(
int i = 0; i < spx->nCols(); ++i )
4273 SPxId
id = spx->basis().baseId(i);
4275 if(
id.isSPxRowId() )
4277 assert(spx->number(
id) >= 0);
4278 assert(spx->number(
id) < spx->nRows());
4280 rowrhs.add(i, v[spx->number(
id)]);
4284 assert(rowrhs[i] == 0.0);
4289 spx->basis().coSolve(y, rowrhs);
4292 for(
int i = 0; i < spx->nRows(); ++i )
4304 assert(index < spx->nRows());
4305 assert(!spx->isRowBasic(index));
4307 x[i] = v[index] - (spx->rowVector(index) * Vector(spx->nCols(), y.get_ptr()));
4313 assert(index < spx->nCols());
4314 assert(!spx->isColBasic(index));
4325 catch(SPxException x)
4328 std::string s = x.what();
4350 assert( lpi !=
NULL );
4352 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4355 DVector e(lpi->
spx->nRows());
4360 assert(c < lpi->spx->nRows());
4385 assert(lpi !=
NULL);
4387 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4389 nrows = lpi->
spx->nRows();
4390 ncols = lpi->
spx->nCols();
4394 if( binvrow ==
NULL )
4403 assert(binv !=
NULL);
4406 soplex::Vector binvvec(nrows, binv);
4407 for( c = 0; c < ncols; ++c )
4408 coef[c] = binvvec * lpi->
spx->colVector(c);
4423 DVector col(lpi->
spx->nRows());
4427 assert( lpi !=
NULL );
4429 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4433 assert(c < lpi->spx->nCols());
4436 col = lpi->
spx->colVector(c);
4437 col.reDim(lpi->
spx->nRows());
4469 assert(blkmem !=
NULL);
4470 assert(lpi !=
NULL);
4472 assert(lpistate !=
NULL);
4474 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4476 ncols = lpi->
spx->nCols();
4477 nrows = lpi->
spx->nRows();
4492 (*lpistate)->ncols = ncols;
4493 (*lpistate)->nrows = nrows;
4514 assert(lpi !=
NULL);
4516 assert(lpistate !=
NULL);
4518 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4520 lpncols = lpi->
spx->nCols();
4521 lpnrows = lpi->
spx->nRows();
4522 assert(lpistate->
ncols <= lpncols);
4523 assert(lpistate->
nrows <= lpnrows);
4533 for( i = lpistate->
ncols; i < lpncols; ++i )
4539 bnd = lpi->
spx->lower(i);
4548 for( i = lpistate->
nrows; i < lpnrows; ++i )
4564 assert(lpi !=
NULL);
4571 catch(SPxException x)
4574 std::string s = x.what();
4577 assert( lpi->
spx->getStatus() != SPxSolver::OPTIMAL );
4593 assert(lpi !=
NULL);
4594 assert(lpistate !=
NULL);
4596 if ( *lpistate !=
NULL )
4619 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4635 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4667 assert(lpinorms !=
NULL);
4683 assert(lpinorms ==
NULL);
4696 assert(lpinorms ==
NULL);
4723 assert(lpi !=
NULL);
4725 assert(ival !=
NULL);
4730 *ival = lpi->
spx->getFromScratch();
4733 *ival = lpi->
spx->getLpInfo();
4736 *ival = lpi->
spx->getIterationLimit();
4739 *ival = lpi->
spx->getPresolving();
4745 *ival = lpi->
spx->getScaling();
4763 assert(lpi !=
NULL);
4770 lpi->
spx->setFromScratch(
bool(ival));
4774 lpi->
spx->setLpInfo(
bool(ival));
4778 lpi->
spx->setIterationLimit(ival);
4782 lpi->
spx->setPresolving(
bool(ival));
4790 lpi->
spx->setAutoPricer();
4793 lpi->
spx->setFullPricer();
4796 lpi->
spx->setParmultPricer();
4799 lpi->
spx->setSteepPricer();
4802 lpi->
spx->setSteepQStartPricer();
4805 lpi->
spx->setDevexPricer();
4813 lpi->
spx->setScaling(
bool(ival));
4831 assert(lpi !=
NULL);
4833 assert(dval !=
NULL);
4838 *dval = lpi->
spx->feastol();
4840 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
4842 *dval = lpi->
spx->opttol();
4846 *dval = lpi->
spx->getObjLoLimit();
4849 *dval = lpi->
spx->getObjUpLimit();
4852 *dval = lpi->
spx->terminationTime();
4876 assert(lpi !=
NULL);
4882 lpi->
spx->setFeastol(dval);
4884 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
4886 lpi->
spx->setOpttol(dval);
4890 lpi->
spx->setObjLoLimit(dval);
4893 lpi->
spx->setObjUpLimit(dval);
4896 lpi->
spx->setTerminationTime(dval);
4899 assert(dval >= -1.5);
4932 return soplex::infinity;
4943 return (val >= soplex::infinity);
4961 const char* filename
4966 f = fopen(filename,
"r");
4983 assert(lpi !=
NULL);
4986 assert( lpi->
spx->preStrongbranchingBasisFreed() );
4993 if( !lpi->
spx->readLP(fname) )
4996 catch(SPxException x)
4999 std::string s = x.what();
5016 assert(lpi !=
NULL);
5021 lpi->
spx->writeFile(fname);
5023 catch(SPxException x)
5026 std::string s = x.what();