【问题标题】:Random occurrences随机事件
【发布时间】:2011-10-24 09:42:28
【问题描述】:

我不太确定该怎么做。

我需要生成 14,296 个具有不同概率水平的随机数。

例如,我需要一个包含数字 18、1 和 17 的数组。每个数字都有不同的出现概率。所以:

55% = 18
(7,862.8 次)

30% = 1
(4,288.8 次)

15% = 17
(2,144.4 次)

结果类似于 new Array () { 18, 18, 1, 17, 1, 18...}

【问题讨论】:

  • 澄清一下,输入是 1) 一组数字,每个数字都有一个相关的期望概率,以及 2) 期望的输出数组大小?
  • 输入正确输出是一个大小为 N 的数组,其中 N / a.probabilty 元素的值为 a
  • 这么多好答案,这次真不知道该选哪一个了!
  • 您需要真正的随机性还是“可预测的随机性”?使用您的示例进行真正的随机性,您最终可能会得到 1% 18、95% 17、4% 1。不确定这些类型的结果是否适合您。
  • @Tom Fobear 这里有一个非常彻底的讨论stackoverflow.com/questions/910215/… 使用洗牌袋kaioa.com/node/53 解决了随机生成器随机的问题。

标签: c# random probability


【解决方案1】:

如果你总是将值作为整数百分比,我会根据概率用值填充一个 100 元素数组,所以在这种情况下,你的数组将出现 55 次 18、30 次 1 和17 出现 15 次。然后您只需要从该数组中选择 14,296 个随机值。 (即在 [0, 100) 范围内选择一个整数并取该元素。)

对于表达概率的不同方式,当然有不同的方法。但是,如果给定整数百分比,这是一个容易理解的选项。 (另一种方法是将所有概率按总数缩放,即进入 [0, 1) 的范围,然后在该范围内随机取一个双精度值。)

【讨论】:

    【解决方案2】:

    将随机发生器的范围划分成比例的段,判断下一个随机数落入哪个段,从你的集合中选择对应的数。

    类似(简化):

    const int numbers[3] = { 1, 17, 18 };
    const int borders[2] = { 0.30*MAX_RANDOM, (0.30 + 0.15) *  MAX_RANDOM };
    
    int i = random.next(), num;
    
    if      (i < borders[0]) num = number[0];
    else if (i < borders[0]) num = number[1];
    else num = number[2];
    

    当然,如果数字多于三个,最好使用循环。

    注意:与 Jon Skeet 的解决方案不同,这个解决方案可以提供高达 1/(MAX_RANDOM+1) 的任何所需粒度(在 32 位机器上通常高达 2^32),而不是严格的 1%。

    【讨论】:

      【解决方案3】:

      这样的东西怎么样(未经测试):

      struct np
      {
          int n;
          int p;
      }
      

      创建一个List&lt;np&gt; 并将其与值/百分比对(例如n = 18, p = 55)。

      然后只需执行以下操作来选择一个数字:

      List<np> npl = new List<np>();
      // (fill the list here)
      
      
      
      int r = rnd.next(total_of_all_p_values); // get random number
      int res = 0; // result
      for(int i = 0; i < npl.Length(); r -= npl[i++].n)
      {
          if(r < npl[i].p) // remaining vlaue is smaller than current percentage
          {
              res = npl[i].n;
              break;
          }
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用 3 个数字中每个数字的适当数字填充 List&lt;T&gt;,然后填充 randomize the List

        【讨论】:

          【解决方案5】:
          Random r = new Random();
          
          // for each number to generate
          int nextNumber;
          double probability = r.NextDouble();
          if (probability < 55.0 / 100.0)
              nextNumber = 18;
          else if (probability < (55.0 + 30.0) / 100.0)
              nextNumber = 1;
          else
              nextNumber = 17;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-09-24
            • 2018-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-07
            • 2023-03-28
            • 1970-01-01
            相关资源
            最近更新 更多