123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- """Functions for computing dominating sets in a graph."""
- from itertools import chain
- import networkx as nx
- from networkx.utils import arbitrary_element
- __all__ = ["dominating_set", "is_dominating_set"]
- def dominating_set(G, start_with=None):
- r"""Finds a dominating set for the graph G.
- A *dominating set* for a graph with node set *V* is a subset *D* of
- *V* such that every node not in *D* is adjacent to at least one
- member of *D* [1]_.
- Parameters
- ----------
- G : NetworkX graph
- start_with : node (default=None)
- Node to use as a starting point for the algorithm.
- Returns
- -------
- D : set
- A dominating set for G.
- Notes
- -----
- This function is an implementation of algorithm 7 in [2]_ which
- finds some dominating set, not necessarily the smallest one.
- See also
- --------
- is_dominating_set
- References
- ----------
- .. [1] https://en.wikipedia.org/wiki/Dominating_set
- .. [2] Abdol-Hossein Esfahanian. Connectivity Algorithms.
- http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
- """
- all_nodes = set(G)
- if start_with is None:
- start_with = arbitrary_element(all_nodes)
- if start_with not in G:
- raise nx.NetworkXError(f"node {start_with} is not in G")
- dominating_set = {start_with}
- dominated_nodes = set(G[start_with])
- remaining_nodes = all_nodes - dominated_nodes - dominating_set
- while remaining_nodes:
- # Choose an arbitrary node and determine its undominated neighbors.
- v = remaining_nodes.pop()
- undominated_neighbors = set(G[v]) - dominating_set
- # Add the node to the dominating set and the neighbors to the
- # dominated set. Finally, remove all of those nodes from the set
- # of remaining nodes.
- dominating_set.add(v)
- dominated_nodes |= undominated_neighbors
- remaining_nodes -= undominated_neighbors
- return dominating_set
- @nx._dispatch
- def is_dominating_set(G, nbunch):
- """Checks if `nbunch` is a dominating set for `G`.
- A *dominating set* for a graph with node set *V* is a subset *D* of
- *V* such that every node not in *D* is adjacent to at least one
- member of *D* [1]_.
- Parameters
- ----------
- G : NetworkX graph
- nbunch : iterable
- An iterable of nodes in the graph `G`.
- See also
- --------
- dominating_set
- References
- ----------
- .. [1] https://en.wikipedia.org/wiki/Dominating_set
- """
- testset = {n for n in nbunch if n in G}
- nbrs = set(chain.from_iterable(G[n] for n in testset))
- return len(set(G) - testset - nbrs) == 0
|