Esempio n. 1
0
 /// <summary>
 /// Adds Connection (Structural Mutation) to Genome from Nodes
 /// </summary>
 /// <param name="nodeFrom">From-Node for Connection</param>
 /// <param name="nodeTo">To-Node for Connection</param>
 internal void MutateAddConnection(NodeGene nodeFrom, NodeGene nodeTo)
 {
     if (!nodeFrom.IsValid)
     {
         throw new ArgumentException("NodeFrom is Invalid", "nodeFrom");
     }
     if (!nodeTo.IsValid)
     {
         throw new ArgumentException("NodeTo is Invalid", "nodeTo");
     }
     if (nodeFrom.Equals(nodeTo))
     {
         throw new ArgumentException("Cannot create Connection with a single Node");
     }
     if (!Nodes.ContainsKey(nodeFrom.Innovation))
     {
         throw new ArgumentException("Node does not exist in Genome", "nodeFrom");
     }
     if (!Nodes.ContainsKey(nodeTo.Innovation))
     {
         throw new ArgumentException("Node does not exist in Genome", "nodeTo");
     }
     if (nodeFrom.Type == NodeType.OUTPUT || nodeTo.Type == NodeType.INPUT)
     {
         throw new InvalidOperationException($"Invalid NodeTypes for Connection. Type NodeFrom: {nodeFrom.Type} Type NodeTo: {nodeTo.Type}");
     }
     // TODO: Check if Connection does not exist already in Genome
     AddConnection(MutationFactory.GetConnection(nodeFrom, nodeTo));
 }
Esempio n. 2
0
        /// <summary>
        /// Adds random connection (Structural Mutation) to Genome
        /// </summary>
        internal void MutateAddRandomConnection()
        {
            if (Nodes.Count < 2)
            {
                throw new InvalidOperationException("Not enough Existing Nodes");
            }
            // Separate out the Nodes by Type
            List <NodeGene> inputNodes  = new List <NodeGene>();
            List <NodeGene> hiddenNodes = new List <NodeGene>();
            List <NodeGene> outputNodes = new List <NodeGene>();

            foreach (NodeGene node in Nodes.Values)
            {
                switch (node.Type)
                {
                case NodeType.INPUT:
                    inputNodes.Add(node);
                    break;

                case NodeType.HIDDEN:
                    hiddenNodes.Add(node);
                    break;

                case NodeType.OUTPUT:
                    outputNodes.Add(node);
                    break;

                default:
                    break;
                }
            }
            // Add hiddenNodes to both lists to create the choice-lists
            inputNodes.AddRange(hiddenNodes);
            outputNodes.AddRange(hiddenNodes);

            // Find 2 nodes in these 2 lists which are NOT connected
            NodeGene inputNode = inputNodes[Functions.GetRandomNumber(0, inputNodes.Count)]; // Pick random inputNode
            int      attempts  = 0;

            while (attempts < MaxFindAttempts) // TODO: Improve this
            {
                attempts++;
                NodeGene outputNode = outputNodes[Functions.GetRandomNumber(0, outputNodes.Count)];
                if (inputNode.Equals(outputNode)) // Same (hidden) node, can't connect to self
                {
                    continue;
                }
                bool foundConnection = false;
                foreach (ConnectionGene conn in Connections.Values)
                {
                    if (conn.HasNode(inputNode) && conn.HasNode(outputNode))
                    {
                        foundConnection = true;
                        break; // Connection Exists
                    }
                }
                if (foundConnection)
                {
                    continue; // failed to find valid pair
                }
                // InputNode != OutputNode and !(I->O) && !(O->I)
                AddConnection(MutationFactory.GetConnection(inputNode, outputNode));
                return;
            }
            Console.WriteLine("Failed to add Connection");
        }