7

I am having problem with random number generation in c#. If I RUN this form application directly, the random number generation is same for all.

If i DEBUG this line by line by pressing F10, then it will generate different random numbers. Why this is happening? What should I do to generate different random numbers?

Greyhound.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ADayAtTheRaces
{
    class Greyhound
    {
        int location=0;
        Random randomize = new Random();

        public int run()
        {
            location = randomize.Next(0, 100);
            return location;
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ADayAtTheRaces
{
    public partial class Form1 : Form
    {
        Greyhound[] greyHound = new Greyhound[4];
        ProgressBar[] progressBar = new ProgressBar[4];
        public Form1()
        {
            InitializeComponent();
            for (int i = 0; i < 4; i++)
            {
                greyHound[i] = new Greyhound();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i <= 3; i++)
            {
                progressBar[i].Value = greyHound[i].run();
            }
        }
    }
}
SHRI
  • 2,406
  • 6
  • 32
  • 48

8 Answers8

12

Don't instantiate a new Random object each time, instead use it as a static member:

class Greyhound
{
    static Random randomize = new Random();
    int location=0;

    public int run()
    {
        location = randomize.Next(0, 100);
        return location;
    }
}

See Random.Next returns always the same values

Community
  • 1
  • 1
ken2k
  • 48,145
  • 10
  • 116
  • 176
3

You are creating x amount of new Random at the same time.

what you should do is create new instance of Random and then inside foreach (or any loop) use instance.Next().

That should give you the unique values.

Hope it helps

Sebastian Siek
  • 2,045
  • 17
  • 16
2

your answer is here: Random Constructor

The distribution of the generated numbers is uniform; each number is equally likely to be returned.

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. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.

you create all those Random objects basically at the same time in the loop and all are initialized with same time dependent seed, try to create only one static object or specify the seed differently. in debug the waiting time of you moving line by line already makes the seed to be different.

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
2

Davide is quite right. In practical terms, this is how you would fix your code.

In Form1, create a new instance of Random:

Random rng = new Random();

and pass it in on the call to Greyhound.run() like this:

for (int i = 0; i <= 3; i++)
{
    progressBar[i].Value = greyHound[i].run(rng);
}

then inside Greyhound.cs, remove the line

Random randomize = new Random();

and change

public int run()

to

public int run(Random randomize)

This will make the different instances of your Greyhound class reuse the same instance of Random, thus solving the problem.

tomfanning
  • 9,552
  • 4
  • 50
  • 78
1

Try making randomize static. I guess the problem comes from the fact that the seed is time dependent.

rcaval
  • 762
  • 5
  • 12
1

The reason that you get the same random number for all is that you are creating a Random object for each instance. The random generator is seeded from the clock, so when you create random objects too close in time, they will all end up with the same seed, and produce the same random numbers.

When you debug the code the objects are created with a long time between them, so the random generators are seeded from different clock values.

Use a single random generator, and pass that into the constructor of the objects:

namespace ANightAtTheOpera {

  class Greyhound {
    int location=0;
    Random randomize;

    public Greyhound(Random rnd);
      randomize = rnd;
    }

    public int run() {
      location = randomize.Next(0, 100);
      return location;
    }
  }

}

initialise:

Random rnd = new Random();
for (int i = 0; i < 4; i++) {
  greyHound[i] = new Greyhound(rnd);
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

Everytime you are instantiating an instance of GreyHound you instantiate an instance of System.Random. The default constructor for System.Random uses System.Environment.TickCount as the seed for the random number generation. System.Environment.TickCount has a resolution of a millisecond and you are creating instances much faster than that. Perhaps make the System.Random instance youo are using static ... that will solve the problem.

MaLio
  • 2,498
  • 16
  • 23
0

This happens because debugging take few time and seed in Random changes. ill use that and it helps me

public static Random RD()
    {
        Guid GD = Guid.NewGuid();
        int realRandom = Math.Abs(GD.GetHashCode());
        Random _rd = new Random(realRandom);
        return _rd;
    } ......

void SomeFunc()
     {
       Random MyRand = RD();
     }