random nicht random...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Demoke
User
Beiträge: 5
Registriert: Donnerstag 11. März 2010, 15:53

Hallo an alle!

Schreibe gerade an einem Evo Algo und brauche dafuer zufaellige "paarungen" von den features. Leider sehen meine ausgaben dann doch immer ziemlich aehnlich aus. Um es kurz zu umreissen was passiert:
Ich habe eine Menge an sog. Features (einfach ints) aus denen zufaellige Submengen erstellt werden. Dann werden diese rekombiniert um eine groessere Anzahl zu erhalten. Die besten werden behalten und diese sind dann die neue elterngeneration. und dann gehts im kreis.

Hier zur veranschaulichung das ergebnis:
zeilen mit den floats(doubles?) sind die eltern mit der Wertigkeit davor
dann kommen die Kinder
dann die mutierten Kinder
und zuletzt noch einmal die eltern damit man sie einfacher vergleichen kann.



sry fuer das riesenteil, ist nur zur veranschaulichung, man sieht aber dass rekombination und mutation staendig dieselben werte produzieren muss! hier der code:

Code: Alles auswählen

from copy import deepcopy
from random import choice
from random import random

class Recombination():
    def __init__(self, lam):
        self.lam = lam
        self.parents = []
        self.childs = []
        
    def getrandom(self,list):
        if list != []:
            feature = choice(list)
            list.remove(feature)
            return feature
        else:
            return None
    
    def deletedouble(self,list):
        d = {}
        
        if len(list)==1:
            return list
        for x in list: d[x]=x
        list = d.values()
        return list

class Random(Recombination):
    def __init__(self,lam):
        Recombination.__init__(self, lam)
        
    def recombination(self, parents):
        self.parents = parents        
        self.childs=[]
        for i in range(self.lam):
            parents =[]
            parentlist = deepcopy(self.parents)
            for k in range(2):
                parents.append(self.getrandom(parentlist))
            
            newchild=[]
            
 
            parents = parents[0][1]+parents[1][1]
          
            parents = self.deletedouble(parents)
            sublen= 0
            while sublen == 0:
                sublen = choice(range(len(parents)+1))
            newchild = []
            for j in range(sublen):
                newchild.append(self.getrandom(parents))
            self.childs.append(newchild)
        return self.childs


############### und aus nem anderen modul die mutation:################

 def mutation(self):
        self.mutatedchilds = []
        for i in range(len(self.childs)):
            mutatingchild = deepcopy(self.childs[i])
            for j in range(len(mutatingchild)):
                if random() <= self.mutationrate:
                    mutatingchild[j] = choice(self.features)
            if self.addition:
                if random() <= self.mutationrate:
                    mutatingchild.append(choice(self.features))
            if self.deletion and len(mutatingchild) > 1:
                if random() <= self.mutationrate:
                    mutatingchild.remove(choice(mutatingchild))        
            mutatingchild = self.deletedouble(mutatingchild)
            self.mutatedchilds.append(mutatingchild)




danke falls sich jmd die muehe macht...
Zuletzt geändert von Demoke am Freitag 12. März 2010, 12:29, insgesamt 2-mal geändert.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Ich sehe nicht, wo du in mutation(self) deine Random-Klasse überhaupt nutzt. Oder anders herum.
Bottle: Micro Web Framework + Development Blog
Demoke
User
Beiträge: 5
Registriert: Donnerstag 11. März 2010, 15:53

from random import choice
from random import random

sry haette ich vlt dazu schreiben sollen....
und es ist ja nicht meine Random Klasse.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Und was ist mit class Random(Recombination)? ist das nicht deine random klasse?

Kleiner Tipp, der Fehler liegt wahrscheinlich nicht in der random Bibliothek von Python.
Bottle: Micro Web Framework + Development Blog
Demoke
User
Beiträge: 5
Registriert: Donnerstag 11. März 2010, 15:53

