コード例 #1
0
        /// <summary>
        /// Gets the species with a centroid closest to the given genome.
        /// If multiple species are equally close then we return all of the those species.
        /// </summary>
        public static List <Species <T> > GetNearestSpeciesList <T>(
            NeatGenome <T> genome,
            Species <T>[] speciesArr,
            IDistanceMetric <T> distanceMetric)
            where T : struct
        {
            var nearestSpeciesList = new List <Species <T> >(4);

            nearestSpeciesList.Add(speciesArr[0]);
            double nearestDistance = distanceMetric.GetDistance(genome.ConnectionGenes, speciesArr[0].Centroid);

            for (int i = 1; i < speciesArr.Length; i++)
            {
                double distance = distanceMetric.GetDistance(genome.ConnectionGenes, speciesArr[i].Centroid);
                if (distance < nearestDistance)
                {
                    nearestSpeciesList.Clear();
                    nearestSpeciesList.Add(speciesArr[i]);
                    nearestDistance = distance;
                }
                else if (distance == nearestDistance)
                {
                    nearestSpeciesList.Add(speciesArr[i]);
                }
            }
            return(nearestSpeciesList);
        }
コード例 #2
0
        // ENHANCEMENT: Optimization candidate.
        /// <summary>
        /// Gets an array of all genomes ordered by their distance from their current specie.
        /// </summary>
        private TGenome[] GetGenomesByDistanceFromSpecie(IList <TGenome> genomeList, IList <Specie <TGenome> > specieList)
        {
            // Build a list of all genomes paired with their distance from their centroid.
            int genomeCount = genomeList.Count;

            GenomeDistancePair <TGenome>[] genomeDistanceArr = new GenomeDistancePair <TGenome> [genomeCount];
            for (int i = 0; i < genomeCount; i++)
            {
                TGenome genome   = genomeList[i];
                double  distance = _distanceMetric.GetDistance(genome.Position, specieList[genome.SpecieIdx].Centroid);
                genomeDistanceArr[i] = new GenomeDistancePair <TGenome>(distance, genome);
            }

            // Sort list. Longest distance first.
            Array.Sort(genomeDistanceArr);

            // Put the sorted genomes in an array and return it.
            TGenome[] genomeArr = new TGenome[genomeCount];
            for (int i = 0; i < genomeCount; i++)
            {
                genomeArr[i] = genomeDistanceArr[i]._genome;
            }

            return(genomeArr);
        }
コード例 #3
0
        // ENHANCEMENT: Optimization candidate.
        /// <summary>
        /// Gets an array of all genomes ordered by their distance from their current specie.
        /// </summary>
        private TGenome[] GetGenomesByDistanceFromSpecie(IList <TGenome> genomeList, IList <Specie <TGenome> > specieList)
        {
            // Build an array of all genomes paired with their distance from their centroid.
            int genomeCount = genomeList.Count;

            GenomeDistancePair <TGenome>[] genomeDistanceArr = new GenomeDistancePair <TGenome> [genomeCount];

            Parallel.For(0, genomeCount, _parallelOptions, delegate(int i)
            {
                TGenome genome       = genomeList[i];
                double distance      = _distanceMetric.GetDistance(genome.Position, specieList[genome.SpecieIdx].Centroid);
                genomeDistanceArr[i] = new GenomeDistancePair <TGenome>(distance, genome);
            });

            // Sort list. Longest distance first.
            // TODO: Pass in parallel options.
            ParallelSort.QuicksortParallel(genomeDistanceArr);

            // Put the sorted genomes in an array and return it.
            TGenome[] genomeArr = new TGenome[genomeCount];
            for (int i = 0; i < genomeCount; i++)
            {
                genomeArr[i] = genomeDistanceArr[i]._genome;
            }

            return(genomeArr);
        }
コード例 #4
0
        private double GetDistanceFromNearestSeed(List <NeatGenome <T> > seedGenomeList, NeatGenome <T> genome)
        {
            double minDistance = _distanceMetric.GetDistance(seedGenomeList[0].ConnectionGenes, genome.ConnectionGenes);

            for (int i = 1; i < seedGenomeList.Count; i++)
            {
                double distance = _distanceMetric.GetDistance(seedGenomeList[i].ConnectionGenes, genome.ConnectionGenes);
                distance = Math.Min(minDistance, distance);
            }
            return(minDistance);
        }
        /// <summary>
        /// Gets an adjusted distance between the given genome and a species centroid.
        /// The adjustment introduces a regularization term.
        /// </summary>
        private double GetAdjustedDistance(
            NeatGenome <T> genome,
            Species <T> species,
            double populationCount,
            double maxIntraSpeciesDistance)
        {
            double distance = _distanceMetric.GetDistance(genome.ConnectionGenes, species.Centroid);

            // Calc regularization term.
            double clusterCount = species.GenomeById.Count;
            double r            = (clusterCount / populationCount) * maxIntraSpeciesDistance * _regularizationConstant;

            // Return the distance plus the regularization term.
            return(distance + r);
        }
