praeferenz-statistik und schonfrist
This commit is contained in:
parent
613ffef9b6
commit
33b8a0047c
@ -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!")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user