Anfänger hat Code bekommen!
-
Hallo zusammen,
ich bin Anfänger in C++ (lese mich paralell ein und mache die Bsp auch). Ich habe hier nun einen Code, der anscheinend lauffähig ist und es auch irgendwie tut... dieser schmeisst aber komische Dinge aus, die ich nicht deuten kann.
Da ist aber auch was von Initialisierung eines Generators die Rede und ich komme nicht so ganz weiter... Ich poste diesen nun hier mal (Bitte nicht schlagen!). Ich kann ihn leider nicht auf das Wesentliche reduzieren, da ich nicht weiss, was das Wesentliche ist!
Gruss
Zoli/* * File: newmain.cpp * Author: * * Created on 12. Mai 2009, 23:23 */ # include <iostream> # include <stdlib.h> # include <time.h> # include <math.h> # include <fstream> using namespace std; int g=0; //Generationanzahl const int maxGen=2500; //Abbruchkriterium, hier nach 2500 Generationen const int mu=60; //Populationsgroesse Elternpopulation const int lambda=50; //Anzahl Nachkommen const int rho=20; //Anzahl der reproduzierenden Individuen const int T=20; //Lebenstage der Pflanze const float sigma=0.01; //Schrittweite //true waere, wenn dominante Rekombination erwuenscht, false bedeutet intermediaere Rekombination const bool dominanteRekombination = false; const char strategie ='+'; //Auswahl zwischen Kommastrategie (,) und Plusstrategie (+) const float r=0.1; const float L0=0.01; //Startbiomasse float population[mu][T]; //Population int reproduzIndividuen[rho]; //Indizes der reproduzierenden Organismen aus der Population float kinder[lambda][T]; //die erzeugten Kinder float nachkomme[T]; //der einzelne Nachkomme, der in einer der lambda- Schleifeniterationen erzeugt wird float zielfkt(float u[]) //berechnet fuer gegebene ur die Bluetenbiomasse nach den T Tagen { float L=L0; float R=0.0; for(int t=0;t<T;t++) { L= L + r*(1-u[t])*L; R= R + r*u[t]*L; } return R; } //generiert ganzzahlige gleichverteilte Zufallszahl zwischen 0 und max //Vor Benutzung der Funktion muss Generator initialisiert werden int zufallszahl(int max) { int wert=rand()%(max+1); return (wert); } //generiert eine Zufallszahl zwischen 0 und 1 //(fueuer die zufaellige Initialiserung der Elterngeneration //auch dieser Generator sollte vor Benutzung der Funktion initialisiert werden float zufallszahl01() { float wert=rand()/(float)RAND_MAX; return (wert); } //erzeugt eine normalverteilte Zufallszahl (nach der Polar- Methode) float normalverteilt() { float u1=2*zufallszahl01()-1; float u2=2*zufallszahl01()-1; float v=(2*u1-1)*(2*u1-1)+(2*u2-1)*(2*u2-1); while (v>=1) { u1=2*zufallszahl01()-1; u2=2*zufallszahl01()-1; v=u1*u1+u2*u2; } float x=u1*sqrt((-2)*log(v)/v); return x; } //Initialisiert die Population der 0-ten Generation mit zufaelligen Werten void initElternpop(){ for(int i=0;i<mu;i++){ for(int j=0;j<T;j++){ population[i][j]=zufallszahl01(); } } } int main(int argc, char *argv[]) { srand(time(NULL)); //der ersten Zufallszahl wird nicht vertraut und deshalb wird sie verworfen rand(); //File- Streams fuer die Beobachtungen ofstream BesteFit; ofstream GewinnBesteFit; ofstream DurchschnFit; ofstream GewinnDurchschnFit; ofstream BestesIndiv; //Öffne die File- Streams BesteFit.open("BesteFit.dat"); GewinnBesteFit.open("GewinnBesteFit.dat"); DurchschnFit.open("DurchschnFit.dat"); GewinnDurchschnFit.open("GewinnDurchschnFit.dat"); BestesIndiv.open("BestesIndiv.dat"); //initialisiere die erste Generation zufaellig initElternpop(); //Variablen zur Dokumentation //beste Fitness im aktuellen Schritt und in der letzten Generation float besteFitnessG, besteFitnessGG; //durschnittliche Fitness im aktuellen Schirtt und einen zuvor float durchschnFitnessG, durchschnFitnessGG; float gewinnBesteFitness=0; float gewinnDurchschnFitness=0; //Index des besten Individums in der aktuellen Generation int fittest=0; //bestimme die beste und die durchschnittliche Fitness //der zufaelligen initialisierten Ausgangspopulation besteFitnessG=zielfkt(population[0]); float fit; float fitsum=0; for(int i=1;i<mu;i++){ fit=zielfkt(population[i]); if(fit>besteFitnessG){ besteFitnessG=fit; fittest=i; } fitsum+=fit; } durchschnFitnessG=fitsum/(float)mu; //Schleife fuer die Generationsdurchlaeufe, das Abbruchskrterium ist //das Erreichen einer bestimmten Generationsanzahl while (g<maxGen){ int elter; int woher; for(int i=0;i<lambda;i++){ for(int j=0;j<rho;j++){ elter=zufallszahl(mu-1); for(int k=0;k<j;k++){ if(elter==reproduzIndividuen[k]){ elter=(elter+1)%mu; k=0; } } reproduzIndividuen[j]=elter; } //rekombiniere Strategieparameter //findet hier nicht statt //rekombiniere Objektparameter //dominat: //bedeutet, dass der Wert des nachkommens fuer jede Stelle //zufaellig aus den Eltern genommen wird if(dominanteRekombination){ for(int tag=0;tag<T;tag++){ woher=zufallszahl(rho-1); nachkomme[tag]=population[reproduzIndividuen[woher]][tag]; } } //intermediaer: //bedeutet, der Mittelwert der Eltern //wird fuer jede Position verwendet else { for(int tag=0;tag<T;tag++){ float summe=0; for (int l=0;l<rho;l++){ summe+=population[reproduzIndividuen[l]][tag]; } nachkomme[tag]=summe/(float)rho; } } //mutierte Strategieparameter finden hier nicht statt //findet hier nicht statt //mutiere Objektparameter float mutierterWert; for (int tag=0;tag<T;tag++){ //addiere normalverteilten Wert dazu mutierterWert=nachkomme[tag]+(sigma*normalverteilt()); //Ueberpruefung, ob der Wert noch zwischen 0 und 1 ist if(mutierterWert<0){ mutierterWert=0; } if(mutierterWert>1){ mutierterWert=1; } nachkomme[tag]=mutierterWert; } //fuege erzeugten Nachkommen in die Gruppe der Nachkommen ein for(int tag=0;tag<T;tag++){ kinder[i][tag]=nachkomme[tag]; } } //endfor //Selektion if (strategie==','){ //mu, lambda: Selektiere mu neue Individuen //(neue Elternpopulation) aus der Kinderpopulation float guete[lambda]; //berechne die Guete der Individuen for(int i=0;i<lambda;i++){ guete[i]=zielfkt(kinder[i]); } //waehle die mu besten aus for(int i=0;i<mu;i++){ //finde bestes Individuum int maxpos=0; for(int j=1;j<lambda;j++){ if(guete[j]>guete[maxpos]){ maxpos=j; } } //Kopiere dieses in die Population for(int l=0;l<T;l++){ population[i][l]=kinder[maxpos][l]; } guete[maxpos]= -1.0; } } else{ //mu + lambda: Selektiere die mu besten Individuen aus Eltern und Kinderpopulation float neuePopulation[mu] [T]; float gueteKinder[lambda]; float gueteEltern[mu]; //berechne die Guete der Kinder for(int i=0;i<mu;i++){ gueteEltern[i]=zielfkt(population[i]); } //waehle daraus die mu besten aus for(int i=0;i<mu;i++){ //finde das beste Individuum int maxposKinder=0; for(int j=1;j<lambda;j++){ if(gueteKinder[j]>gueteKinder[maxposKinder]){ maxposKinder=j; } } int maxposEltern=0; for(int j=1;j<mu;j++){ if(gueteEltern[j]>gueteEltern[maxposEltern]){ maxposEltern=j; } } //ersetze nun alte Population durch neue for(int indiv=0; indiv<mu;indiv++){ for(int day=0;day<T;day++){ population[indiv][day]=neuePopulation[indiv][day]; } } } //Bewertung und Dokumentation //Qualitätsgewinn besteFitnessGG=zielfkt(population[0]); fittest=0; fitsum=0; for(int i=1;i<mu;i++){ fit=zielfkt(population[i]); if(fit>besteFitnessGG){ besteFitnessGG=fit; fittest=i; } fitsum+=fit; } durchschnFitnessGG=fitsum/(float)mu; gewinnBesteFitness=besteFitnessGG-besteFitnessG; gewinnDurchschnFitness=durchschnFitnessGG-durchschnFitnessG; besteFitnessG=besteFitnessGG; durchschnFitnessG=durchschnFitnessGG; //Dokumentation des Fitnessverlaufs, Schreiben in //verschiedene Dokumentationsdateien BesteFit << g << " "<< besteFitnessG <<"\n"; GewinnBesteFit << g << " "<< gewinnBesteFitness << "\n"; DurchschnFit << g << " "<< durchschnFitnessG << "\n"; GewinnDurchschnFit << g << " "<< gewinnDurchschnFitness << "\n"; g++; }//endwhile //gibt das Ergebnis aus cout << "Ende nach " << g << " Generationen mit durschnittlicher Fitness" << durchschnFitnessG << "\n"; cout << "Bestes Individuum mit Fitness " <<besteFitnessG<< " ist Individuum:"<<"\n"; for(int d=0;d<T;d++){ cout << population[fittest][d] << " "; BestesIndiv << d << " " << population[fittest][d] << "\n"; } BesteFit.close(); GewinnBesteFit.close(); DurchschnFit.close(); GewinnDurchschnFit.close(); BestesIndiv.close(); } return(0); }
-
Und deine Frage???Man Leute

