【问题标题】:How to do Lua math random exception如何做 Lua 数学随机异常
【发布时间】:2015-04-09 22:41:36
【问题描述】:

我需要一些关于 Lua 代码的帮助。这个想法是得到一个随机数0-18,但它不能是数字816。我该怎么做?

self.currentSkyTexture = math.random(0,18)

-- 不是816... 怎么办?

【问题讨论】:

    标签: random lua except


    【解决方案1】:

    制作答案表

    local rans = {0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,18}
    

    从表格中选择

    function myRandom() return rans[math.random(#rans)] end
    

    这会以均匀概率从表中选择一个条目,并为每个条目调用一次math.random

    【讨论】:

    • 列表中的双重15 是故意的还是只是拼写错误?
    • @greatwolf,打错了
    【解决方案2】:

    只需检查它是 8 还是 16 并重新运行随机,只要它是其中之一。

    【讨论】:

      【解决方案3】:

      由于 19 个可能的随机数中只有 2 个异常,所以蛮力法不会造成性能问题。

      function myRandom()
          local ret
          repeat
              ret = math.random(0,18)
          until ret ~= 8 and ret ~= 16
          return ret
      end
      
      self.currentSkyTexture = myRandom()
      

      【讨论】:

      • 如果这是@WerewolF 经常做的那种随机,这是一个更优雅、更干燥的解决方案。
      【解决方案4】:

      在最简单的情况下,您可以通过直接检查来替换排除项:

      function skipRandom()
          local ret = math.random(0,16)
          if ret == 8 then 
              ret = 17 
          elseif ret == 16 then 
              ret = 18 
          end
          return ret
      end
      
      self.currentSkyTexture = skipRandom()
      

      【讨论】:

      • 是什么让您认为它比查表运行得更快?您是否对替代方案进行了基准测试?
      • 不,但你让我对我的假设感到好奇。在 lua-5.1 中,我的速度快了 5%。在 5.2 中,你的速度快 5%,在 luajit 2.0.3 中,你的速度比我的快 8%。在所有情况下,对 random 的重复调用都比失败者慢 10-15%。
      • 我在一个微型(Atom 处理器)Debian Wheezy Lua 5.2.1 上运行了一个微基准测试,这两种方法相当相似;对于 10,000,000 次迭代,skipRandom 0m8.138s;基于表的 myRandom 0m7.509s
      【解决方案5】:

      只是为了好玩,这将为特定参数生成排除数组和函数:

      function makeExcludedRandom(min,max,exclude)
          local values = {}
          local i = 0
          local j = 0
          table.sort(exclude)
          while i < max-min-1 do
             while exclude[j+1] == min+i+j do
                j = j + 1
             end
      
             values[i+1]=min+i+j
             i=i+1
          end
      
          return function()
              return values[math.random(min,max)]
          end
      end    
      local skipRandom = makeExcludedRandom(0,18,{8,16})
      
      self.currentSkyTexture = skipRandom()
      

      【讨论】:

        【解决方案6】:

        简单的解决方案(如果使用少量数字,请使用第一个答案)。

        function randomize()
            local r = math.random(0,18);
            if (r == 8 or r == 16) then 
                return randomize();
            end
            return r;
        end
        

        【讨论】:

          猜你喜欢
          • 2020-04-04
          • 1970-01-01
          • 2020-05-02
          • 2012-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-15
          • 1970-01-01
          相关资源
          最近更新 更多