我需要创建一个方法,该方法返回一些随机分布的采样数,每次调用该方法时,返回的数字都大于以前返回的数字。
或者,换句话说,我需要一个用于随机值排序列表的迭代器。
不幸的是,列表太大,无法在内存中创建。我想出的第一个想法是将我的值空间划分为桶,其中每个桶包含某些范围[a,b)中的值。 说我的列表有N个元素。要创建一个存储桶,我会对我的分配进行N次采样,并将每个值放在[a,b]范围内。该桶外的值将被丢弃。
这样我每次迭代时都可以创建一个新的存储桶并保持低内存消耗。
然而,由于我不是统计专家,我有点害怕这会以某种方式搞砸我得到的数字。这是一种合适的方法吗?为每个桶使用相同的分布生成器(org.apache.commons.math3.distribution.RealDistribution的实例)是否很重要?
更新:我似乎在解释我所说的随机数字时做得不好。
我的数字形成随机分布的样本,例如正态分布,均值为m,方差为v,或均匀分布或指数分布。
我使用这些数字来模拟模拟中的某些行为。说我想在某些时候触发事件。我需要安排数十亿个事件,触发这些事件的时间必须形成一个随机分布的样本。
因此,如果我通过在我之前的数字中添加一个随机数来得到我的下一个数字,我确实得到了一系列随机数增长但数字不会形成我的分布样本。
答案 0 :(得分:3)
你可以说你的随机发生器有什么要求。
我需要创建一个方法,该方法返回一些随机分布的采样数,每次调用该方法时,返回的数字都大于以前返回的数字。
你可以做类似的事情。
private long previous = 0;
private final Random rand = new Random();
public long nextNumber() {
return previous += rand.nextInt(10) + 1;
}
详细信息取决于您对随机数进行建模的方式。
答案 1 :(得分:1)
如果列表太大而无法存储在内存中,则可以使用数据库并在数据库中读取/写入批量列表项。
这样,您一次只需要在内存中存储一个批处理。
答案 2 :(得分:1)
我首先创建一个变量并存储你的第一个随机数,然后生成另一个随机数,比较它们,如果它更大,将它保存在大型存储和ram中,重复下一个随机数将与内存中的单一值。
答案 3 :(得分:0)
您可以为先前生成的数字添加随机数。因此,您必须仅在内存中保留您之前在迭代步骤中生成的数字。
答案 4 :(得分:0)
SamplePartitioner
是一个类,它将一些分布的样本分成几个固定大小的分区,这些分区是nextPartition()
逐个返回的。
nextPartition()
在每次调用时创建整个样本,但仅存储最小的partitionSize
值,这些值大于最后一个分区的最大值。通过使用固定种子,nextPartition()
每次调用时都会创建完全相同的样本。
class SamplePartitioner(sampleSize: Long, partitionSize: Int, dist: RealDistribution) {
private val seed = Random.nextInt
private var remaining = sampleSize
private var lastMax = 0.0
def nextPartition(): SortedSet[Double] = remaining.min(partitionSize) match {
case 0 => SortedSet.empty[Double]
case targetSize =>
dist.reseedRandomGenerator(seed)
val partition = fill(sampleSize, SortedSet.empty, targetSize)
lastMax = partition.last
remaining -= partition.size
partition
}
private def fill(samples: Long, partition: SortedSet[Double], targetSize: Long): SortedSet[Double] =
samples match {
case 0 => partition
case n =>
val sample = dist.sample()
val tmp = if (sample > lastMax) partition + sample else partition
fill(n - 1, if (partition.size > targetSize) tmp.init else tmp, targetSize)
}
}