feat: compute resource ceilings only for objective resources

Modify solve() to only compute ceilings (_ceiling solver calls) for
resources that appear in the objective function (where obj_factors[k] != 0).
This avoids unnecessary 20s ceiling solves for resources not contributing
to the maximize criterion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Pagwin 2026-06-11 19:26:18 -04:00
parent ead700adf4
commit 43636d330e
No known key found for this signature in database
GPG key ID: 81137023740CA260

View file

@ -1582,12 +1582,16 @@ def solve(
else max_res
)
capE = _ceiling(finalE)
capB = _ceiling(finalB)
capS = _ceiling(finalS)
m.Add(finalE <= capE)
m.Add(finalB <= capB)
m.Add(finalS <= capS)
finals = {"E": finalE, "B": finalB, "S": finalS, "C": C[NUM_STEPS + 1]}
# Ceilings only for resources that appear in the objective: each
# ceiling solve costs up to 20s, and only objective resources need
# bounds (product mode) / benefit from the redundant cap constraint.
caps = {}
for k, var in finals.items():
if obj_factors[k] != 0:
caps[k] = _ceiling(var)
m.Add(var <= caps[k])
# ======================================================================
# OBJECTIVE IS SET HERE
@ -1629,7 +1633,8 @@ def solve(
status = solver.Solve(m)
if verbose:
print(f"(resource ceilings used: E<={capE} B<={capB} S<={capS})")
caps_str = " ".join(f"{k}<={v}" for k, v in caps.items())
print(f"(resource ceilings used: {caps_str})")
_report(
solver,
status,