我使用<stdlib.h> rand()
函数在范围[0 ... 9]内生成100个随机整数。我使用以下方法在相等分布上生成它们,
int random_numbers[100];
for(register int i = 0; i < 100; i++){
random_numbers[i] = rand() % 10;
}
这很好用。但是现在我希望获得100个数字,我希望这些数字的50%左右是5.我该怎么做?
扩展问题
我想得到100个号码。如果我想要这些数字的50%将在0~2之间怎么办?我的意思是这些数字的50%只包含数字0,1,2。怎么做?
我期待可以在10或100的边界之外应用的通用步骤。
答案 0 :(得分:2)
嗯,如何选择0
和17
之间的随机数,如果数字大于9
,请将其更改为5
?
对于0 - 17,你会得到像
这样的发行版0,1,2,3,4,5,6,7,8,9,5,5,5,5,5,5,5,5
代码:
int random_numbers[100];
for(register int i = 0; i < 100; i++){
random_numbers[i] = rand() % 18;
if (random_numbers[i] > 9) {
random_numbers[i] = 5;
}
}
您基本上添加了一组超出所需范围的数字,当翻译为5
时,会为您提供相同数量的5
和non-5
。
答案 1 :(得分:2)
为了让 这些数字的50%在[0, 2]
范围内,您可以将rand()
的整个范围分成两个相等的一半,然后使用相同的基于%
的技术将上半部分映射到[0, 2]
范围,将后半部分映射到[3, 9]
范围。
int random_numbers[100];
for(int i = 0; i < 100; i++)
{
int r = rand();
random_numbers[i] = r <= RAND_MAX / 2 ? r % 3 : r % 7 + 3;
}
要获得 这些数字中的50%为5
,类似的技术将起作用。只需将后半部分映射到[0, 9]
范围并排除5
int random_numbers[100];
for(int i = 0; i < 100; i++)
{
int r = rand();
if (r <= RAND_MAX / 2)
r = 5;
else if ((r %= 9) >= 5)
++r;
random_numbers[i] = r;
}
答案 2 :(得分:1)
我认为使用其他答案中提到的技术很容易解决50%的特定问题。让我们试着回答一般情况下的问题 -
我们假设您想要一个分布,您希望数字{A1, A2, .. An}
的百分比{P1, P2, .. Pn}
和Pi
的总和是100%
(并且所有百分比都是整数,如果不是可以调整)。
我们将创建一个100大小的数组,并用数字A1-An
填充它。
int distribution[100];
现在我们填写每个数字,它是百分比的次数。
int postion = 0;
for (int i = 0; i < n; i++) {
for( int j = 0; j < P[i]; j++) {
// Add a check here to make sure the sum hasn't crossed 100
distribution[position] = A[i];
position ++;
}
}
现在初始化完成一次,您可以将随机数绘制为 -
int number = distribution[rand() % 100];
如果您的百分比不是整数但是您希望精确度为0.1%
,则可以创建一个1000
而不是100
的数组。
答案 3 :(得分:1)
在这两种情况下,目标是从一组中选择50%,从另一组中选择50%。代码可以调用rand()
并使用一些位(一个)来选择组,剩余的位用于值选择。
如果所需的数字范围远小于RAND_MAX
,则首次尝试可以使用:
int rand_special_50percent(int n, int special) {
int r = rand();
int r_div_2 = r/2;
if (r%2) {
return special;
}
int y = r_div_2%(n-1); // 9 numbers left
if (y >= special) y++;
return y;
}
int rand_low_50percent(int n, int low_special) {
int r = rand();
int r_div_2 = r/2;
if (r%2) {
return r_div_2%(low_special+1);
}
return r_div_2%(n - low_special) + low_special + 1;
}
样品
int r5 = rand_special_50percent(10, 5);
int preferred_low_value_max = 2;
int r012 = rand_low_50percent(10, preferred_low_value_max);
高级:
如果n
高于RAND_MAX/2
,则需要额外调用rand()
。
使用rand()%n
时,除非(RAND_MAX+1u)%n == 0
(n
是RAND_MAX+1
的除数),否则会引入偏差。上面的代码不能弥补这一点。
答案 4 :(得分:1)
C ++ 11解决方案(不是最佳但很简单)
std::piecewise_constant_distribution
可以为每个间隔的给定间隔和权重生成随机实数(浮点数或双精度数)。
不是最佳的,因为 此解决方案正在生成double并将double转换为int 。同样 从[0,3] 100个样本中获得50个不保证,但保证约50个样本。
对于您的情况:2个时间间隔 - [0,3), [3,100)
及其权重[1,1]
等权重,约为[0,3)
的数字的50%和[3,100)
的约50%
#include <iostream>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::vector<double> intervals{0, 3, 3, 100};
std::vector<double> weights{ 1, 0, 1};
std::piecewise_constant_distribution<> d(intervals.begin(), intervals.end(), weights.begin());
std::map<int, int> hist;
for(int n=0; n<100; ++n) {
++hist[(int)d(gen)];
}
for(auto p : hist) {
std::cout << p.first << " : generated " << p.second << " times"<< '\n';
}
}
Output:
0 : generated 22 times
1 : generated 19 times
2 : generated 16 times
4 : generated 1 times
5 : generated 2 times
8 : generated 1 times
12 : generated 1 times
17 : generated 1 times
19 : generated 1 times
22 : generated 2 times
23 : generated 1 times
25 : generated 1 times
29 : generated 1 times
30 : generated 2 times
31 : generated 1 times
36 : generated 1 times
38 : generated 1 times
44 : generated 1 times
45 : generated 1 times
48 : generated 1 times
49 : generated 1 times
51 : generated 1 times
52 : generated 1 times
53 : generated 1 times
57 : generated 2 times
58 : generated 3 times
62 : generated 1 times
65 : generated 2 times
68 : generated 1 times
71 : generated 1 times
76 : generated 2 times
77 : generated 1 times
85 : generated 1 times
90 : generated 1 times
94 : generated 1 times
95 : generated 1 times
96 : generated 2 times