def do_cgp(gens): pop_size = 5 ea = generational_ea( gens, pop_size, representation=cgp_representation, # Our fitness function will be to solve the XOR problem problem=xor_problem, pipeline=[ ops.tournament_selection, ops.clone, cgp.cgp_mutate(cgp_decoder, expected_num_mutations=1), ops.evaluate, ops.pool(size=pop_size), probe.FitnessStatsCSVProbe(stream=sys.stdout) ] + cgp_visual_probes(modulo=10)) list(ea)
def evolve(runs, steps, env, rep, gens, pop_size, num_nodes, mutate_std, output, gui): """Evolve a controller using a Pitt-style rule system.""" check_rep(rep) print(f"Loading environment '{env}'...") environment = gym.make(env) print(f"\tObservation space:\t{environment.observation_space}") print(f"\tAction space: \t{environment.action_space}") with open(output, 'w') as genomes_file: if rep == 'pitt': representation = pitt_representation(environment, num_rules=num_nodes) elif rep == 'neural': representation = neural_representation(environment, num_hidden_nodes=num_nodes) probes = get_probes(genomes_file, environment, rep) with Client() as dask_client: ea = generational_ea( generations=gens, pop_size=pop_size, # Solve a problem that executes agents in the # environment and obtains fitness from it problem=problems.EnvironmentProblem(runs, steps, environment, 'reward', gui), representation=representation, # The operator pipeline. pipeline=[ ops.tournament_selection, ops.clone, mutate_gaussian(std=mutate_std, hard_bounds=(-1, 1)), ops.evaluate, ops.pool(size=pop_size), #synchronous.eval_pool(client=dask_client, size=pop_size), *probes # Inserting all the probes at the end ]) list(ea)
def cgp_cmd(gens): """Use an evolutionary CGP approach to solve the XOR function.""" pop_size = 5 ea = generational_ea(gens, pop_size, representation=cgp_representation, # Our fitness function will be to solve the XOR problem problem=xor_problem, pipeline=[ ops.tournament_selection, ops.clone, cgp.cgp_mutate(cgp_decoder), ops.evaluate, ops.pool(size=pop_size), probe.FitnessStatsCSVProbe(context.context, stream=sys.stdout) ] + cgp_visual_probes(modulo=10) ) list(ea)
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
ea = generational_ea(max_generations=generations,pop_size=pop_size, problem=problem, # Fitness function # Stopping condition: we stop when fitness or diversity drops below a threshold stop=lambda pop: (max(pop).fitness < fitness_threshold) or (probe.pairwise_squared_distance_metric(pop) < diversity_threshold), # Representation representation=Representation( # Initialize a population of integer-vector genomes initialize=create_real_vector( bounds=[problem.bounds] * l) ), # Operator pipeline pipeline=[ ops.tournament_selection(k=2), ops.clone, # Apply binomial mutation: this is a lot like # additive Gaussian mutation, but adds an integer # value to each gene mutate_gaussian(std=0.2, hard_bounds=[problem.bounds]*l, expected_num_mutations=1), ops.evaluate, ops.pool(size=pop_size), # Some visualization probes so we can watch what happens probe.CartesianPhenotypePlotProbe( xlim=problem.bounds, ylim=problem.bounds, contours=problem), probe.FitnessPlotProbe(), probe.PopulationMetricsPlotProbe( metrics=[ probe.pairwise_squared_distance_metric ], title='Population Diversity'), probe.FitnessStatsCSVProbe(stream=sys.stdout) ] )
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=decoder.initializer(num_rules), decoder=decoder), # The operator pipeline. pipeline=[ ops.tournament_selection, ops.clone, decoder.mutator(condition_mutator=genome_mutate_gaussian( std=mutate_std, hard_bounds=decoder.condition_bounds, expected_num_mutations=1 / num_rules), action_mutator=individual_mutate_randint( bounds=decoder.action_bounds, probability=1.0)), ops.evaluate, ops.pool(size=pop_size), *build_probes(genomes_file, decoder) # Inserting all the probes at the end ]) list(ea)
def ea_solve(function, bounds, generations=100, pop_size=cpu_count(), mutation_std=1.0, maximize=False, viz=False, viz_ylim=(0, 1), hard_bounds=True, dask_client=None): """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 bool hard_bounds: if True, bounds are enforced at all times during evolution; otherwise they are only used to initialize the population. :param (float, float) viz_ylim: initial bounds to use of the plots vertical axis :param dask_client: is optional dask Client for enable parallel evaluations The basic call includes instrumentation that prints the best-so-far fitness value of each generation to stdout: >>> from leap_ec.simple import ea_solve >>> ea_solve(sum, bounds=[(0, 1)]*5) # doctest:+ELLIPSIS generation, bsf 0, ... 1, ... ... 100, ... array([..., ..., ..., ..., ...]) When `viz=True`, a live BSF plot will also display: >>> ea_solve(sum, bounds=[(0, 1)]*5, viz=True) # doctest:+ELLIPSIS generation, bsf 0, ... 1, ... ... 100, ... array([..., ..., ..., ..., ...]) .. plot:: from leap_ec.simple import ea_solve ea_solve(sum, bounds=[(0, 1)]*5, viz=True) """ if hard_bounds: mutation_op = mutate_gaussian(std=mutation_std, hard_bounds=bounds, expected_num_mutations='isotropic') else: mutation_op = mutate_gaussian(std=mutation_std, expected_num_mutations='isotropic') pipeline = [ ops.tournament_selection, ops.clone, mutation_op, ops.uniform_crossover(p_swap=0.2), ] # If a dask client is given, then use the synchronous (map/reduce) parallel # evaluation of individuals; else, revert to serial evaluations. if dask_client: pipeline.append( synchronous.eval_pool(client=dask_client, size=pop_size)) else: pipeline.extend([ops.evaluate, ops.pool(size=pop_size)]) if viz: plot_probe = probe.FitnessPlotProbe(ylim=viz_ylim, ax=plt.gca()) pipeline.append(plot_probe) ea = generational_ea(max_generations=generations, pop_size=pop_size, problem=FunctionProblem(function, maximize), representation=Representation( individual_cls=DistributedIndividual, 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
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)
ea = generational_ea(max_generations=generations,pop_size=pop_size, problem=problem, # Fitness function # Representation representation=Representation( # Initialize a population of integer-vector genomes initialize=create_real_vector( bounds=[problem.bounds] * l) ), # Operator pipeline pipeline=[ ops.tournament_selection(k=2), ops.clone, # Apply Gaussian mutation mutate_gaussian(std=1.5, hard_bounds=[problem.bounds]*l, expected_num_mutations=1), ops.evaluate, ops.pool(size=pop_size), # Some visualization probes so we can watch what happens probe.CartesianPhenotypePlotProbe( xlim=problem.bounds, ylim=problem.bounds, contours=problem), probe.FitnessPlotProbe(), # Collect diversity metrics along with the standard CSV columns probe.FitnessStatsCSVProbe(stream=sys.stdout, extra_metrics={ 'diversity_pairwise_dist': probe.pairwise_squared_distance_metric, 'diversity_sum_variance': probe.sum_of_variances_metric, 'diversity_num_fixated': probe.num_fixated_metric }) ] )
from leap_ec.binary_rep.ops import mutate_bitflip pop_size = 5 ea = generational_ea( generations=10, pop_size=pop_size, # Solve a MaxOnes Boolean optimization problem problem=problems.MaxOnes(), representation=representation.Representation( # Genotype and phenotype are the same for this task decoder=decoder.IdentityDecoder(), # Initial genomes are random binary sequences initialize=initializers.create_binary_sequence(length=10)), # The operator pipeline pipeline=[ ops.tournament_selection, # Select parents via tournament_selection selection ops.clone, # Copy them (just to be safe) # Basic mutation: defaults to a 1/L mutation rate mutate_bitflip, # Crossover with a 40% chance of swapping each gene ops.uniform_crossover(p_swap=0.4), ops.evaluate, # Evaluate fitness # Collect offspring into a new population ops.pool(size=pop_size) ]) print('Generation, Best_Individual') for i, best in ea:
# 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 []) ) best_inds = list(ea)