<commit_before>//This is a dual-purpose class for gene pools - it serves as a "base"
//GA, and also as a gene pool for individuals in hierarchical GAs
//Since these functions are, by and large, very similar, they can be
//combined together into one class

#include "core/HierarchicalGenePool.hpp"
#include <sstream>
#include <iostream>

using namespace std;

//If we don't know the optimum
HierarchicalGenePool::HierarchicalGenePool(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) : GenePool() {
	init(newPopulationSize, templateIndividual, myMaxGenerations, numIterations, newModel, newCondition, newPropagator);
}

//Unknown optimum, overridden seed
HierarchicalGenePool::HierarchicalGenePool(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, int newSeed, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) : GenePool(newSeed) {
	init(newPopulationSize, templateIndividual, myMaxGenerations, numIterations, newModel, newCondition, newPropagator);
}

HierarchicalGenePool::~HierarchicalGenePool() {
	for (int i = 0; i < populationSize; i++) {
		delete(myPopulation[i]);
	}

	free(myPopulation);
	free(populationFitnesses);
}

void HierarchicalGenePool::init(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) {
	myPopulation = (Individual**)malloc(sizeof(Individual*)*newPopulationSize);

	populationFitnesses = (int*)malloc(sizeof(int)*newPopulationSize);

	populationSize = newPopulationSize;
        currentGeneration = 0;
	readOnce = false;

	maxGenerations = myMaxGenerations;
	numIterationsPerGeneration = numIterations;
	myModel = newModel;
	myCondition = newCondition;
	myPropagator = newPropagator;

        for (int i = 0; i < populationSize; i++) {
                myPopulation[i] = templateIndividual->makeRandomCopy();
        }

        optimumFound = false;

        evaluateFitnesses();
}

//Evaluates the fitnesses of the population of this particular GenePool
//Basically a convenience thing
void HierarchicalGenePool::evaluateFitnesses() {
	for (int i = 0; i < populationSize; i++) {
		populationFitnesses[i] = myPopulation[i]->checkFitness();
	}
}

//Evaluates the fitnesses of a given population of individuals
//Doesn't care what their genetic makeup is - uses their fitness functions
int * HierarchicalGenePool::evaluateFitnesses(Individual ** populationToEval, int populationToEvalSize) {
	int * populationToEvalFitnesses = (int*)malloc(sizeof(int)*populationToEvalSize);

	for (int i = 0; i < populationToEvalSize; i++) {
		populationToEvalFitnesses[i] = populationToEval[i]->checkFitness();
	}

	return populationToEvalFitnesses;
}

//When we need a specific individual
void * HierarchicalGenePool::getIndex(int index) {
	void * returnValue;

	returnValue = (void*)myPopulation[index];

	return returnValue;
}

void * HierarchicalGenePool::getFittest() {
	int fittestIndex;
	int fittestIndexFitness = 0;

	for (int i = 0; i < populationSize; i++) {
		if (populationFitnesses[i] > fittestIndexFitness) {
			fittestIndex = i;
			fittestIndexFitness = populationFitnesses[i];
		}
	}

	return (void*)myPopulation[fittestIndex];
}

//Run one generation
void HierarchicalGenePool::nextGeneration() {
	Individual ** newPopulation;

	if (currentGeneration < maxGenerations && optimumFound == false) {
		//Run the hierarchical component first - we're evolving
		//from the bottom up
		myPopulation[0]->runHierarchicalGenerations();

		//Re-evaluate the fitnesses to take the lower GenePools
		//running their generations into account
		evaluateFitnesses();

		//We propagate after evaluating because we want the lower
		//levels that DON'T get propagated to (if they exist) to
		//act like normal
		propagateFitnesses();

		newPopulation = myModel->breedMutateSelect(myPopulation, populationFitnesses, populationSize);

                currentGeneration += 1;

		//The new generation replaces the old
		for (int i = 0; i < populationSize; i++) {
			myPopulation[i] = newPopulation[i]->deepCopy();
			delete(newPopulation[i]);
		}

		free(newPopulation);

		if (myCondition != NULL) {
			for (int i = 0; i < populationSize && optimumFound == false; i++) {
				optimumFound = myCondition->checkCondition(myPopulation[i]);
			}
		}
	}
}

