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-Header

    Z16-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


Anmelden zum Antworten