diff --git a/evolutionary_algorithm/README.md b/evolutionary_algorithm/README.md new file mode 100644 index 0000000..3ce82ef --- /dev/null +++ b/evolutionary_algorithm/README.md @@ -0,0 +1,28 @@ +# Evolutionary Algorithm Simulator + +## run the program: + +``` +usage: main.py [-h] [--offspringSize OFFSPRINGSIZE] [--P P] [--L L] [--f F] + [--epsilon EPSILON] [--cycles CYCLES] + +evolutionary algorithm simulation + +optional arguments: + -h, --help show this help message and exit + --offspringSize OFFSPRINGSIZE + size for new offspring + --P P start population size + --L L genome length + --f F fitness function in python syntax. x[0] - x[L] are the arguments + --epsilon EPSILON epsilon for random mutation + --cycles CYCLES cycles to calculate + +``` + +arguments can also be adjusted by the user at runtime. Example for a 2 dimensional fitness function: + +``` +./main.py --f "-abs(x[0] - 6) - abs(x[1] +5)" --L 2 --cycles 1000 +``` + diff --git a/evolutionary_algorithm/ea.py b/evolutionary_algorithm/ea.py index fff0d5c..938d2f6 100644 --- a/evolutionary_algorithm/ea.py +++ b/evolutionary_algorithm/ea.py @@ -55,7 +55,7 @@ class EvolutionaryPopulation(object): externalSelectionFunction=lambda fitness: list(range(len(fitness))), # keep whole population parentSelectionFunction=lambda population, fitness: list(range(len(population))) # all individuals are parents ): - self.L = 3 + self.L = L self.fitnessFunction = fitnessFunction self.inheritanceFunction = inheritanceFunction self.mutationFunction = mutationFunction @@ -97,6 +97,7 @@ class EvolutionaryPopulation(object): newIndividual = Individual(self.fitnessFunction, self.mutationFunction, self.inheritanceFunction, parents) newIndividual.mutate() self.population.append(newIndividual) + # update fitness: self.fitness.append(newIndividual.evaluateFitness()) def printPopulation(self): diff --git a/evolutionary_algorithm/main.py b/evolutionary_algorithm/main.py index b0a9cc9..b2be942 100755 --- a/evolutionary_algorithm/main.py +++ b/evolutionary_algorithm/main.py @@ -51,13 +51,22 @@ def parsingArguments(): # easy adjustable functions for the ea-cycle. Will be packed in lambda objects in main() def inheritance(parents): + ''' + + :param parents: list of Individuals. Their genome can be accessed by parents[i].genome + :return: genome for new offspring individual + ''' # just copy genome from first parent: return parents[0].genome def mutation(genome, e): + ''' - + :param genome: list of length L of real values: the genome to mutate + :param e: epsilon value (for random range) + :return: the mutated genome + ''' # mutate new genome by equally distributed random value in range [-e:e] newGenome = [] @@ -68,12 +77,21 @@ def mutation(genome, e): return newGenome def externalSelection(fitness): + ''' + :param fitness: list with fitness values + :return: list of indices of surviving individuals + ''' # only keep the fittest return [np.argmax(fitness)] def parentSelection(population, fitness): - + ''' + parent selection method for one individual + :param population: list of individuals which survived external selection + :param fitness: list of fitness values for given population + :return: list of parents for one new offspring individual + ''' # only first (and only individual so far) is parent return [0]