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 #define WITH_BOUNDFLIPPING
106 #ifdef WITH_BOUNDFLIPPING
107 #include "spxboundflippingrt.h"
117 #define SOPLEX_VERBLEVEL 5
130 using namespace soplex;
138 #define SOPLEX_TRY(messagehdlr, x) do \
144 catch( const SPxException& E ) \
146 std::string s = E.what(); \
147 SCIPmessagePrintWarning((messagehdlr), "SoPlex threw an exception: %s\n", s.c_str()); \
148 return SCIP_LPERROR; \
154 #define SOPLEX_TRY(messagehdlr, x) do \
160 catch( const SPxException& E ) \
162 return SCIP_LPERROR; \
171 #define SOPLEX_TRY_ABORT(x) do \
177 catch( const SPxException& E ) \
179 std::string s = E.what(); \
180 SCIPerrorMessage("SoPlex threw an exception: %s\n", s.c_str()); \
189 class SPxSCIP :
public SPxSolver
191 SPxLP::SPxSense m_sense;
193 SPxSteepPR m_price_steep;
194 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 6) || SOPLEX_VERSION > 160)
195 SPxSteepExPR m_price_steep_ex;
197 SPxSteepPR m_price_steep_ex;
199 SPxParMultPR m_price_parmult;
200 SPxDevexPR m_price_devex;
201 #ifdef WITH_BOUNDFLIPPING
202 SPxBoundFlippingRT m_ratio;
219 SPxSolver::VarStatus* m_rowstat;
220 SPxSolver::VarStatus* m_colstat;
224 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
239 const char* probname =
NULL
241 : SPxSolver(LEAVE, COLUMN),
243 m_fromscratch(
false),
246 m_objLoLimit(-soplex::infinity),
247 m_objUpLimit(soplex::infinity),
257 m_messagehdlr(messagehdlr)
259 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
260 setOutstream(m_spxout);
263 setSense(SPxLP::MINIMIZE);
266 setPricer(&m_price_steep);
269 if ( probname !=
NULL )
272 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
273 m_lpifeastol = SPxSolver::feastol();
274 m_lpiopttol = SPxSolver::opttol();
276 m_lpifeastol = SPxSolver::delta();
277 m_lpiopttol = SPxSolver::delta();
282 m_cpxenv = CPXopenCPLEX(&cpxstat);
283 assert(m_cpxenv !=
NULL);
284 m_cpxlp = CPXcreateprob(m_cpxenv, &cpxstat, probname !=
NULL ? probname :
"spxcheck");
285 (void) CPXsetintparam(m_cpxenv, CPX_PARAM_SCRIND, 0);
287 m_doublecheck =
false;
293 if( m_probname !=
NULL )
294 spx_free(m_probname);
296 freePreStrongbranchingBasis();
298 if( m_rownames !=
NULL )
300 m_rownames->~NameSet();
301 spx_free(m_rownames);
303 if( m_colnames !=
NULL )
305 m_colnames->~NameSet();
306 spx_free(m_colnames);
308 if( m_colstat !=
NULL )
310 if( m_rowstat !=
NULL )
314 (void) CPXfreeprob(m_cpxenv, &m_cpxlp);
315 (void) CPXcloseCPLEX(&m_cpxenv);
332 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
333 SPxSolver::setFeastol(d);
335 SPxSolver::setDelta(d);
352 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
353 SPxSolver::setOpttol(d);
355 SPxSolver::setDelta(d);
359 bool isPerturbed()
const
362 return (shift() >= 10.0 * epsilon());
366 void setIterationLimit(
375 setPricer(&m_price_devex);
376 m_autopricing =
true;
381 setPricer(&m_price_steep);
382 m_autopricing =
false;
385 void setSteepPricer()
387 setPricer(&m_price_steep_ex);
388 m_autopricing =
false;
391 void setSteepQStartPricer()
393 setPricer(&m_price_steep);
394 m_autopricing =
false;
397 void setParmultPricer()
399 setPricer(&m_price_parmult);
400 m_autopricing =
false;
403 void setDevexPricer()
405 setPricer(&m_price_devex);
406 m_autopricing =
false;
410 int getIterationLimit()
const
415 bool getFromScratch()
const
417 return m_fromscratch;
420 void setFromScratch(
bool fs)
425 bool getScaling()
const
430 void setScaling(
bool s)
435 bool getPresolving()
const
440 void setPresolving(
bool p)
445 bool getLpInfo()
const
450 void setLpInfo(
bool li)
455 SPxLP::SPxSense getSense()
const
457 assert(m_sense == sense());
462 void setSense(
const SPxLP::SPxSense sen)
464 assert(m_sense == sense());
472 if( m_sense == SPxLP::MINIMIZE && getObjUpLimit() < soplex::infinity )
475 SPxSolver::setTerminationValue(getObjUpLimit());
477 else if( m_sense == SPxLP::MAXIMIZE && getObjLoLimit() > -soplex::infinity )
480 SPxSolver::setTerminationValue(getObjLoLimit());
485 void setProbname(
const char* probname)
489 assert(probname !=
NULL);
490 if( m_probname !=
NULL )
491 spx_free(m_probname);
492 len = (int) strlen(probname);
493 spx_alloc(m_probname, len + 1);
494 strncpy(m_probname, probname, len);
495 m_probname[len] =
'\0';
498 Real getObjLoLimit()
const
503 void setObjLoLimit(Real limit)
505 if( getSense() == SPxLP::MAXIMIZE )
507 SCIPdebugMessage(
"setting termination value from <%g> to <%g>\n", m_objLoLimit, limit);
508 SPxSolver::setTerminationValue(limit);
510 m_objLoLimit = limit;
513 Real getObjUpLimit()
const
518 void setObjUpLimit(Real limit)
520 if( getSense() == SPxLP::MINIMIZE )
522 SCIPdebugMessage(
"setting termination value from <%g> to <%g>\n", m_objUpLimit, limit);
523 SPxSolver::setTerminationValue(limit);
525 m_objUpLimit = limit;
528 void setRep(SPxSolver::Representation p_rep)
532 SCIPdebugMessage(
"switching to %s representation of the basis\n", p_rep == SPxSolver::ROW ?
"row" :
"column");
533 SPxSolver::setRep(p_rep);
538 bool getDoubleCheck()
541 return m_doublecheck && m_checknum + 1 >= CHECK_START;
544 void setDoubleCheck(
bool dc)
549 const char* spxStatusString(
const SPxSolver::Status stat)
553 case SPxSolver::ABORT_TIME:
555 case SPxSolver::ABORT_ITER:
557 case SPxSolver::ABORT_VALUE:
558 return "ABORT_VALUE";
559 case SPxSolver::SINGULAR:
561 case SPxSolver::REGULAR:
563 case SPxSolver::UNKNOWN:
565 case SPxSolver::OPTIMAL:
567 case SPxSolver::UNBOUNDED:
569 case SPxSolver::INFEASIBLE:
578 const char* cpxStatusString(
const int stat)
582 case CPX_STAT_ABORT_TIME_LIM:
584 case CPX_STAT_ABORT_IT_LIM:
586 case CPX_STAT_ABORT_OBJ_LIM:
587 return "ABORT_VALUE";
588 case CPX_STAT_OPTIMAL:
590 case CPX_STAT_OPTIMAL_INFEAS:
591 return "CPX_STAT_OPTIMAL_INFEAS: OPT SOL INFEASIBLE AFTER UNSCALING";
592 case CPX_STAT_UNBOUNDED:
594 case CPX_STAT_INFEASIBLE:
596 case CPX_STAT_INForUNBD:
597 return "INFEASIBLE or UNBOUNDED";
598 case CPX_STAT_NUM_BEST:
599 return "CPX_STAT_NUM_BEST: SOL AVAILABLE BUT NOT PROVEN OPTIMAL DUE TO NUM TROUBLE";
609 bool checkConsistentBounds()
const
611 for(
int i = 0; i < nCols(); ++i )
613 if( lower(i) > upper(i) )
615 SCIPerrorMessage(
"inconsistent bounds on column %d: lower=%.17g, upper=%.17g\n",
616 i, lower(i), upper(i));
624 bool checkConsistentSides()
const
626 for(
int i = 0; i < nRows(); ++i )
628 if( lhs(i) > rhs(i) )
640 void trySolve(
bool printwarning =
true)
646 m_stat = SPxSolver::solve();
648 catch(
const SPxException& x )
650 std::string s = x.what();
655 m_stat = SPxSolver::status();
661 assert( m_stat != SPxSolver::OPTIMAL );
665 m_itused += SPxSolver::iterations();
666 assert(m_itlim < 0 || m_itused <= m_itlim);
669 timespent = SPxSolver::time();
673 timelimit = SPxSolver::terminationTime();
674 if( timelimit > timespent )
675 timelimit -= timespent;
679 assert(timelimit >= 0);
680 SPxSolver::setTerminationTime(timelimit);
684 void doSolve(
bool printwarning =
true)
687 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
688 SPxOut::Verbosity verbosity;
689 verbosity = m_spxout.getVerbosity();
690 m_spxout.setVerbosity(getLpInfo() ? (SPxOut::Verbosity)
SOPLEX_VERBLEVEL : (SPxOut::Verbosity) 0);
693 verbosity = Param::verbose();
697 assert(checkConsistentBounds());
698 assert(checkConsistentSides());
702 if( getDoubleCheck() )
707 setTerminationIter(m_autopricing && (m_itlim < 0 || m_itlim - m_itused >
AUTOPRICING_ITERSWITCH) ? AUTOPRICING_ITERSWITCH : m_itlim - m_itused);
709 trySolve(printwarning);
711 if( m_autopricing && m_stat == SPxSolver::ABORT_ITER && (m_itlim < 0 || m_itlim - m_itused > 0) )
713 setTerminationIter(m_itlim - m_itused);
714 setPricer(&m_price_steep_ex);
716 trySolve(printwarning);
718 setPricer(&m_price_devex);
722 setTerminationIter(m_itlim);
724 if( m_stat == OPTIMAL )
726 Real objval = value();
728 if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
729 m_stat = ABORT_VALUE;
734 if( getDoubleCheck() && (m_stat == SPxSolver::OPTIMAL || m_stat == SPxSolver::UNBOUNDED || m_stat == SPxSolver::INFEASIBLE || m_stat == SPxSolver::ABORT_VALUE) )
740 CPX_CALL( CPXreadcopyprob(m_cpxenv, m_cpxlp,
"spxcheck.mps",
NULL) );
741 CPX_CALL( CPXreadcopybase(m_cpxenv, m_cpxlp,
"spxcheck.bas") );
744 CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPOPT,
MAX(opttol(), 1e-9)) );
745 CPX_CALL( CPXsetdblparam(m_cpxenv, CPX_PARAM_EPRHS,
MAX(feastol(), 1e-9)) );
748 CPX_CALL( CPXlpopt(m_cpxenv, m_cpxlp) );
751 CPX_CALL( CPXsolution(m_cpxenv, m_cpxlp, &cpxstat, &cpxobj,
NULL,
NULL,
NULL,
NULL) );
752 if( getSense() == SPxLP::MAXIMIZE )
756 if( cpxstat == CPX_STAT_OPTIMAL_INFEAS )
758 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s)\n",
759 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat));
760 if( EXIT_AT_CPXERROR )
763 else if( (m_stat == SPxSolver::OPTIMAL && cpxstat != CPX_STAT_OPTIMAL)
764 || (m_stat == SPxSolver::UNBOUNDED && cpxstat != CPX_STAT_UNBOUNDED)
765 || (m_stat == SPxSolver::INFEASIBLE && cpxstat != CPX_STAT_INFEASIBLE) )
767 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
768 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
769 if( EXIT_AT_WRONG_RESULT )
772 else if( m_stat == SPxSolver::ABORT_VALUE )
776 case CPX_STAT_OPTIMAL:
777 if( (getSense() == SPxSolver::MINIMIZE && LTrel(cpxobj, getObjUpLimit(), 2*opttol()))
778 || (getSense() == SPxSolver::MAXIMIZE && GTrel(cpxobj, getObjLoLimit(), 2*opttol())) )
780 SCIPerrorMessage(
"In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
781 m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ?
"<" :
">",
782 getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
783 if( EXIT_AT_WRONG_RESULT )
786 else if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
787 || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
789 SCIPerrorMessage(
"In %s: SoPlex returned status=%d (%s) while CPLEX claims obj=%.10f %s %.10f=obj.limit (%s) (checknum=%d)\n",
790 m_probname, m_stat, spxStatusString(m_stat), cpxobj, getSense() == SPxSolver::MINIMIZE ?
"<" :
">",
791 getSense() == SPxSolver::MINIMIZE ? getObjUpLimit() : getObjLoLimit(), cpxStatusString(cpxstat), m_checknum);
794 case CPX_STAT_OPTIMAL_INFEAS:
795 case CPX_STAT_NUM_BEST:
796 if( (getSense() == SPxSolver::MINIMIZE && cpxobj < getObjUpLimit())
797 || (getSense() == SPxSolver::MAXIMIZE && cpxobj > getObjLoLimit()) )
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);
804 case CPX_STAT_INFEASIBLE:
806 case CPX_STAT_UNBOUNDED:
807 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
808 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
809 if( EXIT_AT_WRONG_RESULT )
812 case CPX_STAT_INForUNBD:
814 SCIPerrorMessage(
"In %s: SoPlex status=%d (%s) while CPLEX status=%d (%s) (checknum=%d)\n",
815 m_probname, m_stat, spxStatusString(m_stat), cpxstat, cpxStatusString(cpxstat), m_checknum);
820 else if( m_stat == SPxSolver::OPTIMAL )
822 if( (getSense() == SPxSolver::MINIMIZE && LTrel(value(), cpxobj, 2*opttol()))
823 || (getSense() == SPxSolver::MAXIMIZE && GTrel(value(), cpxobj, 2*opttol())) )
828 else if( (getSense() == SPxSolver::MINIMIZE && GTrel(value(), cpxobj, 2*opttol()))
829 || (getSense() == SPxSolver::MAXIMIZE && LTrel(value(), cpxobj, 2*opttol())) )
831 SCIPerrorMessage(
"In %s: LP optimal; SoPlex value=%.10f %s CPLEX value=%.10f suboptimal (checknum=%d)\n", value(),
832 m_probname, getSense() == SPxSolver::MINIMIZE ?
">" :
"<", cpxobj, m_checknum);
833 if( EXIT_AT_WRONG_RESULT )
843 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
844 m_spxout.setVerbosity(verbosity);
846 Param::setVerbose(verbosity);
851 virtual Status solve()
853 assert(m_sense == sense());
854 SPxEquiliSC* scaler =
NULL;
855 SPxMainSM* simplifier =
NULL;
857 SPxSimplifier::Result result = SPxSimplifier::OKAY;
860 if ( getFromScratch() )
866 catch(
const SPxException& x )
868 std::string s = x.what();
870 m_stat = SPxSolver::status();
871 assert( m_stat != SPxSolver::OPTIMAL );
875 assert(!getFromScratch() || getBasisStatus() == SPxBasis::NO_PROBLEM);
878 if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && getScaling() && nCols() > 0 && nRows() > 0 )
880 spx_alloc(scaler, 1);
881 scaler =
new (scaler) SPxEquiliSC();
882 assert(scaler !=
NULL);
883 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
884 scaler->setOutstream(m_spxout);
888 if( SPxSolver::getBasisStatus() == SPxBasis::NO_PROBLEM && getPresolving() && nCols() > 0 && nRows() > 0 )
890 spx_alloc(simplifier, 1);
891 simplifier =
new (simplifier) SPxMainSM();
892 assert(simplifier !=
NULL);
896 if( scaler !=
NULL || simplifier !=
NULL )
897 origlp = SPxLP(*
this);
904 scaler->scale(*
this);
907 if( simplifier !=
NULL )
910 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
911 SPxOut::Verbosity verbosity;
912 verbosity = m_spxout.getVerbosity();
913 m_spxout.setVerbosity(getLpInfo() ? (SPxOut::Verbosity)
SOPLEX_VERBLEVEL : (SPxOut::Verbosity) 0);
916 verbosity = Param::verbose();
920 #ifdef WITH_BOUNDFLIPPING
921 result = simplifier->simplify(*
this, epsilon(), feastol(), opttol(),
true);
923 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
924 result = simplifier->simplify(*
this, epsilon(), feastol(), opttol());
926 result = simplifier->simplify(*
this, epsilon(), delta());
929 SCIPdebugMessage(
"simplifier ended with status %u (0: OKAY, 1: INFEASIBLE, 2: DUAL_INFEASIBLE, 3: UNBOUNDED, 4: VANISHED)\n", result);
932 if( result == SPxSimplifier::INFEASIBLE || result == SPxSimplifier::DUAL_INFEASIBLE )
934 SCIPdebugMessage(
"simplifier detected primal or dual infeasibility - reloading and solving unsimplified LP\n");
936 simplifier->~SPxMainSM();
937 spx_free(simplifier);
939 SPxSolver::loadLP(origlp);
945 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 201)
946 m_spxout.setVerbosity(verbosity);
948 Param::setVerbose(verbosity);
954 if( result != SPxSimplifier::VANISHED )
957 Real objlolimit = getObjLoLimit();
958 Real objuplimit = getObjUpLimit();
960 if( simplifier !=
NULL || scaler !=
NULL )
962 setObjLoLimit(-soplex::infinity);
963 setObjUpLimit(soplex::infinity);
972 if( simplifier !=
NULL || scaler !=
NULL )
974 setObjLoLimit(objlolimit);
975 setObjUpLimit(objuplimit);
980 if( m_stat != SPxSolver::OPTIMAL && simplifier !=
NULL )
982 SCIPdebugMessage(
"presolved LP not optimal - reloading and solving original LP\n");
984 simplifier->~SPxMainSM();
985 spx_free(simplifier);
987 SPxSolver::loadLP(origlp);
994 if( scaler !=
NULL || simplifier !=
NULL )
996 SPxSolver::VarStatus* cstat =
NULL;
997 SPxSolver::VarStatus* rstat =
NULL;
1000 if( (simplifier ==
NULL || result != SPxSimplifier::VANISHED) && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
1003 spx_alloc(rstat, nRows());
1004 spx_alloc(cstat, nCols());
1005 (void) SPxSolver::getBasis(rstat, cstat);
1009 if( simplifier !=
NULL && SPxSolver::getBasisStatus() >= SPxBasis::REGULAR )
1011 assert((result == SPxSimplifier::VANISHED) == (cstat ==
NULL));
1012 assert((result == SPxSimplifier::VANISHED) == (rstat ==
NULL));
1015 int ncols = result == SPxSimplifier::VANISHED ? 0 : nCols();
1016 int nrows = result == SPxSimplifier::VANISHED ? 0 : nRows();
1019 DVector primals(ncols);
1020 DVector duals(nrows);
1021 DVector slacks(nrows);
1022 DVector redcosts(ncols);
1023 if( result != SPxSimplifier::VANISHED )
1025 (void) SPxSolver::getPrimal(primals);
1026 (void) SPxSolver::getDual(duals);
1027 (void) SPxSolver::getSlacks(slacks);
1028 (void) SPxSolver::getRedCost(redcosts);
1035 simplifier->unsimplify(primals, duals, slacks, redcosts, rstat, cstat);
1037 catch(
const SPxException& x )
1039 std::string s = x.what();
1040 SCIPmessagePrintWarning(m_messagehdlr,
"SoPlex unsimplification unsuccessful; solving again without LP presolving (SoPlex says %s)\n",
1049 if( simplifier->isUnsimplified() )
1054 spx_alloc(rstat, origlp.nRows());
1055 spx_alloc(cstat, origlp.nCols());
1056 simplifier->getBasis(rstat, cstat);
1062 SPxSolver::loadLP(origlp);
1066 if( rstat !=
NULL && cstat !=
NULL )
1069 SPxSolver::setBasis(rstat, cstat);
1084 if( scaler !=
NULL )
1086 scaler->~SPxEquiliSC();
1089 if( simplifier !=
NULL )
1091 simplifier->~SPxMainSM();
1092 spx_free(simplifier);
1096 if( m_stat == OPTIMAL )
1098 Real objval = value();
1100 if( (objval > m_objUpLimit) || (objval < m_objLoLimit) )
1101 m_stat = ABORT_VALUE;
1108 void savePreStrongbranchingBasis()
1110 assert(m_rowstat ==
NULL);
1111 assert(m_colstat ==
NULL);
1113 spx_alloc(m_rowstat, nRows());
1114 spx_alloc(m_colstat, nCols());
1118 m_stat = getBasis(m_rowstat, m_colstat);
1120 catch(
const SPxException& x )
1123 std::string s = x.what();
1130 assert(m_stat != SPxSolver::OPTIMAL);
1136 void restorePreStrongbranchingBasis()
1138 assert(m_rowstat !=
NULL);
1139 assert(m_colstat !=
NULL);
1143 setBasis(m_rowstat, m_colstat);
1145 catch(
const SPxException& x )
1148 std::string s = x.what();
1151 m_stat = SPxSolver::status();
1157 assert(m_stat != SPxSolver::OPTIMAL);
1162 void freePreStrongbranchingBasis()
1164 if( m_rowstat !=
NULL )
1165 spx_free(m_rowstat);
1166 if( m_colstat !=
NULL )
1167 spx_free(m_colstat);
1171 bool preStrongbranchingBasisFreed()
const
1173 return ((m_rowstat ==
NULL ) && (m_colstat ==
NULL));
1176 Status getStatus()
const
1181 Status updateStatus()
1183 m_stat = SPxSolver::status();
1187 bool isInitialized()
const
1189 return SPxSolver::isInitialized();
1192 int iterations()
const
1197 virtual void clear()
1200 freePreStrongbranchingBasis();
1201 m_stat = NO_PROBLEM;
1205 bool readLP(
const char* fname)
1209 if ( m_rownames != 0 )
1210 m_rownames->~NameSet();
1212 spx_alloc(m_colnames, 1);
1214 if ( m_colnames != 0 )
1215 m_colnames->~NameSet();
1217 spx_alloc(m_rownames, 1);
1219 m_rownames =
new (m_rownames) NameSet();
1220 m_colnames =
new (m_colnames) NameSet();
1222 if( SPxSolver::readFile(fname, m_rownames, m_colnames) )
1224 m_stat = NO_PROBLEM;
1238 int namestoragesize,
1242 assert( m_colnames !=
NULL );
1245 if ( namestoragesize == 0 )
1248 *storageleft = -m_colnames->memSize();
1252 NameSet* names = m_colnames;
1253 assert( names != 0 );
1254 int sizeleft = namestoragesize;
1255 char* s = namestorage;
1256 for (
int j = firstcol; j <= lastcol; ++j)
1258 const char* t = (*names)[j];
1259 colnames[j-firstcol] = s;
1260 while( *t !=
'\0' && sizeleft >= 0 )
1267 if ( sizeleft == 0 )
1269 *storageleft = namestoragesize - m_colnames->memSize();
1270 assert( *storageleft <= 0 );
1273 *storageleft = sizeleft;
1283 int namestoragesize,
1287 assert( m_rownames !=
NULL );
1290 if ( namestoragesize == 0 )
1293 *storageleft = -m_rownames->memSize();
1297 NameSet* names = m_rownames;
1298 assert( names != 0 );
1299 int sizeleft = namestoragesize;
1300 char* s = namestorage;
1301 for (
int i = firstrow; i <= lastrow; ++i)
1303 const char* t = (*names)[i];
1304 rownames[i-firstrow] = s;
1305 while( *t !=
'\0' && sizeleft >= 0 )
1312 if ( sizeleft == 0 )
1314 *storageleft = m_rownames->memSize() - namestoragesize;
1315 assert( *storageleft <= 0 );
1318 *storageleft = sizeleft;
1331 #include "scip/bitencode.h"
1334 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
1336 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
1350 SLUFactor* factorization;
1358 struct SCIP_LPiState
1386 assert(lpi !=
NULL);
1388 if( num > lpi->cstatsize )
1392 newsize =
MAX(2*lpi->cstatsize, num);
1393 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
1394 lpi->cstatsize = newsize;
1396 assert(num <= lpi->cstatsize);
1408 assert(lpi !=
NULL);
1410 if( num > lpi->rstatsize )
1414 newsize =
MAX(2*lpi->rstatsize, num);
1415 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
1416 lpi->rstatsize = newsize;
1418 assert(num <= lpi->rstatsize);
1456 assert(lpistate !=
NULL);
1457 assert(lpistate->packcstat !=
NULL);
1458 assert(lpistate->packrstat !=
NULL);
1460 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
1461 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
1466 void lpistateUnpack(
1472 assert(lpistate !=
NULL);
1473 assert(lpistate->packcstat !=
NULL);
1474 assert(lpistate->packrstat !=
NULL);
1476 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
1477 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
1489 assert(lpistate !=
NULL);
1490 assert(blkmem !=
NULL);
1494 int nColPackets = colpacketNum(ncols);
1495 int nRowPackets = rowpacketNum(nrows);
1497 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
1498 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets) );
1499 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets) );
1511 assert(blkmem !=
NULL);
1512 assert(lpistate !=
NULL);
1513 assert(*lpistate !=
NULL);
1515 int nColPackets = colpacketNum((*lpistate)->ncols);
1516 int nRowPackets = rowpacketNum((*lpistate)->nrows);
1518 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, nColPackets);
1519 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, nRowPackets);
1520 BMSfreeBlockMemory(blkmem, lpistate);
1532 SPxLP::SPxSense spxObjsen(
1539 return SPxLP::MAXIMIZE;
1541 return SPxLP::MINIMIZE;
1545 return SPxLP::MINIMIZE;
1551 void invalidateSolution(
SCIP_LPI* lpi)
1553 assert(lpi !=
NULL);
1554 lpi->solved =
FALSE;
1555 if ( lpi->factorization != 0 )
1557 delete lpi->factorization;
1558 lpi->factorization = 0;
1573 static char spxname[100];
1574 static char spxdesc[200];
1586 #if (SOPLEX_SUBVERSION > 0)
1587 sprintf(spxname,
"SoPlex %d.%d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10,
SOPLEX_SUBVERSION);
1589 sprintf(spxname,
"SoPlex %d.%d.%d", SOPLEX_VERSION/100, (SOPLEX_VERSION % 100)/10, SOPLEX_VERSION % 10);
1599 sprintf(spxdesc,
"%s",
"Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de)");
1600 #if (SOPLEX_VERSION >= 160)
1601 sprintf(spxdesc,
"%s [GitHash: %s]", spxdesc, getGitHash());
1603 #ifdef WITH_LPSCHECK
1604 sprintf(spxdesc,
"%s %s", spxdesc,
"- including CPLEX double check");
1614 return (
void*) lpi->spx;
1636 assert(lpi !=
NULL);
1642 (*lpi)->spx =
static_cast<SPxSCIP*
>(BMSallocMemoryCPP(
sizeof(SPxSCIP)));
1643 SOPLEX_TRY( messagehdlr, (*lpi)->spx = new ((*lpi)->spx) SPxSCIP(messagehdlr, name) );
1644 (*lpi)->cstat =
NULL;
1645 (*lpi)->rstat =
NULL;
1646 (*lpi)->cstatsize = 0;
1647 (*lpi)->rstatsize = 0;
1649 (*lpi)->factorization = 0;
1651 (*lpi)->conditionlimit = -1.0;
1652 (*lpi)->checkcondition =
FALSE;
1653 (*lpi)->messagehdlr = messagehdlr;
1655 invalidateSolution(*lpi);
1671 assert(lpi !=
NULL);
1672 assert(*lpi !=
NULL);
1673 assert((*lpi)->spx !=
NULL);
1676 (*lpi)->spx->~SPxSCIP();
1677 BMSfreeMemory(&((*lpi)->spx));
1680 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1681 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1720 assert(lpi !=
NULL);
1721 assert(lpi->spx !=
NULL);
1722 assert(lhs !=
NULL);
1723 assert(rhs !=
NULL);
1725 invalidateSolution(lpi);
1726 assert( lpi->spx->preStrongbranchingBasisFreed() );
1730 SPxSCIP* spx = lpi->spx;
1731 LPRowSet rows(nrows);
1732 DSVector emptyVector(0);
1738 spx->setSense(spxObjsen(objsen));
1741 for( i = 0; i < nrows; ++i )
1742 rows.add(lhs[i], emptyVector, rhs[i]);
1748 catch(
const SPxException& x )
1751 std::string s = x.what();
1776 assert(lpi !=
NULL);
1777 assert(lpi->spx !=
NULL);
1778 assert(obj !=
NULL);
1781 assert(nnonz == 0 || beg !=
NULL);
1782 assert(nnonz == 0 || ind !=
NULL);
1783 assert(nnonz == 0 || val !=
NULL);
1785 invalidateSolution(lpi);
1787 assert( lpi->spx->preStrongbranchingBasisFreed() );
1789 SPxSCIP* spx = lpi->spx;
1792 LPColSet cols(ncols);
1793 DSVector colVector(ncols);
1799 for( i = 0; i < ncols; ++i )
1805 last = (i == ncols-1 ? nnonz : beg[i+1]);
1806 colVector.add( last-start, &ind[start], &val[start] );
1808 cols.add(obj[i], lb[i], colVector, ub[i]);
1812 catch(
const SPxException& x )
1815 std::string s = x.what();
1833 assert(lpi !=
NULL);
1834 assert(lpi->spx !=
NULL);
1835 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
1837 invalidateSolution(lpi);
1839 assert( lpi->spx->preStrongbranchingBasisFreed() );
1841 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeColRange(firstcol, lastcol) );
1859 assert(lpi !=
NULL);
1860 assert(lpi->spx !=
NULL);
1862 invalidateSolution(lpi);
1864 assert( lpi->spx->preStrongbranchingBasisFreed() );
1866 ncols = lpi->spx->nCols();
1869 for( i = 0; i < ncols; ++i )
1872 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeCols(dstat) );
1892 assert(lpi !=
NULL);
1893 assert(lpi->spx !=
NULL);
1894 assert(lhs !=
NULL);
1895 assert(rhs !=
NULL);
1896 assert(nnonz == 0 || beg !=
NULL);
1897 assert(nnonz == 0 || ind !=
NULL);
1898 assert(nnonz == 0 || val !=
NULL);
1900 invalidateSolution(lpi);
1902 assert( lpi->spx->preStrongbranchingBasisFreed() );
1906 SPxSCIP* spx = lpi->spx;
1907 LPRowSet rows(nrows);
1914 for( i = 0; i < nrows; ++i )
1920 last = (i == nrows-1 ? nnonz : beg[i+1]);
1921 rowVector.add( last-start, &ind[start], &val[start] );
1923 rows.add(lhs[i], rowVector, rhs[i]);
1927 catch(
const SPxException& x )
1930 std::string s = x.what();
1948 assert(lpi !=
NULL);
1949 assert(lpi->spx !=
NULL);
1950 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
1952 invalidateSolution(lpi);
1954 assert( lpi->spx->preStrongbranchingBasisFreed() );
1956 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRowRange(firstrow, lastrow) );
1974 assert(lpi !=
NULL);
1975 assert(lpi->spx !=
NULL);
1977 invalidateSolution(lpi);
1979 assert( lpi->spx->preStrongbranchingBasisFreed() );
1981 nrows = lpi->spx->nRows();
1984 for( i = 0; i < nrows; ++i )
1987 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->removeRows(dstat) );
1999 assert(lpi !=
NULL);
2000 assert(lpi->spx !=
NULL);
2002 invalidateSolution(lpi);
2004 assert( lpi->spx->preStrongbranchingBasisFreed() );
2005 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->clear() );
2023 assert(lpi !=
NULL);
2024 assert(lpi->spx !=
NULL);
2025 assert(ind !=
NULL);
2029 invalidateSolution(lpi);
2031 assert( lpi->spx->preStrongbranchingBasisFreed() );
2035 for( i = 0; i < ncols; ++i )
2037 assert(0 <= ind[i] && ind[i] < lpi->spx->nCols());
2038 lpi->spx->changeBounds(ind[i], lb[i], ub[i]);
2039 assert(lpi->spx->lower(ind[i]) <= lpi->spx->upper(ind[i]));
2042 catch(
const SPxException& x )
2045 std::string s = x.what();
2067 assert(lpi !=
NULL);
2068 assert(lpi->spx !=
NULL);
2069 assert(ind !=
NULL);
2070 assert(lhs !=
NULL);
2071 assert(rhs !=
NULL);
2073 invalidateSolution(lpi);
2075 assert( lpi->spx->preStrongbranchingBasisFreed() );
2079 for( i = 0; i < nrows; ++i )
2081 assert(0 <= ind[i] && ind[i] < lpi->spx->nRows());
2082 lpi->spx->changeRange(ind[i], lhs[i], rhs[i]);
2083 assert(lpi->spx->lhs(ind[i]) <= lpi->spx->rhs(ind[i]));
2086 catch(
const SPxException& x )
2089 std::string s = x.what();
2108 assert(lpi !=
NULL);
2109 assert(lpi->spx !=
NULL);
2110 assert(0 <= row && row < lpi->spx->nRows());
2111 assert(0 <= col && col < lpi->spx->nCols());
2113 invalidateSolution(lpi);
2115 assert( lpi->spx->preStrongbranchingBasisFreed() );
2117 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->changeElement(row, col, newval) );
2130 assert(lpi !=
NULL);
2131 assert(lpi->spx !=
NULL);
2133 invalidateSolution(lpi);
2135 assert( lpi->spx->preStrongbranchingBasisFreed() );
2137 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setSense(spxObjsen(objsen)) );
2154 assert(lpi !=
NULL);
2155 assert(lpi->spx !=
NULL);
2156 assert(ind !=
NULL);
2157 assert(obj !=
NULL);
2159 invalidateSolution(lpi);
2161 assert( lpi->spx->preStrongbranchingBasisFreed() );
2165 for( i = 0; i < ncols; ++i )
2167 assert(0 <= ind[i] && ind[i] < lpi->spx->nCols());
2168 lpi->spx->changeObj(ind[i], obj[i]);
2171 catch(
const SPxException& x )
2174 std::string s = x.what();
2195 assert(lpi !=
NULL);
2196 assert(lpi->spx !=
NULL);
2197 assert(scaleval != 0.0);
2201 invalidateSolution(lpi);
2203 assert( lpi->spx->preStrongbranchingBasisFreed() );
2206 SVector rowvec = lpi->spx->rowVector(row);
2207 lhs = lpi->spx->lhs(row);
2208 rhs = lpi->spx->rhs(row);
2214 if( lhs > -soplex::infinity )
2216 else if( scaleval < 0.0 )
2217 lhs = soplex::infinity;
2218 if( rhs < soplex::infinity )
2220 else if( scaleval < 0.0 )
2221 rhs = -soplex::infinity;
2222 if( scaleval < 0.0 )
2230 LPRow lprow(lhs, rowvec, rhs);
2233 lpi->spx->changeRow(row, lprow);
2234 assert(lpi->spx->lhs(row) <= lpi->spx->rhs(row));
2236 catch(
const SPxException& x )
2239 std::string s = x.what();
2263 assert(lpi !=
NULL);
2264 assert(lpi->spx !=
NULL);
2265 assert(scaleval != 0.0);
2269 invalidateSolution(lpi);
2271 assert( lpi->spx->preStrongbranchingBasisFreed() );
2274 SVector colvec = lpi->spx->colVector(col);
2275 obj = lpi->spx->obj(col);
2276 lb = lpi->spx->lower(col);
2277 ub = lpi->spx->upper(col);
2286 if( lb > -soplex::infinity )
2288 else if( scaleval < 0.0 )
2289 lb = soplex::infinity;
2290 if( ub < soplex::infinity )
2292 else if( scaleval < 0.0 )
2293 ub = -soplex::infinity;
2294 if( scaleval < 0.0 )
2302 LPCol lpcol(obj, colvec, ub, lb);
2305 lpi->spx->changeCol(col, lpcol);
2306 assert(lpi->spx->lower(col) <= lpi->spx->upper(col));
2308 catch(
const SPxException& x )
2311 std::string s = x.what();
2340 assert(lpi !=
NULL);
2341 assert(lpi->spx !=
NULL);
2342 assert(nrows !=
NULL);
2344 *nrows = lpi->spx->nRows();
2357 assert(lpi !=
NULL);
2358 assert(lpi->spx !=
NULL);
2359 assert(ncols !=
NULL);
2361 *ncols = lpi->spx->nCols();
2376 assert(lpi !=
NULL);
2377 assert(lpi->spx !=
NULL);
2378 assert(nnonz !=
NULL);
2382 if( lpi->spx->nRows() < lpi->spx->nCols() )
2384 for( i = 0; i < lpi->spx->nRows(); ++i )
2385 (*nnonz) += lpi->spx->rowVector(i).size();
2389 for( i = 0; i < lpi->spx->nCols(); ++i )
2390 (*nnonz) += lpi->spx->colVector(i).size();
2417 assert(lpi !=
NULL);
2418 assert(lpi->spx !=
NULL);
2419 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2425 const Vector& lbvec = lpi->spx->lower();
2426 const Vector& ubvec = lpi->spx->upper();
2427 for( i = firstcol; i <= lastcol; ++i )
2429 lb[i-firstcol] = lbvec[i];
2430 ub[i-firstcol] = ubvec[i];
2439 for( i = firstcol; i <= lastcol; ++i )
2441 beg[i-firstcol] = *nnonz;
2442 const SVector& cvec = lpi->spx->colVector(i);
2443 for( j = 0; j < cvec.size(); ++j )
2445 ind[*nnonz] = cvec.index(j);
2446 val[*nnonz] = cvec.value(j);
2453 assert(beg ==
NULL);
2454 assert(ind ==
NULL);
2455 assert(val ==
NULL);
2482 assert(lpi !=
NULL);
2483 assert(lpi->spx !=
NULL);
2484 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2488 assert(rhs !=
NULL);
2490 const Vector& lhsvec = lpi->spx->lhs();
2491 const Vector& rhsvec = lpi->spx->rhs();
2492 for( i = firstrow; i <= lastrow; ++i )
2494 lhs[i-firstrow] = lhsvec[i];
2495 rhs[i-firstrow] = rhsvec[i];
2499 assert(rhs ==
NULL);
2504 for( i = firstrow; i <= lastrow; ++i )
2506 beg[i-firstrow] = *nnonz;
2507 const SVector& rvec = lpi->spx->rowVector(i);
2508 for( j = 0; j < rvec.size(); ++j )
2510 ind[*nnonz] = rvec.index(j);
2511 val[*nnonz] = rvec.value(j);
2518 assert(beg ==
NULL);
2519 assert(ind ==
NULL);
2520 assert(val ==
NULL);
2533 int namestoragesize,
2537 assert( lpi !=
NULL );
2538 assert( lpi->spx !=
NULL );
2539 assert( colnames !=
NULL || namestoragesize == 0 );
2540 assert( namestorage !=
NULL || namestoragesize == 0 );
2541 assert( namestoragesize >= 0 );
2542 assert( storageleft !=
NULL );
2543 assert( 0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols() );
2547 lpi->spx->getColNames(firstcol, lastcol, colnames, namestorage, namestoragesize, storageleft);
2559 int namestoragesize,
2563 assert( lpi !=
NULL );
2564 assert( lpi->spx !=
NULL );
2565 assert( rownames !=
NULL || namestoragesize == 0 );
2566 assert( namestorage !=
NULL || namestoragesize == 0 );
2567 assert( namestoragesize >= 0 );
2568 assert( storageleft !=
NULL );
2569 assert( 0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows() );
2573 lpi->spx->getRowNames(firstrow, lastrow, rownames, namestorage, namestoragesize, storageleft);
2586 assert(lpi !=
NULL);
2587 assert(lpi->spx !=
NULL);
2588 assert(objsen !=
NULL);
2607 assert(lpi !=
NULL);
2608 assert(lpi->spx !=
NULL);
2609 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2610 assert(vals !=
NULL);
2612 for( i = firstcol; i <= lastcol; ++i )
2613 vals[i-firstcol] = lpi->spx->obj(i);
2631 assert(lpi !=
NULL);
2632 assert(lpi->spx !=
NULL);
2633 assert(0 <= firstcol && firstcol <= lastcol && lastcol < lpi->spx->nCols());
2635 for( i = firstcol; i <= lastcol; ++i )
2638 lbs[i-firstcol] = lpi->spx->lower(i);
2640 ubs[i-firstcol] = lpi->spx->upper(i);
2659 assert(lpi !=
NULL);
2660 assert(lpi->spx !=
NULL);
2661 assert(0 <= firstrow && firstrow <= lastrow && lastrow < lpi->spx->nRows());
2663 for( i = firstrow; i <= lastrow; ++i )
2666 lhss[i-firstrow] = lpi->spx->lhs(i);
2668 rhss[i-firstrow] = lpi->spx->rhs(i);
2684 assert(lpi !=
NULL);
2685 assert(lpi->spx !=
NULL);
2686 assert(0 <= col && col < lpi->spx->nCols());
2687 assert(0 <= row && row < lpi->spx->nRows());
2688 assert(val !=
NULL);
2690 *val = lpi->spx->colVector(col)[row];
2711 SPxSolver::Representation rep,
2712 SPxSolver::Type type
2715 assert( lpi !=
NULL );
2716 assert( lpi->spx !=
NULL );
2717 assert( rep == SPxSolver::ROW || rep == SPxSolver::COLUMN );
2718 assert( type == SPxSolver::ENTER || type == SPxSolver::LEAVE );
2720 SCIPdebugMessage(
"calling SoPlex solve(): %d cols, %d rows, rep=%s\n", lpi->spx->nCols(), lpi->spx->nRows(),
2721 rep == SPxSolver::COLUMN ?
"column" :
"row");
2723 invalidateSolution(lpi);
2725 assert( lpi->spx->preStrongbranchingBasisFreed() );
2728 lpi->spx->setRep(rep);
2729 lpi->spx->setType(type);
2731 #ifdef WITH_LPSCHECK
2732 lpi->spx->setDoubleCheck(CHECK_SPXSOLVE);
2735 SPxSolver::Status status = lpi->spx->solve();
2736 SCIPdebugMessage(
" -> SoPlex status: %d, basis status: %d\n", lpi->spx->getStatus(), lpi->spx->basis().status());
2741 case SPxSolver::ABORT_TIME:
2742 case SPxSolver::ABORT_ITER:
2743 case SPxSolver::ABORT_VALUE:
2744 case SPxSolver::SINGULAR:
2745 case SPxSolver::REGULAR:
2746 case SPxSolver::UNKNOWN:
2747 case SPxSolver::OPTIMAL:
2748 case SPxSolver::UNBOUNDED:
2749 case SPxSolver::INFEASIBLE:
2766 assert(lpi !=
NULL);
2767 assert(lpi->spx !=
NULL);
2771 if( lpi->rowrepswitch >= 0 )
2773 rowrep = lpi->spx->rep() == SPxSolver::ROW;
2776 rowrep = lpi->spx->nRows() > lpi->spx->nCols() * (lpi->rowrepswitch);
2778 rowrep = lpi->spx->nRows() * 1.1 > lpi->spx->nCols() * (lpi->rowrepswitch);
2793 retcode = rowrep ? spxSolve(lpi, SPxSolver::ROW, SPxSolver::LEAVE) : spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::ENTER);
2794 assert(!rowrep || lpi->spx->rep() == SPxSolver::ROW);
2795 assert(rowrep || lpi->spx->rep() == SPxSolver::COLUMN);
2810 assert(lpi !=
NULL);
2811 assert(lpi->spx !=
NULL);
2815 if( lpi->rowrepswitch >= 0 )
2817 rowrep = lpi->spx->rep() == SPxSolver::ROW;
2820 rowrep = lpi->spx->nRows() > lpi->spx->nCols() * (lpi->rowrepswitch);
2822 rowrep = lpi->spx->nRows() * 1.1 > lpi->spx->nCols() * (lpi->rowrepswitch);
2837 retcode = rowrep ? spxSolve(lpi, SPxSolver::ROW, SPxSolver::ENTER) : spxSolve(lpi, SPxSolver::COLUMN, SPxSolver::LEAVE);
2838 assert(!rowrep || lpi->spx->rep() == SPxSolver::ROW);
2839 assert(rowrep || lpi->spx->rep() == SPxSolver::COLUMN);
2862 assert( lpi->spx->preStrongbranchingBasisFreed() );
2863 lpi->spx->savePreStrongbranchingBasis();
2873 assert( ! lpi->spx->preStrongbranchingBasisFreed() );
2874 lpi->spx->restorePreStrongbranchingBasis();
2875 lpi->spx->freePreStrongbranchingBasis();
2897 SPxSolver::Status status;
2902 bool fromparentbasis;
2906 SCIPdebugMessage(
"calling SCIPlpiStrongbranch() on variable %d (%d iterations)\n", col, itlim);
2908 assert(lpi !=
NULL);
2909 assert(lpi->spx !=
NULL);
2912 assert(downvalid !=
NULL);
2913 assert(upvalid !=
NULL);
2916 status = SPxSolver::UNKNOWN;
2917 fromparentbasis =
false;
2919 oldItlim = spx->getIterationLimit();
2922 oldlb = spx->lower(col);
2923 oldub = spx->upper(col);
2932 lpi->spx->setType( lpi->spx->rep() == SPxSolver::ROW ? SPxSolver::ENTER : SPxSolver::LEAVE);
2935 newub =
EPSCEIL(psol-1.0, lpi->spx->feastol());
2936 if( newub >= oldlb - 0.5 && down !=
NULL )
2938 SCIPdebugMessage(
"strong branching down on x%d (%g) with %d iterations\n", col, psol, itlim);
2940 spx->changeUpper(col, newub);
2941 assert(spx->lower(col) <= spx->upper(col));
2943 spx->setIterationLimit(itlim);
2946 #ifdef WITH_LPSCHECK
2947 spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
2949 status = spx->solve();
2953 case SPxSolver::OPTIMAL:
2954 *down = spx->value();
2958 case SPxSolver::ABORT_TIME:
2959 case SPxSolver::ABORT_ITER:
2960 case SPxSolver::ABORT_CYCLING:
2961 *down = spx->value();
2963 case SPxSolver::ABORT_VALUE:
2964 case SPxSolver::INFEASIBLE:
2965 *down = spx->terminationValue();
2973 (*iter) += spx->iterations();
2975 #ifdef STRONGBRANCH_RESTOREBASIS
2977 assert( ! spx->preStrongbranchingBasisFreed() );
2978 spx->restorePreStrongbranchingBasis();
2979 fromparentbasis =
false;
2983 if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
2985 SCIPdebugMessage(
" --> Repeat strong branching down with %d iterations after restoring basis\n", itlim - spx->iterations());
2986 spx->setIterationLimit(itlim - spx->iterations());
2987 assert( ! spx->hasPreStrongbranchingBasis() );
2988 spx->restorePreStrongbranchingBasis();
2989 fromparentbasis =
true;
2994 fromparentbasis =
false;
2997 while( fromparentbasis );
2999 spx->changeUpper(col, oldub);
3000 assert(spx->lower(col) <= spx->upper(col));
3002 else if( down !=
NULL )
3004 *down = spx->terminationValue();
3013 newlb =
EPSFLOOR(psol+1.0, lpi->spx->feastol());
3014 if( newlb <= oldub + 0.5 && up !=
NULL )
3016 SCIPdebugMessage(
"strong branching up on x%d (%g) with %d iterations\n", col, psol, itlim);
3018 spx->changeLower(col, newlb);
3019 assert(spx->lower(col) <= spx->upper(col));
3021 spx->setIterationLimit(itlim);
3024 #ifdef WITH_LPSCHECK
3025 spx->setDoubleCheck(CHECK_SPXSTRONGBRANCH);
3027 status = spx->solve();
3031 case SPxSolver::OPTIMAL:
3036 case SPxSolver::ABORT_TIME:
3037 case SPxSolver::ABORT_ITER:
3038 case SPxSolver::ABORT_CYCLING:
3041 case SPxSolver::ABORT_VALUE:
3042 case SPxSolver::INFEASIBLE:
3043 *up = spx->terminationValue();
3051 (*iter) += spx->iterations();
3053 #ifdef STRONGBRANCH_RESTOREBASIS
3055 assert( ! spx->preStrongbranchingBasisFreed() );
3056 spx->restorePreStrongbranchingBasis();
3057 fromparentbasis =
false;
3061 else if( (status == SPxSolver::ABORT_CYCLING || status == SPxSolver::SINGULAR) && !fromparentbasis && spx->iterations() < itlim )
3063 SCIPdebugMessage(
" --> Repeat strong branching up with %d iterations after restoring basis\n", itlim - spx->iterations());
3064 assert( ! spx->hasPreStrongbranchingBasis() );
3065 spx->restorePreStrongbranchingBasis();
3066 spx->setIterationLimit(itlim - spx->iterations());
3068 fromparentbasis =
true;
3072 fromparentbasis =
false;
3075 while( fromparentbasis );
3077 spx->changeLower(col, oldlb);
3078 assert(spx->lower(col) <= spx->upper(col));
3080 else if( up !=
NULL )
3082 *up = spx->terminationValue();
3090 spx->setIterationLimit(oldItlim);
3094 SCIPdebugMessage(
"SCIPlpiStrongbranch() returned SoPlex status %d\n",
int(status));
3119 retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3149 assert( cols !=
NULL );
3150 assert( psols !=
NULL );
3151 assert( down !=
NULL );
3152 assert( up !=
NULL );
3153 assert( downvalid !=
NULL );
3154 assert( upvalid !=
NULL );
3155 assert( down !=
NULL );
3160 for (
int j = 0; j < ncols; ++j)
3163 retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3193 retcode = lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter);
3223 assert( cols !=
NULL );
3224 assert( psols !=
NULL );
3225 assert( down !=
NULL );
3226 assert( up !=
NULL );
3227 assert( downvalid !=
NULL );
3228 assert( upvalid !=
NULL );
3229 assert( down !=
NULL );
3234 for (
int j = 0; j < ncols; ++j)
3237 retcode = lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter);
3266 assert(lpi !=
NULL);
3280 assert(lpi !=
NULL);
3281 assert(primalfeasible !=
NULL);
3282 assert(dualfeasible !=
NULL);
3299 assert(lpi !=
NULL);
3300 assert(lpi->spx !=
NULL);
3302 return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3314 assert(lpi !=
NULL);
3315 assert(lpi->spx !=
NULL);
3317 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3318 return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3331 assert(lpi !=
NULL);
3332 assert(lpi->spx !=
NULL);
3334 assert(lpi->spx->getStatus() != SPxSolver::UNBOUNDED || lpi->spx->basis().status() == SPxBasis::UNBOUNDED);
3339 return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED && !lpi->spx->isPerturbed());
3349 assert(lpi !=
NULL);
3350 assert(lpi->spx !=
NULL);
3352 return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3360 SPxBasis::SPxStatus basestatus;
3364 assert(lpi !=
NULL);
3365 assert(lpi->spx !=
NULL);
3367 basestatus = lpi->spx->basis().status();
3372 assert(basestatus == SPxBasis::OPTIMAL || lpi->spx->getStatus() != SPxSolver::OPTIMAL);
3374 return basestatus == SPxBasis::OPTIMAL ||
3375 ((basestatus == SPxBasis::PRIMAL || basestatus == SPxBasis::UNBOUNDED) && !lpi->spx->isPerturbed());
3387 assert(lpi !=
NULL);
3388 assert(lpi->spx !=
NULL);
3390 return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3402 assert(lpi !=
NULL);
3403 assert(lpi->spx !=
NULL);
3405 return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE);
3415 assert(lpi !=
NULL);
3416 assert(lpi->spx !=
NULL);
3418 return (lpi->spx->getStatus() == SPxSolver::INFEASIBLE && lpi->spx->basis().status() == SPxBasis::DUAL
3419 && !lpi->spx->isPerturbed());
3429 assert(lpi !=
NULL);
3430 assert(lpi->spx !=
NULL);
3432 return (lpi->spx->getStatus() == SPxSolver::UNBOUNDED);
3442 assert(lpi !=
NULL);
3443 assert(lpi->spx !=
NULL);
3448 assert(lpi->spx->basis().status() == SPxBasis::OPTIMAL || lpi->spx->getStatus() != SPxSolver::OPTIMAL);
3450 return (lpi->spx->basis().status() == SPxBasis::OPTIMAL) ||
3451 (lpi->spx->basis().status() == SPxBasis::DUAL && !lpi->spx->isPerturbed());
3461 assert(lpi !=
NULL);
3462 assert((lpi->spx->basis().status() == SPxBasis::OPTIMAL)
3468 return (lpi->spx->basis().status() == SPxBasis::OPTIMAL);
3478 assert(lpi !=
NULL);
3479 assert(lpi->spx !=
NULL);
3481 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3499 if( kappa > lpi->conditionlimit )
3504 return (lpi->spx->getStatus() != SPxSolver::ERROR && lpi->spx->getStatus() != SPxSolver::SINGULAR);
3514 assert(lpi !=
NULL);
3515 assert(lpi->spx !=
NULL);
3517 return (lpi->spx->getStatus() == SPxSolver::ABORT_VALUE);
3527 assert(lpi !=
NULL);
3528 assert(lpi->spx !=
NULL);
3530 return (lpi->spx->getStatus() == SPxSolver::ABORT_ITER);
3540 assert(lpi !=
NULL);
3541 assert(lpi->spx !=
NULL);
3543 return (lpi->spx->getStatus() == SPxSolver::ABORT_TIME);
3553 assert(lpi !=
NULL);
3554 assert(lpi->spx !=
NULL);
3556 return static_cast<int>(lpi->spx->getStatus());
3567 assert(lpi !=
NULL);
3568 assert(lpi->spx !=
NULL);
3584 assert(lpi !=
NULL);
3585 assert(lpi->spx !=
NULL);
3586 assert(objval !=
NULL);
3588 *objval = lpi->spx->value();
3605 assert(lpi !=
NULL);
3606 assert(lpi->spx !=
NULL);
3608 if( objval !=
NULL )
3609 *objval = lpi->spx->value();
3613 if( primsol !=
NULL )
3615 Vector tmp(lpi->spx->nCols(), primsol);
3616 (void)lpi->spx->getPrimal(tmp);
3618 if( dualsol !=
NULL )
3620 Vector tmp(lpi->spx->nRows(), dualsol);
3621 (void)lpi->spx->getDual(tmp);
3623 if( activity !=
NULL )
3625 Vector tmp(lpi->spx->nRows(), activity);
3626 (void)lpi->spx->getSlacks(tmp);
3628 if( redcost !=
NULL )
3630 Vector tmp(lpi->spx->nCols(), redcost);
3631 (void)lpi->spx->getRedCost(tmp);
3634 catch(
const SPxException& x )
3637 std::string s = x.what();
3654 assert(lpi !=
NULL);
3655 assert(lpi->spx !=
NULL);
3657 #if ((SOPLEX_VERSION == 150 && SOPLEX_SUBVERSION >= 2) || SOPLEX_VERSION > 150)
3660 Vector tmp(lpi->spx->nCols(), ray);
3661 (void)lpi->spx->getPrimalray(tmp);
3663 catch(
const SPxException& x )
3666 std::string s = x.what();
3674 SCIPerrorMessage(
"SCIPlpiGetPrimalRay() not supported by SoPlex versions <= 1.5.0\n");
3687 assert(lpi !=
NULL);
3688 assert(lpi->spx !=
NULL);
3692 Vector tmp(lpi->spx->nRows(), dualfarkas);
3693 (void)lpi->spx->getDualfarkas(tmp);
3695 catch(
const SPxException& x )
3698 std::string s = x.what();
3715 assert(lpi !=
NULL);
3716 assert(lpi->spx !=
NULL);
3718 *iterations = lpi->spx->iterations();
3736 assert(lpi !=
NULL);
3737 assert(quality !=
NULL);
3739 #if ((SOPLEX_VERSION == 172 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 172)
3743 assert(lpi !=
NULL);
3744 assert(quality !=
NULL);
3746 SCIPdebugMessage(
"requesting solution quality from SoPlex: quality %d\n", qualityindicator);
3748 switch( qualityindicator )
3765 *quality = lpi->spx->basis().condition(maxiter, tolerance);
3788 assert( spx !=
NULL );
3789 assert( val !=
NULL );
3795 if (! spx->isInitialized() )
3798 assert( 0 <= col && col < spx->nCols() );
3800 if( spx->rep() == SPxSolver::COLUMN )
3803 if (spx->getSense() == SPxLP::MINIMIZE)
3804 *val = spx->pVec()[col] - spx->maxObj()[col];
3806 *val = spx->maxObj()[col] - spx->pVec()[col];
3810 assert( spx->rep() == SPxSolver::ROW );
3813 #ifdef SCIP_DISABLED_CODE
3816 if ( spx->getSense() == SPxLP::MINIMIZE )
3819 if ( spx->isColBasic(col) )
3822 for (
int i = spx->dim() - 1; i >= 0; --i)
3824 SPxId
id = spx->basis().baseId(i);
3825 if (
id.isSPxColId() && col == spx->number(SPxColId(
id)) )
3827 *val = sign * spx->fVec()[i];
3851 assert(lpi !=
NULL);
3852 assert(lpi->spx !=
NULL);
3854 assert( lpi->spx->preStrongbranchingBasisFreed() );
3858 for( i = 0; i < lpi->spx->nRows(); ++i )
3860 switch( lpi->spx->getBasisRowStatus(i) )
3862 case SPxSolver::BASIC:
3865 case SPxSolver::FIXED:
3866 case SPxSolver::ON_LOWER:
3869 case SPxSolver::ON_UPPER:
3872 case SPxSolver::ZERO:
3873 SCIPerrorMessage(
"slack variable has basis status ZERO (should not occur)\n");
3875 case SPxSolver::UNDEFINED:
3886 for( i = 0; i < lpi->spx->nCols(); ++i )
3889 switch( lpi->spx->getBasisColStatus(i) )
3891 case SPxSolver::BASIC:
3894 case SPxSolver::FIXED:
3900 SCIP_CALL( getRedCostEst(lpi->spx, i, &val) );
3906 case SPxSolver::ON_LOWER:
3909 case SPxSolver::ON_UPPER:
3912 case SPxSolver::ZERO:
3915 case SPxSolver::UNDEFINED:
3935 int nCols = lpi->spx->nCols();
3936 int nRows = lpi->spx->nRows();
3940 assert(lpi !=
NULL);
3941 assert(lpi->spx !=
NULL);
3942 assert(cstat !=
NULL || nCols == 0);
3943 assert(rstat !=
NULL || nRows == 0);
3945 assert( lpi->spx->preStrongbranchingBasisFreed() );
3946 invalidateSolution(lpi);
3948 SPxSolver::VarStatus* spxcstat =
NULL;
3949 SPxSolver::VarStatus* spxrstat =
NULL;
3950 SCIP_ALLOC( BMSallocMemoryArray(&spxcstat, nCols) );
3951 SCIP_ALLOC( BMSallocMemoryArray(&spxrstat, nRows) );
3953 for( i = 0; i < nRows; ++i )
3955 assert( rstat != 0 );
3959 spxrstat[i] = SPxSolver::ON_LOWER;
3962 spxrstat[i] = SPxSolver::BASIC;
3965 spxrstat[i] = SPxSolver::ON_UPPER;
3968 SCIPerrorMessage(
"slack variable has basis status ZERO (should not occur)\n");
3969 BMSfreeMemoryArrayNull(&spxcstat);
3970 BMSfreeMemoryArrayNull(&spxrstat);
3974 BMSfreeMemoryArrayNull(&spxcstat);
3975 BMSfreeMemoryArrayNull(&spxrstat);
3981 for( i = 0; i < nCols; ++i )
3983 assert( cstat != 0 );
3987 spxcstat[i] = SPxSolver::ON_LOWER;
3990 spxcstat[i] = SPxSolver::BASIC;
3993 spxcstat[i] = SPxSolver::ON_UPPER;
3996 spxcstat[i] = SPxSolver::ZERO;
4000 BMSfreeMemoryArrayNull(&spxcstat);
4001 BMSfreeMemoryArrayNull(&spxrstat);
4007 SOPLEX_TRY( lpi->messagehdlr, lpi->spx->setBasis(spxrstat, spxcstat) );
4008 (void) lpi->spx->updateStatus();
4010 BMSfreeMemoryArrayNull(&spxcstat);
4011 BMSfreeMemoryArrayNull(&spxrstat);
4026 assert(lpi !=
NULL);
4027 assert(lpi->spx !=
NULL);
4029 assert( lpi->spx->preStrongbranchingBasisFreed() );
4037 if( spx->rep() == SPxSolver::COLUMN )
4039 for(
int i = 0; i < spx->nRows(); ++i )
4041 SPxId
id = spx->basis().baseId(i);
4043 bind[i] = (
id.isSPxColId() ? spx->number(
id) : - 1 - spx->number(
id));
4050 int nrows = spx->nRows();
4051 int ncols = spx->nCols();
4053 assert( spx->rep() == SPxSolver::ROW );
4055 for(
int i = 0; i < nrows; ++i )
4057 if( !spx->isRowBasic(i) )
4065 for(
int j = 0; j < ncols && k < nrows; ++j )
4067 if( !spx->isColBasic(j) )
4084 SCIPdebugMessage(
"Preparing factorization for computation of basis inverse.\n");
4089 if ( lpi->factorization == 0 )
4091 SPxSolver* spx = lpi->spx;
4094 DataArray <const SVector*> matrix(spx->nRows());
4097 for (
int i = 0; i < spx->nRows(); ++i)
4099 if ( ! spx->isRowBasic(i) )
4100 matrix[k++] =
new UnitVector(i);
4102 for (
int j = 0; j < spx->nCols(); ++j)
4104 if ( ! spx->isColBasic(j) )
4105 matrix[k++] = &spx->colVector(j);
4107 assert( k == spx->nRows() );
4108 assert( k == matrix.size() );
4111 lpi->factorization =
new SLUFactor;
4113 SLinSolver::Status status = lpi->factorization->load(matrix.get_ptr(), k);
4115 (void) lpi->factorization->load(matrix.get_ptr(), k);
4117 assert( status == SLinSolver::OK );
4118 assert( k == lpi->factorization->dim() );
4122 for (
int i = 0; i < spx->nRows(); ++i)
4124 if ( ! spx->isRowBasic(i) )
4129 catch(
const SPxException& x )
4132 std::string s = x.what();
4159 assert( lpi !=
NULL );
4160 assert( lpi->spx !=
NULL );
4161 assert( lpi->spx->preStrongbranchingBasisFreed() );
4163 int nCols = lpi->spx->nCols();
4164 int nRows = lpi->spx->nRows();
4171 SPxSolver* spx = lpi->spx;
4174 if ( spx->rep() == SPxSolver::COLUMN )
4177 spx->basis().coSolve(x, spx->unitVector(r));
4180 if( ninds !=
NULL && inds !=
NULL )
4186 for(
int i = 0; i < *ninds; ++i )
4197 Vector y(nRows, coef);
4205 assert(spx->rep() == SPxSolver::ROW);
4216 assert( lpi->factorization != 0 );
4217 assert( lpi->factorization->dim() == nRows );
4220 lpi->factorization->solveLeft(x, e);
4222 Vector x(nRows, coef);
4224 DSVector rhs(nCols);
4231 SCIP_ALLOC( BMSallocMemoryArray(&bind, nRows) );
4244 assert(idx < nRows);
4245 assert(!spx->isRowBasic(idx));
4248 rhs = spx->rowVector(idx);
4255 assert(idx < nCols);
4256 assert(!spx->isColBasic(idx));
4259 rhs = spx->unitVector(idx);
4263 spx->basis().solve(y, rhs);
4266 BMSclearMemoryArray(coef, nRows);
4269 for(
int i = 0; i < nCols; ++i )
4271 SPxId
id = spx->basis().baseId(i);
4273 if(
id.isSPxRowId() )
4275 assert(spx->number(
id) >= 0);
4276 assert(spx->number(
id) < nRows);
4277 assert(bind[r] >= 0 || spx->number(
id) != idx);
4279 x[spx->number(
id)] = y[i];
4286 assert(x[idx] == 0.0);
4295 BMSfreeMemoryArray(&bind);
4299 catch(
const SPxException& x )
4302 std::string s = x.what();
4321 assert(lpi !=
NULL);
4322 assert(lpi->spx !=
NULL);
4323 assert(lpi->spx->preStrongbranchingBasisFreed());
4324 assert(rhs !=
NULL);
4325 assert(coef !=
NULL);
4327 int nCols = lpi->spx->nCols();
4328 int nRows = lpi->spx->nRows();
4332 SPxSolver* spx = lpi->spx;
4333 Vector v(nRows, rhs);
4334 Vector x(nRows, coef);
4337 if( spx->rep() == SPxSolver::COLUMN )
4340 spx->basis().solve(x, v);
4344 assert(spx->rep() == SPxSolver::ROW);
4349 assert(lpi->factorization != 0);
4350 assert(lpi->factorization->dim() == spx->nRows());
4353 lpi->factorization->solveRight(x, v);
4355 DSVector rowrhs(nCols);
4361 SCIP_ALLOC( BMSallocMemoryArray(&bind, nRows) );
4365 for(
int i = 0; i < nCols; ++i )
4367 SPxId
id = spx->basis().baseId(i);
4369 if(
id.isSPxRowId() )
4371 assert(spx->number(
id) >= 0);
4372 assert(spx->number(
id) < nRows);
4374 rowrhs.add(i, v[spx->number(
id)]);
4378 assert(rowrhs[i] == 0.0);
4383 spx->basis().coSolve(y, rowrhs);
4386 for(
int i = 0; i < nRows; ++i )
4398 assert(idx < nRows);
4399 assert(!spx->isRowBasic(idx));
4401 x[i] = v[idx] - (spx->rowVector(idx) * Vector(nCols, y.get_ptr()));
4407 assert(idx < nCols);
4408 assert(!spx->isColBasic(idx));
4415 BMSfreeMemoryArray(&bind);
4419 catch(
const SPxException& x )
4422 std::string s = x.what();
4452 assert( lpi !=
NULL );
4453 assert( lpi->spx !=
NULL );
4454 assert( lpi->spx->preStrongbranchingBasisFreed() );
4461 DVector e(lpi->spx->nRows());
4466 assert(c < lpi->spx->nRows());
4470 SCIP_CALL( lpiGetBInvVec(lpi, e.get_ptr(), coef) );
4499 assert(lpi !=
NULL);
4500 assert(lpi->spx !=
NULL);
4501 assert( lpi->spx->preStrongbranchingBasisFreed() );
4503 nrows = lpi->spx->nRows();
4504 ncols = lpi->spx->nCols();
4508 if( binvrow ==
NULL )
4510 SCIP_ALLOC( BMSallocMemoryArray(&buf, nrows) );
4517 assert(binv !=
NULL);
4524 soplex::Vector binvvec(nrows, binv);
4525 for( c = 0; c < ncols; ++c )
4526 coef[c] = binvvec * lpi->spx->colVector(c);
4529 BMSfreeMemoryArrayNull(&buf);
4549 DVector col(lpi->spx->nRows());
4553 assert( lpi !=
NULL );
4554 assert( lpi->spx !=
NULL );
4555 assert( lpi->spx->preStrongbranchingBasisFreed() );
4559 assert(c < lpi->spx->nCols());
4566 col = lpi->spx->colVector(c);
4567 col.reDim(lpi->spx->nRows());
4570 SCIP_CALL( lpiGetBInvVec(lpi, col.get_ptr(), coef) );
4599 assert(blkmem !=
NULL);
4600 assert(lpi !=
NULL);
4601 assert(lpi->spx !=
NULL);
4602 assert(lpistate !=
NULL);
4604 assert( lpi->spx->preStrongbranchingBasisFreed() );
4606 ncols = lpi->spx->nCols();
4607 nrows = lpi->spx->nRows();
4612 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4615 SCIP_CALL( ensureCstatMem(lpi, ncols) );
4616 SCIP_CALL( ensureRstatMem(lpi, nrows) );
4622 (*lpistate)->ncols = ncols;
4623 (*lpistate)->nrows = nrows;
4624 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
4644 assert(lpi !=
NULL);
4645 assert(lpi->spx !=
NULL);
4646 assert(lpistate !=
NULL);
4648 assert( lpi->spx->preStrongbranchingBasisFreed() );
4650 lpncols = lpi->spx->nCols();
4651 lpnrows = lpi->spx->nRows();
4652 assert(lpistate->ncols <= lpncols);
4653 assert(lpistate->nrows <= lpnrows);
4656 SCIP_CALL( ensureCstatMem(lpi, lpncols) );
4657 SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
4660 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
4663 for( i = lpistate->ncols; i < lpncols; ++i )
4669 bnd = lpi->spx->lower(i);
4678 for( i = lpistate->nrows; i < lpnrows; ++i )
4694 assert(lpi !=
NULL);
4695 assert(lpi->spx !=
NULL);
4701 catch(
const SPxException& x )
4704 std::string s = x.what();
4707 assert( lpi->spx->getStatus() != SPxSolver::OPTIMAL );
4723 assert(lpi !=
NULL);
4724 assert(lpistate !=
NULL);
4726 if ( *lpistate !=
NULL )
4727 lpistateFree(lpistate, blkmem);
4749 assert( lpi->spx->preStrongbranchingBasisFreed() );
4752 SOPLEX_TRY( lpi->messagehdlr, success = lpi->spx->readBasisFile(fname, 0, 0) );
4765 assert( lpi->spx->preStrongbranchingBasisFreed() );
4768 SOPLEX_TRY( lpi->messagehdlr, res = lpi->spx->writeBasisFile(fname, 0, 0) );
4797 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4801 assert(blkmem !=
NULL);
4802 assert(lpi !=
NULL);
4803 assert(lpi->spx !=
NULL);
4804 assert(lpinorms !=
NULL);
4806 lpi->spx->getNdualNorms(nrows, ncols);
4808 if( nrows == 0 && ncols == 0)
4815 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4816 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols) );
4817 (*lpinorms)->nrows = 0;
4818 (*lpinorms)->ncols = 0;
4820 SCIPdebugMessage(
"storing SoPlex LPi pricing norms in %p (%d rows, %d cols)\n", (
void *) *lpinorms, nrows, ncols);
4822 if( !lpi->spx->getDualNorms((*lpinorms)->nrows, (*lpinorms)->ncols, (*lpinorms)->norms) )
4825 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, nrows + ncols);
4826 BMSfreeBlockMemory(blkmem, lpinorms);
4827 assert(*lpinorms ==
NULL);
4832 assert(nrows == (*lpinorms)->nrows);
4833 assert(ncols == (*lpinorms)->ncols);
4852 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4853 assert(blkmem !=
NULL);
4854 assert(lpi !=
NULL);
4855 assert(lpi->spx !=
NULL);
4858 if( lpinorms ==
NULL )
4861 assert(lpinorms->
nrows <= lpi->spx->nRows());
4862 assert(lpinorms->
ncols <= lpi->spx->nCols());
4864 if( lpinorms->
nrows == 0 )
4867 SCIPdebugMessage(
"loading LPi simplex norms %p (%d rows, %d cols) into SoPlex LP with %d rows and %d cols\n",
4868 (
void *) lpinorms, lpinorms->
nrows, lpinorms->
ncols, lpi->spx->nRows(), lpi->spx->nCols());
4870 if( !lpi->spx->setDualNorms(lpinorms->
nrows, lpinorms->
ncols, lpinorms->
norms) )
4884 #if ((SOPLEX_VERSION == 201 && SOPLEX_SUBVERSION >= 3) || SOPLEX_VERSION > 201)
4885 assert(lpi !=
NULL);
4886 assert(lpinorms !=
NULL);
4890 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norms, (*lpinorms)->nrows + (*lpinorms)->ncols);
4891 BMSfreeBlockMemory(blkmem, lpinorms);
4892 assert(*lpinorms ==
NULL);
4919 assert(lpi !=
NULL);
4920 assert(lpi->spx !=
NULL);
4921 assert(ival !=
NULL);
4926 *ival = lpi->spx->getFromScratch();
4929 *ival = lpi->spx->getLpInfo();
4932 *ival = lpi->spx->getIterationLimit();
4935 *ival = lpi->spx->getPresolving();
4938 *ival = (int)lpi->pricing;
4941 *ival = lpi->spx->getScaling();
4943 #if SOPLEX_VERSION >= 201
4945 *ival = (int) lpi->spx->getTiming();
4964 assert(lpi !=
NULL);
4965 assert(lpi->spx !=
NULL);
4971 lpi->spx->setFromScratch(
bool(ival));
4975 lpi->spx->setLpInfo(
bool(ival));
4979 lpi->spx->setIterationLimit(ival);
4983 lpi->spx->setPresolving(
bool(ival));
4987 switch( lpi->pricing )
4991 lpi->spx->setAutoPricer();
4994 lpi->spx->setFullPricer();
4997 lpi->spx->setParmultPricer();
5000 lpi->spx->setSteepPricer();
5003 lpi->spx->setSteepQStartPricer();
5006 lpi->spx->setDevexPricer();
5014 lpi->spx->setScaling(
bool(ival));
5016 #if SOPLEX_VERSION >= 201
5018 assert(ival >= 0 && ival < 3);
5019 lpi->spx->setTiming((Timer::TYPE) ival);
5038 assert(lpi !=
NULL);
5039 assert(lpi->spx !=
NULL);
5040 assert(dval !=
NULL);
5045 *dval = lpi->spx->feastol();
5047 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
5049 *dval = lpi->spx->opttol();
5053 *dval = lpi->spx->getObjLoLimit();
5056 *dval = lpi->spx->getObjUpLimit();
5059 *dval = lpi->spx->terminationTime();
5062 *dval = lpi->rowrepswitch;
5065 *dval = lpi->conditionlimit;
5083 assert(lpi !=
NULL);
5084 assert(lpi->spx !=
NULL);
5089 lpi->spx->setFeastol(dval);
5091 #if ((SOPLEX_VERSION == 160 && SOPLEX_SUBVERSION >= 5) || SOPLEX_VERSION > 160)
5093 lpi->spx->setOpttol(dval);
5097 lpi->spx->setObjLoLimit(dval);
5100 lpi->spx->setObjUpLimit(dval);
5103 lpi->spx->setTerminationTime(dval);
5106 assert(dval >= -1.5);
5107 lpi->rowrepswitch = dval;
5110 lpi->conditionlimit = dval;
5111 lpi->checkcondition = (dval >= 0);
5139 return soplex::infinity;
5150 return (val >= soplex::infinity);
5168 const char* filename
5173 f = fopen(filename,
"r");
5190 assert(lpi !=
NULL);
5191 assert(lpi->spx !=
NULL);
5193 assert( lpi->spx->preStrongbranchingBasisFreed() );
5195 if( !fileExists(fname) )
5200 if( !lpi->spx->readLP(fname) )
5203 catch(
const SPxException& x )
5206 std::string s = x.what();
5223 assert(lpi !=
NULL);
5224 assert(lpi->spx !=
NULL);
5228 lpi->spx->writeFile(fname);
5230 catch(
const SPxException& x )
5233 std::string s = x.what();
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
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)
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
SCIP_DUALPACKET ROWPACKET
unsigned int SCIP_DUALPACKET
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
#define AUTOPRICING_ITERSWITCH
enum SCIP_ObjSen SCIP_OBJSEN
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
enum SCIP_Retcode SCIP_RETCODE
const char * SCIPlpiGetSolverName(void)
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
enum SCIP_LPParam SCIP_LPPARAM
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
enum SCIP_Pricing SCIP_PRICING
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
#define SOPLEX_TRY(messagehdlr, x)
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
SCIP_DUALPACKET COLPACKET
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
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)
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
SCIP_Real SCIPlpiInfinity(SCIP_LPI *)
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)
SCIP_DUALPACKET ROWPACKET
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *, SCIP_Real val)
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
struct SCIP_LPiState SCIP_LPISTATE
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
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)
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
#define SOPLEX_SUBVERSION
#define SOPLEX_TRY_ABORT(x)
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, int *ind, SCIP_Real *obj)
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
const char * SCIPlpiGetSolverDesc(void)
SCIP_DUALPACKET COLPACKET
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
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)
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
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)
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
public methods for message output
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
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)
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
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)
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
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)
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)