α Horologium·PRJ-25-α

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.

modulplanner · sommersemester 2026 · /grid
Sternatlas
catalog
PRJ-25-α
bayer
α Horologium
spectral
class G
magnitude
3.2
erstes licht
2025

das Uhrwerk — ruhiges Leuchten im Süd-Quadranten der Karte.

Projekt

RolleSolo-Entwicklung (Konzept, Algorithmus, Full-Stack, Deployment)

StackFastAPI · React · PostgreSQL

StatusProduktiv seit 2025

Problem

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.

Ansatz

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.

Parameter
T₀
3.0
Starttemperatur
α
0.9995
Cooling-Rate
T_min
0.001
Abbruch
Moves
3
Swap · Chain · Jump
Score
7
gewichtete Konfliktarten
Optimizer-Loop
01

Move-Vorschlag

Strategie wird gewichtet gesamplet; Zielslots werden nur aus der Menge mit potenziellem Score-Beitrag gezogen.

02

Delta-Evaluation

ΔE wird inkrementell über die sieben Konflikt-Komponenten berechnet — vollständige Re-Scores sind nur bei Chain-Swaps nötig.

03

Metropolis-Akzeptanz

ΔE ≤ 0 wird immer akzeptiert, sonst mit Wahrscheinlichkeit exp(−ΔE/T). Die Temperatur wird nach jedem Schritt mit α skaliert.

04

Polish-Pass

Nach Erreichen von T_min wird die Move-History rückwärts durchgegangen und jeder Zug ohne Score-Verbesserung verworfen.

Architektur

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.

UI
Semester-Dashboard

Semester-Dashboard

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

Planungs-Grid

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

Bildungsgang-Editor

Semester-Grid mit Voraussetzungs-Kanten. Zirkuläre Abhängigkeiten werden beim Speichern erkannt, nicht erst zur Laufzeit.

Stack
Frontend
  • React 19
  • TypeScript
  • Vite
  • Ant Design
  • Refine
  • Zustand
  • dnd-kit
Backend / Optimizer
  • Python 3.11
  • FastAPI
  • SQLAlchemy
  • Pydantic
  • WebSockets
  • Simulated Annealing
Infrastruktur
  • PostgreSQL
  • Tailscale
  • Netlify
  • Render
Ergebnis

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.