0

私は現在プロジェクトを行っており、コードの再利用のために、アイテムの確率的な受け入れ/拒否を実行できるライブラリを探しに行きました:

つまり、3 人 (a, bc) がいて、それぞれがアイテムを取得する確率 P{i} を持っています。ここで、p{a} は a の確率を示します。これらの確率は実行時に計算され、ハードコードすることはできません。

私がやりたかったのは、(アイテムに対して) 乱数を 1 つ生成し、そのアイテムを手に入れる確率に基づいて誰がそのアイテムを手に入れるかを計算することです。ここで概説されているエイリアス メソッド ( http://books.google.com/books?pg=PA133&dq=alias+method+walker&ei=D4ORR8ncFYuWtgOslpVE&sig=TjEThBUa4odbGJmjyF4daF1AKF4&id=ERSSDBDcYOIC&output=html ) で方法を説明しましたが、既製の方法があるかどうかを確認したかったのです。実装なので、それを書く必要はありません。

4

3 に答える 3

1

Ruby の実装は次のとおりです: https://github.com/cantino/walker_method

于 2013-03-05T07:19:44.210 に答える
1

このようなことはありますか?すべての p{i} を配列に入れると、関数はアイテムを取得した人にインデックスを返します。O(n) で実行します。

public int selectPerson(float[] probabilies, Random r) {
    float t = r.nextFloat();
    float p = 0.0f;

    for (int i = 0; i < probabilies.length; i++) {
        p += probabilies[i];
        if (t < p) {
            return i;
        }
    }

    // We should not end up here if probabilities are normalized properly (sum up to one)
    return probabilies.length - 1;      
}

編集:私はこれを実際にテストしていません。私の要点は、あなたが説明した機能はそれほど複雑ではないということでした (私があなたの意図を正しく理解していれば)、これを解決するためにライブラリをダウンロードする必要はありません。

于 2008-09-24T13:30:47.657 に答える
0

私は上記の方法をテストしたばかりです-それは完璧ではありませんが、私の目的のためには、それで十分なはずです。(Groovyでコード化し、単体テストに貼り付けます...)

    void test() {
        for (int i = 0; i < 10; i++) {
            once()
        }
    }
    private def once() {
        def double[] probs = [1 / 11, 2 / 11, 3 / 11, 1 / 11, 2 / 11, 2 / 11]
        def int[] whoCounts = new int[probs.length]
        def Random r = new Random()
        def int who
        int TIMES = 1000000
        for (int i = 0; i < TIMES; i++) {
            who = selectPerson(probs, r.nextDouble())
            whoCounts[who]++
        }
        for (int j = 0; j < probs.length; j++) {
            System.out.printf(" %10f ", (probs[j] - (whoCounts[j] / TIMES)))
        }
        println ""
    }
    public int selectPerson(double[] probabilies, double r) {
        double t = r
        double p = 0.0f;
        for (int i = 0; i < probabilies.length; i++) {
            p += probabilies[i];
            if (t < p) {
                return i;
            }
        }
        return probabilies.length - 1;
    }

outputs: the difference betweenn the probability, and the actual count/total 
obtained over ten 1,000,000 runs:
  -0.000009    0.000027    0.000149   -0.000125    0.000371   -0.000414 
  -0.000212   -0.000346   -0.000396    0.000013    0.000808    0.000132 
   0.000326    0.000231   -0.000113    0.000040   -0.000071   -0.000414 
   0.000236    0.000390   -0.000733   -0.000368    0.000086    0.000388 
  -0.000202   -0.000473   -0.000250    0.000101   -0.000140    0.000963 
   0.000076    0.000487   -0.000106   -0.000044    0.000095   -0.000509 
   0.000295    0.000117   -0.000545   -0.000112   -0.000062    0.000306 
  -0.000584    0.000651    0.000191    0.000280   -0.000358   -0.000181 
  -0.000334   -0.000043    0.000484   -0.000156    0.000420   -0.000372
于 2008-09-25T13:10:42.407 に答える