CarlyneB commited on
Commit
f7a31c3
·
1 Parent(s): 6a939d1

[FIX] Inputs files: Clamp negative resource caps and coefficients to 0 before solver

Browse files
Files changed (1) hide show
  1. optimisation/optimisation.py +27 -1
optimisation/optimisation.py CHANGED
@@ -723,7 +723,33 @@ def run_optimisation(
723
  if resource_caps is None:
724
  return False, {"message": "resource_caps cannot be None."}
725
 
726
- resource_caps = dict(resource_caps)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
  method_costs = apply_enabled_methods(method_costs, enabled_methods)
728
 
729
  # Clamp negative absolute caps to 0 to avoid infeasible LP.
 
723
  if resource_caps is None:
724
  return False, {"message": "resource_caps cannot be None."}
725
 
726
+ # Sanitize inputs that may bypass the UI's own safeguards (widgets floor
727
+ # at 0, but a scenario loaded from Excel/JSON/ZIP, or a hand-edited
728
+ # data/inputs.csv, is never passed through those widgets). A negative
729
+ # resource cap is caught cleanly downstream as an infeasible LP, but a
730
+ # negative coefficient is not: with no other binding constraint on that
731
+ # resource it lets the solver report an unbounded-looking "success" with
732
+ # an astronomically large total instead of an error. Clamping everything
733
+ # to >= 0 here — the single funnel every input path (UI, Excel, ZIP,
734
+ # JSON, or CSV) passes through before reaching the solver — closes both.
735
+ resource_caps = {r: max(0.0, float(v)) for r, v in resource_caps.items()}
736
+ method_costs = {
737
+ m: {r: max(0.0, float(v)) for r, v in resources.items()}
738
+ for m, resources in method_costs.items()
739
+ }
740
+ if custom_resources:
741
+ custom_resources = [
742
+ {
743
+ **batch,
744
+ "amount": max(0.0, float(batch.get("amount", 0.0))),
745
+ "methods": {
746
+ m: {k: max(0.0, float(v)) for k, v in coefs.items()}
747
+ for m, coefs in batch.get("methods", {}).items()
748
+ },
749
+ }
750
+ for batch in custom_resources
751
+ ]
752
+
753
  method_costs = apply_enabled_methods(method_costs, enabled_methods)
754
 
755
  # Clamp negative absolute caps to 0 to avoid infeasible LP.