def fitness(self, net, proc, id_for_printing=-1): total_weights = net.num_edges() total_delays = net.num_edges() total_thresholds = net.num_nodes() dec = [8] * total_weights + [4] * total_delays + [7] * total_thresholds leap_decoder = BinaryToIntDecoder(*dec) problem = NetworkProblem(net, proc, self) genome_len = 8 * total_weights + 4 * total_delays + 7 * total_thresholds parents = Individual.create_population( 10, initialize=create_binary_sequence(genome_len), decoder=leap_decoder, problem=problem) parents = Individual.evaluate_population(parents) max_generation = 10 #stdout_probe = probe.FitnessStatsCSVProbe(context, stream=sys.stdout) generation_counter = util.inc_generation(context=context) while generation_counter.generation() < max_generation: offspring = pipe( parents, ops.tournament_selection, ops.clone, mutate_bitflip, ops.uniform_crossover, ops.evaluate, ops.pool(size=len(parents))) #, # accumulate offspring #stdout_probe) parents = offspring generation_counter() # increment to the next generation best = probe.best_of_gen(parents).decode() set_weights(best, net) return self.get_fitness_score(net, proc, id_for_printing)
def test_pool(): """If a pool of size 3 is used, the first 3 individuals in the input iterator should be collected into a list.""" pop = iter(['a', 'b', 'c', 'd', 'e']) pop = ops.pool(pop, size=3) assert (len(pop) == 3) assert (pop == ['a', 'b', 'c'])
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
from leap_ec.binary_rep.problems import MaxOnes from leap_ec.binary_rep.initializers import create_binary_sequence from leap_ec.binary_rep.ops import mutate_bitflip from leap_ec import util # create initial rand population of 5 individuals parents = Individual.create_population(5, initialize=create_binary_sequence(4), decoder=IdentityDecoder(), problem=MaxOnes()) # Evaluate initial population parents = Individual.evaluate_population(parents) # print initial, random population util.print_population(parents, generation=0) # generation_counter is an optional convenience for generation tracking generation_counter = util.inc_generation(context=context) while generation_counter.generation() < 6: offspring = pipe(parents, ops.tournament_selection, ops.clone, mutate_bitflip(expected_num_mutations=1), ops.uniform_crossover(p_swap=0.2), ops.evaluate, ops.pool(size=len(parents))) # accumulate offspring parents = offspring generation_counter() # increment to the next generation util.print_population(parents, context['leap']['generation'])
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 print_population(parents, generation=0) while generation_counter.generation() < MAX_GENERATIONS: offspring = pipe( parents, ops.random_selection, ops.clone, mutate_gaussian(std=context['leap']['std']), ops.evaluate, ops.pool(size=len(parents) * BROOD_SIZE), # create the brood ops.truncation_selection(size=len(parents), parents=parents)) # mu + lambda parents = offspring generation_counter() # increment to the next generation # Just to demonstrate that we can also get the current generation from # the context print_population(parents, context['leap']['generation'])
# 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) ] )
track_pop_stream = open(args.track_pop_file, 'w') track_pop_func = log_pop(args.update_interval, track_pop_stream) final_pop = asynchronous.steady_state( client, births=args.max_births, init_pop_size=args.init_pop_size, pop_size=args.pop_size, representation=Representation( initialize=create_binary_sequence(args.length), individual_cls=DistributedIndividual), problem=MaxOnes(), offspring_pipeline=[ ops.random_selection, ops.clone, mutate_bitflip(expected_num_mutations=1), ops.pool(size=1) ], evaluated_probe=track_workers_func, pop_probe=track_pop_func) logger.info('Final pop: \n%s', pformat(final_pop)) except Exception as e: logger.critical(str(e)) raise e finally: if client is not None: # Because an exception could have been thrown such that client does # not exist. client.close() if track_workers_func is not None:
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