improve chgReoptObjective performance#1178
Conversation
|
Thank you, @a-schmitt ! This does look very useful! Can you please run the before and after on a bigger problem, to archive the performance improvement? Something I'm wondering is about the removal of the |
There was a problem hiding this comment.
Pull request overview
This PR optimizes Model.chgReoptObjective to avoid O(m·n) scans over all SCIP variables by passing only the variables that appear in the new objective, and adds tests and documentation to cover the updated behavior.
Changes:
- Reimplemented
Model.chgReoptObjectiveto build dense arrays of only the variables present in theExprand callSCIPchgReoptObjectivewith those, including a special-case path for zero-objective expressions. - Updated the
chgReoptObjectivedocstring to describe the reoptimization behavior and theExpr-based API accurately. - Extended
tests/test_reopt.pywith additional cases for maximize sense, sparse objectives with many variables, and zero objective, and documented this improvement inCHANGELOG.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/pyscipopt/scip.pxi |
Refactored Model.chgReoptObjective to compute nvars from the Expr terms, populate _vars/_coeffs arrays directly from the terms (excluding CONST), handle the zero-variable case via a NULL call, and adjusted the docstring accordingly. |
tests/test_reopt.py |
Added tests covering maximize-sense reoptimization, many-variable sparse objective reoptimization, and the zero-objective case (including feasibility and objective value checks), plus a clarifying docstring for the original test. |
CHANGELOG.md |
Recorded the improved chgReoptObjective() performance under unreleased changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Thanks for your effort! I unscientifically tested on a toy problem the proposed version the old version so something like ~14s vs ~2ms per objective change for the 10k variable problem and the difference scales with the problem size.
I don't like that the _varArray() wrapper approach uses a malloc for each individual variable. |
True, but the major speedup comes from the better complexity. It just itches a bit not to have a centralized method for memory handling. Plus, it's safer if Can you run another benchmark with this change? If it's significant enough, we can discard it. |
|
I added the wrapper within the loop similar how it is done in I also removed the |
|
Thank you, @a-schmitt , and very cool that your first Github contribution was so mature! |
For medium sized production problems using reoptimization
chgReoptObjectiveleads to quite some bottleneck.The reason is some O (m * n) (m=#scip variables, n=#variables with non null objective) loop.
The current code seems to assume that the scip c function needs all m scip variables as input.
However, only the n variables to change are needed (see https://github.com/scipopt/scip/blob/775ad66cb8edde846e16d913009b30add5c6d07b/src/scip/scip_prob.c#L1294), reducing the complexity to O ( n ).
Changes: