3

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

例如:

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

[ 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 个之间。

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

4

2 回答 2

6

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

2)计算这n个数字的总和。

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

于 2013-04-19T02:44:43.170 回答
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) 的输出(如果你需要实现的话,Fisher-Yates 打乱)


如果你想让它变得音乐化,你可能想要“离散化”第 2 步,我的意思是:

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

b) 总和除以 D(称为 Sd)(例如 0.5/0.05 = 10)

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

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

这只会给你半分音符。如果你使用 4 而不是 2,你会得到半四分音符,依此类推

于 2013-04-19T02:37:30.810 回答