使用math.random()随机选择一个数字。

我想在一个范围内选择一个随机数,但是如果生成的数字是'x',下一次我希望这个数字至少为x±20。我该怎么做?

math.random()只接受两个参数,所以如果在第一轮中选择的数字是40,在第二轮中它应该是50或更多/30或更少,类似地,下一次应该是60或更多/20或更少。

点赞
用户3527940
用户3527940
t = Math.random(0,60);
if (t > last_value - 20)
    t += 40
last_value = t

由于不会 LUA,我们将使用伪代码。

t = Math.random(0,60); // 生成 0 - 60 之间的随机数
if (t > last_value - 20) // 如果 t 大于上次值减 20
    t += 40 // 将 t 加上 40
last_value = t // 记录 t 为上次值
2014-06-28 00:40:50
用户277304
用户277304

假设您希望在区间 [0,L) 中获取一个数字 x,使得每个数字之间的(循环)距离至少为 d(在 Java 中):

  public static double rand1(double L, double d, double x) {
    double y = x +  d + Math.random() * (L - 2.0 * d) ;
    if (y >= L)
      y -= L;
    return y;
  }

禁止“循环”中距离小的数字似乎是一个不必要的复杂化,但实际上它简化了问题:首先,这个简单的算法生成了在 [0,L) 中均匀分布的数字,而被接受的答案却没有。

2014-06-28 00:48:00
用户869951
用户869951

如果你有一个“主”对象,它随机放置在0到xMax之间,并且有1个或多个“次要”对象,必须在同一范围内的主对象上至少D个距离处放置,如果有多个次要对象,则它们可以彼此靠得很近,那么请尝试下面的代码:

function getRandPosNotTooCloseToMain(xMax, mainX, D)
    assert(2*D < xMax) -- 如果不是,则主对象太“胖了”
    local leftLen = mainX - D
    local rightLen = xMax - (mainX + D)
    local leftSideWins = true -- 需要一些默认值

    if leftLen < 0 then -- 只能在主对象右侧放置
        assert(rightLen > 0)
        leftSideWins = false

    elseif rightLen < 0 then -- 只能在主对象左侧放置
        -- 什么也不做,因为leftSideWins已经是true

    else -- 主对象两侧都有空间(leftLen和rightLen都>0)
         -- 因此随机选择一个侧面,然后在该侧返回随机数字
        local ratio = leftLen / (leftLen + rightLen)
        if math.random() > ratio then -- 右半边获胜
            leftSideWins = false
        else -- 左侧获胜,这是默认值
        end
    end

    if leftSideWins then
        return math.random(0, leftLen)
    else
        return mainX + D + math.random(0, rightLen)
    end
end

可以用以下测试:

-- 测试
math.randomseed(os.time())
local numTests = 100000

-- 生成一堆值,右侧总是获胜:
for x=1,numTests do
    local x = getRandPosNotTooCloseToMain(60, 15, 20)
    assert( x >= 15+20, x )
end

-- 生成一堆值,左侧总是获胜:
for x=1,numTests do
    local x = getRandPosNotTooCloseToMain(60, 45, 20)
    assert( x <= 45-20, x )
end

-- 生成一堆值,左侧总是获胜:
for x=1,numTests do
    local x = getRandPosNotTooCloseToMain(60, 30, 20)
    assert( x <= 10 or x>= 50, x )
end

-- 如果到达这里,则所有测试都通过!
print("通过!")

所有测试都通过。在你的情况下,你可以通过math.random(0,xMax)随机设置mainX

2014-06-28 03:00:17