Skip to content

Instantly share code, notes, and snippets.

@gngdb
Last active May 7, 2020 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gngdb/8ddc6ca142178d280695ee7e3de62927 to your computer and use it in GitHub Desktop.
Save gngdb/8ddc6ca142178d280695ee7e3de62927 to your computer and use it in GitHub Desktop.
Brute Force Ancestral Monte Carlo I used for project planning when writing my PhD thesis
# renders a MAP estimate of the PhD thesis timeline along with estimate of the
# 50%, 90% and 99% chance of thesis being complete
import numpy as np
import time
import datetime
from datetime import timedelta
def main():
# model the PhD as a sequence of events of random length.
# would like to be recursively evaluated
# (name, n, p)
# (str, days to complete, probability of succesful workday)
to_complete = [#("Resouce-Efficient", 1, 2), DONE
#("Moonshine", 5, 0.8), DONE
#("Lit Review", 2, 0.9), DONE
("Low-Rank", 1, 0.8),
("Intro & Conclusion", 2, 0.8),
("Editing", 2, 0.8)]
# sample a lot
rng = np.random.RandomState(42)
n_samples = 100000
samples = [(n,rng.geometric(p, size=(n_samples,d)).sum(1)) for n, d, p in to_complete]
# would be nice to take into account weekends, but probably not going to happen
# combine the samples to get no. of days to completion
sum_events = np.concatenate([s.reshape(1,-1) for n, s in samples],0)
sum_events = sum_events.sum(0)
today = datetime.date.fromtimestamp(time.time())
if False:
######################
# The NIPS condition #
######################
# if any of these exceed the 2nd of December, add a week for NIPS
December2 = datetime.date(2018, 12, 2)
days_until = (December2 - today).days
exceeding = (sum_events > days_until).astype(int)
sum_events = sum_events + exceeding*7 # add a week where we hit NIPS
# sort scenarios
sum_events.sort()
p = lambda x: int(round(sum_events[x*n_samples//100]))
print("50 percent chance to be done by: " + str(today + timedelta(days=p(50))))
print("90 percent chance to be done by: " + str(today + timedelta(days=p(90))))
print("99 percent chance to be done by: " + str(today + timedelta(days=p(99))))
return None
# draw timeline
days = 0
current_month = today.month
to_complete = []
for i, (n,m,s) in enumerate(to_complete):
sum_events = np.concatenate([s.reshape(1,-1) for n, s in samples[:i+1]],0)
sum_events = sum_events.sum(0)
sum_events.sort()
p = lambda x: int(round(sum_events[x*n_samples//100]))
to_complete.append((n[0], p(90)))
timeline = ""
total_days = p(90)
while days < total_days:
if days > days_until and days < days_until + 7:
timeline += "N"
to_complete = [(n,m+1) for n,m in to_complete]
total_days += 1
else:
timeline += "-"
days += 1
# see if we've changed month
now = today + timedelta(days)
if now.month > current_month:
current_month = now.month
timeline += "|%i|"%current_month
# to add in when stuff should be completed
past = [n for n,m in to_complete if days-m == 0]
if len(past) > 0:
to_complete.pop(0)
timeline += "|%s|"%past[0]
print(timeline)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment