C++ 在两个具有一定均值的数字之间获得一组随机数。
问题:在两个值之间获得一组具有一定平均值的随机数 假设我们得到n个随机数,其中的数字在1到100之间。我们的平均值是25 我的第一种方法是有两种模式,其中我们有高于平均值和低于平均值,其中第一个随机数是初始范围1和100。随后的每个数字都将检查总数。如果总和高于平均值,我们转到case overmean,然后得到一个介于1和25之间的随机数。如果总和低于平均值,我们将按低于平均值的大小写,然后得到一个介于26和100之间的随机数 我需要一些关于如何处理这个问题的想法,除了原油,得到一个随机数,把它加到总数中,然后得到平均值。如果它高于所讨论的平均值,我们得到一个低于平均值的随机数,依此类推。虽然它确实有效,但似乎不是最好的方法C++ 在两个具有一定均值的数字之间获得一组随机数。,c++,c,algorithm,random,random-sample,C++,C,Algorithm,Random,Random Sample,问题:在两个值之间获得一组具有一定平均值的随机数 假设我们得到n个随机数,其中的数字在1到100之间。我们的平均值是25 我的第一种方法是有两种模式,其中我们有高于平均值和低于平均值,其中第一个随机数是初始范围1和100。随后的每个数字都将检查总数。如果总和高于平均值,我们转到case overmean,然后得到一个介于1和25之间的随机数。如果总和低于平均值,我们将按低于平均值的大小写,然后得到一个介于26和100之间的随机数 我需要一些关于如何处理这个问题的想法,除了原油,得到一个随机数,把
我想我应该复习一下概率来接近这个随机数发生器 编辑:这将生成1到100范围内的数字,理论平均值为25.25。它通过使用范围为1到100的随机模量来实现这一点。请注意,要求的平均值为25,这并不完全是范围1..100的四分之一 OP想要一种根据平均值小于或大于25来改变下一个数字的方法,但这提供了一些可预测性——如果平均值大于25,那么你知道下一个“随机”数字将小于25 代码中的随机计算是非常简单的一行
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define RUNS 10000000
#define MAXN 100
int main() {
int n, i, sum = 0, min = MAXN, max = 0;
int freq[MAXN+1] = {0};
srand((unsigned)time(NULL));
for(i = 0; i < RUNS; i++) {
n = 1 + rand() % (1 + rand() % 100); // average modulus is (1 + MAX) / 2
if(max < n) {
max = n; // check that whole range is picked
}
if(min > n) {
min = n;
}
freq[n]++; // keep a tally
sum += n;
}
// show statistis
printf("Mean = %f, min = %d, max = %d\n", (double)sum / RUNS, min, max);
for(n = MAXN; n > 0; n--) {
printf("%3d ", n);
for(i = (freq[n] + 5000) / 10000; i > 0; i--) {
printf("|");
}
printf("\n");
}
return 0;
}
OP没有说明需要什么样的分布,例如,两条以25为轴心的直线,或者25的每边的分布相等。然而,这个解决方案很容易实现。实现这一点的方法有无数种。例如,生成3个介于1和100之间的随机数(
std::uniform\u int\u distribution
),并取其中的最小值(std::min(a,b,c)
)
显然,对于平均值75,您需要选择最多3个数字
这种方法的好处是每个结果都独立于以前的结果。这完全是随机的。你必须进入一些概率理论。判断随机序列的方法有很多。例如,如果你降低偏差,你会得到一个三角形的图形序列,它最终会被证明不是真正随机的。因此,除了获得随机生成器并丢弃您不喜欢的序列之外,实际上没有太多的选择。选择一些好的分布并使用它。说。使用
B(99,24/99)
,
因此采样值在0到99之间,参数p
等于24/99
所以,如果你有一个从B来的样本,那么你所需要的就是加上1
在1到100之间
二项式的平均值为p*n
,在这种情况下等于24。因为你要加1,你的平均值是25。C++11在
标准库
一些代码(未测试)
#包括
#包括
int main(){
std::默认随机引擎生成器;
标准:二项分布(99,双(24)/双(99));
对于(int i=0;i!=1000;++i){
整数=配电(发电机)+1;
std::cout假设一个公平的随机(a,b)
函数(这个问题不应该是关于哪个随机函数更好),然后简单地限制它的范围应该是一个好的开始,比如
const int desiredCount = 16;
const int deiredMean = 25;
int sumValues = random(a,b);
int count = 1;
while (count < desriredCount - 1) {
int mean = sumValue/count;
int nextValue = 0;
if (mean < desiredMean) // Too small, reduce probablity of smaller numbers
nextValue = random(a+(desiredMean-mean)/(desriredCount-count),b);
else //too large, reduce probability of larger numbers
nextValue = random(a,b-(mean-desiredMean)/(desriredCount-count));
sumValue += nextValue;
count += 1;
}
int lastValue = desiredMean*desriredCount - sumValue/count;
sumValue += lastValue;
count += 1;
const int desiredCount=16;
恒量平均值=25;
int sumValues=随机(a,b);
整数计数=1;
而(计数
注意:以上内容未经检验,我的想法是,调整上限和下限可能不够积极,不足以达到这一目的,但我希望我能让你继续
某些边界条件,例如,如果您只需要2个数字和0到100之间数字的平均值25,则初始随机数不能大于50,因为这使得无法选择第二个(最后一个)数字——因此,如果您希望algo在所有情况下都能给出准确的平均值,则需要进行更多的调整。让我们将范围分为左右两部分。使用与另一半的相对宽度相对应的频率部分的值
int Leruce_rand(int min, int mean, int max) {
int r = rand()%(max - min + 1);
if (r < mean) {
// find number in right half
return rand()%(max - mean + 1) + mean;
} else {
// find number in left half
return rand()%(mean - min) + min;
}
int-Leruce\u rand(int-min,int-mean,int-max){
int r=rand()%(最大值-最小值+1);
if(r
假设mean
是右半部分的一部分。此快速解决方案可能有小偏差
根据OP的值,大致上,左半部分的平均值为12.5,占75%,右半部分的平均值为62.5,占25%,占25%
这种方法不同于OP的方法,OP的方法是“每个后续的数字都会检查总和。如果总和高于平均值,则我们转到case overmean,然后得到一个介于1和25之间的随机数。”因为这绝对防止了一组高于或低于平均值的事件发生。对于RNG,生成的值不应偏向于先前生成值的历史记录。OP需要一组符合特定标准的数字
考虑生成一个
const int desiredCount = 16;
const int deiredMean = 25;
int sumValues = random(a,b);
int count = 1;
while (count < desriredCount - 1) {
int mean = sumValue/count;
int nextValue = 0;
if (mean < desiredMean) // Too small, reduce probablity of smaller numbers
nextValue = random(a+(desiredMean-mean)/(desriredCount-count),b);
else //too large, reduce probability of larger numbers
nextValue = random(a,b-(mean-desiredMean)/(desriredCount-count));
sumValue += nextValue;
count += 1;
}
int lastValue = desiredMean*desriredCount - sumValue/count;
sumValue += lastValue;
count += 1;
int Leruce_rand(int min, int mean, int max) {
int r = rand()%(max - min + 1);
if (r < mean) {
// find number in right half
return rand()%(max - mean + 1) + mean;
} else {
// find number in left half
return rand()%(mean - min) + min;
}
#include <stdio.h>
#include <stdlib.h>
void L_set(int *set, size_t n, int min, int mean, int max) {
assert(n > 0);
assert(min >= 0);
assert(mean >= min);
assert(max >= mean);
size_t i;
long long diff;
long long sum_target = n;
unsigned long long loop = 0;
sum_target *= mean;
int range = max - min + 1;
do {
loop++;
long long sum = 0;
for (i = 1; i < n; i++) {
set[i] = rand() % range + min;
sum += set[i];
}
diff = sum_target - sum; // What does the final number need to be?
} while (diff < min || diff > max);
set[0] = (int) diff;
printf("n:%zu min:%d mean:%2d max:%3d loop:%6llu {", n, min, mean, max, loop);
for (i = 0; i < n; i++) {
printf("%3d,", set[i]);
}
printf("}\n");
fflush(stdout);
}
int main(void) {
int set[1000];
L_set(set, 10, 1, 2, 4);
L_set(set, 16, 1, 50, 100);
L_set(set, 16, 1, 25, 100);
L_set(set, 16, 1, 20, 100);
return 0;
}
n:10 min:1 mean: 2 max: 4 loop: 1 { 4, 2, 4, 3, 2, 1, 1, 1, 1, 1,}
n:16 min:1 mean:50 max:100 loop: 2 { 45, 81, 24, 50, 93, 65, 70, 52, 28, 91, 25, 36, 21, 45, 11, 63,}
n:16 min:1 mean:25 max:100 loop: 3257 { 52, 1, 15, 70, 66, 30, 1, 4, 26, 1, 16, 4, 48, 42, 19, 5,}
n:16 min:1 mean:20 max:100 loop:192974 { 24, 10, 13, 3, 3, 53, 22, 12, 29, 1, 7, 6, 90, 11, 20, 16,}