2024 day 23.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Mikaël Capelle
2024-12-23 11:35:42 +01:00
parent b9341bdecc
commit 77b24dd148
4 changed files with 3511 additions and 2 deletions

View File

@@ -1,5 +1,13 @@
import heapq
from typing import Callable, Iterable, TypeVar, overload
from typing import (
Callable,
Iterable,
Iterator,
Mapping,
TypeVar,
cast,
overload,
)
_Node = TypeVar("_Node")
@@ -116,3 +124,63 @@ def dijkstra(
return preds
return preds.get(target, None)
def iter_max_cliques(
neighbors: Mapping[_Node, Iterable[_Node]], nodes: Iterable[_Node] | None = None
) -> Iterator[list[_Node]]:
"""
Find max cliques from the given set of neighbors containing the given set of nodes.
This is simply the networkx implementation with typing (and using a simple mapping
to avoid requiring networkx).
"""
if len(neighbors) == 0:
return
# remove the node itself from the neighbors
adj = {u: {v for v in neighbors[u] if v != u} for u in neighbors}
# Initialize Q with the given nodes and subg, cand with their nbrs
Q: list[_Node | None] = list(nodes or [])
cand = set(neighbors)
for node in Q:
if node not in cand:
raise ValueError(f"The given `nodes` {nodes} do not form a clique")
cand &= adj[node]
if not cand:
yield cast(list[_Node], Q[:])
return
subg = cand.copy()
stack: list[tuple[set[_Node], set[_Node], set[_Node]]] = []
Q.append(None)
u = max(subg, key=lambda u: len(cand & adj[u]))
ext_u = cand - adj[u]
try:
while True:
if ext_u:
q = ext_u.pop()
cand.remove(q)
Q[-1] = q
adj_q = adj[q]
subg_q = subg & adj_q
if not subg_q:
yield cast(list[_Node], Q[:])
else:
cand_q = cand & adj_q
if cand_q:
stack.append((subg, cand, ext_u))
Q.append(None)
subg = subg_q
cand = cand_q
u = max(subg, key=lambda u: len(cand & adj[u]))
ext_u = cand - adj[u]
else:
Q.pop()
subg, cand, ext_u = stack.pop()
except IndexError:
pass