Example #1
0
def is_k_forcing_set(G, nodes, k):
    """Return whether or not the nodes in `nodes` comprise a *k*-forcing set in
    *G*.

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

    nodes : list, set
        An iterable container of nodes in G.

    k : int
        A positive integer.

    Returns
    -------
    boolean
        True if the nodes in `nodes` comprise a *k*-forcing set in *G*. False
        otherwise.
    """
    Z = set(n for n in nodes if n in G)
    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(G.nodes())
Example #2
0
def is_total_zero_forcing_set(G, nodes):
    """Return whether or not the nodes in `nodes` comprise a total zero forcing
    set in *G*.

    A *total zero forcing set* in a graph *G* is a zero forcing set that does
    not induce any isolated vertices.

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

    nodes : list, set
        An iterable container of nodes in G.

    Returns
    -------
    boolean
        True if the nodes in `nodes` comprise a total zero forcing set in *G*.
        False otherwise.
    """
    S = set(n for n in nodes if n in G)
    for v in S:
        if set(neighborhood(G, v)).intersection(S) == set():
            return False
    return is_zero_forcing_set(G, S)
Example #3
0
def is_k_forcing_vertex(G, v, nodes, k):
    """Return whether or not *v* can *k*-force relative to the set of nodes
    in `nodes`.

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

    v : node
        A single node in *G*.

    nodes : list, set
        An iterable container of nodes in G.

    k : int
        A positive integer.

    Returns
    -------
    boolean
        True if *v* can *k*-force relative to the nodes in `nodes`. False
        otherwise.
    """
    # 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.")
    S = set(n for n in nodes if n in G)
    n = len(set(neighborhood(G, v)).difference(S))
    return v in S and n >= 1 and n <= k
Example #4
0
def is_k_independent_set(G, nodes, k):
    """Return whether or not `nodes` is a k-independent set in G.
    A set *S* of nodes in *G* is called a *k-independent set* it every
    node in S has at most *k*-1 neighbors in S. Notice that a
    1-independent set is equivalent to an independent set.
    Parameters
    ----------
    G : NetworkX graph
        An undirected graph.
    nodes : list, set
        An iterable container of nodes in G.
    k : int
        A positive integer.
    Returns
    -------
    bool
        True if the nodes in *nodes* comprise a k-independent set, False
        otherwise.
    See Also
    --------
    is_independent_set
    """
    if k == 1:
        return is_independent_set(G, nodes)
    else:
        S = set(n for n in nodes if n in G)
        for v in S:
            N = set(neighborhood(G, v))
            if len(N.intersection(S)) >= k:
                return False
        return True
Example #5
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))
Example #6
0
def is_independent_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]
    S = set(nbunch)
    return set(neighborhood(G, S)).intersection(S) == set()
Example #7
0
def min_total_dominating_set_ilp(G):
    """Return a smallest total dominating set in the graph.

    This method solves an integer linear program in order to find a
    smallest total dominating set. It solves the following integer
    program: minimize

    .. math::

        \\sum_{v \\in V} x_v

    subject to

    ... math::

        \\sum_{u \\in N(v)} x_u \\geq 1 \\mathrm{ for all } v \\in V

    where *V* is the set of nodes of G and *N(v)* is the set of
    neighbors of the vertex *v*.

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

    Returns
    -------
    set
        A set 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)

    """
    prob = LpProblem('min_total_dominating_set', LpMinimize)
    variables = {
        node: LpVariable('x{}'.format(i+1), 0, 1, LpBinary)
        for i, node in enumerate(G.nodes())
    }

    # Set the total domination number objective function
    prob += lpSum([variables[n] for n in variables])

    # Set constraints
    for node in G.nodes():
        combination = [
            variables[n]
            for n in variables if n in neighborhood(G, node)
        ]
        prob += lpSum(combination) >= 1

    prob.solve()
    solution_set = {node for node in variables if variables[node].value() == 1}
    return solution_set
Example #8
0
def is_k_forcing_vertex(G, v, nbunch, k):
    # TODO: Add documentation
    # TODO: add check that k >= 1
    # check if nbunch is an iterable; if not, convert to a list
    try:
        _ = (v for v in nbunch)
    except:
        nbunch = [nbunch]
    S = set(nbunch)
    n = len(set(neighborhood(G, v)).difference(S))
    return v in S and n >= 1 and n <= k
Example #9
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))
Example #10
0
def is_k_independent_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]
    if k == 1:
        return is_independent_set(G, nbunch)
    else:
        for v in nbunch:
            N = set(neighborhood(G, v))
            if len(N.intersection(nbunch)) >= k:
                return False
        return True
Example #11
0
def is_k_dominating_set(G, nodes, k):
    """Return whether or not nodes comprises a k-dominating set.

    A *k-dominating set* is a set of nodes with the property that every
    node in the graph is either in the set or adjacent at least 1 and at
    most k nodes in the set.

    This is a generalization of the well known concept of a dominating
    set (take k = 1).

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

    nodes : list, set
        An iterable container of nodes in G.

    k : int
        A positive integer.

    Returns
    -------
    boolean
        True if the nodes in nbunch comprise a k-dominating set, and
        False otherwise.

    """
    # 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.")
    # check if nbunch is an iterable; if not, convert to a list
    S = set(n for n in nodes if n in G)
    if k == 1:
        return is_dominating_set(G, S)
    else:
        # loop through the nodes in the complement of S and determine
        # if they are adjacent to atleast k nodes in S
        others = set(G.nodes()).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
Example #12
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
Example #13
0
 def test_neighborhood(self):
     G = self.G
     N0 = gp.neighborhood(G, 0)
     N1 = gp.neighborhood(G, 1)
     N2 = gp.neighborhood(G, 2)
     N3 = gp.neighborhood(G, 3)
     N4 = gp.neighborhood(G, 4)
     N5 = gp.neighborhood(G, 5)
     assert N0 == [1, 2, 3]
     assert N1 == [0, 2]
     assert N2 == [0, 1]
     assert N3 == [0, 4, 5]
     assert N4 == [3]
     assert N5 == [3]
def degree(G, x):
    return len(neighborhood(G, x))