public void CheckOnePointRecombinationFromBest() { using (var source = RandomSource.DrillIn()) { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var best = new Genome(parameters, tracker, true); var worst = new Genome(parameters, tracker, true); // Act source.GetParanoid(); source.PushLimitedNexts(1, 3); // crossover points source.PushNextBools(true); // start from best var result = best.Mate(worst, CrossoverType.OnePoint); // Assert Assert.Equal(result.NeatChromosome[0].Weight, best.NeatChromosome[0].Weight); for (var i = 1; i < result.NeatChromosome.Count; i++) { Assert.Equal(result.NeatChromosome[i].Weight, worst.NeatChromosome[i].Weight); } } }
public void SanityCheck() { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); // Act // Assert Assert.Equal(0, genome.VacantConnectionCount); // Act genome.RemoveConnection(1); // Assert Assert.Equal(1, genome.VacantConnectionCount); // Act genome.AddConnection(0); // Assert Assert.Equal(0, genome.VacantConnectionCount); }
/// <summary> /// Creates a new innovation traker. /// </summary> /// <param name="name">The innovation tracker name.</param> /// <param name="initialNodeCount">The initial node count.</param> internal static void CreateInnovationTracker(string name, uint initialNodeCount) { if (!_innovationTrackers.ContainsKey(name)) { _innovationTrackers[name] = new InnovationTracker(initialNodeCount); } }
public void CheckTwoPointRecombinationOfSingleGene() { // TODO fix crossover, make this one green using (var source = RandomSource.DrillIn()) { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var best = new Genome(parameters, tracker, true); var worst = new Genome(parameters, tracker, true); // Act source.GetParanoid(); source.PushLimitedNexts(2, 2); // crossover points source.PushNextBools(true); // start from best var result = best.Mate(worst, CrossoverType.TwoPoints); // Assert Assert.Equal(result.NeatChromosome[2].Weight, worst.NeatChromosome[2].Weight); for (var i = 0; i < result.NeatChromosome.Count; i++) { if (i == 2) { continue; } Assert.Equal(result.NeatChromosome[i].Weight, best.NeatChromosome[i].Weight); } } }
public void CheckTrackerSanity() { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var first = new Genome(parameters, tracker, false); var second = new Genome(parameters, tracker, false); // Act Assert.Equal(5, first.NeatChromosome.Count); Assert.Equal(5, second.NeatChromosome.Count); first.SplitConnection(1); second.SplitConnection(1); // Assert Assert.Equal(6, first.NeatChromosome.Count); Assert.Equal(6, second.NeatChromosome.Count); for (var i = 0; i < first.NeatChromosome.Count; i++) { var firstGene = first.NeatChromosome[i]; var secondGene = second.NeatChromosome[i]; Assert.Equal(firstGene.Id, secondGene.Id); Assert.Equal(firstGene.SourceId, secondGene.SourceId); Assert.Equal(firstGene.TargetId, secondGene.TargetId); } }
public void CheckLinksAmbiguityHandling() { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var first = new Genome(parameters, tracker, false); var second = new Genome(parameters, tracker, false); // Act Assert.True(first.NeatChromosome[1].SourceId == 1 && first.NeatChromosome[1].TargetId == 4); Assert.True(second.NeatChromosome[1].SourceId == 1 && second.NeatChromosome[1].TargetId == 4); first.SplitConnection(1); second.SplitConnection(1); while (second.VacantConnectionCount > 0) // make fully connected network to ensure our link is there { second.AddConnection(0); } // Assert var linkGene = Assert.Single(second.NeatChromosome, gene => gene.SourceId == 1 && gene.TargetId == 4); Assert.DoesNotContain(first.NeatChromosome, gene => gene.Id == linkGene.Id); }
public void AddConnectionsOneByOneFeedforward() { // ReSharper disable once RedundantArgumentDefaultValue var parameters = new NetworkParameters(3, 1, NetworkType.FeedForward) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); var currentConnections = new List <string> { "0b->4e", "1s->4e", "2s->4e", "3s->4e" }; AssertCurrentConnections(genome, currentConnections); genome.SplitConnection(0); // 0 -> 4 into 0 -> 5 -> 4 currentConnections.ChangeCollection(new[] { "0b->4e" }, new[] { "0b->5h", "5h->4e" }); AssertCurrentConnections(genome, currentConnections); genome.SplitConnection(4); // 0 -> 5 -> 4 into 0 -> 6 -> 5 -> 4 currentConnections.ChangeCollection(new[] { "0b->5h" }, new[] { "0b->6h", "6h->5h" }); AssertCurrentConnections(genome, currentConnections); genome.SplitConnection(1); // 2 -> 4 into 2 -> 7 -> 4 currentConnections.ChangeCollection(new[] { "2s->4e" }, new[] { "2s->7h", "7h->4e" }); AssertCurrentConnections(genome, currentConnections); var initialLayers = genome.NetworkTopology.LayerRanges.ToArray(); var initialLinksCount = genome.NetworkTopology.Links.Sum(l => l.Count); genome.AddConnection(15); // 5h->7h AssertNoChanges(); genome.AddConnection(6); // 7h->5h AssertNoChanges(); genome.AddConnection(9); // 5h->6h AssertNoChanges(); genome.AddConnection(9); // 7h->6h AssertNoChanges(); genome.AddConnection(12); // 6h->7h genome.NetworkTopology.Links.Sum(l => l.Count).Should().Be(initialLinksCount + 1, "added allowed connection"); genome.NetworkTopology.LayerRanges.Should().BeEquivalentTo(initialLayers, "expected no changes in layer structure"); void AssertNoChanges() { genome.NetworkTopology.Links.Sum(l => l.Count).Should().Be(initialLinksCount, "expected no changes after adding recurrent connections"); genome.NetworkTopology.LayerRanges.Should().BeEquivalentTo(initialLayers, "expected no changes after adding recurrent connections"); } }
public void AddConnectionsOneByOneRecurrent() { (Genome genome, List <string> currentConnections, List <string> vacantConnections) CreateGenome() { // ReSharper disable once RedundantArgumentDefaultValue var parameters = new NetworkParameters(3, 1, NetworkType.Recurrent) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); var currentConnections = new List <string> { "0b->4e", "1s->4e", "2s->4e", "3s->4e", "4e->4e" }; var vacantConnections = new List <string>(); AssertCurrentConnections(genome, currentConnections); AssertVacantConnections(genome, vacantConnections); // Act genome.SplitConnection(0); currentConnections.ChangeCollection(new[] { "0b->4e" }, new[] { "0b->5h", "5h->4h" }); vacantConnections.AddRange(new[] { "0b->4e", "1s->5h", "2s->5h", "3s->5h", "5h->5h", "4e->5h" }); AssertCurrentConnections(genome, currentConnections); AssertVacantConnections(genome, vacantConnections); genome.SplitConnection(5); currentConnections.ChangeCollection(new[] { "0b->5h" }, new[] { "0b->6h", "6h->5h" }); vacantConnections.AddRange(new[] { "0b->5h", "1s->6h", "2s->6h", "3s->6h", "6h->6h", "5h->6h", "6h->4e", "4e->6h" }); AssertCurrentConnections(genome, currentConnections); AssertVacantConnections(genome, vacantConnections); genome.SplitConnection(1); currentConnections.ChangeCollection(new[] { "2s->4e" }, new[] { "2s->7h", "7h->4e" }); vacantConnections.AddRange(new[] { "2s->4e", "0b->7h", "1s->7h", "3s->7h", "7h->7h", "5h->7h", "6h->7h", "7h->6h", "7h->5h", "4e->7h" }); AssertCurrentConnections(genome, currentConnections); AssertVacantConnections(genome, vacantConnections); vacantConnections.Should().HaveCount(24); return(genome, currentConnections, vacantConnections); } var expectedAddStraightOrder = new[] { "0b->4e", "2s->4e", // outerConnections "0b->5h", "1s->5h", "2s->5h", "3s->5h", "4e->5h", "5h->5h", "7h->5h", // to 5h "1s->6h", "2s->6h", "3s->6h", "4e->6h", "5h->6h", "6h->6h", "7h->6h", // to 6h "0b->7h", "1s->7h", "3s->7h", "4e->7h", "5h->7h", "6h->7h", "7h->7h", // to 7h "6h->4e" // from hidden to effectors }; TestAddConnections(CreateGenome, expectedAddStraightOrder); }
public void SimpleNetworkCheck() { using (var source = RandomSource.DrillIn()) { // Arrange for (var i = 0; i < 10; i++) { source.PushNextFloats(0.6f); // identity weights and density chances } source.GetParanoid(); var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); var network = new RecurrentNetwork(); #region Network initialization network.AddNeuron(0, 0); network.AddNeuron(1, 0); network.AddNeuron(2, 0); network.AddNeuron(3, 0); network.AddNeuron(4, 1); network.AddConnection(0, 4, 1f); network.AddConnection(1, 4, 1f); network.AddConnection(2, 4, 1f); network.AddConnection(3, 4, 1f); network.AddConnection(4, 4, 1f); #endregion float[] result = null; for (var i = 0; i < 5; i++) { for (var j = 0; j < 3; j++) { genome.Network.Sensors[j] = 0.5f; } genome.Network.Activate(); result = network.Activate(new[] { 1f, 0.5f, 0.5f, 0.5f }); } Assert.Equal(result[0], genome.Network.Effectors[0]); } }
public void SplitConnectionTwoLayer() { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); // Act genome.SplitConnection(0); // 0 -> 4 into 0 -> 5 -> 4 genome.SplitConnection(5); // 0 -> 5 -> 4 into 0 -> 6 -> 5 -> 4 // Assert Assert.Equal(14, genome.VacantConnectionCount); }
public void CheckLinkResurrection() { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); // Act Assert.Equal(0, genome.VacantConnectionCount); var oldId = genome.NeatChromosome[1].Id; genome.RemoveConnection(1); Assert.Equal(1, genome.VacantConnectionCount); genome.AddConnection(0); // Assert Assert.Single(genome.NeatChromosome, gene => gene.Id == oldId); }
public void CheckDisjointsAndEtcAreTakenFromBest() { // TODO fix crossover, make this one green using (var source = RandomSource.DrillIn()) { // Arrange var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var best = new Genome(parameters, tracker, true); var worst = new Genome(parameters, tracker, true); best.SplitConnection(1); // Act source.GetParanoid(); source.PushLimitedNexts(0, 2); // crossover points - all from worst source.PushNextBools(true); // start from best var result = best.Mate(worst, CrossoverType.OnePoint); // Assert Assert.Equal(best.NeatChromosome.Count, result.NeatChromosome.Count); for (var i = 0; i < result.NeatChromosome.Count - 2; i++) { var parentGene = Assert.Single(worst.NeatChromosome, g => g.Id == result.NeatChromosome[i].Id); Assert.Equal(result.NeatChromosome[i].Weight, parentGene.Weight); } for (var i = result.NeatChromosome.Count - 2; i < result.NeatChromosome.Count; i++) { Assert.Equal(result.NeatChromosome[i].Id, best.NeatChromosome[i].Id); Assert.Equal(result.NeatChromosome[i].Weight, best.NeatChromosome[i].Weight); } } }
public void LayeredNetworkCheck() { var parameters = new NetworkParameters(3, 1) { InitialConnectionDensity = 1f }; var tracker = new InnovationTracker(NetworkParameters.BiasCount + parameters.SensorCount + parameters.EffectorCount); var genome = new Genome(parameters, tracker, false); genome.SplitConnection(0); genome.SplitConnection(2); genome.SplitConnection(genome.NeatChromosome.Single(g => g.SourceId == 5).Id); while (genome.VacantConnectionCount > 0) { genome.AddConnection(Neat.Utils.RandomSource.Next(genome.VacantConnectionCount)); } var network = new RecurrentNetwork(); void AddConnectionAndCopyWeight(int sourceId, int targetId) { var weight = genome.NeatChromosome.Single(g => g.SourceId == sourceId && g.TargetId == targetId).Weight; network.AddConnection(sourceId, targetId, weight); } #region Network initialization network.AddNeuron(0, 0); network.AddNeuron(1, 0); network.AddNeuron(2, 0); network.AddNeuron(3, 0); network.AddNeuron(5, 1); network.AddNeuron(6, 1); network.AddNeuron(7, 2); network.AddNeuron(4, 3); for (var i = 0; i < 4; i++) { for (var j = 4; j < 8; j++) { AddConnectionAndCopyWeight(i, j); } } for (var i = 4; i < 8; i++) { for (var j = 4; j < 8; j++) { AddConnectionAndCopyWeight(i, j); } } Assert.Equal(network.ConnectionsCount, genome.NeatChromosome.Count); #endregion float[] result = null; for (var i = 0; i < 5; i++) { var values = new[] { 1f, Neat.Utils.RandomSource.Next(), Neat.Utils.RandomSource.Next(), Neat.Utils.RandomSource.Next() }; for (var j = 0; j < 3; j++) { genome.Network.Sensors[j] = values[j + 1]; } genome.Network.Activate(); result = network.Activate(values); } Assert.Equal(result[0], genome.Network.Effectors[0]); }