Search code examples
c++randomprobabilitymontecarlocoin-flipping

Question About a Probability Model Using C++


I am trying to solve a probability question theoretically and then modeling it on C++ but my code outputs a different probability from the theoretical one.

Question:

A balanced coin is tossed three times. Calculate the probability that exactly two of the three tosses result in heads.

Answer:

Sample space: {(H,H,H), (H,H,T), (H,T,H), (H,T,T), (T,T,T), (T,T,H), (T,H,T), (T,H,H)}

Probablity that exactly two of the three tosses result in heads = 3/8

C++ Code:

#include <iostream>
#include <time.h>
#include <stdlib.h>

bool TossCoinXNumber(int x);
int TossCoin();
void CalcProbability(int x);

using namespace std;

int main()
{
    srand (time(NULL));
    CalcProbability(1000000);
    return 0;
}

int TossCoin(){
    int toss = rand() % 2;
    return toss;
}

bool TossCoinXNumber(int x){
    int heads=0;
    int tails = 0;
    for(int i = 0; i < x; i++){
        if(TossCoin() == 1){
            heads++;
        }
        else if(TossCoin() == 0){
            tails++;
        }

    }
            if(heads == 2 && tails == 1){
            return true;
        }
    return false;
}

void CalcProbability(int x){
    double probability = 0.0;
    double count = 0.0;
    for(int i = 0; i < x; i++){
        if(TossCoinXNumber(3) == true){
            count++;
        }
    }
    probability = (count*1.0) / (x*1.0);
    cout << probability;
}

Code Output: 0.187053

Which is different than the theoretical probability of 3/8


Solution

  • As n. 1.8e9-where's-my-share m. correctly pointed out, You are calling TossCoin() twice. This is your modified code that fixes the problem:

    #include <stdlib.h>
    #include <time.h>
    
    #include <iostream>
    
    bool TossCoinXNumber(int x);
    int TossCoin();
    void CalcProbability(int x);
    
    using namespace std;
    
    int main()
    {
        srand(time(NULL));
        CalcProbability(1000000);
        return 0;
    }
    
    int TossCoin()
    {
        int toss = rand() % 2;
        return toss;
    }
    
    bool TossCoinXNumber(int x)
    {
        int heads = 0;
        int tails = 0;
        for (int i = 0; i < x; i++)
        {
            int toss = TossCoin();
            if (toss == 1)
            {
                heads++;
            }
            else if (toss == 0)
            {
                tails++;
            }
        }
        if (heads == 2 && tails == 1)
        {
            return true;
        }
        return false;
    }
    
    void CalcProbability(int x)
    {
        double probability = 0.0;
        double count = 0.0;
        for (int i = 0; i < x; i++)
        {
            if (TossCoinXNumber(3) == true)
            {
                count++;
            }
        }
        probability = (count * 1.0) / (x * 1.0);
        cout << probability;
    }
    

    This is the shorter code that I prefer:

    #include <iostream>
    #include <random>
    
     using namespace std;
    
     int main(void)
    {
         int tries = 1000000, count = 0;
    
        for (int i = 0; i < tries; ++i)
        {
            int heads = 0;
            for (int j = 0; j < 3; ++j) heads += (rand() % 2);
            count += (heads == 2);
        }
    
        cout << count / float(tries) << endl;
    }
    

    In this code, the integer results of comparisons are used to increment heads, count so we don't have any ifs.