2011-12-16 59 views
6

我想生成0和3之间的随机数的概率,在我的代码,我有以下几点:改变得到一个随机数

int random = rand() % 4; 

这工作得很好,但我想它产生1, 2和3大部分时间和0只偶尔。

什么是最好的方式去做这件事?解决这个问题的常用算法的名称是什么?

+0

这不是一个随机数字。这是一种概率分布,与随机分布相反(当您谈论RNG时,可预测性非常糟糕)。 – 2011-12-16 04:15:04

回答

15

这是一种方法。假设你想要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

你测试过多少个数字?如果它实际上是真的,则可以使用a = rand()%4000生成一个范围从0-> 3999,并使用int = a/1000这应该消除显然生成的零的权重。

+1

我认为你误解了问题的正确性与它的相反。 OP在说'rand()%4`均匀地分布数字,但是他希望零不太经常出现。 – ruakh 2011-12-16 04:17:39

+1

我认为OP *希望*产量不足零。这不是观察,而是要求。 – 2011-12-16 04:17:49

0

我只是将更多的值映射到更大的集合中。例如:9和映射1,2,3 => 1,3,4,5 => 2,6,7,8 => 3和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,这是很容易的,你既可以再次调用rand()如果第一个结果为0,或者你可以使用权:

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); 
} 

演示:http://ideone.com/z8bq4

如果您不能使用C++ 11,这些类也存在着提振。