2011-12-16 14 views
6
私は0と3の間の乱数を生成したい

を得る確率を変更し、私は自分のコードに次き:は乱数

int random = rand() % 4; 

これは正常に動作しますが、私はそれが1を生成したいと思い、 2と3はほとんどの時間0はときどきしかありません。

これについてはどのような方法が最適ですか?この問題に対処するための一般的なアルゴリズムの名前は何ですか?

+0

これは乱数ではありません。これは確率分布です。これはランダムとは逆のものです(RNGについて言えば、予測可能性は恐ろしいものです)。 –

答えて

15

ここには1つの方法があります。 0,1,2,3に5%、20%、30%、45%の分布を持たせたいとします。
あなたはこのようにそれを行うことができます:それは浮動小数点で行う必要はありません。もちろん、

double val = (double)rand()/RAND_MAX; 

int random; 
if (val < 0.05)  // 5% 
    random = 0; 
else if (val < 0.25) // 5% + 20% 
    random = 1; 
else if (val < 0.55) // 5% + 20% + 30% 
    random = 2; 
else 
    random = 3; 

。もっと直感的なので、私はちょうどこのようにしました。正確に何をしたい

+0

それは価値があるのですが、これは私が確率を扱う必要があるときに私が実際に使う方法です。 –

0

あなたはこれを何回試しましたか?実際にはtrueの場合は0から3999までの範囲をa = rand()%4000で生成し、int = a/1000を使用すると、明らかに生成されていないゼロの重みが削除されます。

+1

私はあなたが、それが何であるかとは正反対に疑問を誤解していると思います。 OPは、 'rand()%4'が数字を均等に分配するが、0を望むことはあまり頻繁に起こらないと言っている。 – ruakh

+1

私は、OP *が過小生産ゼロを望んでいると思います。これは観測ではなく、要件です。 –

+0

ああ、どういうわけか、私はその文章で「私は欲しい」という言葉を逃した – smitec

0

もっと大きな値から1,2,3に値をマッピングするだけです。例:9と1,2,3 => 1、3,4,5 => 2,6,7,8 => 3、0を0にマッピングします。他の方法もありますが、ご質問の範囲内で作業しています

0

ジャストコード:

int myrand(void) 
{ 
    const int percentZero = 10; 
    if ((rand()%100) < percentZero) return 0; 
    return 1 + (rand() % 3); 
} 

あなたは時間ゼロの割合を変更することができますが、あなたが好きに返されます。

1

正確な比率は指定しませんでしたが、それぞれ1,2,3がそれぞれ32%、0が4%となるようにしたいとします。次に、あなたが書くことができます:

int random = rand() % 25; 
if(random > 0) 
    random = random % 3 + 1; 

(。。もちろん、あなたが異なる比率のためにそれを調整する必要があり、上記と思いますただ一つのアプローチであり、多くの同様のアプローチは、仕事ができる)

0

あなたが確率を見つける必要がありますあなたの場合に適した配布。あなたはこれだけは非常に簡単である0-3の数字の話をしているので、最初の結果が0である、またはあなたが重みを使用することができれば、あなたは再びrand()を呼び出すことができ、次のいずれか

int random = rand() % 16; 

if(random > 10) 
{ 
    random = 3; 
} 
else if(random > 5) 
{ 
    random = 2; 
} 
else if(random > 0) 
{ 
random = 1; 
} 

を、このことは特にないですエレガントですが、必要に応じてカスタムディストリビューションを作成する方法を示してくれることを願っています。

6

ランダムライブラリのdiscrete_distributionクラスを使用できます。

#include <iostream> 
#include <random> 
#include <ctime> 

int main() 
{ 
    std::discrete_distribution<> dist({ 1.0, 4.0, 4.0, 4.0 }); 
    std::mt19937 eng(std::time(0)); 
    for (int i=0; i<100; ++i) 
     std::cout << dist(eng); 
} 

デモ:あなたがC++ 11を使用することができない場合はhttp://ideone.com/z8bq4

、これらのクラスはまた、ブースト中に存在します。