堇酸盐的C#随机性是线性的
我的代码是在一个范围内生成lat和long的随机坐标:堇酸盐的C#随机性是线性的,c#,C#,我的代码是在一个范围内生成lat和long的随机坐标: Random lastLat = new Random(); Random lastLon = new Random(); for (int i = 0; i < 50; i++) { int lat = lastLat.Next(516400146, 630304598); //18.51640014679267 - 18.630304598
Random lastLat = new Random();
Random lastLon = new Random();
for (int i = 0; i < 50; i++)
{
int lat = lastLat.Next(516400146, 630304598); //18.51640014679267 - 18.630304598192915
int lon = lastLon.Next(224464416, 341194152); //-72.34119415283203 - -72.2244644165039
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(Convert.ToDouble("18." + lat), Convert.ToDouble("-72." + lon));
AddPushpin(d0);
}
Random lastLat=new Random();
Random lastLon=新的Random();
对于(int i=0;i<50;i++)
{
int lat=lastLat.Next(51640014630304598);/18.516400146792267-18.63034598192915
int lon=lastLon.Next(224464416341194152);/-72.34119415283203--72.2244644165039
SamplePostData d0=新SamplePostData();
d0.Location=新位置(Convert.ToDouble(“18.”+lat),Convert.ToDouble(“72.”+lon));
添加图钉(d0);
}
我的输出如下所示:
“我的数字”的生成方式是否有问题?您正在初始化两个
随机
实例,但没有显式种子,导致它们返回相同的伪随机数流。您现在所做的相当于使用DateTime.now
作为这两个实例的种子。由于现代计算机往往执行代码的速度非常快,因此在这两种情况下都会得到相同的种子
如果您使用单个
Random
实例来生成lang和long,您应该会看到更“随机”的分布。您不应该使用两个不同的Random
对象。从同一个Random
中同时绘制纬度和经度
Random random = new Random();
for (int i = 0; i < 50; i++)
{
int lat = random.Next(516400146, 630304598); //18.51640014679267 - 18.630304598192915
int lon = random.Next(224464416, 341194152); //-72.34119415283203 - -72.2244644165039
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(Convert.ToDouble("18." + lat), Convert.ToDouble("-72." + lon));
AddPushpin(d0);
}
Random Random=new Random();
对于(int i=0;i<50;i++)
{
int-lat=random.Next(51640014630304598);/18.516400146792267-18.63034598192915
int lon=random.Next(224464416341194152);/-72.34119415283203--72.2244644165039
SamplePostData d0=新SamplePostData();
d0.Location=新位置(Convert.ToDouble(“18.”+lat),Convert.ToDouble(“72.”+lon));
添加图钉(d0);
}
Jørn的回答给出了问题,但没有给出解决方案:只需使用一个Random
的实例:
Random rng = new Random();
for (int i = 0; i < 50; i++)
{
int lat = rng.Next(516400146, 630304598);
int lon = rng.Next(224464416, 341194152);
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(18d + lat / 1000000000d,
-72d - lon / 1000000000d);
AddPushpin(d0);
}
Random rng=new Random();
对于(int i=0;i<50;i++)
{
int lat=rng Next(51640014630304598);
int lon=rng Next(224464416、341194152);
SamplePostData d0=新SamplePostData();
d0.位置=新位置(18d+lat/1000000000d,
-72d-lon/1000000000d);
添加图钉(d0);
}
(我也改变了使用结果的方式-不需要通过转换字符串来实现所需的结果。另一种方法是调用Random。NextDouble
,将其乘以所需范围的大小,然后添加一个基值。)
如果您多次调用例程,您可能应该在这些多个调用中使用一个Random
实例。但是要小心:Random
在.NET中不是线程安全的。理想情况下,每个线程应该有一个实例。有关如何处理Random
的更多详细信息,请参见my。您的问题是,您同时创建了两个随机对象,导致它们使用几乎相同的时间种子进行种子设定
Random random = new Random();
for (int i = 0; i < 50; i++)
{
int lat = random.Next(516400146, 630304598); //18.51640014679267 - 18.630304598192915
int lon = random.Next(224464416, 341194152); //-72.34119415283203 - -72.2244644165039
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(Convert.ToDouble("18." + lat), Convert.ToDouble("-72." + lon));
AddPushpin(d0);
}
只使用一个对象。@Shawn Mclean:您认为在执行第1行和第2行之间的当前时间有多大变化?默认情况下,Random()是以时间为种子的。问题是这两个对象是用相同的时间种子初始化的。@Foxfire:不要混淆计时计数器的精度和准确性。蜱虫的出现并不意味着它们是可见的。尝试用对环境的连续调用填充列表。TickCount
,然后打印出来。。。你会看到很多重复的值。@Foxfire:阅读Eric Lippert的这篇文章:这是有效的,但我仍然不明白为什么一个随机对象可以完美地工作,而不是两个。随机数生成器只是特定数学计算的一系列输出。如果用相同的值初始化随机数生成器,它将始终生成相同的输出。在您的情况下,您的计算机似乎足够快,可以用相同的值初始化两个随机实例,因此每次并行调用它们时,它们都会产生相同的输出值。当使用Next函数时,您总是会得到该计算的下一个值,这就是为什么只使用一个函数有效。您可以使用以下函数作为种子:(int)DateTime.Now.Ticks&0x0000FFFF@JonSkeet这是一个很好的问题,但32767是一个很好的种子,它会给你足够的变异,所以你不会得到相似的坐标。@Oakcool:我不同意。您的代码实际上比只调用new Random()
更糟糕,因为它使用了当前时间的更多位。答案是不要在程序中多次使用当前时间。我有一篇关于这方面的文章,我将链接到答案。两个随机数都是在一个滴答(100纳秒)内创建的,所以从同一个种子开始。因此,在调用Next()时,它们将产生完全相同的值,从而产生您在那里看到的可爱的y=-x行。