public void AddNode3()
    {
        var pop           = CreateNeatPopulation();
        var generationSeq = new Int32Sequence();
        var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

        var genome = pop.GenomeList[0];

        var strategy = new AddNodeStrategy <double>(
            pop.MetaNeatGenome, genomeBuilder,
            pop.GenomeIdSeq, pop.InnovationIdSeq, generationSeq,
            pop.AddedNodeBuffer);

        IRandomSource rng = RandomDefaults.CreateRandomSource();

        CircularBuffer <NeatGenome <double> > genomeRing = new(10);

        genomeRing.Enqueue(genome);

        for (int i = 0; i < 5000; i++)
        {
            NeatGenome <double> childGenome = CreateAndTestChildGenome(genome, strategy, rng);

            // Add the new child genome to the ring.
            genomeRing.Enqueue(childGenome);

            // Take the genome at the tail of the ring for the next parent.
            genome = genomeRing[0];
        }
    }
        /// <summary>
        /// Construct a new instance.
        /// </summary>
        /// <param name="metaNeatGenome">NeatGenome metadata.</param>
        /// <param name="genomeBuilder">NeatGenome builder.</param>
        /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
        /// <param name="innovationIdSeq">Innovation ID sequence; for obtaining new innovation IDs.</param>
        /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
        /// <param name="addedNodeBuffer">A history buffer of added nodes.</param>
        /// <param name="settings">Asexual reproduction settings.</param>
        /// <param name="weightMutationScheme">Connection weight mutation scheme.</param>
        public NeatReproductionAsexual(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            Int32Sequence generationSeq,
            AddedNodeBuffer addedNodeBuffer,
            NeatReproductionAsexualSettings settings,
            WeightMutationScheme <T> weightMutationScheme)
        {
            _settings = settings;

            // Instantiate reproduction strategies.
            _mutateWeightsStrategy    = new MutateWeightsStrategy <T>(metaNeatGenome, genomeBuilder, genomeIdSeq, generationSeq, weightMutationScheme);
            _deleteConnectionStrategy = new DeleteConnectionStrategy <T>(metaNeatGenome, genomeBuilder, genomeIdSeq, generationSeq);

            // Add connection mutation; select acyclic/cyclic strategy as appropriate.
            if (metaNeatGenome.IsAcyclic)
            {
                _addConnectionStrategy = new AddAcyclicConnectionStrategy <T>(
                    metaNeatGenome, genomeBuilder,
                    genomeIdSeq, innovationIdSeq, generationSeq);
            }
            else
            {
                _addConnectionStrategy = new AddCyclicConnectionStrategy <T>(
                    metaNeatGenome, genomeBuilder,
                    genomeIdSeq, innovationIdSeq, generationSeq);
            }

            _addNodeStrategy = new AddNodeStrategy <T>(metaNeatGenome, genomeBuilder, genomeIdSeq, innovationIdSeq, generationSeq, addedNodeBuffer);
        }
Exemple #3
0
 public NeatPopulation(
     MetaNeatGenome <T> metaNeatGenome,
     List <NeatGenome <T> > genomeList,
     Int32Sequence genomeIdSeq,
     Int32Sequence innovationIdSeq)
     : this(metaNeatGenome, genomeList, genomeIdSeq, innovationIdSeq, __defaultInnovationHistoryBufferSize, __defaultInnovationHistoryBufferSize)
 {
 }
Exemple #4
0
        public void Int32Sequence()
        {
            ISequence <int> sequence = new Int32Sequence();

            for (var i = 0; i < 100; i++)
            {
                Assert.That(sequence.GetNext(), Is.EqualTo(i + 1));
            }
        }
 /// <summary>
 /// Construct a new instance.
 /// </summary>
 /// <param name="genomeBuilder">NeatGenome builder.</param>
 /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
 /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
 public DeleteConnectionStrategy(
     INeatGenomeBuilder <T> genomeBuilder,
     Int32Sequence genomeIdSeq,
     Int32Sequence generationSeq)
 {
     _genomeBuilder = genomeBuilder;
     _genomeIdSeq   = genomeIdSeq;
     _generationSeq = generationSeq;
 }
