示例#1
0
        private void removeStaleSpecies()
        {
            //REMOVE STALE SPECIES
            List <newSpecies> survived = new List <newSpecies>();

            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];

                species.genomes.Sort();     //(species.genomes, function(a, b) return (a.fitness > b.fitness) end);
                species.genomes.Reverse();  //A.FITNESS > B.FITNESS

                if (species.genomes[0].fitness > species.topFitness)
                {
                    species.topFitness = species.genomes[0].fitness;
                    species.staleness  = 0;
                }
                else
                {
                    species.staleness = species.staleness + 1;
                }

                if (species.staleness < StaleSpecies || species.topFitness >= Pool.maxFitness)
                {
                    survived.Add(species);
                }
            }

            //TRANSFER TO POOL
            NetMain.setConsoleInvoke("Generation complete:\t" + (Pool.species.Count - survived.Count) + " species removed\t" + survived.Count + " survived");
            Pool.species = survived;
        }
示例#2
0
        private void cullSpecies(bool cutToOne)
        {
            //CULL SPECIES (AUSSORTIEREN)
            int removed = 0;

            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];

                species.genomes.Sort();                                             //table.sort(species.genomes, function(a, b) return (a.fitness > b.fitness) end)
                species.genomes.Reverse();                                          //A.FITNESS > B.FITNESS

                double remaining = Math.Ceiling((double)species.genomes.Count / 2); //HALF GENOME SIZE
                if (cutToOne)
                {
                    remaining = 1;                                                      //SIZE ONE
                }
                while (species.genomes.Count > remaining)
                {
                    species.genomes.Remove(species.genomes[species.genomes.Count - 1]); //DELETE LAST ITEM
                    removed++;
                }
            }

            //CONSOLE FEEDBACK
            NetMain.setConsoleInvoke("Cull species:\t" + removed + " genomes removed from " + Pool.species.Count + " species (cut to one = " + cutToOne + ")");
        }
示例#3
0
        private bool fitnessAlreadyMeasured()
        {
            //FITNESS ALREADY MEASURED
            newSpecies species = Pool.species[Pool.currentSpecies];
            newGenome  genome  = species.genomes[Pool.currentGenome];

            return(genome.fitness != 0);
        }
示例#4
0
        private void initializeRun()
        {
            //INITIALIZE RUN
            Score = 0;
            clearJoypad();

            newSpecies      species = Pool.species[Pool.currentSpecies];
            newGenome       genome  = species.genomes[Pool.currentGenome];
            generateNetwork network = new generateNetwork(genome);

            evaluateCurrent();
        }
示例#5
0
        private double totalAverageFitness()
        {
            //TOTAL AVERAGE FITNESS
            double total = 0;

            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];
                total = total + species.averageFitness;
            }

            return(total);
        }
示例#6
0
        private void calculateAverageFitness(newSpecies species)
        {
            //CALCULATE AVERAGE FITNESS
            double total = 0;

            for (int i = 0; i < species.genomes.Count; i++)
            {
                newGenome genome = species.genomes[i];
                total = total + genome.globalRank;
            }

            //SET SPECIES FITNESS
            species.averageFitness = total / species.genomes.Count;
        }
示例#7
0
        private void newGeneration()
        {
            //NEW GENERATION
            cullSpecies(false); //CULL THE BOTTOM HALF OF EACH SPECIES
            rankGlobally();
            removeStaleSpecies();
            rankGlobally();
            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];
                calculateAverageFitness(species);
            }

            //REMOVE WEAK SPECIES
            removeWeakSpecies();

            double sum = totalAverageFitness();

            List <newGenome> children = new List <newGenome>();

            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];

                double breed = Math.Floor(species.averageFitness / sum * Population) - 1;
                for (double d = 0; d < breed; d++) //DOUBLE LOOP
                {
                    children.Add(breedChild(species));
                }
            }

            cullSpecies(true); //CULL ALL BUT THE TOP MEMBER OF EACH SPECIES
            while (children.Count + Pool.species.Count < Population)
            {
                newSpecies species = Pool.species[Random(0, Pool.species.Count - 1)];
                children.Add(breedChild(species));
            }

            for (int i = 0; i < children.Count; i++)
            {
                newGenome child = children[i];
                addToSpecies(child);
            }

            //RAISE POOL GENERATION
            Pool.generation = Pool.generation + 1;

            //GENERATE BACKUP FILE
            //writeFile("backup."..pool.generation.. "."..forms.gettext(saveLoadFile))
        }
