GOOGLE ADS

пятница, 6 мая 2022 г.

Кривые бета-распределения с Python и scipy для распределения человеко-дней

Цель состоит в том, чтобы распределить трудозатраты в человеко-днях (ось y) по периодам дней (ось x) в соответствии с определенными формами кривой: раструб, передняя нагрузка, задняя нагрузка, U-образная форма.

Эти модели можно было бы идеально нарисовать с помощью бета-распределения и поиграть с параметрами «a» и «b», чтобы получить желаемые формы.

Моя (слабая математик) проблема состоит в том, чтобы преобразовать список плотности результатов бета-функции scipy PDF ( y1, y2, y3) в список процентных нагрузок от 0 до 1 (нагрузки по оси Y в каждой точке периода x (день #)). Сумма этих процентных нагрузок предполагается равной 1 (100%). Значения X - это дни и всегда> 0

Затем возникла идея выполнить итерацию по списку процентных значений оси Y и умножить их на общее значение человеко-дней, чтобы получить желаемое распределение трудозатрат в человеко-днях по дням.

Фрагмент кода выглядит так:

import numpy as np
from scipy.stats import beta
import matplotlib.pyplot as plt
total_demand = 100 # total man-days demand
x = np.linspace(0, 1, 100) # 100 days range. PDF function accepts values in range 0...1
y1 = beta.pdf(x, 2, 8) # a=2, b=8. FrontLoad distribution
y2 = beta.pdf(x, 5, 5) # a=5, b=5. Bell-shape distribution
y3 = beta.pdf(x, 8, 2) # a=8, b=2. BackLoad distribution
y1_demands = [total_demand*y for y in y1] # does not work because y values are density and not percentage and
# could be greater than 1

Графики результатов плотности:


Решение проблемы

Мгновенное значение PDF не ограничено [0,1]. Только интеграл по любому подмножеству. В этом случае вы хотите, чтобы ваши подмножества были днями, поэтому вам нужно будет интегрировать каждый день. Это непросто с pdf, но с предварительно интегрированным cdf это легко - просто возьмите текущую разницу:

y1 = np.diff(beta.cdf(x, 2, 8)) # a=2, b=8. FrontLoad distribution
y2 = np.diff(beta.cdf(x, 5, 5)) # a=5, b=5. Bell-shape distribution
y3 = np.diff(beta.cdf(x, 8, 2)) # a=8, b=2. BackLoad distribution

Я не могу прикреплять изображения, но это должно дать вам ожидаемые графики.

Также это:

y1_demands = [total_demand*y for y in y1]

может быть просто:

y1_demands = total_demand*y1

numpyпредназначен для предотвращения forциклов, которые медленны в python. если вы обнаружите, что перебираете массивы, вероятно, есть гораздо более быстрый (и обычно более понятный) способ сделать это в numpy.

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...