示例#1
0
        // 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);
        }
示例#2
0
        // 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);
        }