def create_label_based_sbm_global_constant_nodes(graph_path,
                                                 labels,
                                                 output_path,
                                                 control_ratio,
                                                 edges_per_node,
                                                 frm,
                                                 to,
                                                 seed=0,
                                                 gen_sbm=False):
    graph = get_graph(graph_path, labels, gen_sbm, seed)

    label_id_to_node_id = create_community_id_to_node_id(labels)
    labels_list = label_id_to_node_id.keys()

    attackers = get_nodes_with_degree_percentile(graph, frm, to)
    control_num = int(len(graph.nodes()) * control_ratio)
    assert control_num <= len(
        attackers
    ), f'control_num={control_num} > len(attackers)={len(attackers)}'
    # print(attackers)
    attackers = np.random.choice(attackers, control_num,
                                 replace=False).tolist()
    # print(attackers)
    print(f'Percentage ({frm}-{to}) controlling {len(attackers)} nodes')
    # print(type(edges_per_node))
    rows = []
    for i in range(edges_per_node):
        rows = rows + attackers
    cols = np.random.choice(graph.nodes(), len(attackers) * edges_per_node)
    edges = [[u, v] for u, v in zip(rows, cols)]
    graph.add_edges_from(edges)
    nx.write_edgelist(graph, output_path)

    return graph
def create_label_based_sbm_local_edges(graph_path,
                                       labels,
                                       output_path,
                                       edges_to_add,
                                       seed=0,
                                       gen_sbm=False):
    graph = get_graph(graph_path, labels, gen_sbm, seed)

    label_id_to_node_id = create_community_id_to_node_id(labels)
    labels_list = list(label_id_to_node_id.keys())

    subg = {
        c: graph.subgraph([u for u in label_id_to_node_id[c]])
        for c in labels_list
    }
    subg_sizes = [len(subg[c].nodes()) for c in labels_list]
    p = [size / len(graph.nodes()) for size in subg_sizes]

    chosen_communities = np.random.choice(labels_list,
                                          edges_to_add,
                                          replace=True,
                                          p=p)

    rows = [np.random.choice(subg[c], 1)[0] for c in chosen_communities]
    cols = [np.random.choice(subg[c], 1)[0] for c in chosen_communities]
    edges = [[u, v] for u, v in zip(rows, cols)]

    print(f'{sum([graph.has_edge(*edge) for edge in edges])} edges duplicated')

    graph.add_edges_from(edges)
    nx.write_edgelist(graph, output_path)

    return graph
def create_label_based_sbm_distant_edges(graph_path,
                                         labels,
                                         output_path,
                                         edges_to_add,
                                         seed=0,
                                         gen_sbm=False):
    graph, node_mappings, reverse_node_mappings = create_graph_and_node_mappings_from_file(
        graph_path)

    label_id_to_node_id = create_community_id_to_node_id(labels)

    block_sizes, edge_probabilities, node_lists = build_stochastic_block_matrix(
        graph, node_mappings, reverse_node_mappings, labels)
    # print(edge_probabilities[0])
    target = [
        np.argwhere(prob == np.amin(prob)).flatten().tolist()
        for prob in edge_probabilities
    ]

    labels_list = list(label_id_to_node_id.keys())

    graph = get_graph(graph_path, labels, gen_sbm, seed)
    subg = {
        c: graph.subgraph([u for u in label_id_to_node_id[c]])
        for c in labels_list
    }
    subg_sizes = [len(subg[c].nodes()) for c in labels_list]
    p = [size / len(graph.nodes()) for size in subg_sizes]
    chosen_communities = np.random.choice(labels_list,
                                          edges_to_add,
                                          replace=True,
                                          p=p)

    rows = [np.random.choice(subg[c], 1)[0] for c in chosen_communities]
    col_targets = [np.random.choice(target[labels[u]], 1)[0] for u in rows]
    # print([labels[u] for u in rows[:10]])
    # print(col_targets[:10])
    # exit(0)
    cols = [np.random.choice(subg[c], 1)[0] for c in col_targets]
    edges = [[u, v] for u, v in zip(rows, cols)]

    print(f'{sum([graph.has_edge(*edge) for edge in edges])} edges duplicated')

    graph.add_edges_from(edges)
    nx.write_edgelist(graph, output_path)

    return graph
def create_label_based_sbm_global_edges(graph_path,
                                        labels,
                                        output_path,
                                        edges_to_add,
                                        seed=0,
                                        gen_sbm=False):
    graph = get_graph(graph_path, labels, gen_sbm, seed)

    label_id_to_node_id = create_community_id_to_node_id(labels)
    labels_list = label_id_to_node_id.keys()

    rows = np.random.choice(graph.nodes(), edges_to_add)
    cols = np.random.choice(graph.nodes(), edges_to_add)
    edges = [[u, v] for u, v in zip(rows, cols)]

    graph.add_edges_from(edges)
    nx.write_edgelist(graph, output_path)

    return graph
def create_label_based_sbm_global_degree_cat(graph_path,
                                             labels,
                                             output_path,
                                             edges_to_add,
                                             frm,
                                             to,
                                             seed=0,
                                             gen_sbm=False):
    graph = get_graph(graph_path, labels, gen_sbm, seed)

    label_id_to_node_id = create_community_id_to_node_id(labels)
    labels_list = label_id_to_node_id.keys()

    attach_to = get_nodes_with_degree_percentile(graph, frm, to)
    print(f'Percentage ({frm}-{to}) able to link to {len(attach_to)} nodes')
    rows = np.random.choice(attach_to, edges_to_add)
    cols = np.random.choice(graph.nodes(), edges_to_add)
    edges = [[u, v] for u, v in zip(rows, cols)]

    graph.add_edges_from(edges)
    nx.write_edgelist(graph, output_path)

    return graph