mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Optimiser objective is required on the private helpers, hoisted in repair 🟪
Review findings on PR #1527: - The objective is required (no sap_rating default) on _repair_to_target, _best_repair_candidate and _rescored_groups: every caller already passes it, and a default would let a future call path silently optimise SAP for a carbon/bill goal while pyright stayed green. The default stays on the public optimise_package / optimise_package_fabric_first entry points. - _best_repair_candidate hoists objective(current) out of the candidate loop: current is loop-invariant, so for the Energy-Savings bill objective this was one full BillDerivation.derive per candidate per repair iteration for the same score. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b71bc788a2
commit
daf4449d0d
1 changed files with 8 additions and 7 deletions
|
|
@ -454,7 +454,7 @@ def _repair_to_target(
|
|||
baseline_epc: EpcPropertyData,
|
||||
budget: Optional[float],
|
||||
target_sap: float,
|
||||
objective: Callable[[Score], float] = sap_rating,
|
||||
objective: Callable[[Score], float],
|
||||
) -> OptimisedPackage:
|
||||
"""Inject dependencies onto the warm-start, re-score for the truth, then
|
||||
greedy-add the untreated-group Option with the best marginal objective-per-£
|
||||
|
|
@ -522,15 +522,16 @@ def _best_repair_candidate(
|
|||
baseline_epc: EpcPropertyData,
|
||||
current: Score,
|
||||
budget: Optional[float],
|
||||
objective: Callable[[Score], float] = sap_rating,
|
||||
objective: Callable[[Score], float],
|
||||
) -> Optional[ScoredOption]:
|
||||
"""The untreated-group Option giving the best **marginal** SAP-per-£ when
|
||||
added to the current package — re-scored (not the role-1 signal) with any
|
||||
ventilation dependency it newly triggers folded in, so both its SAP and its
|
||||
incremental cost are truthful. Affordable when the resulting whole-package
|
||||
"""The untreated-group Option giving the best **marginal** objective-per-£
|
||||
when added to the current package — re-scored (not the role-1 signal) with
|
||||
any ventilation dependency it newly triggers folded in, so both its gain and
|
||||
its incremental cost are truthful. Affordable when the resulting whole-package
|
||||
cost is within ``budget`` and strictly improving. None if there is none."""
|
||||
used: set[int] = _used_group_indices(groups, chosen)
|
||||
base_cost: float = _package_cost(_inject(chosen, dependencies))
|
||||
current_value: float = objective(current)
|
||||
best: Optional[ScoredOption] = None
|
||||
best_ratio: float = 0.0
|
||||
for index, group in enumerate(groups):
|
||||
|
|
@ -544,7 +545,7 @@ def _best_repair_candidate(
|
|||
if budget is not None and package_cost > budget:
|
||||
continue
|
||||
trial: Score = _score(scorer, baseline_epc, trial_selected)
|
||||
marginal: float = objective(trial) - objective(current)
|
||||
marginal: float = objective(trial) - current_value
|
||||
if marginal <= 0.0:
|
||||
continue
|
||||
incremental: float = package_cost - base_cost
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue