Tabellarische Debugausgabe

Gibt die Anzahl zugeteilter Dienste (historisch + neu) nach Dienstart und Eltern aus, sowie abweichung zum Globalen Ziel
This commit is contained in:
Jan Hoheisel 2026-01-25 22:07:39 +01:00
parent e6dc8ff9d4
commit b524edc2ba
2 changed files with 101 additions and 4 deletions

View File

@ -249,3 +249,99 @@ class ElterndienstAusgabe:
print(f"Maximale Abweichung von Global-Ziel: {max_abw_global:.2f} Dienste")
print(f"Maximale Abweichung von Lokal-Ziel: {max_abw_lokal:.2f} Dienste")
print("\nLegende: Δ = Tatsächlich - Ziel (positiv = mehr als Ziel, negativ = weniger als Ziel)")
def visualisiere_dienste_uebersicht(
self,
lösung: Dict[date, Dict[Dienst, List[Eltern]]]
) -> None:
"""Visualisiert die Übersicht der zugeteilten Dienste nach Optimierung
Zeigt für jede Familie und jeden Diensttyp:
- Anzahl Dienste nach Optimierung (Historie + Planungszeitraum)
- Differenz zum globalen Ziel (Historie + Planungszeitraum)
Args:
lösung: Die Lösung der Optimierung
"""
if self.ziel_global is None:
print("FEHLER: Globale Zielverteilung wurde nicht gesetzt!")
return
# Berechne historische Dienste pro Eltern und Dienst
historisch = defaultdict(lambda: defaultdict(int))
for datum, eltern, dienst in self.daten.historische_dienste:
historisch[eltern][dienst] += 1
# Berechne geplante Dienste (aus Lösung)
geplant = defaultdict(lambda: defaultdict(int))
for tag_dienste in lösung.values():
for dienst, eltern_liste in tag_dienste.items():
for eltern in eltern_liste:
geplant[eltern][dienst] += 1
# Berechne globale Ziele für jeden Elternteil und Dienst
# Das globale Ziel ist: faire Verteilung über (Historie + Planungszeitraum) MINUS bereits geleistete Historie
# Also: ziel_global[eltern][dienst] ist die SOLL-Änderung im Planungszeitraum
# Tatsächliches Gesamt-Ziel = historisch[eltern][dienst] + ziel_global[eltern][dienst]
print("\n" + "="*120)
print("ÜBERSICHT: Dienst nach der Optimierung")
print("="*120)
# Tabelle: NACH der Optimierung (historisch + geplant)
print("\n>>> NACH OPTIMIERUNG (historische Dienste + Planungszeitraum) <<<\n")
# Header
print(f"{'Eltern':<20} ", end='')
for dienst in self.daten.dienste:
print(f"{dienst.kuerzel:>14} ", end='')
print(f"{'GESAMT':>14}")
print(f"{'':20} ", end='')
for dienst in self.daten.dienste:
print(f"{'Ist / Δ Ziel':>14} ", end='')
print(f"{'Ist / Δ Ziel':>14}")
print("-" * 120)
# Datenzeilen
for eltern in sorted(self.daten.eltern):
print(f"{eltern:<20} ", end='')
gesamt_ist = 0
gesamt_ziel = 0
for dienst in self.daten.dienste:
ist_dienste = historisch[eltern][dienst] + geplant[eltern][dienst]
gesamt_ist += ist_dienste
# Globales Ziel = historisch + ziel_global (das ist das faire Gesamt-Ziel)
ziel_gesamt = historisch[eltern][dienst] + self.ziel_global[eltern][dienst]
gesamt_ziel += ziel_gesamt
delta = ist_dienste - ziel_gesamt
# Farbcodierung
farbe = ""
reset = ""
if abs(delta) > 0.5:
farbe = "\033[93m" if abs(delta) <= 1.5 else "\033[91m"
reset = "\033[0m"
print(f"{farbe}{ist_dienste:>6} / {delta:>+5.1f}{reset} ", end='')
# Gesamt-Spalte
delta_gesamt = gesamt_ist - gesamt_ziel
farbe = ""
reset = ""
if abs(delta_gesamt) > 0.5:
farbe = "\033[93m" if abs(delta_gesamt) <= 1.5 else "\033[91m"
reset = "\033[0m"
print(f"{farbe}{gesamt_ist:>6} / {delta_gesamt:>+5.1f}{reset}")
print()
print("Legende:")
print(" Ist = Anzahl tatsächlich geleisteter Dienste")
print(" Δ Ziel = Differenz zum globalen fairen Ziel (positiv = mehr als fair, negativ = weniger)")
print(" \033[93mGelb\033[0m = Abweichung 0.5 - 1.5 Dienste")
print(" \033[91mRot\033[0m = Abweichung > 1.5 Dienste")

View File

@ -68,9 +68,9 @@ class Elterndienstplaner:
faire_zuteilung = anteil * anzahl_dienste
ziel_dienste[eltern][dienst] += faire_zuteilung
if faire_zuteilung > 0.01:
print(f" {tag}: {eltern} Faktor={self.daten.dienstfaktoren[eltern][tag]} "
f"-> {faire_zuteilung:.2f} von {anzahl_dienste} Diensten")
#if faire_zuteilung > 0.01:
# print(f" {tag}: {eltern} Faktor={self.daten.dienstfaktoren[eltern][tag]} "
# f"-> {faire_zuteilung:.2f} von {anzahl_dienste} Diensten")
# 2. AKTUELLER PLANUNGSZEITRAUM: Faire Verteilung
benoetigte_dienste_planungszeitraum = 0
@ -467,7 +467,7 @@ class Elterndienstplaner:
solver = None
try:
print("Versuche CBC Solver...")
solver = pulp.PULP_CBC_CMD(msg=0, timeLimit=10)
solver = pulp.PULP_CBC_CMD(msg=0, timeLimit=60)
except:
try:
print("Versuche GLPK Solver...")
@ -523,6 +523,7 @@ def main() -> None:
if loesung is not None:
ausgabe.schreibe_ausgabe_csv(ausgabe_datei, loesung)
ausgabe.drucke_statistiken(loesung)
ausgabe.visualisiere_dienste_uebersicht(loesung)
ausgabe.visualisiere_verteilungen(loesung)
ausgabe.visualisiere_praeferenz_verletzungen(loesung)