Exemplo n.º 1
0
def SpeciationEvent_effi(u, x, S_cost, subtreeLoss, k, H, nodes_table):
    heap = []
    if tree_operations.has_right_child(u) and tree_operations.has_left_child(
            u):
        w = u.adjacent_nodes()[0]
        v = u.adjacent_nodes()[1]
        if not tree_operations.is_a_leaf(x):
            if (tree_operations.has_left_child(x)) and (
                    tree_operations.has_right_child(x)):
                y = x.adjacent_nodes()[0]
                z = x.adjacent_nodes()[1]
                list_v_to_left = utiles.kmin_positive(
                    subtreeLoss[v.label][y.label], k, H, nodes_table,
                    'cost_with_losses')
                list_w_to_left = utiles.kmin_positive(
                    subtreeLoss[w.label][y.label], k, H, nodes_table,
                    'cost_with_losses')
                list_v_to_right = utiles.kmin_positive(
                    subtreeLoss[v.label][z.label], k, H, nodes_table,
                    'cost_with_losses')
                list_w_to_right = utiles.kmin_positive(
                    subtreeLoss[w.label][z.label], k, H, nodes_table,
                    'cost_with_losses')

                for hyper_node1 in list_v_to_right:
                    for hyper_node2 in list_w_to_left:
                        cost_without_losses = hyper_node1[1][
                            'cost_without_losses'] + hyper_node2[1][
                                'cost_without_losses'] + S_cost
                        cost_with_losses = hyper_node1[1][
                            'cost_with_losses'] + hyper_node2[1][
                                'cost_with_losses'] + S_cost
                        heapq.heappush(
                            heap,
                            utiles.heap_items(cost_without_losses,
                                              cost_with_losses, hyper_node1,
                                              hyper_node2))

                for hyper_node1 in list_v_to_left:
                    for hyper_node2 in list_w_to_right:
                        cost_without_losses = hyper_node1[1][
                            'cost_without_losses'] + hyper_node2[1][
                                'cost_without_losses'] + S_cost
                        cost_with_losses = hyper_node1[1][
                            'cost_with_losses'] + hyper_node2[1][
                                'cost_with_losses'] + S_cost
                        heapq.heappush(
                            heap,
                            utiles.heap_items(cost_without_losses,
                                              cost_with_losses, hyper_node1,
                                              hyper_node2))

    return heap
Exemplo n.º 2
0
def DuplicationEvent(H, u, x, D_cost, nodes_table):
    heap = []
    if (not tree_operations.is_a_leaf(x)):
        v = []
        w = []
        list_v_to_right = []
        list_w_to_right = []
        list_v_to_left = []
        list_w_to_left = []

        if (tree_operations.has_right_child(u)):
            v = u.adjacent_nodes()[0]

        if (tree_operations.has_left_child(u)):
            w = u.adjacent_nodes()[1]

        if (tree_operations.has_right_child(x)):
            for y in x.adjacent_nodes()[0].postorder_iter():  # left subtree
                list_v_to_left = list_v_to_left + find_nodes_in_hypergraph(
                    H, v.label, y.label, 0, nodes_table)
                list_w_to_left = list_w_to_left + find_nodes_in_hypergraph(
                    H, w.label, y.label, 0, nodes_table)

        if (tree_operations.has_left_child(x)):
            for z in x.adjacent_nodes()[1].postorder_iter():  # right subtree
                list_v_to_right = list_v_to_right + find_nodes_in_hypergraph(
                    H, v.label, z.label, 0, nodes_table)
                list_w_to_right = list_w_to_right + find_nodes_in_hypergraph(
                    H, w.label, z.label, 0, nodes_table)

        for hyper_node1 in list_v_to_right:
            for hyper_node2 in list_w_to_right:
                heapq.heappush(
                    heap,
                    utiles.heap_items(
                        hyper_node1[1]['cost'] + hyper_node2[1]['cost'] +
                        D_cost, hyper_node1, hyper_node2))

        for hyper_node1 in list_v_to_left:
            for hyper_node2 in list_w_to_left:
                heapq.heappush(
                    heap,
                    utiles.heap_items(
                        hyper_node1[1]['cost'] + hyper_node2[1]['cost'] +
                        D_cost, hyper_node1, hyper_node2))

    return heap
