Random.Next没有返回随机数

7

您好
这是我如何使用随机函数的,但它总是将“1”索引分配给indexOfAChosenListCell.
当我进行调试时,它会显示不同的值,但在常规运行中每次都得到相同的移动..
Random函数有什么问题,它是静态的而不是随机的... :)

internal Square getAutomaticMove()                      
{
            List<Square> LegalMovesArray = GetLegalSquares();
            Random randomListCell = new Random();
            int indexOfAChosenListCell = 0;

            if (CheckForLegalSquares())    
            {
                 indexOfAChosenListCell = randomListCell.Next(LegalMovesArray.Count-1);
            }

2
提示:LegalMovesArray.Count-1的值是多少?另外,将Random的构建移到getAutomaticMove()之外。 - Mitch Wheat
@Mitch:谢谢你的回答,但是LegalMovesArray.Count-1有什么问题吗?我想在LegalMovesArray中抛出一个索引,但它没有一个等于LegalMovesArray.Count的索引... - Mulder
8个回答

21

randomListCell作为实例变量,仅初始化一次 - 否则你将继续得到相同的数字。

根据MSDN

默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值,而其参数化构造函数可以采用基于当前时间中的滴答数的Int32值。然而,由于时钟具有有限的分辨率,因此在紧密相继地使用无参数构造函数创建不同的Random对象会创建产生相同随机数序列的随机数生成器。


5

Random.Next(Int32)

返回小于指定最大值的非负随机数

因此,您可能得到的最大数字是 Count - 2,这可能不是您想要的。


我想要一个从0到数组大小-1的数字,这意味着最后一个单元。 - Mulder
@Mulder:那么您需要调用 randomListCell.Next(array.Length),因为随机数生成器已经排除了您传递的值,无需再减去1。 - Ben Voigt

4
我建议也要种下伪随机数生成器。据我理解,每次运行应用程序都会得到相同的伪随机数序列。我可能错了。
int Seed = (int)DateTime.Now.Ticks;
Random randomListCell = new Random(Seed);

9
完全没有区别 - 这就是默认构造函数new Random()内部执行的操作。关键是只初始化randomListCell一次,然后在此实例上调用Next()方法。 - BrokenGlass
@BrokenGlass:我同意他应该创建一个实例变量,你的回答是正确的。 我不知道默认构造函数会自动执行此操作。 在我的经验中,我必须进行种子设置。 难道这不是为什么有一个带有种子参数的构造函数吗? 我只是在增加对话内容。 - Anx
2
“Random” 创建一系列伪随机数 - 对于相同的种子,该序列始终相同 - 因此,如果您想要重现之前使用过的序列,则通常会传递一个种子。 - BrokenGlass
@Anx+@Mulder:请阅读:msdn.microsoft.com/en-us/library/h343ddh9.aspx。它写了关于默认构造函数(你在问题中使用的那个):“使用一个基于时间的默认种子值初始化 Random 类的新实例。”。所以 new Random()new Random(seed) 是一样的。请解释这是如何不同的答案?请告诉我们这个答案怎么能被接受为正确的? - Martin Mulder
1
即使采用这种方法,如果您尝试连续创建多个随机数,仍然会得到相同的数字。 - Anthony Gatlin

4

将Random声明为私有成员变量,然后在构造函数中实例化它,在您的方法中只调用Random.Next。


3

您应该在函数外创建随机数

Random randomListCell = new Random();

internal Square getAutomaticMove()                      
{
            List<Square> LegalMovesArray = GetLegalSquares();
            int indexOfAChosenListCell = 0;

            if (CheckForLegalSquares())    
            {
                 indexOfAChosenListCell = randomListCell.Next(LegalMovesArray.Count-1);
            }

3
不要每次需要新的数字时都创建一个新的随机数生成器;如果您想要一系列不同的随机数,您需要保留一个单独的随机数生成器,并反复请求新的随机数。

2
我会展示它们的不同之处:
var random = new Random();
var color = Color.FromArgb(200, random.Next(255), // 222
                                random.Next(255), // 33
                                random.Next(255)); // 147

结果: #DE2193

var color = Color.FromArgb(200, new Random().Next(255), // 153
                                new Random().Next(255), // 153
                                new Random().Next(255)); // 153

结果:#999999


0
在函数外声明Random对象,这样它就可以使用相同的对象来生成新的数字。每次创建新对象时都使用相同的种子,导致大多数情况下生成相同的数字...
static Random randomListCell = new Random();
internal Square getAutomaticMove()                      
{
            List<Square> LegalMovesArray = GetLegalSquares();

            int indexOfAChosenListCell = 0;

            if (CheckForLegalSquares())    
            {
                 indexOfAChosenListCell = randomListCell.Next(LegalMovesArray.Count-1);
            }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接