如何解决给定概率生成随机数,概率越高结果越高
public int generatePeople(float luck,int min,int max) {
SecureRandom sr = new SecureRandom();
int people = 0;
// generate random people
return people;
}
我想在最小和最大之间生成一定数量的人,但人数会根据运气的变化而增加或减少,这应该类似于高斯,但我不知道如何在 Java 上做到这一点.
根据运气的值,区间的中心会有所不同,例如有 luck = 0.5f
更有可能在 (min + max)/2
(区间的中心)附近有值,而有 { {1}} 或 luck = 0.25f
将移动左侧 luck = 0.75f
或右侧 (min + max)/4
的值的中心,这意味着它更有可能具有来自左侧或右侧。
解决方法
我们可以用
生成一个从最小值到最大值的随机整数int randomInt = sr.nextGaussian() * (max - min) + min;
然后为了添加运气的影响,我们可以添加移位值。 考虑到运气是一个从 0 到 1 的浮点数,如果运气是 0.5,它必须没有影响,我们可以用这样的方法来实现:
int people = randomInt + (luck - 0.5f) * (sr.nextGaussian() * (max - min) + min);
然而,通过添加一些东西,我们可以超过最小值或最大值。为了避免这种情况,我们可以添加一个超过检查并在超过的情况下分配最小值或最大值:
people = Math.min(people,max);
people = Math.max(people,min);
,
假设 min,max
范围包含在内,则有 span = max-min+1
个可能的值。一种方法是定义以 luck * span
为中心的高斯概率密度函数 (PDF),例如 sigma
为 span/2
- 您可以改变它以改变围绕中心分布的紧密性。
然后您将使用 PDF 计算 span
范围内每个可能值的“权重” - 分布中心附近的值将获得更高的权重 - 并使用标准 {{3 }} 用于选择一个范围内的随机值,其中每个值都有一个关联的权重。
这里有一些 Java 代码来说明。
static int generatePeople(double luck,int min,int max)
{
int span = max - min + 1;
double mean = luck * span;
double sigma = span / 2;
double[] weights = new double[span];
double totWeight = 0;
for(int i=0; i<span; i++)
{
weights[i] = pdf(mean,sigma,i+0.5);
totWeight += weights[i];
}
double rnd = Math.random()*totWeight;
for(int i=0; i<span; i++)
{
if(rnd < weights[i]) return min+i;
rnd -= weights[i];
}
return max;
}
static double pdf(double mean,double sigma,double x)
{
double e = (mean - x) / sigma;
return Math.exp(-(e*e)/2)/(sigma*Math.sqrt(2*Math.PI));
}
我们可以通过生成大量值并检查给定“运气”值的 min
和 max
之间的分布来说明这种方法的行为。
static void test(double luck,int max)
{
int[] score = new int[max-min+1];
for(int i=0; i<1000*score.length; i++)
score[generatePeople(luck,min,max)-min]++;
for(int i=0; i<score.length; i++)
{
System.out.println(min+i + " : " + score[i]);
}
}
输出:
test(0.5,9);
给出:
0 : 786
1 : 878
2 : 1059
3 : 1110
4 : 1152
5 : 1162
6 : 1106
7 : 1020
8 : 962
9 : 765
虽然
test(0.25,9);
给出:
0 : 1195
1 : 1236
2 : 1285
3 : 1284
4 : 1146
5 : 1078
6 : 904
7 : 771
8 : 610
9 : 491
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。