Exemplo n.º 3
0
def HTEvent_effi(u, x, HT_cost, subtreeLoss, incomp, k, H, nodes_table):
    heap = []
    v = u.adjacent_nodes()[0]  #left child
    w = u.adjacent_nodes()[1]  #right child

    list_v_to_subtree = utiles.kmin_positive(subtreeLoss[v.label][x.label], k,
                                             H, nodes_table,
                                             'cost_with_losses')
    list_w_to_subtree = utiles.kmin_positive(subtreeLoss[w.label][x.label], k,
                                             H, nodes_table,
                                             'cost_with_losses')

    list_v_horizontally = utiles.kmin_positive(incomp[v.label][x.label], k, H,
                                               nodes_table,
                                               'cost_without_losses')
    list_w_horizontally = utiles.kmin_positive(incomp[w.label][x.label], k, H,
                                               nodes_table,
                                               'cost_without_losses')
    for hyper_node1 in list_v_to_subtree:
        for hyper_node2 in list_w_horizontally:
            cost_without_losses = hyper_node1[1][
                'cost_without_losses'] + hyper_node2[1][
                    'cost_without_losses'] + HT_cost
            cost_with_losses = hyper_node1[1]['cost_with_losses'] + hyper_node2[
                1]['cost_with_losses'] + HT_cost
            heapq.heappush(
                heap,
                utiles.heap_items(cost_without_losses, cost_with_losses,
                                  hyper_node1, hyper_node2))
    for hyper_node1 in list_w_to_subtree:
        for hyper_node2 in list_v_horizontally:
            cost_without_losses = hyper_node1[1][
                'cost_without_losses'] + hyper_node2[1][
                    'cost_without_losses'] + HT_cost
            cost_with_losses = hyper_node1[1]['cost_with_losses'] + hyper_node2[
                1]['cost_with_losses'] + HT_cost
            heapq.heappush(
                heap,
                utiles.heap_items(cost_without_losses, cost_with_losses,
                                  hyper_node1, hyper_node2))
    return heap
Exemplo n.º 4
0
def HTEvent(S, H, u, x, HT_cost, nodes_table):
    heap = []
    v = u.adjacent_nodes()[0]  #left child
    w = u.adjacent_nodes()[1]  #right child

    list_v_to_subtree = []
    list_w_to_subtree = []
    list_v_horizontally = []
    list_w_horizontally = []

    for y in x.postorder_iter():
        list_v_to_subtree = list_v_to_subtree + find_nodes_in_hypergraph(
            H, v.label, y.label, 0, nodes_table)
        list_w_to_subtree = list_w_to_subtree + find_nodes_in_hypergraph(
            H, w.label, y.label, 0, nodes_table)

    for z in S.postorder_node_iter(lambda nd: (tree_operations.is_not_ancestor(
            nd, x) and tree_operations.is_not_ancestor(x, nd))):
        list_v_horizontally = list_v_horizontally + find_nodes_in_hypergraph(
            H, v.label, z.label, 0, nodes_table)
        list_w_horizontally = list_w_horizontally + find_nodes_in_hypergraph(
            H, w.label, z.label, 0, nodes_table)

    for hyper_node1 in list_v_to_subtree:
        for hyper_node2 in list_w_horizontally:
            heapq.heappush(
                heap,
                utiles.heap_items(
                    hyper_node1[1]['cost'] + hyper_node2[1]['cost'] + HT_cost,
                    hyper_node1, hyper_node2))

    for hyper_node1 in list_w_to_subtree:
        for hyper_node2 in list_v_horizontally:
            heapq.heappush(
                heap,
                utiles.heap_items(
                    hyper_node1[1]['cost'] + hyper_node2[1]['cost'] + HT_cost,
                    hyper_node1, hyper_node2))
    return heap
