C#Random不像随机一样工作

时间:2012-07-24 00:36:14

标签: c# .net random

我有一个图表,每个节点有4个子节点。我写了一个算法来生成从开始节点到结束节点的随机路径。在每个节点,它选择一个随机的下一个节点。访问节点可以重新访问。

代码如下:

public List<Node> GetPath(Node begin, Node end)
{
    var nodes = new List<Node>();
    var node = begin;
    while (node != end)
    {
        nodes.Add(node);
        var next = node.Children[new Random().Next(4)];
        node = next;
    }

    nodes.Add(end);

    return nodes;
}

但有时,Random不能按预期工作。 “new Random()。Next(4)”继续生成0.因此,它总是第一个子节点被选择,并且一个非常长的重复序列,如node1-&gt; node2-&gt; node1-&gt; node2 ...是生成并最终发生内存不足异常。

有没有办法让Random类正常工作?

5 个答案:

答案 0 :(得分:12)

原因是因为Random是根据当前时间初始化的(计算机中没有真正的随机...只有伪随机)。 while循环迭代太快,系统时间没有记录变化。所以你要重新初始化一个以相同值开头的新Random对象。

尝试创建一个在整个方法中重复使用的Random对象:

public List<Node> GetPath(Node begin, Node end)
{
    var nodes = new List<Node>();
    var node = begin;

    Random r = new Random();
    while (node != end)
    {
        nodes.Add(node);
        var next = node.Children[r.Next(4)];
        node = next;
    }

    nodes.Add(end);

    return nodes;
}

答案 1 :(得分:5)

初始化外部循环的随机实例,例如:

public List<Node> GetPath(Node begin, Node end)
{
    var nodes = new List<Node>();
    var node = begin;

    var random = new Random();

    while (node != end)
    {
        nodes.Add(node);
        var next = node.Children[random.Next(4)];
        node = next;
    }

    nodes.Add(end);

    return nodes;
}

答案 2 :(得分:0)

您提到在多个线程中调用该方法。一个解决方案是每个线程有一个随机数generartor,由静态rng播种。

我还删除了常量4并将其更改为node.Children.Count

static Random seed = new Random();
[ThreadLocal] static Random rng;

public List<Node> GetPath(Node begin, Node end)
{
var nodes = new List<Node>();
var node = begin;

if (rng == null)
   rng = new Random(seed.Next());

while (node != end)
{
    nodes.Add(node);
    var next = node.Children[rng.Next(node.Children.Count)];
    node = next;
}

nodes.Add(end);

return nodes;
}

答案 3 :(得分:0)

这里有一些对你不利的事情。第一个是你每次要求一个时都期望一个不同的数字,但这不是这个类所做的,也不是随机的定义。所以,这个类实际上正常工作。

随机

的定义
  1. 制作,完成,发生或选择没有方法或有意识的决定:“100个家庭的随机样本”。
  2. 由每个项目管理或涉及平等机会。
  3. 现在,本课程尽力为每个选项提供平等的选择机会。因此,当您想到随机时,请确保您将该术语的定义置于上下文中。但是,请记住,此类不会像人类一样工作。

    现在,为了解决你经常得到零的事实,这有两个原因。首先,您将在每次迭代中创建一个new Random类。但更重要的是,你的范围太小,因为你期望它每次只在4个选项范围内给你一个不同的数字,并且因为它是伪随机的,就像MSDN表明你得到了经常回答同样的问题。

    我意识到你只给它4个选项的原因,但我认为你可能需要重新考虑你正在寻找的功能类型,因为它可能会减少挫折感。

答案 4 :(得分:0)

这是一篇关于C#中随机数的非常有趣的文章,问题与Stackoverflow上的问题完全相同:)

http://csharpindepth.com/Articles/Chapter12/Random.aspx