示例#8
0
        private void evaluateCurrent()
        {
            //ABBRUCH
            if (!NetMain.Cam.Visible)
            {
                return;
            }

            //EVALUATE CURRENT
            newSpecies species = Pool.species[Pool.currentSpecies];
            newGenome  genome  = species.genomes[Pool.currentGenome];

            List <double> inputs = Mod_Convert.ArrayToList <double>(NetMain.Cam.getDoubleArray());  //READ INPUTS FROM CAM

            Controller = genome.network.evaluateNetwork(inputs);                                    //GET OUTPUTS
        }
示例#9
0
        private void removeWeakSpecies()
        {
            //REMOVE WEAK SPECIES
            List <newSpecies> survived = new List <newSpecies>();

            double sum = totalAverageFitness();

            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];
                double     breed   = Math.Floor(species.averageFitness / sum * Population);
                if (breed >= 1)
                {
                    survived.Add(species);
                }
            }

            //TRANSFER TO POOL
            NetMain.setConsoleInvoke("Weak species:\t" + (Pool.species.Count - survived.Count) + " removed\t" + survived.Count + " survived");
            Pool.species = survived;
        }
示例#10
0
        private newGenome breedChild(newSpecies species)
        {
            //BREED CHILD
            newGenome child;

            if (Random() < CrossoverChance)
            {
                newGenome g1 = species.genomes[Random(0, species.genomes.Count - 1)];
                newGenome g2 = species.genomes[Random(0, species.genomes.Count - 1)];
                child = crossover(g1, g2);
            }
            else
            {
                newGenome g = species.genomes[Random(0, species.genomes.Count - 1)];
                child = g.copyGenome();
            }

            //MUTATE CHILD
            mutate(child);
            return(child);
        }
示例#11
0
        private void rankGlobally()
        {
            List <newGenome> global = new List <newGenome>();

            for (int j = 0; j < Pool.species.Count; j++)
            {
                newSpecies species = Pool.species[j];
                for (int i = 0; i < species.genomes.Count; i++)
                {
                    global.Add(species.genomes[i]);
                }
            }

            //SORT BY FITNESS
            global.Sort(); //function(a, b) return (a.fitness < b.fitness) end)

            //SET GLOBAL RANK
            for (int i = 0; i < global.Count; i++)
            {
                global[i].globalRank = i;
            }
        }
示例#12
0
        private void addToSpecies(newGenome child)
        {
            //ADD TO SPECIES
            bool foundSpecies = false;

            //LOOP AND SEARCH POOL SPECIES
            for (int i = 0; i < Pool.species.Count; i++)
            {
                newSpecies species = Pool.species[i];
                if (!foundSpecies && sameSpecies(child, species.genomes[0]))
                {
                    species.genomes.Add(child);
                    foundSpecies = true;
                }
            }

            //SPECIES NOT FOUND
            if (!foundSpecies)
            {
                newSpecies childSpecies = new newSpecies();
                childSpecies.genomes.Add(child);
                Pool.species.Add(childSpecies);
            }
        }
