2

我需要能够生成一个随机数,然后使用该数字在运行中用布尔值播种理论上无限大的 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) 之间的值。其次,我使用的语言没有种子功能。

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

4

6 回答 6

2

我想你想要柏林噪音

于 2009-10-12T19:51:41.557 回答
1

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

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

于 2009-10-12T19:56:32.263 回答
1

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

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

于 2009-10-12T20:02:36.370 回答
0

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

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

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

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

于 2009-10-12T19:59:02.850 回答
0

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

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;
}
于 2009-10-12T19:54:51.440 回答
0

只需使用一些简单的东西

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 执行此操作。

于 2009-10-12T19:55:04.530 回答