diff --git a/maths/probability_of_n_heads_in_m_tossing.py b/maths/probability_of_n_heads_in_m_tossing.py new file mode 100644 index 000000000000..d9323ce2d5a6 --- /dev/null +++ b/maths/probability_of_n_heads_in_m_tossing.py @@ -0,0 +1,78 @@ +""" +The probability of getting exactly n heads in m tossing. + +Algorithm Explanation: +If you toss 0 time -> 0 head +Distribution [1] -> Meaning: 1 in the 0-index + +If you toss 1 time -> 0 or 1 head +Distribution [0.5 0.5] -> Meaning: 0.5 in both indexes + +If you toss 2 times -> 0 to 2 heads +Distribution [0.25 0.5 0.25] -> +Meaning: probability of n heads from the distribution +{HH, HT, TH, TT} + +If you toss 3 times -> 0 to 3 heads +Distribution [0.125 0.375 0.375 0.125] -> +Meaning: probability of n heads from the distribution +{HHH, HHT, HTH, HTT, THH, THT, TTH, TTT} + +Therefore, +Probability_distribution(N+1) = + [Probability_distribution(N) 0]/2 + [0 Probability_distribution(N)]/2 + +I used that method in my paper +Titled: Uncertainty-aware Decisions in Cloud Computing: +Foundations and Future Directions +Journal: ACM Computing Surveys (CSUR) +""" + +import numpy as np + + +def probability_of_n_heads_in_m_tossing(head_count: int, toss_count: int) -> int: + """ + Calculate the factorial of specified number (n!). + + >>> import math + >>> all(factorial(i) == math.factorial(i) for i in range(20)) + True + >>> Probability_of_n_heads_in_m_tossing(.2,.5) + Traceback (most recent call last): + ... + ValueError: The function only accepts integer values + >>> Probability_of_n_heads_in_m_tossing(-1,5) + Traceback (most recent call last): + ... + ValueError: The function is not defined for negative values + >>> Probability_of_n_heads_in_m_tossing(3,2) + Traceback (most recent call last): + ... + ValueError: Head count should be smaller than toss count + + >>> Probability_of_n_heads_in_m_tossing(1,1) + 0.5 + >>> Probability_of_n_heads_in_m_tossing(0,2) + 0.25 + >>> Probability_of_n_heads_in_m_tossing(2,3) + 0.375 + """ + if head_count != int(head_count) or toss_count != int(toss_count): + raise ValueError("The function only accepts integer values") + if head_count < 0 or toss_count < 0: + raise ValueError("The function only accepts positive values") + if head_count > toss_count: + raise ValueError("Head count should be smaller than toss count") + if toss_count > 100: + raise ValueError("Limited to 100 tossing to avoid memory issues") + + value = np.ones(1) + + iter1 = 0 + while iter1 < toss_count: + value = np.append(value, [0], axis=0) + np.append([0], value, axis=0) + value = value / 2 + iter1 = iter1 + 1 + + return value[head_count]