def spheroid_sample(): """A uniform sample of individuals on the spheroid function.""" DIMENSIONS = 10 N_SAMPLES = 50*DIMENSIONS problem = problems.SpheroidProblem() representation = Representation( initialize=initializers.create_real_vector(bounds=[(-5.12, 5.12)]*DIMENSIONS) ) initial_sample = representation.create_population(N_SAMPLES, problem) Individual.evaluate_population(initial_sample) return problem, representation, initial_sample
def neural_representation(environment, num_hidden_nodes): """Return a neural network representation suitable for learning a controller for this environment.""" num_inputs = int(np.prod(environment.observation_space.shape)) num_actions = environment.action_space.n # Decode genomes into a feed-forward neural network, # but also wrap an argmax around the networks so their # output is a single integer decoder = executable.WrapperDecoder( wrapped_decoder=neural_network.SimpleNeuralNetworkDecoder( shape=(num_inputs, num_hidden_nodes, num_actions)), decorator=executable.ArgmaxExecutable) # Initialized genomes are random real-valued vectors. initialize = create_real_vector(bounds=([[-1, 1]] * decoder.wrapped_decoder.length)) return Representation(decoder, initialize)
def pitt_representation(environment, num_rules): """Return a Pitt-approach rule system representation suitable for learning a controller for this environment.""" num_inputs = int(np.prod(environment.observation_space.shape)) num_outputs = int(np.prod(environment.action_space.shape)) # Decode genomes into Pitt-style rules decoder = rules.PittRulesDecoder( input_space=environment.observation_space, output_space=environment.action_space, priority_metric=rules.PittRulesExecutable.PriorityMetric.RULE_ORDER, num_memory_registers=0) # Initialized genomes are random real-valued vectors. initialize = create_real_vector( # Initialize each element between 0 and 1. bounds=([[0.0, 1.0]] * (num_inputs * 2 + num_outputs)) * num_rules) return Representation(decoder, initialize)
def ea_solve(function, bounds, generations=100, pop_size=2, mutation_std=1.0, maximize=False, viz=False, viz_ylim=(0, 1)): """Provides a simple, top-level interfact that optimizes a real-valued function using a simple generational EA. :param function: the function to optimize; should take lists of real numbers as input and return a float fitness value :param [(float, float)] bounds: a list of (min, max) bounds to define the search space :param int generations: the number of generations to run for :param int pop_size: the population size :param float mutation_std: the width of the mutation distribution :param bool maximize: whether to maximize the function (else minimize) :param bool viz: whether to display a live best-of-generation plot :param (float, float) viz_ylim: initial bounds to use of the plots vertical axis >>> from leap_ec import simple >>> ea_solve(sum, bounds=[(0, 1)]*5) # doctest:+ELLIPSIS generation, bsf 0, ... 1, ... ... 100, ... [..., ..., ..., ..., ...] """ pipeline = [ ops.tournament_selection, ops.clone, mutate_gaussian(std=mutation_std), ops.uniform_crossover(p_swap=0.4), ops.evaluate, ops.pool(size=pop_size) ] if viz: plot_probe = probe.PopulationPlotProbe( context, ylim=viz_ylim, ax=plt.gca()) pipeline.append(plot_probe) ea = generational_ea(generations=generations, pop_size=pop_size, problem=FunctionProblem(function, maximize), representation=Representation( individual_cls=Individual, decoder=IdentityDecoder(), initialize=create_real_vector(bounds=bounds) ), pipeline=pipeline) best_genome = None print('generation, bsf') for g, ind in ea: print(f"{g}, {ind.fitness}") best_genome = ind.genome return best_genome
# this was in the context of the 1/5 success rule, which we've not # implemented here. # Handbook of EC, B1.3:2 context['leap']['std'] *= .85 if __name__ == '__main__': # Define the real value bounds for initializing the population. In this case, # we define a genome of four bounds. # the (-5.12,5.12) was what was originally used for this problem in # Ken De Jong's 1975 dissertation, so was used for historical reasons. bounds = [(-5.12, 5.12), (-5.12, 5.12), (-5.12, 5.12), (-5.12, 5.12)] parents = Individual.create_population( 5, initialize=create_real_vector(bounds), decoder=IdentityDecoder(), problem=SpheroidProblem(maximize=False)) # Evaluate initial population parents = Individual.evaluate_population(parents) context['leap']['std'] = 2 # We use the provided context, but we could roll our own if we # wanted to keep separate contexts. E.g., island models may want to have # their own contexts. generation_counter = util.inc_generation(context=context, callbacks=(anneal_std, )) # print initial, random population
def get_island(context): """Closure that returns a callback for retrieving the current island ID during logging.""" return lambda _: context['leap']['current_subpopulation'] pop_size = 10 ea = multi_population_ea(generations=1000, num_populations=topology.number_of_nodes(), pop_size=pop_size, problem=problems, # Fitness function # Representation representation=Representation( individual_cls=Individual, initialize=create_real_vector( bounds=[bounds] * l), decoder=IdentityDecoder() ), # Operator pipeline shared_pipeline=[ ops.tournament_selection, ops.clone, mutate_gaussian( std=0.03, hard_bounds=bounds), ops.evaluate, ops.pool(size=pop_size), ops.migrate(context, topology=topology, emigrant_selector=ops.tournament_selection, replacement_selector=ops.random_selection,
"""Closure that returns a callback for retrieving the current island ID during logging.""" return lambda _: context['leap']['current_subpopulation'] l = 2 pop_size = 10 ea = multi_population_ea( generations=1000, num_populations=topology.number_of_nodes(), pop_size=pop_size, problem=problem, # Fitness function # Representation representation=Representation( individual_cls=Individual, initialize=create_real_vector(bounds=[problem.bounds] * l), decoder=IdentityDecoder()), # Operator pipeline shared_pipeline=[ ops.tournament_selection, ops.clone, mutate_gaussian(std=30, hard_bounds=problem.bounds), ops.evaluate, ops.pool(size=pop_size), ops.migrate(context, topology=topology, emigrant_selector=ops.tournament_selection, replacement_selector=ops.random_selection, migration_gap=50), probe.FitnessStatsCSVProbe( context, stream=sys.stdout,
shape=(num_inputs, num_hidden_nodes, num_actions)), decorator=executable.ArgmaxExecutable) with open('./genomes.csv', 'w') as genomes_file: ea = generational_ea( max_generations=generations, pop_size=pop_size, # Solve a problem that executes agents in the # environment and obtains fitness from it problem=problems.EnvironmentProblem(runs_per_fitness_eval, simulation_steps, environment, 'reward', gui=gui), representation=Representation(initialize=create_real_vector( bounds=([[-1, 1]] * decoder.wrapped_decoder.length)), decoder=decoder), # The operator pipeline. pipeline=[ ops.tournament_selection, ops.clone, mutate_gaussian(std=mutate_std, hard_bounds=(-1, 1), expected_num_mutations=1), ops.evaluate, ops.pool(size=pop_size), *build_probes( genomes_file) # Inserting all the probes at the end ]) list(ea)
viz_probes = [pop_probe, fit_probe] ############################## # The Evolutionarly Algorithm ############################## ea = generational_ea(max_generations=generations, pop_size=pop_size, problem=problem, # Fitness function # By default, the initial population would be evaluated one-at-a-time. # Passing group_evaluate into init_evaluate evaluates the population in batches. init_evaluate=ops.grouped_evaluate(problem=problem, max_individuals_per_chunk=max_individuals_per_chunk), # Representation representation=Representation( # Initialize a population of integer-vector genomes initialize=create_real_vector( bounds=[problem.bounds] * num_genes) ), # Operator pipeline pipeline=[ ops.tournament_selection(k=2), ops.clone, # Copying individuals before we change them, just to be safe mutate_gaussian(std=0.2, hard_bounds=[problem.bounds]*num_genes, expected_num_mutations=1), ops.pool(size=pop_size), # Here again, we use grouped_evaluate to send chunks of individuals to the ExternalProcessProblem. ops.grouped_evaluate(problem=problem, max_individuals_per_chunk=max_individuals_per_chunk), # Print fitness statistics to stdout at each genration probe.FitnessStatsCSVProbe(stream=sys.stdout) ] + (viz_probes if plots else []) )