示例#1
0
        private static List <int> HandleMatchingAndDisjointConnectionGenes(NeatGenome childGenome, NeatGenome mostFitGenome, ConnectionGeneSequence conns1, ConnectionGeneSequence conns2, bool equalFitness, List <int> InvolvedNodes, int geneIndex)
        {
            ConnectionGene gene1, gene2;

            gene1 = conns1[geneIndex];
            gene2 = conns2[geneIndex];
            bool equalID = gene1.geneID == gene2.geneID;

            if (equalID)
            {
                var gene = Neat.random.NextBoolean() ? gene1 : gene2;
                InvolvedNodes = AddInvolvedConnNodes(InvolvedNodes, gene);
                childGenome.connectionGenes.Add(gene);
            }
            else
            {
                if (equalFitness)
                {
                    var gene = Neat.random.NextBoolean() ? gene1 : gene2;
                    InvolvedNodes = AddInvolvedConnNodes(InvolvedNodes, gene);
                    childGenome.connectionGenes.Add(gene);
                }
                else
                {
                    var gene = mostFitGenome.connectionGenes[geneIndex];
                    InvolvedNodes = AddInvolvedConnNodes(InvolvedNodes, gene);
                    childGenome.connectionGenes.Add(gene);
                }
            }
            InvolvedNodes.Sort();
            return(InvolvedNodes);
        }
示例#2
0
 public NeatGenome(NeatGenome copyFromGenome, bool init = false)
 {
     nodeGenes       = new NodeGeneSequence();
     connectionGenes = new ConnectionGeneSequence();
     foreach (NodeGene gene in copyFromGenome.nodeGenes)
     {
         if (gene.type == NodeType.Sensor)
         {
             nodeGenes.Add(new SensorNodeGene(((SensorNodeGene)gene)));
         }
         else if (gene.type == NodeType.Hidden)
         {
             nodeGenes.Add(new HiddenNodeGene(((HiddenNodeGene)gene)));
         }
         else if (gene.type == NodeType.Output)
         {
             nodeGenes.Add(new OutputNodeGene(((OutputNodeGene)gene)));
         }
     }
     foreach (ConnectionGene gene in copyFromGenome.connectionGenes)
     {
         if (init)
         {
             connectionGenes.Add(new ConnectionGene(gene, newWeight: true));
         }
         else
         {
             connectionGenes.Add(new ConnectionGene(gene));
         }
     }
     hasMutated = false;
 }
示例#3
0
 private static NeatGenome ChangeNodeFunction(NeatGenome genome)
 {
     if (genome.HasInternalNodes())
     {
         var newType  = Neat.random.ActivationFunctionType();
         var nodeGene = Neat.random.InternalNodeGene(genome);
         nodeGene = ((InternalNodeGene)nodeGene).ChangeFunction(newType, nodeGene.geneID);
     }
     return(genome);
 }
示例#4
0
        public void Initialize(Population population)
        {
            var genome = new NeatGenome();

            genome.Initialize(population);
            for (int i = 0; i < EAParameters.PopulationSize; i++)
            {
                var indie = new NEATIndividual(genome, population.IDs, true);
                populace.Add(indie);
            }
            //TODO remember to mutate part of this
        }
示例#5
0
 public NEATIndividual(NeatGenome genome, IDCounters IDs, bool init = false) : base(IDs.IndividualID)
 {
     Fitness = 0.0f;
     if (init)
     {
         this.genome = new NeatGenome(genome, init: true);
     }
     else
     {
         this.genome = new NeatGenome(genome);
     }
 }
示例#6
0
        public static NeatGenome Crossover(NEATIndividual indie1, NEATIndividual indie2)
        {
            var genome1 = indie1.genome;
            var genome2 = indie2.genome;

            var mostFitGenome = indie1.Fitness > indie2.Fitness ? indie1.genome : indie2.genome;

            var childGenome = new NeatGenome();

            int geneIndex     = 0;
            var InvolvedNodes = new List <int>();
            var nodes1        = genome1.nodeGenes;
            var conns1        = genome1.connectionGenes;

            var nodes2 = genome2.nodeGenes;
            var conns2 = genome2.connectionGenes;

            bool moreInBoth   = geneIndex < conns1.Count && geneIndex < conns2.Count;
            bool equalFitness = indie1.Fitness.SameWithinReason(indie2.Fitness);

            while (moreInBoth)
            {
                HandleMatchingAndDisjointConnectionGenes(childGenome, mostFitGenome, conns1, conns2, equalFitness, InvolvedNodes, geneIndex);
                geneIndex++;
                moreInBoth = geneIndex < conns1.Count && geneIndex < conns2.Count;
            }

            AddExcessGenes(childGenome, conns1, conns2, InvolvedNodes, geneIndex);

            childGenome.nodeGenes.AddRange(GetInvolvedNodesFromConnections(InvolvedNodes, nodes1, nodes2));
            var seenBefore = new List <int>();

            foreach (var node in childGenome.nodeGenes)
            {
                if (!seenBefore.Contains(node.nodeID))
                {
                    seenBefore.Add(node.nodeID);
                }
                else
                {
                    Console.WriteLine();
                    foreach (var n in childGenome.nodeGenes)
                    {
                        Console.Write("nID:{0} ", n.nodeID);
                    }
                    Console.WriteLine();
                    throw new Exception("Crossover same nodeID in network!");
                }
            }
            return(childGenome);
        }
