mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 00:45:22 +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:
parent
e65eb6b6dd
commit
6881710295
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
# Import necessary modules from the project
|
||||
from akkudoktoreos.class_optimize import optimization_problem
|
||||
@ -241,7 +242,7 @@ parameter = {
|
||||
# Electricity price forecast (48 hours)
|
||||
"strompreis_euro_pro_wh": strompreis_euro_pro_wh,
|
||||
# Minimum SOC for electric car
|
||||
"eauto_min_soc": 80,
|
||||
"eauto_min_soc": 20,
|
||||
# Electric car battery capacity (Wh)
|
||||
"eauto_cap": 60000,
|
||||
# Charging efficiency of the electric car
|
||||
@ -262,6 +263,9 @@ parameter = {
|
||||
"min_soc_prozent": 15,
|
||||
}
|
||||
|
||||
# Startzeit nehmen
|
||||
start_time = time.time()
|
||||
|
||||
# Initialize the optimization problem
|
||||
opt_class = optimization_problem(
|
||||
prediction_hours=48, strafe=10, optimization_hours=24, verbose=True, fixed_seed=42
|
||||
@ -270,8 +274,16 @@ opt_class = optimization_problem(
|
||||
# Perform the optimisation based on the provided parameters and start hour
|
||||
ergebnis = opt_class.optimierung_ems(parameter=parameter, start_hour=start_hour)
|
||||
|
||||
# Endzeit nehmen
|
||||
end_time = time.time()
|
||||
|
||||
# Berechnete Zeit ausgeben
|
||||
elapsed_time = end_time - start_time
|
||||
print(f"Elapsed time: {elapsed_time:.4f} seconds")
|
||||
|
||||
|
||||
# Print or visualize the result
|
||||
# pprint(ergebnis)
|
||||
|
||||
json_data = json.dumps(ergebnis)
|
||||
print(json_data)
|
||||
#json_data = json.dumps(ergebnis)
|
||||
#print(json_data)
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user