Seite 1 von 1

Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 00:22
von p90
Hi,

suche eine Möglichkeit etwas ähnliches wie genetische Vererbung in Python zu implementieren.
Möchte es ungefähr so machen:

Code: Alles auswählen

class person:
    pass

A = person()
B = person()

A.rot = 255
A.gruen = 50

B.blau = 255
B.gruen = 100

C = mix(A, B)
Jetzt soll C jeweils alle Eigenschaften haben die auch A und B haben auch wenn nur einer von beiden das "Gen" hatte.

Wollte "mix()" irgendwie so aussehen lassen.

Code: Alles auswählen

def mix(A,B):
   C = person()
   for i in vars(A):
      C.i = vars(A)[i] #das hier geht nicht weil i nicht das i aus der schleife ist
   for i in vars(B):
       try:
          C.i #siehe oben
       except:
           C.i = vars(B)[i]
       else:
           C.i = min([A.i, B.i]) + abs(A.i - B.i) * random.random()
Gibts da ne Möglichkeit das zu machen oder hat einer ne Idee wie man das schöner machen kann? Bis später


euer p90

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 00:40
von BlackJack
@p90: `getattr()` und `setattr()` sollten hier helfen können. Wobei mir nicht so ganz klar ist warum das per Attributzugriff gehen soll, denn man muss dafür die Attribute ja vorher kennen, wenn man da drauf zugreifen will. Wenn der Zugriff immer nur über variable Namen passiert, dann wäre ein Dictionary vielleicht besser geeignet.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 03:20
von p90
Also mit getattr und setattr sieht das ganze so aus und sollte soweit funktionieren.
(hab aber leider noch kein Testprogramm geschrieben)

Code: Alles auswählen

def mix(A,B):
   C = person()
   for i in vars(A):
      setattr(C, i, getattr(A,i))
   for i in vars(B):
       try:
          getattr(C,i)
       except:
           setattr(C, i, getattr(B,i))
       else:
           va = getattr(A,i)
           vb = getattr(B,i)
           newattrib = min([va, vb]) + abs(va - vb) * random.random()
Meine Frage ist nun noch ob dies eine gute Lösung ist oder nicht.
(hatte vorher etwas mit Vererbung experimentiert aber hatte da nicht die Möglichkeit Werte zu mischen)

Was ich halt gerne machen möchte ist einen kleine 2D Welt schreiben und sie dann mit kleinen "Lebewesen" bevölkern. Dazu noch einen Anfangspool von "genen" die aber untereinander mixen können. Bin mir aber noch nicht ganz im klaren wie ich schwerere "Gene" um sätze, z.B. wenn das Gen eine Funktion zur Auswahl der Bewegungsrichtung enthält.
Dachte bisher das ich dann einfach beide Funktionen berechnen lasse und dann zufällig rausgreife welche angwendet wird. Nur bekommen sie in diesem Fall pro Generation doppelt so viele Funktionen zum berechnen also muss ich das irgendwie intelligenter machen.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 07:27
von Hyperion
p90 hat geschrieben: Bin mir aber noch nicht ganz im klaren wie ich schwerere "Gene" um sätze, z.B. wenn das Gen eine Funktion zur Auswahl der Bewegungsrichtung enthält.
Dachte bisher das ich dann einfach beide Funktionen berechnen lasse und dann zufällig rausgreife welche angwendet wird. Nur bekommen sie in diesem Fall pro Generation doppelt so viele Funktionen zum berechnen also muss ich das irgendwie intelligenter machen.
Du kannst auch Funktionen an Namen binden und entsprechend weiterreichen.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 08:37
von BlackJack
@p90: Ich sehe immer noch nicht warum das Attribute sein müssen. Du kannst ja im Grunde nie Quelltext schreiben in dem auf die Attribute zugegriffen wird, weil Du nicht weisst welche davon ein "Lebewesen" denn nun hat und welche nicht. Das würde ich in einem Dictionary speichern. Dann kannst Du den "Lebewesen" auch Methoden verpassen.

Solltest Du bei Deinem Weg bleiben, dann schau Dir noch mal an was `vars()` zurück gibt. Du wirfst ja die Hälfte der Informationen weg.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 08:50
von Rekrul
Hallo,

wie generierst du denn die Attriubte und was sollen die darstellen? Sichtbare Eigenschaften wie Größe, Farben etc.? Was für ein Ziel verfolgen denn deine Lebewesen? Einfach rumwuseln und sich verändern, oder konkurrieren die um irgendwas?

Je nach Zielstellung kannst du dir ja mal genetische/evolutionäre Algorithmen anschauen bzw. Partikelschwärme.

Außerdem überlege dir mal genau wieso du Attribute verwenden möchtest. Dictionaries wären vielleicht besser geeignet. So als Ansatz:

