2016-11-04 21 views
0

Ich versuche, ein Statistikproblem über eine Monte-Carlo-Methode zu bewerten. In diesem Problem erzeuge ich eine Zufallszahl und vergleiche sie mit einer festen Wahrscheinlichkeitszahl, die in einem Vektorfeld mit dem Titel comms_reliability gespeichert ist. Angenommen, es gibt nur eine Variable in der Vektormatrix, vergleiche ich die Zufallszahl und die Wahrscheinlichkeit und talisiere die Ergebnisse, wenn die Zufallszahl größer als die Zuverlässigkeitszahl ist. Das Vektorfeld könnte aber auch zwei Werte haben, wobei ich zwei Zufallszahlen erzeuge und diese mit den beiden Zuverlässigkeitszahlen und vergleiche. Wenn beide Zufallszahlen größer als die Zuverlässigkeitszahlen sind, zähle ich die Szenarien. Theoretisch könnte dies für so viele Werte im Vektorfeld immer so weitergehen, wie ich möchte. Durch einen Mangel an Vorstellungskraft kann ich jedoch nur programmieren, wo die for-Anweisung in mehreren if-Anweisungen für jedes mögliche Szenario enthalten ist. In dieser Implementierung muss ich die gleichen Codezeilen mehrmals kopieren, und es begrenzt auch die Arraygrößen commms_reliability, die ausgewertet werden können, basierend darauf, wie oft ich diese Codezeilen kopiert habe, um den nächsten Arraypunkt zu verarbeiten. Wie kann ich das tun, wo ich nur eine if-Anweisung brauche? Ein Beispiel, wie ich es derzeit codiert habe, ist unten gezeigt.Auswerten der Variablen if-Anweisung in C++

int main(int argc, const char * argv[]) { 
    int sample_size  = 1000000; 
    std::vector<float> comms_reliability = {0.6,0.6}; 
    float tally = 0.0; 

    // rang() = random number generator 
    // if statement for comms_reliability array of size 1 
    if (comms_reliability.size() == 1) { 
     for (int i = 0; i < sample_size; i++){ 
      if (rang() > comms_reliability[0]) tally = tally + 1.0; 
     } 

    } 
    // if statement 2 for comms_reliability array of size 2 
    if (comms_reliability.size() == 2) { 
     for (int i = 0; i < sample_size; i++){ 
      if (rang() > comms_reliability[0] && rang() > comms_reliability[1]) tally = tally + 1.0; 
     } 

    } 
    // if statement 3 for comms_reliability array of size 3 
    if (comms_reliability.size() == 3) { 
     for (int i = 0; i < sample_size; i++){ 
      if (rang() > comms_reliability[0] && rang() > comms_reliability[1] && 
      rang() > comms_reliability[2]) tally = tally + 1.0; 
     } 

    } 

Antwort

2

Wenn ich Sie richtig verstehe Sie sicherstellen möchten, dass alle Elemente comms_reliability einige Kriterium erfüllen (nämlich kleiner als rang()) für jede Probe.

machen also eine Schleife über alle Elemente und jeder testen, oder einfach nur benutzen std::all_of:

// Lambda function used to test a single comm_reliability 
auto is_reliable = [] (float r) { return rang() > r; }; 
// Iterate over your samples 
for (int i = 0; i < sample_size; ++i) { 
    // If all elements satisfy your criterion ... 
    if (std::all_of(std::begin(comms_reliability), 
        std::end(comms_reliability), 
        is_reliable)) { 
    // .. perform your action 
    tally += 1.0; 
    } 
} 

Anstelle der Lambda-Funktion auch eine normale Funktion definiert irgendwo vor verwenden:

bool is_reliable(float r) { 
    return rang() > r; 
} 

Hinweis: Versuchen Sie, die Benennung von Variablen/Funktionen zu verbessern.

+0

zu halten, die das Problem lösen, danke. Außerdem habe ich eine neue C++ - Funktionalität gelernt, die ich vorher nicht kannte. – Jon

+0

Ich bin froh, dass ich Ihnen helfen konnte :) Ich habe einen Link zu einer Online-Dokumentation hinzugefügt, wo Sie viele andere "Goodies" finden können, die die C++ - Standardbibliothek bietet. –

0

einen Flag verwenden, um den Wert

int main(int argc, const char * argv[]) { 
    int sample_size  = 1000000; 
    std::vector<float> comms_reliability = {0.6,0.6}; 
    float tally = 0.0; 

    // rang() = random number generator 

     for (int i = 0; i < sample_size; i++){ 
      boolean flag = true; 
      for(int j = 0; j < comms_reliability.size(); j++) 
      { 
       if (rang() <= comms_reliability[j]) 
       { 
        flag = false; 
        break; 
       } 
      } 
      tally = flag ? tally + 1.0 : tally; 
     }