forked from networkx/networkx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
202 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,14 +17,88 @@ | |
# Pieter Swart <[email protected]> | ||
# All rights reserved. | ||
# BSD license. | ||
from collections import deque | ||
from itertools import chain, islice | ||
try: | ||
from itertools import ifilter as filter | ||
except ImportError: | ||
pass | ||
import networkx | ||
from networkx.utils.decorators import * | ||
__author__ = """Dan Schult ([email protected])""" | ||
__all__ = ['find_cliques', 'find_cliques_recursive', 'make_max_clique_graph', | ||
'make_clique_bipartite' ,'graph_clique_number', | ||
'graph_number_of_cliques', 'node_clique_number', | ||
'number_of_cliques', 'cliques_containing_node', | ||
'project_down', 'project_up'] | ||
'project_down', 'project_up', 'enumerate_all_cliques'] | ||
|
||
|
||
@not_implemented_for('directed') | ||
def enumerate_all_cliques(G): | ||
"""Returns all cliques in an undirected graph. | ||
This method returns cliques of size (cardinality) | ||
k = 1, 2, 3, ..., maxDegree - 1. | ||
Where maxDegree is the maximal degree of any node in the graph. | ||
Parameters | ||
---------- | ||
G: undirected graph | ||
Returns | ||
------- | ||
generator of lists: generator of list for each clique. | ||
Notes | ||
----- | ||
To obtain a list of all cliques, use | ||
:samp:`list(enumerate_all_cliques(G))`. | ||
Based on the algorithm published by Zhang et al. (2005) [1]_ | ||
and adapted to output all cliques discovered. | ||
This algorithm is not applicable on directed graphs. | ||
This algorithm ignores self-loops and parallel edges as | ||
clique is not conventionally defined with such edges. | ||
There are often many cliques in graphs. | ||
This algorithm however, hopefully, does not run out of memory | ||
since it only keeps candidate sublists in memory and | ||
continuously removes exhausted sublists. | ||
References | ||
---------- | ||
.. [1] Yun Zhang, Abu-Khzam, F.N., Baldwin, N.E., Chesler, E.J., | ||
Langston, M.A., Samatova, N.F., | ||
Genome-Scale Computational Approaches to Memory-Intensive | ||
Applications in Systems Biology. | ||
Supercomputing, 2005. Proceedings of the ACM/IEEE SC 2005 | ||
Conference, pp. 12, 12-18 Nov. 2005. | ||
doi: 10.1109/SC.2005.29. | ||
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1559964&isnumber=33129 | ||
""" | ||
index = {} | ||
nbrs = {} | ||
for u in G: | ||
index[u] = len(index) | ||
# Neighbors of u that appear after u in the iteration order of G. | ||
nbrs[u] = {v for v in G[u] if v not in index} | ||
|
||
queue = deque(([u], sorted(nbrs[u], key=index.__getitem__)) for u in G) | ||
# Loop invariants: | ||
# 1. len(base) is nondecreasing. | ||
# 2. (base + cnbrs) is sorted with respect to the iteration order of G. | ||
# 3. cnbrs is a set of common neighbors of nodes in base. | ||
while queue: | ||
base, cnbrs = map(list, queue.popleft()) | ||
yield base | ||
for i, u in enumerate(cnbrs): | ||
# Use generators to reduce memory consumption. | ||
queue.append((chain(base, [u]), | ||
filter(nbrs[u].__contains__, | ||
islice(cnbrs, i + 1, None)))) | ||
|
||
|
||
@not_implemented_for('directed') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters