【问题标题】:get current random seed from lua从 lua 获取当前随机种子
【发布时间】:2017-07-10 05:07:16
【问题描述】:

我知道你可以用math.randomseed()设置lua的随机数生成器的种子。

我想在某种程度上并行生成两个独立的确定性数字序列。我已将我的问题简化为:

-- assume seed1 and seed2 exist and are positive integers.
local sequence1 = {};
local sequence2 = {};

math.randomseed(seed1);
for i = 1,50 do
    sequence1[#sequence1 + 1] = math.random();
end
seed1 = math.getseed(); -- This is the function that I want.

-- stuff

math.randomseed(seed2);
for i = 1,75 do
    sequence2[#sequence2 + 1] = math.random();
end
seed2 = math.getseed(); -- This is the function that I want.

-- stuff


math.randomseed(seed1);
for i = 1,50 do
    sequence1[#sequence1 + 1] = math.random();
end
seed1 = math.getseed(); -- This is the function that I want.

我查看了文档并将math 表放入k,v in pairs for 循环中,但没有任何结果。 lua 中是否存在这样的函数,或者我必须为此编写自己的生成器?

【问题讨论】:

  • 你必须自己写生成器
  • 如果您要使用的随机数的总数相对较小(例如 10,000 或更少),您可以预先计算两个随机数组,每个数组都有自己的确定性种子,然后根据需要从它们中提取.
  • @JohnColeman 我不知道每个种子需要多少个。它可能小到 100 个,也可能大到一百万甚至更多。
  • 那就做你自己的发电机吧。一个基本的线性同余只需要几行代码。
  • 如果您自己滚动并使用 Lua 5.3(具有 64 位 int 二进制操作),请考虑使用 PCG 而不是 LCG。多出约 2-3 行代码,但提供了 much 更好的输出。

标签: random lua


【解决方案1】:

目前标准 Lua 库中没有获取当前种子的函数。为此,您需要:

  1. 编写自己的RNG函数(

  2. 更改用 C 编写的 math.randomseed 函数(有风险

  3. 使用具有此功能的 RNG 库(简单

  4. 保存math.random 被调用到变量的次数(最简单但不理想


自定义RNG

编写自己的 RNG 会很耗时,容易出错,而且没有经过优化。您可以在网上搜索有关如何执行此操作的算法,但它们各有不同的怪癖。一些交易表现是为了随机性,而另一些随机数模式可能是可预测的。


在标准库中修改math.randomseed

这样做可能危害任何使用math 库的第三方模块或库。更不用说如果你不知道自己在做什么,这可能会导致 Lua 本身出现问题。


加载 RNG

有多个可用 Lua 编写的 RNG 模块。我强烈建议您选择一个适合您的需求,并确保它能够获得当前的种子。 rotLove 有多个这样做的,但使用它们有一个警告。您为模块之一设置的 RNG 种子 不会math.randomseed 提供种子。

A relevant story on this...

这个问题最近发生在尝试同时使用 rotLove 的 RNG 和我开发的骰子模块的人身上。骰子使用math.random 来确定掷骰。这个人已经用RNG.randomseed 设置了种子,并假设它会影响所有math.random 操作,结果发现他们的应用程序的每个运行时都会产生相同的骰子结果。这是因为他们从未设置math.randomseed!因此,我将我的 dice 模块添加到 rotLove,以便它使用提供的 RNG 生成骰子掷骰,而不必同时使用第三方 RNG 和默认的 Lua RNG。


存储一个变量

设置种子后,每次调用math.random 时,变量都会增加+1。当您只需要获取种子时,

math.randomseed(orginal_seed_provided)
seed_counter = 0  -- every time math.random is called add one
-- whenever you need the current seed, it's the seed_counter

-- run code
-- suddenly you need to reset RNG to a previous seed

math.randomseed(orginal_seed_provided)
for i=1, seed_counter do 
  math.random() -- discarding the results from prior math.random operations 
end  
-- next call to math.random() will be where seed left off 

此选项具有可怕的后果,因为您使用 math.random() 的次数越多,您必须进行的函数调用就越多,才能找到被掩埋的种子。

math.random 被调用 100,000 次以上之后获得种子这将是 CPU 消耗并具有明显的影响,因此请注意。

【讨论】:

    猜你喜欢
    • 2016-10-07
    • 1970-01-01
    • 2011-04-01
    • 2021-07-18
    • 2018-06-17
    • 2021-12-18
    • 2012-04-29
    • 1970-01-01
    • 2014-05-21
    相关资源
    最近更新 更多