private NEAT Crossover(NEAT dominant, NEAT submissive) { NEAT child = new NEAT(dominant); List <Connection> newConnections = new List <Connection>(); foreach (var connection in child.GetConnetionGenom()) { Connection c = submissive.GetConnetionGenom().Find(x => x.innovation == connection.innovation); if (c != null && Random.Range(0f, 1f) > 0.5f) { Node inNode = child.GetNodeGenom().Find(n => n.nodeID == c.inNode); Node outNode = child.GetNodeGenom().Find(n => n.nodeID == c.outNode); if (outNode == null && inNode != null) { outNode = new Node(c.outNode, inNode.order + 1, NodeType.Hidden); child.AddNode(outNode); } else if (outNode == null && inNode == null) { outNode = new Node(c.outNode, 1, NodeType.Hidden); child.AddNode(outNode); } if (inNode == null) { inNode = new Node(c.inNode, 0, NodeType.Hidden); child.AddNode(inNode); } Connection cNew = new Connection(inNode.nodeID, outNode.nodeID, c.weight, c.enabled, c.innovation); newConnections.Add(cNew); } } foreach (var connection in newConnections) { if (!CompareConnection(connection, child)) { if (!LoopSearch(connection, child.GetConnetionGenom())) { child.RemoveConnection(child.GetConnetionGenom().Find(n => n.innovation == connection.innovation)); child.AddConnection(connection); child.GetNodeGenom().Find(n => n.nodeID == connection.inNode).AddConnection(connection); } } } return(child); }
public void DrawNetwork(NEAT network) { List <Node> nodes = network.GetNodeGenom(); List <Connection> connections = network.GetConnetionGenom(); Dictionary <int, List <Node> > table = new Dictionary <int, List <Node> >(); linePositions = new Dictionary <LineRenderer, Connection>(); nodeToTrans = new Dictionary <int, RectTransform>(); int lastOrder = CalculateLargestOrder(nodes); for (int i = 0; i <= lastOrder; i++) { table.Add(i, new List <Node>()); } table.Add(lastOrder + 1, new List <Node>()); foreach (var node in nodes) { if (node.nodeType != NodeType.Output) { table[node.order].Add(node); } else { table[lastOrder + 1].Add(node); } } for (int i = 0; i < table.Count; i++) { table[i].Sort(delegate(Node a, Node b) { return(a.nodeID.CompareTo(b.nodeID)); }); } for (int i = 0; i <= lastOrder + 1; i++) { for (int j = 0; j < table[i].Count; j++) { CreateNode(new Vector2(i * ((panelBounds.x - bounds.x * 2) / (lastOrder + 1)), j * ((panelBounds.y - bounds.y * 1.5f) / table[i].Count)), table[i][j]); } } foreach (var connection in connections) { Vector3[] poses = new Vector3[2]; poses[0] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition); poses[1] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition); CreateConnection(poses, connection); } draw = true; }
public SaveBrain(NEAT neat, Vector2Int gridSize, Vector2 bucketSize, Vector2 offset) { this.gridSize = new int[2]; this.gridSize[0] = gridSize.x; this.gridSize[1] = gridSize.y; this.bucketSize = new float[2]; this.bucketSize[0] = bucketSize.x; this.bucketSize[1] = bucketSize.y; this.offset = new float[2]; this.offset[0] = offset.x; this.offset[1] = offset.y; innovation = neat.GetInnovation(); inputs = neat.GetInputSize(); outputs = neat.GetOutputsSize(); List <float> tempFloatsNodes = new List <float>(); List <float> tempFloatsConnections = new List <float>(); foreach (var node in neat.GetNodeGenom()) { //node vars tempFloatsNodes.Add(node.order); tempFloatsNodes.Add(node.nodeID); tempFloatsNodes.Add((int)node.nodeType); tempFloatsNodes.Add(node.activation); tempFloatsNodes.Add(node.sum); } foreach (var connection in neat.GetConnetionGenom()) { //connections vars tempFloatsConnections.Add(connection.inNode); tempFloatsConnections.Add(connection.outNode); tempFloatsConnections.Add(connection.weight); if (connection.enabled) { tempFloatsConnections.Add(1); } else { tempFloatsConnections.Add(0); } tempFloatsConnections.Add(connection.innovation); } floatNodes = tempFloatsNodes.ToArray(); floatConnections = tempFloatsConnections.ToArray(); }
public NEAT LoadBrain() { NEAT network = new NEAT(0, 0); network.SetSize(inputs, outputs); //create all nodes for (int i = 0; i < floatNodes.Length; i += 5) { Node current = new Node((int)floatNodes[i + 1], (int)floatNodes[i], (NodeType)(int)floatNodes[i + 2]); current.activation = floatNodes[i + 3]; current.sum = floatNodes[i + 4]; network.AddNode(current); } //create all connections for (int i = 0; i < floatConnections.Length; i += 5) { bool enable = floatConnections[i + 3] == 1 ? true : false; Connection current = new Connection((int)floatConnections[i], (int)floatConnections[i + 1], floatConnections[i + 2], enable, (int)floatConnections[i + 4]); Debug.Log(current.inNode + "Innode id, " + current.outNode + "outnode id, " + current.weight + "weight, " + current.innovation + "innovation"); network.AddConnection(current); } //add all connections to nodes foreach (var connection in network.GetConnetionGenom()) { Node currentNode = network.GetNodeGenom().Find(x => x.nodeID == connection.inNode); if (currentNode != null) { currentNode.AddConnection(connection); } } network.SetInnovation(innovation); return(network); }
private float CompareGenes(NEAT networkA, NEAT networkB) { if (networkA.GetConnetionGenom().Count == 0 && networkB.GetConnetionGenom().Count == 0) { return(0); } List <Connection> connectionsA = networkA.GetConnetionGenom(); List <Connection> connectionsB = networkB.GetConnetionGenom(); connectionsA.Sort(delegate(Connection a, Connection b) { return(a.innovation.CompareTo(b.innovation)); }); connectionsB.Sort(delegate(Connection a, Connection b) { return(a.innovation.CompareTo(b.innovation)); }); int diff = 0; int counterMax = 0; #region if (connectionsA.Count == 0 && connectionsB.Count != 0) { diff = connectionsB.Count; counterMax = connectionsB[connectionsB.Count - 1].innovation; } else if (connectionsB.Count == 0 && connectionsA.Count != 0) { diff = connectionsA.Count; counterMax = connectionsA[connectionsA.Count - 1].innovation; } else if (connectionsA.Count > 0 && connectionsB.Count > 0) { diff = connectionsA[connectionsA.Count - 1].innovation - connectionsB[connectionsB.Count - 1].innovation; counterMax = diff < 0 ? connectionsA[connectionsA.Count - 1].innovation : connectionsB[connectionsB.Count - 1].innovation; } #endregion int[] result = new int[counterMax]; for (int i = 1; i < counterMax; i++) { Connection A = connectionsA.Find(x => x.innovation == i); Connection B = connectionsB.Find(x => x.innovation == i); if (A != null && B != null) { result[i] = 1; continue; } result[i] = 0; } int disjoints = 0; foreach (int i in result) { if (i == 0) { disjoints++; } } float weigthSum = 0; counterMax = diff > 0 ? connectionsA.Count : connectionsB.Count; for (int i = 0; i < counterMax; i++) { float w1 = 0; float w2 = 0; if (i < connectionsA.Count) { w1 = connectionsA[i].weight; } if (i < connectionsB.Count) { w2 = connectionsB[i].weight; } weigthSum += Mathf.Abs(w1 - w1); } weigthSum /= counterMax; diff = Mathf.Abs(diff); int genomSumA = connectionsA.Count + networkA.GetNodeGenom().Count; int genomSumB = connectionsB.Count + networkB.GetNodeGenom().Count; if (genomSumA > genomSumB) { return(((excessFactor * diff) / genomSumA) + ((disjointFactor * disjoints) / genomSumA) + (weigthFactor * weigthSum)); } return(((excessFactor * diff) / genomSumB) + ((disjointFactor * disjoints) / genomSumB) + (weigthFactor * weigthSum)); }