def mutate(self, nb_intermediate_neuron:int, nb_total_neuron:int, neuron_types:iter, edges:iter): """Return the data received in input, modified according to mutation settings. nb_intermediate_neuron: integer equal to number of intermediate neuron. nb_total_neuron: integer equal to total number of neuron. neuron_types: iterable of NeuronType. edges: iterable of 2-tuple describing links between neurons. """ MUTATION_RATE = self.mutation_rate mutation = lambda: random() <= MUTATION_RATE mutate_nb_neuron = mutation(), mutation() mutate_neuron_type = mutation(), mutation() mutate_edges = mutation(), mutation() del mutation if any(mutate_nb_neuron): add, rmv = mutate_nb_neuron neuron_types = list(neuron_types) # allow modifications if add: nb_total_neuron += 1 nb_intermediate_neuron += 1 neuron_types.append(random_choice(NeuronType.xano())) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' add new neuron of type ' + neuron_types[-1].name + '.') if rmv and nb_intermediate_neuron > 0: nb_total_neuron -= 1 nb_intermediate_neuron -= 1 target_idx = randrange(0, len(neuron_types)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' remove neuron ' + str(target_idx) + ' (' + neuron_types[target_idx].name + ').') del neuron_types[target_idx] if any(mutate_neuron_type): modify, swap = mutate_neuron_type neuron_types = list(neuron_types) # allow modifications if modify: # modify just one type target_idx = randrange(0, len(neuron_types)) new_type = random_choice(NeuronType.xano()) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' modify type of ' + str(target_idx) + ' from ' + neuron_types[target_idx].name + ' to ' + new_type.name + '.' ) neuron_types[target_idx] = new_type if swap: # swap two types in the list target1_idx = randrange(0, len(neuron_types)) target2_idx = randrange(0, len(neuron_types)) neuron_types[target1_idx], neuron_types[target2_idx] = ( neuron_types[target2_idx], neuron_types[target1_idx] ) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' swaps ' + str(target1_idx) + ' (' + neuron_types[target2_idx].name + ') and ' + str(target1_idx) + ' (' + neuron_types[target2_idx].name + ').' ) if any(mutate_edges): add, rmv = mutate_edges edges = list(edges) # allow modifications if add: # add one new edge target1_idx = randrange(1, nb_total_neuron + 1) target2_idx = randrange(1, nb_total_neuron + 1) edges.append((target1_idx, target2_idx)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' get an edge ' + str((target1_idx, target2_idx)) + '.') if rmv: # remove one existing edge idx = randrange(0, len(edges)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' lose its edge ' + str(edges[idx]) + '.') neuron_types = tuple(neuron_types) edges = tuple(edges) return nb_intermediate_neuron, neuron_types, edges
except (KeyboardInterrupt, EOFError): LOGGER.info('Treatment loop finished through keyboard interruption.') e.world.deinit() LOGGER.info('Deinitialization of World') def run_individual(config): """Run an individual simulation""" from neural_world.incubator import Incubator individual = Incubator(config).spawn() print(individual.network_dict) print('\n'.join(individual.prettyfied_neural_network)) if __name__ == '__main__': # CLI arguments handling args = docopt.docopt(__doc__, version=VERSION) commons.log_level(level=args['--log-level']) render_png = bool(int(args['--render-png'])) # Configuration config = Configuration() assert config.is_valid() # Run if args['simulation']: run_simulation(config, render_png) elif args['individual']: run_individual(config)