<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Grasshopper.Kernel.Special;
using GalapagosComponents;

namespace Biomorpher.IGA
{
    public class Population
    {

        // List of sliders
        private List<GH_NumberSlider> popSliders;
        private List<GalapagosGeneListObject> popGenePools;

        // the population of chromosomes
        public Chromosome[] chromosomes { get; set; }

        // IDs of (12) cluster representatives
        private List<int> clusterIDs { get; set; }

        /// <summary>
        /// Construct a new population of chromosomes
        /// </summary>
        /// <param name="popSize"></param>
        public Population(int popSize, List<GH_NumberSlider> sliders, List<GalapagosGeneListObject> genePools)
        {
            chromosomes = new Chromosome[popSize];
            popSliders = new List<GH_NumberSlider>(sliders);
            popGenePools = new List<GalapagosGeneListObject>(genePools);
            GenerateRandomPop();
        }

        /// <summary>
        /// Creates a value copy of the population's chomosomes and genes
        /// </summary>
        /// <param name="pop"></param>
        public Population(Population pop)
        {
            // same length
            chromosomes = new Chromosome[pop.chromosomes.Length];

            // clone the chromosomes
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = pop.chromosomes[i].Clone();
            }
        }

        /// <summary>
        /// Generates a random population of new chromosomes.
        /// </summary>
        /// <param name="geneNumber"></param>
        public void GenerateRandomPop()
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = new Chromosome(popSliders, popGenePools);
                chromosomes[i].GenerateRandomGenes();
            }
        }

        /// <summary>
        /// Replaces the population with a new one based on fitness using Roulette Wheel selection
        /// </summary>
        public void RoulettePop()
        {
            // Roulette Wheel technique here as described by <NAME>, An Introduction to GAs, p.166
            double fitSum;
            double totalFitness = 0.0;

            // Set up a fresh population  
            // TODO: Do we have to calculate new geometry for everything? Why not have flags if GetGeometry() needs to be called
            Population newPop = new Population(this.chromosomes.Length, popSliders, popGenePools);

            // find the total fitness
            for (int i = 0; i < chromosomes.Length; i++)
            {
                totalFitness += chromosomes[i].GetFitness();
            }

            // Now for the roulette wheel selection for the new population
            for (int i = 0; i < newPop.chromosomes.Length; i++)
            {
                double weightedRandom = Friends.GetRandomDouble() * totalFitness;
                fitSum = 0.0;

                for (int j = 0; j < chromosomes.Length; j++)
                {
                    fitSum += chromosomes[j].GetFitness();
                    if (fitSum > weightedRandom)
                    {
                        newPop.chromosomes[i] = chromosomes[j].Clone();
                        break;
                    }
                }
            }

            // Replace the current popultion of chromosomes with the newPop
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = newPop.chromosomes[i].Clone();
            }

            // Make sure to reset all the fitnesses here (selection has now already occured).
            ResetAllFitness();
        }

        /// <summary>
        /// Mutates a gene according to a probability
        /// </summary>
        /// <param name="probability"></param>
        public void MutatePop(double probability)
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i].Mutate(probability);
            }
        }

        /// <summary>
        /// Resets all the fitness values to zero at the start of a new generation
        /// </summary>
        public void ResetAllFitness()
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i].SetFitness(0.0);
            }
        }


        //----------------------------------------------------------------- K-MEANS --------------------------------------------------------------//

        //K-Means clustering of the chromosomes in this population
        public void KMeansClustering(int numClusters)
        {
            //Initiliase clustering
            initClustering(numClusters);

            //Loop
            bool go = true;
            int count = 0;
            int maxIter = 20;

            while (go && count < maxIter)
            {
                //Calculate mean vectors based on current clustering
                double[][] clusterMeanVectors = calcClusterMeans(numClusters);

                //Update clustering
                go = updateClustering(numClusters, clusterMeanVectors);

                count++;
            }

            //Update chromosome info
            calcKMeansRepresentatives(numClusters);

        }


        //Initialise random clustering (but ensure at least one chromosome in each cluster)
        public void initClustering(int numClusters)
        {
            int seed = 0;
            Random rnd = new Random(seed);

            for (int i = 0; i < numClusters; i++)
            {
                chromosomes[i].clusterId = i;
            }

            for (int i = numClusters; i < chromosomes.Length; i++)
            {
                int r = rnd.Next(0, numClusters);
                chromosomes[i].clusterId = r;
            }
        }


        //Calculate cluster mean vectors (same length as genes)
        public double[][] calcClusterMeans(int numClusters)
        {
            int numGenes = chromosomes[0].GetGenes().Length;

            //Initialise arrays
            double[][] clusterMeanVectors = new double[numClusters][];

            for (int i = 0; i < numClusters; i++)
            {
                clusterMeanVectors[i] = new double[numGenes];<commit_msg>Initial commit<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Grasshopper.Kernel.Special;
using GalapagosComponents;

namespace Biomorpher.IGA
{
    public class Population
    {

        // List of sliders
        private List<GH_NumberSlider> popSliders;
        private List<GalapagosGeneListObject> popGenePools;

        // the population of chromosomes
        public Chromosome[] chromosomes { get; set; }

        // IDs of (12) cluster representatives
        private List<int> clusterIDs { get; set; }

        /// <summary>
        /// Construct a new population of chromosomes
        /// </summary>
        /// <param name="popSize"></param>
        public Population(int popSize, List<GH_NumberSlider> sliders, List<GalapagosGeneListObject> genePools)
        {
            chromosomes = new Chromosome[popSize];
            popSliders = new List<GH_NumberSlider>(sliders);
            popGenePools = new List<GalapagosGeneListObject>(genePools);
            GenerateRandomPop();
        }

        /// <summary>
        /// Creates a value copy of the population's chomosomes and genes
        /// </summary>
        /// <param name="pop"></param>
        public Population(Population pop)
        {
            // same length
            chromosomes = new Chromosome[pop.chromosomes.Length];

            // clone the chromosomes
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = pop.chromosomes[i].Clone();
            }
        }

        /// <summary>
        /// Generates a random population of new chromosomes.
        /// </summary>
        /// <param name="geneNumber"></param>
        public void GenerateRandomPop()
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = new Chromosome(popSliders, popGenePools);
                chromosomes[i].GenerateRandomGenes();
            }
        }

        /// <summary>
        /// Replaces the population with a new one based on fitness using Roulette Wheel selection
        /// </summary>
        public void RoulettePop()
        {
            // Roulette Wheel technique here as described by <NAME>, An Introduction to GAs, p.166
            double fitSum;
            double totalFitness = 0.0;

            // Set up a fresh population  
            // TODO: Do we have to calculate new geometry for everything? Why not have flags if GetGeometry() needs to be called
            Population newPop = new Population(this.chromosomes.Length, popSliders, popGenePools);

            // find the total fitness
            for (int i = 0; i < chromosomes.Length; i++)
            {
                totalFitness += chromosomes[i].GetFitness();
            }

            // Now for the roulette wheel selection for the new population
            for (int i = 0; i < newPop.chromosomes.Length; i++)
            {
                double weightedRandom = Friends.GetRandomDouble() * totalFitness;
                fitSum = 0.0;

                for (int j = 0; j < chromosomes.Length; j++)
                {
                    fitSum += chromosomes[j].GetFitness();
                    if (fitSum > weightedRandom)
                    {
                        newPop.chromosomes[i] = chromosomes[j].Clone();
                        break;
                    }
                }
            }

            // Replace the current popultion of chromosomes with the newPop
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i] = newPop.chromosomes[i].Clone();
            }

            // Make sure to reset all the fitnesses here (selection has now already occured).
            ResetAllFitness();
        }

        /// <summary>
        /// Mutates a gene according to a probability
        /// </summary>
        /// <param name="probability"></param>
        public void MutatePop(double probability)
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i].Mutate(probability);
            }
        }

        /// <summary>
        /// Resets all the fitness values to zero at the start of a new generation
        /// </summary>
        public void ResetAllFitness()
        {
            for (int i = 0; i < chromosomes.Length; i++)
            {
                chromosomes[i].SetFitness(0.0);
            }
        }


        //----------------------------------------------------------------- K-MEANS --------------------------------------------------------------//

        //K-Means clustering of the chromosomes in this population
        public void KMeansClustering(int numClusters)
        {
            //Initiliase clustering
            initClustering(numClusters);

            //Loop
            bool go = true;
            int count = 0;
            int maxIter = 20;

            while (go && count < maxIter)
            {
                //Calculate mean vectors based on current clustering
                double[][] clusterMeanVectors = calcClusterMeans(numClusters);

                //Update clustering
                go = updateClustering(numClusters, clusterMeanVectors);

                count++;
            }

            //Update chromosome info
            calcKMeansRepresentatives(numClusters);

        }


        //--------------------------------------------K-Means++------------------------------------------------------//






        //--------------------------------------------K-Means++------------------------------------------------------//




        //Initialise random clustering (but ensure at least one chromosome in each cluster)
        public void initClustering(int numClusters)
        {
            int seed = 0;
            Random rnd = new Random(seed);

            for (int i = 0; i < numClusters; i++)
            {
                chromosomes[i].clusterId = i;
            }

            for (int i = numClusters; i < chromosomes.Length; i++)
            {
                int r = rnd.Next(0, numClusters);
                chromosomes[i].clusterId = r;
            }
        }


        //Calculate cluster mean vectors (same length as genes)
        public double[][] calcClusterMeans(int numClusters)
        {
            int numGenes = chromosomes[0].GetGenes().Length;

            //Initialise arrays
            double[][] clusterMeanVectors = new double[numClusters][];

            for (int i = 0; i < numClusters; i++)
            {
                clusterMeanVectors[i] = new double[numGenes];
{'fraction_non_alphanumeric': 0.12878497508623993, 'fraction_numerical': 0.004139517056343427, 'mean_word_length': 1.3737263464337701, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3376157', 'n_tokens_mistral': 3516, 'n_tokens_neox': 3113, 'n_words': 924}