python - 在 Python 3.2 和 3.3 中给出不同结果的数值模拟

标签 python python-3.x numerical-methods

这可能是一个奇怪的问题,但问题是:

我有一个数值模拟。这不是一个特别长的程序,但解释它在做什么有点冗长。我正在运行模拟一千次并计算平均结果和方差,方差非常小,大约为 10^(-30)。

但是,我注意到当我在 python 3.3 中运行程序时,事情变得很奇怪。在 Python 2.7 和 Python 3.2 中看到,每次我总是得到相同的答案。相同的平均值,相同的微小差异。

但是当我在 Python 3.3 中运行它时,我每次都会得到一个不同的答案。也就是说,不同的平均值和不同的(但仍然很小)方差。这非常奇怪,因为概率法则表明,如果方差真的那么小,就不会发生这种情况。所以我想知道,自 3.2 以来发生变化的 3.3 解释器到底发生了什么,导致我的模拟变得疯狂?

以下是我想到的一些事情:

  • 我的 Python 版本可能存在奇怪的 32 位/64 位差异,但没有,我检查过它们都运行 64 位。
  • 我可能在 float/int 转换中遇到了一些错误,但这会在 Python 3.2 中得到解决,因为它们在适当的时候使除法返回 float ,所以 3.2 和 3.3 的结果应该是相同的。
  • 我的模拟被表示为生成器,所以可能 3.3 中的生成器发生了一些变化,但我不知道那是什么。
  • 数字浮点表示有一些我不知道的变化。
  • 结果为“未确定”的其中一个函数存在一些潜在的变化,这会影响我的算法的初始条件。例如,在我的代码中的某处,我使用“list(table.keys())”对我的数据列进行排序,这些数据列最初是一个字典,并且 list 决定将字典键从 3.2 排序到 3.3 的方式可能发生了变化。但如果是这种情况,那么代码仍然应该每次都做同样的事情,但事实并非如此(故意使列表随机排序似乎很奇怪!)。

有没有人指出从 3.2 到 3.3 的变化可能会导致我的问题?

最佳答案

您的最后一个要点很可能是原因。在 python3.3 ,默认情况下启用哈希随机化以解决安全问题。基本上,这个想法是您现在永远不知道您的字符串将如何散列(这决定了它们在字典中的顺序)。

这是一个演示:

d = {"a": 1, "b": 2, "c": 3}
print(d)

在我的机器上,使用 python3.4,这会产生 3 个不同顺序的结果:

$ python3.4 test.py
{'a': 1, 'c': 3, 'b': 2}
$ python3.4 test.py
{'c': 3, 'b': 2, 'a': 1}
$ python3.4 test.py
{'b': 2, 'c': 3, 'a': 1}

在散列随机化之前,如果您知道一个字符串将如何散列,那么对您的应用程序有足够了解的恶意攻击者可以为其提供数据,以导致字典查找在 O(n) 时间内运行,而不是通常的 O(1)字典查找。这可能会导致某些应用程序的性能严重下降。

您可以按照文档 here 禁用哈希随机化.在某些时候,他们还向 python 引入了一个 -R 标志,它在“选择加入”的基础上启用了哈希随机化。此选项至少适用于 python3.2,因此您可以使用它来检验我们的假设。

关于python - 在 Python 3.2 和 3.3 中给出不同结果的数值模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20416337/

相关文章:

python - 如何在 Wampserver 上设置和运行 Python?

python - ValueError : Error when checking target: expected model_2 to have shape (None, 252, 252, 1) 但得到形状为 (300, 128, 128, 3) 的数组

python - 导入错误 : cannot import name '_gi' from partially initialized module 'gi' (most likely due to a circular import)

c++ - 二进制搜索数学函数

python - 如何在 Python 中访问 Outlook 收件箱中的子文件夹

python - 如何计算需要将一根字符串更改为另一根字符串的次数?

python - 计算列表列表中某个类的实例的出现次数

python - 使用映射关系进行字典键操作

algorithm - 计算二维函数积分的最佳并行方法

n-body问题issue的Python实现