Random 为测试生成强偏倚随机数
我想用随机输入运行测试,并需要生成“合理的”随机输入 数字,也就是说,匹配好的数字足以通过测试函数的 先决条件,但希望在其代码内部造成更大的破坏Random 为测试生成强偏倚随机数,random,lua,automated-tests,distribution,Random,Lua,Automated Tests,Distribution,我想用随机输入运行测试,并需要生成“合理的”随机输入 数字,也就是说,匹配好的数字足以通过测试函数的 先决条件,但希望在其代码内部造成更大的破坏 math.random()(我使用Lua)生成均匀分布的随机变量 数字。扩大规模将产生比小数字多得多的大数字, 而且会有非常少的整数 我想扭曲随机数(或使用旧的随机数生成新的随机数) 作为随机性源)以强烈支持“简单”数字的方式, 但仍将覆盖整个范围,即扩展到正/负无穷大 (或±1e309用于双精度)。这意味着: 比如说,最多10个数字应该是最常见的
math.random()
(我使用Lua)生成均匀分布的随机变量
数字。扩大规模将产生比小数字多得多的大数字,
而且会有非常少的整数
我想扭曲随机数(或使用旧的随机数生成新的随机数)
作为随机性源)以强烈支持“简单”数字的方式,
但仍将覆盖整个范围,即扩展到正/负无穷大
(或±1e309
用于双精度
)。这意味着:
- 比如说,最多10个数字应该是最常见的
- 整数应该比分数更常见
- 以0.5结尾的数字应该是最常见的分数
- 其次是0.25和0.75;那么0.125,
- 等等
x
(我认为对于无限精度,它将是
零),并且基于此通过迭代计算数字是非常困难的
缓慢(花费几乎无限的时间来构造大量的数字)
有没有人知道一个简单的近似,给定一个均匀分布的
随机性源,产生随机数,随机数大致分布为
如上所述
我想运行数千个随机测试,数量/速度更高
比质量更重要。尽管如此,更好的数字意味着更少的输入被拒绝
Lua有一个JIT,所以性能通常不是什么大问题。然而,跳跃是基于
on randomness将破坏每个预测,并多次调用math.random()
也会很慢。这意味着一个封闭的公式将优于一个封闭的公式
迭代的或递归的
1维基百科有一个 A.超现实数字是两个超现实数字的一对 数字,即<代码> x:{{n} M},其值是中间的数字。 配对,即(对于有限数)
{n | m}=(n+m)/2
(作为有理数)。如果一方
该对的值为空,这被解释为递增(或递减,如果正确的话)
是空的)一个。如果两边都是空的,那就是零。最初,有
没有数字,因此唯一可以构建的数字是0:={124;}
。世代
两个一可以构建数字{0}=:1
和{0}=:-1
,我们得到三个
{1}=:2
,{1}=:-2
,{0}1}=:1/2
和{-1}0}=:-1/2
(加上一些
已知数字的更复杂表示,例如{-1 | 1}?0
)。注意
e、 g.1/3
从来不是由有限数生成的,因为它是无限的
分数–浮点数也是如此,
1/3
永远不会精确表示。这对于算法来说是什么
floor((float_val)对于超现实的十进制扩展,您需要一个随机二进制数。
偶数位告诉您是停止还是继续,奇数位告诉您在树上是向右走还是向左走:
> 0... => 0.0 [50%] Stop
> 100... => -0.5 [<12.5%] Go, Left, Stop
> 110... => 0.5 [<12.5%] Go, Right, Stop
> 11100... => 0.25 [<3.125%] Go, Right, Go, Left, Stop
> 11110... => 0.75 [<3.125%] Go, Right, Go, Right, Stop
> 1110100... => 0.125
> 1110110... => 0.375
> 1111100... => 0.625
> 1111110... => 0.875
或真正的二进制扩展:
Math.random().toString(2).substring(2)
不确定哪个是真正的“随机”——你需要测试它
你可以用这种方法生成超现实的数字,但大多数结果都是a/2^b形式的小数,整数相对较少。在第3天,只生成2个整数(-3和3)对6个小数,在第4天是2对14,在第n天是2对(2^n-2)
如果将math.random()
中的两个均匀随机数相加,将得到一个新的分布,该分布具有类似“三角形”的分布(从中心线性递减)。添加3或更多将得到一个以0为中心的更类似“钟形曲线”的分布:
math.random() + math.random() + math.random() - 1.5
除以一个随机数将得到一个真正的野生数:
A/(math.random()+1e-300)
这将返回介于A和(理论上)A*1e+300之间的结果,
虽然我的测试显示50%的时间结果在A和2*A之间
大约75%的时间在A和4*A之间
把它们放在一起,我们得到:
round(6*(math.random()+math.random()+math.random() - 1.5)/(math.random()+1e-300))
这使得70%以上的数据返回到-9到9之间,很少出现一些大的数据
请注意,此分布的平均值和总和将趋向于向一个较大的负数或正数发散,因为运行它的次数越多,分母中的一个较小的数字越有可能导致该数字“爆炸”为一个较大的数字,如147967或-194137
有关示例代码,请参见
您可以立即计算第n个出生的超现实数字
例如,第1000个超现实数字是:
转换为二进制:
1000年12月=1111101000箱
1变成正0变成负:
1111101000
+++++-+---
第一个“1”位为0值,下一组类似数字为+1(对于1)或-1(对于0),然后每个后续位的值为1/2、1/4、1/8等
11101000
++++++-+--
011小时
+0+1+1+1+1-1/2+1/4-1/8-1/16-1/32
=3+17/32
=113/32
=3.53125
此代表的二进制长度(以位为单位)
round(6*(math.random()+math.random()+math.random() - 1.5)/(math.random()+1e-300))
100010101001101s -> negative number (always start 10...)
111101010110010s -> positive number (always start 01...)