具有 Python 和 scipy 的 Beta 分布曲线用于分配人日工作量

Beta distribution curves with Python and scipy to distribute man-days effort

目标是根据定义的曲线形状:钟形、FrontLoad、BackLoad、U 形

这些模型可以用 Beta distribution 完美绘制并与 'a''b'[=31 一起玩=] 参数以获得所需的形状。

我(弱数学家)的问题是将 scipy beta 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 并不容易,但是使用 pre-integrated 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.

中可能有更快(通常更清晰)的方法