Answers:
看一下这张照片:
它显示了将(随机)值映射到曲线的过程。假设您生成一个范围从0到1的均匀分布的随机值X。通过将该值映射到曲线上-或者换句话说,使用f(X)而不是X-您可以按照自己喜欢的任何方式倾斜分布。
在这张照片中,第一个曲线使更高的值更有可能出现;第二个使更低的值更有可能;第三个使价值集群在中间。曲线的确切公式并不十分重要,可以根据需要选择。
例如,第一条曲线看起来有点像平方根,第二条曲线看起来像平方。第三个有点像多维数据集,只能翻译。如果您认为平方根太慢,则第一条曲线也看起来像f(X)= 1-(1-X)^ 2-平方的倒数。或夸张:f(X)= 2X /(1 + X)。
如第四条曲线所示,您可以简单地使用预先计算的查找表。看起来很丑陋,但是对于粒子系统可能已经足够了。
这种通用技术非常简单而且功能强大。无论您需要什么分布,只要想象一下曲线映射,就可以立即设计一个公式。或者,如果您的引擎具有编辑器,则只需为曲线创建可视化编辑器即可!
更长的解释:
如果您具有所需的概率分布,例如要求的梯度@didito,则可以将其描述为一个函数。假设您想要一个三角分布,其中0处的概率为0.0,并且想要选择一个从0到1的随机数。我们可以将其写为y = x。
下一步是计算此函数的积分。在这种情况下,它的。从0到1评估为½。这是有道理的-它是一个底数为1且高度为1的三角形,因此其面积为½。
然后,您从0到区域(在我们的示例中为½)均匀地选择一个随机点。我们称这个z。(我们从累积分布中统一选择。)
下一步是倒退,找出x的值(我们称为x̂)对应于z的面积。我们正在寻找,从0到x̂求值,等于z。当你解决,你会得到。
在此示例中,您从0到½中选择z,然后所需的随机数是。简化后,可以写成 -正是电子商务推荐。
sqrt(random())
一生都在努力,但我凭经验去尝试。尝试将随机数绑定到曲线上,它确实起作用。现在,我对数学有了更多的了解,知道为什么它很有价值!
通过使用指数系统,您可能会很接近所需的内容。
使x基于1-(rnd ^ value)之类的值(假设rnd在0到1之间),您将根据自己的使用情况从左到右倾斜一些不同的行为。较高的价值将使您的分布更偏斜
您可以使用在线绘图工具来了解一些不同的方程式,然后再放入其中,然后粗略地了解其行为,也可以直接在粒子系统中摆弄这些方程式,这取决于您的口味。
编辑
对于类似粒子系统的每个粒子的CPU时间非常重要的事情,直接使用Math.Pow(或等效语言)可能会导致性能下降。如果需要更高的性能,并且在运行时未更改值,请考虑切换到等效函数,例如x * x而不是x ^ 2。
(分数指数可能更多,但是数学背景比我强的人可能会想出一种创建近似函数的好方法)
value
,这是Beta(value,1)。
您正在寻找的术语是Weighted Random Numbers
,我见过的大多数算法都使用trig函数,但是我想我想出了一种有效的方法:
创建一个表/数组/列表(无论如何),其中包含随机函数的乘数。手动或以编程方式填写...
randMulti= {.1,.1,.1,.1,.1,.1,.2,.2,.3,.3,.9,1,1,1,}
...然后乘以random
随机选择的randMulti
,最后乘以分布的最大值...
weightedRandom = math.random()*randMulti[Math.random(randMulti.length)]*maxValue
我确实相信这将比使用sqrt
或其他计算复杂的函数快得多,并且将允许使用更多自定义分组模式。
我认为您要求的是使用平方根函数实现的分布。
[position] = sqrt(rand(0, 1))
这将在[0, 1]
一个位置的概率等于该位置的概率的单维度字段中给出分布,即“三角分布”。
备用无平方根生成:
[position] = 1-abs(rand(0, 1)-rand(0, 1))
最佳实现中的平方根只是几个没有分支的乘法和求和命令。(请参阅:http : //en.wikipedia.org/wiki/Fast_inverse_square_root)。这两个功能中哪个更快,取决于平台和随机生成器。例如,在x86平台上,随机生成器中仅需几个不可预测的分支即可使第二种方法变慢。
只需使用Beta版本:
等等
两个形状参数不必为整数。
uniform_generator()
为即可gsl_ran_beta(rng, a, b)
。看到这里:gnu.org/software/gsl/manual/html_node/…–
甚至更简单,根据随机生成器的速度,您可以生成两个值并将它们平均。
或者,甚至更简单,其中X是rng的结果,首先double y = double(1/x);
是x = y*[maximum return value of rng];
。这会将数字加权成较低的数字。
生成并平均更多的值,以增加使值更接近中心的可能性。
当然,这仅适用于标准钟形曲线分布或其“折叠”版本*,但使用快速生成器,它可能比使用sqrt等各种数学函数更快,更简单。
您可以找到关于骰子钟形曲线的各种研究。实际上,Anydice.com是一个很好的网站,可以为掷骰子的各种方法生成图形。尽管您使用的是RNG,但前提和结果是相同的。因此,这是在编码之前查看分布的好地方。
*此外,您可以通过取一条轴并减去平均结果,然后再加上该轴,来沿轴“折叠”结果分布。例如,您希望较低的值更常见,例如,您希望最小值为15,最大值为35,范围为20。因此,您将两个范围为20(两倍于您想要的范围),这将产生一个以20为中心的钟形曲线(我们在末尾减去5,将范围从20变为40,从15变为35)。取生成的数字X和Y。
最终号码,
z =(x+y)/2;// average them
If (z<20){z = (20-z)+20;}// fold if below axis
return z-5;// return value adjusted to desired range
如果您的最小值是零,甚至更好,请改为这样做,
z= (x+y)/2;
If (z<20){z = 20-z;}
else {z = z - 20;}
return z;