예제 #1
0
def onepoint_crossover(chain_first: Any, chain_second: Any,
                       requirements) -> Any:
    max_depth = requirements.max_depth
    pairs_of_nodes = equivalent_subtree(chain_first, chain_second)
    if pairs_of_nodes:
        node_from_chain_first, node_from_chain_second = choice(pairs_of_nodes)
        summary_depth = node_depth(chain_first.root_node) - node_depth(
            node_from_chain_first) + node_depth(node_from_chain_second)
        if summary_depth <= max_depth and summary_depth != 0:
            chain_first.replace_node_with_parents(node_from_chain_first,
                                                  node_from_chain_second)
    return chain_first
예제 #2
0
def get_mutation_prob(mut_id, root_node):
    default_mutation_prob = 0.7
    if mut_id == MutationPowerEnum.weak.value:
        mutation_strength = 0.2
        return mutation_strength / (node_depth(root_node) + 1)
    elif mut_id == MutationPowerEnum.mean.value:
        mutation_strength = 1.0
        return mutation_strength / (node_depth(root_node) + 1)
    elif mut_id == MutationPowerEnum.strong.value:
        mutation_strength = 5.0
        return mutation_strength / (node_depth(root_node) + 1)
    else:
        return default_mutation_prob
예제 #3
0
def growth_mutation(chain: Any,
                    parameters: MutationParams,
                    local_growth=True) -> Any:
    random_layer_in_chain = randint(0, chain.depth - 1)
    node_from_chain = choice(
        nodes_from_height(chain.root_node, random_layer_in_chain))
    if local_growth:
        is_primary_node_selected = (not node_from_chain.nodes_from) or (
            node_from_chain.nodes_from and node_from_chain != chain.root_node
            and randint(0, 1))
    else:
        is_primary_node_selected = randint(0, 1) and not node_height(chain, node_from_chain) \
                                                         < parameters.requirements.max_depth

    if is_primary_node_selected:
        new_subtree = parameters.primary_node_func(
            model_type=choice(parameters.requirements.primary))
    else:
        if local_growth:
            max_depth = node_depth(node_from_chain)
        else:

            max_depth = parameters.requirements.max_depth - node_height(
                chain, node_from_chain)
        new_subtree = random_ml_chain(parameters.chain_class,
                                      parameters.secondary_node_func,
                                      parameters.primary_node_func,
                                      parameters.requirements,
                                      max_depth=max_depth).root_node
    chain.replace_node_with_parents(node_from_chain, new_subtree)
    return chain
예제 #4
0
def subtree_crossover(chain_first: Any, chain_second: Any,
                      requirements) -> Any:
    max_depth = requirements.max_depth
    random_layer_in_chain_first = randint(0, chain_first.depth - 1)
    random_layer_in_chain_second = randint(0, chain_second.depth - 1)
    if chain_first.depth - 1 != 0 and chain_second.depth - 1 != 0:
        if random_layer_in_chain_first == 0 and random_layer_in_chain_second == 0:
            if randint(0, 1):
                random_layer_in_chain_first = randint(1, chain_first.depth - 1)
            else:
                random_layer_in_chain_second = randint(1,
                                                       chain_second.depth - 1)

    node_from_chain_first = choice(
        nodes_from_height(chain_first.root_node, random_layer_in_chain_first))
    node_from_chain_second = choice(
        nodes_from_height(chain_second.root_node,
                          random_layer_in_chain_second))

    summary_depth = random_layer_in_chain_first + node_depth(
        node_from_chain_second)
    if summary_depth <= max_depth and summary_depth != 0:
        chain_first.replace_node_with_parents(node_from_chain_first,
                                              node_from_chain_second)

    return chain_first
예제 #5
0
def one_point_crossover(chain_first: Any, chain_second: Any,
                        max_depth: int) -> Any:
    """Finds common structural parts between two trees, and after that randomly
    chooses the location of nodes, subtrees of which will be swapped"""
    pairs_of_nodes = equivalent_subtree(chain_first, chain_second)
    if pairs_of_nodes:
        node_from_chain_first, node_from_chain_second = choice(pairs_of_nodes)

        layer_in_chain_first = node_depth(
            chain_first.root_node) - node_depth(node_from_chain_first)
        layer_in_chain_second = node_depth(
            chain_second.root_node) - node_depth(node_from_chain_second)

        replace_subtrees(chain_first, chain_second, node_from_chain_first,
                         node_from_chain_second, layer_in_chain_first,
                         layer_in_chain_second, max_depth)
    return chain_first, chain_second
예제 #6
0
def nn_growth_mutation(chain: Any,
                       parameters: MutationParams,
                       local_growth=True) -> Any:
    ComposerVisualiser.visualise(chain)
    primary_nodes = parameters.requirements.primary
    secondary_nodes = parameters.requirements.secondary
    random_layer_in_chain = randint(0, node_depth(chain.root_node))
    print(random_layer_in_chain)
    print(node_depth(chain.root_node) + 1)
    node_from_chain = choice(
        nodes_from_height(chain.root_node, random_layer_in_chain))
    if local_growth:
        is_primary_node_selected = (not node_from_chain.nodes_from) or (
            node_from_chain.nodes_from and node_from_chain != chain.root_node
            and randint(0, 1))
    else:
        is_primary_node_selected = randint(0, 1) and not node_height(chain, node_from_chain) \
                                                         < parameters.requirements.max_depth
    if is_primary_node_selected:
        new_node_type = choice(primary_nodes)
        new_layer_params = get_random_layer_params(new_node_type,
                                                   parameters.requirements)
        new_subtree = parameters.primary_node_func(
            layer_params=new_layer_params)
        chain.replace_node_with_parents(node_from_chain, new_subtree)
    else:
        if local_growth:
            max_depth = node_depth(node_from_chain)
        else:
            max_depth = parameters.requirements.max_depth - random_layer_in_chain
        new_node_type = choice(secondary_nodes)
        new_layer_params = get_random_layer_params(new_node_type,
                                                   parameters.requirements)
        new_subtree = parameters.secondary_node_func(
            layer_params=new_layer_params)
        offspring_size = randint(parameters.requirements.min_arity,
                                 parameters.requirements.max_arity)
        for _ in range(offspring_size):
            random_nn_branch(
                secondary_node_func=parameters.secondary_node_func,
                primary_node_func=parameters.primary_node_func,
                requirements=parameters.requirements,
                max_depth=max_depth,
                start_height=(node_height(chain, node_from_chain)),
                node_parent=new_subtree)
        chain.replace_node_with_parents(node_from_chain, new_subtree)
예제 #7
0
def growth_mutation(chain: Any, chain_class, secondary_node_func: Callable,
                    primary_node_func: Callable, requirements) -> Any:
    chain_copy = deepcopy(chain)
    random_layer_in_chain = randint(0, chain_copy.depth - 1)
    node_from_chain = choice(
        nodes_from_height(chain_copy, random_layer_in_chain))
    is_primary_node_selected = (not node_from_chain.nodes_from) or (
        node_from_chain.nodes_from and node_from_chain != chain_copy.root_node
        and randint(0, 1))
    if is_primary_node_selected:
        new_subtree = primary_node_func(
            model_type=choice(requirements.primary))
    else:
        max_depth = node_depth(node_from_chain)
        new_subtree = random_chain(chain_class,
                                   secondary_node_func,
                                   primary_node_func,
                                   requirements,
                                   max_depth=max_depth).root_node
    chain_copy.replace_node_with_parents(node_from_chain, new_subtree)
    return chain_copy