【问题标题】:Random number generator with higher probabilities of giving low values?具有较高概率给出低值的随机数生成器?
【发布时间】:2011-05-24 03:49:28
【问题描述】:

如何生成伪随机数(最好在 Lua 中),其中生成器给出小数的概率更高?

在我的例子中,我想在游戏中给出一个随机分数,通常会获得较低的分数,但很少出现较高的分数。 我见过使用表格的加权随机数生成器,但它不符合我的计划。我只想指定最小值(0)和最大值(变量)并确保大多数数字保持在低位。

我确信这可以通过简单的数学运算来实现,但我不记得是哪一个了。喜欢过滤 math.random 的常规输出,不需要真正的随机生成器。

【问题讨论】:

    标签: lua random


    【解决方案1】:

    这可能不是您要找的,因为它不是平滑偏置的钟形曲线,但为什么不创建两个步骤呢?定义获得较低分数的概率,如果匹配,您的分数范围就是较低分数。否则,您的范围是从低范围的顶部到高范围的末端。

    最终结果是您通常会获得低分,但有时您会获得高分。我敢打赌它看起来不错,而且非常简单。

    你怎么看?

    【讨论】:

      【解决方案2】:

      我只是转换标准随机函数的值,如下所示:

      r1=math.random(0,255)
      r2=math.exp(math.random(0,255))
      

      你需要考虑你的界限,但你会有很多低值,很少有高值的东西。

      【讨论】:

        【解决方案3】:

        试试math.floor(minscore+(maxscore-minscore)*math.random()^2)。调整功率以适合您所需的分布。

        【讨论】:

          【解决方案4】:

          我发现Ihf's answer 非常有用,我为它创建了一个 C# 方法:

              private int GetRandomNumber(int max, int min, double probabilityPower = 2)
              {
                  var randomizer = new Random();
                  var randomDouble = randomizer.NextDouble();
          
                  var result = Math.Floor(min + (max + 1 - min) * (Math.Pow(randomDouble, probabilityPower)));
                  return (int) result;
              }
          

          如果probabilityPower 大于 1,则较低的值将比较高的值更常见。 如果它在 0 到 1 之间,则较高的值将比较低的值更常见。 如果为 1,则结果为一般随机性。

          示例(所有迭代次数为 100 万次,最小值 = 1,最大值 = 20):


          probabilityPower = 1.5

          1: 135534 (13.5534%)
          2: 76829 (7.6829%)
          3: 68999 (6.8999%)
          4: 60909 (6.0909%)
          5: 54595 (5.4595%)
          6: 53555 (5.3555%)
          7: 48529 (4.8529%)
          8: 44688 (4.4688%)
          9: 43969 (4.3969%)
          10: 44314 (4.4314%)
          11: 40123 (4.0123%)
          12: 39920 (3.992%)
          13: 40466 (4.0466%)
          14: 35821 (3.5821%)
          15: 37862 (3.7862%)
          16: 35222 (3.5222%)
          17: 35902 (3.5902%)
          18: 35202 (3.5202%)
          19: 33961 (3.3961%)
          20: 33600 (3.36%)
          

          probabilityPower = 4

          1: 471570 (47.157%)
          2: 90114 (9.0114%)
          3: 60333 (6.0333%)
          4: 46574 (4.6574%)
          5: 38905 (3.8905%)
          6: 32379 (3.2379%)
          7: 28309 (2.8309%)
          8: 27906 (2.7906%)
          9: 22389 (2.2389%)
          10: 21524 (2.1524%)
          11: 19444 (1.9444%)
          12: 19688 (1.9688%)
          13: 18398 (1.8398%)
          14: 16870 (1.687%)
          15: 15517 (1.5517%)
          16: 15871 (1.5871%)
          17: 14550 (1.455%)
          18: 14635 (1.4635%)
          19: 13399 (1.3399%)
          20: 11625 (1.1625%)
          

          probabilityPower = 1

          1: 51534 (5.1534%)
          2: 49239 (4.9239%)
          3: 50955 (5.0955%)
          4: 47992 (4.7992%)
          5: 48971 (4.8971%)
          6: 50456 (5.0456%)
          7: 49282 (4.9282%)
          8: 51344 (5.1344%)
          9: 50841 (5.0841%)
          10: 48548 (4.8548%)
          11: 49294 (4.9294%)
          12: 51795 (5.1795%)
          13: 50583 (5.0583%)
          14: 51020 (5.102%)
          15: 51060 (5.106%)
          16: 48632 (4.8632%)
          17: 48568 (4.8568%)
          18: 50039 (5.0039%)
          19: 49863 (4.9863%)
          20: 49984 (4.9984%)
          

          probabilityPower = 0.5

          1: 3899 (0.3899%)
          2: 5818 (0.5818%)
          3: 12808 (1.2808%)
          4: 17880 (1.788%)
          5: 23109 (2.3109%)
          6: 26469 (2.6469%)
          7: 33435 (3.3435%)
          8: 35243 (3.5243%)
          9: 42276 (4.2276%)
          10: 47235 (4.7235%)
          11: 52907 (5.2907%)
          12: 58107 (5.8107%)
          13: 63719 (6.3719%)
          14: 66266 (6.6266%)
          15: 72708 (7.2708%)
          16: 79257 (7.9257%)
          17: 81830 (8.183%)
          18: 87243 (8.7243%)
          19: 90958 (9.0958%)
          20: 98833 (9.8833%)
          

          probabilityPower = 0.4

          1: 917 (0.0917%)
          2: 3917 (0.3917%)
          3: 3726 (0.3726%)
          4: 10679 (1.0679%)
          5: 13092 (1.3092%)
          6: 17306 (1.7306%)
          7: 22838 (2.2838%)
          8: 29221 (2.9221%)
          9: 35832 (3.5832%)
          10: 38422 (3.8422%)
          11: 47800 (4.78%)
          12: 53431 (5.3431%)
          13: 63791 (6.3791%)
          14: 69460 (6.946%)
          15: 75313 (7.5313%)
          16: 86536 (8.6536%)
          17: 95082 (9.5082%)
          18: 103440 (10.344%)
          19: 110203 (11.0203%)
          20: 118994 (11.8994%)
          

          【讨论】:

            【解决方案5】:
            function weighted_random (weights)
                local summ = 0
                for i, weight in pairs (weights) do
                    summ = summ + weight
                end
                local value = math.random (summ)
                summ = 0
                for i, weight in pairs (weights) do
                    summ = summ + weight
                    if value <= summ then
                        return i, weight
                    end
                end
            end
            

            如何调用:

            local elements = {"a", "b", "c", "d"} -- elements
            local weights = {40, 24, 22, 14} -- weights of elements
            local n = weighted_random (weights) -- returns 1, 2, 3 or 4
            local element = elements[n] -- returns "a", "b", "c" or "d" 
            -- with chances: 40/100, 24/100, 22/100, 14/100, as in weights
            

            【讨论】:

              猜你喜欢
              • 2021-06-30
              • 2021-08-27
              • 2012-12-04
              • 2015-05-18
              • 2012-02-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多