The solver form gains an Objective section with a product/sum mode
select and per-resource factor inputs (E/B/S/C, zero = excluded).
The /solve handler parses both fields and forwards them to solve(),
falling back to solve.py defaults when omitted.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Add objective_factors and objective_mode as optional parameters to solve().
Resolve defaults at function entry and validate using existing _validate_objective.
Normalize objective_factors to ensure all required keys (EBSC) are present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>