Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.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#随机数发生器_C#_Random - Fatal编程技术网

C#随机数发生器

C#随机数发生器,c#,random,C#,Random,我在寻找一个随机数,它总是为给定的种子生成相同的“随机”数。种子由x+(y)定义 我可以创建一个新的系统实例。每次使用我的种子都是随机的 那样做 但这是一个很大的GC压力,特别是因为它会被多次调用 你称它多少次了?它是否表现得很糟糕?注意,GC经过优化,可以处理很多生命周期短的小对象。它应该很容易处理这个问题 还有,有什么替代方案可以接受种子但不创建某个对象的新实例?事实上,这听起来像是一个设计糟糕的类。请参阅C#源代码。状态只是两个无符号整数,因此很容易在调用之间保持一致。而且生成器通过了标准

我在寻找一个随机数,它总是为给定的种子生成相同的“随机”数。种子由x+(y)定义 我可以创建一个新的系统实例。每次使用我的种子都是随机的

那样做

但这是一个很大的GC压力,特别是因为它会被多次调用

你称它多少次了?它是否表现得很糟糕?注意,GC经过优化,可以处理很多生命周期短的小对象。它应该很容易处理这个问题

还有,有什么替代方案可以接受种子但不创建某个对象的新实例?事实上,这听起来像是一个设计糟糕的类。

请参阅C#源代码。状态只是两个无符号整数,因此很容易在调用之间保持一致。而且生成器通过了标准的质量测试。

我不这么认为想象一个“随机数发生器”实际上就是您要查找的。只需创建另一个贴图并用随机值预先填充它。如果您当前的heightmap是W x H,最简单的解决方案是创建一个W x H 2D数组,然后使用System.random用随机值填充每个元素。然后,您可以查找特定(x,y)的预填充随机值需要时随时协调

或者,如果当前的heighmap实际上存储了某种数据结构,则可以修改该结构以存储除高度值之外的随机值

这样做的一个附带好处是,如果以后需要,您可以对整个“随机”地图执行操作,以确保它具有某些属性。例如,根据上下文(这是用于游戏的吗?)稍后你会发现,你想在地图上平滑随机性。如果你预先计算并存储了我所描述的值,这是微不足道的。

< P>因为A显然更接近你想要的,考虑下面的变化:

int Hash(int n) {
    const int prime = 1031;
    return (((n & 0xFFFF) * prime % 0xFFFF)) ^ (n >> 16);
}
在将最低有效的两个字节与素数相乘后,将最低有效的两个字节混洗一小位,然后将最低有效的两个字节与四字节数的最高有效的两个字节进行异或运算。因此,结果的范围为0<0x10000(即,它适合Int16)

这应该会对输入数字进行一点“洗牌”,可靠地为相同的输入生成相同的值,并且看起来是“随机的”。现在,我还没有对分布进行随机分析,如果有统计学家看到它,他可能会直接进入过敏性休克。(事实上,我已经把这个实现写下来了。)


如果您需要较少的半烘烤,请考虑使用已建立的校验和(例如).< /P> < P>存储“<代码>词典>代码> >如何提供新的<代码> Read < /Cord>对象对给定种子的第一个值?< /P>

class RandomSource
{
    Dictionary<int, int> _dictionary = new Dictionary<int, int>();

    public int GetValue(int seed)
    {
        int value;
        if (!_dictionary.TryGetValue(seed, out value))
        {
            value = _dictionary[seed] = new Random(seed).Next();
        }

        return value;
    }
}
类随机源
{
字典_Dictionary=新字典();
公共整数GetValue(整数种子)
{
int值;
if(!\u dictionary.TryGetValue(种子,输出值))
{
value=_dictionary[seed]=new Random(seed).Next();
}
返回值;
}
}
这会导致在您第一次需要特定种子的值时构造一个新的
Random
实例的GC压力,但是使用相同种子的每个后续调用都会检索一个缓存的值。

为多个随机数生成器提供源代码。您必须进行实验,看看这些对per的影响是否较小性能比系统随机

提供一个包含多个生成器的库。他们还讨论生成器的质量和速度,并和System.Random进行比较


最后,你所说的GC压力是什么意思?你真的是指内存压力,这是我见过的唯一一个使用它的上下文吗?GC的工作是非常有效地处理大量对象的创建和销毁。我担心你会受到过早优化的诱惑。也许你可以创建一个能够提供一些冷而硬的数字。

这不是很随机的,是吗?你会有多少种不同的组合?你可以将你的随机实例存储在以种子为键的字典中重复使用。正如你所指出的,
System.random
已经为给定的种子生成了相同的序列。你在寻找一个具有可变所以你可以简单地“重置”它?多少次是“很多”好几次了,你分析过这是否真的会导致GC性能差吗?@driis:这行不通,因为只要对其中一个实例调用
Next
,种子就会改变。没错,如果你只希望每个种子有一个值,而不是一个序列,那么它就不是真正的随机(甚至是伪随机)实际上,重读这个问题,我得到了一个明显的印象,这个问题试图重新创造哈希代码。另一个选择是一个对象,你可以直接传递一个种子值,而不需要构造函数。@Robert:是的,我包含了这个unter“糟糕的设计”“需要一个很好的理由来实现一个对象可重置而不是依赖于<代码>新的<代码>:可重置对象使它更难对状态进行推理。”康纳德:“我认为你总是使用不可变的对象。我们中的一些人仍然使用可变对象使用常规OOP编程,并且我们不认为它是坏的设计,特别是如果我们使用了可变对象。最好是一个简单的函数,比如int Random(int seed)@汉内什:不,那将是一件非常糟糕的事情,因为它显然总是返回相同的值——根本不是随机的。地图需要无限连续,如果我重新输入一个区域,musn不会改变。因为它需要无限连续,我需要一个(x,y)高度的函数.我已经解决了大部分问题,现在所需要的只是随机数。写这篇文章后,我开始感到失望