Modul-planner
Constraint-Solver für einen wöchentlich rotierenden Modulplan mit ~600 Platzierungen, harten Ketten-Constraints und weichen Verteilungszielen. Ersetzt eine jahrelang gepflegte Excel-Heuristik durch einen domänenspezifischen Simulated-Annealing-Optimierer.
- catalog
- PRJ-25-α
- bayer
- α Horologium
- spectral
- class G
- magnitude
- 3.2
- erstes licht
- 2025
das Uhrwerk — ruhiges Leuchten im Süd-Quadranten der Karte.
RolleSolo-Entwicklung (Konzept, Algorithmus, Full-Stack, Deployment)
StackFastAPI · React · PostgreSQL
StatusProduktiv seit 2025
Das Schuljahr besteht aus rund 40 Kalenderwochen, in denen ~600 Modulinstanzen zu platzieren sind. Jede Platzierung ist durch die Lehrkraft-Verfügbarkeit, die Klassenzuordnung, Ferien- und Blockfenster sowie Ketten-Vorgaben (Modul B darf erst nach A laufen) gebunden. Der Lösungsraum ist kombinatorisch, die Zielfunktion nicht konvex — klassische ILP-Formulierungen waren zu langsam und zu starr für die manuelle Nachbearbeitung, die in der Praxis immer erforderlich bleibt.
Der Planungszustand wird als Dictionary {Slot → Modul} modelliert; jeder Move ist eine lokale Mutation, deren Score-Delta inkrementell berechnet wird. Akzeptiert wird nach Metropolis-Kriterium, die Temperatur fällt geometrisch. Drei Move-Strategien decken unterschiedliche Skalen ab: Swap für Nachbarschafts-Feinschliff, Chain-Swap für das atomare Verschieben gekoppelter Module, Random-Jump für das Entkommen aus lokalen Minima. Ein abschließender Polish-Pass rollt jeden nicht score-reduzierenden Zug zurück — der Output bleibt damit so nah wie möglich am Eingabeplan.
Move-Vorschlag
Strategie wird gewichtet gesamplet; Zielslots werden nur aus der Menge mit potenziellem Score-Beitrag gezogen.
Delta-Evaluation
ΔE wird inkrementell über die sieben Konflikt-Komponenten berechnet — vollständige Re-Scores sind nur bei Chain-Swaps nötig.
Metropolis-Akzeptanz
ΔE ≤ 0 wird immer akzeptiert, sonst mit Wahrscheinlichkeit exp(−ΔE/T). Die Temperatur wird nach jedem Schritt mit α skaliert.
Polish-Pass
Nach Erreichen von T_min wird die Move-History rückwärts durchgegangen und jeder Zug ohne Score-Verbesserung verworfen.
Snapshot-isolierte Planungsdomäne
Stammdaten (Module, Klassen, Lehrkräfte, Bildungsgänge) und Planungsdaten sind strikt getrennt. Jedes Semester arbeitet auf einem eigenen Snapshot — aktive Planung kann keine produktiven Stammdaten zerstören, abgeschlossene Semester bleiben reproduzierbar. Der Optimizer läuft im FastAPI-Prozess und streamt Zustandsänderungen über WebSockets ans Frontend; Undo-Management hält Move-Deltas im Speicher und erlaubt Replay bis zum Initialzustand.

Semester-Dashboard
Einstiegspunkt pro Planung: aktives Semester, Konflikt-Zusammenfassung und Sprung ins Grid oder in die Stammdaten.

Planungs-Grid
Das eigentliche Arbeitstool. Zellen sind Platzierungs-Slots, Konflikte werden farblich markiert, manuelle Korrekturen und Optimizer-Runs laufen gemeinsam mit Live-Update.

Bildungsgang-Editor
Semester-Grid mit Voraussetzungs-Kanten. Zirkuläre Abhängigkeiten werden beim Speichern erkannt, nicht erst zur Laufzeit.
- React 19
- TypeScript
- Vite
- Ant Design
- Refine
- Zustand
- dnd-kit
- Python 3.11
- FastAPI
- SQLAlchemy
- Pydantic
- WebSockets
- Simulated Annealing
- PostgreSQL
- Tailscale
- Netlify
- Render
Ein vollständiger Semesterplan konvergiert in unter einer Minute auf 0 harte Konflikte; weiche Verletzungen werden gewichtet heruntergefahren. Die manuelle Nachbearbeitung bleibt erstklassig — Optimizer und Hand-Editor arbeiten auf derselben Repräsentation. Das System ist für Winter- und Sommerplanung im produktiven Einsatz.