Exemple #6
0
        /// <summary>
        /// Construct a new instance.
        /// </summary>
        /// <param name="eaSettings">NEAT evolution algorithm settings.</param>
        /// <param name="evaluator">An evaluator of lists of genomes.</param>
        /// <param name="speciationStrategy">Speciation strategy.</param>
        /// <param name="population">An initial population of genomes.</param>
        /// <param name="complexityRegulationStrategy">Complexity regulation strategy.</param>
        /// <param name="reproductionAsexualSettings">Asexual reproduction settings.</param>
        /// <param name="reproductionSexualSettings">Sexual reproduction settings.</param>
        /// <param name="weightMutationScheme">Connection weight mutation scheme.</param>
        /// <param name="rng">Random source.</param>
        public NeatEvolutionAlgorithm(
            NeatEvolutionAlgorithmSettings eaSettings,
            IGenomeListEvaluator <NeatGenome <T> > evaluator,
            ISpeciationStrategy <NeatGenome <T>, T> speciationStrategy,
            NeatPopulation <T> population,
            IComplexityRegulationStrategy complexityRegulationStrategy,
            NeatReproductionAsexualSettings reproductionAsexualSettings,
            NeatReproductionSexualSettings reproductionSexualSettings,
            WeightMutationScheme <T> weightMutationScheme,
            IRandomSource rng)
        {
            _eaSettingsCurrent       = eaSettings ?? throw new ArgumentNullException(nameof(eaSettings));
            _eaSettingsComplexifying = eaSettings;
            _eaSettingsSimplifying   = eaSettings.CreateSimplifyingSettings();

            _evaluator          = evaluator ?? throw new ArgumentNullException(nameof(evaluator));
            _speciationStrategy = speciationStrategy ?? throw new ArgumentNullException(nameof(speciationStrategy));
            _pop = population ?? throw new ArgumentNullException(nameof(population));
            _complexityRegulationStrategy = complexityRegulationStrategy ?? throw new ArgumentNullException(nameof(complexityRegulationStrategy));

            if (reproductionAsexualSettings == null)
            {
                throw new ArgumentNullException(nameof(reproductionAsexualSettings));
            }
            if (reproductionSexualSettings == null)
            {
                throw new ArgumentNullException(nameof(reproductionSexualSettings));
            }

            _rng = rng;
            _genomeComparerDescending = new GenomeComparerDescending(evaluator.FitnessComparer);

            if (eaSettings.SpeciesCount > population.PopulationSize)
            {
                throw new ArgumentException("Species count is higher then the population size.");
            }

            _generationSeq = new Int32Sequence();

            _reproductionAsexual = new NeatReproductionAsexual <T>(
                _pop.MetaNeatGenome, _pop.GenomeBuilder,
                _pop.GenomeIdSeq, population.InnovationIdSeq, _generationSeq,
                _pop.AddedNodeBuffer, reproductionAsexualSettings, weightMutationScheme);

            _reproductionSexual = new NeatReproductionSexual <T>(
                _pop.MetaNeatGenome, _pop.GenomeBuilder,
                _pop.GenomeIdSeq, _generationSeq,
                reproductionSexualSettings);

            _offspringBuilder = new OffspringBuilder <T>(
                _reproductionAsexual,
                _reproductionSexual,
                eaSettings.InterspeciesMatingProportion,
                evaluator.FitnessComparer);
        }
