2

我需要创建一个方法,该方法返回一个随机分布的采样数,每次调用该方法时,返回的数字都大于任何先前返回的数字。

或者,换句话说,我需要一个用于随机值排序列表的迭代器。

不幸的是,该列表太大而无法在整个内存中创建。我想出的第一个想法是将我的值空间划分为桶,其中每个桶包含某个范围内的值 [a, b)。假设我的列表有 N 个元素。要创建一个桶,我将对我的分布进行 N 次采样,并将 [a, b) 范围内的每个值放入桶中。该桶之外的值将被丢弃。

这样我可以在每次迭代最后一个时创建一个新的存储桶并保持低内存消耗。

然而,由于我不是统计学专家,我有点担心这会以某种方式搞砸我得到的数字。这是一个合适的方法吗?为每个存储桶使用相同的精确分布生成器(org.apache.commons.math3.distribution.RealDistribution 的一个实例)是否重要?

更新:似乎我在解释我在说什么类型的随机数方面做得不好。

我的数字形成随机分布的样本,例如平均值为 m 方差为 v 的正态分布,或者均匀分布或指数分布。

我使用这些数字来模拟模拟中的某些行为。假设我想在某些时候触发事件。我需要安排数十亿个事件,并且这些事件被触发的时间必须形成一个随机分布的样本。

因此,如果我通过将随机数添加到我以前的数字来导出我的下一个数字,我确实会得到一系列不断增长的随机数,但这些数字不会形成我的分布样本。

4

5 回答 5

3

你可以说你的随机发生器有什么要求。

我需要创建一个方法,该方法返回从某个随机分布中采样的数字,每次调用该方法时,返回的数字都大于任何先前返回的数字。

你可以做类似的事情。

private long previous = 0;
private final Random rand = new Random();

public long nextNumber() {
  return previous += rand.nextInt(10) + 1;
}

详细信息取决于您希望如何建模随机数。

于 2013-01-08T10:10:43.053 回答
1

如果列表太大而无法存储在内存中,您可以使用数据库并从数据库中读取/写入批量列表项。

这样,您只需要在任何时候将一批存储在内存中。

于 2013-01-08T10:10:24.427 回答
1

我将首先创建一个变量并存储您的第一个随机数,然后生成另一个随机数,比较它们,如果它更大,将其保存在大型存储和内存中,重复下一个随机数将与单个值进行比较记忆。

于 2013-01-08T10:11:57.347 回答
0

您可以将随机数添加到先前生成的数字中。因此,您必须仅将您在之前的迭代步骤中生成的数字保留在内存中。

于 2013-01-08T10:09:47.210 回答
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)
        }
}
于 2013-01-08T20:02:00.397 回答