[英]Custom Random Number Generator
是否有可能获得一个非常快速但可靠的伪随机数生成器(相同的输入=相同的输出,所以我不能使用时间)? 我希望最终结果类似于float NumGen( int x, int y, int seed );
以便根据这三个值创建一个介于0和1之间的随机数。 我找到了几个随机数生成器,但是我无法使它们正常工作,并且Unity附带的随机数生成器使用起来很慢。 我必须在每1米的地形上对生成器进行9次调用,因此我并不在乎它是否在统计上不是完全随机的,只是它的运行速度非常快。 有人知道适合我需求的算法吗? 谢谢 :)
我认为您低估了System.Random
类。 这是相当快的。 我相信您的速度降低与每次调用NumGen
方法时创建Random
类的新实例有关。
在我的快速测试中,我能够在大约1毫秒内使用System.Random
生成100,000个随机数。
为避免速度变慢,请考虑2D平面中的种子点。 分散种子点,使其覆盖范围不超过100,000米。 然后关联(或计算)每米的最近种子点,并将该点用作System.Random
的种子。
是的,您将生成大量您永远不会使用的随机数,但是它们实际上是免费的。
伪代码:
double NumGen(x, y, distance, seed) {
Random random = new Random(seed);
double result = 0;
for (int i=0; i<distance; i++) {
result = random.NextDouble();
}
}
您可以修改此简单轮廓以返回随机数序列(可能表示一个网格),并将其与缓存机制结合使用。 这样可以节省内存并改善(减少)CPU消耗。
我想您必须在每次调用NumGen时创建一个Random实例。 要使函数为相同的参数返回相同的数字,可以使用哈希函数。
我测试了几件事,并且此代码比重新创建Random实例大约快3倍。
//System.Security.Cryptography
static MD5 hasher = MD5.Create();
static byte[] outbuf;
static byte[] inbuf = new byte[12];
static float floatHash(uint x, uint y, uint z) {
inbuf[0]= (byte)(x >> 24);
inbuf[1]=(byte)(x >> 16);
inbuf[2]=(byte)(x >> 8);
inbuf[3]=(byte)(x);
inbuf[4]=(byte)(y >> 24);
inbuf[5]=(byte)(y >> 16);
inbuf[6]=(byte)(y >> 8);
inbuf[7]=(byte)(y);
inbuf[8]=(byte)(z >> 24);
inbuf[9]=(byte)(z >> 16);
inbuf[10]=(byte)(z >> 8);
inbuf[11]=(byte)(z);
outbuf = hasher.ComputeHash(inbuf);
return ((float)BitConverter.ToUInt64(outbuf, 0))/ulong.MaxValue;
}
使用某些RSA方法的另一种方法比新的System.Random(seed)快约5倍:
static uint prime = 4294967291;
static uint ord = 4294967290;
static uint generator = 4294967279;
static uint sy;
static uint xs;
static uint xy;
static float getFloat(uint x, uint y, uint seed) {
//will return values 1=> x >0; replace 'ord' with 'prime' to get 1> x >0
//one call to modPow would be enough if all data fits into an ulong
sy = modPow(generator, (((ulong)seed) << 32) + (ulong)y, prime);
xs = modPow(generator, (((ulong)x) << 32) + (ulong)seed, prime);
xy = modPow(generator, (((ulong)sy) << 32) + (ulong)xy, prime);
return ((float)xy) / ord;
}
static ulong b;
static ulong ret;
static uint modPow(uint bb, ulong e, uint m) {
b = bb;
ret = 1;
while (e > 0) {
if (e % 2 == 1) {
ret = (ret * b) % m;
}
e = e >> 1;
b = (b * b) % m;
}
return (uint)ret;
}
我进行了一次测试,生成了100000个浮动。 我将索引用作System.Random的种子,并用作floatHash的x参数(y和z为0)。
System.Random:最小值:2.921559E-06最大值:0.9999979重复次数:0
floatHash MD5:最小值:7.011156E-06最大值:0.9999931重复:210(值被返回两次)
getFloat RSA:最小值:1.547858E-06最大值:0.9999989重复次数:190
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.