Skip to content

Andersen implemented#1

Merged
fantasy2fry merged 14 commits into
mainfrom
andersen
May 26, 2026
Merged

Andersen implemented#1
fantasy2fry merged 14 commits into
mainfrom
andersen

Conversation

@fantasy2fry
Copy link
Copy Markdown
Collaborator

I implemented method based on Andersen Paper, and then I runned: uv run python benchmark.py --mode all --exact-limit-seconds 300.0

results I'll send via messenger

self.best_assignment = tuple(tuple(row) for row in assignment)


def solve_branch_and_adjust(
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name solve_branch_and_adjust is a bit misleading after removing the Gurobi implementation. The current code performs a static Piecewise Linear Approximation before starting the solver, rather than a dynamic B&A algorithm (we are not generating cuts/tangents on the fly during the tree search).
Consider renaming it to something like solve_piecewise_linear_scip or updating the docstring to better reflect what is actually happening here.

Comment thread src/wta_optimization/exact.py Outdated

min_y_j = sum(val for val in ln_q if val < 0)

if min_y_j < 0:
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work with manually building these tangent supports! Moving to the open-source SCIP is a fantastic step.

I do have a small note though: the method applied here is a lower bound approximation for a convex function (the tangents lie "under" the $e^x$ curve). This means the solver optimizes a slightly distorted space, which can lead to suboptimal solutions for the original problem. SCIP is one of the world's best MINLP (Mixed-Integer Nonlinear Programming) solvers. Instead of manually building 20 tangents, we could likely pass the exponential function directly to the model, and SCIP would handle generating optimal cuts under the hood. I'm leaving this as food for thought for future iterations (we can leave it as is for now).

Comment thread src/wta_optimization/exact.py Outdated
)


class TrueObjectiveTracker(Eventhdlr):
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very clever workaround for the approximation error! Using SCIP's Eventhdlr to listen for BESTSOLFOUND and calculating the actual (nonlinear) objective value on the side is a great and architecturally "clean" idea. Well written!

Comment thread src/wta_optimization/exact.py Outdated

model = Model("WTA_Branch_and_Adjust_SCIP")
model.hideOutput(True)
model.setRealParam("limits/time", time_limit_seconds)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we are setting a time limit here: model.setRealParam("limits/time", time_limit_seconds). Shouldn't we also explicitly set the multithreading parameter (e.g., parallel/maxnthreads), as is usually done in benchmarks, to ensure reproducible results between Gurobi and SCIP?

@fantasy2fry fantasy2fry merged commit ae040fb into main May 26, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants