Search code examples
algorithmmathoptimizationprobability

Coin flipping - returning random outcome


forgive me if this was already posted :) I have had a problem stuck in my head all day which I have been trying to think of an efficient solution for. Basically the problem is this: Imagine you have to flip a coin 3 billion times and would like a function that returns the amount of heads after all these flips. One possible solution would be to obviously make a for loop iterating 3 billion times recording how many heads and tails and returning the heads - this is obviously an incredibly inefficient solution. I thought of binomial probability but could not see where this could come in to help solve this problem (i'm probably missing something really obvious).

For example say I input in the function NumberOfHeads(flips) most the time (statistically) it will likely return some number around flips / 2. However say flips = 3 billion there should still be a chance that (although incredibly slim to never) it may return 1000 heads or something. Hope I explained whats been troubling me well enough :) thanks for any reponses.


Solution

  • You could use scipy.stats.binom here. The function below returns the number of heads from a randomly sampled binomial distribution with fair coin flips at each (bernoulli) trial.

    import scipy.stats as scs
    def num_heads(num_flips):
        flips = scs.binom(n=num_flips, p=0.5)
        return np.asscalar(flips.rvs(1))
    
    num_heads(3000000000)
    # 1499985766
    

    .rvs() here stands for random variate.

    Without looking through the source, I'm going to guess random number generation is using the analytic binomial CDF p=CDF(x), taking the inverse CDF, then choosing p from a ~U(0,1) distribution. You can read more about that method in Downey - ThinkStats - section 5.6. Disclosure: I might be totally wrong, as I often am.