Beispiel #1
0
    // create neuron at network initialization
    public Neuron CreateStartNeuron(Neuron.Type type, int neuronID, float splitX, float splitY)
    {
        var    oldNeuronInnovID = innovationDB.CheckNeuronStartInnovation(neuronID);
        Neuron newNeuron;

        // new innovation
        if (oldNeuronInnovID == -1)
        {
            var neuronInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_NEURON, -1, -1, type, splitX, splitY);
            newNeuron = new Neuron(neuronInnov.neuronID, type, splitX, splitY);
        }
        else
        {
            var newNeuronID = innovationDB.GetNeuronID(oldNeuronInnovID);
            newNeuron = new Neuron(newNeuronID, type, splitX, splitY);
        }
        neurons.Add(newNeuron.ID, newNeuron);
        return(newNeuron);
    }
Beispiel #2
0
    public Genome Crossover(Genome other)
    {
        var    parentA = this;
        var    parentB = other;
        Genome best    = new Genome();

        if (parentA.fitness == parentB.fitness)
        {
            // if same fitness pick shortest genome
            if (parentA.NumGenes() < parentB.NumGenes())
            {
                best = parentA;
            }
            else if (parentB.NumGenes() < parentA.NumGenes())
            {
                best = parentB;
            }
            else
            {
                int randomElement = Random.Range(0, 2);
                best = randomElement == 0 ? parentA : parentB;
            }
        }

        else if (parentA.fitness > parentB.fitness)
        {
            best = parentA;
        }
        else
        {
            best = parentB;
        }

        var    childWeights = new IntWeightDictionary();
        var    childNeurons = new IntNeuronDictionary();
        int    parentAIndex = 0, parentBIndex = 0;
        Weight parentAWeight = null, parentBWeight = null;

        // while end of both genes is not reached
        while (parentAIndex < parentA.weights.Count || parentBIndex < parentB.weights.Count)
        {
            if (parentAIndex < parentA.weights.Count)
            {
                parentAWeight = parentA.weights.ElementAt(parentAIndex).Value.Copy();
            }
            if (parentBIndex < parentB.weights.Count)
            {
                parentBWeight = parentB.weights.ElementAt(parentBIndex).Value.Copy();
            }
            Weight selectedWeight = null;

            if (parentAIndex == parentA.weights.Count && parentBIndex != parentB.weights.Count)
            {
                // add excess genes
                if (parentB == best)
                {
                    selectedWeight = parentBWeight;
                }
                parentBIndex++;
            }

            else if (parentBIndex == parentB.weights.Count && parentAIndex != parentA.weights.Count)
            {
                // add excess genes
                if (parentA == best)
                {
                    selectedWeight = parentAWeight;
                }
                parentAIndex++;
            }

            else if (parentAWeight.innovID < parentBWeight.innovID)
            {
                // add parentA disjoint genes
                if (parentA == best)
                {
                    selectedWeight = parentAWeight;
                }
                parentAIndex++;
            }
            else if (parentBWeight.innovID < parentAWeight.innovID)
            {
                // add parentB disjoint genes
                if (parentB == best)
                {
                    selectedWeight = parentBWeight;
                }
                parentBIndex++;
            }

            else
            {
                int randomElement = Random.Range(0, 2);
                selectedWeight = randomElement == 0 ? parentAWeight : parentBWeight;

                if (!parentAWeight.enabled && !parentBWeight.enabled)
                {
                    float random = Random.value;
                    if (random <= pWeightEnabled)
                    {
                        selectedWeight.enabled = true;
                    }
                }

                parentAIndex++;
                parentBIndex++;
            }

            if (selectedWeight != null && !childWeights.ContainsKey(selectedWeight.innovID))
            {
                childWeights.Add(selectedWeight.innovID, selectedWeight);
            }

            if (selectedWeight != null)
            {
                if (!childNeurons.ContainsKey(selectedWeight.neuronIn))
                {
                    Neuron neuron = null;
                    if (parentA.weights.Any(x => x.Value.neuronIn == selectedWeight.neuronIn))
                    {
                        neuron = parentA.neurons[selectedWeight.neuronIn].Copy();
                    }
                    else if (parentB.weights.Any(x => x.Value.neuronIn == selectedWeight.neuronIn))
                    {
                        neuron = parentB.neurons[selectedWeight.neuronIn].Copy();
                    }

                    if (neuron == null)
                    {
                        Debug.LogError("NEURON IS NULL!");
                    }

                    childNeurons.Add(neuron.ID, neuron);
                }

                if (!childNeurons.ContainsKey(selectedWeight.neuronOut))
                {
                    Neuron neuron = null;
                    if (parentA.weights.Any(x => x.Value.neuronOut == selectedWeight.neuronOut))
                    {
                        neuron = parentA.neurons[selectedWeight.neuronOut].Copy();
                    }
                    else if (parentB.weights.Any(x => x.Value.neuronOut == selectedWeight.neuronOut))
                    {
                        neuron = parentB.neurons[selectedWeight.neuronOut].Copy();
                    }

                    if (neuron == null)
                    {
                        Debug.LogError("NEURON IS NULL!");
                    }

                    childNeurons.Add(neuron.ID, neuron);
                }
            }
        }
        return(new Genome(childNeurons, childWeights));
    }