我的计划需要:
一个。生成一个由0到9的20个随机整数的数组。搜索数字7的第一个匹配项(如果有),并在数组中报告其位置。
湾重复计算1000次,对于数组中的每个位置,报告数组中第一次出现7次的次数
然而,每当我运行程序时,我都会得到奇怪的结果(每次都不同),例如:
有没有人知道我的程序有什么问题?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Week_6_Project_2
{
class Program
{
static int intArrayLength = 20;
static int[] resultsArray = new int[intArrayLength];
public static Array generateRandomArray() {
int[] randomNumberArray = new int[intArrayLength];
Random random = new Random();
int popcounter = 0;
while (popcounter < intArrayLength) {
randomNumberArray[popcounter] = random.Next(0, 10);
popcounter += 1;
}
return randomNumberArray;
}
public static void searchForSevens()
{
int counter = 0;
int[] randomArray = (int[])generateRandomArray();
while (counter < intArrayLength)
{
if (randomArray[counter] == 7)
{
resultsArray[counter] += 1;
counter = intArrayLength;
}
counter += 1;
}
}
static void Main()
{
int searchCounter = 0;
while (searchCounter < 1000)
{
searchForSevens();
searchCounter += 1;
}
int displayCounter = 0;
while (displayCounter < intArrayLength)
{
Console.WriteLine("Number of first occurrence of 7 at position {0} = {1}", displayCounter, resultsArray[displayCounter]);
displayCounter += 1;
}
Console.ReadLine();
}
}
}
答案 0 :(得分:6)
您的主要问题是每个searchForSevens()
测试只需要一小部分时间,而Random类使用时钟自动播种。然而,时钟具有有限的分辨率。结果是许多(有时是全部)随机序列都是相同的。最多只有2到3个不同的结果集。
这个单线程程序的简单修复是使用1个静态的Random实例。
答案 1 :(得分:3)
每次调用Random
方法时,您都会实例化generateRandomArray
的新实例。由于随机数生成器使用当前时间作为种子,同时实例化两个Random
个实例会导致生成相同的数字,这可以解释您的意外结果。
要解决您的问题,您应该只实例化一个Random
实例,将其存储在私有字段中,并在每次调用Next
方法时重复使用它。
答案 2 :(得分:0)
我不会回答,但会尝试对那些认为他们需要更多随机实例的人进行类比...
假设您需要用1-6中的随机数填充6张纸。问问自己:你需要6个骰子或一个来完成这项工作吗?如果你回答你需要不止一个骰子,那就问问自己:每次投掷不同的骰子而不是相同的骰子有多么不同或更随机?
我的意思是,如果你掷骰子,下一次掷骰子的机会将不会比任何其他数字更少。它违背了直觉,但它在数学上和统计上都是如此。
答案 3 :(得分:-1)
我假设的问题源于这样一个事实:Random()
使用当前时间作为种子。并且计算发生得如此之快,以至于每次调用new Random()
时,它都使用相同的时间。所以你得到相同的数字序列。
要解决这个问题,你只需要自己设置种子,每个周期都应该增加种子。
long base = DateTime.Now.TotalMilliseconds;
Random rand = new Random(base+searchCounter);
..类似的东西。
答案 4 :(得分:-2)
在原始代码中,您快速连续[broken example based on OP's original code]调用Random
方法,因此使用相同的数字播种该方法,从而产生重复的“随机”数字。创建静态成员将确保随机性,因为您只创建了它的单个实例。
尝试像这样创建random
的单个静态实例。 [static member example]。
static readonly Random Random = new Random();
基于此,以下是我将如何解决您的特定问题。
using System;
namespace Week_6_Project_2
{
class Program
{
// ******************************************
// THIS IS A SINGLE INSTANCE OF Random.
// read below as to why I'm seeding the instantiation of Random();
static readonly Random Random = new Random(Guid.NewGuid().GetHashCode());
// ******************************************
private const int IntArrayLength = 20;
static readonly int[] ResultsArray = new int[IntArrayLength];
public static Array GenerateRandomArray()
{
var randomNumberArray = new int[IntArrayLength];
var popcounter = 0;
while (popcounter < IntArrayLength)
{
randomNumberArray[popcounter] = Random.Next(0, 10);
popcounter += 1;
}
return randomNumberArray;
}
public static void SearchForSevens()
{
var counter = 0;
var randomArray = (int[])GenerateRandomArray();
while (counter < IntArrayLength)
{
if (randomArray[counter] == 7)
{
ResultsArray[counter] += 1;
counter = IntArrayLength;
}
counter += 1;
}
}
static void Main()
{
var searchCounter = 0;
while (searchCounter < 1000)
{
SearchForSevens();
searchCounter += 1;
}
var displayCounter = 0;
while (displayCounter < IntArrayLength)
{
Console.WriteLine("Number of first occurrence of 7 at position {0} = {1}", displayCounter, ResultsArray[displayCounter]);
displayCounter += 1;
}
Console.ReadLine();
}
}
}
进一步了解Random()
除了上面的答案,有时需要种子Random(int);
(我喜欢使用Guid的HashCode)来确保进一步的随机性。这是因为默认种子使用来自文档[microsoft]的时钟具有有限分辨率的时钟。如果您的类快速连续多次实例化(<16ms),您将从时钟中获得相同的种子...这会破坏内容。
[example of seeded Random(int)
run in rapid succession with random results]
“使用无参数构造函数以紧密连续的方式创建不同的随机对象,创建随机数生成器,生成相同的随机数序列。”
当我说你不应该在循环的每次迭代中实例化一个新的Random时听到我 - 使用静态成员
实现自己的种子的另一个有效理由是,当您想 重新创建 随机序列[example of two identical lists based on same seed]时。重复使用相同的种子将重新创建序列,因为序列基于种子。
注意:其他人可能会认为播种它是不必要的[link],但我个人认为,对于额外的几次按键和时钟上的微观命中,你可能会增加概率独特的种子。它不会伤害任何东西,在某些情况下它可以提供帮助。