0

I am currently trying to make an evolutional neural network, and for that purpose I am at first giving the objects random values. This works af first but after a few iterations they start to behave in a very strange way. Sometimes when a new iteration starts they all move in the same pattern or with the same speed.

I've researched a bit and from what I read apparently Random can output the same numbers if used in a very short time span, but I have no clue how to prevent that/work around that. I am working with only one global instance of Random, all in one thread so the problem is not there.

private void Evolve()
    {
        var newNetObjects = new List<NeuralNetObject>(); // make a list for new objects we create replace old ones
        var netObjects =
            new List<NeuralNetObject>(NeuralNetObjectManager.NeuralNetObjects); //get all neuralnetobjects
        if (netObjects.Count == 0) //just stop when the list is empty
            return;
        //the half we remove is the one with the lower fitness values
        foreach (var netObject in netObjects) //go through all net objects and do crossover of weights
        {
            float[] newWeigths = (float[]) netObject.GetNet().Weights.Clone(); //get original weights
            ;
            var randomNet = rnd.Next(netObjects.Count); //random number
            float[] otherWeigths = (float[]) netObjects[randomNet].GetNet().Weights.Clone(); //get a random other net
            for (int i = 0; i < newWeigths.Length; i++) //for each weight
            {
                if (rnd.Next(2) == 1)
                {
                    newWeigths[i] = otherWeigths[i]; // 25% to get the weight of the other net
                }
            }

            var newNet = new NeuralNet(netObject.GetNet())
            {
                Weights = (float[]) newWeigths.Clone()
            }; // make a new neural net with the generated weigths

            newNetObjects.Add(new NeuralNetObject(100, 300, "KISTE", newNet)
            {
                Speed = (float) (rnd.NextDouble() - 0.5f) * 2, Direction = (float) (rnd.NextDouble() - 0.5f) * 2
            }); //add new object to list
        }
    }

So I might be missing something, but I thought what I coded should assign every instance at

newNetObjects.Add(new NeuralNetObject(100, 300, "KISTE", newNet)
            {
                Speed = (float) (rnd.NextDouble() - 0.5f) * 2, Direction = (float) (rnd.NextDouble() - 0.5f) * 2
            });

a random speed and direction, but as I said earlier, after a few iterations they all move with the same speed and sometimes even with the same pattern. Do you have any idea what my problem would be? If you need I can post more code, but what I posted is simplified and some stuff taken out so it's easier to read and understand. Thanks in advance!

Aaron H
  • 134
  • 10
  • does https://stackoverflow.com/a/22697508/1263884 help? – WiseStrawberry May 18 '19 at 14:26
  • This can happen when the Random method is called to quickly and the timer does not change that fast, when the seed is based on time. Easiest solution is to create a new Random object each time. – Markus Zeller May 18 '19 at 14:33
  • @WiseStrawberry The solution you sent me only works for Intel cpus, right? I'd prefer a universal solution, but it's interesting nonetheless! – Aaron H May 18 '19 at 14:36
  • @MarkusZeller But doesn't creating a new Random object also use the current time as a seed which means I'd have the same problem? – Aaron H May 18 '19 at 14:37
  • I should not, because it creates a new seed *based* on the time not *of* the time. – Markus Zeller May 18 '19 at 14:38
  • 2
    Some RNGs have very non-random behaviour in the lowest bit; your `rnd.next(2)` might be falling foul of this. Try using something like `(rnd.next(50000) < 25000)` instead, which uses a larger range of outputs from the RNG. Also, you should, in general, declare `rnd` once only, outside any loops, and pull numbers from it as needed. – rossum May 18 '19 at 14:45
  • @Markus Zeller : The random generator does use time as the default constructor. But if you call random too quickly you get same results. – jdweng May 18 '19 at 15:30
  • @jdweng Try it out. And tell me again. – Markus Zeller May 18 '19 at 15:36
  • I changed some things, and the only thing I now know is that there is something seriously wrong with my code. I tried to just always apply random values for each object every iteration, but they still at some point behave the exact same. I don't understand how it happens, it might be the random, but it might be something other as well, but I can't find it. – Aaron H May 18 '19 at 15:38
  • I meant calling the constructor too quickly get same results. – jdweng May 18 '19 at 16:51

0 Answers0