Code: Alles auswählen

class Lifeform(object):
    def __init__(self, gene):
        self.gene = gene
        
    def mix(self, lifeform):
        Child = Lifeform(dict(self.gene))
        Child.gene.update(lifeform)
        keys_to_modify = set(self.gene.keys()).intersection(lifeform.gene)
        for key in keys_to_modify:
            va = self.gene[key]
            vb = lifeform.gene[key] 
            Child.gene[key] = min([va, vb]) + abs(va - vb) * random.random()
            
        Child.move = random.choice([self.move, lifeform.move])
    
    def move(self):
        raise NotImplementedError
Hmmm ... das geht bestimmt besser, aber zur Demonstration sollte es wohl reichen. :)

EDIT: def Lifeform(...): korrigiert (heißt natürlich class Lifeform...). Hat mich nicht losgelassen, daher musste ich es verbessern ...

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 12:41
von p90
@Hyperion
Das ist schon klar nur was ich meine ist das.
Ich baue mir Bewegungsfunktionen.
Nun hat das Lebewesen aber zwei oder mehr davon.
Nun muss ich ja alle erst berechnen, bekomme dann für jedes einen Rückgabe Wert und
muss daraus entscheiden was es tun soll. Aber wie gesagt, da ist mir noch keine gute Lösung für eingefallen.

@BlackJack
Es müssen keinen Attribute sein.
Das hier ist erst mal nur ein Experiment um zu sehen wie ich es am besten machen.
Hab in der Vergangenheit die Erfahrung gemacht das wenn ich selber an etwas erst rum schreibe und mir dann Gedanken mache wieder von vorne Anfangen kann. Hatte eigentlich gehofft das einer von euch vlt noch einen Geistesblitz hat ^^
Wie gesagt, vorher hatte ich versucht direkt Pythons Klassenvererbung zu verwenden aber da hatte ich Probleme durch das überschreiben.
Aber ansonsten könnte man das schon so wie hier machen denke ich.

@Rekrul
Also was ich eigentlich erreichen will ist erst mal eine möglichst einfache Lebensform zu erreichen. So ähnlich wie unbewegliche Bakterien. Dachte als Test lasse ich sie auf einem Bitmap leben und vergleiche in jeder Generation ihre "Anpassung" an den Hintergrund. Sind sie schlecht angepasst werden sie wahrscheinlich gefressen, sind sie besser angepasst (also grüne Bakterie auf grünem Pixel) ist es eher unwahrscheinlich das sie gefressen wird.
Wo ich hin möchte ist, das ich mit einer Population auf einem Grid starte auf dem verschiedene Materialien und andere Populationen und mir dann ansehe wie sie sich verhalten.
Aber das ist noch in weiter ferne. Immo ist das nur rumspielen um eine gute Methode zum vererben und mixen von genen zu bekommen insbesondere da ich wenn das ganze schon läuft nachträglich "Mutationen", also von mir neu geschriebene Gene einbringen möchte um dann zu sehen wie sie sich verteilen.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 13:42
von Rekrul
Wenn deine 'Bakterien' sich an bestimmte Situationen anpassen sollen, dann solltest du die Mutionen anders machen. Um Parameter / Gene anzupassen eignet sich die Evolutionsstrategie sehr gut. Wenn du aber unbedingt mehrere Elter haben möchtest solltest du zuerst die Gene mischen, indem du sie zufällig von den Eltern wählst und erst dann 'mutieren' (Genetischer Algorithmus). Bei einer Mutation sollten dann kleine Veränderungen immer wahrscheinlicher sein als große Veränderungen.

Beispiel:

Code: Alles auswählen

def recombine(self, lifeform):
    child = Lifeform(dict(self.gene))
    child.gene.update(lifeform.gene)
    for key in set(self.gene.keys()).intersection(lifeform.gene):
        child.gene[key] = random.choice([self.gene[key], lifeform.gene[key]])
    for key in child.gene:
        if random.random() < 0.2:
            child.gene[key]+= random.gauss(0,1)
    return child
Methoden als Gene ist schwierig (geht aber auch). Ich würde mir aber zuerst überlegen, ob ich nicht besser die Methoden selbst unverändert in eine neue Generation übernehme und dafür deren Parameter in die Gene packe.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 15:12
von Hyperion
p90 hat geschrieben:@Hyperion
Das ist schon klar nur was ich meine ist das.
Ich baue mir Bewegungsfunktionen.
Nun hat das Lebewesen aber zwei oder mehr davon.
Nun muss ich ja alle erst berechnen, bekomme dann für jedes einen Rückgabe Wert und
muss daraus entscheiden was es tun soll. Aber wie gesagt, da ist mir noch keine gute Lösung für eingefallen.
Muss ein Lebenwesen davon mehrere haben oder hat es bei Dir ggf. welche? Ok, ein Vogel kann laufen und fliegen. Wenn man so etwas nicht simulieren will, dann kann man doch verschiedene Callables schreiben, von denen man dann eines auswählt, welches übernommen werden soll. Oder kapiere ich das noch immer nicht?

