public void AddGenomesToSpeciesTest() { UnitTests.RandomStub randomStub = new UnitTests.RandomStub(); Simulation sim = new Simulation(randomStub, gen, 10); // Create some fake species and genomes Species species1 = new Species(randomStub); // Two genomes are matching, one is not so we should get 2 species (with 2 and 1 Genomes respectively) Genome gen1 = new Genome(randomStub); Genome gen2 = new Genome(randomStub); Genome gen3 = new Genome(randomStub); gen3.ParentSimulation = sim; gen3.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen3.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen3.AddNode(new Node(Node.ENodeType.OUTPUT, 3)); gen3.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); gen3.AddConnectionGene(1, 2, true); gen3.AddConnectionGene(1, 3, true); gen3.AddConnectionGene(1, 4, true); sim.Species.Clear(); sim.AddGenomesToSpecies(new List <Genome> { gen1, gen2, gen3 }); Assert.AreEqual(2, sim.Species.Count); Assert.AreEqual(2, sim.Species[0].Genomes.Count); Assert.AreEqual(1, sim.Species[1].Genomes.Count); }
public static void Test4() { Genome genome = new Genome(); NeuralNetwork net; float[] input; float[] output; string logs = "======================TEST 4===================================\n\n"; genome = new Genome(); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, 0)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, 1)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, 2)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.OUTPUT, 3)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.HIDDEN, 4)); genome.AddConnectionGene(new ConnectionGene(0, 4, 0.4f, true, 0)); genome.AddConnectionGene(new ConnectionGene(1, 4, 0.7f, true, 1)); genome.AddConnectionGene(new ConnectionGene(2, 4, 0.1f, true, 2)); genome.AddConnectionGene(new ConnectionGene(4, 3, 1f, true, 3)); net = new NeuralNetwork(genome, Neuron.ActivationType.SIGMOID, false); input = new float[] { 0.5f, 0.75f, 0.90f }; for (int i = 0; i < 3; i++) { output = net.FeedForward(input); logs += "output is of length=" + output.Length + " and has output[0]=" + output[0] + " expecting 0.9924\n"; } Debug.Log(logs); }
// Use this for initialization void Start() { Genome parent3GenomeSimple = new Genome(); //Create the input nodes parent3GenomeSimple.AddNodeGene(new NodeGene(1, NodeGeneType.INPUT, 0f)); parent3GenomeSimple.AddNodeGene(new NodeGene(2, NodeGeneType.INPUT, 0f)); parent3GenomeSimple.AddNodeGene(new NodeGene(3, NodeGeneType.INPUT, 0f)); //Create the output node parent3GenomeSimple.AddNodeGene(new NodeGene(4, NodeGeneType.OUTPUT, 1f)); //Create connections parent3GenomeSimple.AddConnectionGene(new ConnectionGene(1, 4, 1.0, true, 1)); parent3GenomeSimple.AddConnectionGene(new ConnectionGene(2, 4, 1.0, true, 2)); parent3GenomeSimple.AddConnectionGene(new ConnectionGene(3, 4, 1.0, true, 3)); //Init the connection gene counter with 11 connectionCounter = new GeneCounter(4); nodeCounter = new GeneCounter(5); manager.Callback = this; manager.CreateInitialPopulation(parent3GenomeSimple, nodeCounter, connectionCounter, 100); }
/// <summary> /// Crossover of two parent genomes to procuce one child /// </summary> /// <param name="parent1">the more fit parent!</param> /// <param name="parent2">the less fit parent</param> /// <returns>the newly breed child genome</returns> public static Genome CrossOver(Genome parent1, Genome parent2) { Genome childGenome = new Genome(); //Copy nodes of the more fit parent foreach (NodeGene parent1Node in parent1.Nodes.Values) { childGenome.AddNodeGene(new NodeGene(parent1Node)); } //Iterate through every connection foreach (ConnectionGene parent1Connection in parent1.Connections.Values) { if (parent2.Connections.ContainsKey(parent1Connection.InnovationNumber)) { //Matching genes if (Random.Range(-1.0f, 1.0f) >= 0) { childGenome.AddConnectionGene(new ConnectionGene(parent1Connection)); } else { childGenome.AddConnectionGene(new ConnectionGene(parent2.Connections[parent1Connection.InnovationNumber])); } } else { //Distjoint or excess gene childGenome.AddConnectionGene(new ConnectionGene(parent1Connection)); } } return(childGenome); }
/// <summary> /// Create the start genome /// </summary> private void SetStartGenome() { _nodeCounter = new GeneCounter(0); _connectionCounter = new GeneCounter(0); _startGenome = new Genome(); int amountPlayerInputs = PlayerController.GetAmountOfInputs(_levelViewWidht, _levelViewHeight); List <NodeGene> tmpInputNodes = new List <NodeGene>(); //Crate input nodes for (int i = 0; i < amountPlayerInputs; i++) { NodeGene node = new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.SIGMOID); _startGenome.AddNodeGene(node); tmpInputNodes.Add(node); } //Create output nodes NodeGene outputNode1 = new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.OUTPUT, 1f, ActivationFunctionHelper.Function.SIGMOID); NodeGene outputNode2 = new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.OUTPUT, 1f, ActivationFunctionHelper.Function.SIGMOID); _startGenome.AddNodeGene(outputNode1); _startGenome.AddNodeGene(outputNode2); //Create connections for (int i = 0; i < amountPlayerInputs; i++) { _startGenome.AddConnectionGene(new ConnectionGene(tmpInputNodes[i].ID, outputNode1.ID, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(tmpInputNodes[i].ID, outputNode2.ID, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); } }
public void CompatibilityDistanceTest_TwoDifferentGenomes_3() { Simulation tmpSim = new Simulation(r, gen1, 1); Genome genCopy = gen1.Copy(); gen1.ParentSimulation = tmpSim; genCopy.ParentSimulation = tmpSim; // Change some weights and add connections genCopy.ConnectionGenes[0].Weight = 0.0f; genCopy.ConnectionGenes[1].Weight = 0.0f; genCopy.AddConnectionGene(1, 2, 0.0f); genCopy.AddConnectionGene(1, 3, 0.0f); float epsilon = 0.0001f; Assert.IsTrue(Genome.DisjointGenesCount(gen1, genCopy) == 2); float distance = Math.Abs(gen1.CompatibilityDistance(genCopy)); float weightDiff = 0.4f * (0.5f + 1.0f) / 6.0f; float expected = 2.0f + weightDiff; // -> 2 new genes (2 x 1.0) + average weight difference Assert.IsTrue(Math.Abs(distance - expected) < epsilon, String.Format("Expected {0}, got {1}", expected, distance)); }
public void AddConnectionTest_Null_ExpectectedException() { Simulation tmpSim = new Simulation(r, gen1, 1); gen1.ParentSimulation = tmpSim; gen1.AddConnectionGene(null); }
public void SetupTest() { r = new Random(0); // Genome 1 gen1 = new Genome(r); // Create 3 sensors gen1.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen1.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen1.AddNode(new Node(Node.ENodeType.SENSOR, 3)); // Create 1 output gen1.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); // Create 1 hidden node gen1.AddNode(new Node(Node.ENodeType.HIDDEN, 5)); // Add connections from the paper gen1.AddConnectionGene(1, 4, 0.5f); gen1.AddConnectionGene(2, 4, false); gen1.AddConnectionGene(3, 4); gen1.AddConnectionGene(2, 5); gen1.AddConnectionGene(5, 4); gen1.AddConnectionGene(1, 5, 8, true); // Genome 2 gen2 = new Genome(r); // Create 3 sensors gen2.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen2.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen2.AddNode(new Node(Node.ENodeType.SENSOR, 3)); // Create 1 output gen2.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); // Create 2 hidden nodes gen2.AddNode(new Node(Node.ENodeType.HIDDEN, 5)); gen2.AddNode(new Node(Node.ENodeType.HIDDEN, 6)); // Add connections from the paper gen2.AddConnectionGene(1, 4); gen2.AddConnectionGene(2, 4, false); gen2.AddConnectionGene(3, 4); gen2.AddConnectionGene(2, 5); gen2.AddConnectionGene(5, 4, false); gen2.AddConnectionGene(5, 6); gen2.AddConnectionGene(6, 4); gen2.AddConnectionGene(3, 5, 9, true); gen2.AddConnectionGene(1, 6, 10, true); }
public void CrossoverTest() { // Parent 1 Genome parent1 = new Genome(); for (int i = 0; i < 3; i++) { NodeGene node = new NodeGene(NodeGene.TYPE.INPUT, i + 1); parent1.AddNodeGene(node); } parent1.AddNodeGene(new NodeGene(NodeGene.TYPE.OUTPUT, 4)); parent1.AddNodeGene(new NodeGene(NodeGene.TYPE.HIDDEN, 5)); parent1.AddConnectionGene(new ConnectionGene(1, 4, 1f, true, 1)); parent1.AddConnectionGene(new ConnectionGene(2, 4, 1f, false, 2)); parent1.AddConnectionGene(new ConnectionGene(3, 4, 1f, true, 3)); parent1.AddConnectionGene(new ConnectionGene(2, 5, 1f, true, 4)); parent1.AddConnectionGene(new ConnectionGene(5, 4, 1f, true, 5)); parent1.AddConnectionGene(new ConnectionGene(1, 5, 1f, true, 8)); // Parent 2 (More Fit) Genome parent2 = new Genome(); for (int i = 0; i < 3; i++) { NodeGene node = new NodeGene(NodeGene.TYPE.INPUT, i + 1); parent2.AddNodeGene(node); } parent2.AddNodeGene(new NodeGene(NodeGene.TYPE.OUTPUT, 4)); parent2.AddNodeGene(new NodeGene(NodeGene.TYPE.HIDDEN, 5)); parent2.AddNodeGene(new NodeGene(NodeGene.TYPE.HIDDEN, 6)); parent2.AddConnectionGene(new ConnectionGene(1, 4, 1f, true, 1)); parent2.AddConnectionGene(new ConnectionGene(2, 4, 1f, false, 2)); parent2.AddConnectionGene(new ConnectionGene(3, 4, 1f, true, 3)); parent2.AddConnectionGene(new ConnectionGene(2, 5, 1f, true, 4)); parent2.AddConnectionGene(new ConnectionGene(5, 4, 1f, false, 5)); parent2.AddConnectionGene(new ConnectionGene(5, 6, 1f, true, 6)); parent2.AddConnectionGene(new ConnectionGene(6, 4, 1f, true, 7)); parent2.AddConnectionGene(new ConnectionGene(3, 5, 1f, true, 9)); parent2.AddConnectionGene(new ConnectionGene(1, 6, 1f, true, 10)); // Crossover Genome child = Genome.Crossover(parent2, parent1, new System.Random(), 0.75f); // Return Results Debug.Log(String.Format("PARENT 1\n{0}\n\nPARENT 2\n{1}\n\nCROSSOVER CHILD\n{2}", parent1.ToString(), parent2.ToString(), child.ToString())); }
public void EvaluatorTestInit() { Genome genome = new Genome(); int n1 = _nodeInnovation.GetNewInnovationNumber(); int n2 = _nodeInnovation.GetNewInnovationNumber(); int n3 = _nodeInnovation.GetNewInnovationNumber(); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, n1)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, n2)); genome.AddNodeGene(new NodeGene(NodeGene.TYPE.OUTPUT, n3)); int c1 = _connectionInnovation.GetNewInnovationNumber(); int c2 = _connectionInnovation.GetNewInnovationNumber(); genome.AddConnectionGene(new ConnectionGene(n1, n3, 0.5f, true, c1)); genome.AddConnectionGene(new ConnectionGene(n2, n3, 0.5f, true, c2)); _eval = new EvalutorTestEvaluator(_config, genome, _nodeInnovation, _connectionInnovation); }
public void InnovationNumberTest() { // Genome Genome gen1 = new Genome(r); Assert.IsTrue(gen1.GetInnovationNumber() == 0); // Create 3 sensors gen1.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen1.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen1.AddNode(new Node(Node.ENodeType.SENSOR, 3)); // Create 1 output gen1.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); // Create 1 hidden node gen1.AddNode(new Node(Node.ENodeType.HIDDEN, 5)); // Add connections from the paper gen1.AddConnectionGene(1, 4, 0.5f); Assert.IsTrue(gen1.GetInnovationNumber() == 1); gen1.AddConnectionGene(2, 4, false); Assert.IsTrue(gen1.GetInnovationNumber() == 2); gen1.AddConnectionGene(3, 4); Assert.IsTrue(gen1.GetInnovationNumber() == 3); gen1.AddConnectionGene(2, 5); Assert.IsTrue(gen1.GetInnovationNumber() == 4); gen1.AddConnectionGene(5, 4); Assert.IsTrue(gen1.GetInnovationNumber() == 5); gen1.AddConnectionGene(1, 5, true); Assert.IsTrue(gen1.GetInnovationNumber() == 6); }
// Use this for initialization void Start() { startingGenome = new Genome(); startingGenome.AddNodeGene(new NodeGene(0, NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); startingGenome.AddNodeGene(new NodeGene(1, NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); startingGenome.AddNodeGene(new NodeGene(2, NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); startingGenome.AddNodeGene(new NodeGene(3, NodeGeneType.OUTPUT, 1f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); startingGenome.AddConnectionGene(new ConnectionGene(0, 3, Random.Range(0f, 1f), true, 0)); startingGenome.AddConnectionGene(new ConnectionGene(1, 3, Random.Range(0f, 1f), true, 1)); startingGenome.AddConnectionGene(new ConnectionGene(2, 3, Random.Range(0f, 1f), true, 2)); //Nodes for a complete network /* * startingGenome.AddNodeGene(new NodeGene(4, NodeGeneType.HIDDEN, 0.5f)); * startingGenome.AddNodeGene(new NodeGene(5, NodeGeneType.HIDDEN, 0.5f)); * * startingGenome.AddConnectionGene(new ConnectionGene(0, 4, Random.Range(0f, 1f), true, 0)); * startingGenome.AddConnectionGene(new ConnectionGene(0, 5, Random.Range(0f, 1f), true, 1)); * startingGenome.AddConnectionGene(new ConnectionGene(1, 4, Random.Range(0f, 1f), true, 2)); * startingGenome.AddConnectionGene(new ConnectionGene(1, 5, Random.Range(0f, 1f), true, 3)); * * startingGenome.AddConnectionGene(new ConnectionGene(4, 3, Random.Range(0f, 1f), true, 4)); * startingGenome.AddConnectionGene(new ConnectionGene(5, 3, Random.Range(0f, 1f), true, 5)); * * startingGenome.AddConnectionGene(new ConnectionGene(2, 3, Random.Range(0f, 1f), true, 6)); * startingGenome.AddConnectionGene(new ConnectionGene(2, 4, Random.Range(0f, 1f), true, 7)); * startingGenome.AddConnectionGene(new ConnectionGene(2, 5, Random.Range(0f, 1f), true, 8)); */ result = new List <int>(); _manager = new PopulationManager(); _manager.Callback = this; _manager.CreateInitialPopulation(startingGenome, new GeneCounter(6), new GeneCounter(9), 400, true); }
public static Genome Crossover(Genome parent1, Genome parent2) { Genome child = new Genome(); foreach (NodeGene parent1Node in parent1.GetNodeGenes().Values) { child.AddNodeGene(parent1Node.Clone()); } foreach (ConnectionGene parent1Node in parent1.GetConnectionGenes().Values) { if (parent2.GetConnectionGenes().ContainsKey(parent1Node.innovation)) //matching gene { child.AddConnectionGene(Random.value < 0.5f ? parent1Node.Clone() : parent2.GetConnectionGenes()[parent1Node.innovation].Clone()); } else { child.AddConnectionGene(parent1Node.Clone()); } } return(child); }
public static void MutateAddNode(this Genome genome) { var connection = genome.ConnectionGenes.Values.Where(cg => cg.IsEnabled).GetRandomElement(); if (connection == null) { return; } var newNode = new NodeGene(); genome.AddNodeGene(newNode); var newPreviousConnection = new ConnectionGene(connection.PreviousNodeId, newNode.Id, 1); genome.AddConnectionGene(newPreviousConnection); var newNextConnection = new ConnectionGene(newNode.Id, connection.NextNodeId, connection.Weight); genome.AddConnectionGene(newNextConnection); connection.Toggle(false); }
public void TestAddNodeMutation() { Simulation tmpSim = new Simulation(r, gen1, 1); gen1.ParentSimulation = tmpSim; List <Innovation> innovations = new List <Innovation>(); Genome gen3 = new Genome(r); gen3.ParentSimulation = tmpSim; gen3.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen3.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen3.AddNode(new Node(Node.ENodeType.OUTPUT, 3)); gen3.AddConnectionGene(1, 3, 0.5f); gen3.AddConnectionGene(2, 3, 1.0f); Assert.IsTrue(gen3.Nodes.Count == 3); gen3.AddNodeMutation(innovations); Assert.IsTrue(gen3.Nodes.Count == 4); }
public void FindConnectionGeneToSplitTest_NoEnabledGenes_Expected_False() { Genome genome = new Genome(r); genome.AddNode(new Node(Node.ENodeType.SENSOR, 1)); genome.AddNode(new Node(Node.ENodeType.OUTPUT, 2)); genome.AddConnectionGene(1, 2, false); int connectionIndex = -1; bool found = genome.FindConnectionGeneToSplit(out connectionIndex); Assert.AreEqual(false, found); Assert.AreEqual(-1, connectionIndex); }
public void TestAddConnectionMutation() { List <Innovation> innovations = new List <Innovation>(); Simulation tmpSim = new Simulation(r, gen1, 1); gen1.ParentSimulation = tmpSim; Genome gen4 = new Genome(r); gen4.ParentSimulation = tmpSim; // Create 3 sensors gen4.AddNode(new Node(Node.ENodeType.SENSOR, 1)); gen4.AddNode(new Node(Node.ENodeType.SENSOR, 2)); gen4.AddNode(new Node(Node.ENodeType.SENSOR, 3)); // Create 1 output gen4.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); // Create 1 hidden node gen4.AddNode(new Node(Node.ENodeType.HIDDEN, 5)); // Add connections from the paper gen4.AddConnectionGene(1, 4); gen4.AddConnectionGene(2, 4); gen4.AddConnectionGene(3, 4); gen4.AddConnectionGene(2, 5); gen4.AddConnectionGene(5, 4); Assert.IsTrue(gen4.ConnectionGenes.Count == 5); gen4.AddConnectionMutation(innovations); Assert.IsTrue(gen4.ConnectionGenes.Count == 6); }
public static Genome Crossover(Genome parent1, Genome parent2) { // parent1 always more fit parent - no equal fitness parents System.Random rand = new System.Random(); Genome offspring = new Genome(); foreach (NodeGene parent1Node in parent1.GetNodes().Values) { offspring.AddNodeGene(parent1Node.CopyNode()); } foreach (ConnectionGene parent1Connection in parent1.GetConnections().Values) { if (parent2.GetConnections().ContainsKey(parent1Connection.getInnovation())) { offspring.AddConnectionGene((rand.NextDouble() > 0.5) ? parent1Connection.CopyConnection() : parent2.GetConnections()[parent1Connection.getInnovation()].CopyConnection()); } else { offspring.AddConnectionGene(parent1Connection.CopyConnection()); } } return(offspring); }
public static Genome Clone(Genome genome) { Genome child = new Genome(); foreach (NodeGene node in genome.GetNodeGenes().Values) { child.AddNodeGene(node.Clone()); } foreach (ConnectionGene con in genome.GetConnectionGenes().Values) { child.AddConnectionGene(con.Clone()); } return(child); }
public void CompatibilityDistanceTest_TwoDifferentGenomes_2() { Simulation tmpSim = new Simulation(r, gen1, 1); Genome genCopy = gen1.Copy(); gen1.ParentSimulation = tmpSim; genCopy.ParentSimulation = tmpSim; genCopy.AddConnectionGene(1, 2, 0.0f); float epsilon = 0.0001f; Assert.IsTrue(Genome.DisjointGenesCount(gen1, genCopy) == 1); float distance = Math.Abs(gen1.CompatibilityDistance(genCopy)); Assert.IsTrue(Math.Abs(distance - 1.0f) < epsilon, String.Format("Expected {0}, got {1}", 1.0f, distance)); }
public void FindConnectionGeneToSplitTest_Correct_Expected_True() { UnitTests.RandomStub randomStub = new UnitTests.RandomStub(); randomStub.NextIntValue = 0; randomStub.NextDoubleValue = 0.0; Genome genome = new Genome(randomStub); genome.AddNode(new Node(Node.ENodeType.SENSOR, 1)); genome.AddNode(new Node(Node.ENodeType.OUTPUT, 2)); genome.AddConnectionGene(1, 2, true); int connectionIndex = -1; bool found = genome.FindConnectionGeneToSplit(out connectionIndex); Assert.AreEqual(true, found); Assert.AreEqual(0, connectionIndex); }
public static void MutateAddConnection(this Genome genome, bool forceBias = false) { NodeGene firstNode; if (forceBias) { firstNode = genome.NodeGenes.Values.Where(g => g.Type == NodeGeneType.Input).Last(); } else { firstNode = genome.NodeGenes.Values.GetRandomElement(); } var secondNode = genome.NodeGenes.Values.GetRandomElement(); // TODO: Fix this hack that prevent possible endless loop int limiter = 0; while (firstNode.Id == secondNode.Id || genome.ConnectionGenes.GetConnection(firstNode, secondNode) != null || firstNode.Type == NodeGeneType.Input && secondNode.Type == NodeGeneType.Input || firstNode.Type == NodeGeneType.Output && secondNode.Type == NodeGeneType.Output) { secondNode = genome.NodeGenes.Values.GetRandomElement(); if (limiter > 100) { return; } limiter++; } if (firstNode.Type == NodeGeneType.Output && secondNode.Type == NodeGeneType.Hidden || firstNode.Type == NodeGeneType.Hidden && secondNode.Type == NodeGeneType.Input || firstNode.Type == NodeGeneType.Output && secondNode.Type == NodeGeneType.Input) { var tmp = secondNode; secondNode = firstNode; firstNode = tmp; } var newConnection = new ConnectionGene(firstNode.Id, secondNode.Id); genome.AddConnectionGene(newConnection); }
public Genome InitGenome() { Genome g1 = new Genome(gt); for (int i = 0; i < inputSize + outputSize; i++) { NodeGene node = GetDeafultGenome().GetNodeGenes()[i].Copy(); if (node.GetNodeType() == NodeGene.NODETYPE.OUTPUT || node.GetNodeType() == NodeGene.NODETYPE.HIDDEN) { node.SetBias(Random.Range(-1.0f, 1.0f)); //node.SetBias(1.0f); } g1.AddNodeGene(node); //g1.GetNodeGenes()[inputSize + i].SetBias(Random.Range(-1.0f, 1.0f)); } for (int i = 0; i < startConnections; i++)//sample n connections { ConnectionGene con = connections[Random.Range(0, connections.Count)].Copy(); //ConnectionGene con = connections[i].Copy(); con.SetWeight(Random.Range(-weightRange, weightRange)); //con.SetWeight(1.0f); int inId = con.GetInNode().GetId(); con.SetInNode(g1.GetNodeGenes()[inId]); int outId = con.GetOutNode().GetId(); //Debug.Log(con.GetOutNode()); //Debug.Log(outId); con.SetOutNode(g1.GetNodeGenes()[outId]); g1.AddConnectionGene(con); } if (speciation) { InsertGenomeIntoSpecies(g1, species); impf.StatsSpecies(species.Count); } genomes.Add(g1); return(g1); }
public Genome Copy() { Genome g = new Genome(track); List <NodeGene> nodesList = new List <NodeGene>(); for (int i = 0; i < nodes.Count; i++) { nodesList.Add(nodes[i].Copy()); g.AddNodeGene(nodesList[i]); } List <ConnectionGene> connectionsList = new List <ConnectionGene>(); for (int i = 0; i < connections.Count; i++) { connectionsList.Add(connections[i].Copy()); connectionsList[i].SetInNode(g.FindNode(connections[i].GetInNode().GetId())); connectionsList[i].SetOutNode(g.FindNode(connections[i].GetOutNode().GetId())); //Debug.Log(connectionsList[i]); g.AddConnectionGene(connectionsList[i]); } g.SetLayers(layers); return(g); }
public Genome CrossoverGenes(Genome genome1, Genome genome2, GeneTracker track) { Genome child = new Genome(track); List <NodeGene> newNodeGenes = new List <NodeGene>(); //for (int i = 0; i < genome1.GetNodeGenes().Count; i++) //{ // commonNodeGenes.Add(genome1.GetNodeGenes()[i].Copy()); //} //for (int i = 0; i < genome2.GetNodeGenes().Count; i++) //{ // if (!commonNodeGenes.Contains(genome2.GetNodeGenes()[i])) // { // commonNodeGenes.Add(genome2.GetNodeGenes()[i].Copy()); // } //} if (genome1.GetFitness() < genome2.GetFitness()) {//swap so genome1 has the higher fitness Genome temp = genome2; genome2 = genome1; genome1 = temp; } //Debug.Log("g1 "+genome1+ "\ng2 " + genome2); child.SetLayers(genome1.GetLayers()); /* * for (int i = 0; i < genome1.GetNodeGenes().Count; i++) { * for (int i2 = 0; i2 < genome2.GetNodeGenes().Count; i2++) * { * * * } * } */ for (int i = 0; i < genome1.GetNodeGenes().Count; i++) { newNodeGenes.Add(genome1.GetNodeGenes()[i].Copy()); } for (int i = 0; i < genome2.GetNodeGenes().Count; i++) { if (newNodeGenes.Contains(genome2.GetNodeGenes()[i])) { if (Random.Range(0, 2) == 1) { // newNodeGenes.RemoveAt(newNodeGenes.IndexOf(genome2.GetNodeGenes()[i])); //newNodeGenes.Add(genome2.GetNodeGenes()[i].Copy()); newNodeGenes[newNodeGenes.IndexOf(genome2.GetNodeGenes()[i])].SetBias(genome2.GetNodeGenes()[i].GetBias()); } } } for (int i = 0; i < genome1.GetNodeGenes().Count; i++) { child.AddNodeGene(newNodeGenes[i]); } List <ConnectionGene> newConnectionGenes = new List <ConnectionGene>(); //if equal choose random for (int i = 0; i < genome1.GetConnectionGenes().Count; i++) //copy all connections { newConnectionGenes.Add(genome1.GetConnectionGenes()[i].Copy()); newConnectionGenes[i].SetInNode(child.FindNode(genome1.GetConnectionGenes()[i].GetInNode().GetId())); newConnectionGenes[i].SetOutNode(child.FindNode(genome1.GetConnectionGenes()[i].GetOutNode().GetId())); } for (int i = 0; i < genome2.GetConnectionGenes().Count; i++) { //Debug.Log(newConnectionGenes.Contains(genome2.GetConnectionGenes()[i])); if (newConnectionGenes.Contains(genome2.GetConnectionGenes()[i])) { //Debug.Log(Random.Range(0, 2) ); if (Random.Range(0, 2) == 1) { //newConnectionGenes.RemoveAt(newConnectionGenes.IndexOf(genome2.GetConnectionGenes()[i])); //newConnectionGenes.Add(genome2.GetConnectionGenes()[i].Copy()); //newConnectionGenes[i].SetWeight(genome2.GetConnectionGenes()[i].GetWeight()); //Debug.Log(newConnectionGenes[newConnectionGenes.IndexOf(genome2.GetConnectionGenes()[i])].GetWeight()); newConnectionGenes[newConnectionGenes.IndexOf(genome2.GetConnectionGenes()[i])].SetWeight(genome2.GetConnectionGenes()[i].GetWeight()); } } } for (int i = 0; i < genome1.GetConnectionGenes().Count; i++) { child.AddConnectionGene(newConnectionGenes[i]); } //Debug.Log("child "+child); return(child); }
private void CreateStartingGenomeAndEvaluator() { // Create New Genome Genome genome = new Genome(config.newWeightRange, config.perturbingProbability); // Check there is at least 1 Input & 1 Output Nodes if (config.inputNodeNumber == 0) { config.inputNodeNumber = 1; } if (config.outputNodeNumber == 0) { config.outputNodeNumber = 1; } // Create Input Nodes for (int i = 0; i < config.inputNodeNumber; i++) { genome.AddNodeGene(new NodeGene(NodeGene.TYPE.INPUT, _nodeInnovation.GetNewInnovationNumber())); } // Create Hidden Nodes foreach (int nb in config.hiddenNodeStartNumberByLayer) { for (int i = 0; i < nb; ++i) { genome.AddNodeGene(new NodeGene(NodeGene.TYPE.HIDDEN, _nodeInnovation.GetNewInnovationNumber())); } } // Create Output Nodes for (int i = 0; i < config.outputNodeNumber; i++) { genome.AddNodeGene(new NodeGene(NodeGene.TYPE.OUTPUT, _nodeInnovation.GetNewInnovationNumber())); } // Create Connections if (config.addConnectionOnCreation) { if (config.hiddenNodeStartNumberByLayer.Count > 0) { int inputStartId = 0; int previousHiddenStatId = 0; int previousHiddenStopId = 0; int hiddenStartId = config.inputNodeNumber; int hiddenStopId = config.inputNodeNumber; int outputStartId = genome.Nodes.Count - config.outputNodeNumber; // Loop through Hidden Layers for (int hiddenLayer = 0; hiddenLayer < config.hiddenNodeStartNumberByLayer.Count; hiddenLayer++) { // Get Hidden Start & Stop Ids if (hiddenLayer > 0) { hiddenStartId += config.hiddenNodeStartNumberByLayer[hiddenLayer - 1]; } hiddenStopId += config.hiddenNodeStartNumberByLayer[hiddenLayer]; // Loop through Nodes of the current Layer for (int hiddenNodeId = hiddenStartId; hiddenNodeId < hiddenStopId; ++hiddenNodeId) { // If current Hidden Layer is the first Layer if (hiddenLayer == 0) { // Add Connections from Inputs to First Hidden Layer for (int inputNodeId = inputStartId; inputNodeId < config.inputNodeNumber; ++inputNodeId) { genome.AddConnectionGene(new ConnectionGene(inputNodeId, hiddenNodeId, Random.Range(config.newWeightRange.x, config.newWeightRange.y), true, _connectionInnovation.GetNewInnovationNumber())); } } else { // Add Connections from previous Hidden Layer to current Hidden Layer for (int previousHiddenNodeId = previousHiddenStatId; previousHiddenNodeId < previousHiddenStopId; ++previousHiddenNodeId) { genome.AddConnectionGene(new ConnectionGene(previousHiddenNodeId, hiddenNodeId, Random.Range(config.newWeightRange.x, config.newWeightRange.y), true, _connectionInnovation.GetNewInnovationNumber())); } // If current Hidden Layer is the last Layer if (hiddenLayer + 1 == config.hiddenNodeStartNumberByLayer.Count) { // Add Connections from Last Hidden Layer to Outputs for (int outputNodeId = outputStartId; outputNodeId < genome.Nodes.Count; ++outputNodeId) { genome.AddConnectionGene(new ConnectionGene(hiddenNodeId, outputNodeId, Random.Range(config.newWeightRange.x, config.newWeightRange.y), true, _connectionInnovation.GetNewInnovationNumber())); } } } } // Save previous Hidden Layer Start & Stop Ids previousHiddenStatId = hiddenStartId; previousHiddenStopId = hiddenStopId; } } else { int outputStartId = config.inputNodeNumber; int outputStopId = config.inputNodeNumber + config.outputNodeNumber; // Loop Input Node for (int inputNodeId = 0; inputNodeId < outputStartId; ++inputNodeId) { // Loop Output Node & add Connection between Input Node & Hidden Node for (int outputNodeId = outputStartId; outputNodeId < outputStopId; ++outputNodeId) { genome.AddConnectionGene(new ConnectionGene(inputNodeId, outputNodeId, Random.Range(config.newWeightRange.x, config.newWeightRange.y), true, _connectionInnovation.GetNewInnovationNumber())); } } } } _startingGenome = genome; Debug.Log("Starting Genome:\n" + genome.ToString()); // Create Evaluator _evaluator = new CreatureEvaluator(config, genome, _nodeInnovation, _connectionInnovation); }
public void LoadGenome(string filename, bool all) { string path = filename; Genome genome = new Genome(); using (StreamReader reader = new StreamReader(path)) { bool node = false; bool connection = false; string line; while ((line = reader.ReadLine()) != null) { if (line.Equals("Nodes")) { node = true; connection = false; } else if (line.Equals("Connections")) { node = false; connection = true; } else { string[] info = line.Split(','); if (node) { int id = int.Parse(info[0]); NodeGene.Type type = (NodeGene.Type)System.Enum.Parse(typeof(NodeGene.Type), info[1]); GenomeUtils.Activation activation = (GenomeUtils.Activation)System.Enum.Parse(typeof(GenomeUtils.Activation), info[2]); genome.AddNodeGene(new NodeGene(type, id, activation)); Counter.SetNodeCounter(id); } else if (connection) { int innovation = int.Parse(info[0]); bool expressed = bool.Parse(info[1]); int inNode = int.Parse(info[2]); int outNode = int.Parse(info[3]); float weight = float.Parse(info[4]); genome.AddConnectionGene(new ConnectionGene(inNode, outNode, weight, expressed, innovation)); Counter.SetConnectionCounter(innovation); } else { Debug.LogError("Invalid genome file"); } } } } genomes.Clear(); genomes.Add(genome); if (all) { for (int i = 1; i < GenomeUtils.POP_SIZE; i++) { genomes.Add(GenomeUtils.Clone(genome)); } } else { for (int i = 1; i < GenomeUtils.POP_SIZE; i++) { genomes.Add(new Genome(inputNodes, outputNodes)); } } SetSpecies(); MakeNNets(); }
/// <summary> /// Create the start genome /// </summary> private void SetStartGenome() { _nodeCounter = new GeneCounter(0); _connectionCounter = new GeneCounter(0); _startGenome = new Genome(); //5 input nodes + 1 bias node _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.INPUT, 0f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); //OutputNodes _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.OUTPUT, 1f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); _startGenome.AddNodeGene(new NodeGene(_nodeCounter.GetNewNumber(), NodeGeneType.OUTPUT, 1f, ActivationFunctionHelper.Function.STEEPENED_SIGMOID)); //Add connections to first output nde _startGenome.AddConnectionGene(new ConnectionGene(0, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(1, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(2, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(3, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(4, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(5, 6, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); //Connection to second ouztputNode _startGenome.AddConnectionGene(new ConnectionGene(0, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(1, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(2, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(3, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(4, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); _startGenome.AddConnectionGene(new ConnectionGene(5, 7, Random.Range(-1f, 1f), true, _connectionCounter.GetNewNumber())); }
private static void PoleBalanceSingleTest(Random r) { Genome startGenome = new Genome(r); startGenome.AddNode(new Node(Node.ENodeType.SENSOR, 1)); startGenome.AddNode(new Node(Node.ENodeType.SENSOR, 2)); startGenome.AddNode(new Node(Node.ENodeType.SENSOR, 3)); startGenome.AddNode(new Node(Node.ENodeType.SENSOR, 4)); startGenome.AddNode(new Node(Node.ENodeType.SENSOR, 5)); startGenome.AddNode(new Node(Node.ENodeType.OUTPUT, 6)); startGenome.AddNode(new Node(Node.ENodeType.OUTPUT, 7)); startGenome.AddConnectionGene(1, 6, 0.0f); startGenome.AddConnectionGene(2, 6, 0.0f); startGenome.AddConnectionGene(3, 6, 0.0f); startGenome.AddConnectionGene(4, 6, 0.0f); startGenome.AddConnectionGene(5, 6, 0.0f); startGenome.AddConnectionGene(1, 7, 0.0f); startGenome.AddConnectionGene(2, 7, 0.0f); startGenome.AddConnectionGene(3, 7, 0.0f); startGenome.AddConnectionGene(4, 7, 0.0f); startGenome.AddConnectionGene(5, 7, 0.0f); // Run simulation Simulation sim = new Simulation(r, startGenome, 150); int numberOfRuns = 200; int numnodes; // Used to figure out how many nodes should be visited during activation int thresh; // How many visits will be allowed before giving up (for loop detection) int MAX_STEPS = 100000; bool solutionFound = false; Genome bestGenome = null; for (int i = 0; i < numberOfRuns; ++i) { double epochBestFitness = 0.0f; float avgConnectionGenes = 0.0f; // Evaluate all genomes foreach (Genome gen in sim.Genomes) { Network network = gen.GetNetwork(); numnodes = gen.Nodes.Count; thresh = numnodes * 2; gen.Fitness = Go_cart(network, MAX_STEPS, thresh, r); if (gen.Fitness > epochBestFitness) { epochBestFitness = gen.Fitness; } avgConnectionGenes += gen.ConnectionGenes.Count; if (gen.Fitness >= MAX_STEPS) { bestGenome = gen; solutionFound = true; break; } } avgConnectionGenes /= sim.Genomes.Count; Console.WriteLine(String.Format("Epoch {0} | best: {1} | avg genes: {2} | species: {3}", i, epochBestFitness, avgConnectionGenes, sim.Species.Count)); if (solutionFound) { break; } sim.Epoch(); } if (solutionFound) { Console.WriteLine(String.Format("Solution network nodes count: {0} | connections count: {1}", bestGenome.Nodes.Count, bestGenome.ConnectionGenes.Count)); } else { Console.WriteLine("Solution NOT found!"); } }
private static void XorTest(Random r) { Genome xorGene = new Genome(r); xorGene.AddNode(new Node(Node.ENodeType.SENSOR, 1)); xorGene.AddNode(new Node(Node.ENodeType.SENSOR, 2)); xorGene.AddNode(new Node(Node.ENodeType.SENSOR, 3)); xorGene.AddNode(new Node(Node.ENodeType.OUTPUT, 4)); xorGene.AddConnectionGene(1, 4, 0.0f); xorGene.AddConnectionGene(2, 4, 0.0f); xorGene.AddConnectionGene(3, 4, 0.0f); // Run simulation Simulation sim = new Simulation(r, xorGene, 150); sim.Parameters.AreConnectionWeightsCapped = false; sim.Parameters.MaxWeight = 1.0f; sim.Parameters.WeightMutationPower = 2.5f; int numberOfRuns = 200; bool solutionFound = false; Genome bestGenome = null; float[] output = { 0.0f, 0.0f, 0.0f, 0.0f }; float[] bestOutput = new float[4]; float[,] input = { { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } }; for (int i = 0; i < numberOfRuns; ++i) { double epochBestFitness = 0.0f; float avgConnectionGenes = 0.0f; // Evaluate all genomes foreach (Genome gen in sim.Genomes) { Network network = gen.GetNetwork(); //network.ActivationFunction = new NeuralEvolution.ActivationFunctions.ReLU(); bool couldActivate = true; for (int inputIdx = 0; inputIdx < 4; ++inputIdx) { float[] inputRow = new float[3]; for (int k = 0; k < 3; ++k) { inputRow[k] = input[inputIdx, k]; } network.SetInput(inputRow); if (!network.Activate()) { couldActivate = false; } // Relax network int networkDepth = network.GetMaxDepth(); for (int relax = 0; relax <= networkDepth; ++relax) { network.Activate(); } output[inputIdx] = network.Output[0].Activation; network.Reset(); } float errorsum = (float)(Math.Abs(output[0]) + Math.Abs(1.0 - output[1]) + Math.Abs(1.0 - output[2]) + Math.Abs(output[3])); if (!couldActivate) { errorsum = 4; } gen.Fitness = Math.Pow((4.0 - errorsum), 2); gen.Error = errorsum; if (gen.Fitness > epochBestFitness) { bestOutput[0] = output[0]; bestOutput[1] = output[1]; bestOutput[2] = output[2]; bestOutput[3] = output[3]; epochBestFitness = gen.Fitness; } avgConnectionGenes += gen.ConnectionGenes.Count; if ((output[0] < 0.5f) && (output[1] >= 0.5f) && (output[2] >= 0.5f) && (output[3] < 0.5f)) { bestOutput[0] = output[0]; bestOutput[1] = output[1]; bestOutput[2] = output[2]; bestOutput[3] = output[3]; bestGenome = gen; solutionFound = true; break; } } avgConnectionGenes /= sim.Genomes.Count; Console.WriteLine(String.Format("Epoch {0} | best: {1} | best output: [{2}, {3}, {4}, {5}] | avg genes: {6} | species: {7}", i, epochBestFitness, bestOutput[0], bestOutput[1], bestOutput[2], bestOutput[3], avgConnectionGenes, sim.Species.Count)); // We found a solution so we can exit already if (solutionFound) { break; } // Advance to the next step of simulation sim.Epoch(); } if (solutionFound) { Console.WriteLine(String.Format("Solution found: [{0}, {1}, {2}, {3}]", bestOutput[0], bestOutput[1], bestOutput[2], bestOutput[3])); Console.WriteLine(String.Format("Solution network nodes count: {0} | connections count: {1}", bestGenome.Nodes.Count, bestGenome.ConnectionGenes.Count)); } else { Console.WriteLine("Solution NOT found!"); } }