void HierarchicalGenePool::propagateFitnesses() {
	myPropagator->propagateFitnesses(myPopulation, populationSize);
}

void HierarchicalGenePool::run(bool verbose) {
	if (verbose == true) {
		cout << "Before:\n" << toString() << "-----------------------------------------------------------------\n";
	}

	while (currentGeneration < maxGenerations && optimumFound == false) {
		if (verbose == true) {
			cout << "Before generation " << currentGeneration << ":\n";
			cout << toString();
			cout << "-----------------------------------------------------------------\n";
		}

		runGenerations();
	}

	if (verbose == true) {
		cout << "After:\n" << toString() << "-----------------------------------------------------------------\n";
		if (optimumFound == true) {
			cout << "Genetic algorithm ended after generation " << currentGeneration-1 << " because specified ending condition was met.\n";
		}
	}

}

//For HGAs - if we want to run multiple generations of a lower-level gene pool
//for every one of a higher-level one, this is how
//Basically a loop wrapped around nextGeneration()
void HierarchicalGenePool::runGenerations() {
	int target = currentGeneration + numIterationsPerGeneration;

	for (int i = currentGeneration; i < target && i < maxGenerations && optimumFound == false; i++) {
		nextGeneration();
	}
}

void HierarchicalGenePool::sortPopulation() {
	myModel->sortPopulation(myPopulation, populationFitnesses, populationSize);<commit_msg>[HierarchicalGenePool]: Fixed generation count in verbose mode<commit_after>//This is a dual-purpose class for gene pools - it serves as a "base"
//GA, and also as a gene pool for individuals in hierarchical GAs
//Since these functions are, by and large, very similar, they can be
//combined together into one class

#include "core/HierarchicalGenePool.hpp"
#include <sstream>
#include <iostream>

using namespace std;

//If we don't know the optimum
HierarchicalGenePool::HierarchicalGenePool(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) : GenePool() {
	init(newPopulationSize, templateIndividual, myMaxGenerations, numIterations, newModel, newCondition, newPropagator);
}

//Unknown optimum, overridden seed
HierarchicalGenePool::HierarchicalGenePool(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, int newSeed, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) : GenePool(newSeed) {
	init(newPopulationSize, templateIndividual, myMaxGenerations, numIterations, newModel, newCondition, newPropagator);
}

HierarchicalGenePool::~HierarchicalGenePool() {
	for (int i = 0; i < populationSize; i++) {
		delete(myPopulation[i]);
	}

	free(myPopulation);
	free(populationFitnesses);
}

void HierarchicalGenePool::init(int newPopulationSize, Individual * templateIndividual, int myMaxGenerations, int numIterations, GenerationModel * newModel, EndCondition * newCondition, FitnessPropagator * newPropagator) {
	myPopulation = (Individual**)malloc(sizeof(Individual*)*newPopulationSize);

	populationFitnesses = (int*)malloc(sizeof(int)*newPopulationSize);

	populationSize = newPopulationSize;
        currentGeneration = 0;
	readOnce = false;

	maxGenerations = myMaxGenerations;
	numIterationsPerGeneration = numIterations;
	myModel = newModel;
	myCondition = newCondition;
	myPropagator = newPropagator;

        for (int i = 0; i < populationSize; i++) {
                myPopulation[i] = templateIndividual->makeRandomCopy();
        }

        optimumFound = false;

        evaluateFitnesses();
}

//Evaluates the fitnesses of the population of this particular GenePool
//Basically a convenience thing
void HierarchicalGenePool::evaluateFitnesses() {
	for (int i = 0; i < populationSize; i++) {
		populationFitnesses[i] = myPopulation[i]->checkFitness();
	}
}

//Evaluates the fitnesses of a given population of individuals
//Doesn't care what their genetic makeup is - uses their fitness functions
int * HierarchicalGenePool::evaluateFitnesses(Individual ** populationToEval, int populationToEvalSize) {
	int * populationToEvalFitnesses = (int*)malloc(sizeof(int)*populationToEvalSize);

	for (int i = 0; i < populationToEvalSize; i++) {
		populationToEvalFitnesses[i] = populationToEval[i]->checkFitness();
	}

	return populationToEvalFitnesses;
}

//When we need a specific individual
void * HierarchicalGenePool::getIndex(int index) {
	void * returnValue;

	returnValue = (void*)myPopulation[index];

	return returnValue;
}

void * HierarchicalGenePool::getFittest() {
	int fittestIndex;
	int fittestIndexFitness = 0;

	for (int i = 0; i < populationSize; i++) {
		if (populationFitnesses[i] > fittestIndexFitness) {
			fittestIndex = i;
			fittestIndexFitness = populationFitnesses[i];
		}
	}

	return (void*)myPopulation[fittestIndex];
}

//Run one generation
void HierarchicalGenePool::nextGeneration() {
	Individual ** newPopulation;

	if (currentGeneration < maxGenerations && optimumFound == false) {
		//Run the hierarchical component first - we're evolving
		//from the bottom up
		myPopulation[0]->runHierarchicalGenerations();

		//Re-evaluate the fitnesses to take the lower GenePools
		//running their generations into account
		evaluateFitnesses();

		//We propagate after evaluating because we want the lower
		//levels that DON'T get propagated to (if they exist) to
		//act like normal
		propagateFitnesses();

		newPopulation = myModel->breedMutateSelect(myPopulation, populationFitnesses, populationSize);

                currentGeneration += 1;

		//The new generation replaces the old
		for (int i = 0; i < populationSize; i++) {
			myPopulation[i] = newPopulation[i]->deepCopy();
			delete(newPopulation[i]);
		}

		free(newPopulation);

		if (myCondition != NULL) {
			for (int i = 0; i < populationSize && optimumFound == false; i++) {
				optimumFound = myCondition->checkCondition(myPopulation[i]);
			}
		}
	}
}

void HierarchicalGenePool::propagateFitnesses() {
	myPropagator->propagateFitnesses(myPopulation, populationSize);
}

void HierarchicalGenePool::run(bool verbose) {
	if (verbose == true) {
		cout << "Before:\n" << toString() << "-----------------------------------------------------------------\n";
	}

	while (currentGeneration < maxGenerations && optimumFound == false) {
		if (verbose == true) {
			//Because currentGeneration is 0-indexed, but humans
			//start counting from 1
			cout << "Before generation " << currentGeneration+1 << ":\n";
			cout << toString();
			cout << "-----------------------------------------------------------------\n";
		}

		runGenerations();
	}

	if (verbose == true) {
		cout << "After:\n" << toString() << "-----------------------------------------------------------------\n";
		if (optimumFound == true) {
			cout << "Genetic algorithm ended after generation " << currentGeneration << " because specified ending condition was met.\n";
		} else {
			cout << "Genetic algorithm ended after generation " << currentGeneration << " because it reached the maximum generation count.\n";
		}
	}

}

//For HGAs - if we want to run multiple generations of a lower-level gene pool
//for every one of a higher-level one, this is how
//Basically a loop wrapped around nextGeneration()
void HierarchicalGenePool::runGenerations() {
	int target = currentGeneration + numIterationsPerGeneration;

	for (int i = currentGeneration; i < target && i < maxGenerations && optimumFound == false; i++) {
		nextGeneration();
	}
}

void HierarchicalGenePool::sortPopulation() {
	myModel->sortPopulation(myPopulation, populationFitnesses, populationSize);
{'fraction_non_alphanumeric': 0.13767700744863715, 'fraction_numerical': 0.0021281820414176967, 'mean_word_length': 4.190314358538657, 'pattern_counts': {'":': 2, '<': 91, '<?xml version=': 0, '>': 27, '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': '4871751', 'n_tokens_mistral': 3797, 'n_tokens_neox': 3395, 'n_words': 976}