Bessere Verteilung: Strafen/Mutation, plus Abstammungsbaum mit Id-Herkunft

Weniger vermeidbare Gruppentrennungen:
- strafen.cfg: Tischbesetzung bestraft jetzt gestaffelt nach freien
  Plaetzen (teilbelegte Tische am teuersten, mit Fallback auf den
  naechstkleineren Eintrag), Trennungsstrafen deutlich erhoeht - so
  werden Gruppen nicht mehr getrennt, obwohl leere Tische danebenstehen
- gibPunkte('Tischbesetzung') mit Naechst-kleiner-Fallback
- mutieren() setzt geraeumte Gruppen groesste-zuerst neu
  (GruppenSetzen(GrosseZuerst=True)), damit grosse Gruppen die frei
  gewordenen ganzen Tische bekommen und wieder zusammenkommen
  (uebrig bleiben nur physisch unvermeidbare Trennungen, Gruppe > Tisch)

Abstammungsbaum (neuer Schalter --show-lineage -> Abstammung.svg):
- neue Klasse ga.Abstammung zeichnet den vollen Mutationsbaum aller
  Loesungen; der Ast der finalen besten Loesung ist hervorgehoben und
  mit ihrer Id beschriftet
- hierarchische Loesungs-Ids (Farm._WurzelId/_KindId): Wurzel '7',
  Mutationskind '7.2', dessen Kind '7.2.1' - die ganze Abstammung ist
  direkt aus der Id ablesbar

Tests (15 gruen), README und CLAUDE.md aktualisiert; Beispiele mit den
neuen Strafen und beiden Grafiken neu berechnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-07-11 22:38:43 +02:00
parent 644f61ef6b
commit 6710d4f06a
28 changed files with 3908 additions and 1468 deletions
+17 -10
View File
@@ -1,22 +1,29 @@
# Strafpunkte fuer die Trennung einer Gruppe:
# Aufbau: Anzahl der Trennungen = { Gruppengroesse:Strafpunkte, .. }
# Aufbau: Anzahl der Trennungen = { Gruppengroesse:Strafpunkte, .. }
# Deutlich hoeher als frueher, damit eine Trennung teurer ist als der Gewinn,
# einen Tisch dafuer teilbelegt zu lassen (sonst werden Gruppen getrennt,
# obwohl daneben leere Tische stehen).
[Trennung]
1={ 2:-10, 3:-8, 4:-6, 6:-4, 10:-2 }
2={ 3:-20, 4:-8, 6:-6, 10:-4 }
3={ 4:-30, 6:-10, 10:-6 }
1={ 2:-25, 3:-22, 4:-18, 6:-14, 8:-12, 10:-10 }
2={ 3:-40, 4:-30, 6:-22, 8:-18, 10:-14 }
3={ 4:-60, 6:-40, 8:-30, 10:-20 }
# Wieviele Strafpunkte bekommt man
# Wieviele Strafpunkte bekommt man
# wenn zwei Gruppen nicht am Nachbartisch sitzen
# wenn einer aus einer Gruppe allein sitzen muss
[Globals]
NichtNachbar=-3
Allein=-30
TischWertigkeiten={ 1:-3, 2:-2, 3:-1 }
TischWertigkeiten={ 1:-3, 2:-3, 4:-5, 6:-6, 8:-4 }
# TischWertigkeiten sind Strafpunkte fuer schlechte Ausnutzung der
# freien Sitze an einem Tisch.
# An einem Tisch, der bis auf einen Platz voll besetzt ist,
# kann niemand mehr gut dazu. wenn zwei Plaetze frei sind, ist das etwas besser.
# TischWertigkeiten sind Strafpunkte fuer freie Sitze an einem Tisch, je nach
# Anzahl freier Plaetze (fehlt ein exakter Eintrag, gilt der naechstkleinere).
# Ziel: teilbelegte Tische sind am schlechtesten (dort passt keine ganze
# Gruppe mehr hin und die Sitzenden haben leere Nachbarplaetze), daher steigt
# die Strafe mit den freien Plaetzen an (1..7 frei: -3 -> -6). Ein *komplett*
# leerer Tisch ist etwas besser als ein halbleerer (-4 bei 8 frei), weil ein
# leerer Tisch als Ganzes fuer eine Gruppe frei bleibt - er soll aber nicht
# gratis sein, damit sich das Zusammenziehen von Gruppen lohnt.
# Strafpunkte fuer den Abstand zwischen getrennten Teilen einer Gruppe.
# Wird eine Gruppe auf mehrere Tische aufgeteilt, ist ein grosser raeumlicher