Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 来自多个64位输入的确定性随机噪声发生器?_C#_Random_Noise - Fatal编程技术网

C# 来自多个64位输入的确定性随机噪声发生器?

C# 来自多个64位输入的确定性随机噪声发生器?,c#,random,noise,C#,Random,Noise,我试图在C#中创建一个伪随机数生成器,在给定相同的输入集的情况下生成相同的输出。它需要快速,接受64位数字,尤其重要的是允许任意输入集。输出应该是介于[0和1}之间的双精度 大多数情况下,输入将是一个种子值,该种子值在应用程序的生命周期内保持不变,以及一个或多个其他数值,如x、y、z和w坐标,其本身可能是int32、int64或double类型 我已经尝试过调整我发现的其他一些随机数生成器,但我一直遇到大量的聚集问题,主要是因为我不知道围绕这个主题的理论,或者素数的数学性质,而这些似乎在大多数情

我试图在C#中创建一个伪随机数生成器,在给定相同的输入集的情况下生成相同的输出。它需要快速,接受64位数字,尤其重要的是允许任意输入集。输出应该是介于[0和1}之间的双精度

大多数情况下,输入将是一个种子值,该种子值在应用程序的生命周期内保持不变,以及一个或多个其他数值,如x、y、z和w坐标,其本身可能是int32、int64或double类型

我已经尝试过调整我发现的其他一些随机数生成器,但我一直遇到大量的聚集问题,主要是因为我不知道围绕这个主题的理论,或者素数的数学性质,而这些似乎在大多数情况下都起到了作用

我想使用这个函数来生成随机噪声,这些随机噪声将在许多其他算法中内部使用,包括我自己的算法和标准算法,例如Perlin噪声等


我该怎么做呢?

我已经找到了一个解决方案,我会一直使用,直到有人说服我为什么我不应该这样做

下面的代码是我的类的一个可用摘录。第一个
Generate
函数可以根据您的需要接受任意数量的重载。您可以将输入转换为字节数组,并将其传递给private Generate方法,该方法完成其余部分。请注意,内部有一个对
\u seed
的引用,它只是一个字节数组它本身,由通过构造函数提供的种子值生成

此外,代码依赖于,这是非常快的

我已经运行了大量迭代来检查分布,它似乎分布非常均匀,没有明显的人为聚集在给定值周围。我让它在大约720ms的时间内在Intel Core i7上生成一百万个值,这对于我的目的来说足够快。我还测试了它在纹理上生成2D白噪声,而且噪音看起来很随机

public double Generate(double x, double y, double z, double w)
{
    return Generate(
        _seed,
        BitConverter.GetBytes(x),
        BitConverter.GetBytes(y),
        BitConverter.GetBytes(z),
        BitConverter.GetBytes(w)
    );
}

private double Generate(params byte[][] inputs)
{
    var len = 0;
    int i;
    for(i = 0; i < inputs.Length; i++)
        len += inputs[i].Length;
    var buffer = new byte[len];
    var offset = 0;
    for(i = 0; i < inputs.Length; i++)
    {
        var bytes = inputs[i];
        Buffer.BlockCopy(bytes, 0, buffer, offset, bytes.Length);
        offset += bytes.Length;
    }
    return Hash(buffer);
}

