Compile-time vs. Run-time, in Java and C# - c#

I have read somewhere one of the main differences between Java and C++/C# is Java does something at Run-time and C# does something at compile-time. Is this true? If so could you explain this a bit more?
In C#, I created a function which takes in two inputs and returns a random number (called RandomNumber(int x, int y)), using the Random Object. I then called this function twice in another function, expecting to get two difference values (two different random numbers). However, I kept getting same values, which baffled me, since I can do the same thing in Java and expect to get different numbers.
I then decided, to remove my function - RandomNumber(int x, int y) and call the Random inside my other function, show below.
Random random = new Random();
int randomNum;
int la;
randomNum = random.Next(1, 10);
numOne.Text = randomNum.ToString();
la = random.Next(1, 10);
This generates two different random numbers. Why is this the case?

The random number issue has nothing to do with compile-time or run-time. It has everything to do with where the Random class is instantiated.
The Random class doesn't really generate true random numbers. They are generated based on a mathematical formula that includes the current date/time and several other bits of data.
The following:
Random r = new Random(100)
for(int i = 0; i < 100; i++)
{
Console.WriteLine(r.Netc().ToString());
}
will generate a series of numbers that looks random.
This:
for(int i = 0; i < 100; i++)
{
Random r = new Random(100);
Console.WriteLine(r.Next().ToString());
}
will produce the same numbers for a few loops, then a new series of similar numbers for a few loops.
This is because of the formula. In the second example, each Random class is being created with very similar conditions, and will therefore produce the same number until the time changes enough to change the outcome.
However, with the first example, there is only one Random class and in subsequent iterations of the loop, it knows to produce a different number, because it knows it just generated one in the last loop.
If your code is calling a function that declared a new Random object and then uses Random.Next then in the scope of your function, Random is a new object on each call. Therefore, if your calls are within a few milliseconds, you'll get the same result.

Related

What exactly does the parameter seed in MLContext do? [duplicate]

This is my code to generate random numbers using a seed as an argument:
double randomGenerator(long seed) {
Random generator = new Random(seed);
double num = generator.nextDouble() * (0.5);
return num;
}
Every time I give a seed and try to generate 100 numbers, they all are the same.
How can I fix this?
If you're giving the same seed, that's normal. That's an important feature allowing tests.
Check this to understand pseudo random generation and seeds:
Pseudorandom number generator
A pseudorandom number generator (PRNG), also known as a deterministic
random bit generator DRBG, is an algorithm for generating a sequence
of numbers that approximates the properties of random numbers. The
sequence is not truly random in that it is completely determined by
a relatively small set of initial values, called the PRNG's state,
which includes a truly random seed.
If you want to have different sequences (the usual case when not tuning or debugging the algorithm), you should call the zero argument constructor which uses the nanoTime to try to get a different seed every time. This Random instance should of course be kept outside of your method.
Your code should probably be like this:
private Random generator = new Random();
double randomGenerator() {
return generator.nextDouble()*0.5;
}
The easy way is to use:
Random rand = new Random(System.currentTimeMillis());
This is the best way to generate Random numbers.
You shouldn't be creating a new Random in method scope. Make it a class member:
public class Foo {
private Random random
public Foo() {
this(System.currentTimeMillis());
}
public Foo(long seed) {
this.random = new Random(seed);
}
public synchronized double getNext() {
return generator.nextDouble();
}
}
This is only an example. I don't think wrapping Random this way adds any value. Put it in a class of yours that is using it.
That's the principle of a Pseudo-RNG. The numbers are not really random. They are generated using a deterministic algorithm, but depending on the seed, the sequence of generated numbers vary. Since you always use the same seed, you always get the same sequence.
Problem is that you seed the random generator again. Every time you seed it the initial state of the random number generator gets reset and the first random number you generate will be the first random number after the initial state
If you'd want to generate multiple numbers using one seed you can do something like this:
public double[] GenerateNumbers(long seed, int amount) {
double[] randomList = new double[amount];
for (int i=0;i<amount;i++) {
Random generator = new Random(seed);
randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000);
seed--;
}
return randomList;
}
It will display the same list if you use the same seed.
Several of the examples here create a new Random instance, but this is unnecessary. There is also no reason to use synchronized as one solution does. Instead, take advantage of the methods on the ThreadLocalRandom class:
double randomGenerator() {
return ThreadLocalRandom.current().nextDouble(0.5);
}

