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

リストが大きすぎてメモリに格納できない場合は、データベースを使用して、データベースとの間でリスト アイテムのバッチを読み書きできます。

このようにして、一度に 1 つのバッチをメモリに保存するだけで済みます。

于 2013-01-08T10:10:24.427 に答える
1

変数を作成して最初の乱数を保存することから始め、次に別の乱数を生成して比較し、それが大きい場合は大きなストレージとRAMの両方に保存し、次の乱数が単一の値と比較されるように繰り返しますメモリー。

于 2013-01-08T10:11:57.347 に答える
0

SamplePartitionerは、ある分布のサンプルを固定サイズのいくつかのパーティションに分割するクラスです。これらのパーティションは、 によって 1 つずつ返され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 に答える
0

以前に生成された数値に乱数を追加できます。したがって、前の反復ステップで生成した数値のみをメモリに保持する必要があります。

于 2013-01-08T10:09:47.210 に答える