Фон
Мне попалась загадка.Вот оно:
Однажды пришелец приходит на Землю.Каждый день каждый иностранец делает одну из четырех вещей, каждая с равной вероятностью:
- Убить себя
- Ничего не делать
- Разделить себя на двух пришельцев (убиваясам)
- раскололся на трех инопланетян (убивая себя)
Какова вероятность того, что инопланетный вид в конечном итоге полностью исчезнет?
Ссылка на источник и решение, проблема # 10
К сожалению, я не смог решить проблему теоретически.Затем я перешел к моделированию с использованием базовых симуляций Маркова и Монте-Карло.
Об этом мне не говорили в интервью.Я узнал проблему от друга, а затем нашел ссылку выше при поиске математических решений.
Переосмысление вопроса
Начнем с количества пришельцев n = 1
.n
имеет шанс не измениться, быть уменьшенным на 1
, увеличенным на 1
и уменьшенным на 2
,% 25 для каждого.Если n
увеличивается, то есть умножается на инопланетян, мы повторяем эту процедуру еще раз n
.Это соответствует тому, что каждый инопланетянин снова сделает свое дело.Я должен установить верхний предел, чтобы мы прекратили симуляцию и избежали сбоев.n
, вероятно, увеличится, и мы повторяем n
раз снова и снова.
Если инопланетяне как-то вымирают, мы прекращаем симуляцию снова, так как имитировать нечего.
Послеn
достигает нуля или верхнего предела, мы также записываем население (это будет либо ноль, либо некоторое число >= max_pop
).
Я повторяю это много раз и записываю каждый результат.В конце, число нулей, деленное на общее число результатов, должно дать мне приближение.
Код
from random import randint
import numpy as np
pop_max = 100
iter_max = 100000
results = np.zeros(iter_max, dtype=int)
for i in range(iter_max):
n = 1
while n > 0 and n < pop_max:
for j in range(n):
x = randint(1, 4)
if x == 1:
n = n - 1
elif x == 2:
continue
elif x == 3:
n = n + 1
elif x == 4:
n = n + 2
results[i] = n
print( np.bincount(results)[0] / iter_max )
iter_max
и pop_max
действительно можно изменить, но ясчиталось, что если будет 100 инопланетян, вероятность их вымирания будет ничтожно мала.Хотя это всего лишь предположение, я ничего не сделал, чтобы рассчитать (более) правильный верхний предел для населения.
Этот код дает многообещающие результаты, довольно близкие к реальному ответу, который составляет примерно% 41,4.
Некоторые результаты
> python aliens.py
0.41393
> python aliens.py
0.41808
> python aliens.py
0.41574
> python aliens.py
0.4149
> python aliens.py
0.41505
> python aliens.py
0.41277
> python aliens.py
0.41428
> python aliens.py
0.41407
> python aliens.py
0.41676
Последствия
Я согласен с результатами, но я не могу сказать то же самое в течение времени, которое занимает этот код.Это занимает около 16-17 секунд:)
Как мне улучшить скорость?Как я могу оптимизировать циклы (особенно цикл while
)?Может быть, есть гораздо лучший подход или лучшие модели?