mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-06-28 00:46:53 +00:00
EAuto mit unterschiedlicher Ladeleistung (auch Optimierung)
2 stufige Optimierung, erst binär, dann mit float
This commit is contained in:
parent
8fffec91f3
commit
4baf758ef2
@ -30,8 +30,9 @@ class EAuto:
|
|||||||
return
|
return
|
||||||
|
|
||||||
for moeglich in self.laden_moeglich:
|
for moeglich in self.laden_moeglich:
|
||||||
if moeglich == 1 and self.soc < 100:
|
if moeglich > 0.0 and self.soc < 100:
|
||||||
geladene_energie = min(self.ladegeschwindigkeit, (100 - self.soc) / 100 * self.akku_kapazitaet)
|
# Berechnung der geladenen Energie basierend auf dem Anteil der Lademöglichkeit
|
||||||
|
geladene_energie = min(self.ladegeschwindigkeit * moeglich, (100 - self.soc) / 100 * self.akku_kapazitaet)
|
||||||
self.soc += geladene_energie / self.akku_kapazitaet * 100
|
self.soc += geladene_energie / self.akku_kapazitaet * 100
|
||||||
self.soc = min(100, self.soc)
|
self.soc = min(100, self.soc)
|
||||||
self.stuendliche_last.append(geladene_energie)
|
self.stuendliche_last.append(geladene_energie)
|
||||||
@ -42,6 +43,24 @@ class EAuto:
|
|||||||
# Umwandlung der stündlichen Last in ein NumPy-Array
|
# Umwandlung der stündlichen Last in ein NumPy-Array
|
||||||
self.stuendliche_last = np.array(self.stuendliche_last)
|
self.stuendliche_last = np.array(self.stuendliche_last)
|
||||||
|
|
||||||
|
# def berechne_ladevorgang(self):
|
||||||
|
# if self.laden_moeglich is None:
|
||||||
|
# print("Lademöglichkeit wurde nicht gesetzt.")
|
||||||
|
# return
|
||||||
|
|
||||||
|
# for moeglich in self.laden_moeglich:
|
||||||
|
# if moeglich > 1 and self.soc < 100:
|
||||||
|
# geladene_energie = min(self.ladegeschwindigkeit, (100 - self.soc) / 100 * self.akku_kapazitaet)
|
||||||
|
# self.soc += geladene_energie / self.akku_kapazitaet * 100
|
||||||
|
# self.soc = min(100, self.soc)
|
||||||
|
# self.stuendliche_last.append(geladene_energie)
|
||||||
|
# else:
|
||||||
|
# self.stuendliche_last.append(0) # Keine Ladung in dieser Stunde
|
||||||
|
# self.stuendlicher_soc.append(self.soc)
|
||||||
|
|
||||||
|
# # Umwandlung der stündlichen Last in ein NumPy-Array
|
||||||
|
# self.stuendliche_last = np.array(self.stuendliche_last)
|
||||||
|
|
||||||
def get_stuendliche_last(self):
|
def get_stuendliche_last(self):
|
||||||
"""Gibt das NumPy-Array mit der stündlichen Last zurück."""
|
"""Gibt das NumPy-Array mit der stündlichen Last zurück."""
|
||||||
return self.stuendliche_last
|
return self.stuendliche_last
|
||||||
|
@ -4,8 +4,9 @@ import numpy as np
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
class Gesamtlast:
|
class Gesamtlast:
|
||||||
def __init__(self):
|
def __init__(self, prediction_hours=24):
|
||||||
self.lasten = {} # Enthält Namen und Lasten-Arrays für verschiedene Quellen
|
self.lasten = {} # Enthält Namen und Lasten-Arrays für verschiedene Quellen
|
||||||
|
self.prediction_hours=prediction_hours
|
||||||
|
|
||||||
def hinzufuegen(self, name, last_array):
|
def hinzufuegen(self, name, last_array):
|
||||||
"""
|
"""
|
||||||
@ -14,8 +15,11 @@ class Gesamtlast:
|
|||||||
:param name: Name der Lastquelle (z.B. "Haushalt", "Wärmepumpe")
|
:param name: Name der Lastquelle (z.B. "Haushalt", "Wärmepumpe")
|
||||||
:param last_array: Array von Lasten, wobei jeder Eintrag einer Stunde entspricht
|
:param last_array: Array von Lasten, wobei jeder Eintrag einer Stunde entspricht
|
||||||
"""
|
"""
|
||||||
|
if(len(last_array) != self.prediction_hours):
|
||||||
|
raise ValueError(f"Gesamtlast Inkonsistente Längen bei den Arrays: ", name," ", len(last_array) )
|
||||||
self.lasten[name] = last_array
|
self.lasten[name] = last_array
|
||||||
|
|
||||||
|
|
||||||
def gesamtlast_berechnen(self):
|
def gesamtlast_berechnen(self):
|
||||||
"""
|
"""
|
||||||
Berechnet die gesamte Last für jede Stunde und gibt ein Array der Gesamtlasten zurück.
|
Berechnet die gesamte Last für jede Stunde und gibt ein Array der Gesamtlasten zurück.
|
||||||
|
@ -63,11 +63,11 @@ def visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecas
|
|||||||
|
|
||||||
ax1 = plt.subplot(3, 2, 5)
|
ax1 = plt.subplot(3, 2, 5)
|
||||||
for hour, value in enumerate(discharge_hours):
|
for hour, value in enumerate(discharge_hours):
|
||||||
if value == 1:
|
#if value == 1:
|
||||||
ax1.axvspan(hour, hour+1, color='red', alpha=0.3, label='Entlademöglichkeit' if hour == 0 else "")
|
ax1.axvspan(hour, hour+1, color='red',ymax=value, alpha=0.3, label='Entlademöglichkeit' if hour == 0 else "")
|
||||||
for hour, value in enumerate(laden_moeglich):
|
for hour, value in enumerate(laden_moeglich):
|
||||||
if value == 1:
|
#if value == 1:
|
||||||
ax1.axvspan(hour, hour+1, color='green', alpha=0.3, label='Lademöglichkeit' if hour == 0 else "")
|
ax1.axvspan(hour, hour+1, color='green',ymax=value, alpha=0.3, label='Lademöglichkeit' if hour == 0 else "")
|
||||||
ax1.legend(loc='upper left')
|
ax1.legend(loc='upper left')
|
||||||
|
|
||||||
|
|
||||||
|
97
test.py
97
test.py
@ -37,7 +37,7 @@ discharge_array = np.full(prediction_hours,1) #np.array([1, 0, 1, 0, 1, 1, 1, 1,
|
|||||||
laden_moeglich = np.full(prediction_hours,1) # np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0])
|
laden_moeglich = np.full(prediction_hours,1) # np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0])
|
||||||
#np.full(prediction_hours,1)
|
#np.full(prediction_hours,1)
|
||||||
eauto = EAuto(soc=10, capacity = 60000, power_charge = 7000, load_allowed = laden_moeglich)
|
eauto = EAuto(soc=10, capacity = 60000, power_charge = 7000, load_allowed = laden_moeglich)
|
||||||
min_soc_eauto = 20
|
min_soc_eauto = 100
|
||||||
hohe_strafe = 10.0
|
hohe_strafe = 10.0
|
||||||
|
|
||||||
|
|
||||||
@ -102,13 +102,18 @@ o = ems.simuliere(0)#ems.simuliere_ab_jetzt()
|
|||||||
|
|
||||||
# Optimierung
|
# Optimierung
|
||||||
|
|
||||||
# Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren)
|
def evaluate_inner(individual):
|
||||||
def evaluate(individual):
|
#print(individual)
|
||||||
|
discharge_hours_bin = individual[0::2]
|
||||||
|
eautocharge_hours_float = individual[1::2]
|
||||||
|
|
||||||
|
#print(discharge_hours_bin)
|
||||||
|
#print(len(eautocharge_hours_float))
|
||||||
ems.reset()
|
ems.reset()
|
||||||
eauto.reset()
|
eauto.reset()
|
||||||
ems.set_akku_discharge_hours(individual[:prediction_hours])
|
ems.set_akku_discharge_hours(discharge_hours_bin)
|
||||||
|
|
||||||
eauto.set_laden_moeglich(individual[prediction_hours:])
|
eauto.set_laden_moeglich(eautocharge_hours_float)
|
||||||
eauto.berechne_ladevorgang()
|
eauto.berechne_ladevorgang()
|
||||||
leistung_eauto = eauto.get_stuendliche_last()
|
leistung_eauto = eauto.get_stuendliche_last()
|
||||||
gesamtlast.hinzufuegen("eauto", leistung_eauto)
|
gesamtlast.hinzufuegen("eauto", leistung_eauto)
|
||||||
@ -116,6 +121,11 @@ def evaluate(individual):
|
|||||||
ems.set_gesamtlast(gesamtlast.gesamtlast_berechnen())
|
ems.set_gesamtlast(gesamtlast.gesamtlast_berechnen())
|
||||||
|
|
||||||
o = ems.simuliere(0)
|
o = ems.simuliere(0)
|
||||||
|
return o, eauto
|
||||||
|
|
||||||
|
# Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren)
|
||||||
|
def evaluate(individual):
|
||||||
|
o,eauto = evaluate_inner(individual)
|
||||||
gesamtbilanz = o["Gesamtbilanz_Euro"]
|
gesamtbilanz = o["Gesamtbilanz_Euro"]
|
||||||
|
|
||||||
# Überprüfung, ob der Mindest-SoC erreicht wird
|
# Überprüfung, ob der Mindest-SoC erreicht wird
|
||||||
@ -125,19 +135,24 @@ def evaluate(individual):
|
|||||||
# Fügt eine Strafe hinzu, wenn der Mindest-SoC nicht erreicht wird
|
# Fügt eine Strafe hinzu, wenn der Mindest-SoC nicht erreicht wird
|
||||||
strafe = max(0,(min_soc_eauto - final_soc) * hohe_strafe ) # `hohe_strafe` ist ein vorher festgelegter Strafwert
|
strafe = max(0,(min_soc_eauto - final_soc) * hohe_strafe ) # `hohe_strafe` ist ein vorher festgelegter Strafwert
|
||||||
gesamtbilanz += strafe
|
gesamtbilanz += strafe
|
||||||
#if strafe > 0.0:
|
|
||||||
# print(min_soc_eauto," - ",final_soc,"*10 = ",strafe)
|
|
||||||
|
|
||||||
return (gesamtbilanz,)
|
return (gesamtbilanz,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Werkzeug-Setup
|
# Werkzeug-Setup
|
||||||
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
|
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
|
||||||
creator.create("Individual", list, fitness=creator.FitnessMin)
|
creator.create("Individual", list, fitness=creator.FitnessMin)
|
||||||
|
|
||||||
toolbox = base.Toolbox()
|
toolbox = base.Toolbox()
|
||||||
|
|
||||||
toolbox.register("attr_bool", random.randint, 0, 1)
|
toolbox.register("attr_bool", random.randint, 0, 1)
|
||||||
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, prediction_hours*2)
|
toolbox.register("attr_bool", random.randint, 0, 1)
|
||||||
|
toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_bool), n=prediction_hours)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
||||||
|
|
||||||
toolbox.register("evaluate", evaluate)
|
toolbox.register("evaluate", evaluate)
|
||||||
@ -155,31 +170,69 @@ def optimize():
|
|||||||
stats.register("min", np.min)
|
stats.register("min", np.min)
|
||||||
stats.register("max", np.max)
|
stats.register("max", np.max)
|
||||||
|
|
||||||
algorithms.eaSimple(population, toolbox, cxpb=0.4, mutpb=0.3, ngen=100,
|
algorithms.eaMuPlusLambda(population, toolbox, 50, 100, cxpb=0.5, mutpb=0.5, ngen=500, stats=stats, halloffame=hof, verbose=True)
|
||||||
stats=stats, halloffame=hof, verbose=True)
|
#algorithms.eaSimple(population, toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True)
|
||||||
|
return hof[0]
|
||||||
|
|
||||||
|
|
||||||
|
start_solution = optimize()
|
||||||
|
|
||||||
|
|
||||||
|
print("Start Lösung:", start_solution)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Werkzeug-Setup
|
||||||
|
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
|
||||||
|
creator.create("Individual", list, fitness=creator.FitnessMin)
|
||||||
|
|
||||||
|
toolbox = base.Toolbox()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
toolbox.register("attr_bool", random.randint, 0, 1)
|
||||||
|
toolbox.register("attr_float", random.uniform, 0.0, 1.0)
|
||||||
|
toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_float), n=prediction_hours)
|
||||||
|
|
||||||
|
start_individual = toolbox.individual()
|
||||||
|
start_individual[:] = start_solution
|
||||||
|
|
||||||
|
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
||||||
|
|
||||||
|
toolbox.register("evaluate", evaluate)
|
||||||
|
toolbox.register("mate", tools.cxTwoPoint)
|
||||||
|
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
|
||||||
|
toolbox.register("select", tools.selTournament, tournsize=3)
|
||||||
|
|
||||||
|
# Genetischer Algorithmus
|
||||||
|
def optimize():
|
||||||
|
population = toolbox.population(n=1000)
|
||||||
|
population[0] = start_individual
|
||||||
|
hof = tools.HallOfFame(1)
|
||||||
|
|
||||||
|
stats = tools.Statistics(lambda ind: ind.fitness.values)
|
||||||
|
stats.register("avg", np.mean)
|
||||||
|
stats.register("min", np.min)
|
||||||
|
stats.register("max", np.max)
|
||||||
|
|
||||||
|
algorithms.eaMuPlusLambda(population, toolbox, 100, 200, cxpb=0.5, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True)
|
||||||
|
#algorithms.eaSimple(population, toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True)
|
||||||
return hof[0]
|
return hof[0]
|
||||||
|
|
||||||
best_solution = optimize()
|
best_solution = optimize()
|
||||||
print("Beste Lösung:", best_solution)
|
print("Beste Lösung:", best_solution)
|
||||||
|
|
||||||
#ems.set_akku_discharge_hours(best_solution)
|
#ems.set_akku_discharge_hours(best_solution)
|
||||||
ems.reset()
|
o,eauto = evaluate_inner(best_solution)
|
||||||
eauto.reset()
|
|
||||||
ems.set_akku_discharge_hours(best_solution[:prediction_hours])
|
|
||||||
eauto.set_laden_moeglich(best_solution[prediction_hours:])
|
|
||||||
eauto.berechne_ladevorgang()
|
|
||||||
leistung_eauto = eauto.get_stuendliche_last()
|
|
||||||
gesamtlast.hinzufuegen("eauto", leistung_eauto)
|
|
||||||
ems.set_gesamtlast(gesamtlast.gesamtlast_berechnen())
|
|
||||||
|
|
||||||
o = ems.simuliere(0)
|
|
||||||
|
|
||||||
soc_eauto = eauto.get_stuendlicher_soc()
|
soc_eauto = eauto.get_stuendlicher_soc()
|
||||||
print(soc_eauto)
|
print(soc_eauto)
|
||||||
pprint(o)
|
pprint(o)
|
||||||
pprint(eauto.get_stuendlicher_soc())
|
pprint(eauto.get_stuendlicher_soc())
|
||||||
|
|
||||||
visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o,soc_eauto,best_solution[:prediction_hours],best_solution[prediction_hours:] )
|
visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o,soc_eauto,best_solution[0::2],best_solution[1::2] )
|
||||||
|
|
||||||
|
|
||||||
# for data in forecast.get_forecast_data():
|
# for data in forecast.get_forecast_data():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user