Exemplo n.º 5
0
def DuplicationEvent_effi(H, u, x, D_cost, loss_cost, nodes_table, subtreeLoss,
                          k):
    heap = []
    if not tree_operations.is_a_leaf(x):
        list_v_to_right = []
        list_w_to_right = []
        list_v_to_left = []
        list_w_to_left = []
        if tree_operations.has_right_child(
                x) and tree_operations.has_right_child(u):
            y = x.adjacent_nodes()[0]
            v = u.adjacent_nodes()[0]
            list_v_to_left = utiles.kmin_positive(
                subtreeLoss[v.label][y.label], k, H, nodes_table,
                'cost_with_losses')
        if tree_operations.has_right_child(
                x) and tree_operations.has_left_child(u):
            y = x.adjacent_nodes()[0]
            w = u.adjacent_nodes()[1]
            list_w_to_left = utiles.kmin_positive(
                subtreeLoss[w.label][y.label], k, H, nodes_table,
                'cost_with_losses')
        if tree_operations.has_left_child(
                x) and tree_operations.has_right_child(u):
            z = x.adjacent_nodes()[1]
            v = u.adjacent_nodes()[0]
            list_v_to_right = utiles.kmin_positive(
                subtreeLoss[v.label][z.label], k, H, nodes_table,
                'cost_with_losses')
        if tree_operations.has_left_child(
                x) and tree_operations.has_left_child(u):
            z = x.adjacent_nodes()[1]
            w = u.adjacent_nodes()[1]
            list_w_to_right = utiles.kmin_positive(
                subtreeLoss[w.label][z.label], k, H, nodes_table,
                'cost_with_losses')

        for hyper_node1 in list_v_to_right:
            for hyper_node2 in list_w_to_right:
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + 2 * loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
            hyper_node3 = find_nodes_in_hypergraph(H, w.label, x.label, 0,
                                                   nodes_table)
            if hyper_node3:
                hyper_node3 = hyper_node3[0]
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node3[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node3[1][
                        'cost_with_losses'] + D_cost + loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node3))
        for hyper_node1 in list_v_to_left:
            for hyper_node2 in list_w_to_left:
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + 2 * loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
            hyper_node3 = find_nodes_in_hypergraph(H, w.label, x.label, 0,
                                                   nodes_table)

            if hyper_node3:
                hyper_node3 = hyper_node3[0]
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node3[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node3[1][
                        'cost_with_losses'] + D_cost + loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node3))

        for hyper_node1 in list_w_to_right:
            hyper_node2 = find_nodes_in_hypergraph(H, v.label, x.label, 0,
                                                   nodes_table)
            if hyper_node2:
                hyper_node2 = hyper_node2[0]
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
        for hyper_node1 in list_w_to_left:
            hyper_node2 = find_nodes_in_hypergraph(H, v.label, x.label, 0,
                                                   nodes_table)
            if hyper_node2 != []:
                hyper_node2 = hyper_node2[0]
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
        for hyper_node1 in list_v_to_left:
            for hyper_node2 in list_w_to_right:
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + 2 * loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
        for hyper_node1 in list_w_to_left:
            for hyper_node2 in list_v_to_right:
                cost_without_losses = hyper_node1[1][
                    'cost_without_losses'] + hyper_node2[1][
                        'cost_without_losses'] + D_cost
                cost_with_losses = hyper_node1[1][
                    'cost_with_losses'] + hyper_node2[1][
                        'cost_with_losses'] + D_cost + 2 * loss_cost
                heapq.heappush(
                    heap,
                    utiles.heap_items(cost_without_losses, cost_with_losses,
                                      hyper_node1, hyper_node2))
        hyper_node1 = find_nodes_in_hypergraph(H, w.label, x.label, 0,
                                               nodes_table)
        hyper_node2 = find_nodes_in_hypergraph(H, v.label, x.label, 0,
                                               nodes_table)
        if hyper_node2 and hyper_node1:
            hyper_node1 = hyper_node1[0]
            hyper_node2 = hyper_node2[0]
            cost_without_losses = hyper_node1[1][
                'cost_without_losses'] + hyper_node2[1][
                    'cost_without_losses'] + D_cost
            cost_with_losses = hyper_node1[1]['cost_with_losses'] + hyper_node2[
                1]['cost_with_losses'] + D_cost
            heapq.heappush(
                heap,
                utiles.heap_items(cost_without_losses, cost_with_losses,
                                  hyper_node1, hyper_node2))
    return heap
