| | """ |
| | Algorithm to find a maximal (not maximum) independent set. |
| | |
| | """ |
| |
|
| | import networkx as nx |
| | from networkx.utils import not_implemented_for, py_random_state |
| |
|
| | __all__ = ["maximal_independent_set"] |
| |
|
| |
|
| | @not_implemented_for("directed") |
| | @py_random_state(2) |
| | @nx._dispatchable |
| | def maximal_independent_set(G, nodes=None, seed=None): |
| | """Returns a random maximal independent set guaranteed to contain |
| | a given set of nodes. |
| | |
| | An independent set is a set of nodes such that the subgraph |
| | of G induced by these nodes contains no edges. A maximal |
| | independent set is an independent set such that it is not possible |
| | to add a new node and still get an independent set. |
| | |
| | Parameters |
| | ---------- |
| | G : NetworkX graph |
| | |
| | nodes : list or iterable |
| | Nodes that must be part of the independent set. This set of nodes |
| | must be independent. |
| | |
| | seed : integer, random_state, or None (default) |
| | Indicator of random number generation state. |
| | See :ref:`Randomness<randomness>`. |
| | |
| | Returns |
| | ------- |
| | indep_nodes : list |
| | List of nodes that are part of a maximal independent set. |
| | |
| | Raises |
| | ------ |
| | NetworkXUnfeasible |
| | If the nodes in the provided list are not part of the graph or |
| | do not form an independent set, an exception is raised. |
| | |
| | NetworkXNotImplemented |
| | If `G` is directed. |
| | |
| | Examples |
| | -------- |
| | >>> G = nx.path_graph(5) |
| | >>> nx.maximal_independent_set(G) # doctest: +SKIP |
| | [4, 0, 2] |
| | >>> nx.maximal_independent_set(G, [1]) # doctest: +SKIP |
| | [1, 3] |
| | |
| | Notes |
| | ----- |
| | This algorithm does not solve the maximum independent set problem. |
| | |
| | """ |
| | if not nodes: |
| | nodes = {seed.choice(list(G))} |
| | else: |
| | nodes = set(nodes) |
| | if not nodes.issubset(G): |
| | raise nx.NetworkXUnfeasible(f"{nodes} is not a subset of the nodes of G") |
| | neighbors = set.union(*[set(G.adj[v]) for v in nodes]) |
| | if set.intersection(neighbors, nodes): |
| | raise nx.NetworkXUnfeasible(f"{nodes} is not an independent set of G") |
| | indep_nodes = list(nodes) |
| | available_nodes = set(G.nodes()).difference(neighbors.union(nodes)) |
| | while available_nodes: |
| | node = seed.choice(list(available_nodes)) |
| | indep_nodes.append(node) |
| | available_nodes.difference_update(list(G.adj[node]) + [node]) |
| | return indep_nodes |
| |
|