-
Notifications
You must be signed in to change notification settings - Fork 277
getTermsQuadractic correctly returns linear terms #1132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -316,7 +316,7 @@ | |||||
| if rc == SCIP_OKAY: | ||||||
| pass | ||||||
| elif rc == SCIP_ERROR: | ||||||
| raise Exception('SCIP: unspecified error!') | ||||||
| elif rc == SCIP_NOMEMORY: | ||||||
| raise MemoryError('SCIP: insufficient memory error!') | ||||||
| elif rc == SCIP_READERROR: | ||||||
|
|
@@ -335,7 +335,7 @@ | |||||
| raise Exception('SCIP: method cannot be called at this time' | ||||||
| + ' in solution process!') | ||||||
| elif rc == SCIP_INVALIDDATA: | ||||||
| raise Exception('SCIP: error in input data!') | ||||||
| elif rc == SCIP_INVALIDRESULT: | ||||||
| raise Exception('SCIP: method returned an invalid result code!') | ||||||
| elif rc == SCIP_PLUGINNOTFOUND: | ||||||
|
|
@@ -5730,6 +5730,13 @@ | |||||
|
|
||||||
| PyCons = Constraint.create(scip_cons) | ||||||
|
|
||||||
| # Store the original polynomial expression on the constraint so that | ||||||
| # helpers such as getTermsQuadratic can reconstruct full linear terms | ||||||
| # even if SCIP's internal quadratic representation does not expose | ||||||
| # all linear coefficients explicitly. | ||||||
| if PyCons.data is None: | ||||||
| PyCons.data = quadcons.expr | ||||||
|
|
||||||
| return PyCons | ||||||
|
|
||||||
| def _createConsNonlinear(self, cons, **kwargs): | ||||||
|
|
@@ -6064,6 +6071,11 @@ | |||||
|
|
||||||
| PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons)) | ||||||
| pycons = Constraint.create(scip_cons) | ||||||
| # propagate any problem data (such as the original Expr for | ||||||
| # expression-based constraints) from the temporary constraint | ||||||
| # created in createConsFromExpr to the final Constraint object | ||||||
| # that is returned to the user | ||||||
| pycons.data = (<Constraint>pycons_initial).data | ||||||
| PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons)) | ||||||
|
|
||||||
| return pycons | ||||||
|
|
@@ -8085,8 +8097,17 @@ | |||||
| Returns | ||||||
| ------- | ||||||
| bilinterms : list of tuple | ||||||
| Triples ``(var1, var2, coef)`` for terms of the form | ||||||
| ``coef * var1 * var2`` with ``var1 != var2``. | ||||||
| quadterms : list of tuple | ||||||
| Triples ``(var, sqrcoef, lincoef)`` corresponding to diagonal | ||||||
| quadratic terms of the form ``sqrcoef * var**2`` and the linear | ||||||
| coefficient ``lincoef`` associated with the same variable when it | ||||||
| also appears linearly in the quadratic part. | ||||||
| linterms : list of tuple | ||||||
| Pairs ``(var, coef)`` for all variables with a nonzero linear | ||||||
| coefficient in the constraint, including variables that also | ||||||
| appear in quadratic or bilinear terms. | ||||||
|
Comment on lines
+8108
to
+8110
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would |
||||||
|
|
||||||
| """ | ||||||
| cdef SCIP_EXPR* expr | ||||||
|
|
@@ -8117,15 +8138,36 @@ | |||||
| assert self.checkQuadraticNonlinear(cons), "constraint is not quadratic" | ||||||
|
|
||||||
| expr = SCIPgetExprNonlinear(cons.scip_cons) | ||||||
| SCIPexprGetQuadraticData(expr, NULL, &nlinvars, &linexprs, &lincoefs, &nquadterms, &nbilinterms, NULL, NULL) | ||||||
| SCIPexprGetQuadraticData(expr, NULL, &nlinvars, &linexprs, &lincoefs, | ||||||
| &nquadterms, &nbilinterms, NULL, NULL) | ||||||
|
|
||||||
| linterms = [] | ||||||
| bilinterms = [] | ||||||
| quadterms = [] | ||||||
|
|
||||||
| for termidx in range(nlinvars): | ||||||
| var = Variable.create(SCIPgetVarExprVar(linexprs[termidx])) | ||||||
| linterms.append((var, lincoefs[termidx])) | ||||||
| # First try to recover all linear coefficients from the original | ||||||
| # polynomial expression, if it has been stored on the Constraint. | ||||||
| if isinstance(cons.data, Expr): | ||||||
| lindict = {} | ||||||
| for term, coef in cons.data.terms.items(): | ||||||
| if coef == 0.0: | ||||||
| continue | ||||||
| if len(term) == 1: | ||||||
| var = term[0] | ||||||
| key = var.ptr() | ||||||
| if key in lindict: | ||||||
| _, oldcoef = lindict[key] | ||||||
| lindict[key] = (var, oldcoef + coef) | ||||||
| else: | ||||||
| lindict[key] = (var, coef) | ||||||
| for _, (var, coef) in lindict.items(): | ||||||
| linterms.append((var, coef)) | ||||||
Joao-Dionisio marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| else: | ||||||
| # use only the purely linear part as exposed by SCIP's quadratic representation | ||||||
| for termidx in range(nlinvars): | ||||||
| scipvar1 = SCIPgetVarExprVar(linexprs[termidx]) | ||||||
| var = Variable.create(scipvar1) | ||||||
| linterms.append((var, lincoefs[termidx])) | ||||||
|
|
||||||
| for termidx in range(nbilinterms): | ||||||
| SCIPexprGetQuadraticBilinTerm(expr, termidx, &bilinterm1, &bilinterm2, &bilincoef, NULL, NULL) | ||||||
|
|
@@ -8137,13 +8179,13 @@ | |||||
| bilinterms.append((var1,var2,bilincoef)) | ||||||
| else: | ||||||
| quadterms.append((var1,bilincoef,0.0)) | ||||||
|
|
||||||
| for termidx in range(nquadterms): | ||||||
| SCIPexprGetQuadraticQuadTerm(expr, termidx, NULL, &lincoef, &sqrcoef, NULL, NULL, &sqrexpr) | ||||||
| if sqrexpr == NULL: | ||||||
| continue | ||||||
|
Comment on lines
8184
to
8185
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Use |
||||||
| var = Variable.create(SCIPgetVarExprVar(sqrexpr)) | ||||||
| quadterms.append((var,sqrcoef,lincoef)) | ||||||
| scipvar1 = SCIPgetVarExprVar(sqrexpr) | ||||||
| var = Variable.create(scipvar1) | ||||||
| quadterms.append((var, sqrcoef, lincoef)) | ||||||
|
|
||||||
| return (bilinterms, quadterms, linterms) | ||||||
|
|
||||||
|
|
@@ -8488,6 +8530,31 @@ | |||||
|
|
||||||
| return _dualsol | ||||||
|
|
||||||
| def getVarFarkasCoef(self, Variable var): | ||||||
| """ | ||||||
| Returns the Farkas coefficient of the variable in the current node's LP relaxation; the current node has to have an infeasible LP. | ||||||
|
|
||||||
| Parameters | ||||||
| ---------- | ||||||
| var : Variable | ||||||
| variable to get the farkas coefficient of | ||||||
|
|
||||||
| Returns | ||||||
| ------- | ||||||
| float | ||||||
|
|
||||||
| """ | ||||||
| assert SCIPgetStatus(self._scip) == SCIP_STATUS_INFEASIBLE, "Method can only be called with an infeasible model." | ||||||
Joao-Dionisio marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| farkas_coef = None | ||||||
| try: | ||||||
| farkas_coef = SCIPgetVarFarkasCoef(self._scip, var.scip_var) | ||||||
| if self.getObjectiveSense() == "maximize": | ||||||
| farkas_coef = -farkas_coef | ||||||
| except Exception: | ||||||
| raise Warning("no farkas coefficient available for variable " + var.name) | ||||||
Joao-Dionisio marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| return farkas_coef | ||||||
|
|
||||||
| def optimize(self): | ||||||
| """Optimize the problem.""" | ||||||
| PY_SCIP_CALL(SCIPsolve(self._scip)) | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot get the data from SCIP instead of this added complexity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find a way, Mo :/ It does seem that the SCIP method has this limitation