C# 多个随机数相同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14673876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple random numbers are the same
提问by Nejc Ucman
Possible Duplicate:
Random number generator only generating one random number
可能重复:
随机数生成器只生成一个随机数
A beginner question. I have a very simple program that draws a line and I want to randomize the locations, but each time I create a new instance of Random it returns the same value. Where is the problem? Thank you.
一个初学者的问题。我有一个非常简单的画一条线的程序,我想随机化位置,但是每次我创建一个新的 Random 实例时,它都会返回相同的值。问题出在哪儿?谢谢你。
private void Draw()
{
Random random1 = new Random();
int randomNumber1 = random1.Next(0, 300);
Random random2 = new Random();
int randomNumber2 = random2.Next(0, 300);
Random random3 = new Random();
int randomNumber3 = random3.Next(0, 300);
Random random4 = new Random();
int randomNumber4 = random4.Next(0, 300);
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(randomNumber1, randomNumber2),
new Point(randomNumber3, randomNumber4));
}
private void btndraw1_Click(object sender, EventArgs e)
{
Draw();
}
采纳答案by Blachshma
The reason this happens is that every time you do a new Random
it is initialized using the clock. So in a tight loop (or many calls one after the other) you get the same value lots of times since all those random variables are initialized with the same seed.
发生这种情况的原因是每次执行新操作Random
时都会使用时钟对其进行初始化。所以在一个紧密的循环中(或者一个接一个的多次调用)你会多次得到相同的值,因为所有这些随机变量都是用相同的种子初始化的。
To solve this: Create only one Random variable, preferably outside your function and use only that one instance.
解决这个问题:只创建一个 Random 变量,最好在你的函数之外,并且只使用那个实例。
Random random1 = new Random();
private void Draw()
{
int randomNumber1 = random1.Next(0, 300);
int randomNumber2 = random1.Next(0, 300);
int randomNumber3 = random1.Next(0, 300);
int randomNumber4 = random1.Next(0, 300);
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(randomNumber1, randomNumber2), new Point(randomNumber3, randomNumber4));
}
回答by Shadow Wizard is Ear For You
Simply use the same instance:
只需使用相同的实例:
Random random = new Random();
int randomNumber1 = random.Next(0, 300);
int randomNumber2 = random.Next(0, 300);
//...
Random numbers in programming are not really random; they are based on some unique seedthat is taken and manipulated to generate what appears to be set of random numbers. Using the same seed will result in same set of numbers.
编程中的随机数并不是真正的随机数;它们基于一些独特的种子,这些种子被获取和操纵以生成似乎是一组随机数的东西。使用相同的种子将产生相同的一组数字。
The default constructor of the Random
class is using the number of milliseconds elapsed since the system started as the seed, so what actually happened is the same seed was used.
Random
该类的默认构造函数使用自系统启动以来经过的毫秒数作为种子,因此实际发生的是使用相同的种子。
There is really no reason to create more than once Random
instance; the single instance will generate random set of numbers on each execution of the code.
真的没有理由创建多次Random
实例;单个实例将在每次执行代码时生成一组随机数字。
To prove my above statement of default seed, I used reflection:
为了证明我的上述默认种子声明,我使用了反射:
// System.Random
/// <summary>Initializes a new instance of the <see cref="T:System.Random" /> class, using a time-dependent default seed value.</summary>
public Random() : this(Environment.TickCount)
{
}
And the Environment.TickCount
:
和Environment.TickCount
:
// System.Environment
/// <summary>Gets the number of milliseconds elapsed since the system started.</summary>
/// <returns>A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started.</returns>
/// <filterpriority>1</filterpriority>
public static extern int TickCount
{
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
回答by alu
You only need one instance of the Random class.
您只需要 Random 类的一个实例。
private void Draw()
{
Random random1 = new Random();
int randomNumber1 = random1.Next(0, 300);
int randomNumber2 = random1.Next(0, 300);
int randomNumber3 = random1.Next(0, 300);
int randomNumber4 = random1.Next(0, 300);
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(randomNumber1, randomNumber2), new Point(randomNumber3, randomNumber4));
}
private void btndraw1_Click(object sender, EventArgs e)
{
Draw();
}
回答by Parimal Raj
private static readonly Random Random1 = new Random();
private void Draw()
{
int randomNumber1 = Random1.Next(0, 300);
int randomNumber2 = Random1.Next(0, 300);
int randomNumber3 = Random1.Next(0, 300);
int randomNumber4 = Random1.Next(0, 300);
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(randomNumber1, randomNumber2), new Point(randomNumber3, randomNumber4));
}
private void btndraw1_Click(object sender, EventArgs e)
{
Draw();
}
回答by Adi Lester
You shouldn't create a new Random
object for each number. Instead, use the same object:
您不应该Random
为每个数字创建一个新对象。相反,使用相同的对象:
Random r = new Random();
private void Draw()
{
// Create 4 random numbers
int[] numbers = Enumerable.Range(0, 4).Select(x => r.Next(0, 300)).ToArray();
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(numbers[0], numbers[1]),
new Point(numbers[2], numbers[3]));
}
回答by Nikshep
What random class of .Net needs is a seed value you can use a date value as a seed and it would work.
.Net 的随机类别需要一个种子值,您可以使用日期值作为种子,它会起作用。
private void Draw()
{
Random random1 = new Random(unchecked((int)DateTime.Now.Ticks << (int)100));
int randomNumber1 = random1.Next(0, 300);
Random random2 = new Random(unchecked((int)DateTime.Now.Ticks << (int)200));
int randomNumber2 = random2.Next(0, 300);
Random random3 = new Random(unchecked((int)DateTime.Now.Ticks << (int)300));
int randomNumber3 = random3.Next(0, 300);
Random random4 = new Random(unchecked((int)DateTime.Now.Ticks << (int)400));
int randomNumber4 = random4.Next(0, 300);
System.Drawing.Graphics g = this.CreateGraphics();
Pen green = new Pen(Color.Green, 5);
g.DrawLine(green, new Point(randomNumber1, randomNumber2), new Point(randomNumber3, randomNumber4));
}
private void btndraw1_Click(object sender, EventArgs e)
{
Draw();
}
回答by Nolonar
A random number generator (RNG) does not actually generate random numbers. Instead, it uses an algorithm to define a sequence of numbers, that appear to be random. This sequence depends on the seed
that is run through said algorithm at the time you RNG is created.
随机数生成器 (RNG) 实际上不会生成随机数。相反,它使用一种算法来定义一系列看似随机的数字。此序列取决于在seed
创建 RNG 时通过所述算法运行的序列。
By default, RNGs are created using the system's clock as a seed, since the clock will usually vary every time the program is run, making it extremely difficult to predict the "random" sequence.
默认情况下,RNG 是使用系统时钟作为种子创建的,因为时钟通常会在每次程序运行时发生变化,因此很难预测“随机”序列。
In your case, it is very likely, that the clock didn't change between creating a random object and another; possibly due to CPU-internal re-ordering of instructions.
在您的情况下,很可能时钟在创建随机对象和另一个对象之间没有变化;可能是由于 CPU 内部对指令的重新排序。
As Blachshma states, it is best to create only a single random object and use only that.
正如 Blachshma 所说,最好只创建一个随机对象并只使用它。
public static Random MyRNG = new Random(); // create a single static random object, that you can use across all classes
private void Draw()
{
randomNumber1 = MyRNG.Next(0, 300);
randomNumber2 = MyRNG.Next(0, 300);
// and so forth
}
Keep in mind that any instance of System.Random
are not guaranteed to be thread-safe, meaning that if you plan on having multiple threads share the same random object, you mustlock it.
请记住,System.Random
不能保证 的任何实例都是线程安全的,这意味着如果您计划让多个线程共享同一个随机对象,则必须锁定它。
lock (MyRNG)
{
randomNumber = MyRNG.Next(0, 300);
}
Failure to do so might break your random object, leading to consequent calls returning only 0 as a result.
不这样做可能会破坏您的随机对象,从而导致随后的调用结果仅返回 0。