Exemple #7
0
 /// <summary>
 /// Construct a new instance.
 /// </summary>
 /// <param name="genomeBuilder">NeatGenome builder.</param>
 /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
 /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
 /// <param name="weightMutationScheme">Connection weight mutation scheme.</param>
 public MutateWeightsStrategy(
     INeatGenomeBuilder <T> genomeBuilder,
     Int32Sequence genomeIdSeq,
     Int32Sequence generationSeq,
     WeightMutationScheme <T> weightMutationScheme)
 {
     _genomeBuilder        = genomeBuilder;
     _genomeIdSeq          = genomeIdSeq;
     _generationSeq        = generationSeq;
     _weightMutationScheme = weightMutationScheme;
 }
        public void TestAddAcyclicConnection()
        {
            var pop           = CreateNeatPopulation();
            var generationSeq = new Int32Sequence();
            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

            var genome = pop.GenomeList[0];

            var strategy = new AddAcyclicConnectionStrategy <double>(
                pop.MetaNeatGenome, genomeBuilder,
                pop.GenomeIdSeq, pop.InnovationIdSeq, generationSeq);

            IRandomSource rng = RandomDefaults.CreateRandomSource();

            var nodeIdSet = GetNodeIdSet(genome);
            var connSet   = GetDirectedConnectionSet(genome);

            CyclicGraphAnalysis cyclicGraphAnalysis = new CyclicGraphAnalysis();

            for (int i = 0; i < 1000;)
            {
                var childGenome = strategy.CreateChildGenome(genome, rng);

                // Note. the strategy will return a null if it cannot find an acyclic connection to add;
                // test for this and try again. The test will be for N successful mutations rather than N attempts.
                if (null == childGenome)
                {
                    continue;
                }

                // The child genome should have one more connection than parent.
                Assert.AreEqual(genome.ConnectionGenes.Length + 1, childGenome.ConnectionGenes.Length);

                // The child genome's new connection should not be a duplicate of any of the existing/parent connections.
                var childConnSet = GetDirectedConnectionSet(childGenome);
                var newConnList  = new List <DirectedConnection>(childConnSet.Except(connSet));
                Assert.AreEqual(1, newConnList.Count);

                // The connection genes should be sorted.
                Assert.IsTrue(SortUtils.IsSortedAscending(childGenome.ConnectionGenes._connArr));

                // The child genome should have the same set of node IDs as the parent.
                var childNodeIdSet = GetNodeIdSet(childGenome);
                Assert.IsTrue(nodeIdSet.SetEquals(childNodeIdSet));

                // The child genome should describe an acyclic graph, i.e. the new connection should not have
                // formed a cycle in the graph.
                var digraph = childGenome.DirectedGraph;
                Assert.IsFalse(cyclicGraphAnalysis.IsCyclic(digraph));

                // Increment for successful tests only.
                i++;
            }
        }
 /// <summary>
 /// Construct a new instance.
 /// </summary>
 /// <param name="metaNeatGenome">NEAT genome metadata.</param>
 /// <param name="genomeBuilder">NeatGenome builder.</param>
 /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
 /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
 public DeleteConnectionStrategy(
     MetaNeatGenome <T> metaNeatGenome,
     INeatGenomeBuilder <T> genomeBuilder,
     Int32Sequence genomeIdSeq,
     Int32Sequence generationSeq)
 {
     _metaNeatGenome = metaNeatGenome;
     _genomeBuilder  = genomeBuilder;
     _genomeIdSeq    = genomeIdSeq;
     _generationSeq  = generationSeq;
 }
Exemple #10
0
        /// <summary>
        /// Construct the population with the provided list of genomes that make up the initial population.
        /// </summary>
        /// <param name="genomeList"></param>
        public Population(List <TGenome> genomeList)
        {
            this.GenomeList     = genomeList ?? throw new ArgumentNullException(nameof(genomeList));
            this.PopulationSize = genomeList.Count;
            this.GenerationSeq  = new Int32Sequence();

            if (genomeList.Count == 0)
            {
                throw new ArgumentException("Empty genome list. The initial population cannot be empty.", nameof(genomeList));
            }
        }
    public void AddCyclicConnection()
    {
        var pop           = CreateNeatPopulation();
        var generationSeq = new Int32Sequence();
        var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

        var genome = pop.GenomeList[0];

        var strategy = new AddCyclicConnectionStrategy <double>(
            pop.MetaNeatGenome, genomeBuilder,
            pop.GenomeIdSeq, generationSeq);

        IRandomSource rng = RandomDefaults.CreateRandomSource();

        var nodeIdSet = GetNodeIdSet(genome);
        var connSet   = GetDirectedConnectionSet(genome);

        const int loops             = 1000;
        int       nullResponseCount = 0;

        for (int i = 0; i < loops; i++)
        {
            var childGenome = strategy.CreateChildGenome(genome, rng);

            // The strategy may return null if no appropriately connection could be found to add.
            if (childGenome is null)
            {
                nullResponseCount++;
                continue;
            }

            // The child genome should have one more connection than parent.
            Assert.Equal(genome.ConnectionGenes.Length + 1, childGenome.ConnectionGenes.Length);

            // The child genome's new connection should not be a duplicate of any of the existing/parent connections.
            var childConnSet = GetDirectedConnectionSet(childGenome);
            var newConnList  = new List <DirectedConnection>(childConnSet.Except(connSet));
            Assert.Single(newConnList);

            // The connection genes should be sorted.
            Assert.True(SortUtils.IsSortedAscending <DirectedConnection>(childGenome.ConnectionGenes._connArr));

            // The child genome should have the same set of node IDs as the parent.
            var childNodeIdSet = GetNodeIdSet(childGenome);
            Assert.True(nodeIdSet.SetEquals(childNodeIdSet));
        }

        // nullResponseProportion will typically be 0, with 1.0% being so unlikely
        // it probably will never be observed.
        double nullResponseProportion = nullResponseCount / (double)loops;

        Assert.True(nullResponseProportion <= 0.01);
    }
 /// <summary>
 /// Construct a new instance.
 /// </summary>
 /// <param name="metaNeatGenome">NeatGenome metadata.</param>
 /// <param name="genomeBuilder">NeatGenome builder.</param>
 /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
 /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
 /// <param name="settings">Sexual reproduction settings.</param>
 public NeatReproductionSexual(
     MetaNeatGenome <T> metaNeatGenome,
     INeatGenomeBuilder <T> genomeBuilder,
     Int32Sequence genomeIdSeq,
     Int32Sequence generationSeq,
     NeatReproductionSexualSettings settings)
 {
     _strategy = new UniformCrossoverReproductionStrategy <T>(
         metaNeatGenome.IsAcyclic,
         settings.SecondaryParentGeneProbability,
         genomeBuilder,
         genomeIdSeq, generationSeq);
 }
        /// <summary>
        /// Construct a new instance.
        /// </summary>
        /// <param name="metaNeatGenome">NEAT genome metadata.</param>
        /// <param name="genomeBuilder">NeatGenome builder.</param>
        /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
        /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
        public AddCyclicConnectionStrategy(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence generationSeq)
        {
            _metaNeatGenome = metaNeatGenome;
            _genomeBuilder  = genomeBuilder;
            _genomeIdSeq    = genomeIdSeq;
            _generationSeq  = generationSeq;

            _weightSamplerA = UniformDistributionSamplerFactory.CreateStatelessSampler <T>(metaNeatGenome.ConnectionWeightScale, true);
            _weightSamplerB = UniformDistributionSamplerFactory.CreateStatelessSampler <T>(metaNeatGenome.ConnectionWeightScale * 0.01, true);
        }
