genetische Algorythmern
-
cool danke

-
ist dass jetzt ein genetischer algorythmus?
#include <iostream> using namespace std; int main() { int a,b,c,d; a=0; b=0; c=0; d=0; while(a+b+c+d!=10){ if((a+b+c+d)<7){ a++; b++; c++; d++; } else if((a+b+c+d)<8){ a++; b++; c++; } else if((a+b+c+d)<9){ a++; b++; } else{ a++; } } printf("a==%d\nb==%d\nc==%d\nd==%d\n",a,b,c,d); return system("Pause"); }
-
nee
weit davon entfernt 
-
gut was muss ich daran anders machen?
-
Hier hast du mal etwas was dir vielleicht weiterhelfen wird:
http://fuzzy.cs.uni-magdeburg.de/studium/ga/#Unterlagen
An der Uni hab ich das Zeug gelernt. Lesen musst du trotzdem viel. Von heute auf morgen wird das nix.
BeispielCode ist unter dem Link auch zu finden.
gut was muss ich daran anders machen?
Dein Codebeispiel zeigt mir, dass du noch viel zu wenig gelesen hast

Eine genetischer Algorithmus passt sicher nicht in 30 Zeilen Code, bei mir passt er nicht mal in eine Klasse ^^( OOP-Kenntnisse sind empfehlenswert, aber kein Zwang )
-
hmm gut ...
dass lernt man erst an der uni?? cool
werde mir dass mal anschauen und wenn ich weiter bin nochmal dasselbe probieren
danke für deine Hilfe
-
wenn du beim Code Unterstützung brauchst, kann ich dir gerne helfen. Aber ohne Grundkenntnisse bringt das absolut nix, einfach draufloszuproggen.
Nimm dir nen Zettel und konstruier doch mal einen genetischen Algorithmus, wie du dir den Ablauf vorstellst.
-
ist dass jetzt ein genetischer algorythmus?
Wie waere es mit Gross/Kleinschreibung, Interpunktion und Rechtschreibung? Wenn du willst, dass man sich Zeit fuer dich nimmt, so solltest du dir selbst etwas Zeit nehmen.
-
Ich werde demnächst noch mehr auf meine Rechtsschreibung achten:D
So Ich habe jetzt einen weiteren Code geschrieben der auch tadellos funktioniert.
Ist dass jetzt ein genetischer Algorythmus oder ist er zumindest besser?
Ich habe deinen Vorschlag, den mit : a+b+c+d+e=10.
mein code:#include <stdlib.h> #include <stdarg.h> #include <limits.h> #include <time.h> #include <assert.h> #include <math.h> #include <iostream.h> typedef struct { /* --- an individual --- */ int fitness; /* fitness (number of collisions) */ int n; /* number of genes (number of rows) */ int genes[4]; /* genes (queen positions in rows) */ } IND; /* (individual) */ typedef struct { /* --- a population --- */ int size; /* number of individuals */ IND **inds; /* vector of individuals */ IND **buf; /* buffer for individuals */ IND *best; /* best individual */ } POP; /* (population) */ void pop_init(POP *pop); void ind_init(IND *ind,POP *pop); void checkFitness(IND *ind); int main (int argc, char *argv[]) { POP *pop=(POP*)malloc(sizeof(POP)*5); pop->size=1; pop_init(pop); while(pop->inds[0]->fitness!=10){ for(int i=0;i<5;i++){ pop->inds[0]->genes[i]=(int)rand()%10; checkFitness(pop->inds[0]); if(pop->inds[0]->fitness==10){ cout<<"Fitness ist 10 abbruch"<<endl; break; } } } cout <<pop->inds[0]->genes[0]<<" " <<pop->inds[0]->genes[1]<<" " <<pop->inds[0]->genes[2]<<" " <<pop->inds[0]->genes[3]<<" " <<pop->inds[0]->genes[4]<<" " <<"Sume: "<<pop->inds[0]->genes[0]+pop->inds[0]->genes[1]+pop->inds[0]->genes[2]+pop->inds[0]->genes[3]+pop->inds[0]->genes[4]<<" " <<endl; return system("Pause"); } /* main()*/ void pop_init(POP *pop) { pop->inds=(IND**)malloc(sizeof(IND)*5); pop->best=(IND*)malloc(sizeof(IND)*5); pop->inds[0]=(IND*)malloc(sizeof(IND)*5); for(int i=0;i<=pop->size;i++){ pop->inds[i]->n=5; srand (time(NULL)); ind_init(pop->inds[i],pop); } } void ind_init(IND *ind,POP *pop){ ind->fitness==0; for(int i=0;i<5;i++){ ind->genes[i]=rand() % 10 ; checkFitness(ind); } } void checkFitness(IND *ind){ int sum=0; for(int i=0;i<5;i++){ sum=sum+ind->genes[i]; } if(sum==10){ ind->fitness=10; } else ind->fitness=-abs(sum-10); }
-
So ich hab einige Hinweise für dich.
1. Wir sind hier im C++-Forum, was du programmierst ist ANSI-C
( aber das soll uns erstmal nicht aufhalten )2. Deine Vorgehensweise ist folgende:
- du erzeugst zufällig einen Satz von Genen.
- du berechnest die Fitness ( den Fehler )
(soweit so richtig)Aber dann machst du folgendes
for(int i=0;i<5;i++) { pop->inds[0]->genes[i]=(int)rand()%10; ... }D.h. du initialisierst das allererste Element komplett neu. Warum?
Ich schreib dir mal meine Vorgehensweise auf ( und ich würde dir empfehlen auf C++ und OOP zurückzugreifen, weil das die Sache deutlich übersichtlicher macht ):
1. Lege N Genome der Größe M an.
2. Berechne die Fitness ( oder den Fehler ) aller Genome
3. Sortiere diese Genome nach Fitness ( das beste Element sollte als ganz oben oder ganz unten in der Liste stehen )
( Tipp: wenn du deine Genome in einem std::vector lagerst, kannst du mit std::sort ganz leicht und auch einigermaßen performant sortieren )
4. Jetzt kommen die biologischen Operatoren ( Kreuzung, Mutation, Elitimus )
- Elitismus: Das Beste Element wird direkt in die nächste Generation mit übernommen
- Mutation: nimm dir einige gute Elemente ( ich nehm gern die besten 10% ) und auch das Beste, lege Kopien davon an und verändere nur ein einzelnes Gen ( rand() ). Füge diese veränderten Genome wieder der neuen Generation hinzu.
- Kreuzung: Wähle zufällig ( entweder aus den besseren Genomen, oder per Roulette-Wheel ) zwei Eltern-Genome und erzeuge daraus zwei Kinder-Genome, in dem du für jedes Gen der Kinder zufällig entscheidest, ob das Gen vom Vater oder von der Mutter kommt. Füge diese beiden neuen Genome wiederum der neuen Generation hinzu.(Du kannst auch erst eine festgelegte Anzahl von Kreuzungen machen und dann solange Mutationen bis die neue Generation ( Population ) exakt die Größe der alten Population hat. )
5. erste die alte Population durch die neue.
6. Wiederhole diese Schritte solange, bis du deine gewünschte Fitness erreicht hast ( bis der Fehler ausreichend klein ist )
Anmerkung: das ist erstmal nur eine Grundstruktur - es gibt noch sehr viele Variantionsmöglichkeiten! Genetische Algorithmen sind ein weites Feld. Ebenso wie genetische Programmierung.
-
Ein nettes "Problem" war auch immer der Travelling Salesman:
Du hast X Punkte in einem 2D-Raum. Die Aufgabe ist es die alle zu verbinden und dabei die Verbindungen zu finden die am kürzesten ist, jeden aber exakt einmal besucht.
-
Fellhuhn schrieb:
Ein nettes "Problem" war auch immer der Travelling Salesman:
Du hast X Punkte in einem 2D-Raum. Die Aufgabe ist es die alle zu verbinden und dabei die Verbindungen zu finden die am kürzesten ist, jeden aber exakt einmal besucht.wie würde man da vorgehen?
Ich hab mich ehrlich gesagt bis zu diesem Thread nicht mit dieser Art Algorithmen beschäftigt, aber jetzt bin ich neugierigMein (naiver) Vorschlag wäre folgender:
- Ausreichend viele mögliche Lösungen erzeugen, die alle Punkte einmal besuchen
- die kürzeste davon in die neue Generation übernehmen
- die etwas längeren mutieren und kreuzen und auch in die nächste Generation übernehmen
- das selbe mit der neuen Generation wiederholen, bis die neuen Generationen nicht mehr wesentlich kürzer werdenlieg ich da (einigermaßen) richtig, oder hab ich da was falsch verstanden?
-
Ja, so in etwa. Man arbeitet halt auf Listen die die IDs der Punkte beinhalten, natürlich keine doppelt und alle drin. Und dann wird bei der Mutation zufällig ein paar vertauscht und so weiter.
Als die Aufgabe allerdigns bearbeitet wurde bei dem "Programmierwochenende" während der Studienzeit (auch schon lange her) war eher Pornos auf Leinwand gucken und Bier saufen angesagt. Daher habe ich da keine Erinnerung dran.
-
Fellhuhn schrieb:
Ja, so in etwa. Man arbeitet halt auf Listen die die IDs der Punkte beinhalten, natürlich keine doppelt und alle drin. Und dann wird bei der Mutation zufällig ein paar vertauscht und so weiter.
Wobei du bei dem Travelling-Salesman immer jede Zahl ( jeden Ort ) im Genom haben musst.
D.h. bei Mutation von
123456789
kannst du nicht die 4 durch ne 9 ersetzen, weil dann der Ort 4 garnicht besucht wird und der Ort 9 zweimal.
D.h. du kannst höchstens mutieren indem du innerhalb des Genomes zwei Ziffern miteinander vertauschst.
(Sozusagen ein Spezialfall der Mutation, den ich beim Sudoku-Problem auch hatte)
-
Siehe das drittletzte Wort das du von mir zitierst.

-
Fellhuhn schrieb:
Siehe das drittletzte Wort das du von mir zitierst.

aso ok, das hatte ich anders interpretiert. Dann sind wir natürlich einer Meinung
( ich hatte jetzt zuerst an Kreuzung gedacht, denn die is bei sowas echt unangenehm ^^ )
-
Vielleicht hätte ich "Paar" groß schreiben sollen.

-
Fellhuhn schrieb:
Vielleicht hätte ich "Paar" groß schreiben sollen.

nee du hast das schon richtig geschrieben, ich war nur mit meinen Gedanken etwas durcheinander ^^
-
Fellhuhn schrieb:
Und dann wird bei der Mutation zufällig ein paar vertauscht und so weiter.
aber wenn immer nur per Zufall vorgegangen wird, wie kann ich dann sicher sein, dass die neue Generation besser ist als die alte?
-
In dem die, die schlechter getauscht werden wieder absterben.