refactoring: monat in planungszeitraum umbenannt

This commit is contained in:
Jan Hoheisel 2025-12-25 19:53:05 +01:00
parent 909e8ff9a0
commit 2f0609b570

View File

@ -99,7 +99,7 @@ class Elterndienstplaner:
def berechne_faire_zielverteilung_global(self) -> DefaultDict[str, DefaultDict[Dienst, float]]:
"""Berechnet die faire Zielanzahl von Diensten für den Planungszeitraum
basierend auf globaler Fairness (Historie + aktueller Monat).
basierend auf globaler Fairness (Historie + aktueller Planungszeitraum).
Gibt die Ziel-Dienstanzahl für den aktuellen Planungszeitraum zurück,
korrigiert um bereits geleistete Dienste. Kann negativ sein, wenn bereits
@ -152,16 +152,16 @@ class Elterndienstplaner:
print(f" {tag}: {eltern} Faktor={self.dienstfaktoren[eltern][tag]} "
f"-> {faire_zuteilung:.2f} von {anzahl_dienste} Diensten")
# 2. AKTUELLER MONAT: Faire Verteilung der benötigten Dienste (tageweise wie bei historischen Diensten)
benoetigte_dienste_monat = 0
# 2. AKTUELLER PLANUNGSZEITRAUM: Faire Verteilung der benötigten Dienste (tageweise wie bei historischen Diensten)
benoetigte_dienste_planungszeitraum = 0
# Für jeden Tag im aktuellen Monat faire Umverteilung berechnen
# Für jeden Tag im aktuellen Planungszeitraum faire Umverteilung berechnen
for tag in self.planungszeitraum:
# Prüfe ob an diesem Tag der Dienst benötigt wird
if dienst not in self.benoetigte_dienste.get(tag, []):
continue
benoetigte_dienste_monat += dienst.personen_anzahl
benoetigte_dienste_planungszeitraum += dienst.personen_anzahl
# Dienstfaktoren aller Eltern für diesen Tag berechnen
dienstfaktoren = {}
@ -193,45 +193,45 @@ class Elterndienstplaner:
def berechne_faire_zielverteilung_lokal(self) -> DefaultDict[str, DefaultDict[Dienst, float]]:
"""Berechnet die lokale faire Zielanzahl von Diensten pro Eltern-Dienst-Kombination
basierend auf Dienstfaktoren und benötigten Diensten im aktuellen Planungsmonat"""
basierend auf Dienstfaktoren und benötigten Diensten im aktuellen Planungszeitraum"""
ziel_dienste_lokal: DefaultDict[str, DefaultDict[Dienst, float]] = \
defaultdict(lambda: defaultdict(float))
print("\nBerechne lokale faire Zielverteilung für aktuellen Monat...")
print("\nBerechne lokale faire Zielverteilung für aktuellen Planungszeitraum...")
# Gesamtdienstfaktor für aktuellen Monat berechnen
gesamt_dienstfaktor_monat = sum(
# Gesamtdienstfaktor für aktuellen Planungszeitraum berechnen
summe_dienstfaktor_planungszeitraum_alle_eltern = sum(
sum(self.dienstfaktoren[e][tag] for tag in self.planungszeitraum)
for e in self.eltern
)
if gesamt_dienstfaktor_monat == 0:
if summe_dienstfaktor_planungszeitraum_alle_eltern == 0:
print(" WARNUNG: Gesamtdienstfaktor ist 0, keine lokale Zielverteilung möglich")
return ziel_dienste_lokal
# Für jeden Dienst die lokale faire Verteilung berechnen
for dienst in self.dienste:
# Anzahl benötigter Dienste im aktuellen Monat
benoetigte_dienste_monat = sum(
# Anzahl benötigter Dienste im aktuellen Planungszeitraum
benoetigte_dienste_planungszeitraum = sum(
1 for tag in self.planungszeitraum
if dienst in self.benoetigte_dienste.get(tag, [])
)
# Multipliziere mit Anzahl benötigter Personen pro Dienst
benoetigte_dienste_monat *= dienst.personen_anzahl
benoetigte_dienste_planungszeitraum *= dienst.personen_anzahl
if benoetigte_dienste_monat > 0:
print(f" {dienst.kuerzel}: {benoetigte_dienste_monat} Dienste benötigt")
if benoetigte_dienste_planungszeitraum > 0:
print(f" {dienst.kuerzel}: {benoetigte_dienste_planungszeitraum} Dienste benötigt")
for eltern in self.eltern:
# Dienstfaktor für diesen Elternteil im aktuellen Monat
monatlicher_dienstfaktor = sum(
# Dienstfaktor für diesen Elternteil im aktuellen Planungszeitraum
summe_dienstfaktor_planungszeitraum = sum(
self.dienstfaktoren[eltern][tag] for tag in self.planungszeitraum
)
if monatlicher_dienstfaktor > 0:
anteil = monatlicher_dienstfaktor / gesamt_dienstfaktor_monat
faire_zuteilung = anteil * benoetigte_dienste_monat
if summe_dienstfaktor_planungszeitraum > 0:
anteil = summe_dienstfaktor_planungszeitraum / summe_dienstfaktor_planungszeitraum_alle_eltern
faire_zuteilung = anteil * benoetigte_dienste_planungszeitraum
ziel_dienste_lokal[eltern][dienst] = faire_zuteilung
return ziel_dienste_lokal
@ -374,8 +374,8 @@ class Elterndienstplaner:
# Fairness-Constraints hinzufügen
for eltern in self.eltern:
for dienst in self.dienste:
# Tatsächliche Dienste im aktuellen Monat
tatsaechliche_dienste_monat = pulp.lpSum(
# Tatsächliche Dienste im aktuellen Planungszeitraum
zugeteilte_dienste_planungszeitraum = pulp.lpSum(
x[eltern, tag, dienst]
for tag in self.planungszeitraum
if (eltern, tag, dienst) in x
@ -383,9 +383,9 @@ class Elterndienstplaner:
# Ziel für diese Fairness-Variante
ziel = ziel_dienste[eltern][dienst]
prob += (tatsaechliche_dienste_monat - ziel <=
prob += (zugeteilte_dienste_planungszeitraum - ziel <=
fairness_abweichung[eltern, dienst])
prob += (ziel - tatsaechliche_dienste_monat <=
prob += (ziel - zugeteilte_dienste_planungszeitraum <=
fairness_abweichung[eltern, dienst])
return fairness_abweichung
@ -438,27 +438,6 @@ class Elterndienstplaner:
return fairness_abweichung_gesamt
def _berechne_fairness_gewichte(self) -> Tuple[int, int, int, int]:
"""Berechnet Gewichtung basierend auf Jahreszeit (Sep-Jul Schuljahr)"""
aktueller_monat = self.planungszeitraum[0].month if self.planungszeitraum else 1
if 9 <= aktueller_monat <= 12: # Sep-Dez: Jahresanfang
gewicht_f1 = 100 # Global wichtiger
gewicht_f2 = 50 # Lokal weniger wichtig
gewicht_f3_global = 30 # Gesamtfairness global
gewicht_f3_lokal = 15 # Gesamtfairness lokal
elif 1 <= aktueller_monat <= 3: # Jan-Mar: Jahresmitte
gewicht_f1 = 75
gewicht_f2 = 75
gewicht_f3_global = 25
gewicht_f3_lokal = 25
else: # Apr-Jul: Jahresende
gewicht_f1 = 50 # Global weniger wichtig
gewicht_f2 = 100 # Lokal wichtiger
gewicht_f3_global = 15
gewicht_f3_lokal = 30
return gewicht_f1, gewicht_f2, gewicht_f3_global, gewicht_f3_lokal
def _erstelle_zielfunktion(
self,
@ -761,7 +740,7 @@ class Elterndienstplaner:
Args:
lösung: Die tatsächliche Lösung nach Optimierung
ziel_lokal: Lokale Zielverteilung (nur aktueller Monat)
ziel_lokal: Lokale Zielverteilung (nur aktueller Planungszeitraum)
ziel_global: Globale Zielverteilung (inkl. Historie)
"""
# Tatsächliche Dienste zählen