Exemple #14
0
        public void CreateGenome()
        {
            var metaNeatGenome = new MetaNeatGenome <double>(
                inputNodeCount: 10,
                outputNodeCount: 20,
                isAcyclic: true,
                activationFn: new NeuralNets.Double.ActivationFunctions.ReLU());

            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(metaNeatGenome);

            int count = 100;
            NeatPopulation <double> pop = NeatPopulationFactory <double> .CreatePopulation(metaNeatGenome, 0.1, count, RandomDefaults.CreateRandomSource());

            var generationSeq = new Int32Sequence();

            var strategy = new UniformCrossoverReproductionStrategy <double>(
                pop.MetaNeatGenome.IsAcyclic,
                0.02,
                genomeBuilder,
                pop.GenomeIdSeq, generationSeq);

            IRandomSource rng = RandomDefaults.CreateRandomSource(0);

            var cyclicGraphCheck = new CyclicGraphCheck();

            for (int i = 0; i < 1000; i++)
            {
                // Randomly select two parents from the population.
                var genome1 = pop.GenomeList[rng.Next(count)];
                var genome2 = pop.GenomeList[rng.Next(count)];

                var childGenome = strategy.CreateGenome(genome1, genome2, rng);

                // The connection genes should be sorted.
                Assert.True(SortUtils.IsSortedAscending <DirectedConnection>(childGenome.ConnectionGenes._connArr));

                // The child genome should describe an acyclic graph, i.e. the new connection should not have
                // formed a cycle in the graph.
                var digraph = childGenome.DirectedGraph;
                Assert.False(cyclicGraphCheck.IsCyclic(digraph));

                // The child genome node IDs should be a superset of those from parent1 + parent2.
                var childNodeIdSet = GetNodeIdSet(childGenome);
                var parentIdSet    = GetNodeIdSet(genome1);
                parentIdSet.IntersectWith(GetNodeIdSet(genome2));

                Assert.True(childNodeIdSet.IsSupersetOf(parentIdSet));
            }
        }
Exemple #15
0
    /// <summary>
    /// Construct with the given strategy arguments.
    /// </summary>
    /// <param name="isAcyclic">Indicates that the strategy will be operating on acyclic graphs/genomes.</param>
    /// <param name="secondaryParentGeneProbability">The probability that a gene that exists only on the secondary parent is copied into the child genome.</param>
    /// <param name="genomeBuilder">A neat genome builder.</param>
    /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
    /// <param name="generationSeq">A sequence that provides the current generation number.</param>
    public UniformCrossoverReproductionStrategy(
        bool isAcyclic,
        double secondaryParentGeneProbability,
        INeatGenomeBuilder <T> genomeBuilder,
        Int32Sequence genomeIdSeq,
        Int32Sequence generationSeq)
    {
        _isAcyclic = isAcyclic;
        _secondaryParentGeneProbability = secondaryParentGeneProbability;
        _genomeBuilder = genomeBuilder;
        _genomeIdSeq   = genomeIdSeq;
        _generationSeq = generationSeq;

        _connGeneListBuilder = new ConnectionGeneListBuilder <T>(_isAcyclic, 1024);
    }