示例#7
0
        private static NeatGenome ChangeWeight(NeatGenome genome)
        {
            var   oldConnGene = Neat.random.ConnectionGene(genome);
            float newWeight   = (oldConnGene.connectionWeight + Neat.random.NextFloat() * 2.0f * MutationChances.MutatWeightAmount
                                 - MutationChances.MutatWeightAmount).ClampWeight();

            oldConnGene.connectionWeight = newWeight;

            var newConnGene = new ConnectionGene(oldConnGene);

            genome.connectionGenes.Remove(oldConnGene);
            genome.connectionGenes.Add(newConnGene);
            return(genome);
        }
示例#8
0
        public static NeatGenome Mutate(NeatGenome genome, Population population)
        {
            NeatGenome newGenome = new NeatGenome(genome);

            foreach (MutationType type in Enum.GetValues(typeof(MutationType)))
            {
                if (Neat.random.DoMutation(type))
                {
                    newGenome            = MutateOfType(type, newGenome, population);
                    newGenome.hasMutated = true;
                }
            }

            return(newGenome);
        }
示例#9
0
 private static List <int> AddExcessGenes(NeatGenome childGenome, ConnectionGeneSequence conns1, ConnectionGeneSequence conns2, List <int> InvolvedNodes, int geneIndex)
 {
     if (geneIndex == conns1.Count)
     {
         HandleExcessGenes(conns2, InvolvedNodes, geneIndex, childGenome);
     }
     else if (geneIndex == conns2.Count)
     {
         HandleExcessGenes(conns1, InvolvedNodes, geneIndex, childGenome);
     }
     else
     {
         throw new Exception("genIndex did not catch up to either parent genome!");
     }
     return(InvolvedNodes);
 }
示例#10
0
        private static NeatGenome MutateOfType(MutationType type, NeatGenome genome, Population population)
        {
            switch (type)
            {
            case MutationType.MutateWeight:
                return(ChangeWeight(genome));

            case MutationType.AddConnection:
                return(AddConnection(genome, population));

            case MutationType.AddNode:
                return(AddNode(genome, population));

            case MutationType.ChangeFunction:             //and then maybe "mutateCurrentFunction type"
                return(ChangeNodeFunction(genome));

            default:
                return(genome);
            }
        }
示例#11
0
        private static NeatGenome AddNode(NeatGenome genome, Population population)
        {
            var connectionToSplitt = Neat.random.ConnectionGene(genome);
            int fromGeneID         = -1;
            int newNodeGeneID      = -1;
            int newNodeID          = -1;
            int toGeneID           = -1;

            if (population.PreviouslySplitConnectionGeneIDs.Contains(connectionToSplitt.geneID))
            {
                var IDs = population.PreviouslySplitConnections[connectionToSplitt.geneID];
                fromGeneID    = IDs.Item1;
                newNodeGeneID = IDs.Item2;
                newNodeID     = IDs.Item3;
                toGeneID      = IDs.Item4;
                if (genome.nodeGenes.Contains(newNodeGeneID))
                {
                    Console.WriteLine();
                    foreach (var n in genome.nodeGenes)
                    {
                        Console.Write("nID:{0} ", n.nodeID);
                    }

                    Console.WriteLine();
                    throw new Exception("already this generation same nodeID in network!");
                }
            }
            else
            {
                population.PreviouslySplitConnectionGeneIDs.Add(connectionToSplitt.geneID);
                fromGeneID    = population.IDs.ConnectionGeneID;
                newNodeGeneID = population.IDs.NodeGeneID;
                newNodeID     = genome.nodeGenes.Count + 1;             //not ok!
                toGeneID      = population.IDs.ConnectionGeneID;
                population.PreviouslySplitConnections.Add(connectionToSplitt.geneID, Tuple.Create(fromGeneID, newNodeGeneID, newNodeID, toGeneID));
                var seeneBefore = new List <int>();
                if (genome.nodeGenes.Contains(newNodeGeneID))
                {
                    Console.WriteLine();
                    foreach (var n in genome.nodeGenes)
                    {
                        Console.Write("nID:{0} ", n.nodeID);
                    }

                    Console.WriteLine();
                    throw new Exception("new this generation same nodeID in network!");
                }
            }

            connectionToSplitt.isEnabled = false;
            var newNode = new HiddenNodeGene(newNodeGeneID,
                                             newNodeID,
                                             Neat.random.ActivationFunctionType());

            var firstHalfGene = new ConnectionGene(fromGeneID,
                                                   connectionToSplitt.fromNodeID,
                                                   newNode.nodeID,
                                                   true,
                                                   1.0f);

            var secondHalfGene = new ConnectionGene(toGeneID,
                                                    newNode.nodeID,
                                                    connectionToSplitt.toNodeID,
                                                    true,
                                                    (float)Neat.random.NextRangedDouble(0.0, CPPNParameters.InitialMaxConnectionWeight));

            if (genome.nodeGenes.Contains(newNode.nodeID))
            {
                Console.WriteLine();
                foreach (var n in genome.nodeGenes)
                {
                    Console.Write("nID:{0} ", n.nodeID);
                }
                Console.WriteLine("newID:{0} - newNodeID:{1}", newNode.nodeID, newNodeGeneID);
                Console.WriteLine();
                throw new Exception("addNode NewNode same nodeID in network!");
            }
            genome.nodeGenes.Add(newNode);
            genome.connectionGenes.Add(firstHalfGene);
            genome.connectionGenes.Add(secondHalfGene);
            var seenBefore = new List <int>();

            foreach (var node in genome.nodeGenes)
            {
                if (!seenBefore.Contains(node.nodeID))
                {
                    seenBefore.Add(node.nodeID);
                }
                else
                {
                    Console.WriteLine();
                    foreach (var n in genome.nodeGenes)
                    {
                        Console.Write("nID:{0} ", n.nodeID);
                    }
                    Console.WriteLine();
                    throw new Exception("addNode same nodeID in network!");
                }
            }
            return(genome);
        }
