如何有效地随机化一个相对较小的数组,所有相同的浮点数保持总和



如何有效地随机化所有相同浮点数的相对较小的数组?

例如:

我有一个相等的浮点数数组:

[ 0.1, 0.1, 0.1, 0.1, 0.1 ] // sum === 0.5

我想这样随机化它:

[ 0.1, 0.2, 0.0, 0.15, 0.05 ] // sum === 0.5

初始数组的值总是相等的,但它可以在不同的范围内:

[ 3.56, 3.56, 3.56, 3.56, 3.56 ]

我不知道这些初始数组的实际大小,但我猜它们的长度将在50到100项之间。

(仅供参考:这些是音符持续时间,如果算法是音乐的,则额外加分)

1)在0到1之间随机计算n个浮点数

2)计算这n个数的和。

3)你必须把总和除以它本身,然后乘以你想要得到的总和(在下面的resultsum中)。因此,如果将1)中生成的n个数字中的每一个除以2)中计算的和,并将结果与结果和相乘,那么您将得到您想要的结果中的随机数。

非音乐但:

1)计算数组中所有值的和

2)在0到sum之间生成N-1个点,其中N为数组中条目的个数。

3)将这N-1个点从最小到最大排序,然后在左边增加0,在右边求和。基本上,想象你已经取了一个sum长度的条,并在N-1个点上切割它。

4)对于现在N+1个点中的每个元素(不包括第一个点),计算它与前一个点的差。这些差的和仍然是sum -你可以自己证明这一点,想象一下被切成碎片的棒子是差。如果你在0.2和0.7处切割长度为1的条,那么你将得到0,0.2,0.7,1.0,差异为0.2,0.5,0.3,总和为1。

5)随机对4)的输出进行洗牌(如果需要实现的话,可以进行费雪-叶茨洗牌)


如果你想让它具有音乐性,你可能想要"离散"步骤2,我的意思是:

a)将数组的第一个元素除以2(称为D)(例如0.1/2 = 0.05)

b)将sum除以D(称之为Sd)(例如0.5/0.05 = 10)

c)创建从0到Sd的随机数作为整数,然后将它们乘以D

d)现在从原算法中的3继续

这将只给你半分音符。如果你用4个而不是2个,你会得到半分频,等等

最新更新