Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
168
venv/Lib/site-packages/networkx/algorithms/asteroidal.py
Normal file
168
venv/Lib/site-packages/networkx/algorithms/asteroidal.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
"""
|
||||
Algorithms for asteroidal triples and asteroidal numbers in graphs.
|
||||
|
||||
An asteroidal triple in a graph G is a set of three non-adjacent vertices
|
||||
u, v and w such that there exist a path between any two of them that avoids
|
||||
closed neighborhood of the third. More formally, v_j, v_k belongs to the same
|
||||
connected component of G - N[v_i], where N[v_i] denotes the closed neighborhood
|
||||
of v_i. A graph which does not contain any asteroidal triples is called
|
||||
an AT-free graph. The class of AT-free graphs is a graph class for which
|
||||
many NP-complete problems are solvable in polynomial time. Amongst them,
|
||||
independent set and coloring.
|
||||
"""
|
||||
import networkx as nx
|
||||
from networkx.utils import not_implemented_for
|
||||
|
||||
__all__ = ["is_at_free", "find_asteroidal_triple"]
|
||||
|
||||
|
||||
@not_implemented_for("directed")
|
||||
@not_implemented_for("multigraph")
|
||||
def find_asteroidal_triple(G):
|
||||
r"""Find an asteroidal triple in the given graph.
|
||||
|
||||
An asteroidal triple is a triple of non-adjacent vertices such that
|
||||
there exists a path between any two of them which avoids the closed
|
||||
neighborhood of the third. It checks all independent triples of vertices
|
||||
and whether they are an asteroidal triple or not. This is done with the
|
||||
help of a data structure called a component structure.
|
||||
A component structure encodes information about which vertices belongs to
|
||||
the same connected component when the closed neighborhood of a given vertex
|
||||
is removed from the graph. The algorithm used to check is the trivial
|
||||
one, outlined in [1]_, which has a runtime of
|
||||
:math:`O(|V||\overline{E} + |V||E|)`, where the second term is the
|
||||
creation of the component structure.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX Graph
|
||||
The graph to check whether is AT-free or not
|
||||
|
||||
Returns
|
||||
-------
|
||||
list or None
|
||||
An asteroidal triple is returned as a list of nodes. If no asteroidal
|
||||
triple exists, i.e. the graph is AT-free, then None is returned.
|
||||
The returned value depends on the certificate parameter. The default
|
||||
option is a bool which is True if the graph is AT-free, i.e. the
|
||||
given graph contains no asteroidal triples, and False otherwise, i.e.
|
||||
if the graph contains at least one asteroidal triple.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The component structure and the algorithm is described in [1]_. The current
|
||||
implementation implements the trivial algorithm for simple graphs.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Ekkehard Köhler,
|
||||
"Recognizing Graphs without asteroidal triples",
|
||||
Journal of Discrete Algorithms 2, pages 439-452, 2004.
|
||||
https://www.sciencedirect.com/science/article/pii/S157086670400019X
|
||||
"""
|
||||
V = set(G.nodes)
|
||||
|
||||
if len(V) < 6:
|
||||
# An asteroidal triple cannot exist in a graph with 5 or less vertices.
|
||||
return None
|
||||
|
||||
component_structure = create_component_structure(G)
|
||||
E_complement = set(nx.complement(G).edges)
|
||||
|
||||
for e in E_complement:
|
||||
u = e[0]
|
||||
v = e[1]
|
||||
u_neighborhood = set(G[u]).union([u])
|
||||
v_neighborhood = set(G[v]).union([v])
|
||||
union_of_neighborhoods = u_neighborhood.union(v_neighborhood)
|
||||
for w in V - union_of_neighborhoods:
|
||||
"""Check for each pair of vertices whether they belong to the
|
||||
same connected component when the closed neighborhood of the
|
||||
third is removed."""
|
||||
if (
|
||||
component_structure[u][v] == component_structure[u][w]
|
||||
and component_structure[v][u] == component_structure[v][w]
|
||||
and component_structure[w][u] == component_structure[w][v]
|
||||
):
|
||||
return [u, v, w]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@not_implemented_for("directed")
|
||||
@not_implemented_for("multigraph")
|
||||
def is_at_free(G):
|
||||
"""Check if a graph is AT-free.
|
||||
|
||||
The method uses the `find_asteroidal_triple` method to recognize
|
||||
an AT-free graph. If no asteroidal triple is found the graph is
|
||||
AT-free and True is returned. If at least one asteroidal triple is
|
||||
found the graph is not AT-free and False is returned.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX Graph
|
||||
The graph to check whether is AT-free or not.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if G is AT-free and False otherwise.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> G = nx.Graph([(0, 1), (0, 2), (1, 2), (1, 3), (1, 4), (4, 5)])
|
||||
>>> nx.is_at_free(G)
|
||||
True
|
||||
|
||||
>>> G = nx.cycle_graph(6)
|
||||
>>> nx.is_at_free(G)
|
||||
False
|
||||
"""
|
||||
return find_asteroidal_triple(G) is None
|
||||
|
||||
|
||||
@not_implemented_for("directed")
|
||||
@not_implemented_for("multigraph")
|
||||
def create_component_structure(G):
|
||||
r"""Create component structure for G.
|
||||
|
||||
A *component structure* is an `nxn` array, denoted `c`, where `n` is
|
||||
the number of vertices, where each row and column corresponds to a vertex.
|
||||
|
||||
.. math::
|
||||
c_{uv} = \begin{cases} 0, if v \in N[u] \\
|
||||
k, if v \in component k of G \setminus N[u] \end{cases}
|
||||
|
||||
Where `k` is an arbitrary label for each component. The structure is used
|
||||
to simplify the detection of asteroidal triples.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX Graph
|
||||
Undirected, simple graph.
|
||||
|
||||
Returns
|
||||
-------
|
||||
component_structure : dictionary
|
||||
A dictionary of dictionaries, keyed by pairs of vertices.
|
||||
|
||||
"""
|
||||
V = set(G.nodes)
|
||||
component_structure = {}
|
||||
for v in V:
|
||||
label = 0
|
||||
closed_neighborhood = set(G[v]).union({v})
|
||||
row_dict = {}
|
||||
for u in closed_neighborhood:
|
||||
row_dict[u] = 0
|
||||
|
||||
G_reduced = G.subgraph(set(G.nodes) - closed_neighborhood)
|
||||
for cc in nx.connected_components(G_reduced):
|
||||
label += 1
|
||||
for u in cc:
|
||||
row_dict[u] = label
|
||||
|
||||
component_structure[v] = row_dict
|
||||
|
||||
return component_structure
|
Loading…
Add table
Add a link
Reference in a new issue