-
ZoliTeglas schrieb:
dieser schmeisst aber komische Dinge aus, die ich nicht deuten kann.
Wie wär's, wenn du uns diese einfach mal nennen würdest? Das macht die Sache u.U. leichter.

-
abgesehen von (_sehr_) wenigen Zeilen, wäre der Quellcode wohl im C-Unterforum besser aufgehoben...
Z8-Z12:
2 C++-Header, 3 C-HeaderZ16-Z35:
Variablen, die wohl mindestens in ne andere Datei gehören, aber besser noch in Klassen gekapselt wären, werden mit teils total dummen namen definiert: mu, T, sigma, r, L0, ...Z37:
Man braucht globale Variablen, um der Fkt nich so viel Parameter (wie z.bsp. die Array-Länge übergeben zu müssen... n1)eingerückt wird immermal anders...
zur main-fkt wollte ich eigtl gar nix sagen, weils mir die zeit nich ma wert war... aber wenn ich dann so sinnlose casts sehe (fitsum ist ein float -> mu wird automatisch in float convertiert(gecastet) und das ergebnis ist auch ein float...):
durchschnFitnessG=fitsum/(float)mu;frag ich mich doch, ob der Programmierer wirklich ein solcher ist...
und die x Zeilen in der main-fkt, die nur mit Variablen-Deklarationen und zum Teil -Definitionen sind auch ma wieder C-like...alles in allem ein C-Quellcode, der aufgrund von ca. 20 Zeilen nicht mehr mit nem C-Compiler zum laufen gebracht werden kann...
Ich glaube nicht, dass sich irgendwer hier die Mühe machen wird, ohne Fehlermeldungen Fehler zu finden - weils einfach ma mehr als nur unübersichtlich is...
bb
-
Ich werde aus Deinem "Beitrag" auch nicht schlau, vermute aber mal, Du suchst Infos zu srand und rand
-
ZoliTeglas schrieb:
Ich kann ihn leider nicht auf das Wesentliche reduzieren, da ich nicht weiss, was das Wesentliche ist!
Nette Ausrede. :p
Wenn du eine aussagekräftige Frage stellst, brauchst du unter Umständen gar keinen Code. Wenn es um Fehler im Code geht, lokalisier diese zumindest mit einem Debugger oder mit Konsolenausgaben. Teilweise kannst du sie dann gleich selbst beheben, andernfalls postest du ein wenig Kontext. Bei Code über 100 Zeilen sind die Wahrscheinlichkeit rapide, dass sich jemand ernsthaft Zeit nimmt.
-
der scheint gut zu sein