forked from colonelpanic/dotfiles
Add miscellaneous python code that I want to keep.
This commit is contained in:
73
resources/python/birthday_problem.py
Normal file
73
resources/python/birthday_problem.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import random
|
||||
import math
|
||||
|
||||
class BirthdayProblem(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def birthday_problem(problem_size=365):
|
||||
birthdays = set()
|
||||
while True:
|
||||
new_birthday = random.randint(1, problem_size)
|
||||
if new_birthday in birthdays:
|
||||
return len(birthdays) + 1
|
||||
birthdays.add(new_birthday)
|
||||
|
||||
|
||||
def theoretical_average(problem_size):
|
||||
probabilities = []
|
||||
contributions = []
|
||||
for n in range(1, problem_size):
|
||||
probability = (float(n-1) / problem_size) * falling_factorial_over_exponentiation(problem_size, n-1)
|
||||
contribution = n * probability
|
||||
probabilities.append(probability)
|
||||
contributions.append(contribution)
|
||||
return sum(contributions)
|
||||
|
||||
|
||||
def falling_factorial(n, k):
|
||||
product = 1
|
||||
while k > 0:
|
||||
product *= n
|
||||
n -= 1
|
||||
k -= 1
|
||||
return product
|
||||
|
||||
|
||||
|
||||
def falling_factorial_over_exponentiation(n, k):
|
||||
orig = n
|
||||
product = float(1)
|
||||
while k > 0:
|
||||
product *= n
|
||||
product = product/orig
|
||||
n -= 1
|
||||
k -= 1
|
||||
return product
|
||||
|
||||
|
||||
def run_birthday_problem_n_times(times_to_run, problem_size=365):
|
||||
return [birthday_problem(problem_size) for i in range(int(times_to_run))]
|
||||
|
||||
|
||||
def number_of_people_to_times_occured(runs):
|
||||
number_of_people_to_times_occured = {}
|
||||
for run in runs:
|
||||
number_of_people_to_times_occured[run] = number_of_people_to_times_occured.get(run, 0) + 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
times_to_run = 131072
|
||||
while times_to_run <= 131072:
|
||||
for problem_size in range(4000, 5000, 100):
|
||||
average = sum(run_birthday_problem_n_times(times_to_run, problem_size=problem_size))/float(times_to_run)
|
||||
print "problem size {3} ran {0} times, average was {1}, theoretical average is {2}".format(
|
||||
times_to_run,
|
||||
average,
|
||||
theoretical_average(problem_size),
|
||||
problem_size
|
||||
)
|
||||
print math.fabs(average - theoretical_average(problem_size))
|
||||
times_to_run *= 2
|
||||
Reference in New Issue
Block a user