Tabellarische Debugausgabe
Gibt die Anzahl zugeteilter Dienste (historisch + neu) nach Dienstart und Eltern aus, sowie abweichung zum Globalen Ziel
This commit is contained in:
parent
e6dc8ff9d4
commit
b524edc2ba
96
ausgabe.py
96
ausgabe.py
@ -249,3 +249,99 @@ class ElterndienstAusgabe:
|
|||||||
print(f"Maximale Abweichung von Global-Ziel: {max_abw_global:.2f} Dienste")
|
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(f"Maximale Abweichung von Lokal-Ziel: {max_abw_lokal:.2f} Dienste")
|
||||||
print("\nLegende: Δ = Tatsächlich - Ziel (positiv = mehr als Ziel, negativ = weniger als Ziel)")
|
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")
|
||||||
|
|||||||
@ -68,9 +68,9 @@ class Elterndienstplaner:
|
|||||||
faire_zuteilung = anteil * anzahl_dienste
|
faire_zuteilung = anteil * anzahl_dienste
|
||||||
ziel_dienste[eltern][dienst] += faire_zuteilung
|
ziel_dienste[eltern][dienst] += faire_zuteilung
|
||||||
|
|
||||||
if faire_zuteilung > 0.01:
|
#if faire_zuteilung > 0.01:
|
||||||
print(f" {tag}: {eltern} Faktor={self.daten.dienstfaktoren[eltern][tag]} "
|
# print(f" {tag}: {eltern} Faktor={self.daten.dienstfaktoren[eltern][tag]} "
|
||||||
f"-> {faire_zuteilung:.2f} von {anzahl_dienste} Diensten")
|
# f"-> {faire_zuteilung:.2f} von {anzahl_dienste} Diensten")
|
||||||
|
|
||||||
# 2. AKTUELLER PLANUNGSZEITRAUM: Faire Verteilung
|
# 2. AKTUELLER PLANUNGSZEITRAUM: Faire Verteilung
|
||||||
benoetigte_dienste_planungszeitraum = 0
|
benoetigte_dienste_planungszeitraum = 0
|
||||||
@ -467,7 +467,7 @@ class Elterndienstplaner:
|
|||||||
solver = None
|
solver = None
|
||||||
try:
|
try:
|
||||||
print("Versuche CBC Solver...")
|
print("Versuche CBC Solver...")
|
||||||
solver = pulp.PULP_CBC_CMD(msg=0, timeLimit=10)
|
solver = pulp.PULP_CBC_CMD(msg=0, timeLimit=60)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
print("Versuche GLPK Solver...")
|
print("Versuche GLPK Solver...")
|
||||||
@ -523,6 +523,7 @@ def main() -> None:
|
|||||||
if loesung is not None:
|
if loesung is not None:
|
||||||
ausgabe.schreibe_ausgabe_csv(ausgabe_datei, loesung)
|
ausgabe.schreibe_ausgabe_csv(ausgabe_datei, loesung)
|
||||||
ausgabe.drucke_statistiken(loesung)
|
ausgabe.drucke_statistiken(loesung)
|
||||||
|
ausgabe.visualisiere_dienste_uebersicht(loesung)
|
||||||
ausgabe.visualisiere_verteilungen(loesung)
|
ausgabe.visualisiere_verteilungen(loesung)
|
||||||
ausgabe.visualisiere_praeferenz_verletzungen(loesung)
|
ausgabe.visualisiere_praeferenz_verletzungen(loesung)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user