从范围 (0:10^12) 生成整数随机数
Posted
技术标签:
【中文标题】从范围 (0:10^12) 生成整数随机数【英文标题】:Generate integer random numbers from range (0:10^12) 【发布时间】:2013-11-19 01:58:04 【问题描述】:我想生成 0 到 10^12 之间的 10000 个整数随机数。 通常,代码如下所示:
x <- sample(0:1000000000000,10000,replace=T)
但我收到以下错误消息:
Error in 0:1000000000000 : result would be too long a vector
有没有一种内存效率更高的方法,不必将 10^12 个整数放入一个向量中即可获得大小为 10000 的样本? 如果没有,有没有办法增加向量的最大大小?我正在开发具有 12GB 可用 RAM 的 64 位操作系统。
【问题讨论】:
它们需要是唯一的吗? 您是否估计过包含 10^12 个元素的向量的内存需求? 12 GB 是不够的。 为什么要这么大的范围?本质上,您要求的是具有 12 位精度的均匀随机样本,我无法理解对这种精细细节的需求。 【参考方案1】:真正的问题在于您无法将0:10^12
的序列存储到内存中。只需将 0 和 10^12 定义为均匀分布的边界,您就可以得到您想要的:
runif(10000, 0, 10^12)
[1] 136086417828 280099797063 747063538991 250189170474 589044594904
[6] 65385828028 361086657969 186271687970 338900779840 649082854623 ........
这将从均匀分布中提取(有替换,尽管我怀疑这很重要)。
但是,你看不到的是这些实际上是浮点数。
您可以使用ceiling
将它们四舍五入:
samp = runif(1, 0, 10^12)
samp
[1] 19199806033
samp == 19199806033
[1] FALSE
ceiling(samp) == 19199806033
[1] TRUE
所以完整的代码是:
ceiling(runif(10000, 0, 10^12))
进一步吹毛求疵:
请注意,这在技术上不允许 0 存在(因为 0.0001 将被四舍五入),所以你可以从
ceiling(runif(10000, -1, 10^12))
正如Carl Witthoft 提到的,不适合整数大小的数字显然不是整数,因此您不能指望这些数字是整数。与没有小数的相同浮点数相比,您仍然可以指望它们评估为 TRUE
。
【讨论】:
除了那些不是整数,因为2^31 < 10^12
。它们仍然是浮点数,如果你不小心,你很可能会遇到舍入错误。
@CarlWitthoft 这不是用ceiling
解决的吗?
is.integer(ceiling(10^11)) [1] FALSE
。就计算机而言,没有小数部分的float
不是integer
。
我发现is.integer(ceiling(runif(1, -1, 10^12)))
评估为FALSE
确实令人惊叹。我想这对 OP 来说并不重要,但这肯定是一个问题。 as.integer
介绍NA
。
您仍然可以使用高达 2^53 的双精度数来精确表示整数值,这仅略低于 10^16。【参考方案2】:
我不明白你为什么不能这样做......
sample(10^12,10,replace=TRUE)
#[1] 827013669653 233988208530 653034892160 564841068001 801391072663 683607493313
#[7] 254556497302 510154570389 51922126428 537709431414
如果
x
具有length 1
,是numeric
(在is.numeric
的意义上)和x >= 1
,则通过样本采样从1:x
进行。
注意这并不意味着sample
必须生成向量1:x
!! @James 指出,对于0:x
的采样,您需要调整为sample(10^12+1,10,replace=TRUE)-1
【讨论】:
非常正确......首先要拼凑一个答案,然后再思考。 虽然现在不包括 0。sample(10^12+1,10,replace=TRUE)-1
真的吗?比使用ceiling
?
在可能性向量中是否包含零完全没有关系,因为即使它只有10^(-12),选择它的概率!【参考方案3】:
floor(runif(10000,min=0,max=(10^12)))
【讨论】:
10^12 永远不会返回【参考方案4】:as.integer(runif(10000, min = 0, max = (1 + 10^12)))
仅供参考:as.integer
执行截断,而不是舍入。
为了测试它是否有效,您可以尝试生成较小区间(即从 0 到 6)的数字并可视化结果的直方图以查看结果是否为均匀分布,即
test <- as.integer(runif(10000, min = 0, max = (6 + 1)))
hist(test)
【讨论】:
我在寻找类似的想法...我使用了m <- as.integer(runif(10000, min = 0, max = (1 + 10^12)))
但发现NAs introduced by coercion to integer range
因此谨慎使用。 m <- ceiling(runif(10000, -1, 10^12))
没有产生 NA。【参考方案5】:
包extraDistr
提供了一系列额外的概率分布可供抽样,包括离散均匀分布。
使用函数rdunif
的随机抽样与R 中包含的其他stats
随机抽样函数(如runif
)一样工作,并且避免像其他解决方案那样需要舍入:
> library("extraDistr")
> rdunif(n = 10000, min = 0, max = 10^12)
[1] 699559531175 881392957410 315869810758 941600866616
[5] 906084092567 681591022527 514061764115 122652820777
[9] 583204373950 517842726316 741211620393 422150962055 ...
【讨论】:
以上是关于从范围 (0:10^12) 生成整数随机数的主要内容,如果未能解决你的问题,请参考以下文章