Files
platz/libs/platz.py
T
Michael Stangl d19913a53d SVG-Farbprofile: --farben mit palette- und kategorien-Modus
Neues Modul libs/Farben.py mit Farbschema, das Gruppen Farben zuordnet,
gesteuert durch Profile aus cfg/farben.cfg. Zwei Modi: "palette" (Farbliste
zyklisch je Gruppe, Profil grosse_gruppen) und "kategorien" (Hochzeit:
Familie/Verein/VIP getrennt ueber Farbverlaeufe, Profil hochzeit).

Sitzplatzverteilung.alsSVG bekommt Parameter Farbschema; Farben werden nun
fest fuer die vollstaendige Gruppenliste (nach Id) vergeben statt lazy in
Zeichenreihenfolge, damit jede Gruppe variantenuebergreifend dieselbe Farbe
hat. platz.py bekommt Schalter --farben (Vorgabe grosse_gruppen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 10:10:23 +02:00

157 lines
6.0 KiB
Python
Executable File

"""
Enthaelt alle Datenstrukturen um die Sitzplatzverteilung als GA zu variieren
"""
__author__ = "Michael Stangl"
__version__ = "$Revision: $"
__date__ = "$Date: $"
__copyright__ = "Copyright (c) 2005 Michael Stangl"
__license__ = "Python"
from ga import *
from Strukturdaten import *
from Farben import Farbschema
import optparse
import random
if __name__ == '__main__':
# Kommandozeilenoption --indir: Verzeichnis mit den Eingabedateien
# (tische.ini, bestellung.json) und Ziel fuer die Ausgabedateien
# (TischePersonen.txt, PersonenTische.csv)
parser = optparse.OptionParser()
parser.add_option( "--indir", dest="indir", default=None,
help="Verzeichnis mit tische.ini und bestellung.json; "
"dort werden auch TischePersonen.txt und PersonenTische.csv abgelegt" )
parser.add_option( "--tosvg", dest="tosvg", action="store_true", default=False,
help="zusaetzlich eine Sitzplatzverteilung.svg im --indir Verzeichnis "
"erzeugen (Tische als weisse Kreise, Personen als farbige "
"Kreise je Gruppe)" )
parser.add_option( "--show-connections", dest="showconn", action="store_true",
default=True,
help="in der Sitzplatzverteilung.svg jede ueber mehrere Tische "
"getrennte Gruppe mit einer Linie in ihrer Gruppenfarbe "
"verbinden (Vorgabe: an; nur mit --tosvg wirksam)" )
parser.add_option( "--hide-connections", dest="showconn",
action="store_false",
help="die Verbindungslinien getrennter Gruppen in der "
"Sitzplatzverteilung.svg nicht zeichnen" )
parser.add_option( "--show-development", dest="showdev", action="store_true",
default=False,
help="zusaetzlich eine Entwicklung.svg im --indir Verzeichnis "
"erzeugen: Verlauf der Loesungsfindung (Zeitachse nach rechts, "
"beste/durchschnittliche/schlechteste Wertigkeit auf der Y-Achse)" )
parser.add_option( "--show-lineage", dest="showlineage", action="store_true",
default=False,
help="zusaetzlich eine Abstammung.svg im --indir Verzeichnis "
"erzeugen: Stammbaum aller Loesungen (Mutationsbaum); der Ast der "
"finalen besten Loesung ist hervorgehoben und mit ihrer "
"Abstammungs-Id beschriftet" )
parser.add_option( "--zyklus-art", dest="zyklusart", default="Adaptiv",
help="Name des GA-Profils in zyklus.cfg (Vorgabe: Adaptiv). "
"Weitere mitgelieferte Profile: Easy, Simple" )
parser.add_option( "--strafen", dest="strafen", default="default",
help="Name des Strafpunkte-Profils (Sektion in strafen.cfg; "
"Vorgabe: default). Erlaubt mehrere Bewertungs-Vorgehen in einer "
"Datei, z.B. --strafen locker" )
parser.add_option( "--farben", dest="farben", default="grosse_gruppen",
help="Name des Farbprofils fuer die SVG-Ausgabe (Sektion in "
"farben.cfg; Vorgabe: grosse_gruppen). Fuer Hochzeiten: "
"--farben hochzeit (Familien/Vereine/VIPs getrennt)" )
parser.add_option( "--seed", dest="seed", type="int", default=None,
help="Zufalls-Startwert (int) fuer random.seed(), macht den Lauf "
"reproduzierbar. Ohne Angabe laeuft der GA nichtdeterministisch. "
"Fuer Support-Rueckfragen ('warum sitzt Tante Erna dort?') mit "
"demselben --seed exakt denselben Sitzplan erneut erzeugen" )
(options, args) = parser.parse_args()
# Determinismus auf Wunsch: den globalen Zufallsgenerator seeden, bevor
# irgendeine GA-Aktion laeuft. Der gesamte Algorithmus (ga.py und
# Strukturdaten.py nutzen 'from random import *') zieht aus demselben
# Modul-RNG, daher genuegt ein einziges random.seed() hier.
if options.seed is not None:
random.seed( options.seed )
print( "Determinismus: random.seed(%d) - Lauf ist reproduzierbar"
% options.seed )
if options.indir is None:
parser.error( "--indir ist erforderlich" )
InDir = os.path.expandvars( os.path.expanduser( options.indir ) )
if not os.path.isdir( InDir ):
parser.error( "--indir '%s' ist kein Verzeichnis" % InDir )
# zyklus.cfg (GA-Profile) und strafen.cfg (Strafpunkte) direkt aus dem
# per $PLATZ_CFG bestimmten cfg-Verzeichnis laden. Das GA-Profil waehlt
# der Schalter --zyklus-art (Vorgabe: Adaptiv).
CfgDir = os.getenv('PLATZ_CFG')
if not CfgDir:
parser.error( "Umgebungsvariable PLATZ_CFG ist nicht gesetzt "
"(bin/setenv aufrufen)" )
Zyklusconfig = os.path.join( CfgDir, 'zyklus.cfg' )
Zyklusart = options.zyklusart
Strafenconfig = os.path.join( CfgDir, 'strafen.cfg' )
Strafenart = options.strafen
Farbenconfig = os.path.join( CfgDir, 'farben.cfg' )
Farbenart = options.farben
# lade Eingabedateien
Tischconfig = os.path.join( InDir, 'tische.ini' )
Bestellung = os.path.join( InDir, 'bestellung.json' )
# lade Ausgabedateien
AusgabeTP= os.path.join( InDir, 'TischePersonen.txt' )
AusgabePT = os.path.join( InDir, 'PersonenTische.csv' )
AusgabeSVG = os.path.join( InDir, 'Sitzplatzverteilung.svg' )
AusgabeEntwicklung = os.path.join( InDir, 'Entwicklung.svg' )
AusgabeAbstammung = os.path.join( InDir, 'Abstammung.svg' )
Z = Zyklus()
Z.laden( Zyklusconfig, Zyklusart )
print(Z)
SL = Strafliste()
try:
SL.laden( Strafenconfig, Strafenart )
except ValueError as Fehler:
parser.error( str(Fehler) )
print(SL)
FS = Farbschema()
try:
FS.laden( Farbenconfig, Farbenart )
except ValueError as Fehler:
parser.error( str(Fehler) )
TE = Tische()
TE.laden( Tischconfig )
print(TE)
InputFile = JSONConfig()
[ PN, GN, VIPGruppe, VIPListePT, GruppenNamen ] = InputFile.laden( Bestellung )
print(PN)
print(GN)
print(VIPGruppe)
print(VIPListePT)
print("\n-- Erzeuge Farm:")
F1 = Farm( Z, Sitzplatzverteilung, Tische=TE, Gruppen=GN, Strafen=SL, VIPListe=VIPListePT, VIPs=VIPGruppe )
#print(F1)
S = F1.Bester()
print(S)
S.speichern( AusgabeTP, AusgabePT )
if options.tosvg:
S.alsSVG( AusgabeSVG, Verbindungen=options.showconn,
GruppenNamen=GruppenNamen, Farbschema=FS )
if options.showdev:
F1.Entwicklung.alsSVG( AusgabeEntwicklung )
print( "Entwicklungsverlauf geschrieben:", AusgabeEntwicklung )
if options.showlineage:
F1.Abstammung.alsSVG( AusgabeAbstammung,
HervorId=getattr(S, '_absid', None) )
print( "Abstammungsbaum geschrieben:", AusgabeAbstammung )
else:
pass