// Add new connection to the network public Result AddConnection() { // Select a random node which will have an extra connections // Do not select nodes in the output layer // Check if network is fully connected if (IsNetworkFullyConnected()) { return(Result.fail); } Node fromNode = null; do { // Select a random node int rndNodeNumb = MyRand.Next(0, Nodes.Count); fromNode = Nodes[rndNodeNumb]; //Find new node if this node is fully connected, OR in the output layer } while(IsNodeInOutputLayer(fromNode) || IsNodeFullyConnected(fromNode) ); // Find a node to connect to Node toNode = null; do { // Select a random node int rndNodeNumb = MyRand.Next(0, Nodes.Count); toNode = Nodes[rndNodeNumb]; // Find new node if this node is in the same layer, OR both already connected } while((toNode.Layer == fromNode.Layer) || (IsConnected(fromNode, toNode)) ); //If the tonode is in a lower layer than the fromnode, change positon if (toNode.Layer < fromNode.Layer) { Node tmp = toNode; toNode = fromNode; fromNode = tmp; } // Add connections between the two nodes with random weight Connection newConn = new Connection(fromNode); newConn.ONode = toNode; fromNode.Connections.Add(newConn); Connections.Add(newConn); // Assign innovation ID for new connection InnovationHandler.GetInnovationID(newConn); return(Result.success); }
// Add new node on an existing connection public Result AddNode() { if (Connections.Count == 0) { //Cannot Add new node return(Result.fail); } //Get a random connection, it can be disabled too int rndConnNumb = MyRand.Next(0, Connections.Count); Connection rndConn = Connections[rndConnNumb]; //Deactivate this connection rndConn.Enabled = false; //Add a new node on it Node newNode = new Node(NodeCnt); NodeCnt++; newNode.Layer = rndConn.INode.Layer + 1; //Connect INode and new node Connection conn1 = new Connection(rndConn.INode); conn1.Weight = 1.0; conn1.Bias = 0.0; conn1.Enabled = true; conn1.ONode = newNode; InnovationHandler.GetInnovationID(conn1); rndConn.INode.Connections.Add(conn1); //TODO i could consider if the connection was disabled to create two "low" effect connections //Connect new node and Onode Connection conn2 = new Connection(newNode); conn2.Weight = rndConn.Weight; conn2.Bias = rndConn.Bias; conn2.Enabled = true; conn2.ONode = rndConn.ONode; InnovationHandler.GetInnovationID(conn2); newNode.Connections.Add(conn2); //If the connection we are breaking is between layers that are next to eachother //it means we need to add a new layer //else we need to increase the first intermediate layer if ((rndConn.INode.Layer + 1) == rndConn.ONode.Layer) { //New layer is needed //Shift every layer by one after the new layer foreach (var node in Nodes) { if (node.Layer > rndConn.INode.Layer) { node.Layer++; } } OutputLayer++; } else if ((rndConn.INode.Layer + 1) < rndConn.ONode.Layer) { //Layer should already exist } else { throw new Exception("Error: The connection is wrong!"); } //Finally add new object to the lists Nodes.Add(newNode); Connections.Add(conn1); Connections.Add(conn2); return(Result.success); }