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)
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
예제 #3
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
예제 #4
0
def get_mutation_prob(mut_id, root_node):
    default_mutation_prob = 0.7
    if mut_id == MutationStrengthEnum.weak.value:
        mutation_strength = 0.2
        return mutation_strength / (node_depth(root_node) + 1)
    elif mut_id == MutationStrengthEnum.mean.value:
        mutation_strength = 1.0
        return mutation_strength / (node_depth(root_node) + 1)
    elif mut_id == MutationStrengthEnum.strong.value:
        mutation_strength = 5.0
        return mutation_strength / (node_depth(root_node) + 1)
    else:
        return default_mutation_prob
예제 #5
0
파일: mutation.py 프로젝트: STATAN/FEDOT
def growth_mutation(chain: Any,
                    requirements,
                    chain_generation_params,
                    max_depth: int,
                    local_growth=True) -> Any:
    """
    This mutation selects a random node in a tree, generates new subtree, and replaces the selected node's subtree.
    :param local_growth: if true then maximal depth of new subtree equals depth of tree located in
    selected random node, if false then previous depth of selected node doesn't affect to new subtree depth,
    maximal depth of new subtree just should satisfy depth constraint in parent tree
    """

    random_layer_in_chain = randint(0, chain.depth - 1)
    node_from_chain = choice(nodes_from_height(chain, 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) \
                                                         < max_depth
    if is_primary_node_selected:
        new_subtree = chain_generation_params.primary_node_func(
            model_type=choice(requirements.primary))
    else:
        if local_growth:
            max_depth = node_depth(node_from_chain)
        else:
            max_depth = max_depth - node_height(chain, node_from_chain)
        new_subtree = random_chain(
            chain_generation_params=chain_generation_params,
            requirements=requirements,
            max_depth=max_depth).root_node
    chain.replace_node_with_parents(node_from_chain, new_subtree)
    return chain
예제 #6
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
예제 #7
0
파일: mutation.py 프로젝트: STATAN/FEDOT
def get_mutation_prob(mut_id, root_node):
    default_mutation_prob = 0.7
    if mut_id in list(MutationStrengthEnum):
        mutation_strength = mut_id.value
        mutation_prob = mutation_strength / (node_depth(root_node) + 1)
    else:
        mutation_prob = default_mutation_prob
    return mutation_prob
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