77093cb0b0
Add 21-vertex and 24-vertex examples showing recursive lopsidedness at d=2. Empirically confirm that the iterated algorithm (balanced switch when available, preprocess otherwise) drives every face to depth 0 on all tested configurations. Frame the remaining open question as identifying a strictly-decreasing monovariant under unbalanced preprocessing switches. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
"""Apply preprocessing surface switches to the 21-vertex depth-2 example
|
|
and check whether the new depth-2 face admits a balanced surface switch.
|
|
If not, iterate."""
|
|
import sys, os
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import math
|
|
import networkx as nx
|
|
from d2_balanced_existence import (
|
|
POS, n, OUTER_EDGES, outer_set, face_edges, compute_depths,
|
|
check_balanced, FACES as FACES0, CHORDS as CHORDS0
|
|
)
|
|
|
|
|
|
def apply_switch(faces, chords, uv, ux_vx):
|
|
"""Apply an edge switch removing edge uv and inserting edge wx.
|
|
`ux_vx` = (third-vertex-of-F = w, third-vertex-of-F' = x).
|
|
Returns (new_faces, new_chords).
|
|
Replaces the two old triangles uvw, uvx with the two new triangles
|
|
uwx, vwx.
|
|
"""
|
|
u, v = uv
|
|
w, x = ux_vx
|
|
new_chords = [c for c in chords if set(c) != {u, v}] + [tuple(sorted((w, x)))]
|
|
new_faces = []
|
|
for f in faces:
|
|
if set(f) == {u, v, w} or set(f) == {u, v, x}:
|
|
continue
|
|
new_faces.append(f)
|
|
new_faces.append(tuple(sorted((u, w, x))))
|
|
new_faces.append(tuple(sorted((v, w, x))))
|
|
return new_faces, new_chords
|
|
|
|
|
|
def find_third_vertices(faces, uv):
|
|
"""Find the two faces containing edge uv; return their third vertices."""
|
|
u, v = uv
|
|
thirds = []
|
|
for f in faces:
|
|
if u in f and v in f:
|
|
for vert in f:
|
|
if vert not in (u, v):
|
|
thirds.append(vert)
|
|
break
|
|
return thirds
|
|
|
|
|
|
def find_max_depth_face(faces, depth):
|
|
max_d = max(depth.values())
|
|
return [i for i, d in depth.items() if d == max_d][0], max_d
|
|
|
|
|
|
# Initial state
|
|
faces = list(FACES0)
|
|
chords = list(CHORDS0)
|
|
depth, _ = compute_depths(faces, outer_set)
|
|
F_idx, d = find_max_depth_face(faces, depth)
|
|
F = faces[F_idx]
|
|
print(f'Iter 0: F = {F}, depth = {d}')
|
|
|
|
for step in range(8):
|
|
ok, _, fp_idx, e = check_balanced(F_idx, faces, depth, outer_set)
|
|
if ok:
|
|
Fp = faces[fp_idx]
|
|
print(f' -> balanced switch exists on edge {tuple(e)}, F = {F}, '
|
|
f'F\' = {Fp}. STOP.')
|
|
break
|
|
|
|
# Pick any depth-(d-1) neighbour for preprocessing.
|
|
F_set = set(F)
|
|
fp_choice = None
|
|
for e_test in [frozenset((F[0], F[1])), frozenset((F[1], F[2])),
|
|
frozenset((F[0], F[2]))]:
|
|
if e_test in outer_set:
|
|
continue
|
|
cands = [j for j, fj in enumerate(faces)
|
|
if j != F_idx and e_test in face_edges(fj)]
|
|
if cands and depth[cands[0]] == d - 1:
|
|
fp_choice = (e_test, cands[0])
|
|
break
|
|
if fp_choice is None:
|
|
print(' no depth-(d-1) neighbour; cannot preprocess.')
|
|
break
|
|
|
|
e, fp_idx = fp_choice
|
|
Fp = faces[fp_idx]
|
|
u, v = tuple(e)
|
|
w = [vert for vert in F if vert != u and vert != v][0]
|
|
x = [vert for vert in Fp if vert != u and vert != v][0]
|
|
print(f' preprocessing switch: uv = ({u},{v}), w = {w}, x = {x}, '
|
|
f'F\' = {Fp}')
|
|
|
|
faces, chords = apply_switch(faces, chords, (u, v), (w, x))
|
|
depth, _ = compute_depths(faces, outer_set)
|
|
F_idx, d = find_max_depth_face(faces, depth)
|
|
F = faces[F_idx]
|
|
print(f'Iter {step + 1}: max-depth face = {F}, depth = {d}')
|
|
|
|
print('Done.')
|