【问题标题】:A pseudo-random number generator based on 2 inputs [closed]基于 2 个输入的伪随机数生成器
【发布时间】:2016-05-24 10:46:47
【问题描述】:

我需要根据 2 个输入值 X 和 Y 生成一个伪随机数。给定相同的 X 和 Y 值,我需要得到相同的结果。结果应介于 0 和 1 之间。

到目前为止,我有这个:

const int a = 0x7fffffff / 48271;
const int b = 0x7fffffff % 48397;

float rand(int x, int y) {
    float seed, result;

    seed = x ^ ((y << 1) & 0x2AAAAAAA) ^ ((y >> 1) & 0x33333333);
    result = 48353 * (seed % a) - b * (seed / a);

    return (result);
}

它给了我一个结果,但不是我想要的。我是根据我在网上看到的随机东西拼凑而成的,所以不知道它是否真的有什么好处。

【问题讨论】:

  • 您的问题是什么?很难猜出“不是我要找的”是什么意思。好的随机数生成器也不能通过在网上随机查找来构建。
  • 使用无符号数学是很好的第一步。
  • 我认为你想要的hash 比 RNG 更接近。
  • 这两种输入类型是int(可能是32、64、16位)还是signed 32-bit?

标签: c algorithm random


【解决方案1】:

借用xxHash:

float rand(uint32_t x, uint32_t y) {
  /* mix around the bits in x: */
  x = x * 3266489917 + 374761393;
  x = (x << 17) | (x >> 15);

  /* mix around the bits in y and mix those into x: */
  x += y * 3266489917;

  /* Give x a good stir: */
  x *= 668265263;
  x ^= x >> 15;
  x *= 2246822519;
  x ^= x >> 13;
  x *= 3266489917;
  x ^= x >> 16;

  /* trim the result and scale it to a float in [0,1): */
  return (x & 0x00ffffff) * (1.0f / 0x1000000);
}

总体思路是让x 和y 进行各种1:1 转换,并将它们混合在一起以在整个结果中均匀分布所有输入位。然后结果以浮点为 [0,1)。我已经从可能的输出中排除了 1.0,因为包含它是一种繁琐的操作。

任何奇数乘以无符号溢出是 1:1 变换,因为奇数都是 2 的幂的互质数(uint32_t 的范围限制)。不幸的是,乘法只允许低位影响高位;它不允许高位影响低位。为了弥补这一点,我们有一些x ^= x &gt;&gt; k 术语,将高位混合到低位。

【讨论】:

    【解决方案2】:

    要“获得相同的结果”,PRNG 状态的位数至少需要与x,y 位宽的总和一样多。 float 不够宽。

    “相同的结果”是指生成相同的数字序列。

    long double可能对你有用,但看来你需要一个状态更广泛的新 PRNG 算法。

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2011-09-22
      • 2018-06-15
      • 2014-05-18
      • 1970-01-01
      • 2011-02-08
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多