I am surprised that networkx does not seem to have a built in function to do this, but maybe I am missing some clever way to do this using the built-in algorithms?
You can use one of these built in functions: enumerate_all_cliques or find_cliques in order to get all k-clique in an un-directed graph.
The difference between these functions is that enumerate_all_cliques
goes over all possible cliques and find_cliques
goes over only the maximal cliques. We will see in the end it affects the run time.
Option 1 using enumerate_all_cliques
:
import networkx as nx
def enumerate_all_cliques_size_k(G, k):
i = 0
for clique in nx.enumerate_all_cliques(G):
if len(clique) == k:
i += 1
elif len(clique) > k:
return i
return i
Option 2 using find_cliques
:
import networkx as nx
import itertools
def find_cliques_size_k(G, k):
i = 0
for clique in nx.find_cliques(G):
if len(clique) == k:
i += 1
elif len(clique) > k:
i += len(list(itertools.combinations(clique, k)))
return i
The first option is more straight forward but it's run time is problematic since we go over all possible sub-sets of the maximal cliques, even if the maximal clique size is less than k.
We can see enumerate_all_cliques_size_k
takes 10 times longer to run on a complete graph of size 20:
G = nx.complete_graph(20)
@timing
def test_enumerate_all_cliques_size_k(G,k):
print(enumerate_all_cliques_size_k(G, k))
@timing
def test_find_cliques_size_k(G, k):
print(find_cliques_size_k(G, k))
test_enumerate_all_cliques_size_k(G,5)
test_find_cliques_size_k(G,5)
# --------------------Result-----------------------
15504
test_enumerate_all_cliques_size_k function took 616.645 ms
15504
test_find_cliques_size_k function took 56.967 ms
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With