Пример #1
0
        /// <summary>
        /// Adds Connection (Structural Mutation) to Genome from Nodes
        /// </summary>
        /// <param name="nodeFrom">From-Node (Innovation-Number) for Connection</param>
        /// <param name="nodeTo">To-Node (Innovation-Number) for Connection</param>
        internal void MutateAddConnection(ulong nodeFrom, ulong nodeTo)
        {
            if (nodeFrom == 0)
            {
                throw new ArgumentException("NodeInnovation cannot be 0", "nodeFrom");
            }
            if (nodeTo == 0)
            {
                throw new ArgumentException("NodeInnovation cannot be 0", "nodeTo");
            }
            if (nodeFrom == nodeTo)
            {
                throw new ArgumentException("Cannot create Connection with a single Node");
            }
            if (!Nodes.ContainsKey(nodeFrom))
            {
                throw new ArgumentException("Node does not exist in Genome", "nodeFrom");
            }
            if (!Nodes.ContainsKey(nodeTo))
            {
                throw new ArgumentException("Node does not exist in Genome", "nodeTo");
            }
            NodeGene from = Nodes[nodeFrom];
            NodeGene to   = Nodes[nodeTo];

            if (from.Type == NodeType.OUTPUT || to.Type == NodeType.INPUT)
            {
                throw new InvalidOperationException($"Invalid NodeTypes for Connection. Type NodeFrom: {from.Type} Type NodeTo: {to.Type}");
            }
            // TODO: Check if Connection does not exist already in Genome
            AddConnection(MutationFactory.GetConnection(from, to));
        }
Пример #2
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));
 }
Пример #3
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");
        }