mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-08-25 06:52:23 +00:00
EV possible currents -> Work now (new Mutate Function)
-> Some Penalties are removed (deprecated) AC Charge -> Parameter in Optimization -1,0,1 -> Missing integration in class_ems
This commit is contained in:
@@ -84,7 +84,7 @@ class PVAkku:
|
||||
return (self.soc_wh / self.kapazitaet_wh) * 100
|
||||
|
||||
def energie_abgeben(self, wh, hour):
|
||||
if self.discharge_array[hour] == 0:
|
||||
if self.discharge_array[hour] == 0 and self.discharge_array[hour] == -1:
|
||||
return 0.0, 0.0 # No energy discharge and no losses
|
||||
|
||||
# Calculate the maximum energy that can be discharged considering min_soc and efficiency
|
||||
|
@@ -28,6 +28,7 @@ class EnergieManagementSystem:
|
||||
self.akku.set_discharge_per_hour(ds)
|
||||
|
||||
def set_eauto_charge_hours(self, ds: List[int]) -> None:
|
||||
|
||||
self.eauto.set_charge_per_hour(ds)
|
||||
|
||||
def set_haushaltsgeraet_start(self, ds: List[int], global_start_hour: int = 0) -> None:
|
||||
|
@@ -39,7 +39,7 @@ class optimization_problem:
|
||||
) -> Tuple[List[int], List[float], Optional[int]]:
|
||||
"""
|
||||
Split the individual solution into its components:
|
||||
1. Discharge hours (binary),
|
||||
1. Discharge hours (-1 (Charge),0 (Nothing),1 (Discharge)),
|
||||
2. Electric vehicle charge hours (float),
|
||||
3. Dishwasher start time (integer if applicable).
|
||||
"""
|
||||
@@ -69,8 +69,8 @@ class optimization_problem:
|
||||
|
||||
# Initialize toolbox with attributes and operations
|
||||
self.toolbox = base.Toolbox()
|
||||
self.toolbox.register("attr_bool", random.randint, 0, 1)
|
||||
self.toolbox.register("attr_float", random.uniform, 0, 1)
|
||||
self.toolbox.register("attr_discharge_state", random.randint, -1, 1)
|
||||
self.toolbox.register("attr_ev_charge_index", random.randint, 0, len(moegliche_ladestroeme_in_prozent) - 1)
|
||||
self.toolbox.register("attr_int", random.randint, start_hour, 23)
|
||||
|
||||
# Register individual creation method based on household appliance parameter
|
||||
@@ -78,8 +78,8 @@ class optimization_problem:
|
||||
self.toolbox.register(
|
||||
"individual",
|
||||
lambda: creator.Individual(
|
||||
[self.toolbox.attr_bool() for _ in range(self.prediction_hours)]
|
||||
+ [self.toolbox.attr_float() for _ in range(self.prediction_hours)]
|
||||
[self.toolbox.attr_discharge_state() for _ in range(self.prediction_hours)]
|
||||
+ [self.toolbox.attr_ev_charge_index() for _ in range(self.prediction_hours)]
|
||||
+ [self.toolbox.attr_int()]
|
||||
),
|
||||
)
|
||||
@@ -87,15 +87,48 @@ class optimization_problem:
|
||||
self.toolbox.register(
|
||||
"individual",
|
||||
lambda: creator.Individual(
|
||||
[self.toolbox.attr_bool() for _ in range(self.prediction_hours)]
|
||||
+ [self.toolbox.attr_float() for _ in range(self.prediction_hours)]
|
||||
[self.toolbox.attr_discharge_state() for _ in range(self.prediction_hours)]
|
||||
+ [self.toolbox.attr_ev_charge_index() for _ in range(self.prediction_hours)]
|
||||
),
|
||||
)
|
||||
|
||||
# Register population, mating, mutation, and selection functions
|
||||
self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual)
|
||||
self.toolbox.register("mate", tools.cxTwoPoint)
|
||||
self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1)
|
||||
#self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1)
|
||||
# Register separate mutation functions for each type of value:
|
||||
# - Discharge state mutation (-1, 0, 1)
|
||||
self.toolbox.register("mutate_discharge", tools.mutUniformInt, low=0, up=1, indpb=0.1)
|
||||
# - Float mutation for EV charging values
|
||||
self.toolbox.register("mutate_ev_charge_index", tools.mutUniformInt, low=0, up=len(moegliche_ladestroeme_in_prozent) - 1, indpb=0.1)
|
||||
# - Start hour mutation for household devices
|
||||
self.toolbox.register("mutate_hour", tools.mutUniformInt, low=start_hour, up=23, indpb=0.3)
|
||||
|
||||
# Custom mutation function that applies type-specific mutations
|
||||
def mutate(individual):
|
||||
# Mutate the discharge state genes (-1, 0, 1)
|
||||
individual[:self.prediction_hours], = self.toolbox.mutate_discharge(
|
||||
individual[:self.prediction_hours]
|
||||
)
|
||||
|
||||
# Mutate the EV charging indices
|
||||
ev_charge_part = individual[self.prediction_hours : self.prediction_hours * 2]
|
||||
ev_charge_part_mutated, = self.toolbox.mutate_ev_charge_index(ev_charge_part)
|
||||
individual[self.prediction_hours : self.prediction_hours * 2] = ev_charge_part_mutated
|
||||
|
||||
# Mutate the appliance start hour if present
|
||||
if len(individual) > self.prediction_hours * 2:
|
||||
appliance_part = [individual[-1]]
|
||||
appliance_part_mutated, = self.toolbox.mutate_hour(appliance_part)
|
||||
individual[-1] = appliance_part_mutated[0]
|
||||
|
||||
return (individual,)
|
||||
|
||||
|
||||
# Register custom mutation function
|
||||
self.toolbox.register("mutate", mutate)
|
||||
|
||||
|
||||
self.toolbox.register("select", tools.selTournament, tournsize=3)
|
||||
|
||||
def evaluate_inner(
|
||||
@@ -106,16 +139,22 @@ class optimization_problem:
|
||||
using the provided individual solution.
|
||||
"""
|
||||
ems.reset()
|
||||
discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(
|
||||
discharge_hours_bin, eautocharge_hours_index, spuelstart_int = self.split_individual(
|
||||
individual
|
||||
)
|
||||
if self.opti_param.get("haushaltsgeraete", 0) > 0:
|
||||
ems.set_haushaltsgeraet_start(spuelstart_int, global_start_hour=start_hour)
|
||||
|
||||
ems.set_akku_discharge_hours(discharge_hours_bin)
|
||||
eautocharge_hours_float[self.prediction_hours - self.fixed_eauto_hours :] = [
|
||||
0.0
|
||||
eautocharge_hours_index[self.prediction_hours - self.fixed_eauto_hours :] = [
|
||||
0
|
||||
] * self.fixed_eauto_hours
|
||||
|
||||
eautocharge_hours_float = [
|
||||
moegliche_ladestroeme_in_prozent[i] for i in eautocharge_hours_index
|
||||
]
|
||||
|
||||
|
||||
ems.set_eauto_charge_hours(eautocharge_hours_float)
|
||||
return ems.simuliere(start_hour)
|
||||
|
||||
@@ -134,16 +173,17 @@ class optimization_problem:
|
||||
o = self.evaluate_inner(individual, ems, start_hour)
|
||||
except Exception as e:
|
||||
return (100000.0,) # Return a high penalty in case of an exception
|
||||
|
||||
|
||||
gesamtbilanz = o["Gesamtbilanz_Euro"] * (-1.0 if worst_case else 1.0)
|
||||
|
||||
discharge_hours_bin, eautocharge_hours_float, _ = self.split_individual(individual)
|
||||
max_ladeleistung = np.max(moegliche_ladestroeme_in_prozent)
|
||||
|
||||
# Penalty for not discharging
|
||||
# Small Penalty for not discharging
|
||||
gesamtbilanz += sum(
|
||||
0.01 for i in range(self.prediction_hours) if discharge_hours_bin[i] == 0.0
|
||||
)
|
||||
|
||||
|
||||
# Penalty for charging the electric vehicle during restricted hours
|
||||
gesamtbilanz += sum(
|
||||
self.strafe
|
||||
@@ -151,13 +191,6 @@ class optimization_problem:
|
||||
if eautocharge_hours_float[i] != 0.0
|
||||
)
|
||||
|
||||
# Penalty for exceeding maximum charge power
|
||||
gesamtbilanz += sum(
|
||||
self.strafe * 10
|
||||
for ladeleistung in eautocharge_hours_float
|
||||
if ladeleistung > max_ladeleistung
|
||||
)
|
||||
|
||||
# Penalty for not meeting the minimum SOC (State of Charge) requirement
|
||||
if parameter["eauto_min_soc"] - ems.eauto.ladezustand_in_prozent() <= 0.0:
|
||||
gesamtbilanz += sum(
|
||||
@@ -205,7 +238,7 @@ class optimization_problem:
|
||||
self.toolbox,
|
||||
mu=100,
|
||||
lambda_=200,
|
||||
cxpb=0.5,
|
||||
cxpb=0.7,
|
||||
mutpb=0.3,
|
||||
ngen=ngen,
|
||||
stats=stats,
|
||||
|
Reference in New Issue
Block a user