From 2f0609b570ead228046ef973d91537f7c05f5709 Mon Sep 17 00:00:00 2001 From: Jan Hoheisel Date: Thu, 25 Dec 2025 19:53:05 +0100 Subject: [PATCH] refactoring: monat in planungszeitraum umbenannt --- elterndienstplaner.py | 71 +++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/elterndienstplaner.py b/elterndienstplaner.py index eabbc96..06bd519 100755 --- a/elterndienstplaner.py +++ b/elterndienstplaner.py @@ -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