예제 #1
0
        public static float averageWeightDifference(Genome g1, Genome g2)
        {
            float g1TotalWeights      = 0.0f;
            float g2TotalWeights      = 0.0f;
            float matchingGeneCounter = 0.0f;

            foreach (KeyValuePair <int, ConnectionGene> c in g1.getConnections())
            {
                if (g2.getConnections().ContainsKey(c.Key))
                {
                    matchingGeneCounter++;
                    g1TotalWeights += c.Value.getWeight();
                }
            }

            foreach (KeyValuePair <int, ConnectionGene> c in g2.getConnections())
            {
                if (g1.getConnections().ContainsKey(c.Key))
                {
                    g2TotalWeights += c.Value.getWeight();
                }
            }

            // Debug.Log("g1TotalWeights" + g1TotalWeights + "g2TotalWeights" + g1TotalWeights + "matchingGeneCounter" + matchingGeneCounter);
            //Console.WriteLine("g1TotalWeights " + g1TotalWeights + " g2TotalWeights " + g1TotalWeights + " matchingGeneCounter " + matchingGeneCounter);

            if (matchingGeneCounter == 0)
            {
                return(0f);
            }

            return((Math.Abs(g1TotalWeights - g2TotalWeights)) / matchingGeneCounter);
        }
예제 #2
0
        public static int excessCount(Genome g1, Genome g2)
        {
            int count = 0;
            int g1HighestInnovation = g1.getConnections().Keys.Max();
            int g2HighestInnovation = g2.getConnections().Keys.Max();

            // if g1 has lower innovation, count excess genes on g2
            if (g1HighestInnovation < g2HighestInnovation)
            {
                foreach (KeyValuePair <int, ConnectionGene> c in g2.getConnections())
                {
                    if (c.Key > g1HighestInnovation)
                    {
                        count++;
                    }
                }
            }
            else if (g1HighestInnovation > g2HighestInnovation)
            {
                foreach (KeyValuePair <int, ConnectionGene> c in g1.getConnections())
                {
                    if (c.Key > g2HighestInnovation)
                    {
                        count++;
                    }
                }
            }
            return(count);
        }
예제 #3
0
        public static int disjointCount(Genome g1, Genome g2)
        {
            int count = 0;
            int g1HighestInnovation = g1.getConnections().Keys.Max();
            int g2HighestInnovation = g2.getConnections().Keys.Max();

            if (g1HighestInnovation <= g2HighestInnovation)
            {
                foreach (KeyValuePair <int, ConnectionGene> c in g1.getConnections())
                {
                    if (!g2.getConnections().ContainsKey(c.Key))
                    {
                        count++;
                    }
                }

                foreach (KeyValuePair <int, ConnectionGene> c in g2.getConnections())
                {
                    if (!g1.getConnections().ContainsKey(c.Key) && c.Key < g1HighestInnovation)
                    {
                        count++;
                    }
                }
            }
            else if (g1HighestInnovation > g2HighestInnovation)
            {
                foreach (KeyValuePair <int, ConnectionGene> c in g2.getConnections())
                {
                    if (!g1.getConnections().ContainsKey(c.Key))
                    {
                        count++;
                    }
                }

                foreach (KeyValuePair <int, ConnectionGene> c in g1.getConnections())
                {
                    if (!g2.getConnections().ContainsKey(c.Key) && c.Key < g2HighestInnovation)
                    {
                        count++;
                    }
                }
            }
            return(count);
        }
예제 #4
0
        // matching genes are inherited randomly, disjoint and excess (unmatching genes) genes are inherited from the more fit parent
        // parent1 is the more fit parent
        public static Genome crossover(Random random, Genome parent1, Genome parent2)
        {
            Genome offspring = new Genome();

            /**
             * NodeGene Crossover
             */

            // add NodeGenes from parent1 (fittest parent) to the offspring
            foreach (KeyValuePair <int, NodeGene> n in parent1.getNodes())
            {
                NodeGene oNode = new NodeGene(n.Value);
                offspring.addNodeGene(oNode);
            }

            /**
             * ConnectionGene Crossover
             */

            foreach (KeyValuePair <int, ConnectionGene> p1Gene in parent1.getConnections())
            {
                // when parent connection genes match one must be inherited by the offspring randomly
                if (parent2.getConnections().ContainsKey(p1Gene.Key))
                {
                    if (random.Next(100) <= 50)
                    {
                        // takes a copy of parent2 gene
                        offspring.addConnectionGene(new ConnectionGene(parent2.getConnections()[p1Gene.Key]));
                    }
                    else
                    {
                        //takes a copy of parent1 gene
                        offspring.addConnectionGene(new ConnectionGene(p1Gene.Value));
                    }
                }
                else   // if they don't match (disjoint or excess), copy from more fit parent

                {
                    offspring.addConnectionGene(new ConnectionGene(p1Gene.Value));
                }
            }

            return(offspring);
        }
