Files
troupe-standup/wizard-work/beam/test_scc.py
T

43 lines
1.3 KiB
Python

import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from scc import scc
def tarjan_recursive(adj):
idx=[0]; stack=[]; on=set(); indices={}; low={}; res=[]
import sys as _s
_s.setrecursionlimit(100000)
def strong(v):
indices[v]=low[v]=idx[0]; idx[0]+=1; stack.append(v); on.add(v)
for w in adj.get(v,()):
if w not in indices:
strong(w); low[v]=min(low[v],low[w])
elif w in on: low[v]=min(low[v],indices[w])
if low[v]==indices[v]:
comp=[]
while True:
w=stack.pop(); on.discard(w); comp.append(w)
if w==v: break
res.append(comp)
for u in list(adj):
if u not in indices: strong(u)
return res
import random
random.seed(42)
for trial in range(200):
n=random.randint(1,40)
adj={i:[] for i in range(n)}
for i in range(n):
for j in range(n):
if random.random()<0.25: adj[i].append(j)
a=sorted(sorted(c) for c in scc(adj))
b=sorted(sorted(c) for c in tarjan_recursive(adj))
assert a==b, (a,b)
print("ALL 200 RANDOM TRIALS PASSED")
# big graph no recursion
N=200000
adj={i:[i+1] for i in range(N-1)}
adj[N-1]=[0]
r=scc(adj)
assert len(r)==1 and len(r[0])==N
print("BIG CYCLE OK", len(r[0]))