Exemple #16
0
        public UniformCrossoverReproductionStrategy(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence generationSeq,
            IRandomSource rng)
        {
            _metaNeatGenome = metaNeatGenome;
            _genomeBuilder  = genomeBuilder;
            _genomeIdSeq    = genomeIdSeq;
            _generationSeq  = generationSeq;

            _rng     = rng;
            _builder = new ConnectionGeneListBuilder <T>(_metaNeatGenome.IsAcyclic, 1024);
        }
Exemple #17
0
 /// <summary>
 /// Construct a new instance.
 /// </summary>
 /// <param name="metaNeatGenome">NEAT genome metadata.</param>
 /// <param name="genomeBuilder">NeatGenome builder.</param>
 /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
 /// <param name="innovationIdSeq">Innovation ID sequence; for obtaining new innovation IDs.</param>
 /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
 /// <param name="addedNodeBuffer">A history buffer of added nodes.</param>
 public AddNodeStrategy(
     MetaNeatGenome <T> metaNeatGenome,
     INeatGenomeBuilder <T> genomeBuilder,
     Int32Sequence genomeIdSeq,
     Int32Sequence innovationIdSeq,
     Int32Sequence generationSeq,
     AddedNodeBuffer addedNodeBuffer)
 {
     _metaNeatGenome  = metaNeatGenome;
     _genomeBuilder   = genomeBuilder;
     _genomeIdSeq     = genomeIdSeq;
     _innovationIdSeq = innovationIdSeq;
     _generationSeq   = generationSeq;
     _addedNodeBuffer = addedNodeBuffer;
 }
