-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathclique.py
More file actions
36 lines (28 loc) · 1 KB
/
clique.py
File metadata and controls
36 lines (28 loc) · 1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
"""Maximum clique / clique number via backtracking."""
from __future__ import annotations
from evaluation_function.schemas import Graph
from .utils import node_ids
def clique_number(graph: Graph) -> int:
"""Return the size of the largest clique in the graph."""
nodes = node_ids(graph)
n = len(nodes)
if n == 0:
return 0
adj: dict[str, set[str]] = {nid: set() for nid in nodes}
for e in graph.edges:
adj[e.source].add(e.target)
adj[e.target].add(e.source)
best = 1
def bt(clique: list[str], candidates: list[str]) -> None:
nonlocal best
if len(clique) + len(candidates) <= best:
return # pruning
if not candidates:
if len(clique) > best:
best = len(clique)
return
for i, v in enumerate(candidates):
new_cand = [u for u in candidates[i + 1:] if u in adj[v]]
bt(clique + [v], new_cand)
bt([], nodes)
return best