【问题标题】:Turning Random Number Into Deterministic White Noise将随机数转化为确定性白噪声
【发布时间】:2009-10-12 19:45:08
【问题描述】:

我需要能够生成一个随机数,然后使用该数字在运行中用布尔值播种理论上无限大的 2d 平面。我需要一个我可以调用的函数,它具有三个输入(x、y 和随机种子)并返回一个伪随机结果:

int r = random()
//...
var value_for_point = f(x,y,r);

如果我要使用此函数用 1 和 0 填充 10x10 数组,理想情况下,它看起来与我在进行过程中要求每个单元格的随机值相同/相似,即白噪声。它不必是完美的——它不是用于统计分析。我只需要能够在给定相同随机数的情况下重新创建数组。

我不能简单地为随机数生成器播种,原因有二。首先,我需要这个函数基于 x 和 y。我可以调用这个函数来填充 (0,0) 和 (10, 10) 之间的数组,然后再请求 (-10,-5) 和 (3,4) 之间的值。其次,我使用的语言没有种子功能。

我敢肯定,要么有一种我没有看到的简单方法来做到这一点,要么是分形领域中的某些东西可能对我有所帮助。有人知道怎么做吗?

【问题讨论】:

  • 这是什么语言,为什么它不允许你为生成器做种?
  • Javascript。不知道为什么它不允许种子,它就是不允许。

标签: math fractals


【解决方案1】:

我想你想要Perlin noise?

【讨论】:

【解决方案2】:

它不是 100% 完美的,但是使用像 SHA1 或 MD5 这样的固定算法怎么样? SHA1 从任何字符串中取出一个 160 位的字符串,它或多或少是随机的。要填充 10x10 布尔数组,您只需要非常接近随机的最低有效 100 位。因为您从已知的基本字符串(任意长度)作为种子开始,所以您的值是可重现的。

我不知道您使用的是什么语言,但几乎所有操作系统都可以使用 SHA1 和 MD5 的实现。

【讨论】:

  • 这会给我我的 10x10 数组,但这是一个理论上无限的数组。我需要一个函数,给定三个输入数字,输出一个伪随机结果。
  • 然后将您第一次获得的字符串送回 SHA1/MD5 并将其用作下一次迭代的种子。它仍然是确定性的,您可以根据需要扩展任意数量的位。
【解决方案3】:

非常简单的数学算法可以产生非常复杂的确定性输出。看看wolfram's book。

例如,您可以使用rule 30 来生成它。

【讨论】:

    【解决方案4】:

    只需使用一些简单的东西,比如

    private static uint GetUint()
    {
        m_z = 36969 * (m_z & 65535) + (m_z >> 16);
        m_w = 18000 * (m_w & 65535) + (m_w >> 16);
        return (m_z << 16) + m_w;
    }
    

    并为初始值 m_z 和 m_w 播种。对每个 x 和 y 执行此操作。

    【讨论】:

      【解决方案5】:

      您无法模拟无限大的平面。最终,您会遇到某种随机数生成器,并且生成器可以存储的状态位数总是有限制的。

      也就是说,限制主要是理论上的。对于大多数实际目的,您可以根据用户可以指定的大小来限制平面的大小。例如,如果 x 和 y 是两个 32 位整数,那么您只需要能够模拟一个 2^32-1x2^32-1 的平面——这是一个远小于无限的 long .

      鉴于您对系统随机数生成器的描述,您可能需要(或至少非常想要)编写自己的生成器,或者使用网络上现有的足够长的时间。如果您要为 X 和 Y 坐标使用 32 位,那么您需要一个至少具有 64 位周期的生成器。

      从那里开始,事情就变得很简单了:你将 x,y 坐标的位组合起来,就像生成一个线性地址到任何其他二维数组中一样,然后将结果用作 PRNG 的种子,然后得到结果。

      【讨论】:

        【解决方案6】:

        如果我们知道这种语言可能会有所帮助。

        C#...

        static bool GetPixel(int seed, ushort x, ushort y)
        {
            int randomSeed = (x << 16 | y) ^ seed;
            Random rnd = new Random(randomSeed); 
            /* if you just want a constant result you can seed the function 
               on app start and never touch the random generator again */
            return rnd.NextDouble() >= .5;
        }
        

        【讨论】:

        • 我正在使用 javasript。不幸的是,它没有种子功能。
        • 好吧,如果你没有状态,你就不能为函数做种,你需要结果是一致的......听起来你需要硬编码一个常量。
        猜你喜欢
        • 2019-12-24
        • 2018-12-09
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 2011-06-20
        • 2015-02-20
        • 1970-01-01
        相关资源
        最近更新 更多