Beispiel #1
0
        /// <summary>
        /// Add a new Node to a Random Connection
        /// </summary>
        /// <param name="r">Random</param>
        /// <param name="connectionInnovationCounter">Connection Innovation Counter</param>
        /// <param name="nodeInnovationCounter">Node Innovation Counter</param>
        public void AddNodeMutation(Random r, InnovationCounter connectionInnovationCounter, InnovationCounter nodeInnovationCounter)
        {
            // Get enabled Connections
            List <ConnectionGene> enabledConnections = new List <ConnectionGene>();

            foreach (ConnectionGene c in Connections.Values)
            {
                if (c.IsEnable)
                {
                    enabledConnections.Add(c);
                }
            }
            if (enabledConnections.Count == 0)
            {
                return;
            }

            // Get a Random Connection
            ConnectionGene connection = enabledConnections[r.Next(enabledConnections.Count)];
            NodeGene       inNode     = Nodes[connection.InNode];
            NodeGene       outNode    = Nodes[connection.OutNode];

            // Disbale Old Connection
            connection.IsEnable = false;

            // Create a node w/ IN & OUT Connection to replace old Connection
            NodeGene       newNode  = new NodeGene(NodeGene.TYPE.HIDDEN, nodeInnovationCounter.GetNewInnovationNumber());
            ConnectionGene inToNew  = new ConnectionGene(inNode.Id, newNode.Id, 1f, true, connectionInnovationCounter.GetNewInnovationNumber());                 // Weight of 1
            ConnectionGene newToOut = new ConnectionGene(newNode.Id, outNode.Id, connection.Weight, true, connectionInnovationCounter.GetNewInnovationNumber()); // Weight of old Connection

            // Add Node & Connections to the Genome
            Nodes.Add(newNode.Id, newNode);
            Connections.Add(inToNew.InnovationId, inToNew);
            Connections.Add(newToOut.InnovationId, newToOut);
        }
Beispiel #2
0
        private string _mutationLogs = "";                                                          // Mutation Logs

        public EvaluatorRT(RTNEATConfig config, Genome startingGenome, InnovationCounter nodeInnovation, InnovationCounter connectionInnovation)
        {
            _config               = config;
            _nodeInnovation       = nodeInnovation;
            _connectionInnovation = connectionInnovation;
            _currentPop           = 0;

            _genomes = new List <Genome>();
            for (int i = 0; i < _config.startPopulation; ++i)
            {
                AddGenomeToList(Genome.GenomeRandomWeights(startingGenome, _r));
            }

            BestFitness = -1f;
            BestGenome  = null;
        }
Beispiel #3
0
        private string _mutationLogs = "";                                                          // Mutation Logs

        public Evaluator(NEATConfig config, Genome startingGenome, InnovationCounter nodeInnovation, InnovationCounter connectionInnovation)
        {
            _config               = config;
            GenerationNumber      = 0;
            _nodeInnovation       = nodeInnovation;
            _connectionInnovation = connectionInnovation;

            _genomes = new List <Genome>();
            for (int i = 0; i < _config.populationSize; ++i)
            {
                _genomes.Add(Genome.GenomeRandomWeights(startingGenome, _r));
            }

            _nextEvaluationGenomes = new List <Genome>();

            _species = new List <Species>();

            _genomesSpecies = new Dictionary <Genome, Species>();

            BestFitness = -1f;
            BestGenome  = null;
        }
Beispiel #4
0
        /// <summary>
        /// Add a new Connection between 2 Random Nodes
        /// </summary>
        /// <param name="r">Random</param>
        /// <param name="connectionInnovationCounter">Connection Innovation Counter</param>
        /// <param name="maxTries">Max Tries to attemp Mutation</param>
        /// <returns>Success</returns>
        public bool AddConnectionMutation(Random r, InnovationCounter connectionInnovationCounter, int maxTries = 10)
        {
            bool success = false;

            // Try maxTries times
            for (int tries = 0; tries < maxTries && !success; tries++)
            {
                // Get 2 Random Nodes & a Random Weight
                List <int> nodeInnovationIds = new List <int>(Nodes.Keys);
                NodeGene   node1             = Nodes[nodeInnovationIds[r.Next(nodeInnovationIds.Count)]];
                NodeGene   node2             = Nodes[nodeInnovationIds[r.Next(nodeInnovationIds.Count)]];

                // Sigmoid Weights
                // float weight = (float)r.NextDouble() * 2f - 1f;

                // Tanh Weights
                // float weight = UnityEngine.Random.Range(-0.5f, 0.5f);

                // Config Weights
                float weight = UnityEngine.Random.Range(NewWeightRange.x, NewWeightRange.y);

                // Is Reversed ?
                if ((node1.Type == NodeGene.TYPE.HIDDEN && node2.Type == NodeGene.TYPE.INPUT) ||
                    (node1.Type == NodeGene.TYPE.OUTPUT && node2.Type == NodeGene.TYPE.HIDDEN) ||
                    (node1.Type == NodeGene.TYPE.OUTPUT && node2.Type == NodeGene.TYPE.INPUT))
                {
                    NodeGene swap = node1;
                    node1 = node2;
                    node2 = swap;
                }

                // Is Connection Impossible ?
                if ((node1.Type == NodeGene.TYPE.INPUT && node2.Type == NodeGene.TYPE.INPUT) ||
                    (node1.Type == NodeGene.TYPE.OUTPUT && node2.Type == NodeGene.TYPE.OUTPUT) ||
                    (node1 == node2))
                {
                    continue;
                }

                // Does Connection already exists ?
                bool connectionExists = false;
                foreach (ConnectionGene c in Connections.Values)
                {
                    if ((c.InNode == node1.Id && c.OutNode == node2.Id) ||
                        (c.InNode == node2.Id && c.OutNode == node1.Id))
                    {
                        connectionExists = true;
                        break;
                    }
                }
                if (connectionExists)
                {
                    continue;
                }

                // Circular structure ?
                bool       connectionImpossible = false;
                List <int> nodeIds     = new List <int>();                  // Node that need output from node2
                List <int> nodeToCheck = new List <int>();                  // Nodes to check
                foreach (int connectionId in Connections.Keys)              // Get all Connections w/ outNode == node2
                {
                    ConnectionGene connection = Connections[connectionId];
                    if (connection.InNode == node2.Id)                      // Connection comes from node2
                    {
                        nodeIds.Add(connection.OutNode);
                        nodeToCheck.Add(connection.OutNode);
                    }
                }
                while (nodeToCheck.Count > 0)                               // Get all Connections w/ outNode == nodeToCheck
                {
                    int nodeId = nodeToCheck[0];
                    foreach (int connectionId in Connections.Keys)
                    {
                        ConnectionGene connection = Connections[connectionId];
                        if (connection.InNode == nodeId)                    // Connection comes from nodeToCheck
                        {
                            nodeIds.Add(connection.OutNode);
                            nodeToCheck.Add(connection.OutNode);
                        }
                    }
                    nodeToCheck.RemoveAt(0);
                }
                foreach (int i in nodeIds)                                  // Loop through all Node Ids
                {
                    if (i == node1.Id)                                      // If one of the Node == node1 => Connection is Impossible
                    {
                        connectionImpossible = true;
                        break;
                    }
                }
                if (connectionImpossible)
                {
                    continue;
                }

                // Add new Connection
                ConnectionGene newConnection = new ConnectionGene(
                    node1.Id,
                    node2.Id,
                    weight,
                    true,
                    connectionInnovationCounter.GetNewInnovationNumber()
                    );
                Connections.Add(newConnection.InnovationId, newConnection);
                success = true;
            }

            return(success);
        }