def _calculate_possible_inputs_when_adding_connection( genome: Genome, out_node_key: int, config: BaseConfiguration): # all nodes possible_input_keys_set = set(genome.node_genes.keys()).union( set(genome.get_input_nodes_keys())) # no connection between two output nodes possible_input_keys_set -= set(genome.get_output_nodes_keys()) if config.feed_forward: # avoid self-recurrency possible_input_keys_set -= {out_node_key} # pass # REMOVE POSSIBLE CONNECTIONS possible_connection_set = set( itertools.product(list(possible_input_keys_set), [out_node_key])) # remove already existing connections: don't duplicate connections possible_connection_set -= set(genome.connection_genes.keys()) # remove possible connections that introduce cycles possible_connection_set = \ ArchitectureMutation._remove_connection_that_introduces_cycles(genome=genome, possible_connection_set=possible_connection_set) # # remove possible connections that introduce multihop jumps # possible_connection_set = \ # Mutation._remove_connection_that_introduces_multihop_jumps(genome=genome, # possible_connection_set=possible_connection_set) if len(possible_connection_set) == 0: return [] possible_input_keys_set = list(zip(*list(possible_connection_set)))[0] return possible_input_keys_set
def plot_genome_network(genome: Genome, filename='./network.png', view=True): return plot_network(nodes=list(genome.node_genes.keys()), edges=list(genome.connection_genes.keys()), input_nodes=genome.get_input_nodes_keys(), output_nodes=genome.get_output_nodes_keys(), filename=filename, view=view)
def _remove_connection_that_introduces_multihop_jumps( genome: Genome, possible_connection_set: set) -> set: output_node_keys = genome.get_output_nodes_keys() input_node_keys = genome.get_input_nodes_keys() connections_to_remove = [] for connection in possible_connection_set: connections = list(genome.connection_genes.keys()) + [connection] if adds_multihop_jump(connections=connections, output_node_keys=output_node_keys, input_node_keys=input_node_keys): connections_to_remove.append(connection) possible_connection_set -= set(connections_to_remove) return possible_connection_set
def transform_genome_to_layers(genome: Genome) -> dict: layers = dict() nodes = genome.node_genes connections = genome.connection_genes nodes_per_layer = calculate_nodes_per_layer( links=list(connections.keys()), input_node_keys=genome.get_input_nodes_keys(), output_node_keys=genome.get_output_nodes_keys()) layer_indices = list(nodes_per_layer.keys()) layer_indices.sort() for layer_index in layer_indices[:-1]: original_nodes_in_layer = nodes_per_layer[layer_index] layer = LayerBuilder(nodes=nodes, connections=connections, layer_node_keys=original_nodes_in_layer, nodes_per_layer=nodes_per_layer, layer_counter=layer_index) \ .create() \ .get_layer() layers[layer_index] = layer # enrich layers for layer_counter, layer in layers.items(): # logger.debug(f'Layer: {layer_counter}') # add needed indices for node_key in layer.external_input_keys: index = None for layer_2 in layers.values(): if node_key in layer_2.original_input_keys: index = (layer_2.key, layer_2.input_keys.index(node_key)) break assert index is not None layer.indices_of_needed_nodes.append(index) layer.needed_nodes[node_key] = index # add indices to cache for node_key in layer.original_input_keys: for layer_2 in layers.values(): if node_key in layer_2.external_input_keys: index = layer.input_keys.index(node_key) # add if not in list if index not in layer.indices_of_nodes_to_cache: layer.indices_of_nodes_to_cache.append(index) if len(layer.indices_of_needed_nodes) > 1: needed_node_keys = list(layer.needed_nodes.keys()) needed_node_keys.sort() sorted_indices_of_needed_nodes = [] for node_key in needed_node_keys: sorted_indices_of_needed_nodes.append( layer.needed_nodes[node_key]) assert len(sorted_indices_of_needed_nodes) == len( layer.indices_of_needed_nodes) layer.indices_of_needed_nodes = sorted_indices_of_needed_nodes logger.debug(f'Indices to cache: {layer.indices_of_nodes_to_cache}') logger.debug( f'Indices needed from cache: {layer.indices_of_needed_nodes}') return layers