Why doesn't this create a "true" random number? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Random number generator only generating one random number
Im trying to create a loop to create and output 5 random numbers in a listbox. Basically it outputs the same random number 5 times instead of 5 different ones. When I use a break point and go through the code it does actually generate the 5 numbers. So why does it only output the first answer? Thank you. (This is not the entirety of the project, but I need to get this working first).
public string Numbertext1;
public string Numbertext2;
public int GeneratedNumbers;
public int Average = 0;
public int TotalSum = 0;
public int TotalCalcs = 0;
public int Counter = 0;
private void btnRandomise_Click(object sender, EventArgs e)
{
Numbertext1 = txtNum1.Text;
int Number1;
int.TryParse(Numbertext1, out Number1);
Numbertext2 = txtNum2.Text;
int Number2;
int.TryParse(Numbertext2, out Number2);
do
{
Random num = new Random();
int number = num.Next(Number1, Number2);
lbNumbers.Items.Add(Convert.ToString(number));
Counter++;
}
while (Counter < 5);
{
TotalCalcs++;
Counter = 0;
}
}
}
}
You need to initialize your num variable at the global level. It's using the same seed over and over again.
Put this : Random num = new Random(); at the top where you are initializing everything else. Then remove it from inside your method.
It's because you're creating a new Random instance within a tight loop, so the seed number will be the same. The Random class is not truly random (in the mathematical sense), so you should change the seed or use one instance of it. Move Random num = new Random(); to the top with the other variables.
Because you didn't adequately seed the random number generator.
The generator has an algorithmn it follows, if you just create it without seeding it then your numbers will be the same each time. To quote from MSDN:
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.
To fix this use the other constructor which allows you to specify a seed - there is a good example of this on MSDN.
The Random class instantiation is time-dependent. With a very quick loop, you're creating the same object every time and thus you're getting the same value over and over. You need to move the instantiation outside the loop so you get new numbers when you call Next() .
This is also the reason why it "works" when you use a break point to check the values. The Random object you created will have different reference times and thus would be different.

