Model/domain/modelling
Khalim Conn-Kowlessar 77983caed8 feat(modelling): Optimiser core — exact grouped knapsack (#1160)
Slice 1 of #1160. Recycles the GainOptimiser/CostOptimiser formulation
(≤1 Option per Recommendation, maximise SAP gain subject to budget) as a
clean typed DDD function — but as an exact pure-Python multiple-choice
knapsack rather than the legacy `mip` MILP, since mip's CBC backend does
not load on aarch64 (so the legacy solver path can't run / be tested
here). At retrofit scale the candidate space Π(|group|+1) is tiny, so
exhaustive enumeration is exact and instant; ADR-0016 only needs the
knapsack as a warm-start signal anyway (the truthful figure comes from
the whole-package re-score + repair, next slice).

`optimise(groups, budget) -> list[ScoredOption]`: maximise total gain,
tie-break toward lower cost, skip-per-group covers "select none". 6 tests
(budget-bound selection, ≤1/group, unconstrained, budget-too-small,
empty groups, partial-affordability); pyright strict clean.

Multi-phase remains descoped (ADR-0005) — single-phase optimiser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 12:39:47 +00:00
..
__init__.py feat(modelling): Overlay Applicator folds EpcSimulation onto EpcPropertyData 2026-06-02 22:13:51 +00:00
contingencies.py feat(modelling): floor Recommendation Generator + ground-floor-area geometry 2026-06-03 09:12:29 +00:00
floor_recommendation.py feat(modelling): floor insulation-type overlay field + cascade pins (#1159) 2026-06-03 09:41:54 +00:00
optimiser.py feat(modelling): Optimiser core — exact grouped knapsack (#1160) 2026-06-03 12:39:47 +00:00
overlay_applicator.py feat(modelling): Overlay Applicator folds EpcSimulation onto EpcPropertyData 2026-06-02 22:13:51 +00:00
package_scorer.py feat(modelling): Package Scorer — compose overlays + score on the calculator 2026-06-03 08:41:30 +00:00
plan.py feat(modelling): domain Plan + PlanMeasure types (#1157) 2026-06-03 11:40:27 +00:00
product.py feat(modelling): ProductRepository + Postgres materials-table source 2026-06-03 08:32:38 +00:00
recommendation.py feat(modelling): wall Recommendation Generator — cavity-fill detection + overlay 2026-06-02 22:49:33 +00:00
roof_recommendation.py feat(modelling): loft overlay 270→300 mm + Elmhurst cascade pin (#1158) 2026-06-03 09:39:21 +00:00
scenario.py feat(modelling): domain Scenario + ScenarioPostgresRepository (#1157) 2026-06-03 11:19:52 +00:00
scoring.py feat(modelling): per-measure scoring — marginal cascade + per-Option signal (#1156) 2026-06-03 08:50:49 +00:00
simulation.py feat(modelling): floor insulation-type overlay field + cascade pins (#1159) 2026-06-03 09:41:54 +00:00
wall_recommendation.py feat(modelling): price the cavity Option from area x Product — closes #1155 2026-06-03 08:35:52 +00:00