【问题标题】:How can I generate N random values that sum to predetermined value?如何生成总和为预定值的 N 个随机值?
【发布时间】:2011-08-16 02:32:08
【问题描述】:

我需要你的帮助来解决一个小问题。我有四个标签,我想在它们上显示 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();
}   

问题是我让 alpha 有机会获得 biggest 值,而对于 delta 则获得 lowest 值。

有没有办法让他们都有相同的机会获得真正的random 值?

【问题讨论】:

  • 一个真实随机数?简而言之,没有。只有一个伪随机数。随机数生成器在时钟周期之外运行,并且通常会看到重复的序列。使用的种子取决于当前 DateTime.Now 的 .Tick 属性(如果我没记错的话)。 .Net 有很多不错的随机数生成器和 API。如果您觉得自己没有时间或不想自己动手,我建议您搜索它们。

标签: c# .net random generator


【解决方案1】:

如果您想要的数字代表互斥结果的概率,您可以将它们想象为多项分布。由于您需要一个随机概率向量,因此您应该从多项分布的共轭先验中对其进行采样:Dirichlet 分布。

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

【讨论】:

    【解决方案2】:

    你可以这样做:

    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。

    【讨论】:

      【解决方案3】:

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

      随机数生成器在时钟周期之外运行,并且通常会看到重复的序列。使用的种子取决于当前 DateTime.Now 的 .Tick 属性(如果我没记错的话)。 .Net 有很多不错的随机数生成器和 API。如果您觉得自己没有时间或不想自己动手,我建议您搜索它们。

      向上移动到 cmets,因为它看起来更合适。

      【讨论】:

      • ...标准 P-RNG 的问题在于,由于时钟的循环特性,它的执行几乎没有偏差。
      • @finnw:不,不是:“有没有办法让它们都有相同的机会获得真正的随机值。”
      • @finnw:最初,当我写下我的答案时,他的标题是:生成随机值
      • @IAbstract,我相当确定 OP 的意思是“所有四个变量都可以具有相同的分布”(是的)或“如果独立考虑,所有四个变量都可以均匀分布吗?” (不,但这不是因为 PRNG 的确定性。)
      • 您可以单击此答案上的小“删除”链接,以找回您从反对票中失去的代表。
      【解决方案4】:

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

      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];
      

      【讨论】:

      • +1 为什么这甚至被否决了?事实上,这是一个很好的解决方案,不必依赖除法/乘法。
      • 谢谢@Philip。人们通常会期望在研究生级别的概率和统计课程中学到的技巧能够与即兴解决方案相媲美,但我猜天真的选民更喜欢他们自己提出的天真的解决方案。
      • 我非常怀疑 alpha 和 delta 与 beta 和 gamma 具有相同的分布,这与 Ivan 不同。
      【解决方案5】:

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

      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 添加到某些变量中。)此外,您可以随机播放值。

      有趣的部分现在来了。如果我们改变“行”:

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

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

      • 分钟 = 0;最大值 = 100:原始;
      • 分钟 = 20; max = 80:避免小数字;
      • 分钟 = 33; max = 100:强制两个数字小于 32。

      【讨论】:

      • 即使 min=0, max=100,这也与 Ivan 的解决方案不同,因为如果 half
      【解决方案6】:

      如果将所有四个值都放在一个数组then shuffle them 中,然后根据它们的序号位置分配它们会怎样?这样,每个变量(gamma、theta 等)获得高数和低数的概率相等。

      【讨论】:

      • 这使所有四个值都具有相同的分布,但这是一个非常奇怪的分布。
      猜你喜欢
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2021-07-12
      • 1970-01-01
      相关资源
      最近更新 更多