same random values [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Random number generator not working the way I had planned (C#)
Why does it appear that my random number generator isn't random in C#?
I have a problem with random values
int weight = 0;
Random random = new Random();
for (int i = 0; i < entriesCount; i++)
{
weight = random.Next(10);
this.weights[i] = weight;
}
This code is in constructor of my object. I create 3 diffrent objects
Object object1 = new Object(2);
Object object2 = new Object(2);
Object object3 = new Object(2);
For every object I get same random values for example: 4, 5 | 4, 5 | 4, 5
Every time I get same values in same sequence. I don`t get why> Please help
Best regards,
Dawid
The problem is that you're creating a new Random each time. When you create an instance of the Random class, it uses the current time as a seed. If you do this multiple times very quickly, you get the same seed value, so the different Random instances output the same results.
In order to work around this, you need to either make sure your random is seeded uniquely each time, or share and use a single Random instance. The easiest option is to just make the Random instance static:
class YourClass
{
private static Random randomGenerator = new Random();
public YourClass(int entriesCount)
{
int weight = 0;
for (int i = 0; i < entriesCount; i++)
{
weight = randomGenerator.Next(10);
this.weights[i] = weight;
}
}
// .. rest of your class
This will cause the class to always reuse the same Random instance, so you'll get different values each time.
Note that if you're going to be using this in a multithreaded scenario, you'll also have to synchronize access to the random instance, or come up with a different approach (such as saving a seed value, and using something like Interlocked.Increment to increment it and seed a new random from each instance, etc).
Random is a pseudorandom number generator, which means the sequence of outputs is the same for any given seed. If you pass a seed to the constructor, you get a different sequence.
As far as I am aware, a random is seeded by the system time unless you specify otherwise. It generates numbers based on this number. As you create them almost exactly at the same time, they have the same seed and will almost always return the same number and sequence.
Any easy fix would be to create a static random all instances share, and just call .Next() on that static object.
From the MSDN documentation:
"using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers."

C# Random codes - Is most of it simply wrong?

I had a lot of issues with randomizing lists. I am talking about a list of 200 elements, where I want to shuffle the list. Don't get me wrong, I read a lot of examples, and on first glance there are pretty nice things, like this:
Randomize a List<T>
But in my experience, at least on a fast machine, this is basically worthless. The shuffling works so fast that there is NOT a MS delay between two calls to Random.NEXT() which results in not nearly random behaviour.
I am NOT talking about super secure stuff, just a basic game random. I know I can add a delay of 1 MS, but this means "wasting" 200 MS just to randomize a list.
Now I found this approach: http://www.codinghorror.com/blog/2007/12/shuffling.html
It looks nice, using GUIDs to sort. BUT aren't they created the same way? Lets step it up a notch, lets assume I want to create 1000 numbers, between 0 - 5. This code is basically useless:
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(new Random().Next(5));
}
var resultB = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultB.Add(new Random().Next(5));
Thread.Sleep(1);
}
A does not work at all, at least not im my environment in Windows Phone 7. B is fine, but it takes a second, which is also stupid. Any comments or thoughts, it can't be that hard to create a random list of integers :-)
Don't keep initializing a new instance of Random; make just one and continually reference it.
var random = new Random();
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(random.Next(5));
}
You are correct that repeatedly creating new instances of Random within the same "timestamp" will result in the same seed; but calling .Next on an instance of Random "advances" the seed so that the next number you retrieve is (most likely) different.
This is also covered in the documentation on Random:
... because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.
...
This problem can be avoided by creating a single Random object rather than multiple ones.
You need to keep hold of the same instance of Random.
var random = new Random();
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(random.Next(5));
}
var resultB = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultB.Add(random.Next(5));
Thread.Sleep(1);
}
This is because when Random initializes it uses the system clock to get a point in time. When you call next it can use the difference in time to get the next number. If you keep initializing a Random object you will keep getting the same number most of the time.
The shuffling works so fast that there is NOT a MS delay between two calls to Random.NEXT() which results in not nearly random behaviour.
What makes you think that there needs to be a ms delay between two calls to Random.Next?
Your bog standard random number generator is going to take some initial seed (say the system clock) and then repeatedly some algorithm to that seed to produce a sequence of numbers that appears to be random. Most of these algorithms don't take the clock as an input other than for the seed and so it doesn't matter how quickly two consecutive calls are executed.
The reason your code fails is because you keep instantiating a new random number generator on each iteration. This is where the clock can kill you because you end up with the same seed twice. You are not calling Random.Next consecutively on the same random number generator. You are calling Random.Next on a new random number generator on every iteration and sometimes these random number generators are seeded with the same value because you are seeding them by the system clock.
Move the instantiation of the random number generator outside of your loop.
var resultA = new List<int>();
Random rg = new Random();
for (int i = 0; i < 1000; i++) {
resultA.Add(rg.Next(5));
}

Correct method of a "static" Random.Next in C#?

Why do i need to create an instance of Random class, if i want to create a random number between 1 and 100 ....like
Random rand = new Random();
rand.Next(1,100);
Is there any static function of Random class to do the same? like...
Random.Next(1,100);
I don't want to create an instance unnecessarily
It is best practice to create a single instance of Random and use it throughout your program - otherwise the results may not be as random. This behavior is encouraged by not creating a static function.
You shouldn't worry about "creating an instance unnecessarily", the impact is negligible at best - this is the way the framework works.
//Function to get random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}
Copied directly from
It's not "unnecessary", because the Random class stores some state internally. It does that to make sure that if you call .Next() multiple times very quickly (in the same millisecond or tick or whatever) you still won't get the same number.
Of course, if that's not a problem in your case you can always combine those two lines of code into one:
new Random().Next(1, 100);
You already got answers here. Just reiterating the right solution:
namespace mySpace
{
public static class Util
{
private static Random rnd = new Random();
public static int GetRandom()
{
return rnd.Next();
}
}
}
So you can call:
var i = Util.GetRandom();
all throughout. If you strictly need a true stateless static method to generate random numbers, you can rely on a Guid.
public static class Util
{
public static int GetRandom()
{
return Guid.NewGuid().GetHashCode();
}
}
It's going to be a wee bit slower, but can be much more random than Random.Next, at least from my experience.
But not:
new Random(Guid.NewGuid().GetHashCode()).Next();
The unnecessary object creation is going to make it slower especially under a loop.
And never:
new Random().Next();
Not only its slower (inside a loop), it's randomness is... well not really good according to me..
From MSDN: Random Class (System):
"The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. The following example illustrates that two Random objects that are instantiated in close succession generate an identical series of random numbers..."
Wikipedia explains PRNGs
The best way to do it is to have a ThreadStatic Random instance:
[ThreadStatic] static Random random;
Random Get() {
if (random == null) random = new Random(Guid.NewGuid().GetHashCode());
return random;
}
This takes care of everything.
Thread safety
Performance
No need to seed
It eludes me why the .NET Framework (and any other framework on earth) does not use something in this spirit.
Creating a new instance of Random then calling it immediately multiple times, e.g.:
for (int i = 0; i < 1000; i++)
{
Random rand = new Random();
Console.WriteLine(rand.Next(1,100));
}
Will give you a distribution that is weighted towards the lower end of the range.
Doing it this way:
Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
Console.WriteLine(rand.Next(1,100));
}
Will give you a better distribution.
Why not?
You need to create an instance because the way random numbers are generated is that previous answers affect subsequent answers. By default, the new Random() constructor uses the current system time to "seed" the sequence, but it doesn't have to: you can pass your own number in if you like. In particular:
var rand = new Random(1234);
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Will produce the same sequence of "random" number every time.
That means the Random class needs to keep instance data (the previous answer, or "seed") around for subsequent calls.
Creating a short-lived instance in C# is almost free. Don't waste your time worrying about this. You probably have better places to look for perf or memory gains.
Random number generators must maintain state in order to be "random." The random number generator creates a sequence that is generated based on a random seed. The problem is that nothing in a computer is actually random. The closest thing the computer has at hand is the system clock; that is the effectively the time at which the process takes place. So by default the current tick count of the system clock is used. If your application is fast enough then many random number calculations may occur under the same system tick. If the random number generator doesn't maintain state at all, it will provide the same random number multiple times (same input gives the same output). This is not usually what you want.
I know its already answered, but I just have to say that I prefer to use the singleton pattern in this case.
You need something similar to this if you want the syntax you mention.
namespace MyRandom
{
public class Random
{
private static m_rand = new Random();
public static Next(int min, int max)
{
return m_rand.Next(min, max);
}
}
}
This should allow you to do Random.Next(1,100); without having to worry about seeding.

Categories

Resources