コード例 #6
0
        public static void ValidationTests(
            Species <double>[] speciesArr,
            IDistanceMetric <double> distanceMetric,
            int speciesCountExpected,
            List <NeatGenome <double> > fullGenomeList,
            bool validateNearestSpecies)
        {
            // Confirm correct number of species.
            Assert.AreEqual(speciesCountExpected, speciesArr.Length);

            // Confirm no empty species.
            int minSpeciesSize = speciesArr.Select(x => x.GenomeList.Count).Min();

            Assert.IsTrue(minSpeciesSize > 0);

            // Get IDs of all genomes in species.
            var idSet = GetAllGenomeIds(speciesArr);

            // Confirm number of IDs equals number of genomes in main population list.
            Assert.AreEqual(fullGenomeList.Count, idSet.Count);

            // Confirm the genome list IDs match up with the genomes in the species.
            fullGenomeList.ForEach(x => Assert.IsTrue(idSet.Contains(x.Id)));

            // Confirm all species centroids are correct.
            Array.ForEach(speciesArr, x => Assert.AreEqual(0.0, distanceMetric.GetDistance(x.Centroid, distanceMetric.CalculateCentroid(x.GenomeList.Select(y => y.ConnectionGenes)))));

            if (validateNearestSpecies)
            {
                // Confirm all genomes are in the species with the nearest centroid.
                // Note. If there are two or more species that are equally near then we test that a genome is in one of those.
                Array.ForEach(speciesArr, species => species.GenomeList.ForEach(genome => Assert.IsTrue(GetNearestSpeciesList(genome, speciesArr, distanceMetric).Contains(species))));
            }
        }
コード例 #7
0
        /// <summary>
        /// Get the index of the species with a centroid that is nearest to the provided genome.
        /// </summary>
        public static int GetNearestSpecies <T>(
            IDistanceMetric <T> distanceMetric,
            NeatGenome <T> genome,
            Species <T>[] speciesArr)
            where T : struct
        {
            int    nearestSpeciesIdx = 0;
            double nearestDistance   = distanceMetric.GetDistance(genome.ConnectionGenes, speciesArr[0].Centroid);

            for (int i = 1; i < speciesArr.Length; i++)
            {
                double distance = distanceMetric.GetDistance(genome.ConnectionGenes, speciesArr[i].Centroid);
                if (distance < nearestDistance)
                {
                    nearestSpeciesIdx = i;
                    nearestDistance   = distance;
                }
            }
            return(nearestSpeciesIdx);
        }
コード例 #8
0
        /// <summary>
        /// Calculate the mean distance of the specified coord from all of the other coords using
        /// the provided distance metric.
        /// </summary>
        /// <param name="distanceMetric">The distance metric.</param>
        /// <param name="coordList">The list of coordinates.</param>
        /// <param name="idx">The index of the coordinate to measure distance to.</param>
        private static double CalculateMeanDistanceFromCoords(IDistanceMetric distanceMetric, IList <CoordinateVector> coordList, int idx)
        {
            double           totalDistance = 0.0;
            int              count         = coordList.Count;
            CoordinateVector targetCoord   = coordList[idx];

            // Measure distance to all coords before the target one.
            for (int i = 0; i < idx; i++)
            {
                totalDistance += distanceMetric.GetDistance(targetCoord, coordList[i]);
            }

            // Measure distance to all coords after the target one.
            for (int i = idx + 1; i < count; i++)
            {
                totalDistance += distanceMetric.GetDistance(targetCoord, coordList[i]);
            }

            return(totalDistance / (count - 1));
        }
コード例 #9
0
        private static NeatGenome <T> GetGenomeForEmptySpecies <T>(
            IDistanceMetric <T> distanceMetric,
            Species <T>[] speciesArr)
            where T : struct
        {
            // Get the species with the highest number of genomes.
            Species <T> species = speciesArr.Aggregate((x, y) => x.GenomeById.Count > y.GenomeById.Count ?  x : y);

            // Get the genome furthest from the species centroid.
            var genome = species.GenomeById.Values.Aggregate((x, y) => distanceMetric.GetDistance(species.Centroid, x.ConnectionGenes) > distanceMetric.GetDistance(species.Centroid, y.ConnectionGenes) ? x : y);

            // Remove the genome from its current species.
            species.GenomeById.Remove(genome.Id);

            // Update the species centroid.
            species.Centroid = distanceMetric.CalculateCentroid(species.GenomeById.Values.Select(x => x.ConnectionGenes));

            // Return the selected genome.
            return(genome);
        }