Ejemplo n.º 1
0
    public void PerformsDnaMutation()
    {
        // Arrange
        const int nInputs  = 2;
        const int nOutputs = 2;
        const int outputLayerActivationIndex = 3;

        int[] hiddenLayers             = new int[] { 7 };
        Dna   originalDna              = Dna.GenerateRandomDnaEncoding(nInputs, hiddenLayers, nOutputs, (ActivationType)outputLayerActivationIndex, true);
        float weightMutationPrevalence = 0.2f;

        // Act
        Dna mutatedDna = Dna.CloneAndMutate(originalDna, DnaHeritage.MutatedElite, weightMutationPrevalence, 0.8f);

        // Assert
        CheckDnaIsNotReferentiallyEqual(originalDna, mutatedDna);
        // Structure
        mutatedDna.OutputsPerLayer.Should().Equal(originalDna.OutputsPerLayer);
        mutatedDna.Heritage.Should().Be(DnaHeritage.MutatedElite);

        // Weights
        mutatedDna.WeightsAndBiases.Should().NotEqual(originalDna.WeightsAndBiases);
        mutatedDna.WeightsAndBiases.Should().HaveCount(originalDna.WeightsAndBiases.Count);
        List <double> mutatedWeights = new List <double>();

        for (int i = 0; i < originalDna.WeightsAndBiases.Count; i++)
        {
            if (originalDna.WeightsAndBiases[i] != mutatedDna.WeightsAndBiases[i])
            {
                mutatedWeights.Add(mutatedDna.WeightsAndBiases[i]);
            }
        }
        mutatedWeights.Should().HaveCount(Mathf.CeilToInt(weightMutationPrevalence * originalDna.WeightsAndBiases.Count));

        // Activation
        mutatedDna.ActivationIndexes.Should().NotEqual(originalDna.ActivationIndexes);
        mutatedDna.ActivationIndexes.Should().HaveCount(originalDna.ActivationIndexes.Count);
        int indexOfOutputLayerActivation = originalDna.ActivationIndexes.Count - nOutputs;

        mutatedDna.ActivationIndexes.Skip(indexOfOutputLayerActivation)
        .Should().Equal(originalDna.ActivationIndexes.Skip(indexOfOutputLayerActivation), "preserves output layer activation functions");
    }