private double Hash(byte[] bytes)
{
    var hash = new Murmur3().ComputeHash(bytes);
    var buffer = new byte[8];
    for(var i = 0; i < hash.Length; i++)
        buffer[i%8] ^= hash[i];
    var n = BitConverter.ToInt64(buffer, 0);
    if(n < 0) n = -n;
    if(n == long.MaxValue) n--;
    return n / (double)long.MaxValue;
}
公共双生成(双x、双y、双z、双w)
{
返回生成(
_种子,
BitConverter.GetBytes(x),
BitConverter.GetBytes(y),
BitConverter.GetBytes(z),
BitConverter.GetBytes(w)
);
}
专用双生成(参数字节[][]输入)
{
var-len=0;
int i;
对于(i=0;i
这仍然是一个相当缓慢的rng,但速度大约是基于Murruld3的rng的10倍。为每个产生的数量重新播种都有成本,因此需要大量种子,这些种子都会对结果产生非系统性影响

更新:真的没有任何理由允许弱位,这个版本应该没有明显的模式

class Prng
{
    const double shift3 = .125;
    const double shift9 = shift3 * shift3 * shift3;
    const double shift27 = shift9 * shift9 * shift9;
    const double shift53 = shift27 * shift27 * 2.0;
    public ulong rndlong(ulong a, ulong b, ulong c, ulong d){
        ulong e = ((a ^ (b >> 14 | b << 50)) + ((c >> 31 | c << 33) ^ (d >> 18 | d << 46)))*1911413418482053185;
        ulong f = (((a >> 30 | a << 34) ^ c) + ((b >> 32 | b << 32) ^ (d >> 50 | d << 14)))*1139072524405308145;
        ulong g = (((a >> 49 | a << 15) ^ (d >> 33 | d << 31)) + (b ^ (c >> 48 | c << 16)))*8792993707439626365;
        ulong h = (((a >> 17 | a << 47) ^ (b >> 47 | b << 17)) + ((c >> 15 | c << 49) ^ d))*1089642907432013597;
        return (e ^ f ^ (g >> 21 | g << 43) ^ (h >> 44 | h << 20)) * 2550117894111961111 +
            ((e >> 20 | e << 44) ^ (f >> 41 | f << 23) ^ (g >> 42 | g << 22) ^ h) * 8786584852613159497 +
            ((e >> 43 | e << 21) ^ (f >> 22 | f << 42) ^ g ^ (h >> 23 | h << 41)) * 3971056679291618767;
    }
    public double rnddouble(ulong a, ulong b, ulong c, ulong d)
    {
        return (double)(rndlong(a, b, c, d) >> 11) * shift53;
    }
}
class-Prng
{
常数双移位3=.125;
常数双移位9=shift3*shift3*shift3;
常数双移位27=移位9*移位9*移位9;
常数双移位53=移位27*移位27*2.0;
公共区域(区域a、区域b、区域c、区域d){
乌隆e=((a^(b>>14|b>31|c>18|d>30|a>32|b>50|d>49|a>33|d>48|c>17|a>47|b>15|c>21|g>44|h>20|e>41|f>42|g>43|e>22|f>23|T53);
}
}

“特别重要的是允许任意输入。”-你可以散列任何值,并使用该散列作为种子。我刚刚得出了相同的结论,即构造输入的字节数组并生成该值的散列。如果你要从字节数组生成散列,你可能需要考虑负零和浮点精度。看起来4D或5D柏林或单纯形噪声可以做到这一点但是x,y,z和w的用途是什么?你期望噪声是沿着这四个维度的连续函数吗?听起来你好像不知道如何描述你要寻找的噪声的特性,所以也许你应该给出更多关于你到底需要它做什么的细节。@stslavik实际上是一个PRNG i这正是我想要的,但是在谷歌搜索失败之后,我找不到任何需要任意数量输入的东西,所以我想我必须自己做。另一个区别当然是它必须是不变的——也就是说,我找到了许多发电机,但它们都是为了在连续运行时改变输出而设计的。我想要它在给定相同的输入集的情况下,每次都要生成相同的输出。我并不是说下面的解决方案是完美的,但有时你只需要运行一些东西,直到有人给你指出更好的方向。每秒超过一百万个值实际上是相当慢的。还要记住,
-long.MinValue
溢出到
long、 MinValue
,如果您想将结果限制为正有符号整数,您可以执行
n=n&long。MaxValue
@eBusiness感谢您提供的提示,我将相应地修改模式代码。鉴于您对速度的评论,您建议我应该怎么做?摆脱杂音,对于大数据块,它可能会很快,但您是sti我将为初始化付出沉重的代价。而且,我不确定你认为这将如何使用浮点作为输入,如果你想要决定论,你必须远离浮点,除非你真的知道你想要什么