Beispiel #1
0
    public void MutateEnableDisable(bool enable)
    {
        var candidates = new IntWeightDictionary();

        for (int i = 0; i < weights.Count; i++)
        {
            var weight = weights.ElementAt(i).Value;
            if (weight.enabled != enable)
            {
                candidates.Add(i, weight);
            }
        }

        if (candidates.Count == 0)
        {
            return;
        }

        var chosen = candidates.ElementAt(Random.Range(0, candidates.Count)).Value;

        chosen.enabled = enable;
    }
Beispiel #2
0
    public void MutateAddNeuron()
    {
        bool done = false;

        while (!done)
        {
            int index  = Random.Range(0, weights.Count);
            var weight = weights.ElementAt(index).Value;

            if (weight.enabled && !weight.recurrent && neurons[weight.neuronIn].type != Neuron.Type.BIAS)
            {
                done = true;

                float oldValue = weight.value;
                weight.enabled = false;
                int from = weight.neuronIn;
                int to   = weight.neuronOut;

                float newSplitX = (neurons[from].splitX + neurons[to].splitX) / 2f;
                float newSplitY = (neurons[from].splitY + neurons[to].splitY) / 2f;

                // check whether new neuron is already in innovation database
                var oldNeuronInnovID = innovationDB.CheckNeuronInnovation(from, to);

                // new innovation
                if (oldNeuronInnovID == -1)
                {
                    var neuronInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_NEURON, from, to, Neuron.Type.HIDDEN, newSplitX, newSplitY);
                    var newNeuron   = new Neuron(neuronInnov.neuronID, Neuron.Type.HIDDEN, newSplitX, newSplitY);
                    neurons.Add(newNeuron.ID, newNeuron);

                    var weightInInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_WEIGHT, from, newNeuron.ID, Neuron.Type.NONE, -1, -1);
                    var weightIn      = new Weight(weightInInnov.ID, from, newNeuron.ID, 1f, true, false);
                    weights.Add(weightInInnov.ID, weightIn);

                    var weightOutInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_WEIGHT, newNeuron.ID, to, Neuron.Type.NONE, -1, -1);
                    var weightOut      = new Weight(weightOutInnov.ID, newNeuron.ID, to, oldValue, true, false);
                    weights.Add(weightOut.innovID, weightOut);
                }
                // innovation is already in innovation database
                else
                {
                    var newNeuronID    = innovationDB.GetNeuronID(oldNeuronInnovID);
                    var oldWeightInID  = innovationDB.CheckWeightInnovation(from, newNeuronID);
                    var oldWeightOutID = innovationDB.CheckWeightInnovation(newNeuronID, to);

                    if (oldWeightInID == -1 || oldWeightOutID == -1)
                    {
                        Debug.LogError("old innov ID " + oldNeuronInnovID);
                        Debug.LogError("Error in MutateAddNeuron: weights not in database, from " + from + ", to " + to + " newNeuronID " + newNeuronID);
                        return;
                    }
                    var newNeuron = new Neuron(newNeuronID, Neuron.Type.HIDDEN, newSplitX, newSplitY);
                    neurons.Add(newNeuron.ID, newNeuron);

                    var weightIn = new Weight(oldWeightInID, from, newNeuron.ID, 1f, true, false);
                    weights.Add(weightIn.innovID, weightIn);
                    var weightOut = new Weight(oldWeightOutID, newNeuron.ID, to, oldValue, true, false);
                    weights.Add(weightOut.innovID, weightOut);
                }
            }
        }
    }