in der Roademap weitergemacht
This commit is contained in:
+56
-21
@@ -160,10 +160,17 @@ Die folgenden Grundsatzfragen sind entschieden und gelten für alle Meilensteine
|
||||
|
||||
- [x] Python 2 → 3 Migration (bereits erledigt)
|
||||
- [x] Unittest-Suite mit Kernszenarien (bereits erledigt)
|
||||
- [ ] `Farm` erweitern: `TopN()` statt nur `Bester()` — Grundlage für "mehrere Varianten"
|
||||
später. Kleine, risikoarme Änderung am bestehenden Code.
|
||||
- [ ] Determinismus-Option: `random.seed()` als Parameter durchreichen, damit ein Ergebnis
|
||||
bei Bedarf reproduzierbar ist (Support-Anfragen: "warum sitzt Tante Erna da?")
|
||||
- [x] `Farm` erweitern: `TopN()` statt nur `Bester()` — Grundlage für "mehrere Varianten"
|
||||
später. Umgesetzt in `libs/ga.py` (`Farm.TopN(n)`: die `n` besten Lösungen absteigend,
|
||||
geclamped auf `[0, len(Pool)]`).
|
||||
- [x] Determinismus-Option: `random.seed()` als Parameter durchreichen, damit ein Ergebnis
|
||||
bei Bedarf reproduzierbar ist (Support-Anfragen: "warum sitzt Tante Erna da?").
|
||||
Umgesetzt als `--seed <int>` in `libs/platz.py`. **Wichtig:** der RNG-Seed allein
|
||||
reichte nicht — `Person` hasht im `set()` einer `Gruppe` sonst über `id()`
|
||||
(Speicheradresse), wodurch `set.pop()`-Reihenfolge in `Gruppe.teilen()` pro Prozess
|
||||
variierte. Behoben durch Id-basiertes `__hash__`/`__eq__` an `Person`
|
||||
(`libs/Strukturdaten.py`); Integer-Ids sind zudem `PYTHONHASHSEED`-unabhängig. Auf
|
||||
`work/hochzeit` verifiziert: gleicher Seed → bytegleicher Plan, anderer Seed → abweichend.
|
||||
- [x] Rechtsform geklärt: Betrieb über die bestehende **MiSta GmbH** (Impressum), keine
|
||||
Neugründung — Ausgründung aus der Holding erst bei Erfolg (Konzeptentscheidung Nr. 7)
|
||||
- [x] Namensfrage geklärt: **"Sitz & Platz"** für Deutschland, **Sitzwunder/SeatWonder**
|
||||
@@ -201,11 +208,22 @@ Session-basiert, nichts wird dauerhaft gespeichert (schont Datenschutz-Aufwand i
|
||||
- [x] Einfache Browser-Testoberfläche (`web/static/index.html`): Tisch-Tabelle mit
|
||||
Presets, CSV-Textfeld/-Upload, Berechnen-Button, Kennzahlen + SVG-Anzeige —
|
||||
Zwischenschritt, wird durch den Konva-Tisch-Editor (unten) abgelöst
|
||||
- [ ] **Interaktiver Tisch-Editor** (Frontend, React/Vue + SVG):
|
||||
Kreise per Drag & Drop platzieren, Kapazität einstellen, Nachbarschaft automatisch
|
||||
aus räumlicher Nähe ableiten (statt manueller `Nachbarliste`-Pflege in `tische.ini`)
|
||||
- [x] **Interaktiver Tisch-Editor** (Frontend): Kreise per Drag & Drop platzieren,
|
||||
Kapazität einstellen (+/−/Direkteingabe), Tische hinzufügen/löschen, Nachbarschaft
|
||||
live aus räumlicher Nähe abgeleitet (gleiche Radius-Logik wie `_NachbarnAbleiten`
|
||||
im Backend, Radius per Slider). Umgesetzt als `web/static/editor.html` —
|
||||
**buildfrei, Inline-SVG + Vanilla-JS** statt React/Konva, weil das bestehende
|
||||
Frontend keine Build-Toolchain (npm/package.json) hat; das State-Modell
|
||||
(`{id, plaetze, x, y}`) ist dasselbe wie für eine spätere Konva-Portierung.
|
||||
Backend um `GET /sitzung/{id}/tische` (Layout-Round-Trip) ergänzt, Session wird
|
||||
per `localStorage` mit der Testoberfläche geteilt. Nebenbei behoben: fehlender
|
||||
`import configparser` in `web/main.py` (der `/tische-datei`-Upload wäre sonst mit
|
||||
`NameError` abgestürzt).
|
||||
- Baut direkt auf `alsSVG()`-Geometrie auf (Radius-Berechnung ist bereits da)
|
||||
- [ ] Undo/Redo, "Variante neu berechnen"-Button
|
||||
- [x] **Undo/Redo** im Editor: Snapshot-History (Stapel je Vor-Zustand von `state.tische`),
|
||||
ein Drag zählt als ein Schritt; Tastatur `Strg+Z` / `Strg+Y` (bzw. `Strg+Shift+Z`),
|
||||
`Entf` löscht den ausgewählten Tisch. "Variante neu berechnen" liegt bereits als
|
||||
wiederholter `POST .../berechnen` in der Testoberfläche vor (jeder Klick = neue Variante).
|
||||
- [ ] Hosting: einfacher Single-Server-Betrieb bei **Hetzner** reicht (Konzeptentscheidung
|
||||
Nr. 6 — kein Kubernetes-Overkill für MVP)
|
||||
|
||||
@@ -225,15 +243,28 @@ verarbeitet werden (was bei jedem Webserver der Fall ist).
|
||||
|
||||
**Ziel:** Nutzer bekommt mehrere Vorschläge statt einer festen Lösung, kann vergleichen.
|
||||
|
||||
- [ ] `Farm.TopN(n)` nutzen, um z.B. 3–5 unterschiedliche gute Lösungen zurückzugeben
|
||||
(ggf. mit verschiedenen Zufalls-Seeds parallel starten für Diversität)
|
||||
- [ ] Vergleichsansicht im Frontend: Varianten nebeneinander, Kennzahlen sichtbar machen
|
||||
(Wertigkeit, Anzahl Gruppentrennungen, "Alleine sitzende Personen")
|
||||
- [ ] Performance: bei sehr großen Sälen (200+ Personen) ggf. `Zyklus`-Parameter
|
||||
(Anzahl Generationen/Population) an Problemgröße koppeln, damit Antwortzeit
|
||||
im Web-Kontext (Sekunden, nicht Minuten) bleibt — Lasttest nötig
|
||||
- [ ] Optional: Hintergrund-Job-Queue (z.B. Celery/RQ), falls Berechnung >5s dauert,
|
||||
damit der Webserver nicht blockiert
|
||||
- [x] `Farm.TopN(n)` nutzen, um z.B. 3–5 unterschiedliche gute Lösungen zurückzugeben:
|
||||
`POST /berechnen?varianten=N` (1–5, Default 3) nimmt `TopN` über den ganzen Endpool
|
||||
und dedupliziert über eine Sitzordnungs-Signatur (`frozenset` aus Tisch-Id ×
|
||||
Personen-Ids), damit Mutations-Verwandte mit identischer Sitzordnung nicht als
|
||||
"Varianten" zählen. Liefert der Pool weniger unterschiedliche Sitzordnungen, kommen
|
||||
weniger zurück; ein weiterer Berechnen-Klick startet einen frischen Lauf.
|
||||
Seed-parallele Läufe für noch mehr Diversität ("ggf.") waren nicht nötig —
|
||||
ein Lauf liefert im Test bereits 3 paarweise verschiedene Varianten.
|
||||
`GET /ergebnis.svg?variante=k` rendert jede Variante einzeln.
|
||||
- [x] Vergleichsansicht im Frontend: Varianten-Karten nebeneinander mit Kennzahlen
|
||||
(Wertigkeit, getrennte Gruppen + Teilungen gesamt, allein sitzende Personen —
|
||||
letzteres via `LeuteAllein()`, zählt nur Personen aus mehrköpfigen Gruppen ohne
|
||||
Gruppenmitglied am Tisch); Klick auf eine Karte schaltet Tische-/Gruppen-Tabellen
|
||||
und den SVG-Raumplan auf die Variante um.
|
||||
- [x] Performance: Lasttest erledigt (2026-07-12) — `work/innenhoefe` (300 Gäste,
|
||||
88 Tische) rechnet mit dem **Adaptiv**-Profil (Web-Default) in ~1,7–1,9 s
|
||||
(5–7 Generationen, inkl. Python-Start), Easy in ~0,3 s. Beides weit unter der
|
||||
5-s-Schwelle → `Zyklus`-Parameter-Kopplung an die Problemgröße ist **nicht nötig**;
|
||||
erst wieder prüfen, falls Zyklen deutlich vergrößert werden (siehe Risiko Nr. 2).
|
||||
- [x] Optional: Hintergrund-Job-Queue (z.B. Celery/RQ), falls Berechnung >5s dauert —
|
||||
**entfällt nach dem Lasttest** (s.o.): Adaptiv bleibt bei ~2 s, der Webserver
|
||||
blockiert nicht spürbar. Entscheidung dokumentiert, bei Bedarf reaktivierbar.
|
||||
|
||||
**Tech-Debt / Modernisierung (Code-Review 2026-07-11):** Beim Umbau bereits erledigt sind
|
||||
`eval()` → `ast.literal_eval` (bzw. ein sicherer Mini-Auswerter für die String-Ausdrücke
|
||||
@@ -331,10 +362,14 @@ parallel anlaufen — eher ~4–4,5 Monate bis M4-Abschluss.
|
||||
nicht erst kurz vor Launch.
|
||||
2. **GA-Performance bei großen Sälen** — erster Datenpunkt (2026-07-11): das Beispiel
|
||||
`work/innenhoefe` mit 300 Gästen an 88 Tischen rechnet mit dem Easy-Zyklus in ~0,4 s
|
||||
durch — weit unter der 5-s-Schwelle, ab der M2 eine Job-Queue vorsieht. Offen bleibt
|
||||
der Test mit größeren Zyklen (mehr Generationen für bessere Lösungsqualität bei
|
||||
vielen Trennungen) — die Lösungsgüte bei 4er-Tischen mit großen Gruppen (Wertigkeit
|
||||
−384) legt nahe, dass hier eher mehr GA-Iterationen nötig sind als bisher.
|
||||
durch — weit unter der 5-s-Schwelle, ab der M2 eine Job-Queue vorsieht. Zweiter
|
||||
Datenpunkt (2026-07-12, M2-Lasttest): dasselbe Beispiel mit dem **Adaptiv**-Profil
|
||||
(Web-Default) braucht ~1,7–1,9 s (5–7 Generationen, 3 Seeds, inkl. Python-Start) —
|
||||
Job-Queue und Parameter-Kopplung bleiben unnötig. Weiter offen ist nur die
|
||||
Lösungsgüte-Frage: bei 4er-Tischen mit großen Gruppen (Wertigkeit ~−560) legen die
|
||||
vielen Trennungen nahe, dass mehr GA-Iterationen (größere `Geduld`/`Start`-Werte)
|
||||
bessere Pläne liefern könnten — das würde die Laufzeit dann wieder Richtung
|
||||
5-s-Schwelle schieben und wäre neu zu messen.
|
||||
3. **Wettbewerb ist real und etabliert** — siehe Abschnitt "Marktübersicht" oben.
|
||||
PerfectTablePlan verfolgt seit Jahren denselben GA-Ansatz, allerdings als Desktop-Tool.
|
||||
Differenzierung muss über Web-nativ + DSGVO-Hosting + detailliertere Regeln
|
||||
|
||||
Reference in New Issue
Block a user