Ejemplo n.º 1
0
def max_k_independent_set(G, k):
    """Return a largest k-independent set of nodes in *G*.
    The method used is brute force, except when *k*=1. In this case,
    the search starts with subsets of *G* with cardinality equal to the
    annihilation number of *G*, which was shown by Pepper to be an upper
    bound for the independence number of a graph, and then continues
    checking smaller subsets until a maximum independent set is found.
    Parameters
    ----------
    G : NetworkX graph
        An undirected graph.
    k : int
        A positive integer.
    Returns
    -------
    list
        A list of nodes comprising a largest k-independent set in *G*.
    See Also
    --------
    max_independent_set
    """
    # set the maximum for the loop range
    rangeMax = number_of_nodes(G) + 1
    if k == 1:
        rangeMax = annihilation_number(G) + 1

    # loop through subsets of nodes of G in decreasing order of size
    # until a k-independent set is found
    for i in reversed(range(rangeMax)):
        for S in combinations(nodes(G), i):
            if is_k_independent_set(G, S, k):
                return set(S)
Ejemplo n.º 2
0
def number_of_nodes_of_degree_k(G, k):
    """Return the number of nodes of the graph with degree equal to k.

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

    k : int
        A positive integer.

    Returns
    -------
    int
        The number of nodes in the graph with degree equal to k.

    See Also
    --------
    number_of_leaves, number_of_min_degree_nodes, number_of_max_degree_nodes

    Examples
    --------
    >>> G = nx.path_graph(3) # Path on 3 nodes
    >>> nx.number_of_nodes_of_degree_k(G, 1)
    2
    """
    return sum(1 for v in nodes(G) if degree(G, v) == k)