Will man bei manchen Tieren mehrere Bewegungsarten simulieren, so braucht es eine Art "Medium", an die man eine Bewegung einordnet. Also "luft" -> fliegen, "erde" -> laufen | kriechen | robben, "wasser" -> schwimmen. So in der Art.

Will man da kein exklusives oder bei mehreren Dimensionen wirds noch komplizierter. Dann musst Du eben unterhalb von / zusätzlich zu einem Medium noch eine weitere Kategorie einbauen. Bei einer Vererbung wird dann bei Kollision nach welcher Regel auch immer nur eine von zwei Bewegungsalternativen gewählt. Wichtig ist dabei eben die Charakterisierung.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 15:48
von p90
Hyperion hat geschrieben: Muss ein Lebenwesen davon mehrere haben oder hat es bei Dir ggf. welche? Ok, ein Vogel kann laufen und fliegen. Wenn man so etwas nicht simulieren will, dann kann man doch verschiedene Callables schreiben, von denen man dann eines auswählt, welches übernommen werden soll. Oder kapiere ich das noch immer nicht?

Will man bei manchen Tieren mehrere Bewegungsarten simulieren, so braucht es eine Art "Medium", an die man eine Bewegung einordnet. Also "luft" -> fliegen, "erde" -> laufen | kriechen | robben, "wasser" -> schwimmen. So in der Art.

Will man da kein exklusives oder bei mehreren Dimensionen wirds noch komplizierter. Dann musst Du eben unterhalb von / zusätzlich zu einem Medium noch eine weitere Kategorie einbauen. Bei einer Vererbung wird dann bei Kollision nach welcher Regel auch immer nur eine von zwei Bewegungsalternativen gewählt. Wichtig ist dabei eben die Charakterisierung.
Ich meine das nicht im Sinnen von verschiedene Fortbewegunsmöglichkeiten. Vlt sollte ich es eher Aktionen nennen. Einfach mal ein Bsp.

Ich habe 3 Bakterienarten
A, lebt einfach nur vor sich hin
B, frisst A, flieht vor C
C, frisst B
Ich verwende ein 2D grid

Nehmen wir an es sieht so aus:
x y z
1. | | C | |
2. | A | B | |
3. | | | |

Was soll B nun tun?
Einerseits will es vor C fliehen, also nach Y3 ziehen, andrerseits aber auch A fressen, also nach X2 ziehen. Über Aktionsgene möchte ich dies nun darstellen.
Dabei versuche ich ein einfach erweiterbares System zu verwenden.
Sagen wir in Zukunft erfinde ich ein Gen das es B ermöglicht C anzugreifen.
Dadurch erhält B zwar keine Nahrung, kann sich aber C mit einer Bestimmten Wahrscheinlichkeit vom Hals schaffen. Welche Aktion macht er nun?

Das einzige System das ich bisher gefunden habe ist dies. Ich sammle einfach alle Aktionen, berechne sie und greife dann zufällig eines der Ergebnis heraus. Sagen wir Es hat 20 Aktionsgene und 15 sagen geh nach links (aus welchen gründen auch immer) und 5 sagen geh nach rechts. Dann geht Es mit 75% Wahrscheinlichkeit nach links und mit 25% nach rechts.
Da ich aber Gene mixen möchte bekomme ich Probleme den eine Funktion kann man schlecht mit einer anderen mixen und dann immer noch was vernünftiges raus bekommen. Deshalb muss ich die Ergebnisse mixen was aber dazu führt das ich mit jeder Generation mehr und mehr Funktionen berechnen müsste oder ich einen Normierungsfaktor mit einbauen müsste.
Oder ich baue eine feste Funktion und verändere nur die Parameter die sie bekommt. Dann kann ich aber nicht einfach neue Gene einbauen die dann neue Parameter einführen.
Alles nicht so toll.

Re: Genetische Vererbung in Python implementieren?

Verfasst: Freitag 25. März 2011, 16:10
von Rekrul
Was du haben willst geht vermutlich schon sehr in Richtung neuronale Netze.

Mehrere Methoden liefern dir jeweils einen evtl. unterschiedlichen Wert (z.B. die Position vom Futter(A) und die Position vom Feind(C)). Diese Werte dienen dann als Eingabe für dein neuronales Netz, welches dir als Ausgabe eine Bewegungsrichtung liefert. Die Parameter dieses neuronalen Netzes kannst du dann in deinem Gen verändern lassen.