Adaptiver GA-Zyklus, Pool-Groessen-Panel, Konfig direkt aus cfg-Dateien

Zyklus/Farm:
- neuer adaptiver Modus: grosse Startpopulation, die je Generation
  schrumpft (Start/Schrumpfung/MinPopulation) und bei Konvergenz stoppt
  (Geduld Generationen ohne Verbesserung >= Schwelle, max MaxGenerationen)
- Zyklus.laden erkennt adaptives Profil am Feld 'Start' (Modus adaptiv),
  sonst klassisch (Abfolge/Anzahl); Farm._LaufStatisch/_LaufAdaptiv
- neue Trunkierungs-Selektion Farm.PopulationBegrenzen
- [Adaptiv]-Profil in zyklus.cfg (dokumentiert)

Entwicklungsgrafik:
- zweites Panel unter dem Verlauf zeigt die Anzahl erzeugter
  Verteilungen im Pool je Schritt (gemeinsame Zeitachse)

Konfiguration:
- platz.cfg entfernt; zyklus.cfg/strafen.cfg werden direkt aus
  $PLATZ_CFG geladen
- neuer Schalter --zyklus-art (Default Adaptiv) waehlt das GA-Profil
- web/main.py analog: direktes Laden, Profil via PLATZ_ZYKLUSART

Doku (README.md, CLAUDE.md) und Tests entsprechend aktualisiert;
Beispiele mit dem Adaptiv-Default neu berechnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-07-11 14:31:59 +02:00
parent 4f87895303
commit 644f61ef6b
23 changed files with 1909 additions and 1607 deletions
+13 -13
View File
@@ -11,7 +11,6 @@ __license__ = "Python"
from ga import *
from Strukturdaten import *
import configparser
import optparse
@@ -42,6 +41,9 @@ if __name__ == '__main__':
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( "--zyklus-art", dest="zyklusart", default="Adaptiv",
help="Name des GA-Profils in zyklus.cfg (Vorgabe: Adaptiv). "
"Weitere mitgelieferte Profile: Easy, Simple" )
(options, args) = parser.parse_args()
if options.indir is None:
@@ -50,18 +52,16 @@ if __name__ == '__main__':
if not os.path.isdir( InDir ):
parser.error( "--indir '%s' ist kein Verzeichnis" % InDir )
# lade Vorgaben fuer Optimierungszyklus und
config = configparser.ConfigParser()
ConfigPath= os.path.join( os.getenv('PLATZ_CFG'), 'platz.cfg')
config.read( os.path.expandvars( ConfigPath ))
Zyklusconfig = os.path.normpath( config.get( 'Config', 'Zyklusdatei' ))
Zyklusconfig = os.path.expandvars( Zyklusconfig )
Zyklusart = config.get( 'Config', 'Zyklusart' )
Strafenconfig = os.path.normpath(config.get( 'Config', 'Strafendatei' ))
Strafenconfig = os.path.expandvars( Strafenconfig )
## print Strafenconfig
# 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' )
# lade Eingabedateien
Tischconfig = os.path.join( InDir, 'tische.ini' )