示例#13
0
        public void Plot(Graphics g)
        {
            Pool = Main.Mario.Pool;

            //ABBRUCH
            if (Pool == null)
            {
                return;
            }

            //RECALCULATE NEUROEVOLUTION
            RecalculateNeuroevolution(Pool);

            //GET SPCIES LIST
            List <newSpecies> spciesList = Pool.species;

            for (int i = 0; i < spciesList.Count; i++)
            {
                float width   = PanelLeft[2] + getScoreWidth(spciesList[i].topFitness);
                float average = PanelLeft[2] + getScoreWidth(spciesList[i].averageFitness);
                float height  = PanelTop[0] + i * PenPositive.Width;

                //DRAW NUMBER
                g.DrawString((i + 1) + ".", Mod_Convert.FontSize(Fonts.MainFont, PenText.Width), PenText.Brush, new PointF(PanelLeft[1], height - PenPositive.Width / 2));

                //DRAW SCORE
                if (Mod_Check.isEven(i))
                {
                    g.DrawLine(PenNegative, new PointF(PanelLeft[2], height), new PointF(width, height));
                }
                else
                {
                    g.DrawLine(PenPositive, new PointF(PanelLeft[2], height), new PointF(width, height));
                }

                //DRAW STALE
                for (int l = 0; l < Pool.species[i].staleness; l++)
                {
                    g.FillEllipse(new SolidBrush(Colors.MainLight), PanelLeft[2] + 1f + l * PenPositive.Width, height, PenPositive.Width / 2, PenPositive.Width / 2);
                }

                //DRAW AVERAGE
                g.DrawLine(new Pen(Colors.MainDominant, 1), new PointF(average, height), new PointF(average, height + PenPositive.Width / 2));
            }

            //INFORMATIONS
            newSpecies currSpecies = Pool.species[Pool.currentSpecies];             //GET CURRENT SPECIES
            newGenome  currGenome  = currSpecies.genomes[Pool.currentGenome];       //GET CURRENT GENOME

            float left     = PanelLeft[0];
            Font  infoFont = Mod_Convert.FontSize(Fonts.MainFont, 9);

            g.DrawString("Generation:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString(Pool.generation.ToString(), infoFont, PenText.Brush, new PointF(left, PanelTop[2]));

            left += PanelLeft[0] * 2.5f;
            g.DrawString("Species:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString((Pool.currentSpecies + 1) + "/" + Pool.species.Count, infoFont, PenText.Brush, new PointF(left, PanelTop[2]));

            left += PanelLeft[0] * 2.5f;
            g.DrawString("Genome:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString((Pool.currentGenome + 1) + "/" + currSpecies.genomes.Count, infoFont, PenText.Brush, new PointF(left, PanelTop[2]));

            left += PanelLeft[0] * 2.5f;
            g.DrawString("Stale:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString(currSpecies.staleness + "/" + (NetMario.StaleSpecies - 1), infoFont, PenText.Brush, new PointF(left, PanelTop[2]));

            left += PanelLeft[0] * 2.5f;
            g.DrawString("Fitness:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString(currGenome.fitness + " (" + Pool.maxFitness + ", " + currSpecies.averageFitness + ")", infoFont, PenText.Brush, new PointF(left, PanelTop[2]));

            left += PanelLeft[0] * 2.5f;
            g.DrawString("Measure:", infoFont, PenNegative.Brush, new PointF(left, PanelTop[1]));
            g.DrawString(Pool.measured + " %", infoFont, PenText.Brush, new PointF(left, PanelTop[2]));
        }
示例#14
0
        public void Load()
        {
            //LOAD
            string[] path = Mod_File.FileOpenDialog(false, FILTER.TXT);

            //ABBRUCH
            if (path == null)
            {
                return;
            }

            //START LOADING
            UniLoad.loadingStart();

            //READ TXT FILE
            string[] file = Mod_TXT.readTXT(path[0]);
            int      x    = 0;

            //GET DURATION
            Duration = TimeSpan.FromMilliseconds(Mod_Convert.StringToDouble(file[x++]));

            //GET OUTPUT KEYS
            OutputKeys = file[x++].Split(' ');

            //INITIALIZE POOL
            Initialize(OutputKeys, true);
            Pool.generation = Mod_Convert.StringToInteger(file[x++]);
            Pool.maxFitness = Mod_Convert.StringToDouble(file[x++]);

            int numSpecies = Mod_Convert.StringToInteger(file[x++]);

            for (int j = 0; j < numSpecies; j++) //SPECIES
            {
                newSpecies species = new newSpecies();
                Pool.species.Add(species);
                species.topFitness = Mod_Convert.StringToDouble(file[x++]);
                species.staleness  = Mod_Convert.StringToInteger(file[x++]);
                int numGenomes = Mod_Convert.StringToInteger(file[x++]);
                for (int i = 0; i < numGenomes; i++) //GENOME
                {
                    newGenome genome = new newGenome();
                    species.genomes.Add(genome);
                    genome.fitness   = Mod_Convert.StringToDouble(file[x++]);
                    genome.maxneuron = Mod_Convert.StringToInteger(file[x++]);

                    string line = file[x++];
                    while (line != "done")
                    {
                        genome.mutationRates[line] = Mod_Convert.StringToDouble(file[x++]);
                        line = file[x++];
                    }

                    int numGenes = Mod_Convert.StringToInteger(file[x++]);
                    for (int k = 0; k < numGenes; k++) //GENE
                    {
                        newGene gene = new newGene();

                        genome.genes.Add(gene);
                        string[] split = file[x++].Split(' ');

                        gene.into       = Mod_Convert.StringToInteger(split[0]);
                        gene.output     = Mod_Convert.StringToInteger(split[1]);
                        gene.weight     = Mod_Convert.StringToDouble(split[2]);
                        gene.innovation = Mod_Convert.StringToInteger(split[3]);
                        gene.enabled    = Mod_Convert.ObjectToBool(split[4]);
                    }
                }
            }
            //FITNESS ALREADY MEASURED
            while (fitnessAlreadyMeasured())
            {
                nextGenome();
            }

            initializeRun();

            //UPDATE LEARN PANEL
            NetMain.RoundFinished(0);

            //END LOADING
            UniLoad.loadingEnd();
        }
示例#15
0
        public void LearningRun()
        {
            //LEARNING RUN
            if (!Learning)
            {
                Status = "stopped"; return;
            }

            //GET SCORE
            Score = NetMain.Cam.Score; //SCORE = TIME -> T-REX RUNNING

            //RESET GAME
            if (Reset)
            {
                NetMain.Cam.eventResetGame(); Wait = true; Status = "reset";
            }
            if (Wait)
            {
                if (NetMain.Cam.Alive)
                {
                    Reset = Wait = false; StartRun = DateTime.Now;
                }
                else
                {
                    return;
                }
            }

            Status = "alive";

            //GET CURRENT SPECIES & GENOME
            newSpecies species = Pool.species[Pool.currentSpecies];
            newGenome  genome  = species.genomes[Pool.currentGenome];

            //CONVERT INPUTS TO OUTPUTS
            evaluateCurrent();

            //EXECUTE OUTPUTS
            foreach (string key in Controller.Keys.ToList())
            {
                if (Controller[key])
                {
                    NetMain.Cam.eventGlobalSendKeys(Array.IndexOf(Controller.Keys.ToArray(), key));                  //SENDKEYS
                }
                else
                {
                    NetMain.Cam.eventGlobalSendKeys(int.MinValue);
                }
            }

            //CHECK IS ALIVE
            if (!NetMain.Cam.Alive && !Reset)
            {
                double fitness = Score;
                if (Score > 500) //INPUT BONUS SCORE
                {
                    fitness = fitness + 200;
                }

                if (fitness == 0)
                {
                    fitness = -1;
                }

                genome.fitness = fitness;

                //MAKE BACKUP IF HIGHSCORE REACHED
                if (fitness > Pool.maxFitness)
                {
                    Pool.maxFitness = fitness;
                    Console.WriteLine("Max Fitness: " + Math.Floor(Pool.maxFitness));
                    Console.WriteLine("backup." + Pool.generation + ".");
                }

                Pool.currentSpecies = 0;        //ZERO START
                Pool.currentGenome  = 0;        //ZERO START

                while (fitnessAlreadyMeasured())
                {
                    Status = "next genome"; nextGenome();
                }
                Status = "dead";

                //FEEDBACK
                int currSpecies = Pool.currentSpecies + 1;
                int currGenome  = Pool.currentGenome + 1;

                //LEARN PANEL CALLBACK FUNCTION
                NetMain.RoundFinished(Score);

                //INITIALIZE RUN
                initializeRun();

                double measured = 0;
                double total    = 0;
                foreach (newSpecies spec in Pool.species)
                {
                    foreach (newGenome gen in spec.genomes)
                    {
                        total = total + 1;
                        if (gen.fitness != 0)
                        {
                            measured = measured + 1;
                        }
                        Status = "measure";
                    }
                }

                //CONSOLE FEEDBACK
                Pool.measured = Math.Floor(measured / total * 100);
                DurationRun   = StartRun - DateTime.Now;
                NetMain.setConsoleInvoke("Round finished!\tDuration: " + DurationRun.ToString(@"mm\:ss") + "\tGeneration: " + Pool.generation + "\tSpecies: " + currSpecies + "\tStale: " + Pool.species[Pool.currentSpecies].staleness + "\tGenome: " + currGenome + "\tFitness: " + fitness + "\tMeasured: " + Pool.measured + "%");

                //RESET GAME
                Reset = true;
            }
        }