Ejemplo n.º 3
0
def min_connected_k_dominating_set(G, k):
    """Return a smallest connected k-dominating set in the graph.

    The method to compute the set is brute force.

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

    k : int
        A positive integer.

    Returns
    -------
    list
        A list of nodes in a smallest k-dominating set in the graph.

    """
    # check that k is a positive integer
    if not float(k).is_integer():
        raise TypeError("Expected k to be an integer.")
    k = int(k)
    if k < 1:
        raise ValueError("Expected k to be a positive integer.")
    # Only proceed with search if graph is connected
    if not is_connected(G):
        return []
    for i in range(1, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_connected_k_dominating_set(G, S, k):
                return list(S)
Ejemplo n.º 4
0
def closed_vertex_disparity(G, v):
    """Return number of distinct degrees of nodes in the closed neighborhood
    of v.

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

    v : node
        A node in G.

    Returns
    -------
    int
        The number of distinct degrees of nodes in the closed neighborhood
        of v.

    See Also
    --------
    vertex_disparity
    """
    if v not in nodes(G):
        raise(ValueError)

    return len(closed_neighborhood_degree_list(G, v))
Ejemplo n.º 5
0
def is_k_regular(G, k):
    """ Return True if the graph is regular of degree k and False otherwise.

    A graph is *regular of degree k* if all nodes have degree equal to *k*.

    Parameters
    ----------
    G : NetworkX graph
        An undirected graph

    k : int
        An integer

    Returns
    -------
    boolean
        True if all nodes have degree equal to *k*, False otherwise.
    """
    # check that k is an integer
    if not float(k).is_integer():
        raise TypeError('Expected k to be an integer.')
    k = int(k)
    for v in nodes(G):
        if not degree(G, v) == k:
            return False
    return True
Ejemplo n.º 6
0
def is_total_dominating_set(G, nbunch):
    # TODO: Add documentation
    # check if nbunch is an iterable; if not, convert to a list
    try:
        _ = (v for v in nbunch)
    except:
        nbunch = [nbunch]
    return set(neighborhood(G, nbunch)) == set(nodes(G))
Ejemplo n.º 7
0
def min_power_dominating_set(G):
    # TODO: Add documentation
    for i in range(1, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_power_dominating_set(G, S):
                return list(S)
    # if above loop completes, return None (should not occur)
    return None
Ejemplo n.º 8
0
def min_k_forcing_set(G, k):
    # TODO: Add documentation
    # use naive lower bound to compute a starting point for the search range
    rangeMin = min_degree(G) if k == 1 else 1
    # loop through subsets of nodes of G in increasing order of size until a zero forcing set is found
    for i in range(rangeMin, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_k_forcing_set(G, S, k):
                return list(S)
    # if the above loop completes, return None (should not occur)
    return None
Ejemplo n.º 9
0
def min_total_dominating_set(G):
    # TODO: Add documentation
    # use naive lower bound for domination to compute a starting point for the search range
    rangeMin = sub_total_domination_number(G)
    # loop through subsets of nodes of G in increasing order of size until a total dominating set is found
    for i in range(rangeMin, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_total_dominating_set(G, S):
                return list(S)
    # return None if no total dominating set is found (should not occur)
    return None
Ejemplo n.º 10
0
def is_k_forcing_set(G, nbunch, k):
    # TODO: Add documentation
    # check if nbunch is an iterable; if not, convert to a list
    try:
        _ = (v for v in nbunch)
    except:
        nbunch = [nbunch]
    Z = set(nbunch)
    while is_k_forcing_active_set(G, Z, k):
        Z_temp = Z.copy()
        for v in Z:
            if is_k_forcing_vertex(G, v, Z, k):
                Z_temp |= set(neighborhood(G, v))
        Z = Z_temp
    return Z == set(nodes(G))
Ejemplo n.º 11
0
def max_k_independent_set(G, k):
    # TODO: Add documentation
    # set the maximum for the loop range
    rangeMax = number_of_nodes(G) + 1
    if k == 1:
        rangeMax = annihilation_number(G) + 1
    elif number_of_edges(G) > 0:
        rangeMax = number_of_nodes(G)
    # TODO: can the above range be improved with some general upper bound for the k-independence number?
    # loop through subsets of nodes of G in decreasing order of size until a k-independent set is found
    for i in reversed(range(rangeMax)):
        for S in combinations(nodes(G), i):
            if is_k_independent_set(G, S, k):
                return list(S)
    # return None if no independent set is found (should not occur)
    return None
Ejemplo n.º 12
0
def disparity_sequence(G):
    """Return the sequence of disparities of each node in the graph.

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

    Returns
    -------
    list
        The sequence of disparities of each node in the graph.

    See Also
    --------
    closed_disparity_sequence, vertex_disparity
    """
    return [vertex_disparity(G, v) for v in nodes(G)]
Ejemplo n.º 13
0
def is_complete_graph(G):
    """Returns True if *G* is a complete graph, and False otherwise.

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

    Returns
    -------
    boolean
        True if G is a complete graph, False otherwise.
    """
    V = set(nodes(G))
    for v in V:
        if not set(neighborhood(G, v)) == V.difference({v}):
            return False
    return True
Ejemplo n.º 14
0
def min_k_dominating_set(G, k):
    """Return a smallest k-dominating set in the graph.

    The method to compute the set is brute force except that the subsets
    searched begin with those whose cardinality is equal to the
    sub-k-domination number of the graph, which was defined by Amos et
    al. and shown to be a tractable lower bound for the k-domination
    number.

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

    k : int
        A positive integer.

    Returns
    -------
    list
        A list of nodes in a smallest k-dominating set in the graph.

    References
    ----------
    D. Amos, J. Asplund, and R. Davila, The sub-k-domination number of a
    graph with applications to k-domination, *arXiv preprint
    arXiv:1611.02379*, (2016)

    """
    # check that k is a positive integer
    if not float(k).is_integer():
        raise TypeError("Expected k to be an integer.")
    k = int(k)
    if k < 1:
        raise ValueError("Expected k to be a positive integer.")
    # use the sub-k-domination number to compute a starting point for the
    # search range
    rangeMin = sub_k_domination_number(G, k)
    # loop through subsets of nodes of G in increasing order of size until a
    # dominating set is found
    for i in range(rangeMin, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_k_dominating_set(G, S, k):
                return list(S)
Ejemplo n.º 15
0
def is_k_dominating_set(G, nbunch, k):
    # TODO: Add documentation
    # TODO: add check that k >= 1 and throw error if not
    # check if nbunch is an iterable; if not, convert to a list
    try:
        _ = (v for v in nbunch)
    except:
        nbunch = [nbunch]
    if k == 1:
        return is_dominating_set(G, nbunch)
    else:
        S = set(nbunch)
        # loop through the nodes in the complement of S and determine if they are adjacent to atleast k nodes in S
        others = set(nodes(G)).difference(S)
        for v in others:
            if len(set(neighborhood(G, v)).intersection(S)) < k:
                return False
        # if the above loop completes, nbunch is a k-dominating set
        return True
Ejemplo n.º 16
0
def min_independent_k_dominating_set(G, k):
    """Return a smallest independent k-dominating set in the graph.

    The method to compute the set is brute force.

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

    Returns
    -------
    list
        A list of nodes in a smallest independent k-dominating set in
        the graph.

    """
    # loop through subsets of nodes of G in increasing order of size until a
    # total dominating set is found
    for i in range(1, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_independent_k_dominating_set(G, S, k):
                return list(S)
Ejemplo n.º 17
0
def degree_sequence(G):
    """Return the degree sequence of G.

    The degree sequence of a graph is the sequence of degrees of the nodes
    in the graph.

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

    Returns
    -------
    list
        The degree sequence of the graph.

    Examples
    --------
    >>> G = nx.path_graph(3) # Path on 3 nodes
    >>> nx.degree_sequence(G)
    [1, 2, 1]
    """
    return [degree(G, v) for v in nodes(G)]
Ejemplo n.º 18
0
def min_total_dominating_set_bf(G):
    """Return a smallest total dominating set in the graph.

    The method to compute the set is brute force except that the subsets
    searched begin with those whose cardinality is equal to the
    sub-total-domination number of the graph, which was defined by
    Davila and shown to be a tractable lower bound for the k-domination
    number.

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

    Returns
    -------
    list
        A list of nodes in a smallest total dominating set in the graph.

    References
    ----------
    R. Davila, A note on sub-total domination in graphs. *arXiv preprint
    arXiv: 1701.07811*, (2017)

    """
    # use naive lower bound for domination to compute a starting point
    # for the search range
    rangeMin = sub_total_domination_number(G)

    if number_of_nodes_of_degree_k(G, 0) > 0:
        return set()

    for i in range(rangeMin, number_of_nodes(G) + 1):
        for S in combinations(nodes(G), i):
            if is_total_dominating_set(G, S):
                return list(S)
Ejemplo n.º 19
0
def test_non_adjacent_vertices_not_total_dominating_set_of_star():
    G = gp.star_graph(3)
    for v in gp.nodes(G):
        for u in gp.nodes(G):
            if not gp.are_neighbors(G, u, v):
                assert gp.is_total_dominating_set(G, [u, v]) is False
Ejemplo n.º 20
0
def pairs_of_nodes(G):
    return itertools.combinations(nodes(G), 2)
Ejemplo n.º 21
0
def test_max_independent_set_of_empty_graph_is_all_nodes():
    for i in range(1, 11):
        G = gp.empty_graph(i)
        assert gp.max_independent_set(G, method="bf") == set(gp.nodes(G))
        assert gp.max_independent_set(G, method="ilp") == set(gp.nodes(G))
Ejemplo n.º 22
0
def test_no_single_node_is_total_dominating_set_of_star():
    G = gp.star_graph(3)
    for v in gp.nodes(G):
        assert gp.is_total_dominating_set(G, [v]) is False