有没有一种优雅的方法来创建一个给定浮点数列表中不存在的数字?如果这个数字不接近数组中的现有值,那就太好了。
例如,在列表中[-1.5, 1e+38, -1e38, 1e-12]
,最好选择一个20
与现有数字“远”的数字,而0.0
不是不在列表中但非常接近的数字1e-12
。
我能想出的唯一算法是创建一个随机数并测试它是否不在数组中。如果是这样,请重新生成。有更好的确定性方法吗?
这是一种选择不在列表中的随机数的方法,其中概率越高,离现有点越远。
创建一个概率分布函数f,如下所示:
f(x) = <离x最近的点的绝对距离>
这样的函数给出的概率越高,离给定点越远。(注意,它应该被归一化,使函数下方的面积为 1。)
创建f的原始函数F(即f下方到给定点的累积面积)。
生成一个介于 0 和 1 之间的均匀随机数x(这很容易!:)
通过将F的倒数应用于该值来获得最终结果:F -1 (x)。
下图描述了以 1.5、2.2 和 2.9 作为现有数字的情况:
这是它为什么起作用的直觉:
您的概率越高(蓝线越高)红线越陡。
红线越陡峭, x在该点击中红线的可能性就越大。
例如:在给定的点上,蓝线是 0,因此红线是水平的。如果红线是水平的,则x命中该点的概率为零。
(如果你想要完整的双打,你可以将 min / max 分别设置为 -Double.MAX_VALUE 和 Double.MAX_VALUE。)
如果您有约束,新值必须介于两者之间,[min, max]
那么您可以对值进行排序并插入具有最大绝对差的两个相邻值的平均值。
在您的示例案例[-1e38, -1.5, 1e-12, 1e+38]
中是有序列表。在计算绝对差异时,您会找到这些值的最大差异,(1e-12, 1e+38)
因此您可以计算出新的值((n[i+1] - n[i]) / 2) + n[i]
(简单的平均值计算)。
更新:
此外,您还可以检查FLOAT_MAX
orFLOAT_MIN
值是否会提供好的候选人。只需检查它们的距离min
,max
如果结果值大于两个相邻值的最大差值,则选择它们。
如果没有上限,只需将所有数字的绝对值相加,或者将它们全部相减。
另一种可能的解决方案是获取列表中的最小数字和最大数字,并选择超出其范围的内容(可能是最大数字的两倍)。
或者可能最好的方法是计算平均值,最小和最大的数字,只要标准偏差。然后,有了所有这些数据,您就知道数字的结构,并可以做出相应的选择(所有都围绕给定的负值聚集?选择一个正值。所有小数字?选择一个大数字。等等)
类似的东西
number := 1
multiplier := random(1000)+1
if avg>0
number:= -number
if min < 1 and max > 1
multiplier:= 1 / (random(1000)+1)
if stdDev > 1000
number := avg+random(500)-250
multiplier:= multiplier / (random(1000)+1)
(只是我头脑中的一个例子)
或者另一种可能性是将所有数字异或在一起。应该会产生不错的效果。