:lol: das hoffe ich doch, sonst muesste ich mir ja meine eigene Random Klasse schreiben...
und nein das ist nicht meine Random Klasse, meine Random Klasse zieht aus den zufaellig
ausgewaehlten eltern(also zwei aus anzahl eltern) eine zufaellig grosse(s. sublen) Menge
von features( for j in range(sublen):
newchild.append(self.getrandom(parents)

edit: seltsam ausgedrueckt, also nochmal klarer: meine Klasse heisst random ersetzt aber nicht die standartklasse sondern hat eine andere funktion. und es ist auch nicht moeglich dass ich aus versehen diese anspreche wenn ich random aufrufe da ganz andere werte uebergeben werden muessen, bzw die ganzen funktionen ueberhaupt nicht definiert sind
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Lagere bitte den Code und dieses Ungetüm von Ausgabe in ein pastebin aus (z.B. http://paste.pocoo.org/), da man auf diesen Thread kaum noch antworten kann - die Forumsoftware kommt mit soviel "Code" nicht zurecht.

Und wenn Du den Code ausgelagerst, dann bitte lauffähigen Code - damit man auch wirklich sehen und nachvollziehen kann, was schiefläuft. So, wie es jetzt ist, ist mir das zu aufwendig - mal ganz abgesehen davon, daß der Code etwas "angestrengt" aussieht.

Außerdem: Bitte nicht das Syntaxhighlighting ausschalten! Mit dem "Python"-Knopf im Editiermodus ist das ja schon mutwillig zu nennen ;-).

Gruß,
Christian
Demoke
User
Beiträge: 5
Registriert: Donnerstag 11. März 2010, 15:53

ich arbeite seit 2 wochen mit python dementsprechend ist das alles noch ziemlich konventionslos...

und den ganzen code kann, will und werde ich nicht hochladen, da es nicht mein projekt ist, sondern ich nur nen kleinen teil zu beitrage und derjenige der die forschung leitet nicht sonderlich begeistert sein würde den code vorab zu veröffentlichen..
mal abgesehen von der tatsache dass sowieso niemand sich die muehe machen wird sich durch die ganzen module zu quälen..

also ich bin um jede hilfe dankbar aber wenns mit dem geposteten nicht geht, muss ichs alleine schaffen...

ps: das ergebnis hab ich einfach entfernt... man kann ja aus dem text entnehmen was los war, aber als bsp nochmal so in etwa:
erster durchlauf:
[1,2,3],[2,4,5]...
zweiter durchlauf: also der aufruf von außen des codes..
[1,2,3],[2,4,5]...

pps: ich hab nichts ausgemacht von wegen highlighted... und schnall auch nicht wie ichs einschalten kann... help,pls
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hightlighting siehe FAQ.

Konventionen sind ja nicht völlig umsonst - sie machen, dass andere den Code besser verstehen können und verhindern auch eigene Fehler.

Und was auch immer der Algorithmus machen soll: Genetische Algorithmen finden auch außerhalb der Biologie breite Anwendung - ein gänzlich neues Konzept würde mich überraschen ;-). Aber es geht auch nicht darum den ganzen Code zu sehen - ein funktionierendes Minimalbeispiel ist wohl besser als eine ganze Software(bibliothek)/ein Programm.

Vielleicht bin ich zu doof, aber ich kann nicht nachvollziehen, was erreicht werden soll und somit auch nicht sagen, wo der Knackpunkt ist. Aber ein paar Dinge, die mir auffallen mal zufällig rausgepickt:

- Statt

Code: Alles auswählen

for x in range(len(iterable)):
     y = iterable(x)
kannst Du fast immer

Code: Alles auswählen

for item in iterable
nutzen. Ggf. schau Dir noch enumerate und Konsorten an.

- Die "deepcopy"s sind fast sicher überflüssig und macht den Code langsam.

- Importe kann man auch zusammenfassen:

Code: Alles auswählen

from random import random, choice
- Statt mehrere if in Reihe, kannst Du ggf. auch elif benutzen: Das dürfte den Code etwas schneller machen und macht vielleicht auch Zeile 72 überflüssig - wie gesagt, ich weiß nicht genau was Du erreichen willst.

- Eigentlich scheint mir die ganze Klasse "Recombination" überflüssig: Warum umständlich Elternkopien erzeugen und dann die Eltern überschreiben - man kann die Eltern doch direkt auswählen und überschreiben?

- Das führt uns zu der Designfrage was für ein Objekt bei der "Random"-Klasse rausspringt: Also wenn ich einen genetischen Algorithmus implementiere baue ich mir eine "Population" mit "Individuen" bestimmter Eigenschaften. Deren Klassen erben auch nicht voneinander, sondern eine "Population" hat "Individuen". Und wenn man sich einmal darüber im klaren ist, welche Eigenschaften wie vererbt werden müssen, dann ergibt sich der Sprung von Generation zu Generation rel. zwanglos. (Mein "www-Knopf" verlinkt eine Software mit einem Beispiel - Du darfst Dich im Code bedienen, aber gerade dieses Beispiel ist eher unorthodox und schwer zu verstehen.)

Zum Schluß noch: Das mit dem Rat langen Code auszulagern ist kein Witz! Die Forumssoftware bremst uns sonst schnell aus und antworten auf diesen Thread wird sehr schwierig.

HTH
Christian
Demoke
User
Beiträge: 5
Registriert: Donnerstag 11. März 2010, 15:53

hey hat sich erledigt!
irgendwo im code( ich habs nicht gefunden!) wurde wohl der seed gesetzt.... auf jedenfall funktionierts wenn ich vor jedem durchlauf einfach den seed generieren lasse..


thx @ all anyway...
und thx CM fuer die tipps! aber kurz noch als antwort:
die klasse recombination brauch ich da ich verschiedene rekombinationsstrategien habe und die erben alle von der klasse recombinations. die klasse wird dann dem hauptprogramm uebergeben damit man weiss wie sich die eltern paaren sollen..

deepcopy brauche ich da mir gesagt wurde wenn ich zb parents = self.parents schreibe eine referenz und kein neues objekt erstellt wird.. und wenn ich ohne wiederholung aus ner liste ziehen will muss ich die gezogenen elemente loeschen.. da ich das aber mehrmals wiederholen will brauch ich ne neue instanz...

und zu der designfrage: wenn ich dich richtig verstehe dann haben wir keine unterschiedliche meinung dazu, mein problem war ja auch nie der vorgang an sich, sondern so wies aussieht der gesetzte seed.....


so far
Demoke
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Meine bescheidenen Kryptokenntnisse behaupten, dass du eigentlich den Seed wiederverwenden möchtest statt ihn jedes Mal neu zu generieren.
lunar

@mkesper: Bei Pseudozufallsgeneratoren führt ein identischer Seed zur exakt identischen Zahlenfolge. Den Seed wiederzuverwenden, ist demnach genau das, was man nicht will …
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

OK, sorry, stimmt natürlich. :oops:
Ist höchstens zum Testen gut.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Demoke hat geschrieben:hey hat sich erledigt! ...
Freut mich!
Demoke hat geschrieben: die klasse recombination brauch ich da ich verschiedene rekombinationsstrategien habe ...
Dann solltest Du IMHO immer noch darüber nachdenken, ob Du nicht ein wenig daran feilen möchtest:
- Eine Rekombination ist ein Ereignis und daher != Strategie. Der Name einer Klasse sollte das ausdrücken (sonst wird man selber irgendwann vom eigenen Code verwirrt).
- Ggf. tut es auch ein dictionary statt einer Eigenbau-Klasse?
Demoke hat geschrieben:deepcopy brauche ich da mir gesagt wurde wenn ich zb parents = self.parents schreibe eine referenz und kein neues objekt erstellt wird..
So, hat man Dir gesagt. :roll: Ja, stimmt auch und dennoch ...
Demoke hat geschrieben:und wenn ich ohne wiederholung aus ner liste ziehen will muss ich die gezogenen elemente loeschen.. da ich das aber mehrmals wiederholen will brauch ich ne neue instanz...
... stimmt das nicht. Also:
- Eine Generation besteht aus Individuen. Diese haben Eltern und können Eltern werden. Individuen haben bestimmte Eigenschaften und sind meist so komplex, daß man dazu am besten eine Klasse baut. Zu den Eigenschaften können auch die Parameter einer Reproduktionsstrategie gehören (!= Rekombinationsstrategie - was ist das eigentlich? Wenn Du Parameter für die optimale Rekombination in einem genetisch Algorithmus testen willst, würde ich das nicht "Strategie" nennen.)
- Eine Generation also kann auch nur eine Liste von Individuen sein. Eine neue Generation überschreibt also diese "parentale" Liste nach bestimmten Regeln ausgehend von der "parentalen" Liste, z. B.:

Code: Alles auswählen

generation = propagation(generation, **kwds)
- Allerdings kann man eine Generation auch als Klasse bauen (und ggf. von list erben), wenn diese zusätzliche Metadaten handeln soll.
Demoke hat geschrieben:und zu der designfrage: wenn ich dich richtig verstehe dann haben wir keine unterschiedliche meinung dazu
Doch ;-). Mir würden auch noch mehr Dinge einfallen. Aber wie Du selbst sagst, fängst Du gerade an und dafür ist es schon ziemlich gut!
Antworten