示例#12
0
 private static void HandleExcessGenes(ConnectionGeneSequence connsLong, List <int> InvolvedNodes, int geneIndex, NeatGenome childGenome)
 {
     for (int i = geneIndex; i < connsLong.Count; i++)
     {
         InvolvedNodes = AddInvolvedConnNodes(InvolvedNodes, connsLong[i]);
         childGenome.connectionGenes.Add(connsLong[i]);
     }
 }
示例#13
0
        private static NeatGenome AddConnection(NeatGenome genome, Population population)
        {
            var toNode = Neat.random.NotInputNodeGene(genome);

            var connGenes = genome.connectionGenes;
            var fromNode  = Neat.random.NotOutputNodeGene(genome);

            bool baseCase = fromNode.type == NodeType.Sensor && toNode.type == NodeType.Output; //already exist all of these

            baseCase |= connGenes.Contains(fromNode.nodeID, toNode.nodeID);                     //existing "internal" connection

            if (baseCase)
            {
                return(genome);
            }

            int allottedTries = genome.nodeGenes.Count - Neat.parameters.CPPN.InputSize - 1;           //allowed to try every other node that's not input or itself.
            //making a minimal linked-list graph for checking
            var graph = new Dictionary <int, List <int> >();

            foreach (var node in genome.nodeGenes)
            {
                graph.Add(node.nodeID, new List <int>());
            }
            foreach (var connection in genome.connectionGenes)
            {
                graph[connection.fromNodeID].Add(connection.toNodeID);
            }

            while (allottedTries > 0)
            {
                if (graph.CanReachGoalFromRoot(toNode.nodeID, fromNode.nodeID))
                {
                    allottedTries--;
                    toNode = Neat.random.NotInputNodeGene(genome);

                    if (toNode.type == NodeType.Output)
                    {
                        if (fromNode.type == NodeType.Sensor)
                        {
                            return(genome);
                        }
                        else if (connGenes.Contains(fromNode.nodeID, toNode.nodeID))
                        {
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                else
                {
                    break;                     //the connection is none-cyclic
                }
            }
            int id  = -1;
            var key = Tuple.Create(fromNode.nodeID, toNode.nodeID);

            if (population.PreviouslyAddedConnections.ContainsKey(key))            //TODO finish the gene tracking stuff!
            {
                id = population.PreviouslyAddedConnections[key];
            }
            else
            {
                id = population.IDs.ConnectionGeneID;
                population.PreviouslyAddedConnections.Add(key, id);
            }

            var conGene = new ConnectionGene(id,
                                             fromNode.nodeID,
                                             toNode.nodeID,
                                             true,                                                    //was this supposed to be weighted random for new ones?
                                             Neat.random.InitialConnectionWeight());

            genome.connectionGenes.Add(conGene);
            return(genome);
        }
示例#14
0
 public static NeatGenome GetLeastConnected(NeatGenome genome1, NeatGenome genome2)
 {
     return(genome1.IsMoreConnectedThan(genome2) ? genome2 : genome1);
 }
示例#15
0
 public NEATIndividual(NEATIndividual indie) : base(indie.individualID)
 {
     Fitness = 0.0f;
     genome  = new NeatGenome(indie.genome);
 }