예제 #5
0
        public static bool compatibilityDistance(Genome g1, Genome g2)
        {
            int normalize   = 1;
            int g1GeneCount = g1.getConnections().Count;
            int g2GeneCount = g2.getConnections().Count;

            // if  either genome has more than 20 genes, change normalize
            if (g1GeneCount >= GENE_THRESHOLD || g2GeneCount >= GENE_THRESHOLD)
            {
                //normalise is set to the length of the largest genome
                normalize = Math.Max(g1GeneCount, g2GeneCount);
            }

            float cDistance = ((excessCount(g1, g2) * Utility.COEFFICIENT1) / normalize)
                              + ((disjointCount(g1, g2) * Utility.COEFFICIENT2) / normalize)
                              + (averageWeightDifference(g1, g2) * Utility.COEFFICIENT3);

            return(cDistance <= Utility.COMPATIBILITY_THRESHOLD);
        }
예제 #6
0
        public static void Main(string[] args)
        {
            Random random = new Random();


            Genome initialGenome = new Genome();

            int node0 = initialGenome.getNodes().Count;

            initialGenome.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node0));
            int node1 = initialGenome.getNodes().Count;

            initialGenome.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node1));
            int node2 = initialGenome.getNodes().Count;

            initialGenome.addNodeGene(new NodeGene(NodeGene.NodeType.OUTPUT, node2));

            InnovationUtility.incrementGlobalInnovation();
            initialGenome.addConnectionGene(new ConnectionGene(node0, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, InnovationUtility.getGlobalInnovation()));

            InnovationUtility.incrementGlobalInnovation();
            initialGenome.addConnectionGene(new ConnectionGene(node1, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, InnovationUtility.getGlobalInnovation()));

            Genome initialGenome1 = new Genome();

            node0 = initialGenome1.getNodes().Count;
            initialGenome1.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node0));
            node1 = initialGenome1.getNodes().Count;
            initialGenome1.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node1));
            node2 = initialGenome1.getNodes().Count;
            initialGenome1.addNodeGene(new NodeGene(NodeGene.NodeType.OUTPUT, node2));

            initialGenome1.addConnectionGene(new ConnectionGene(node0, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 1));

            initialGenome1.addConnectionGene(new ConnectionGene(node1, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 2));

            Genome initialGenome2 = new Genome();

            node0 = initialGenome2.getNodes().Count;
            initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node0));
            node1 = initialGenome2.getNodes().Count;
            initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node1));
            node2 = initialGenome2.getNodes().Count;
            initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.OUTPUT, node2));

            initialGenome2.addConnectionGene(new ConnectionGene(node0, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 1));

            initialGenome2.addConnectionGene(new ConnectionGene(node1, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 2));

            Genome initialGenome3 = new Genome();

            node0 = initialGenome3.getNodes().Count;
            initialGenome3.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node0));
            node1 = initialGenome3.getNodes().Count;
            initialGenome3.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node1));
            node2 = initialGenome3.getNodes().Count;
            initialGenome3.addNodeGene(new NodeGene(NodeGene.NodeType.OUTPUT, node2));

            initialGenome3.addConnectionGene(new ConnectionGene(node0, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 1));

            initialGenome3.addConnectionGene(new ConnectionGene(node1, node2, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 2));


            // //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            // Genome initialGenome2 = new Genome();

            // node1 = initialGenome2.getNodes().Count;
            // initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node1));
            // node2 = initialGenome2.getNodes().Count;
            // initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.INPUT, node2));
            // node3 = initialGenome2.getNodes().Count;
            // initialGenome2.addNodeGene(new NodeGene(NodeGene.NodeType.OUTPUT, node3));

            // InnovationUtility.incrementGlobalInnovation();
            // initialGenome2.addConnectionGene(new ConnectionGene(node1, node3, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 1));

            // InnovationUtility.incrementGlobalInnovation();
            // initialGenome2.addConnectionGene(new ConnectionGene(node2, node3, Genome.getRandomFloatBetweenPoints(random, -1.0, 1.0), true, 2));


//-------------------------------------------------------------------

            initialGenome.addNodeMutation(random);
            initialGenome3.addNodeMutation(random);


            Console.Write("initialGenome: ");
            foreach (KeyValuePair <int, ConnectionGene> c in initialGenome.getConnections())
            {
                Console.Write("[" + c.Key + "]");
            }

            Console.Write("\n" + "initialGenome1: ");
            foreach (KeyValuePair <int, ConnectionGene> c in initialGenome1.getConnections())
            {
                Console.Write("[" + c.Key + "]");
            }
            Console.Write("\n");

            Console.WriteLine("disjoint: " + Speciation.disjointCount(initialGenome, initialGenome1));
            Console.WriteLine("excess: " + Speciation.excessCount(initialGenome, initialGenome1));

            Console.Write("\n");

            GeneratePopulation population = new GeneratePopulation(4);

            population.addGenomeToPopulation(new Genome(initialGenome));
            population.addGenomeToPopulation(new Genome(initialGenome1));
            population.addGenomeToPopulation(new Genome(initialGenome2));
            population.addGenomeToPopulation(new Genome(initialGenome3));

            for (int i = 0; i < 60; i++)
            {
                population.sortGenomesIntoSpecies(random);
                population.addAdjustedFitness();
                population.fillNextGeneration(random);
                Console.WriteLine("\n Generation: " + i);
                // foreach(Species s in population.getSpeciesList()) {
                //  Console.WriteLine("New Species ");
                //  foreach(Genome g in s.getGenomesList()) {
                //      Console.WriteLine("Genome fitness: " + g.getFitness());
                //  }
                // }
            }



