praeferenz-statistik und schonfrist

This commit is contained in:
Jan Hoheisel 2025-12-24 23:56:11 +01:00
parent 613ffef9b6
commit 33b8a0047c

View File

@ -479,8 +479,8 @@ class Elterndienstplaner:
objective_terms = [] objective_terms = []
# Fairness-Gewichtung # Fairness-Gewichtung
gewicht_global = 10 gewicht_global = 40
gewicht_lokal = 50 gewicht_lokal = 60
gewicht_f1 = gewicht_global gewicht_f1 = gewicht_global
gewicht_f2 = gewicht_lokal gewicht_f2 = gewicht_lokal
gewicht_f3_global = 0.25 * gewicht_global gewicht_f3_global = 0.25 * gewicht_global
@ -649,6 +649,114 @@ class Elterndienstplaner:
faktor_summe = sum(self.dienstfaktoren[eltern][tag] for tag in self.tage) faktor_summe = sum(self.dienstfaktoren[eltern][tag] for tag in self.tage)
print(f" {eltern:15} {faktor_summe:.1f}") print(f" {eltern:15} {faktor_summe:.1f}")
def visualisiere_praeferenz_verletzungen(
self,
lösung: Dict[date, Dict[Dienst, List[str]]]
) -> None:
"""Visualisiert verletzte Präferenzen als Tabelle
Args:
lösung: Die tatsächliche Lösung nach Optimierung
"""
print("\n" + "="*110)
print("PRÄFERENZ-VERLETZUNGEN")
print("="*110)
# Sammle alle zugeteilten Dienste pro Eltern
zugeteilte_dienste = defaultdict(lambda: defaultdict(list)) # eltern -> dienst -> [dates]
for tag, tag_dienste in lösung.items():
for dienst, eltern_liste in tag_dienste.items():
for eltern in eltern_liste:
zugeteilte_dienste[eltern][dienst].append(tag)
# Sammle Präferenzen strukturiert
# praeferenzen_pro_eltern_dienst[eltern][dienst] = {datum: präf_wert}
praeferenzen_pro_eltern_dienst = defaultdict(lambda: defaultdict(dict))
for (eltern, tag, dienst), präf in self.präferenzen.items():
praeferenzen_pro_eltern_dienst[eltern][dienst][tag] = präf
# Berechne Verletzungen
verletzungen = defaultdict(lambda: defaultdict(lambda: {'negativ': 0, 'positiv_nicht_erfuellt': 0}))
for eltern in sorted(self.eltern):
for dienst in self.dienste:
zugeteilte_tage = zugeteilte_dienste[eltern][dienst]
praeferenzen_dienst = praeferenzen_pro_eltern_dienst[eltern][dienst]
if not zugeteilte_tage:
continue # Keine Dienste zugeteilt
# a) Negative Präferenzen die verletzt wurden
for tag in zugeteilte_tage:
if tag in praeferenzen_dienst and praeferenzen_dienst[tag] == -1:
verletzungen[eltern][dienst]['negativ'] += 1
# b) Positive Präferenzen nicht erfüllt (Dienst an nicht-präferiertem Tag)
# Sammle alle Tage mit positiver Präferenz für diesen Dienst
positive_praef_tage = {tag for tag, präf in praeferenzen_dienst.items() if präf == 1}
if positive_praef_tage: # Es gibt positive Präferenzen
# Prüfe ob ALLE zugeteilten Dienste an nicht-präferierten Tagen sind
for tag in zugeteilte_tage:
if tag not in positive_praef_tage:
# Dienst wurde an nicht-präferiertem Tag zugeteilt
verletzungen[eltern][dienst]['positiv_nicht_erfuellt'] += 1
# Tabelle ausgeben
print(f"\n{'Eltern':<20} ", end='')
for dienst in self.dienste:
print(f"{dienst.kuerzel:>12}", end='')
print()
print(f"{'':20} ", end='')
for dienst in self.dienste:
print(f"{'neg, pos':>12}", end='')
print()
print("-" * (20 + 12 * len(self.dienste)))
gesamt_negativ = defaultdict(int)
gesamt_positiv = defaultdict(int)
for eltern in sorted(self.eltern):
print(f"{eltern:<20} ", end='')
for dienst in self.dienste:
neg = verletzungen[eltern][dienst]['negativ']
pos = verletzungen[eltern][dienst]['positiv_nicht_erfuellt']
gesamt_negativ[dienst] += neg
gesamt_positiv[dienst] += pos
# Farbcodierung
farbe = ""
reset = ""
if neg > 0 or pos > 0:
farbe = "\033[91m" if neg > 0 else "\033[93m" # Rot für negativ, Gelb für positiv
reset = "\033[0m"
print(f"{farbe}{neg:>3}, {pos:>3}{reset:>6}", end='')
print()
# Summenzeile
print("-" * (20 + 12 * len(self.dienste)))
print(f"{'SUMME':<20} ", end='')
for dienst in self.dienste:
neg = gesamt_negativ[dienst]
pos = gesamt_positiv[dienst]
farbe = ""
reset = ""
if neg > 0 or pos > 0:
farbe = "\033[91m" if neg > 0 else "\033[93m"
reset = "\033[0m"
print(f"{farbe}{neg:>3}, {pos:>3}{reset:>6}", end='')
print()
print("\nLegende:")
print(" neg = Anzahl negativer Präferenzen (abgelehnte Tage), die verletzt wurden")
print(" pos = Anzahl Dienste an nicht-präferierten Tagen (obwohl präferierte Tage angegeben waren)")
print(" \033[91mRot\033[0m = Negative Präferenz verletzt")
print(" \033[93mGelb\033[0m = Positive Präferenz nicht erfüllt")
def visualisiere_verteilungen( def visualisiere_verteilungen(
self, self,
lösung: Dict[date, Dict[Dienst, List[str]]], lösung: Dict[date, Dict[Dienst, List[str]]],
@ -765,6 +873,9 @@ def main() -> None:
# Visualisierung der Verteilungen # Visualisierung der Verteilungen
planer.visualisiere_verteilungen(lösung, ziel_lokal, ziel_global) planer.visualisiere_verteilungen(lösung, ziel_lokal, ziel_global)
# Visualisierung der Präferenz-Verletzungen
planer.visualisiere_praeferenz_verletzungen(lösung)
print("\n✓ Planung erfolgreich abgeschlossen!") print("\n✓ Planung erfolgreich abgeschlossen!")
else: else:
print("\n✗ Fehler: Keine gültige Lösung gefunden!") print("\n✗ Fehler: Keine gültige Lösung gefunden!")