如何有效地随机化所有相同浮点数的相对较小的数组?
例如:我有一个相等的浮点数数组:
[ 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个,你会得到半分频,等等