Exemplo n.º 6
0
def build_hyper_garph(S, G, k, nodes_table, D_cost, S_cost, loss_cost, HT_cost,
                      sigma, S_dis_matrix, track_solution, res):
    H = nx.MultiDiGraph()
    H.clear()

    H, H_number_of_nodes, nodes_table = inits.init_leafs_efficient(
        G, H, k, 0, sigma, nodes_table)
    incomp = inits.init_dict_inf(H, S, G, k, nodes_table, 'incomp', sigma,
                                 S_dis_matrix, loss_cost)
    subtree = inits.init_dict_inf(H, S, G, k, nodes_table, 'subtree', sigma,
                                  S_dis_matrix, loss_cost)
    subtreeLoss = inits.init_dict_inf(H, S, G, k, nodes_table, 'subtreeLoss',
                                      sigma, S_dis_matrix, loss_cost)

    for u in G.postorder_node_iter():
        if not tree_operations.is_a_leaf(u):
            for x in S.postorder_node_iter():
                key_counter = 0
                S_list = SpeciationEvent_effi(u, x, S_cost, subtreeLoss, k, H,
                                              nodes_table)
                SE = list(map(lambda nd: (nd, 'S'), S_list))
                D_list = DuplicationEvent_effi(H, u, x, D_cost, loss_cost,
                                               nodes_table, subtreeLoss, k)
                DE = list(map(lambda nd: (nd, 'D'), D_list))
                HT_list = HTEvent_effi(u, x, HT_cost, subtreeLoss, incomp, k,
                                       H, nodes_table)
                HTE = list(map(lambda nd: (nd, 'HT'), HT_list))
                Kbest = SE + DE + HTE
                random.shuffle(Kbest, random.random)
                heapq.heapify(Kbest)

                if len(Kbest) > 0:
                    H.add_node(H_number_of_nodes, s=u.label, t=x.label, l=[])
                    nodes_table[x.label][u.label] = H_number_of_nodes
                    big_node = H_number_of_nodes
                    H_number_of_nodes += 1

                for i in range(0, k):
                    if len(Kbest) > 0:
                        match = heapq.heappop(Kbest)
                        new_cost_no_losses = match[0].val[0]
                        new_cost_with_losses = match[0].val[1]
                        event = match[1]
                        match1 = match[0].val[2]
                        match2 = match[0].val[3]

                        if event == 'S':
                            H.nodes[big_node]['l'] = H.nodes[big_node]['l'] + [
                                {
                                    's': u.label,
                                    't': x.label,
                                    'cost_without_losses': new_cost_no_losses,
                                    'cost_with_losses': new_cost_with_losses,
                                    'event': "S",
                                    'list_place': len(H.nodes[big_node]['l'])
                                }
                            ]
                        elif event == 'D':
                            H.nodes[big_node]['l'] = H.nodes[big_node]['l'] + [
                                {
                                    's': u.label,
                                    't': x.label,
                                    'cost_without_losses': new_cost_no_losses,
                                    'cost_with_losses': new_cost_with_losses,
                                    'event': "D",
                                    'list_place': len(H.nodes[big_node]['l'])
                                }
                            ]
                        elif event == 'HT':
                            H.nodes[big_node]['l'] = H.nodes[big_node]['l'] + [
                                {
                                    's': u.label,
                                    't': x.label,
                                    'cost_without_losses': new_cost_no_losses,
                                    'cost_with_losses': new_cost_with_losses,
                                    'event': "HT",
                                    'list_place': len(H.nodes[big_node]['l'])
                                }
                            ]

                        H.add_edge(match1[0],
                                   big_node,
                                   key=key_counter,
                                   source=match1[1]['list_place'],
                                   target=len(H.nodes[big_node]['l']) - 1,
                                   probability=0)
                        key_counter += 1
                        H.add_edge(match2[0],
                                   big_node,
                                   key=key_counter,
                                   source=match2[1]['list_place'],
                                   target=len(H.nodes[big_node]['l']) - 1,
                                   probability=0)
                        key_counter += 1

                        new_node1 = find_nodes_in_hypergraph(
                            H, match1[1]['s'], match1[1]['t'],
                            match1[1]['list_place'] + 1, nodes_table)
                        new_node2 = find_nodes_in_hypergraph(
                            H, match2[1]['s'], match2[1]['t'],
                            match2[1]['list_place'] + 1, nodes_table)
                        if new_node1 and new_node2:
                            new_node1 = new_node1[0]
                            new_node2 = new_node2[0]
                            if event == 'D':
                                additional_cost = D_cost
                            elif event == 'S':
                                additional_cost = S_cost
                            else:
                                additional_cost = HT_cost
                            cost_with_losses = match1[1][
                                'cost_with_losses'] + new_node2[1][
                                    'cost_with_losses'] + additional_cost
                            cost_without_losses = match1[1][
                                'cost_with_losses'] + new_node2[1][
                                    'cost_without_losses'] + additional_cost
                            new_node12 = (utiles.heap_items(
                                cost_without_losses, cost_with_losses, match1,
                                new_node2), event)
                            new_node21 = (utiles.heap_items(
                                cost_without_losses, cost_with_losses, match2,
                                new_node1), event)

                            if new_node12[0] == new_node21[0]:
                                Kbest.insert(len(Kbest), new_node12)
                                Kbest.insert(len(Kbest), new_node21)
                            else:
                                heapq.heappush(Kbest, tuple(new_node12))
                                heapq.heappush(Kbest, tuple(new_node21))
                if not tree_operations.is_a_leaf(x):
                    y = x.adjacent_nodes()[0]
                    z = x.adjacent_nodes()[1]
                    subtree[u.label][x.label] += utiles.kmin_list(
                        find_nodes_in_hypergraph(H, u.label, x.label, -1,
                                                 nodes_table),
                        subtree[u.label][y.label], subtree[u.label][z.label],
                        H, nodes_table, 'cost_without_losses')

                    list1 = [
                        deepcopy(tocopy)
                        for tocopy in subtreeLoss[u.label][y.label]
                    ]
                    list2 = [
                        deepcopy(tocopy)
                        for tocopy in subtreeLoss[u.label][z.label]
                    ]
                    for lst in (list1, list2):
                        for node in lst:
                            node[1]['cost_with_losses'] += loss_cost
                    #print('u: %s, x: %s\nsubtree[u.label][y.label]:%s\nsubtree[u.label][z.label]:%s\nc(u,x): %s\nsubtreeLoss[u.label][y.label]: %s\nsubtreeLoss[u.label][z.label]: %s\n' %
                    #      (str(u.label),str(x.label),str(subtree[u.label][y.label]),str(subtree[u.label][z.label]),
                    #       str(find_nodes_in_hypergraph(H,u.label,x.label,-1,nodes_table)),str(subtreeLoss[u.label][y.label]),subtreeLoss[u.label][z.label]))
                    subtreeLoss[u.label][x.label] += utiles.kmin_list(
                        find_nodes_in_hypergraph(H, u.label, x.label, -1,
                                                 nodes_table), list1, list2, H,
                        nodes_table, 'cost_with_losses')
                else:
                    subtree[u.label][x.label] += utiles.kmin_list(
                        find_nodes_in_hypergraph(H, u.label, x.label, -1,
                                                 nodes_table), [], [], H,
                        nodes_table, 'cost_without_losses')
                    subtreeLoss[u.label][x.label] += utiles.kmin_list(
                        find_nodes_in_hypergraph(H, u.label, x.label, -1,
                                                 nodes_table), [], [], H,
                        nodes_table, 'cost_with_losses')
                    #print('u: %s, x: %s\nsubtree[u.label][y.label]:%s\nsubtree[u.label][z.label]:%s\nc(u,x): %s\nsubtreeLoss[u.label][y.label]: %s\nsubtreeLoss[u.label][z.label]: %s\n' %
                    #      (str(u.label),str(x.label),str(subtree[u.label][y.label]),str(subtree[u.label][z.label]),
                    #       str(find_nodes_in_hypergraph(H,u.label,x.label,-1,nodes_table)),str(subtreeLoss[u.label][y.label]),subtreeLoss[u.label][z.label]))

        for x in S.preorder_node_iter():
            if not tree_operations.is_a_leaf(x):
                y = x.adjacent_nodes()[0]
                z = x.adjacent_nodes()[1]
                incomp[u.label][y.label] += utiles.kmin_positive(
                    incomp[u.label][x.label] + subtree[u.label][z.label], k, H,
                    nodes_table, 'cost_without_losses')
                incomp[u.label][z.label] += utiles.kmin_positive(
                    incomp[u.label][x.label] + subtree[u.label][y.label], k, H,
                    nodes_table, 'cost_without_losses')

    H_root = [
        nd for nd in list(H.node(data=True))
        if nd[1]['s'] == G.seed_node.label and nd[1]['t'] == S.seed_node.label
    ]
    if track_solution:
        res['solution'] += 'Solution number ' + str(
            track_solution) + '\n\n' + format_solution(
                track_a_solution(H_root, H, S, G, nx.DiGraph(),
                                 int(track_solution), -1)[0].nodes(data=True))
    return H, H_number_of_nodes, nodes_table
