working on the optimiser algorithm

This commit is contained in:
Khalim Conn-Kowlessar 2025-08-12 19:36:18 +01:00
parent 051ee240ba
commit 0c6a0827b2

View file

@ -494,12 +494,65 @@ def _find_measure(input_measures, measure_type):
def make_funding_paths(input_measures, tenure):
"""
This function generates funding paths based on the input measures and the tenure of the property.
It checks for the presence of specific measures and creates paths that include necessary insulation measures
to meet minimum insulation requirements, particularly when a heating system is recommended.
Remaining measures that are not fixed as part of the package are then optimised
:param input_measures:
:param tenure:
:return:
"""
funding_paths = []
# We handle the case of minimum insulation requirements. Whenever we have a heating system recommendation,
# we *must* include an additional insulation measure, unless the property already has sufficient insulation.
# We determine which insulation measures need to be included
wall_insulation_measures = [
"internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation",
"extension_cavity_wall_insulation"
]
roof_insulation_measures = [
"loft_insulation", "flat_roof_insulation", "room_roof_insulation"
]
# These are the insulation measures that the property still needs and so will be considered for
# filling the minimum insulation requirements
remaining_insulation_type = []
for insulation_measure in wall_insulation_measures + roof_insulation_measures:
if _find_measure(input_measures, insulation_measure):
remaining_insulation_type.append(insulation_measure)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Air source heat pump
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# For all tenures, if we have an air source heat pump it's a funded measure and so we must consider the minimum
# insulation requirements
if _find_measure(input_measures, "air_source_heat_pump"):
ashp_template = [{"AND": ["air_source_heat_pump"]}]
ashp_paths = []
for insulation_measure in remaining_insulation_type:
new_ashp_path = deepcopy(ashp_template)
new_ashp_path[0]["AND"].append(insulation_measure)
ashp_paths.append(new_ashp_path)
if ashp_paths:
# If we have any insulation measures, we add them to the funding paths
funding_paths.extend(ashp_paths)
else:
# If we have no insulation measures, we just add the ASHP path
funding_paths.append(ashp_template)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Solar PV with existing eligible heating system
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if tenure == "Social":
raise NotImplementedError("Implement me!")
funding_paths = []
if tenure == "Private"
if tenure == "Private":
# We cover off the main funding paths
# 1) The package must include EWI or IWI
# We check if we have any EWI or IWI measures available
@ -514,12 +567,6 @@ def make_funding_paths(input_measures, tenure):
if ewi_or_iwi[0]["OR"]:
funding_paths.append(ewi_or_iwi)
# 2) The package must include a renewable heating system like an ASHP
ashp = [{"OR": []}]
if _find_measure(input_measures, "air_source_heat_pump"):
ashp[0]["OR"].append("air_source_heat_pump")
funding_paths.append(ashp)
# 3) The package must have an existing eligible heating system. We test this with the funding checker
# If we have any remaining insulation measure to be applied to the property, we also need to include that in
# the package
@ -532,14 +579,6 @@ def make_funding_paths(input_measures, tenure):
if has_eligible_heating_system:
single_solar_template[0]["AND"].append("solar_pv")
# We now look to pair this with any lingering insulation measures
wall_insulation_measures = [
"internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation",
"extension_cavity_wall_insulation"
]
roof_insulation_measures = [
"loft_insulation", "flat_roof_insulation", "room_roof_insulation"
]
# We search for these
solar_paths_with_insulation = []
for insulation_measure in wall_insulation_measures + roof_insulation_measures:
if _find_measure(input_measures, insulation_measure):
@ -555,14 +594,16 @@ def make_funding_paths(input_measures, tenure):
else:
# If we don't have an eligible heating system, we check if we have an eligible heating system
# (HHRSH/ASHP/Electric boiler) + solar PV
if _find_measure(input_measures, "solar_pv") and _find_measure(input_measures,
"high_heat_retention_storage_heater"):
if (_find_measure(input_measures, "solar_pv") and
_find_measure(input_measures, "high_heat_retention_storage_heater")):
funding_paths.append([{"AND": ["solar_pv", "high_heat_retention_storage_heater"]}])
if _find_measure(input_measures, "solar_pv") and _find_measure(input_measures, "air_source_heat_pump"):
if (_find_measure(input_measures, "solar_pv") and
_find_measure(input_measures, "air_source_heat_pump")):
funding_paths.append([{"AND": ["solar_pv", "air_source_heat_pump"]}])
if _find_measure(input_measures, "solar_pv") and _find_measure(input_measures, "electric_boiler"):
if (_find_measure(input_measures, "solar_pv") and
_find_measure(input_measures, "electric_boiler")):
funding_paths.append([{"AND": ["solar_pv", "electric_boiler"]}])
@ -791,9 +832,6 @@ def expand_min_insulation_if_needed(input_measures, fixed_selection):
return expanded
from copy import deepcopy
# ---- tiny utilities ----------------------------------------------------------
def parse_types(t):