即使在 Lua 中使用相同的随机种子,也会得到不同的结果?
Even when using the same randomseed in Lua, get different results?
我有一个大型的、相当复杂的程序内容生成 lua 项目。为了调试目的,我希望能够做的一件事是使用随机种子,这样我就可以重新 运行 系统并获得相同的结果。
到最后,我在运行的开头打印出种子。问题是,每次 运行 我仍然得到完全不同的结果。假设种子在其他任何地方都没有改变,这应该是不可能的,对吧?
我的问题是,还有哪些其他方法可以影响 lua 的 math.random() 的输出?我搜索了项目中的所有代码,只有一个地方调用了 math.randomseed(),而且我在调用 anything 之前调用了它。我不使用时间或日期进行任何计算,因此不会影响结果...我还能遗漏什么?
更新于 2/22/16 monkey patching math.random & math.randomseed 经常(但不总是)输出相同的随机序列数字。但结果仍然不一样——所以我猜 真正的 问题现在是:lua 中的行为是不确定的,并且当相同的代码是 运行 按顺序?注意它在哪里发散,什么时候发散,这有助于我缩小范围,但我仍然没有找到它。 (这段代码没有使用协程,所以我认为这不是线程/竞争条件问题)
randomseed
正在使用 srandom
/srand
函数,"sets its argument as the seed for a new sequence of pseudo-random integers to be returned by random()".
我可以提供几种可能的解释:
- 你认为你调用了
randomseed
,但你没有调用(在这种情况下,random
将为你初始化序列)。
- 你认为你调用了一次
randomseed
,但你调用了多次(或者代码的其他部分也调用了 randomseed
,可能在你的序列中的不同时间)。
- 代码的其他部分调用
random
(一些次数),这会为您的代码部分生成不同的结果。
- 生成的序列没有任何问题,但您误解了结果。
- 您的 Lua 版本在
srandom
/random
处理中存在错误。
- 您系统中的
srandom
或 random
功能有问题。
了解有关您的 Lua 版本和系统的一些信息(除了演示该问题的小示例之外)将有助于找出导致此问题的原因。
更新于2016/2/22:应该比较容易查; monkeypatch math.randomseed
和 math.random
并记录所有调用和函数为后续两次运行返回的值。比较结果。如果结果不同,您应该能够找出它们不同的原因并在较小的示例上重现。您还可以使用 debug.traceback
.
查看调用函数的位置
正确,如 documentation、'equal seeds produce equal sequences of numbers.'
中所述
在将种子设置为已知常量值后,立即输出对 rand 的调用 - 如果这在运行过程中有所不同,您就知道出现了严重错误(损坏的库下载、重击安装、伽马射线击中您的驱动器等) .
假设第一个值跨运行匹配,在代码中途添加另一个输出。从那里,您可以使用二进制搜索将出错的地方归零(即有问题的代码块的前半部分或后半部分)。
虽然您可以并且应该使用一些直觉来发现错误,但请记住,如果仅凭直觉就足够了,您早就发现了错误,因此有必要进行一些系统性的消除。
修订以涵盖有关数组顺序的注释:
如果可能,使用调试工具。 detecting when the value of a Lua variable changes 上的这个 SO post 可能会有所帮助。
在没有工具的情况下,这里有一种方法可以解决这个问题:
任何相当大的数组的完整调试转储很快就会变得一团糟,很难发现更改。相反,我会使用一些额外的变量和一个测试函数来保持简洁。
制作数组的两个深拷贝。我们称它们为 debug01
& debug02
并称其为原始数组 original
。接下来,故意调换debug02
.
中两个元素的顺序
接下来,构建一个函数来比较两个数组并测试它们的元素是否匹配 & return/如果不匹配则打印第一个不匹配的索引。初始化数组后,立即对其进行测试以确保:
original
& debug01
匹配
original
&debug02
不匹配
original
& debug02
您更改的地方不匹配
我再怎么强调使用未经验证(因此可能存在错误)的测试函数来追踪错误的疯狂行为也不为过。
一旦您验证了函数的工作原理,您就可以再次使用二进制搜索来归零 rails 中出现的问题。和以前一样,平衡使用系统搜索和您的直觉。
我有一个大型的、相当复杂的程序内容生成 lua 项目。为了调试目的,我希望能够做的一件事是使用随机种子,这样我就可以重新 运行 系统并获得相同的结果。
到最后,我在运行的开头打印出种子。问题是,每次 运行 我仍然得到完全不同的结果。假设种子在其他任何地方都没有改变,这应该是不可能的,对吧?
我的问题是,还有哪些其他方法可以影响 lua 的 math.random() 的输出?我搜索了项目中的所有代码,只有一个地方调用了 math.randomseed(),而且我在调用 anything 之前调用了它。我不使用时间或日期进行任何计算,因此不会影响结果...我还能遗漏什么?
更新于 2/22/16 monkey patching math.random & math.randomseed 经常(但不总是)输出相同的随机序列数字。但结果仍然不一样——所以我猜 真正的 问题现在是:lua 中的行为是不确定的,并且当相同的代码是 运行 按顺序?注意它在哪里发散,什么时候发散,这有助于我缩小范围,但我仍然没有找到它。 (这段代码没有使用协程,所以我认为这不是线程/竞争条件问题)
randomseed
正在使用 srandom
/srand
函数,"sets its argument as the seed for a new sequence of pseudo-random integers to be returned by random()".
我可以提供几种可能的解释:
- 你认为你调用了
randomseed
,但你没有调用(在这种情况下,random
将为你初始化序列)。 - 你认为你调用了一次
randomseed
,但你调用了多次(或者代码的其他部分也调用了randomseed
,可能在你的序列中的不同时间)。 - 代码的其他部分调用
random
(一些次数),这会为您的代码部分生成不同的结果。 - 生成的序列没有任何问题,但您误解了结果。
- 您的 Lua 版本在
srandom
/random
处理中存在错误。 - 您系统中的
srandom
或random
功能有问题。
了解有关您的 Lua 版本和系统的一些信息(除了演示该问题的小示例之外)将有助于找出导致此问题的原因。
更新于2016/2/22:应该比较容易查; monkeypatch math.randomseed
和 math.random
并记录所有调用和函数为后续两次运行返回的值。比较结果。如果结果不同,您应该能够找出它们不同的原因并在较小的示例上重现。您还可以使用 debug.traceback
.
正确,如 documentation、'equal seeds produce equal sequences of numbers.'
中所述在将种子设置为已知常量值后,立即输出对 rand 的调用 - 如果这在运行过程中有所不同,您就知道出现了严重错误(损坏的库下载、重击安装、伽马射线击中您的驱动器等) .
假设第一个值跨运行匹配,在代码中途添加另一个输出。从那里,您可以使用二进制搜索将出错的地方归零(即有问题的代码块的前半部分或后半部分)。
虽然您可以并且应该使用一些直觉来发现错误,但请记住,如果仅凭直觉就足够了,您早就发现了错误,因此有必要进行一些系统性的消除。
修订以涵盖有关数组顺序的注释:
如果可能,使用调试工具。 detecting when the value of a Lua variable changes 上的这个 SO post 可能会有所帮助。
在没有工具的情况下,这里有一种方法可以解决这个问题:
任何相当大的数组的完整调试转储很快就会变得一团糟,很难发现更改。相反,我会使用一些额外的变量和一个测试函数来保持简洁。
制作数组的两个深拷贝。我们称它们为 debug01
& debug02
并称其为原始数组 original
。接下来,故意调换debug02
.
接下来,构建一个函数来比较两个数组并测试它们的元素是否匹配 & return/如果不匹配则打印第一个不匹配的索引。初始化数组后,立即对其进行测试以确保:
original
&debug01
匹配original
&debug02
不匹配original
&debug02
您更改的地方不匹配
我再怎么强调使用未经验证(因此可能存在错误)的测试函数来追踪错误的疯狂行为也不为过。
一旦您验证了函数的工作原理,您就可以再次使用二进制搜索来归零 rails 中出现的问题。和以前一样,平衡使用系统搜索和您的直觉。