Exemplo n.º 7
0
def build_hyper_garph(S, G, test, k, nodes_table, D_cost, S_cost, HT_cost,
                      path, alpha, sigma, save_data):
    #print('Building hypergraph...')
    H = nx.MultiDiGraph()
    H.clear()

    if test:
        print("     Reading file 'H_edges.txt'...")
        input = open(path + '/saved_data/H_edges_k=' + str(k) + '.txt', 'r')
        new_edges = []
        for line in input:
            new_edges.append(eval(line))
        new_edges = new_edges[0]
        print("     Finished reading file 'H_edges.txt'")

        print("     Reading file 'H_nodes.txt'...")
        input = open(
            path + '/saved_data/H_nodes_k=' + str(k) + '_alpha=' + str(alpha) +
            '.txt', 'r')
        new_nodes = []
        for line in input:
            new_nodes.append(eval(line))
        new_nodes = new_nodes[0]
        print("     Finished reading file 'H_nodes.txt'.")

        print("     Reading file 'nodes_table.txt'...")
        input = open(path + '/saved_data/nodes_table_k=' + str(k) + '.txt',
                     'r')
        nodes = {}
        for line in input:
            nodes.update(eval(line))
        nodes_table = nodes
        print("     Finished reading file 'nodes_table_k=" + str(k) + ".txt'")

        H.add_nodes_from(new_nodes)
        H.add_edges_from(new_edges)
        H_number_of_nodes = (len(H.nodes()))
    else:
        H, H_number_of_nodes, nodes_table = inits.init_leafs(
            G, H, k, 0, sigma, nodes_table)
        for u in G.postorder_node_iter():
            if (not tree_operations.is_a_leaf(u)):
                for x in S.postorder_node_iter():
                    key_counter = 0
                    SE = list(
                        map(lambda nd: (nd, 'S'),
                            SpeciationEvent(H, u, x, S_cost, nodes_table)))
                    DE = list(
                        map(lambda nd: (nd, 'D'),
                            DuplicationEvent(H, u, x, D_cost, nodes_table)))
                    HTE = list(
                        map(lambda nd: (nd, 'HT'),
                            HTEvent(S, H, u, x, HT_cost, nodes_table)))

                    Kbest = SE + DE + HTE
                    random.shuffle(Kbest, random.random)
                    heapq.heapify(Kbest)

                    if (len(Kbest) > 0):
                        H.add_node(H_number_of_nodes,
                                   s=u.label,
                                   t=x.label,
                                   l=[])
                        nodes_table[x.label][u.label] = H_number_of_nodes
                        big_node = H_number_of_nodes
                        H_number_of_nodes += 1

                    for i in range(0, k):
                        if (len(Kbest) > 0):
                            match = heapq.heappop(Kbest)
                            new_cost = match[0].val[0]
                            event = match[1]
                            match1 = match[0].val[1]
                            match2 = match[0].val[2]

                            if (event == 'S'):
                                H.nodes[big_node][
                                    'l'] = H.nodes[big_node]['l'] + [{
                                        's':
                                        u.label,
                                        't':
                                        x.label,
                                        'cost':
                                        new_cost,
                                        'event':
                                        "S",
                                        'list_place':
                                        len(H.nodes[big_node]['l'])
                                    }]
                            elif (event == 'D'):
                                H.nodes[big_node][
                                    'l'] = H.nodes[big_node]['l'] + [{
                                        's':
                                        u.label,
                                        't':
                                        x.label,
                                        'cost':
                                        new_cost,
                                        'event':
                                        "D",
                                        'list_place':
                                        len(H.nodes[big_node]['l'])
                                    }]
                            else:
                                H.nodes[big_node][
                                    'l'] = H.nodes[big_node]['l'] + [{
                                        's':
                                        u.label,
                                        't':
                                        x.label,
                                        'cost':
                                        new_cost,
                                        'event':
                                        "HT",
                                        'list_place':
                                        len(H.nodes[big_node]['l'])
                                    }]

                            H.add_edge(match1[0],
                                       big_node,
                                       key=key_counter,
                                       source=match1[1]['list_place'],
                                       target=len(H.nodes[big_node]['l']) - 1,
                                       probability=0)
                            key_counter += 1
                            H.add_edge(match2[0],
                                       big_node,
                                       key=key_counter,
                                       source=match2[1]['list_place'],
                                       target=len(H.nodes[big_node]['l']) - 1,
                                       probability=0)
                            key_counter += 1

                            new_node1 = find_nodes_in_hypergraph(
                                H, match1[1]['s'], match1[1]['t'],
                                match1[1]['list_place'] + 1, nodes_table)
                            new_node2 = find_nodes_in_hypergraph(
                                H, match2[1]['s'], match2[1]['t'],
                                match2[1]['list_place'] + 1, nodes_table)
                            if (new_node1 != [] and new_node2 != []):
                                new_node1 = new_node1[0]
                                new_node2 = new_node2[0]
                                if event == 'D':
                                    additional_cost = D_cost
                                elif event == 'S':
                                    additional_cost = S_cost
                                else:
                                    additional_cost = HT_cost
                                new_node12 = (utiles.heap_items(
                                    match1[1]['cost'] + new_node2[1]['cost'] +
                                    additional_cost, match1, new_node2), event)
                                new_node21 = (utiles.heap_items(
                                    match2[1]['cost'] + new_node1[1]['cost'] +
                                    additional_cost, match2, new_node1), event)

                                if (new_node12[0] == new_node21[0]):
                                    Kbest.insert(len(Kbest), new_node12)
                                    Kbest.insert(len(Kbest), new_node21)

                                else:
                                    heapq.heappush(Kbest, tuple(new_node12))
                                    heapq.heappush(Kbest, tuple(new_node21))
        if save_data:
            print('     Writing nodes...')
            file = open(path + '/saved_data/H_nodes_naive.txt', 'w')
            file.write(str(H.nodes(data=True)))
            file.close()
            print('     Finished writing nodes.\n')

            print('     Writing edges...')
            file = open(path + '/saved_data/H_edges_k=' + str(k) + '.txt', 'w')
            file.write(str(H.edges(data=True)))
            file.close()
            print('     Finished writing edges.\n')

            print('     Writing nodes table...')
            file = open(path + '/saved_data/nodes_table_k=' + str(k) + '.txt',
                        'w')
            file.write(str(nodes_table))
            file.close()
            print('     Finished writing nodes table.\n')

    #print('     No. of nodes: '+str(H_number_of_nodes * k)+'        No. on edges: '+str(len(H.edges())))
    #print('Finished building hypergraph.\n')
    return H, H_number_of_nodes, nodes_table