//--------------------------------------------------------------------------------


            // Console.WriteLine("Parent1");
            // foreach(KeyValuePair<int, NodeGene> n in initialGenome.getNodes()) {
            //  Console.WriteLine("ID: " + n.Value.getNodeNumber() + " Layer: " + n.Value.getNodeType());
            // }

            // Console.Write("\n");

            // foreach(KeyValuePair<int, ConnectionGene> c in initialGenome.getConnections()) {
            //  Console.WriteLine("In: " + c.Value.getIn() + " Out: " + c.Value.getOut() + " Innov: " + c.Value.getInnovationNumber() + " Enabled: " + c.Value.getEnabled() + " Weight: " + c.Value.getWeight());
            // }

            // Console.Write("\n");

            // Console.WriteLine("Parent2");
            // foreach(KeyValuePair<int, NodeGene> n in initialGenome2.getNodes()) {
            //  Console.WriteLine("ID: " + n.Value.getNodeNumber() + " Layer: " + n.Value.getNodeType());
            // }

            // Console.Write("\n");

            // foreach(KeyValuePair<int, ConnectionGene> c in initialGenome2.getConnections()) {
            //  Console.WriteLine("In: " + c.Value.getIn() + " Out: " + c.Value.getOut() + " Innov: " + c.Value.getInnovationNumber() + " Enabled: " + c.Value.getEnabled() + " Weight: " + c.Value.getWeight());
            // }

            // Console.Write("\n");

            // Genome child = Evolution.crossover(random, initialGenome, initialGenome2);

            // Console.WriteLine("Child");
            // foreach(KeyValuePair<int, NodeGene> n in child.getNodes()) {
            //  Console.WriteLine("ID: " + n.Value.getNodeNumber() + " Layer: " + n.Value.getNodeType());
            // }

            // Console.Write("\n");

            // foreach(KeyValuePair<int, ConnectionGene> c in child.getConnections()) {
            //  Console.WriteLine("In: " + c.Value.getIn() + " Out: " + c.Value.getOut() + " Innov: " + c.Value.getInnovationNumber() + " Enabled: " + c.Value.getEnabled() + " Weight: " + c.Value.getWeight());
            // }


            //------------------------------------------------------------------------------------------------------------------------------------------------------------

            // Console.WriteLine(Speciation.compatibilityDistance(initialGenome, initialGenome2));


            //------------------------------------------------------------------------------------------------------------------------------------------------------------

            // GeneratePopulation population = new GeneratePopulation(4);

            // population.addGenomeToPopulation(new Genome(initialGenome));
            // population.addGenomeToPopulation(new Genome(initialGenome1));
            // population.addGenomeToPopulation(new Genome(initialGenome2));
            // population.addGenomeToPopulation(new Genome(initialGenome3));


            // GeneratePopulation population = new GeneratePopulation(50);

            // for(int i = 0; i < population.getPopulationSize(); i++) {
            //  population.addGenomeToPopulation(new Genome(initialGenome));
            // }


            // print connection genes
            // Console.WriteLine("CONNECTION GENES: ");
            // foreach(ConnectionGene gene in initialGenome.connections) {
            //  Console.WriteLine("IN: " + gene.getIn() + " OUT: " + gene.getOut() + " WEIGHT: " + gene.getWeight() + " ENABLED: " + gene.getEnabled() + " INNO: " + gene.getInnovationNumber());

            // }

            // Console.WriteLine("\n");



            // for(int i = 1; i < 20; i++) {
            //  bestGen = population.GenerateNextGeneration(random);


            //  Console.Write(" Generation: " + i);
            //  // Console.Write(", Species Count: " + population.getSpeciesList().Count);
            //  Console.Write(", Highest Fitness: " + population.getHighestScore() + "\n");
            // }
        }
예제 #7
0
 public void Check_Connection_Weights()
 {
     Assert.AreEqual(-0.9f, genome.getConnections()[genome.getInnovationNumbers()[0]].getWeight());
 }
예제 #8
0
 public void Length_After_Connection_Mutation()
 {
     genome.addConnectionMutation(random);
     Assert.AreEqual(6, genome.getConnections().Count);
 }