我想生成0到3之间的随机数,我的代码中有以下内容:
int random = rand() % 4;
这样可以正常工作,但我希望它能在大部分时间生成1,2和3,偶尔生成0。
最好的方法是什么?解决这个问题的常用算法的名称是什么?
答案 0 :(得分: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;
当然不必使用浮点数。我这样做是因为它更直观。
答案 1 :(得分:7)
您可以使用随机库中的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,这些类也存在于boost中。
答案 2 :(得分:1)
你没有给出确切的比例,但是假设你想要1,2和3分别出现32%的时间,而0则出现另外4%。然后你可以写:
int random = rand() % 25;
if(random > 0)
random = random % 3 + 1;
(显然你需要根据不同的比例调整它。以上只是一种方法;许多类似的方法都可以。)
答案 3 :(得分:0)
你测试了多少个数字?如果它实际上是真的,你可以使用a = rand()%4000
生成一个范围从0-> 3999开始,并使用int = a/1000
这将删除明显产生的零的权重。
答案 4 :(得分:0)
我只是从更大的集合中将更多的值映射到1,2,3。例如:9和地图1,2,3 =&gt; 1,3,4,5 =&gt; 2,6,7,8 =&gt; 3和0为零。还有其他方法,但我正在你的问题中工作
答案 5 :(得分:0)
只需准确编码您想要的内容:
int myrand(void)
{
const int percentZero = 10;
if ((rand()%100) < percentZero) return 0;
return 1 + (rand() % 3);
}
您可以将零返回的时间百分比更改为您想要的任何值。
答案 6 :(得分: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;
}
这不是特别优雅,但希望它能告诉您如何创建自定义发行版以满足您的需求。