""" 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 * 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( "--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 # 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) 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 ) 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