From d3b82827af991a7f76ed1ddb53120895878f6c38 Mon Sep 17 00:00:00 2001 From: Jan Hoheisel Date: Tue, 23 Dec 2025 23:00:01 +0100 Subject: [PATCH] constraint ein dienst pro woche um historische dienste erweitert --- elterndienstplaner.py | 36 +++++++++++++++++++++++++++--------- test/simple/ausgabe.csv | 32 ++++++++++++++++---------------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/elterndienstplaner.py b/elterndienstplaner.py index c7bd4c7..1bcc3aa 100755 --- a/elterndienstplaner.py +++ b/elterndienstplaner.py @@ -272,22 +272,40 @@ class Elterndienstplaner: prob: pulp.LpProblem, x: Dict[Tuple[str, date, Dienst], pulp.LpVariable] ) -> None: - """C1: Je Eltern und Dienst nur einmal die Woche""" - woche_start = self.tage[0] + """C1: Je Eltern und Dienst nur einmal die Woche (Woche = Montag bis Sonntag)""" + erster_tag = self.tage[0] + # weekday(): 0=Montag, 6=Sonntag + # Finde Montag am oder vor dem ersten Planungstag (für historische Dienste) + woche_start = erster_tag - timedelta(days=erster_tag.weekday()) + woche_nr = 0 - while woche_start <= self.tage[-1]: - woche_ende = min(woche_start + timedelta(days=6), self.tage[-1]) - woche_tage = [t for t in self.tage if woche_start <= t <= woche_ende] + letzter_tag = self.tage[-1] + + while woche_start <= letzter_tag: + woche_ende = woche_start + timedelta(days=6) # Sonntag for eltern in self.eltern: for dienst in self.dienste: woche_vars = [] - for tag in woche_tage: - if (eltern, tag, dienst) in x: - woche_vars.append(x[eltern, tag, dienst]) + # Zähle historische Dienste in dieser Woche (VOR dem Planungszeitraum) + historische_dienste_in_woche = 0 + if woche_start < erster_tag: + for hist_datum, hist_eltern, hist_dienst in self.historische_dienste: + if (hist_eltern == eltern and + hist_dienst == dienst and + woche_start <= hist_datum < erster_tag): + historische_dienste_in_woche += 1 + + # Sammle Variablen für Planungszeitraum in dieser Woche + for tag in self.tage: + if woche_start <= tag <= woche_ende: + if (eltern, tag, dienst) in x: + woche_vars.append(x[eltern, tag, dienst]) + + # Constraint: Historische + geplante Dienste <= 1 if woche_vars: - prob += pulp.lpSum(woche_vars) <= 1, \ + prob += pulp.lpSum(woche_vars) <= 1 - historische_dienste_in_woche, \ f"C1_{eltern.replace(' ', '_')}_{dienst.kuerzel}_w{woche_nr}" woche_start += timedelta(days=7) diff --git a/test/simple/ausgabe.csv b/test/simple/ausgabe.csv index 6bdca70..2bbbedc 100644 --- a/test/simple/ausgabe.csv +++ b/test/simple/ausgabe.csv @@ -1,24 +1,24 @@ Datum,Wochentag,Frühstücksdienst,Putznotdienst,Essensausgabenotdienst,Kochen,Elternabend -2026-01-01,Donnerstag,Paula,Marie,Jonas,, +2026-01-01,Donnerstag,Ben & Nele,Marie,Jonas,, 2026-01-02,Freitag,Jonas,Ben & Nele,Laura,, 2026-01-03,Samstag,Marie,Jonas,Ben & Nele,, -2026-01-06,Dienstag,Laura,Paula,Erwin,, -2026-01-07,Mittwoch,Ben & Nele,Erwin,Marie,, -2026-01-08,Donnerstag,Jonas,Paula,Marie,Ben & Nele, -2026-01-09,Freitag,Erwin,Marie,Paula,, -2026-01-10,Samstag,Paula,Laura,Ben & Nele,, +2026-01-06,Dienstag,Laura,Jonas,Marie,, +2026-01-07,Mittwoch,Paula,Ben & Nele,Jonas,, +2026-01-08,Donnerstag,Jonas,Paula,Erwin,Ben & Nele, +2026-01-09,Freitag,Ben & Nele,Marie,Paula,, +2026-01-10,Samstag,Marie,Laura,Ben & Nele,, 2026-01-13,Dienstag,Ben & Nele,Jonas,Laura,, -2026-01-14,Mittwoch,Marie,Ben & Nele,Jonas,, -2026-01-15,Donnerstag,Laura,Jonas,Erwin,, +2026-01-14,Mittwoch,Paula,Erwin,Jonas,, +2026-01-15,Donnerstag,Laura,Paula,Marie,, 2026-01-16,Freitag,Marie,Laura,Ben & Nele,, -2026-01-17,Samstag,Jonas,Ben & Nele,Paula,, -2026-01-20,Dienstag,Ben & Nele,Erwin,Marie,, -2026-01-21,Mittwoch,Erwin,Marie,Jonas,, +2026-01-17,Samstag,Erwin,Ben & Nele,Paula,, +2026-01-20,Dienstag,Jonas,Erwin,Marie,, +2026-01-21,Mittwoch,Erwin,Ben & Nele,Jonas,, 2026-01-22,Donnerstag,Ben & Nele,Marie,Laura,Jonas, -2026-01-23,Freitag,Marie,Jonas,Ben & Nele,, -2026-01-24,Samstag,Laura,Erwin,Marie,,Ben & Nele Jonas +2026-01-23,Freitag,Marie,Laura,Ben & Nele,, +2026-01-24,Samstag,Laura,Jonas,Erwin,,Ben & Nele Marie 2026-01-27,Dienstag,Erwin,Ben & Nele,Jonas,, -2026-01-28,Mittwoch,Jonas,Paula,Erwin,, -2026-01-29,Donnerstag,Marie,Ben & Nele,Jonas,, +2026-01-28,Mittwoch,Jonas,Erwin,Marie,, +2026-01-29,Donnerstag,Marie,Paula,Ben & Nele,, 2026-01-30,Freitag,Ben & Nele,Jonas,Paula,, -2026-01-31,Samstag,Paula,Marie,Ben & Nele,, +2026-01-31,Samstag,Paula,Marie,Erwin,,