带偏斜的Python随机数生成

1 投票
1 回答
768 浏览
提问于 2025-04-17 18:19

我正在尝试为一个生物模拟器创建一个非常简单的进化算法。我想要的是,每个生物都有一个特征和一个支配等级,这两个都是整数。它们的孩子的特征会是生物A的特征和生物B的特征之间的一个随机数,但会偏向于更有支配力的那个生物。比如说,如果生物A的特征是5,支配等级是2,而生物B的特征是10,支配等级是7,那么他们的孩子更有可能拥有8这个特征,而不是6。有没有好的方法来实现这个?

1 个回答

0

你可能并不想要你描述的那种情况,因为这样的话,种群会迅速趋于一致。这是因为你要求的后代值总是在父母值之间,所以极端值会很快消失。

更可能的是,你想要的是一个有固定波动的数字,但这个数字是围绕你描述的值计算出来的。这个其实很简单——中心值就是加权平均。

举个例子,假设特征是T1和T2,主导值是D1和D2。孩子的特征中心值可以表示为TC:

TC = (D1 * T1 + D2 * T2) / (D1 + D2)

然后你可以在这个值上加上一些波动,可以是正的也可以是负的,最后再转换成整数。

[顺便提一下,以上的计算是有道理的:如果主导值相等,即D1=D2,那么上面的公式就变成了

TC = (T1 + T2) / 2

这就是你预期的平均值。如果D1远大于D2,那么

TC ~ T1

这也是符合预期的,因为这时1的影响力大于2。

在Python中:

from random import uniform

delta = 2 # the amount of noise

def child(t1, d1, t2, d2):
    tc = float(d1 * t1 + d2 * t2) / float(d1 + d2)
    tc += uniform(-delta, delta)
    return int(0.5 + tc) # convert to int unbiased

如果我用你给的例子中的数字运行几次:

>>> child(5, 2, 10, 7)
7
>>> child(5, 2, 10, 7)
11
>>> child(5, 2, 10, 7)
8
>>> child(5, 2, 10, 7)
9

结果看起来差不多。注意,这个值并不是强制在父母值之间——在某个情况下它是11——但它的中心值大约在8附近,这也是预期的。

最后,你可以在种群稳定时慢慢减少delta(这是一种模拟退火的方法)。

撰写回答