Importer:Error:WasEmpty



  • Hallo ihr Lieben,

    ich habe mal wieder eine Frage. Ich habe folgendes Minimalbeispiel: Ich möchte im Zuge eines stochastischen Modells nacheinander Ereignisse ausführen, die mit einer gewissen Wahrscheinlichkeit eintreten.
    In dem vorliegenden Minimalbeispiel habe ich z.B. in Zeile 11 drei Ereignisse mit den Wahrscheinlichkeiten 0.2, 0.5 und 0.3. Im weiteren Verlauf berechne ich die kumulative Wahrscheinlichkeit und frage in Zeile 24 zusammen mit einer Zufallszahl zwischen 0 und 1 das zufällige Ereignis ab [1]. Mit dem index gehe ich dann in die switch Abfrage.

    So. Das Problem ist nun folgendes: Der Vektor in Zeile 11 wird zur Laufzeit dynamisch erzeugt, d.h. die Anzahl der möglichen Ereignisse mitsamt ihrer Wahrscheinlichkeit sind nicht fix. Das führt z.B. dazu, dass manche Ereignisse nicht eintreten können. Das ist im weiteren Verlauf bis Zeile 26 eigentlich kein Problem, allerdings scheitert es dann an der switch Abfrage, denn dabei sind die Nummern fix!

    Ich müsste also den eintretenden Wahrscheinlichkeiten direkt die Nummer des Falls in der switch Abfrage mitgeben ... oder so ähnlich. Wie kriege ich das Problem denn gelöst? Ich schätze, dass es wieder ein Standarproblem ist und ich jetzt ein Schlagwort um die Ohren gehauen kriege. 😃

    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <vector>
    
    int main()
    {
    	std::mt19937 generator;
    	std::uniform_real_distribution<double> distribution(0.0,1.0);
    
    	std::vector<double> probs = { 0.2, 0.5, 0.3 };
    	std::vector<double> cum_probs;
    
    	for(unsigned int i = 0; i < probs.size(); ++i)
    	{
    		if(i == 0)
    			cum_probs.push_back(probs);
    		else
    			cum_probs.push_back(probs[i] + cum_probs[i-1]);
    	}
    
    	double random_number = distribution(generator);
    
    	auto low = lower_bound(cum_probs.begin(),cum_probs.end(),random_number);
    
    	unsigned int index = low - cum_probs.begin();
    
    	switch(index)
    	{
    		case 0: std::cout << "Event Nr. " << index << std::endl; break;
    		case 1: std::cout << "Event Nr. " << index << std::endl; break;
    		case 2: std::cout << "Event Nr. " << index << std::endl; break;
    	}
    
    	return 0;
    }
    

    Gruß,
    -- Klaus.

    [1] Ich bin so froh Sean Parents Vortrag über [i]No Raw Loops* gesehen zu haben, algorithm enthält so viel. 😃



  • Also egal was das wirkliche Problem ist.

    Das switch am Ende deines Codes ist unnötig. Es macht vor allem nichts. In jedem Fall wird dasgleiche ausgegeben, jedoch abhängig von der Variablenbelegung.

    Nimm nur das cout, das switch drumherum kann weg.



  • Hallo Klaus,

    nur ein Hinweis: die Zeilen 14-20 kannst Du auch durch std::partial_sum ersetzen

    Klaus82 schrieb:

    algorithm enthält so viel. 😃

    ja - und <numeric> gibt es auch noch.

    Gruß
    Werner



  • Hallo Werner,

    Werner Salomon schrieb:

    nur ein Hinweis: die Zeilen 14-20 kannst Du auch durch std::partial_sum ersetzen

    Das ist cool! 🙂 😃

    Damit werden daraus drei Zeilen, ja? 👍

    std::vector<double> probs = { 0.2, 0.5, 0.3 };
    	std::vector<double> cum_probs(probs.size(), 0.0);
    
    	std::partial_sum(probs.begin(), probs.end() , cum_probs.data());
    

    Gruß,
    -- Klaus.



  • Skym0sh0 schrieb:

    Das switch am Ende deines Codes ist unnötig. Es macht vor allem nichts. In jedem Fall wird dasgleiche ausgegeben, jedoch abhängig von der Variablenbelegung.

    Ja, die switch Abfrage ist symbolisch für die Fallunterscheidung.

    Vielleicht an einem Beispiel:
    Der Ursprüngliche Vektor mit den Wahrscheinlichkeiten könnte in einem anderen Schritt derart aussehen, dass das Ereignis für 0.5 nicht möglich ist. D.h. die neuen relativen Wahrscheinlichkeiten werden damit zu 0.2 / (0.2 + 0.3) = 0.4 und 0.3 / (0.2 + 0.3) = 0.6

    Damit ergibt sich vector<double> probs = { 0.4, 0.6 }; .

    Jetzt kann es sein, dass der Algorithmus durch die erzeugte Zufallszahl den Index 1 zurückgibt, d.h. das zweite Ereignis anhand des aktuellen Vektors.

    Dieses Ereignis hätte im vorangegangenen Schritt allerdings noch den Index 2, da der Vektor drei Elemente enthielt.

    D.h. die Auswahl des Ereignisses kann nicht starr als Indexnummer abgefragt werden, sondern muss mit den tatsächlich möglichen Ereignissen variieren.

    Gruß,
    -- Klaus.


Log in to reply