【问题标题】:How to sync a PRNG between C#/Unity and Python?如何在 C#/Unity 和 Python 之间同步 PRNG?
【发布时间】:2020-05-06 19:35:15
【问题描述】:

我有一个用 Unity/C# 实现的游戏,它使用内置的 PRNG (UnityEngine.Random) 生成简单的环境。我正在尝试在 Python 3 中重新实现环境生成过程。我需要同步随机数生成器,以便在提供相同种子时,Unity 中的实际游戏和 Python 重新实现会生成完全相同的环境。同步这两个平台的最佳方法是什么?

目前我考虑过的一些解决方案:

  • 尝试在 C# 中重新实现 Python 的默认随机数生成器 (random)。源代码可用,但相当长,因此在实践中可能难以实施。
  • 尝试在 Python 中重新实现 UnityEngine.Random。但是,我没有任何源代码,即使我知道使用的 PRNG 的类,也不能保证我能够以完全相同的方式成功地重新实现它。
  • 在两者中实现相同的 PRNG。但是,我不知道 PRNG 对我的用例有什么好的选择。我基本上需要一些看起来随机的东西(尽管它不一定是安全的),并且不需要超过一两个小时的时间来组装。 Wikipedia 有一长串 PRNG,我不知道实现它们的难度。
  • 或者也许其他人在某个时候已经这样做了......?不过,我在网上找不到任何东西。

关于最佳方法的任何建议,或者我可以在 C# 和 Python 中轻松实现的简单 PRNG?

谢谢!

【问题讨论】:

  • 为什么首先需要重新实现它?为什么生成必须在运行时发生?虽然如果你真的需要这样做,你应该将生成的代码分开,使其足够独立,以便能够将其包含在两个项目中(例如:作为动态链接库)
  • 我在游戏中做强化学习,需要极快地生成大量环境。我不需要渲染它们,因此使用游戏的编译版本的开销是不必要的,并且会减慢进程。但我确实需要它们在平台之间保持一致,以便我可以渲染它们以进行调试。我并没有考虑从生成大量随机数序列开始,但这可能相对简单。弄清楚如何创建 DLL 可能太耗时了。
  • 你可以通过IronPython在C#中运行Python的random。如果您不关心速度或优雅,它应该可以工作。
  • FWIW,一位朋友刚刚推荐了 mulberry32 PRNG。我想我会先尝试实现它(似乎实现起来比较简单)。谢谢!
  • @Sweeper,酷,我去看看!

标签: c# python unity3d random


【解决方案1】:

一般来说,在不同语言的两个程序之间“同步”PRNG 的最佳方法是在两种语言中实现相同的 PRNG。

出于您的目的,如果您只想要“看起来随机的东西(尽管它不一定是安全的)”,那么线性同余生成器 (LCG) 是一个简单的 PRNG。这种生成器在 C# 和 Python 中都很容易实现。

在许多其他可能性中,一个示例是以下 32 位 LCG(其中 x 是种子):

C#:

// Generate the next x from the current one.
unchecked {
    // NOTE: x is an `int`
    x = ((int)0xadb4a92d * x) + 9999999;
}

Python:

# Generate the next x from the current one.
x = ((0xadb4a92d * x) + 9999999) & 0xFFFFFFFF

有关其他参数选择以及对涉及 LCG 的理论的回顾,请参阅最近的 paper by Steele and Vigna 的第 8 节。

但是,LCG 远非完美。 (例如,上面的 LCG 产生的 x 的低位很弱,因此,每隔一个 x 是奇数,每隔一个 x 是偶数。)一般来说,LCG,尤其是那些具有 32比特种子或其他短种子远不适合许多情况,包括科学工作或信息安全。如果您想要另一个 PRNG 选择,我会列出 many of them

【讨论】:

  • 太棒了,非常感谢!该列表看起来非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 2018-12-31
  • 2017-12-08
  • 2011-01-12
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多