[1113] | 1 | import argparse |
---|
| 2 | import os |
---|
| 3 | import sys |
---|
| 4 | import numpy as np |
---|
| 5 | |
---|
| 6 | #TODO add new example: steadystate.py (analogous to standard.py) |
---|
| 7 | #TODO extend both standard.py and steadystate.py to support >1 criteria (using DEAP's selNSGA2() and selSPEA2()) |
---|
| 8 | #TODO add comments to all examples in this directory |
---|
| 9 | #TODO add to standard.py and steadystate.py evaluating each genotype in HOF N (configurable, default 10) times when the evolution ends |
---|
| 10 | #TODO protect all examples against invalid genotypes (fill population until all genotypes are conrrectly evaluated). And maybe remove invalid.py if it overlaps with (is a subset of) other examples |
---|
| 11 | |
---|
| 12 | from FramsticksLib import FramsticksLib |
---|
| 13 | from evolalg.base.lambda_step import LambdaStep |
---|
| 14 | from evolalg.dissimilarity.frams_dissimilarity import FramsDissimilarity |
---|
| 15 | from evolalg.experiment import Experiment |
---|
| 16 | from evolalg.fitness.fitness_step import FitnessStep |
---|
| 17 | from evolalg.mutation_cross.frams_cross_and_mutate import FramsCrossAndMutate |
---|
| 18 | from evolalg.population.frams_population import FramsPopulation |
---|
| 19 | from evolalg.selection.tournament import TournamentSelection |
---|
| 20 | from evolalg.statistics.halloffame_stats import HallOfFameStatistics |
---|
| 21 | from evolalg.statistics.statistics_deap import StatisticsDeap |
---|
| 22 | from evolalg.base.union_step import UnionStep |
---|
| 23 | |
---|
| 24 | |
---|
| 25 | def ensureDir(string): |
---|
| 26 | if os.path.isdir(string): |
---|
| 27 | return string |
---|
| 28 | else: |
---|
| 29 | raise NotADirectoryError(string) |
---|
| 30 | |
---|
| 31 | |
---|
| 32 | def parseArguments(): |
---|
| 33 | parser = argparse.ArgumentParser( |
---|
| 34 | description='Run this program with "python -u %s" if you want to disable buffering of its output.' % sys.argv[ |
---|
| 35 | 0]) |
---|
| 36 | parser.add_argument('-path', type=ensureDir, required=True, help='Path to Framsticks without trailing slash.') |
---|
| 37 | parser.add_argument('-opt', required=True, |
---|
| 38 | help='optimization criteria : vertpos, velocity, distance, vertvel, lifespan, numjoints, numparts, numneurons, numconnections. Single or multiple criteria.') |
---|
| 39 | parser.add_argument('-lib', required=False, help="Filename of .so or .dll with framsticks library") |
---|
| 40 | parser.add_argument('-genformat', required=False, default="1", |
---|
| 41 | help='Genetic format for the demo run, for example 4, 9, or B. If not given, f1 is assumed.') |
---|
| 42 | |
---|
| 43 | parser.add_argument("-popsize", type=int, default=50, help="Size of population, default 50.") |
---|
| 44 | return parser.parse_args() |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | def extract_fitness(ind): |
---|
| 48 | return ind.fitness |
---|
| 49 | |
---|
| 50 | |
---|
| 51 | def print_population_count(pop): |
---|
| 52 | print("Current:", len(pop)) |
---|
| 53 | return pop # Each step must return a population |
---|
| 54 | |
---|
| 55 | |
---|
| 56 | def main(): |
---|
| 57 | parsed_args = parseArguments() |
---|
| 58 | frams = FramsticksLib(parsed_args.path, parsed_args.lib, |
---|
| 59 | "eval-allcriteria.sim") |
---|
| 60 | |
---|
| 61 | hall_of_fame = HallOfFameStatistics(100, "fitness") |
---|
| 62 | statistics_union = UnionStep([ |
---|
| 63 | hall_of_fame, |
---|
| 64 | StatisticsDeap([ |
---|
| 65 | ("avg", np.mean), |
---|
| 66 | ("stddev", np.std), |
---|
| 67 | ("min", np.min), |
---|
| 68 | ("max", np.max), |
---|
| 69 | ("count", len) |
---|
| 70 | ], extract_fitness) |
---|
| 71 | ]) |
---|
| 72 | |
---|
| 73 | fitness = FitnessStep(frams, fields={parsed_args.opt: "fitness", }, fields_defaults={}) |
---|
| 74 | |
---|
| 75 | init_stages = [FramsPopulation(frams, parsed_args.genformat, 50), |
---|
| 76 | fitness, |
---|
| 77 | statistics_union] |
---|
| 78 | |
---|
| 79 | selection = TournamentSelection(5, copy=True, fit_attr="fitness") |
---|
| 80 | |
---|
| 81 | new_generation_steps = [ |
---|
| 82 | FramsCrossAndMutate(frams, cross_prob=0.2, mutate_prob=0.9), |
---|
| 83 | fitness, |
---|
| 84 | ] |
---|
| 85 | |
---|
| 86 | generation_modifications = [ |
---|
| 87 | statistics_union |
---|
| 88 | ] |
---|
| 89 | |
---|
| 90 | experiment = Experiment(init_population=init_stages, |
---|
| 91 | selection=selection, |
---|
| 92 | new_generation_steps=new_generation_steps, |
---|
| 93 | generation_modification=generation_modifications, |
---|
| 94 | end_steps=[], |
---|
| 95 | population_size=parsed_args.popsize |
---|
| 96 | ) |
---|
| 97 | experiment.init() |
---|
| 98 | experiment.run(3) |
---|
| 99 | for ind in hall_of_fame.haloffame: |
---|
| 100 | print("%g\t%s" % (ind.fitness, ind.genotype)) |
---|
| 101 | |
---|
| 102 | |
---|
| 103 | if __name__ == '__main__': |
---|
| 104 | main() |
---|