Exemple #18
0
        public NeatPopulation(
            MetaNeatGenome <T> metaNeatGenome,
            List <NeatGenome <T> > genomeList,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            int addedConnectionHistoryBufferSize,
            int addedNodeHistoryBufferSize)
            : base(genomeList)
        {
            this.MetaNeatGenome  = metaNeatGenome;
            this.GenomeIdSeq     = genomeIdSeq;
            this.InnovationIdSeq = innovationIdSeq;
            this.AddedNodeBuffer = new AddedNodeBuffer(addedNodeHistoryBufferSize);

            // Assert that the ID sequences have a current IDs higher than any existing ID.
            Debug.Assert(ValidateIdSequences(genomeList, genomeIdSeq, innovationIdSeq));
        }
        public NeatReproductionSexual(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            Int32Sequence generationSeq,
            AddedNodeBuffer addedNodeBuffer,
            NeatReproductionSexualSettings settings,
            IRandomSourceBuilder rngBuilder)
        {
            _settings = settings;
            _rng      = rngBuilder.Create();

            _strategy = new UniformCrossoverReproductionStrategy <T>(
                metaNeatGenome, genomeBuilder,
                genomeIdSeq, generationSeq,
                rngBuilder.Create());
        }
        /// <summary>
        /// Construct a new population with the provided genomes and accompanying objects.
        /// </summary>
        /// <param name="metaNeatGenome">NeatGenome metadata.</param>
        /// <param name="genomeBuilder">NeatGenome builder.</param>
        /// <param name="genomeList">A list of genomes that will make up the population.</param>
        /// <param name="genomeIdSeq">Genome ID sequence.</param>
        /// <param name="innovationIdSeq">Innovation ID sequence.</param>
        /// <param name="addedNodeHistoryBufferSize">The size to allocate for the added node history buffer.</param>
        public NeatPopulation(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            List <NeatGenome <T> > genomeList,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            int addedNodeHistoryBufferSize)
            : base(genomeList)
        {
            this.MetaNeatGenome  = metaNeatGenome ?? throw new ArgumentNullException(nameof(metaNeatGenome));
            this.GenomeBuilder   = genomeBuilder ?? throw new ArgumentNullException(nameof(genomeBuilder));
            this.GenomeIdSeq     = genomeIdSeq ?? throw new ArgumentNullException(nameof(genomeIdSeq));
            this.InnovationIdSeq = innovationIdSeq ?? throw new ArgumentNullException(nameof(innovationIdSeq));
            this.AddedNodeBuffer = new AddedNodeBuffer(addedNodeHistoryBufferSize);

            // Assert that the ID sequence objects represent an ID higher than any existing ID used by the genomes.
            Debug.Assert(ValidateIdSequences(genomeList, genomeIdSeq, innovationIdSeq));
        }
        public AddCyclicConnectionStrategy(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            Int32Sequence generationSeq,
            IRandomSource rng)
        {
            _metaNeatGenome  = metaNeatGenome;
            _genomeBuilder   = genomeBuilder;
            _genomeIdSeq     = genomeIdSeq;
            _innovationIdSeq = innovationIdSeq;
            _generationSeq   = generationSeq;

            _weightDistA = ContinuousDistributionFactory.CreateUniformDistribution <T>(_metaNeatGenome.ConnectionWeightRange, true);
            _weightDistB = ContinuousDistributionFactory.CreateUniformDistribution <T>(_metaNeatGenome.ConnectionWeightRange * 0.01, true);
            _rng         = rng;
        }
        public async Task Test()
        {
            using var _ = HConsoleForTest();

            var options = HazelcastOptions.Build();

            options.Messaging.RetryTimeoutSeconds = 1;

            var loggerFactory = new NullLoggerFactory();

            var address = NetworkAddress.Parse("127.0.0.1:11000");

            var state = new ServerState
            {
                Id       = 0,
                MemberId = Guid.NewGuid(),
                Address  = address
            };

            await using var server = new Server(address, ServerHandler, loggerFactory, state, "0")
                        {
                            MemberId = state.MemberId,
                        };
            await server.StartAsync();

            var serializationService = HazelcastClientFactory.CreateSerializationService(options.Serialization, loggerFactory);
            var authenticator        = new Authenticator(options.Authentication, serializationService);

            ISequence <int>  connectionIdSequence  = new Int32Sequence();
            ISequence <long> correlationIdSequence = new Int64Sequence();

            var memberConnection = new MemberConnection(address, authenticator,
                                                        options.Messaging, options.Networking, options.Networking.Ssl,
                                                        connectionIdSequence, correlationIdSequence,
                                                        loggerFactory);

            var memberConnectionHasClosed = false;

            memberConnection.Closed += connection =>
            {
                memberConnectionHasClosed = true;
                return(default);
Exemple #23
0
        public static bool ValidateIdSequences <T>(
            List <NeatGenome <T> > genomeList,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq)
            where T : struct
        {
            GetMaxObservedIds(genomeList, out int maxGenomeId, out int maxInnovationId);

            if (maxGenomeId >= genomeIdSeq.Peek)
            {
                return(false);
            }

            if (maxInnovationId >= innovationIdSeq.Peek)
            {
                return(false);
            }

            return(true);
        }
    public void AddNode1()
    {
        var pop           = CreateNeatPopulation();
        var generationSeq = new Int32Sequence();
        var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

        var genome = pop.GenomeList[0];

        var strategy = new AddNodeStrategy <double>(
            pop.MetaNeatGenome, genomeBuilder,
            pop.GenomeIdSeq, pop.InnovationIdSeq, generationSeq,
            pop.AddedNodeBuffer);

        IRandomSource rng = RandomDefaults.CreateRandomSource();

        for (int i = 0; i < 10_000; i++)
        {
            CreateAndTestChildGenome(genome, strategy, rng);
        }
    }
        private NeatPopulationFactory(
            MetaNeatGenome <T> metaNeatGenome,
            double connectionsProportion,
            IRandomSource rng)
        {
            _metaNeatGenome = metaNeatGenome;
            _genomeBuilder  = NeatGenomeBuilderFactory <T> .Create(metaNeatGenome);

            _connectionsProportion = connectionsProportion;

            // Define the set of all possible connections between the input and output nodes (fully interconnected).
            int inputCount  = metaNeatGenome.InputNodeCount;
            int outputCount = metaNeatGenome.OutputNodeCount;

            _connectionDefArr = new DirectedConnection[inputCount * outputCount];

            // Notes.
            // Nodes are assigned innovation IDs. By convention the input nodes are assigned IDs first starting at zero, then the output nodes.
            // Thus, because all of the evolved networks have a fixed number of inputs and outputs, the IDs of these nodes are always fixed.
            int firstOutputNodeId = inputCount;

            for (int srcId = 0, i = 0; srcId < inputCount; srcId++)
            {
                for (int tgtIdx = 0; tgtIdx < outputCount; tgtIdx++)
                {
                    _connectionDefArr[i++] = new DirectedConnection(srcId, firstOutputNodeId + tgtIdx);
                }
            }

            // Init RNG and ID sequences.
            _rng         = rng;
            _genomeIdSeq = new Int32Sequence();
            int nextInnovationId = inputCount + outputCount;

            _innovationIdSeq = new Int32Sequence(nextInnovationId);

            // Init random connection weight source.
            _connWeightDist = ContinuousDistributionFactory.CreateUniformDistribution <T>(_metaNeatGenome.ConnectionWeightRange, true);
        }
        public void TestDeleteConnection()
        {
            var pop           = CreateNeatPopulation();
            var generationSeq = new Int32Sequence();
            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

            var genome = pop.GenomeList[0];

            var strategy = new DeleteConnectionStrategy <double>(
                pop.MetaNeatGenome, genomeBuilder,
                pop.GenomeIdSeq, generationSeq);

            IRandomSource rng = RandomDefaults.CreateRandomSource();

            var nodeIdSet = GetNodeIdSet(genome);
            var connSet   = GetDirectedConnectionSet(genome);

            for (int i = 0; i < 1000; i++)
            {
                var childGenome = strategy.CreateChildGenome(genome, rng);

                // The child genome should have one less connection than the parent.
                Assert.AreEqual(genome.ConnectionGenes.Length - 1, childGenome.ConnectionGenes.Length);

                // The child genome's connections should be a proper subset of the parent genome's.
                var childConnSet = GetDirectedConnectionSet(childGenome);
                Assert.IsTrue(childConnSet.IsProperSubsetOf(connSet));

                // The connection genes should be sorted.
                Assert.IsTrue(SortUtils.IsSortedAscending(childGenome.ConnectionGenes._connArr));

                // Test that the array of hidden node IDs is correct, i.e. corresponds with the hidden node IDs described by the connections.
                Assert.IsTrue(ConnectionGenesUtils.ValidateHiddenNodeIds(
                                  childGenome.HiddenNodeIdArray,
                                  childGenome.ConnectionGenes._connArr,
                                  childGenome.MetaNeatGenome.InputOutputNodeCount));
            }
        }
    public void AddNode2()
    {
        var pop           = CreateNeatPopulation();
        var generationSeq = new Int32Sequence();
        var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

        var genome = pop.GenomeList[0];

        var strategy = new AddNodeStrategy <double>(
            pop.MetaNeatGenome, genomeBuilder,
            pop.GenomeIdSeq, pop.InnovationIdSeq, generationSeq,
            pop.AddedNodeBuffer);

        IRandomSource rng = RandomDefaults.CreateRandomSource();

        for (int i = 0; i < 2000; i++)
        {
            NeatGenome <double> childGenome = CreateAndTestChildGenome(genome, strategy, rng);

            // Make the child genome the parent in the next iteration. I.e. accumulate add node mutations.
            genome = childGenome;
        }
    }
Exemple #28
0
        /// <summary>
        /// Construct a new instance.
        /// </summary>
        /// <param name="metaNeatGenome">NeatGenome metadata.</param>
        /// <param name="genomeBuilder">NeatGenome builder.</param>
        /// <param name="genomeIdSeq">Genome ID sequence; for obtaining new genome IDs.</param>
        /// <param name="innovationIdSeq">Innovation ID sequence; for obtaining new innovation IDs.</param>
        /// <param name="generationSeq">Generation sequence; for obtaining the current generation number.</param>
        /// <param name="addedNodeBuffer">A history buffer of added nodes.</param>
        /// <param name="settings">Asexual reproduction settings.</param>
        /// <param name="weightMutationScheme">Connection weight mutation scheme.</param>
        public NeatReproductionAsexual(
            MetaNeatGenome <T> metaNeatGenome,
            INeatGenomeBuilder <T> genomeBuilder,
            Int32Sequence genomeIdSeq,
            Int32Sequence innovationIdSeq,
            Int32Sequence generationSeq,
            AddedNodeBuffer addedNodeBuffer,
            NeatReproductionAsexualSettings settings,
            WeightMutationScheme <T> weightMutationScheme)
        {
            var settingsComplexifying = settings;
            var settingsSimplifying   = settings.CreateSimplifyingSettings();

            _mutationTypeDistributionsComplexifying = new MutationTypeDistributions(settingsComplexifying);
            _mutationTypeDistributionsSimplifying   = new MutationTypeDistributions(settingsSimplifying);
            _mutationTypeDistributionsCurrent       = _mutationTypeDistributionsComplexifying;

            // Instantiate reproduction strategies.
            _mutateWeightsStrategy    = new MutateWeightsStrategy <T>(genomeBuilder, genomeIdSeq, generationSeq, weightMutationScheme);
            _deleteConnectionStrategy = new DeleteConnectionStrategy <T>(genomeBuilder, genomeIdSeq, generationSeq);

            // Add connection mutation; select acyclic/cyclic strategy as appropriate.
            if (metaNeatGenome.IsAcyclic)
            {
                _addConnectionStrategy = new AddAcyclicConnectionStrategy <T>(
                    metaNeatGenome, genomeBuilder,
                    genomeIdSeq, generationSeq);
            }
            else
            {
                _addConnectionStrategy = new AddCyclicConnectionStrategy <T>(
                    metaNeatGenome, genomeBuilder,
                    genomeIdSeq, generationSeq);
            }

            _addNodeStrategy = new AddNodeStrategy <T>(metaNeatGenome, genomeBuilder, genomeIdSeq, innovationIdSeq, generationSeq, addedNodeBuffer);
        }
Exemple #29
0
 public Population(
     List <TGenome> genomeList)
 {
     this.GenomeList    = genomeList;
     this.GenerationSeq = new Int32Sequence();
 }
        public void TestAddAcyclicConnection_CumulativeAdditions()
        {
            var pop           = CreateNeatPopulation();
            var generationSeq = new Int32Sequence();
            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

            var rootGenome = pop.GenomeList[0];

            var strategy = new AddAcyclicConnectionStrategy <double>(
                pop.MetaNeatGenome, genomeBuilder,
                pop.GenomeIdSeq, pop.InnovationIdSeq, generationSeq);

            IRandomSource rng = RandomDefaults.CreateRandomSource();

            var nodeIdSet = GetNodeIdSet(rootGenome);

            CyclicGraphAnalysis cyclicGraphAnalysis = new CyclicGraphAnalysis();

            AcyclicGraphDepthAnalysis graphDepthAnalysis = new AcyclicGraphDepthAnalysis();

            // Run the inner loop test multiple times.
            // Note. The add-connection mutations are random, thus each loop accumulates a different set of mutations.
            for (int i = 0; i < 50; i++)
            {
                var parentGenome = rootGenome;

                // Accumulate random mutations for some number of loops.
                for (int j = 0; j < 20;)
                {
                    var childGenome = strategy.CreateChildGenome(rootGenome, rng);

                    // Note. the strategy will return a null if it cannot find an acyclic connection to add;
                    // test for this and try again. The test will be for N successful mutations rather than N attempts.
                    if (null == childGenome)
                    {
                        continue;
                    }

                    // The child genome should have one more connection than parent.
                    Assert.AreEqual(rootGenome.ConnectionGenes.Length + 1, childGenome.ConnectionGenes.Length);

                    // The child genome's new connection should not be a duplicate of any of the existing/parent connections.
                    var connSet      = GetDirectedConnectionSet(rootGenome);
                    var childConnSet = GetDirectedConnectionSet(childGenome);
                    var newConnList  = new List <DirectedConnection>(childConnSet.Except(connSet));
                    Assert.AreEqual(1, newConnList.Count);

                    // The connection genes should be sorted.
                    Assert.IsTrue(SortUtils.IsSortedAscending(childGenome.ConnectionGenes._connArr));

                    // The child genome should have the same set of node IDs as the parent.
                    var childNodeIdSet = GetNodeIdSet(childGenome);
                    Assert.IsTrue(nodeIdSet.SetEquals(childNodeIdSet));

                    // The child genome should describe an acyclic graph, i.e. the new connection should not have
                    // formed a cycle in the graph.
                    var digraph = childGenome.DirectedGraph;
                    Assert.IsFalse(cyclicGraphAnalysis.IsCyclic(digraph));

                    // Run the acyclic graph depth analysis algorithm.
                    GraphDepthInfo depthInfo = graphDepthAnalysis.CalculateNodeDepths(childGenome.DirectedGraph);

                    // Run again with the alternative algorithm (that uses function recursion).
                    GraphDepthInfo depthInfo2 = AcyclicGraphDepthAnalysisByRecursion.CalculateNodeDepths(childGenome.DirectedGraph);

                    Assert.AreEqual(nodeIdSet.Count, depthInfo._nodeDepthArr.Length);
                    Assert.AreEqual(nodeIdSet.Count, depthInfo2._nodeDepthArr.Length);
                    ArrayTestUtils.Compare(depthInfo2._nodeDepthArr, depthInfo._nodeDepthArr);

                    // Set the child genome to be the new parent, thus we accumulate random new connections over time.
                    parentGenome = childGenome;

                    // Increment for successful tests only.
                    j++;
                }
            }
        }