Exemple #1
0
def _get_lower_bound_of_ap_nodes(G, c=1.0):
    """
    Returns the articulation points and lower bound for each of them.
    Procedure 3 of https://dl.acm.org/profile/81484650642

    Parameters
    ----------
    G : graph
        An undirected graph.

    c : float
        To define zeta: zeta = c * (n*n*n), and zeta is the large
        value assigned as the shortest distance of two unreachable
        vertices.
        Default is 1.
    """
    v_ap = []
    lower_bound = dict()

    N_G = len(G)
    zeta = c * math.pow(N_G, 3)
    components = connected_components(G)
    for component in components:
        component_subgraph = G.nodes_subgraph(from_nodes=list(component))
        articulation_points = list(
            generator_articulation_points(component_subgraph))
        N_component = len(component_subgraph)
        for articulation in articulation_points:
            component_subgraph_after_remove = component_subgraph.copy()
            component_subgraph_after_remove.remove_node(articulation)

            lower_bound_value = 0
            lower_bound_value += sum([(len(temp) * (N_G - len(temp)))
                                      for temp in components])
            lower_bound_value += sum([
                (len(temp) * (N_component - 1 - len(temp)))
                for temp in connected_components(
                    component_subgraph_after_remove)
            ])
            lower_bound_value += (2 * N_component - 2 * N_G)
            lower_bound_value *= zeta

            v_ap.append(articulation)
            lower_bound[articulation] = lower_bound_value

            del component_subgraph_after_remove

        del component_subgraph

    return v_ap, lower_bound
Exemple #2
0
def procedure1(G, c=1.0):
    """
    Procedure 1 of https://dl.acm.org/profile/81484650642

    Parameters
    -----------
    G : graph
    c : float
        To define zeta: zeta = c * (n*n*n)
        Default is 1.
    """
    components = connected_components(G)
    upper_bound = 0
    for component in components:
        component_subgraph = G.nodes_subgraph(from_nodes=list(component))
        spanning_tree = _get_spanning_tree_of_component(component_subgraph)

        random_root = list(spanning_tree.nodes)[random.randint(
            0,
            len(spanning_tree) - 1)]
        num_subtree_nodes = _get_num_subtree_nodes(spanning_tree, random_root)

        N_tree = num_subtree_nodes[random_root]
        for node, num in num_subtree_nodes.items():
            upper_bound += 2 * num * (N_tree - num)

        del component_subgraph, spanning_tree

    N_G = len(G)
    zeta = c * math.pow(N_G, 3)
    for component in components:
        N_c = len(component)
        upper_bound += N_c * (N_G - N_c) * zeta

    return upper_bound
Exemple #3
0
def _get_upper_bound_of_non_ap_nodes(G, ap: list, c=1.0):
    """
    Returns the upper bound value for each non-articulation points.
    Eq.(14) of https://dl.acm.org/profile/81484650642

    Parameters
    ----------
    G : graph
        An undirected graph.
    ap : list
        Articulation points of G.
    c : float
        To define zeta: zeta = c * (n*n*n), and zeta is the large
        value assigned as the shortest distance of two unreachable
        vertices.
        Default is 1.
    """
    upper_bound = []

    N_G = len(G)
    zeta = c * math.pow(N_G, 3)
    components = connected_components(G)
    for component in components:
        non_articulation_points = component - set(ap)
        for node in non_articulation_points:
            upper_bound_value = 0
            upper_bound_value += sum(
                (len(temp) * (N_G - len(temp))) for temp in components)
            upper_bound_value += (2 * len(component) + 1 - 2 * N_G)
            upper_bound_value *= zeta

            upper_bound.append(upper_bound_value)

    return upper_bound
Exemple #4
0
def procedure2(G, c=1.0):
    """
    Procedure 2 of https://dl.acm.org/profile/81484650642

    Parameters
    -----------
    G : graph

    c : float
        To define zeta: zeta = c * (n*n*n)
        Default is 1.
    """
    components = connected_components(G)
    C = 0
    N_G = len(G)
    zeta = c * math.pow(N_G, 3)
    for component in components:
        component_subgraph = G.nodes_subgraph(from_nodes=list(component))
        C_l = _get_sum_all_shortest_paths_of_component(component_subgraph)
        N_c = len(component)
        C += (C_l + N_c * (N_G - N_c) * zeta)

        del component_subgraph

    return C