Beispiel #1
0
        private void AddGeneFromOther(Gene curr1, Gene curr2, Dictionary <int, Node> dict, Random rnd, SortedList <int, Gene> genes)
        {
            var gene = curr2.ShallowCopy();

            AddNodesToDictIfNotIn(dict, gene); // Layers are not OK
            gene.Type = (curr2.CrossoverChildDisabled(rnd, curr1)) ? GeneType.Enabled : GeneType.Disabled;
            genes.Add(gene.Innovation, gene);
            // Correct Layers from more fit parent A.K.A. this genome
            gene.In.Layer  = curr1.In.Layer;
            gene.Out.Layer = curr1.Out.Layer;
        }
Beispiel #2
0
        /// <summary>
        /// Add nodes to random connection gene in genome
        /// </summary>
        private void AddNode(Random rnd, ref int innovation, ref int number, List <Gene> allGenes)
        {
            int  index = rnd.Next(0, Genes.Count);
            var  pair  = Genes.ElementAt(index);
            Gene gene  = pair.Value;

            gene.Type = GeneType.Disabled;
            Node node       = null;
            Gene firstGene  = null;
            Gene latterGene = null;
            bool exists     = FindExistingNode(gene, ref node, ref firstGene, ref latterGene, allGenes, ref innovation, ref number);

            if (!exists)
            {
                node       = new Node(NodeType.Hidden, gene.In.Layer + 1, ++number);
                firstGene  = new Gene(gene.In, node, 1f, GeneType.Enabled, ++innovation);
                latterGene = new Gene(node, gene.Out, gene.Weight, GeneType.Enabled, ++innovation);
            }
            // Check if the latter gene connection cannot be from the same layer to the same layer
            if (gene.Out.Layer == node.Layer)
            {
                IncrementLayer(node);
            }

            if (!Genes.ContainsKey(firstGene.Innovation)) // should always go to if branch
            {
                Genes.Add(firstGene.Innovation, firstGene);
                firstGene.In.OutgoingConnections.Add(firstGene);
                if (!exists)
                {
                    var g = firstGene.ShallowCopy();
                    g.Type = GeneType.AddNode;
                    allGenes.Add(g); // still points to nodes in this genome
                }
            }
            else
            {
                ;
            }
            if (!Genes.ContainsKey(latterGene.Innovation)) // should always go to if branch
            {
                Genes.Add(latterGene.Innovation, latterGene);
                latterGene.In.OutgoingConnections.Add(latterGene);
                if (!exists)
                {
                    var g = latterGene.ShallowCopy();
                    g.Type = GeneType.AddNode;
                    allGenes.Add(g); // still points to nodes in this genome
                }
            }
            else
            {
                ;
            }
            if (!Nodes.Contains(node)) // should always go to if branch
            {
                Nodes.Add(node);
            }
            else
            {
                for (int i = 0; i < Nodes.Count; i++)
                {
                    if (node.Number == Nodes[i].Number)
                    {
                        if (ReferenceEquals(node, Nodes[i]))
                        {
                            ;
                        }
                        else
                        {
                            ;
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Fitness of this is greater than or equal to fitness of other
        /// </summary>
        /// <returns>child of this and other</returns>
        internal Genome Crossover(Genome other, Random rnd, bool sameFitness, int disableChance = 75)
        {
            var enumThis  = Genes.GetEnumerator();
            var enumOther = other.Genes.GetEnumerator();
            var dict      = new Dictionary <int, Node>();
            SortedList <int, Gene> genes = new SortedList <int, Gene>(Genes.Count);

            Gene curr1 = enumThis.MoveNext() ? enumThis.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
            Gene curr2 = enumOther.MoveNext() ? enumOther.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);

            while (true)
            {
                if (curr1.Innovation == curr2.Innovation)
                {
                    if (curr1.Innovation == -1)
                    {
                        break;
                    }
                    if (rnd.Next(0, 100) > 50)
                    {
                        AddGeneFromThis(curr1, curr2, dict, rnd, genes);
                    }
                    else
                    {
                        AddGeneFromOther(curr1, curr2, dict, rnd, genes);
                    }
                    curr1 = enumThis.MoveNext() ? enumThis.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                    curr2 = enumOther.MoveNext() ? enumOther.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                }
                else if (curr1.Innovation < curr2.Innovation)
                {
                    if (curr1.Innovation == -1)
                    {
                        if (sameFitness)
                        {
                            AddGeneFromThis(curr2, curr1, dict, rnd, genes);
                        }
                        curr2 = enumOther.MoveNext() ? enumOther.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                    }
                    else
                    {
                        AddGeneFromThis(curr1, curr2, dict, rnd, genes);
                        curr1 = enumThis.MoveNext() ? enumThis.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                    }
                }
                else
                {
                    if (curr2.Innovation == -1)
                    {
                        AddGeneFromThis(curr1, curr2, dict, rnd, genes);
                        curr1 = enumThis.MoveNext() ? enumThis.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                    }
                    else
                    {
                        if (sameFitness)
                        {
                            AddGeneFromThis(curr2, curr1, dict, rnd, genes);
                        }
                        // THE OTHER GENE HAS LOWER FITNESS SO WHY ADD IT'S GENE ??? - case onlu with same fitness of genomes
                        curr2 = enumOther.MoveNext() ? enumOther.Current.Value : new Gene(null, null, 0f, GeneType.Enabled, -1);
                    }
                }
            }

            var nodes = new List <Node>(Nodes.Count);

            // Copy Nodes from Genes from Other Genome
            foreach (var item in dict)
            {
                nodes.Add(item.Value);
            }
            Node node;

            for (int i = 0; i < Nodes.Count; i++)
            {
                if (dict.TryGetValue(Nodes[i].Number, out node))
                {
                    ;
                }
                else
                {
                    nodes.Add(Nodes[i].ShallowCopy());
                }
            }

            nodes.Sort(new NodeNumberComparer());


            var child = new Genome(nodes, genes, null);

            // CORRECT LAYER MESS
            if (sameFitness)
            {
                bool notdone = false;
                do
                {
                    notdone = false;
                    foreach (var item in genes)
                    {
                        var g = item.Value;
                        while (g.In.Layer >= g.Out.Layer)
                        {
                            g.Out.Layer++;
                            notdone = true;
                        }
                    }
                }while (notdone);
            }
            return(child);
        }