重新设置 PCG 种子
Rebase PCG seed
我正在研究一种算法(程序赛道生成器),其结果在一般情况下仅基于 RNG 输出。但在某些特定场景下,我需要为用户提供绕过某些生成步骤(例如地形构造)而不影响其余生成过程的能力。
我举个简单实用的例子:
## Procedural racetrack ##
*
| Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3 | 4 5 6 7 | 8 9 | 0 |
## User-overridden racetrack ##
*
| Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3 | provided by user | 4 5 | 6 |
如您所见,在用户覆盖赛道情况下,地形生成步骤被绕过(等等不消耗 RNG 输出)改变所有后续生成步骤。每个生成步骤所需的 RNG 输出数量在不同的赛道生成之间不是恒定的(甚至不能预先确定)。
我正在寻找的是某种 RNG 同步操作(可能不是最正确的术语...)放在 Terrain generation 步骤和 Surfaces generation 步骤从 *
开始具有相同的 RNG 流,无论地形是否由用户提供。我想到了类似的东西:
uint64_t seed = // initialized with racetrack ID
pcg32 rng(seed);
// Do Track shape generation step
// Do Terrain generation generation step
seed = seed + k; // where k is some constant
rng.seed(seed);
// Do Surfaces generation step
// Do Assets picking step
但是我不知道seed = seed + k
;是一种有效的重新播种方法(或者有更好的方法)并且如果 k
.
的某些值比其他值更好
参考最初在 PCG 存储库的 问题 部分提交的问题:https://github.com/imneme/pcg-cpp/issues/72
这归结为为您的四个(或更多)生成阶段(在您的示例中,轨道形状生成、地形生成、表面生成和资产拾取)中的每一个分配一个单独的 PRNG,并将种子分配给他们每个人。 (在您的情况下,一种可行的方法是形成赛道 ID 的哈希值、每个生成阶段的 ID 和固定的位串,并将该哈希值用作每个 PRNG 的种子。)
然而,一般来说,您对种子的选择可能很重要,即使在理论上并非如此。
例如,有许多 PRNG,给定的播种策略将为其生成相关的伪随机数序列。例如,在大多数版本的 PCG 中,从种子生成的两个序列仅在高位不同 will be highly correlated(“来自同一生成器的子序列”)。
要降低相关伪随机数的风险,您可以使用 PRNG 算法,例如 SFC 和其他所谓的“基于计数器的”PRNG(Salmon 等人,“平行随机数:与 1 一样简单, 2, 3", 2011),通过为每个种子提供自己独立的伪随机数序列来支持伪随机数的独立“流”。 (但是请注意,PCG has a flawed notion of "streams".) There are other strategies as well, and I explain more about this in "Seeding Multiple Processes".
另请参阅:
- Best practices for seeding random and numpy.random in the same program
我正在研究一种算法(程序赛道生成器),其结果在一般情况下仅基于 RNG 输出。但在某些特定场景下,我需要为用户提供绕过某些生成步骤(例如地形构造)而不影响其余生成过程的能力。
我举个简单实用的例子:
## Procedural racetrack ##
*
| Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3 | 4 5 6 7 | 8 9 | 0 |
## User-overridden racetrack ##
*
| Track shape generation | Terrain generation | Surfaces generation | Assets picking |
RNG stream | 1 2 3 | provided by user | 4 5 | 6 |
如您所见,在用户覆盖赛道情况下,地形生成步骤被绕过(等等不消耗 RNG 输出)改变所有后续生成步骤。每个生成步骤所需的 RNG 输出数量在不同的赛道生成之间不是恒定的(甚至不能预先确定)。
我正在寻找的是某种 RNG 同步操作(可能不是最正确的术语...)放在 Terrain generation 步骤和 Surfaces generation 步骤从 *
开始具有相同的 RNG 流,无论地形是否由用户提供。我想到了类似的东西:
uint64_t seed = // initialized with racetrack ID
pcg32 rng(seed);
// Do Track shape generation step
// Do Terrain generation generation step
seed = seed + k; // where k is some constant
rng.seed(seed);
// Do Surfaces generation step
// Do Assets picking step
但是我不知道seed = seed + k
;是一种有效的重新播种方法(或者有更好的方法)并且如果 k
.
参考最初在 PCG 存储库的 问题 部分提交的问题:https://github.com/imneme/pcg-cpp/issues/72
这归结为为您的四个(或更多)生成阶段(在您的示例中,轨道形状生成、地形生成、表面生成和资产拾取)中的每一个分配一个单独的 PRNG,并将种子分配给他们每个人。 (在您的情况下,一种可行的方法是形成赛道 ID 的哈希值、每个生成阶段的 ID 和固定的位串,并将该哈希值用作每个 PRNG 的种子。)
然而,一般来说,您对种子的选择可能很重要,即使在理论上并非如此。
例如,有许多 PRNG,给定的播种策略将为其生成相关的伪随机数序列。例如,在大多数版本的 PCG 中,从种子生成的两个序列仅在高位不同 will be highly correlated(“来自同一生成器的子序列”)。
要降低相关伪随机数的风险,您可以使用 PRNG 算法,例如 SFC 和其他所谓的“基于计数器的”PRNG(Salmon 等人,“平行随机数:与 1 一样简单, 2, 3", 2011),通过为每个种子提供自己独立的伪随机数序列来支持伪随机数的独立“流”。 (但是请注意,PCG has a flawed notion of "streams".) There are other strategies as well, and I explain more about this in "Seeding Multiple Processes".
另请参阅:
- Best practices for seeding random and numpy.random in the same program