我如何生成N个随机值它们之和等于预定值

本文关键字:于预定 何生成 随机 | 更新日期: 2023-09-27 17:54:11

我有个小问题需要你的帮助。我有四个标签,我想在它们上面显示0到100之间的随机值,它们的和必须是100。

这是我的代码:

private void randomly_Click(object sender, EventArgs e)
{
    double alpha = 0, beta = 0, gamma = 0, delta = 0;
    double temp;
    int tempDouble;
    Random rnd = new Random();
    alpha = rnd.Next(0, 100);
    temp = 100 - alpha;
    tempDouble = (int)temp;
    beta = rnd.Next(0, tempDouble);
    temp = 100 - (alpha + beta);
    tempDouble = (int)temp;
    gamma = rnd.Next(0, tempDouble);
    temp = 100 - (alpha + beta + gamma);
    tempDouble = (int)temp;
    delta = rnd.Next(0, tempDouble);
    temp = alpha + beta + delta + gamma;
    temp = 100 - temp;
    temp = temp / 4;
    alpha = alpha + temp;
    beta = beta + temp;
    gamma = gamma + temp;
    delta = delta + temp;
    cInsertion.Text = alpha.ToString();
    cMoyens.Text = beta.ToString();
    cInternational.Text = gamma.ToString();
    cRecherche.Text = delta.ToString();
}   

问题是我给了α一个机会得到biggest的值,给了δ一个机会得到lowest的值。

是否有办法让他们都有相同的机会有一个真正的random值?

我如何生成N个随机值它们之和等于预定值

你可以这样做:

double alpha = 0, beta = 0, gamma = 0, delta = 0, k = 0;
Random rnd = new Random();
alpha = rnd.Next(0, 100);
beta = rnd.Next(0, 100);
gamma = rnd.Next(0, 100);
delta = rnd.Next(0, 100);
k = (alpha + beta + gamma + delta) / 100;
alpha /= k;
beta /= k;
gamma /= k;
delta /= k;
cInsertion.Text = alpha.ToString();
cMoyens.Text = beta.ToString();
cInternational.Text = gamma.ToString();
cRecherche.Text = delta.ToString();

这样你就说,让我们为所有4个变量取一个随机值,然后我们将它们按因子k缩放,使它们的总和为100。

如果您将所有四个值粘贴到一个数组中,然后对它们进行洗牌,然后根据它们的序数位置分配它们会怎么样?这样,每个变量(gamma, theta等)获得高值和低值的概率是相等的。

这是一个非常有趣的问题。我喜欢@ ivan_feriic的解决方案,我认为它很完美,但我有另一个想法:

int total = 100;
Random rand = new Random();
int half = rand.next(0,total);   // the line
a = rand.Next(0,half);
b = max - a;
c = rand.Next(0,half);
d = max - c;

(未测试,也许+/-1必须添加到某些变量。)此外,还可以对值进行洗牌。

现在有趣的部分来了。如果我们改变"the line":

min = <some_value>
max = <another_value>;
int half = rand.next(min,max);

…然后我们可以微调结果:

  • min = 0;
  • min = 20;max = 80:避免小数字;
  • min = 33;max = 100:强制两个数字小于32。

不是随机生成单个数字,而是生成部分和,然后计算部分:

double alpha, beta, gama, delta = 0;
var rnd = new System.Random();
var cuts = new List<double>();
cuts.Add(Math.Floor(rnd.Next(0, 101)));
cuts.Add(Math.Floor(rnd.Next(0, 101)));
cuts.Add(Math.Floor(rnd.Next(0, 101)));
cuts.Sort();
alpha = cuts[0];
beta = cuts[1] - cuts[0];
gamma = cuts[2] - cuts[1];
delta = 100 - cuts[2];

如果你想要的数字表示互斥结果的概率,你可以把它们想象成一个多项分布。因为你想要一个随机概率向量,你应该从多项分布的共轭先验中采样:狄利克雷分布。

在代码中,您可以按照Ivan的建议,除了alpha、beta、gamma和delta都应该分别从具有形状参数alpha_shape、beta_shape、gamma_shape和delta_shape的gamma分布中绘制。(假设Gamma分布的另一个参数为1。)这些形状参数控制预期的相对比例。

A 实数随机数?简而言之,没有。只是一个伪随机数。

随机数生成器在时钟周期外运行,通常会看到重复的序列。使用的种子取决于当前DateTime的. tick属性。现在(如果我没记错的话)。有很多不错的随机数生成器和。net api。如果你觉得你没有时间或者不想自己动手制作,我建议你去搜索一下。

移到注释中,因为看起来更合适。