Loesungs-Ids wieder als fortlaufende Nummern 1..N (Vorgaenger separat)

- Farm._WurzelId/_KindId ersetzt durch _NeueId: jede Loesung bekommt eine
  einfache fortlaufende Nummer (Wurzeln wie Mutationskinder gleich)
- die Abstammung steckt nicht mehr in der Id, sondern im schon vorher
  gemerkten Vorgaenger (Abstammung-Knoten 'eltern'); der Baum und die
  Hervorhebung des Sieger-Astes funktionieren unveraendert
- Tests auf das neue Id-Schema umgestellt (Nummern 1..N, Abstammung ueber
  Vorgaenger), README/CLAUDE.md aktualisiert
- Beispiele neu berechnet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-07-11 22:48:49 +02:00
parent 6710d4f06a
commit 740c420900
22 changed files with 3554 additions and 3507 deletions
+18 -19
View File
@@ -351,41 +351,40 @@ class TestAbstammung(unittest.TestCase):
Z.Adaptiv.update(params)
return Z
def test_hierarchische_ids_kodieren_abstammung(self):
def test_fortlaufende_nummern_ids(self):
Z = self._zyklus( Start=5, Schrumpfung=1.0, MinPopulation=5,
MaxGenerationen=3, Geduld=99, Schwelle=0.0 )
F = Farm( Z, self._L )
Knoten = F.Abstammung.Knoten
# Wurzeln sind schlichte Zahlen ohne Punkt und haben keine Eltern
wurzeln = [ Id for Id, K in Knoten.items() if K['eltern'] is None ]
self.assertTrue( all( '.' not in Id for Id in wurzeln ) )
self.assertEqual( len(wurzeln), 5 )
# alle Ids sind fortlaufende Nummern 1..N ueber alle Loesungen
Ids = sorted(Knoten)
self.assertTrue( all( isinstance(Id, int) for Id in Ids ) )
self.assertEqual( Ids, list(range(1, len(Ids) + 1)) )
# jede Kind-Id ist Eltern-Id + '.' + index; die Eltern-Id ist damit
# das Praefix bis zum letzten Punkt und existiert als Knoten
# genau die 5 Startloesungen sind Wurzeln (kein Vorgaenger),
# alle uebrigen haben einen Vorgaenger, der als Knoten existiert
wurzeln = [ Id for Id, K in Knoten.items() if K['eltern'] is None ]
self.assertEqual( len(wurzeln), 5 )
for Id, K in Knoten.items():
if K['eltern'] is None:
continue
self.assertIn( '.', Id )
self.assertEqual( Id.rsplit('.', 1)[0], K['eltern'] )
self.assertIn( K['eltern'], Knoten )
self.assertNotEqual( K['eltern'], Id )
def test_ahnenkette_ist_aus_id_ablesbar(self):
# Bei einem Kind '3.2.1' muessen '3.2' und '3' die Ahnen sein
def test_abstammung_ueber_vorgaenger(self):
# Abstammung wird ueber den gemerkten Vorgaenger verfolgt, nicht ueber
# die Id selbst (Ids sind schlichte Nummern)
A = Abstammung()
A.erfassen( '3', None, 0, -100, 'e' )
A.erfassen( '3.2', '3', 1, -99, 'm' )
A.erfassen( '3.2.1', '3.2', 2, -98, 'm' )
# rueckwaerts ueber die Eltern-Verweise
A.erfassen( 1, None, 0, -100, 'e' )
A.erfassen( 2, 1, 1, -99, 'm' )
A.erfassen( 3, 2, 2, -98, 'm' )
kette = []
Id = '3.2.1'
Id = 3
while Id is not None:
kette.append(Id)
Id = A.Knoten[Id]['eltern']
self.assertEqual( kette, ['3.2.1', '3.2', '3'] )
# und das laesst sich auch rein syntaktisch aus der Id ablesen
self.assertEqual( '3.2.1'.split('.'), ['3', '2', '1'] )
self.assertEqual( kette, [3, 2, 1] )
def test_svg_hebt_beste_hervor(self):
Z = self._zyklus( Start=4, Schrumpfung=1.0, MinPopulation=4,