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
132
venv/Lib/site-packages/networkx/algorithms/dominance.py
Normal file
132
venv/Lib/site-packages/networkx/algorithms/dominance.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
"""
|
||||
Dominance algorithms.
|
||||
"""
|
||||
|
||||
from functools import reduce
|
||||
import networkx as nx
|
||||
from networkx.utils import not_implemented_for
|
||||
|
||||
__all__ = ["immediate_dominators", "dominance_frontiers"]
|
||||
|
||||
|
||||
@not_implemented_for("undirected")
|
||||
def immediate_dominators(G, start):
|
||||
"""Returns the immediate dominators of all nodes of a directed graph.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : a DiGraph or MultiDiGraph
|
||||
The graph where dominance is to be computed.
|
||||
|
||||
start : node
|
||||
The start node of dominance computation.
|
||||
|
||||
Returns
|
||||
-------
|
||||
idom : dict keyed by nodes
|
||||
A dict containing the immediate dominators of each node reachable from
|
||||
`start`.
|
||||
|
||||
Raises
|
||||
------
|
||||
NetworkXNotImplemented
|
||||
If `G` is undirected.
|
||||
|
||||
NetworkXError
|
||||
If `start` is not in `G`.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Except for `start`, the immediate dominators are the parents of their
|
||||
corresponding nodes in the dominator tree.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
|
||||
>>> sorted(nx.immediate_dominators(G, 1).items())
|
||||
[(1, 1), (2, 1), (3, 1), (4, 3), (5, 1)]
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] K. D. Cooper, T. J. Harvey, and K. Kennedy.
|
||||
A simple, fast dominance algorithm.
|
||||
Software Practice & Experience, 4:110, 2001.
|
||||
"""
|
||||
if start not in G:
|
||||
raise nx.NetworkXError("start is not in G")
|
||||
|
||||
idom = {start: start}
|
||||
|
||||
order = list(nx.dfs_postorder_nodes(G, start))
|
||||
dfn = {u: i for i, u in enumerate(order)}
|
||||
order.pop()
|
||||
order.reverse()
|
||||
|
||||
def intersect(u, v):
|
||||
while u != v:
|
||||
while dfn[u] < dfn[v]:
|
||||
u = idom[u]
|
||||
while dfn[u] > dfn[v]:
|
||||
v = idom[v]
|
||||
return u
|
||||
|
||||
changed = True
|
||||
while changed:
|
||||
changed = False
|
||||
for u in order:
|
||||
new_idom = reduce(intersect, (v for v in G.pred[u] if v in idom))
|
||||
if u not in idom or idom[u] != new_idom:
|
||||
idom[u] = new_idom
|
||||
changed = True
|
||||
|
||||
return idom
|
||||
|
||||
|
||||
def dominance_frontiers(G, start):
|
||||
"""Returns the dominance frontiers of all nodes of a directed graph.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : a DiGraph or MultiDiGraph
|
||||
The graph where dominance is to be computed.
|
||||
|
||||
start : node
|
||||
The start node of dominance computation.
|
||||
|
||||
Returns
|
||||
-------
|
||||
df : dict keyed by nodes
|
||||
A dict containing the dominance frontiers of each node reachable from
|
||||
`start` as lists.
|
||||
|
||||
Raises
|
||||
------
|
||||
NetworkXNotImplemented
|
||||
If `G` is undirected.
|
||||
|
||||
NetworkXError
|
||||
If `start` is not in `G`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
|
||||
>>> sorted((u, sorted(df)) for u, df in nx.dominance_frontiers(G, 1).items())
|
||||
[(1, []), (2, [5]), (3, [5]), (4, [5]), (5, [])]
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] K. D. Cooper, T. J. Harvey, and K. Kennedy.
|
||||
A simple, fast dominance algorithm.
|
||||
Software Practice & Experience, 4:110, 2001.
|
||||
"""
|
||||
idom = nx.immediate_dominators(G, start)
|
||||
|
||||
df = {u: set() for u in idom}
|
||||
for u in idom:
|
||||
if len(G.pred[u]) >= 2:
|
||||
for v in G.pred[u]:
|
||||
if v in idom:
|
||||
while v != idom[u]:
|
||||
df[v].add(u)
|
||||
v = idom[v]
|
||||
return df
|
Loading…
Add table
Add a link
Reference in a new issue