Add Level Switching paper with surface-switch framework
Defines level cycles, edge switches, surface switches, and facial depth on level components of plane triangulations. Proves outerplanarity of level components and a depth-descent lemma. Introduces balanced surface switches and proves they remove a depth-d level cycle while creating 1-2 new depth-(d-1) cycles. Documents the 9-vertex counterexample where no balanced switch exists and sketches preprocessing toward balancedness, leaving general termination open. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@@ -0,0 +1,98 @@
|
||||
"""9-vertex L_k where the unique depth-1 face has NO balanced surface switch.
|
||||
|
||||
Outer cycle: 0..8. Triangulated with chords 0-2, 0-3, 3-5, 3-6, 0-6, 6-8.
|
||||
Central triangle F = (0,3,6) has depth 1; its three neighbours
|
||||
(0,2,3), (3,5,6), (6,8,0) are all depth 0 but each has only ONE
|
||||
outer-cycle edge (not two), so none is an "ear" of F.
|
||||
|
||||
For d = 1, balancedness requires F' to be an ear of uv (both non-uv
|
||||
edges on the outer cycle). No neighbour of F qualifies.
|
||||
"""
|
||||
import os
|
||||
import math
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Polygon
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
|
||||
|
||||
n = 9
|
||||
POS = {i: (math.cos(math.radians(90 - i * 360 / n)),
|
||||
math.sin(math.radians(90 - i * 360 / n))) for i in range(n)}
|
||||
OUTER_EDGES = [(i, (i + 1) % n) for i in range(n)]
|
||||
CHORDS = [(0, 2), (0, 3), (3, 5), (3, 6), (0, 6), (6, 8)]
|
||||
|
||||
FACES = [
|
||||
(0, 1, 2), # ear
|
||||
(0, 2, 3), # 1 outer edge, depth 0
|
||||
(3, 4, 5), # ear
|
||||
(3, 5, 6), # 1 outer edge, depth 0
|
||||
(6, 7, 8), # ear
|
||||
(6, 8, 0), # 1 outer edge, depth 0
|
||||
(0, 3, 6), # central, depth 1 -- the troublemaker
|
||||
]
|
||||
|
||||
|
||||
def face_edges(f):
|
||||
return {frozenset((f[0], f[1])), frozenset((f[1], f[2])),
|
||||
frozenset((f[0], f[2]))}
|
||||
|
||||
|
||||
outer_set = {frozenset(e) for e in OUTER_EDGES}
|
||||
|
||||
D = nx.Graph()
|
||||
D.add_nodes_from(range(len(FACES)))
|
||||
for i, fi in enumerate(FACES):
|
||||
for j, fj in enumerate(FACES):
|
||||
if i < j and face_edges(fi) & face_edges(fj):
|
||||
D.add_edge(i, j)
|
||||
|
||||
B = [i for i, f in enumerate(FACES)
|
||||
if len(face_edges(f) & outer_set) >= 1]
|
||||
depth = {i: min(nx.shortest_path_length(D, i, b) for b in B)
|
||||
for i in range(len(FACES))}
|
||||
|
||||
palette = {0: '#86efac', 1: '#fde68a', 2: '#fca5a5'}
|
||||
edge_pal = {0: '#16a34a', 1: '#d97706', 2: '#dc2626'}
|
||||
|
||||
fig, ax = plt.subplots(figsize=(7, 7))
|
||||
for i, f in enumerate(FACES):
|
||||
d = depth[i]
|
||||
poly = Polygon([POS[v] for v in f], closed=True,
|
||||
facecolor=palette[d], edgecolor=edge_pal[d],
|
||||
linewidth=1.6, alpha=0.7, zorder=0)
|
||||
ax.add_patch(poly)
|
||||
cx = sum(POS[v][0] for v in f) / 3
|
||||
cy = sum(POS[v][1] for v in f) / 3
|
||||
ax.text(cx, cy, rf'$\mathrm{{depth}}={d}$',
|
||||
ha='center', va='center', fontsize=10,
|
||||
color=edge_pal[d], fontweight='bold')
|
||||
|
||||
# Mark the three "bad" chord edges (would-be-switched edges of F that
|
||||
# fail balancedness because the chord side has no outer-cycle edge to
|
||||
# pair with).
|
||||
F_edges = [(0, 3), (3, 6), (0, 6)]
|
||||
for (a, b) in OUTER_EDGES + CHORDS:
|
||||
color = '#333'; lw = 1.2
|
||||
if (a, b) in F_edges or (b, a) in F_edges:
|
||||
color = '#dc2626'; lw = 3.0
|
||||
ax.plot([POS[a][0], POS[b][0]], [POS[a][1], POS[b][1]],
|
||||
color=color, linewidth=lw, zorder=1)
|
||||
|
||||
for i, (x, y) in POS.items():
|
||||
ax.scatter([x], [y], s=300, c='#1f2937', edgecolors='black',
|
||||
linewidths=1.0, zorder=2)
|
||||
ax.text(x, y, str(i), ha='center', va='center',
|
||||
fontsize=10, color='white', fontweight='bold', zorder=3)
|
||||
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_xlim(-1.3, 1.3); ax.set_ylim(-1.3, 1.3)
|
||||
ax.set_title('Depth-1 face with no balanced surface switch',
|
||||
fontsize=12)
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_no_balanced_switch.png')
|
||||
fig.savefig(out, dpi=180, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
for i, f in enumerate(FACES):
|
||||
print(f' {f} -> depth {depth[i]}')
|
||||
@@ -0,0 +1,179 @@
|
||||
"""Counterexample showing that a surface switch on the edge between a
|
||||
depth-d face F and a depth-(d-1) face F' can create a new face of depth
|
||||
d (not d-1) when the depth-0 neighbor of F' lies on only one side of
|
||||
the shared edge.
|
||||
|
||||
14-vertex maximal outerplanar L_k. Outer cycle order:
|
||||
u, p1, p2, p3, x, q1, v, b1, b2, b3, w, a1, a2, a3 -> u
|
||||
|
||||
Central triangle F = (u, v, w) has depth 2.
|
||||
F' = (u, v, x) has depth 1 (its depth-0 neighbor is the q1-ear on the
|
||||
v-side of x; its u-side neighbor A_ux is depth 1).
|
||||
A_uw = (u, a2, w), A_vw = (v, b2, w) are both depth 1.
|
||||
|
||||
Surface switch on uv: flip uv -> wx. New faces are
|
||||
A = (u, w, x) and B = (v, w, x).
|
||||
B inherits the depth-0 q1-ear, so depth(B) = 1.
|
||||
A's neighbors are A_uw (1), A_ux (1), B (1), so depth(A) = 2 = d. BAD.
|
||||
"""
|
||||
import os
|
||||
import math
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Polygon
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
|
||||
|
||||
OUTER = ['u', 'p1', 'p2', 'p3', 'x', 'q1', 'v',
|
||||
'b1', 'b2', 'b3', 'w', 'a1', 'a2', 'a3']
|
||||
n = len(OUTER)
|
||||
|
||||
POS = {}
|
||||
for i, name in enumerate(OUTER):
|
||||
a = math.radians(90 - i * (360 / n))
|
||||
POS[name] = (math.cos(a), math.sin(a))
|
||||
|
||||
OUTER_EDGES = [(OUTER[i], OUTER[(i + 1) % n]) for i in range(n)]
|
||||
|
||||
CHORDS_BEFORE = [
|
||||
('u', 'v'), ('u', 'w'), ('v', 'w'), # central F = (u,v,w)
|
||||
('u', 'x'), ('v', 'x'), # F' = (u,v,x)
|
||||
('u', 'a2'), ('a2', 'w'), # A_uw = (u,a2,w)
|
||||
('v', 'b2'), ('b2', 'w'), # A_vw = (v,b2,w)
|
||||
('u', 'p2'), ('p2', 'x'), # A_ux = (u,p2,x)
|
||||
]
|
||||
|
||||
CHORDS_AFTER = [c for c in CHORDS_BEFORE if set(c) != {'u', 'v'}] + [('w', 'x')]
|
||||
|
||||
FACES_BEFORE = [
|
||||
('u', 'v', 'w'), # F (depth 2 -- bad)
|
||||
('u', 'v', 'x'), # F' (depth 1)
|
||||
('u', 'a2', 'w'), # A_uw (depth 1)
|
||||
('v', 'b2', 'w'), # A_vw (depth 1)
|
||||
('u', 'p2', 'x'), # A_ux (depth 1)
|
||||
('v', 'q1', 'x'), # A_vx (depth 0)
|
||||
('u', 'a1', 'a2'), # depth 0
|
||||
('a2', 'a3', 'w'), # depth 0
|
||||
('v', 'b1', 'b2'), # depth 0
|
||||
('b2', 'b3', 'w'), # depth 0
|
||||
('u', 'p1', 'p2'), # depth 0
|
||||
('p2', 'p3', 'x'), # depth 0
|
||||
]
|
||||
|
||||
FACES_AFTER = [
|
||||
('u', 'w', 'x'), # A (depth 2 -- still bad!)
|
||||
('v', 'w', 'x'), # B (depth 1)
|
||||
('u', 'a2', 'w'),
|
||||
('v', 'b2', 'w'),
|
||||
('u', 'p2', 'x'),
|
||||
('v', 'q1', 'x'),
|
||||
('u', 'a1', 'a2'),
|
||||
('a2', 'a3', 'w'),
|
||||
('v', 'b1', 'b2'),
|
||||
('b2', 'b3', 'w'),
|
||||
('u', 'p1', 'p2'),
|
||||
('p2', 'p3', 'x'),
|
||||
]
|
||||
|
||||
|
||||
def compute_depths(faces, chords):
|
||||
"""Compute facial depth for each face using threshold-1 definition."""
|
||||
outer_set = {frozenset(e) for e in OUTER_EDGES}
|
||||
|
||||
def face_edges(f):
|
||||
return {frozenset((f[0], f[1])), frozenset((f[1], f[2])),
|
||||
frozenset((f[0], f[2]))}
|
||||
|
||||
# Build inner-face dual
|
||||
D = nx.Graph()
|
||||
D.add_nodes_from(range(len(faces)))
|
||||
for i, fi in enumerate(faces):
|
||||
for j, fj in enumerate(faces):
|
||||
if i < j and face_edges(fi) & face_edges(fj):
|
||||
D.add_edge(i, j)
|
||||
|
||||
B = [i for i, f in enumerate(faces)
|
||||
if len(face_edges(f) & outer_set) >= 1]
|
||||
|
||||
depth = {}
|
||||
for i in range(len(faces)):
|
||||
if not B:
|
||||
depth[i] = float('inf')
|
||||
continue
|
||||
depth[i] = min(nx.shortest_path_length(D, i, b) for b in B)
|
||||
return depth
|
||||
|
||||
|
||||
def draw_panel(ax, faces, chords, depth, title, highlight_edge=None,
|
||||
highlight_face=None):
|
||||
palette = {0: '#86efac', 1: '#fde68a', 2: '#fca5a5'}
|
||||
edge_pal = {0: '#16a34a', 1: '#d97706', 2: '#dc2626'}
|
||||
|
||||
for i, f in enumerate(faces):
|
||||
d = depth[i]
|
||||
face_color = palette.get(d, '#ddd')
|
||||
face_edge = edge_pal.get(d, '#333')
|
||||
lw = 1.4
|
||||
if highlight_face is not None and i == highlight_face:
|
||||
face_edge = '#7c2d12'
|
||||
lw = 3.0
|
||||
poly = Polygon([POS[v] for v in f], closed=True,
|
||||
facecolor=face_color, edgecolor=face_edge,
|
||||
linewidth=lw, alpha=0.7, zorder=0)
|
||||
ax.add_patch(poly)
|
||||
cx = sum(POS[v][0] for v in f) / 3
|
||||
cy = sum(POS[v][1] for v in f) / 3
|
||||
ax.text(cx, cy, str(d), ha='center', va='center', fontsize=11,
|
||||
color=edge_pal.get(d, '#333'), fontweight='bold')
|
||||
|
||||
# Draw edges
|
||||
all_edges = OUTER_EDGES + list(chords)
|
||||
for (a, b) in all_edges:
|
||||
color = '#333'; lw = 1.2
|
||||
if highlight_edge is not None and {a, b} == set(highlight_edge):
|
||||
color = '#dc2626'; lw = 3.5
|
||||
elif (a, b) == ('w', 'x') or (a, b) == ('x', 'w'):
|
||||
color = '#16a34a'; lw = 3.0
|
||||
ax.plot([POS[a][0], POS[b][0]], [POS[a][1], POS[b][1]],
|
||||
color=color, linewidth=lw, zorder=1)
|
||||
|
||||
# Draw vertices
|
||||
for name, (x, y) in POS.items():
|
||||
ax.scatter([x], [y], s=260, c='#1f2937', edgecolors='black',
|
||||
linewidths=0.8, zorder=2)
|
||||
ax.text(x, y, name, ha='center', va='center',
|
||||
fontsize=8, color='white', fontweight='bold', zorder=3)
|
||||
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_xlim(-1.35, 1.35); ax.set_ylim(-1.35, 1.35)
|
||||
ax.set_title(title, fontsize=12)
|
||||
|
||||
|
||||
def main():
|
||||
depth_before = compute_depths(FACES_BEFORE, CHORDS_BEFORE)
|
||||
depth_after = compute_depths(FACES_AFTER, CHORDS_AFTER)
|
||||
|
||||
print("BEFORE:")
|
||||
for i, f in enumerate(FACES_BEFORE):
|
||||
print(f" {f} -> depth {depth_before[i]}")
|
||||
print("AFTER:")
|
||||
for i, f in enumerate(FACES_AFTER):
|
||||
print(f" {f} -> depth {depth_after[i]}")
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(15, 7.5))
|
||||
draw_panel(axes[0], FACES_BEFORE, CHORDS_BEFORE, depth_before,
|
||||
r'Before: $F=(u,v,w)$ depth 2, $F\'=(u,v,x)$ depth 1',
|
||||
highlight_edge=('u', 'v'), highlight_face=0)
|
||||
draw_panel(axes[1], FACES_AFTER, CHORDS_AFTER, depth_after,
|
||||
r'After surface switch on $uv$: $A=(u,w,x)$ still depth 2!',
|
||||
highlight_face=0)
|
||||
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_counterexample_surface_switch.png')
|
||||
fig.savefig(out, dpi=180, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,370 @@
|
||||
"""Generate the three definition figures for the Level Switching paper.
|
||||
|
||||
Uses a stacked 7-vertex triangulation T:
|
||||
outer triangle {0,1,2}, inner vertex 3 connected to all three,
|
||||
then vertices 4,5,6 inserted into faces (1,2,3),(0,2,3),(0,1,3).
|
||||
"""
|
||||
import os
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Polygon
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
|
||||
|
||||
# Vertex positions (hand-placed for a clean planar drawing).
|
||||
POS = {
|
||||
0: (-1.5, -0.9),
|
||||
1: (1.5, -0.9),
|
||||
2: (0.0, 1.6),
|
||||
3: (0.0, 0.0),
|
||||
4: (0.55, 0.2), # in face (1,2,3)
|
||||
5: (-0.55, 0.2), # in face (0,2,3)
|
||||
6: (0.0, -0.55), # in face (0,1,3)
|
||||
}
|
||||
|
||||
EDGES = [
|
||||
(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3), # K_4
|
||||
(4, 1), (4, 2), (4, 3), # stack in (1,2,3)
|
||||
(5, 0), (5, 2), (5, 3), # stack in (0,2,3)
|
||||
(6, 0), (6, 1), (6, 3), # stack in (0,1,3)
|
||||
]
|
||||
|
||||
|
||||
def make_graph():
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from(POS.keys())
|
||||
G.add_edges_from(EDGES)
|
||||
return G
|
||||
|
||||
|
||||
def draw_base(ax, G, node_colors, node_size=520, font_color='white',
|
||||
edge_color='#555', edge_width=1.4):
|
||||
nx.draw_networkx_edges(G, POS, ax=ax, edge_color=edge_color, width=edge_width)
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=node_colors,
|
||||
node_size=node_size, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(G, POS, ax=ax, font_color=font_color,
|
||||
font_size=11, font_weight='bold')
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure 1: Level source (face source vs. degree-3 vertex source)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_level_source():
|
||||
G = make_graph()
|
||||
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
|
||||
|
||||
# Panel A: face source S = {0,1,2}
|
||||
ax = axes[0]
|
||||
face_S = {0, 1, 2}
|
||||
colors = ['#ef4444' if v in face_S else '#cbd5e1' for v in G.nodes()]
|
||||
# Highlight the source face
|
||||
tri = Polygon([POS[v] for v in [0, 1, 2]], closed=True,
|
||||
facecolor='#fecaca', edgecolor='#ef4444', linewidth=2.0,
|
||||
alpha=0.45, zorder=0)
|
||||
ax.add_patch(tri)
|
||||
draw_base(ax, G, colors)
|
||||
ax.set_title(r'Face source $S = \{0,1,2\}$', fontsize=12)
|
||||
|
||||
# Panel B: degree-3 vertex source S = {4}
|
||||
ax = axes[1]
|
||||
vert_S = {4}
|
||||
colors = ['#ef4444' if v in vert_S else '#cbd5e1' for v in G.nodes()]
|
||||
draw_base(ax, G, colors)
|
||||
ax.set_title(r'Degree-3 vertex source $S = \{4\}$', fontsize=12)
|
||||
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_level_source.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure 2: Levels (BFS distance from a source)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_levels():
|
||||
G = make_graph()
|
||||
source = 4 # degree-3 vertex source
|
||||
levels = nx.single_source_shortest_path_length(G, source)
|
||||
|
||||
# Color by level
|
||||
palette = {0: '#ef4444', 1: '#f59e0b', 2: '#3b82f6'}
|
||||
colors = [palette[levels[v]] for v in G.nodes()]
|
||||
|
||||
# Labels = level numbers
|
||||
labels = {v: rf'$\ell={levels[v]}$' for v in G.nodes()}
|
||||
|
||||
fig, ax = plt.subplots(figsize=(6.5, 5.5))
|
||||
nx.draw_networkx_edges(G, POS, ax=ax, edge_color='#555', width=1.4)
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=colors,
|
||||
node_size=720, edgecolors='black', linewidths=1.0)
|
||||
# Draw vertex id slightly above, level label inside
|
||||
for v, (x, y) in POS.items():
|
||||
ax.text(x, y, str(v), ha='center', va='center',
|
||||
fontsize=10, fontweight='bold', color='white')
|
||||
ax.text(x + 0.18, y + 0.18, rf'$\ell={levels[v]}$',
|
||||
fontsize=10, color='black',
|
||||
bbox=dict(boxstyle='round,pad=0.15',
|
||||
facecolor='white', edgecolor='#999', linewidth=0.6))
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title(r'Levels $\ell_G(v)$ from source $S=\{4\}$', fontsize=12)
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_levels.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure 3: Parity subgraph (even and odd induced subgraphs)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_parity_subgraph():
|
||||
G = make_graph()
|
||||
source = 4
|
||||
levels = nx.single_source_shortest_path_length(G, source)
|
||||
parity = {v: levels[v] % 2 for v in G.nodes()}
|
||||
|
||||
even = [v for v in G.nodes() if parity[v] == 0]
|
||||
odd = [v for v in G.nodes() if parity[v] == 1]
|
||||
even_color = '#3b82f6' # blue
|
||||
odd_color = '#f59e0b' # orange
|
||||
|
||||
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
|
||||
|
||||
# Panel A: full triangulation, vertices coloured by parity
|
||||
ax = axes[0]
|
||||
colors = [even_color if parity[v] == 0 else odd_color for v in G.nodes()]
|
||||
draw_base(ax, G, colors)
|
||||
ax.set_title(r"$G'$ with vertices coloured by $\ell_G$ mod 2", fontsize=12)
|
||||
|
||||
# Panel B: even parity subgraph (induced on even vertices)
|
||||
ax = axes[1]
|
||||
# Draw all edges faintly, then the induced subgraph in colour
|
||||
nx.draw_networkx_edges(G, POS, ax=ax, edge_color='#ddd', width=1.0)
|
||||
even_sub = G.subgraph(even)
|
||||
nx.draw_networkx_edges(even_sub, POS, ax=ax, edge_color=even_color, width=2.4)
|
||||
node_colors = [even_color if v in even else '#e5e7eb' for v in G.nodes()]
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=node_colors,
|
||||
node_size=520, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(G, POS, ax=ax,
|
||||
font_color='white', font_size=11, font_weight='bold')
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title(r"Even parity subgraph $E_{G,S}(G')$", fontsize=12)
|
||||
|
||||
# Panel C: odd parity subgraph
|
||||
ax = axes[2]
|
||||
nx.draw_networkx_edges(G, POS, ax=ax, edge_color='#ddd', width=1.0)
|
||||
odd_sub = G.subgraph(odd)
|
||||
nx.draw_networkx_edges(odd_sub, POS, ax=ax, edge_color=odd_color, width=2.4)
|
||||
node_colors = [odd_color if v in odd else '#e5e7eb' for v in G.nodes()]
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=node_colors,
|
||||
node_size=520, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(G, POS, ax=ax,
|
||||
font_color='white', font_size=11, font_weight='bold')
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title(r"Odd parity subgraph $O_{G,S}(G')$", fontsize=12)
|
||||
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_parity_subgraph.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure: Level cycle (simple cycle within a single level)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_level_cycle():
|
||||
G = make_graph()
|
||||
source = 4
|
||||
levels = nx.single_source_shortest_path_length(G, source)
|
||||
|
||||
palette = {0: '#ef4444', 1: '#f59e0b', 2: '#3b82f6'}
|
||||
colors = [palette[levels[v]] for v in G.nodes()]
|
||||
|
||||
# Level cycle: 1-2-3-1 lies entirely in L_1
|
||||
cycle_edges = [(1, 2), (2, 3), (1, 3)]
|
||||
|
||||
fig, ax = plt.subplots(figsize=(6.5, 5.5))
|
||||
nx.draw_networkx_edges(G, POS, ax=ax, edge_color='#bbb', width=1.2)
|
||||
nx.draw_networkx_edges(G, POS, edgelist=cycle_edges, ax=ax,
|
||||
edge_color='#dc2626', width=3.4)
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=colors,
|
||||
node_size=620, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(G, POS, ax=ax, font_color='white',
|
||||
font_size=11, font_weight='bold')
|
||||
# Annotate levels in small floating labels
|
||||
for v, (x, y) in POS.items():
|
||||
ax.text(x + 0.18, y + 0.18, rf'$\ell={levels[v]}$',
|
||||
fontsize=9, color='black',
|
||||
bbox=dict(boxstyle='round,pad=0.12',
|
||||
facecolor='white', edgecolor='#999', linewidth=0.5))
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title(r'Level cycle in $L_1 = \{1,2,3\}$ (highlighted)', fontsize=12)
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_level_cycle.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure: Edge switch (flip on a level-cycle edge)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_edge_switch():
|
||||
G = make_graph()
|
||||
source = 4
|
||||
levels = nx.single_source_shortest_path_length(G, source)
|
||||
palette = {0: '#ef4444', 1: '#f59e0b', 2: '#3b82f6'}
|
||||
colors = [palette[levels[v]] for v in G.nodes()]
|
||||
|
||||
# We switch edge (1,2), which lies in the L_1 cycle 1-2-3-1.
|
||||
# Its two adjacent faces in T are (0,1,2) and (1,2,4); the flip
|
||||
# removes 1-2 and adds 0-4.
|
||||
removed = (1, 2)
|
||||
added = (0, 4)
|
||||
|
||||
Gprime = G.copy()
|
||||
Gprime.remove_edge(*removed)
|
||||
Gprime.add_edge(*added)
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(12, 5.5))
|
||||
|
||||
# Panel A: before — highlight the level-cycle edge to be switched
|
||||
ax = axes[0]
|
||||
other_edges = [e for e in G.edges() if set(e) != set(removed)]
|
||||
nx.draw_networkx_edges(G, POS, edgelist=other_edges, ax=ax,
|
||||
edge_color='#bbb', width=1.2)
|
||||
nx.draw_networkx_edges(G, POS, edgelist=[removed], ax=ax,
|
||||
edge_color='#dc2626', width=3.4)
|
||||
nx.draw_networkx_nodes(G, POS, ax=ax, node_color=colors,
|
||||
node_size=560, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(G, POS, ax=ax, font_color='white',
|
||||
font_size=11, font_weight='bold')
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_title(r'Before: edge $1\!-\!2$ lies on the $L_1$ cycle',
|
||||
fontsize=12)
|
||||
|
||||
# Panel B: after — the new edge highlighted in green
|
||||
ax = axes[1]
|
||||
other_edges = [e for e in Gprime.edges() if set(e) != set(added)]
|
||||
nx.draw_networkx_edges(Gprime, POS, edgelist=other_edges, ax=ax,
|
||||
edge_color='#bbb', width=1.2)
|
||||
nx.draw_networkx_edges(Gprime, POS, edgelist=[added], ax=ax,
|
||||
edge_color='#16a34a', width=3.4)
|
||||
nx.draw_networkx_nodes(Gprime, POS, ax=ax, node_color=colors,
|
||||
node_size=560, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(Gprime, POS, ax=ax, font_color='white',
|
||||
font_size=11, font_weight='bold')
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_title(r'After: $1\!-\!2$ replaced by $0\!-\!4$',
|
||||
fontsize=12)
|
||||
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_edge_switch.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Figure: Facial depth (depths in an outerplanar L_k)
|
||||
# ---------------------------------------------------------------------------
|
||||
def fig_facial_depth():
|
||||
import math
|
||||
# 12-vertex maximal outerplanar graph with 3-fold symmetry.
|
||||
# Central triangle (0,4,8); three "in-between" triangles (0,2,4),
|
||||
# (4,6,8), (0,8,10) sit between the central triangle and the
|
||||
# outer "ears" (0,1,2), (2,3,4), (4,5,6), (6,7,8), (8,9,10),
|
||||
# (10,11,0).
|
||||
n = 12
|
||||
pos = {}
|
||||
for i in range(n):
|
||||
a = math.radians(90 - i * (360 / n))
|
||||
pos[i] = (math.cos(a), math.sin(a))
|
||||
|
||||
outer_edges = [(i, (i + 1) % n) for i in range(n)]
|
||||
diagonals = [(0, 2), (2, 4), (4, 6), (6, 8), (8, 10), (10, 0), # "short" chords
|
||||
(0, 4), (4, 8), (0, 8)] # central triangle
|
||||
L = nx.Graph()
|
||||
L.add_nodes_from(pos)
|
||||
L.add_edges_from(outer_edges + diagonals)
|
||||
|
||||
inner_faces = [
|
||||
(0, 1, 2), (2, 3, 4), (4, 5, 6),
|
||||
(6, 7, 8), (8, 9, 10), (10, 11, 0), # 6 outer "ears"
|
||||
(0, 2, 4), (4, 6, 8), (0, 8, 10), # 3 in-between
|
||||
(0, 4, 8), # central
|
||||
]
|
||||
|
||||
# Build dual graph on inner faces: edge iff faces share an edge
|
||||
def face_edges(f):
|
||||
a, b, c = f
|
||||
return {frozenset((a, b)), frozenset((b, c)), frozenset((a, c))}
|
||||
|
||||
outer_edge_set = {frozenset(e) for e in outer_edges}
|
||||
D = nx.Graph()
|
||||
D.add_nodes_from(range(len(inner_faces)))
|
||||
for i, fi in enumerate(inner_faces):
|
||||
for j, fj in enumerate(inner_faces):
|
||||
if i < j and face_edges(fi) & face_edges(fj):
|
||||
D.add_edge(i, j)
|
||||
|
||||
# Boundary set B: faces whose bounding level cycle has >= 1 outer-cycle edge
|
||||
B = [i for i, f in enumerate(inner_faces)
|
||||
if len(face_edges(f) & outer_edge_set) >= 1]
|
||||
|
||||
# Depth = min distance in D to any face in B
|
||||
depth = {}
|
||||
for i in range(len(inner_faces)):
|
||||
dists = [nx.shortest_path_length(D, i, b) for b in B]
|
||||
depth[i] = min(dists)
|
||||
|
||||
# Colour by depth
|
||||
depth_color = {0: '#86efac', 1: '#fde68a', 2: '#fca5a5'}
|
||||
depth_edge = {0: '#16a34a', 1: '#d97706', 2: '#dc2626'}
|
||||
|
||||
fig, ax = plt.subplots(figsize=(7, 7))
|
||||
# Fill faces by depth
|
||||
for i, f in enumerate(inner_faces):
|
||||
poly = Polygon([pos[v] for v in f], closed=True,
|
||||
facecolor=depth_color[depth[i]],
|
||||
edgecolor=depth_edge[depth[i]],
|
||||
linewidth=1.5, alpha=0.7, zorder=0)
|
||||
ax.add_patch(poly)
|
||||
cx = sum(pos[v][0] for v in f) / 3
|
||||
cy = sum(pos[v][1] for v in f) / 3
|
||||
ax.text(cx, cy, rf'$\mathrm{{depth}}={depth[i]}$',
|
||||
ha='center', va='center', fontsize=10,
|
||||
color=depth_edge[depth[i]], fontweight='bold')
|
||||
|
||||
# Draw the graph on top
|
||||
nx.draw_networkx_edges(L, pos, ax=ax, edge_color='#333', width=1.4)
|
||||
nx.draw_networkx_nodes(L, pos, ax=ax, node_color='#1f2937',
|
||||
node_size=320, edgecolors='black', linewidths=1.0)
|
||||
nx.draw_networkx_labels(L, pos, ax=ax, font_color='white',
|
||||
font_size=10, font_weight='bold')
|
||||
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_xlim(-1.3, 1.3); ax.set_ylim(-1.3, 1.3)
|
||||
ax.set_title(r'Facial depth in an outerplanar $L_k$', fontsize=12)
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_facial_depth.png')
|
||||
fig.savefig(out, dpi=200, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fig_level_source()
|
||||
fig_levels()
|
||||
fig_level_cycle()
|
||||
fig_edge_switch()
|
||||
fig_parity_subgraph()
|
||||
fig_facial_depth()
|
||||
@@ -0,0 +1,118 @@
|
||||
"""Demonstrate the preprocessing strategy on the 9-vertex example.
|
||||
|
||||
Start: F = (0,3,6) at depth 1, no balanced surface switch exists
|
||||
(F has no edge of "span 1" -- no edge with a single outer-cycle
|
||||
vertex between the endpoints, hence no ear neighbour).
|
||||
|
||||
Step: perform the (unbalanced) surface switch on edge uv = 03, with
|
||||
F' = (0,2,3) and third vertex x = 2; in Case (ii) the flip removes 03
|
||||
and adds wx = 62.
|
||||
|
||||
Result: A = (0,2,6) at depth 1 has edge 02 at span 1, so the ear
|
||||
(0,1,2) is now a balanced-switch target.
|
||||
"""
|
||||
import os
|
||||
import math
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Polygon
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
|
||||
|
||||
n = 9
|
||||
POS = {i: (math.cos(math.radians(90 - i * 360 / n)),
|
||||
math.sin(math.radians(90 - i * 360 / n))) for i in range(n)}
|
||||
OUTER_EDGES = [(i, (i + 1) % n) for i in range(n)]
|
||||
outer_set = {frozenset(e) for e in OUTER_EDGES}
|
||||
|
||||
|
||||
def face_edges(f):
|
||||
return {frozenset((f[0], f[1])), frozenset((f[1], f[2])),
|
||||
frozenset((f[0], f[2]))}
|
||||
|
||||
|
||||
def compute_depths(faces):
|
||||
D = nx.Graph()
|
||||
D.add_nodes_from(range(len(faces)))
|
||||
for i, fi in enumerate(faces):
|
||||
for j, fj in enumerate(faces):
|
||||
if i < j and face_edges(fi) & face_edges(fj):
|
||||
D.add_edge(i, j)
|
||||
B = [i for i, f in enumerate(faces)
|
||||
if len(face_edges(f) & outer_set) >= 1]
|
||||
return {i: min(nx.shortest_path_length(D, i, b) for b in B)
|
||||
for i in range(len(faces))}
|
||||
|
||||
|
||||
CHORDS_BEFORE = [(0, 2), (0, 3), (3, 5), (3, 6), (0, 6), (6, 8)]
|
||||
FACES_BEFORE = [
|
||||
(0, 1, 2), (0, 2, 3), (3, 4, 5), (3, 5, 6),
|
||||
(6, 7, 8), (6, 8, 0), (0, 3, 6),
|
||||
]
|
||||
|
||||
# After non-balanced switch on edge 03: remove 03, add 26
|
||||
CHORDS_AFTER = [c for c in CHORDS_BEFORE if set(c) != {0, 3}] + [(2, 6)]
|
||||
FACES_AFTER = [
|
||||
(0, 1, 2), (3, 4, 5), (3, 5, 6),
|
||||
(6, 7, 8), (6, 8, 0),
|
||||
(0, 2, 6), (2, 3, 6),
|
||||
]
|
||||
|
||||
|
||||
def draw(ax, faces, chords, depth, title, highlight_edges=None,
|
||||
green_edges=None):
|
||||
palette = {0: '#86efac', 1: '#fde68a', 2: '#fca5a5'}
|
||||
edge_pal = {0: '#16a34a', 1: '#d97706', 2: '#dc2626'}
|
||||
for i, f in enumerate(faces):
|
||||
d = depth[i]
|
||||
poly = Polygon([POS[v] for v in f], closed=True,
|
||||
facecolor=palette.get(d, '#ddd'),
|
||||
edgecolor=edge_pal.get(d, '#333'),
|
||||
linewidth=1.4, alpha=0.7, zorder=0)
|
||||
ax.add_patch(poly)
|
||||
cx = sum(POS[v][0] for v in f) / 3
|
||||
cy = sum(POS[v][1] for v in f) / 3
|
||||
ax.text(cx, cy, str(d), ha='center', va='center', fontsize=11,
|
||||
color=edge_pal.get(d, '#333'), fontweight='bold')
|
||||
for (a, b) in OUTER_EDGES + chords:
|
||||
color = '#333'; lw = 1.2
|
||||
if highlight_edges and ((a, b) in highlight_edges or
|
||||
(b, a) in highlight_edges):
|
||||
color = '#dc2626'; lw = 3.0
|
||||
if green_edges and ((a, b) in green_edges or
|
||||
(b, a) in green_edges):
|
||||
color = '#16a34a'; lw = 3.0
|
||||
ax.plot([POS[a][0], POS[b][0]], [POS[a][1], POS[b][1]],
|
||||
color=color, linewidth=lw, zorder=1)
|
||||
for i, (x, y) in POS.items():
|
||||
ax.scatter([x], [y], s=270, c='#1f2937', edgecolors='black',
|
||||
linewidths=1.0, zorder=2)
|
||||
ax.text(x, y, str(i), ha='center', va='center',
|
||||
fontsize=9, color='white', fontweight='bold', zorder=3)
|
||||
ax.set_aspect('equal'); ax.axis('off')
|
||||
ax.set_xlim(-1.3, 1.3); ax.set_ylim(-1.3, 1.3)
|
||||
ax.set_title(title, fontsize=11)
|
||||
|
||||
|
||||
depth_before = compute_depths(FACES_BEFORE)
|
||||
depth_after = compute_depths(FACES_AFTER)
|
||||
print('BEFORE:')
|
||||
for i, f in enumerate(FACES_BEFORE):
|
||||
print(f' {f} -> depth {depth_before[i]}')
|
||||
print('AFTER:')
|
||||
for i, f in enumerate(FACES_AFTER):
|
||||
print(f' {f} -> depth {depth_after[i]}')
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(14, 7))
|
||||
draw(axes[0], FACES_BEFORE, CHORDS_BEFORE, depth_before,
|
||||
'Before: F=(0,3,6) depth 1; spans (2,2,2) so no ear neighbour',
|
||||
highlight_edges=[(0, 3)])
|
||||
draw(axes[1], FACES_AFTER, CHORDS_AFTER, depth_after,
|
||||
'After non-balanced switch 03->26: A=(0,2,6) depth 1; edge 02 has span 1',
|
||||
green_edges=[(2, 6)], highlight_edges=[(0, 2)])
|
||||
|
||||
fig.tight_layout()
|
||||
out = os.path.join(OUT_DIR, 'fig_preprocessing.png')
|
||||
fig.savefig(out, dpi=180, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
print(f'wrote {out}')
|
||||
|
After Width: | Height: | Size: 349 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 225 KiB |
@@ -0,0 +1,56 @@
|
||||
\relax
|
||||
\providecommand\hyper@newdestlabel[2]{}
|
||||
\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
|
||||
\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
|
||||
\global\let\oldcontentsline\contentsline
|
||||
\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
|
||||
\global\let\oldnewlabel\newlabel
|
||||
\gdef\newlabel#1#2{\newlabelxx{#1}#2}
|
||||
\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
|
||||
\AtEndDocument{\ifx\hyper@anchor\@undefined
|
||||
\let\contentsline\oldcontentsline
|
||||
\let\newlabel\oldnewlabel
|
||||
\fi}
|
||||
\fi}
|
||||
\global\let\hyper@last\relax
|
||||
\gdef\HyperFirstAtBeginDocument#1{#1}
|
||||
\providecommand\HyField@AuxAddToFields[1]{}
|
||||
\providecommand\HyField@AuxAddToCoFields[2]{}
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{1}{Introduction}}{1}{section.1}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{2}{Definitions}}{1}{section.2}\protected@file@percent }
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces The two kinds of level source on a 7-vertex triangulation $T$ (K\textsubscript {4} with vertices $4,5,6$ stacked into the three interior faces). Left: the face source $S = \{0,1,2\}$ (level-0 vertices are the corners of the highlighted triangle). Right: the degree-$3$ vertex source $S = \{4\}$.}}{1}{figure.1}\protected@file@percent }
|
||||
\newlabel{fig:level-source}{{1}{1}{The two kinds of level source on a 7-vertex triangulation $T$ (K\textsubscript {4} with vertices $4,5,6$ stacked into the three interior faces). Left: the face source $S = \{0,1,2\}$ (level-0 vertices are the corners of the highlighted triangle). Right: the degree-$3$ vertex source $S = \{4\}$}{figure.1}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces BFS levels from the degree-$3$ vertex source $S = \{4\}$. The source is level $0$, its three neighbours are level $1$, and the remaining vertices are level $2$. Colour encodes the level.}}{2}{figure.2}\protected@file@percent }
|
||||
\newlabel{fig:levels}{{2}{2}{BFS levels from the degree-$3$ vertex source $S = \{4\}$. The source is level $0$, its three neighbours are level $1$, and the remaining vertices are level $2$. Colour encodes the level}{figure.2}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces A level cycle in the triangulation of Figure\nonbreakingspace \ref {fig:levels}. The triangle $1\!-\!2\!-\!3$ is a simple cycle whose three vertices all lie at level $1$, so it is a level cycle at level $1$.}}{2}{figure.3}\protected@file@percent }
|
||||
\newlabel{fig:level-cycle}{{3}{2}{A level cycle in the triangulation of Figure~\ref {fig:levels}. The triangle $1\!-\!2\!-\!3$ is a simple cycle whose three vertices all lie at level $1$, so it is a level cycle at level $1$}{figure.3}{}}
|
||||
\newlabel{def:edge-switch}{{2.4}{2}{Edge switch}{theorem.2.4}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces An edge switch on the level cycle of Figure\nonbreakingspace \ref {fig:level-cycle}. The chosen cycle edge $1\!-\!2$ is shared by the triangular faces $(0,1,2)$ and $(1,2,4)$; the switch deletes $1\!-\!2$ (red, left) and inserts $0\!-\!4$ (green, right). Vertex colours indicate the original levels in $G$.}}{3}{figure.4}\protected@file@percent }
|
||||
\newlabel{fig:edge-switch}{{4}{3}{An edge switch on the level cycle of Figure~\ref {fig:level-cycle}. The chosen cycle edge $1\!-\!2$ is shared by the triangular faces $(0,1,2)$ and $(1,2,4)$; the switch deletes $1\!-\!2$ (red, left) and inserts $0\!-\!4$ (green, right). Vertex colours indicate the original levels in $G$}{figure.4}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Parity subgraphs of $G' = T$ with respect to the level structure of Figure\nonbreakingspace \ref {fig:levels} (here we take $G = G' = T$). Left: $T$ with vertices coloured by $\ell _G \nonscript \mskip -\medmuskip \mkern 5mu\mathbin {\mathgroup \symoperators mod}\penalty 900 \mkern 5mu\nonscript \mskip -\medmuskip 2$ (blue $=$ even, orange $=$ odd). Middle: the even parity subgraph $E_{G,S}(G')$, induced on $\{0, 4, 5, 6\}$; only edges with both endpoints even appear. Right: the odd parity subgraph $O_{G,S}(G')$, induced on $\{1, 2, 3\}$; the highlighted triangle shows that $O_{G,S}(G')$ is not bipartite for this choice of $G'$.}}{3}{figure.5}\protected@file@percent }
|
||||
\newlabel{fig:parity-subgraph}{{5}{3}{Parity subgraphs of $G' = T$ with respect to the level structure of Figure~\ref {fig:levels} (here we take $G = G' = T$). Left: $T$ with vertices coloured by $\ell _G \bmod 2$ (blue $=$ even, orange $=$ odd). Middle: the even parity subgraph $E_{G,S}(G')$, induced on $\{0, 4, 5, 6\}$; only edges with both endpoints even appear. Right: the odd parity subgraph $O_{G,S}(G')$, induced on $\{1, 2, 3\}$; the highlighted triangle shows that $O_{G,S}(G')$ is not bipartite for this choice of $G'$}{figure.5}{}}
|
||||
\newlabel{def:facial-depth}{{2.6}{3}{Facial depth}{theorem.2.6}{}}
|
||||
\newlabel{def:surface-switch}{{2.7}{3}{Surface switch}{theorem.2.7}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Facial depths in a maximal outerplanar graph on $12$ vertices. The six green ear-triangles share an edge with the outer $12$-cycle and so lie in $\mathcal {B}$ (depth $0$). The three yellow ``in-between'' triangles $(0,2,4),(4,6,8),(0,8,10)$ have only diagonal edges but each is dual-adjacent to ears, giving them $\mathrm {depth} = 1$. The central triangle $(0,4,8)$ is also all-diagonal; its dual neighbours are the three depth-$1$ triangles, so it is isolated with $\mathrm {depth} = 2$.}}{4}{figure.6}\protected@file@percent }
|
||||
\newlabel{fig:facial-depth}{{6}{4}{Facial depths in a maximal outerplanar graph on $12$ vertices. The six green ear-triangles share an edge with the outer $12$-cycle and so lie in $\mathcal {B}$ (depth $0$). The three yellow ``in-between'' triangles $(0,2,4),(4,6,8),(0,8,10)$ have only diagonal edges but each is dual-adjacent to ears, giving them $\mathrm {depth} = 1$. The central triangle $(0,4,8)$ is also all-diagonal; its dual neighbours are the three depth-$1$ triangles, so it is isolated with $\mathrm {depth} = 2$}{figure.6}{}}
|
||||
\newlabel{def:balanced-surface-switch}{{2.8}{4}{Balanced surface switch}{theorem.2.8}{}}
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{3}{Outerplanarity of level components}}{4}{section.3}\protected@file@percent }
|
||||
\newlabel{sec:outerplanar-components}{{3}{4}{Outerplanarity of level components}{section.3}{}}
|
||||
\newlabel{thm:outerplanar-component}{{3.1}{4}{}{theorem.3.1}{}}
|
||||
\newlabel{lem:depth-descent}{{3.2}{5}{}{theorem.3.2}{}}
|
||||
\newlabel{prop:balanced-descent}{{3.3}{5}{}{theorem.3.3}{}}
|
||||
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{When does a balanced surface switch exist?}}{6}{section*.1}\protected@file@percent }
|
||||
\newlabel{obs:span1-balanced-d1}{{3.4}{6}{}{theorem.3.4}{}}
|
||||
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{Preprocessing toward balanced switches}}{6}{section*.2}\protected@file@percent }
|
||||
\newlabel{ex:preprocessing}{{3.5}{6}{}{theorem.3.5}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces $9$-vertex maximal outerplanar $L_k$. $F = (0,3,6)$ has $\mathrm {depth} = 1$ and all three of its edges have span $2$, so none of $F$'s depth-$0$ neighbours is an ear. No balanced surface switch is available on $F$.}}{7}{figure.7}\protected@file@percent }
|
||||
\newlabel{fig:no-balanced}{{7}{7}{$9$-vertex maximal outerplanar $L_k$. $F = (0,3,6)$ has $\mathrm {depth} = 1$ and all three of its edges have span $2$, so none of $F$'s depth-$0$ neighbours is an ear. No balanced surface switch is available on $F$}{figure.7}{}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces One step of preprocessing on the $9$-vertex example. Left: $F = (0,3,6)$ has no edge of span $1$; the chosen surface-switch edge $uv = 03$ (red) is unbalanced. Right: after the switch $03 \DOTSB \mapstochar \rightarrow 26$ (green), the new depth-$1$ face $A = (0,2,6)$ has its edge $02$ (red) at span $1$, exposing the ear $(0,1,2)$ as a balanced surface-switch target.}}{7}{figure.8}\protected@file@percent }
|
||||
\newlabel{fig:preprocessing}{{8}{7}{One step of preprocessing on the $9$-vertex example. Left: $F = (0,3,6)$ has no edge of span $1$; the chosen surface-switch edge $uv = 03$ (red) is unbalanced. Right: after the switch $03 \mapsto 26$ (green), the new depth-$1$ face $A = (0,2,6)$ has its edge $02$ (red) at span $1$, exposing the ear $(0,1,2)$ as a balanced surface-switch target}{figure.8}{}}
|
||||
\newlabel{tocindent-1}{0pt}
|
||||
\newlabel{tocindent0}{14.69437pt}
|
||||
\newlabel{tocindent1}{17.77782pt}
|
||||
\newlabel{tocindent2}{0pt}
|
||||
\newlabel{tocindent3}{0pt}
|
||||
\newlabel{q:preprocessing-terminates}{{3.6}{8}{}{theorem.3.6}{}}
|
||||
\gdef \@abspage@last{8}
|
||||
@@ -0,0 +1,465 @@
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 20 MAY 2026 23:02
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**paper.tex
|
||||
(./paper.tex
|
||||
LaTeX2e <2021-11-15> patch level 1
|
||||
L3 programming layer <2022-02-24>
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsart.cls
|
||||
Document Class: amsart 2020/05/29 v2.20.6
|
||||
\linespacing=\dimen138
|
||||
\normalparindent=\dimen139
|
||||
\normaltopskip=\skip47
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsmath.sty
|
||||
Package: amsmath 2021/10/15 v2.17l AMS math features
|
||||
\@mathmargin=\skip48
|
||||
|
||||
For additional information on amsmath, use the `?' option.
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amstext.sty
|
||||
Package: amstext 2021/08/26 v2.01 AMS text
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsgen.sty
|
||||
File: amsgen.sty 1999/11/30 v2.0 generic functions
|
||||
\@emptytoks=\toks16
|
||||
\ex@=\dimen140
|
||||
))
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsbsy.sty
|
||||
Package: amsbsy 1999/11/29 v1.2d Bold Symbols
|
||||
\pmbraise@=\dimen141
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsopn.sty
|
||||
Package: amsopn 2021/08/26 v2.02 operator names
|
||||
)
|
||||
\inf@bad=\count185
|
||||
LaTeX Info: Redefining \frac on input line 234.
|
||||
\uproot@=\count186
|
||||
\leftroot@=\count187
|
||||
LaTeX Info: Redefining \overline on input line 399.
|
||||
\classnum@=\count188
|
||||
\DOTSCASE@=\count189
|
||||
LaTeX Info: Redefining \ldots on input line 496.
|
||||
LaTeX Info: Redefining \dots on input line 499.
|
||||
LaTeX Info: Redefining \cdots on input line 620.
|
||||
\Mathstrutbox@=\box50
|
||||
\strutbox@=\box51
|
||||
\big@size=\dimen142
|
||||
LaTeX Font Info: Redeclaring font encoding OML on input line 743.
|
||||
LaTeX Font Info: Redeclaring font encoding OMS on input line 744.
|
||||
\macc@depth=\count190
|
||||
\c@MaxMatrixCols=\count191
|
||||
\dotsspace@=\muskip16
|
||||
\c@parentequation=\count192
|
||||
\dspbrk@lvl=\count193
|
||||
\tag@help=\toks17
|
||||
\row@=\count194
|
||||
\column@=\count195
|
||||
\maxfields@=\count196
|
||||
\andhelp@=\toks18
|
||||
\eqnshift@=\dimen143
|
||||
\alignsep@=\dimen144
|
||||
\tagshift@=\dimen145
|
||||
\tagwidth@=\dimen146
|
||||
\totwidth@=\dimen147
|
||||
\lineht@=\dimen148
|
||||
\@envbody=\toks19
|
||||
\multlinegap=\skip49
|
||||
\multlinetaggap=\skip50
|
||||
\mathdisplay@stack=\toks20
|
||||
LaTeX Info: Redefining \[ on input line 2938.
|
||||
LaTeX Info: Redefining \] on input line 2939.
|
||||
)
|
||||
LaTeX Font Info: Trying to load font information for U+msa on input line 397
|
||||
.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
|
||||
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amsfonts.sty
|
||||
Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
|
||||
\symAMSa=\mathgroup4
|
||||
\symAMSb=\mathgroup5
|
||||
LaTeX Font Info: Redeclaring math symbol \hbar on input line 98.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
|
||||
(Font) U/euf/m/n --> U/euf/b/n on input line 106.
|
||||
)
|
||||
\copyins=\insert199
|
||||
\abstractbox=\box52
|
||||
\listisep=\skip51
|
||||
\c@part=\count197
|
||||
\c@section=\count198
|
||||
\c@subsection=\count266
|
||||
\c@subsubsection=\count267
|
||||
\c@paragraph=\count268
|
||||
\c@subparagraph=\count269
|
||||
\c@figure=\count270
|
||||
\c@table=\count271
|
||||
\abovecaptionskip=\skip52
|
||||
\belowcaptionskip=\skip53
|
||||
\captionindent=\dimen149
|
||||
\thm@style=\toks21
|
||||
\thm@bodyfont=\toks22
|
||||
\thm@headfont=\toks23
|
||||
\thm@notefont=\toks24
|
||||
\thm@headpunct=\toks25
|
||||
\thm@preskip=\skip54
|
||||
\thm@postskip=\skip55
|
||||
\thm@headsep=\skip56
|
||||
\dth@everypar=\toks26
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hyperref/hyperref.sty
|
||||
Package: hyperref 2022-02-21 v7.00n Hypertext links for LaTeX
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty
|
||||
Package: ltxcmds 2020-05-10 v1.25 LaTeX kernel commands for general use (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/iftex/iftex.sty
|
||||
Package: iftex 2022/02/03 v1.0f TeX engine tests
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty
|
||||
Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO
|
||||
)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/infwarerr/infwarerr.sty
|
||||
Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO)
|
||||
)
|
||||
Package pdftexcmds Info: \pdf@primitive is available.
|
||||
Package pdftexcmds Info: \pdf@ifprimitive is available.
|
||||
Package pdftexcmds Info: \pdfdraftmode found.
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/keyval.sty
|
||||
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
|
||||
\KV@toks@=\toks27
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty
|
||||
Package: kvsetkeys 2019/12/15 v1.18 Key value parser (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty
|
||||
Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/pdfescape/pdfescape.sty
|
||||
Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hycolor/hycolor.sty
|
||||
Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty
|
||||
Package: letltxmacro 2019/12/03 v1.6 Let assignment for LaTeX macros (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/auxhook/auxhook.sty
|
||||
Package: auxhook 2019-12-17 v1.6 Hooks for auxiliary files (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/kvoptions/kvoptions.sty
|
||||
Package: kvoptions 2020-10-07 v3.14 Key value format for package options (HO)
|
||||
)
|
||||
\@linkdim=\dimen150
|
||||
\Hy@linkcounter=\count272
|
||||
\Hy@pagecounter=\count273
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hyperref/pd1enc.def
|
||||
File: pd1enc.def 2022-02-21 v7.00n Hyperref: PDFDocEncoding definition (HO)
|
||||
Now handling font encoding PD1 ...
|
||||
... no UTF-8 mapping file for font encoding PD1
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/intcalc/intcalc.sty
|
||||
Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/etexcmds/etexcmds.sty
|
||||
Package: etexcmds 2019/12/15 v1.7 Avoid name clashes with e-TeX commands (HO)
|
||||
)
|
||||
\Hy@SavedSpaceFactor=\count274
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hyperref/puenc.def
|
||||
File: puenc.def 2022-02-21 v7.00n Hyperref: PDF Unicode definition (HO)
|
||||
Now handling font encoding PU ...
|
||||
... no UTF-8 mapping file for font encoding PU
|
||||
)
|
||||
Package hyperref Info: Hyper figures OFF on input line 4137.
|
||||
Package hyperref Info: Link nesting OFF on input line 4142.
|
||||
Package hyperref Info: Hyper index ON on input line 4145.
|
||||
Package hyperref Info: Plain pages OFF on input line 4152.
|
||||
Package hyperref Info: Backreferencing OFF on input line 4157.
|
||||
Package hyperref Info: Implicit mode ON; LaTeX internals redefined.
|
||||
Package hyperref Info: Bookmarks ON on input line 4390.
|
||||
\c@Hy@tempcnt=\count275
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/url/url.sty
|
||||
\Urlmuskip=\muskip17
|
||||
Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc.
|
||||
)
|
||||
LaTeX Info: Redefining \url on input line 4749.
|
||||
\XeTeXLinkMargin=\dimen151
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/bitset/bitset.sty
|
||||
Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty
|
||||
Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO
|
||||
)
|
||||
))
|
||||
\Fld@menulength=\count276
|
||||
\Field@Width=\dimen152
|
||||
\Fld@charsize=\dimen153
|
||||
Package hyperref Info: Hyper figures OFF on input line 6027.
|
||||
Package hyperref Info: Link nesting OFF on input line 6032.
|
||||
Package hyperref Info: Hyper index ON on input line 6035.
|
||||
Package hyperref Info: backreferencing OFF on input line 6042.
|
||||
Package hyperref Info: Link coloring OFF on input line 6047.
|
||||
Package hyperref Info: Link coloring with OCG OFF on input line 6052.
|
||||
Package hyperref Info: PDF/A mode OFF on input line 6057.
|
||||
LaTeX Info: Redefining \ref on input line 6097.
|
||||
LaTeX Info: Redefining \pageref on input line 6101.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/atbegshi-ltx.sty
|
||||
Package: atbegshi-ltx 2021/01/10 v1.0c Emulation of the original atbegshi
|
||||
package with kernel methods
|
||||
)
|
||||
\Hy@abspage=\count277
|
||||
\c@Item=\count278
|
||||
\c@Hfootnote=\count279
|
||||
)
|
||||
Package hyperref Info: Driver (autodetected): hpdftex.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hyperref/hpdftex.def
|
||||
File: hpdftex.def 2022-02-21 v7.00n Hyperref driver for pdfTeX
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/atveryend-ltx.sty
|
||||
Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atveryend pac
|
||||
kage
|
||||
with kernel methods
|
||||
)
|
||||
\Fld@listcount=\count280
|
||||
\c@bookmark@seq@number=\count281
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty
|
||||
Package: rerunfilecheck 2019/12/05 v1.9 Rerun checks for auxiliary files (HO)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty
|
||||
Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO)
|
||||
)
|
||||
Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2
|
||||
86.
|
||||
)
|
||||
\Hy@SectionHShift=\skip57
|
||||
) (/usr/local/texlive/2022/texmf-dist/tex/latex/enumitem/enumitem.sty
|
||||
Package: enumitem 2019/06/20 v3.9 Customized lists
|
||||
\labelindent=\skip58
|
||||
\enit@outerparindent=\dimen154
|
||||
\enit@toks=\toks28
|
||||
\enit@inbox=\box53
|
||||
\enit@count@id=\count282
|
||||
\enitdp@description=\count283
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphicx.sty
|
||||
Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphics.sty
|
||||
Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/trig.sty
|
||||
Package: trig 2021/08/11 v1.11 sin cos tan (DPC)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
|
||||
File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
|
||||
)
|
||||
Package graphics Info: Driver file: pdftex.def on input line 107.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-def/pdftex.def
|
||||
File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex
|
||||
))
|
||||
\Gin@req@height=\dimen155
|
||||
\Gin@req@width=\dimen156
|
||||
)
|
||||
\c@theorem=\count284
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
|
||||
File: l3backend-pdftex.def 2022-02-07 L3 backend support: PDF output (pdfTeX)
|
||||
\l__color_backend_stack_int=\count285
|
||||
\l__pdf_internal_box=\box54
|
||||
)
|
||||
(./paper.aux)
|
||||
\openout1 = `paper.aux'.
|
||||
|
||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 60.
|
||||
LaTeX Font Info: ... okay on input line 60.
|
||||
LaTeX Font Info: Trying to load font information for U+msa on input line 60.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
|
||||
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
|
||||
)
|
||||
LaTeX Font Info: Trying to load font information for U+msb on input line 60.
|
||||
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsb.fd
|
||||
File: umsb.fd 2013/01/14 v3.01 AMS symbols B
|
||||
)
|
||||
Package hyperref Info: Link coloring OFF on input line 60.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/hyperref/nameref.sty
|
||||
Package: nameref 2021-04-02 v2.47 Cross-referencing by name of section
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/refcount/refcount.sty
|
||||
Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/gettitlestring/gettitlestring.s
|
||||
ty
|
||||
Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO)
|
||||
)
|
||||
\c@section@level=\count286
|
||||
)
|
||||
LaTeX Info: Redefining \ref on input line 60.
|
||||
LaTeX Info: Redefining \pageref on input line 60.
|
||||
LaTeX Info: Redefining \nameref on input line 60.
|
||||
(./paper.out) (./paper.out)
|
||||
\@outlinefile=\write3
|
||||
\openout3 = `paper.out'.
|
||||
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
|
||||
[Loading MPS to PDF converter (version 2006.09.02).]
|
||||
\scratchcounter=\count287
|
||||
\scratchdimen=\dimen157
|
||||
\scratchbox=\box55
|
||||
\nofMPsegments=\count288
|
||||
\nofMParguments=\count289
|
||||
\everyMPshowfont=\toks29
|
||||
\MPscratchCnt=\count290
|
||||
\MPscratchDim=\dimen158
|
||||
\MPnumerator=\count291
|
||||
\makeMPintoPDFobject=\count292
|
||||
\everyMPtoPDFconversion=\toks30
|
||||
) (/usr/local/texlive/2022/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
|
||||
Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
|
||||
Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
|
||||
85.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
|
||||
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
|
||||
e
|
||||
))
|
||||
<fig_level_source.png, id=24, 715.11165pt x 317.988pt>
|
||||
File: fig_level_source.png Graphic file (type png)
|
||||
<use fig_level_source.png>
|
||||
Package pdftex.def Info: fig_level_source.png used on input line 105.
|
||||
(pdftex.def) Requested size: 306.0022pt x 136.07228pt.
|
||||
<fig_levels.png, id=26, 454.21695pt x 391.34206pt>
|
||||
File: fig_levels.png Graphic file (type png)
|
||||
<use fig_levels.png>
|
||||
Package pdftex.def Info: fig_levels.png used on input line 122.
|
||||
(pdftex.def) Requested size: 198.0011pt x 170.59666pt.
|
||||
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
<fig_level_cycle.png, id=27, 452.04884pt x 391.34206pt>
|
||||
File: fig_level_cycle.png Graphic file (type png)
|
||||
<use fig_level_cycle.png>
|
||||
Package pdftex.def Info: fig_level_cycle.png used on input line 136.
|
||||
(pdftex.def) Requested size: 198.0011pt x 171.40878pt.
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map} <./fig
|
||||
_level_source.png>]
|
||||
<fig_edge_switch.png, id=49, 859.65166pt x 378.33345pt>
|
||||
File: fig_edge_switch.png Graphic file (type png)
|
||||
<use fig_edge_switch.png>
|
||||
Package pdftex.def Info: fig_edge_switch.png used on input line 155.
|
||||
(pdftex.def) Requested size: 341.9989pt x 150.51671pt.
|
||||
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
<fig_parity_subgraph.png, id=51, 1076.46165pt x 319.79475pt>
|
||||
File: fig_parity_subgraph.png Graphic file (type png)
|
||||
<use fig_parity_subgraph.png>
|
||||
Package pdftex.def Info: fig_parity_subgraph.png used on input line 173.
|
||||
(pdftex.def) Requested size: 360.0pt x 106.9477pt.
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[2 <./fig_levels.png> <./fig_level_cycle.png>]
|
||||
<fig_facial_depth.png, id=64, 482.40225pt x 498.663pt>
|
||||
File: fig_facial_depth.png Graphic file (type png)
|
||||
<use fig_facial_depth.png>
|
||||
Package pdftex.def Info: fig_facial_depth.png used on input line 200.
|
||||
(pdftex.def) Requested size: 216.0022pt x 223.28535pt.
|
||||
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[3 <./fig_edge_switch.png> <./fig_parity_subgraph.png>] [4 <./fig_facial_depth.
|
||||
png>] [5]
|
||||
Overfull \hbox (1.09193pt too wide) in paragraph at lines 354--357
|
||||
[]\OT1/cmr/m/n/10 if $\OML/cmm/m/it/10 A[]$ \OT1/cmr/m/n/10 is an in-ner face,
|
||||
bal-anced-ness gives $[](\OML/cmm/m/it/10 A[]\OT1/cmr/m/n/10 ) = \OML/cmm/m/it/
|
||||
10 d \OMS/cmsy/m/n/10 ^^@ \OT1/cmr/m/n/10 2$, so $[](\OML/cmm/m/it/10 A\OT1/cmr
|
||||
/m/n/10 ) \OMS/cmsy/m/n/10 ^^T
|
||||
[]
|
||||
|
||||
<fig_no_balanced_switch.png, id=99, 483.0045pt x 498.2615pt>
|
||||
File: fig_no_balanced_switch.png Graphic file (type png)
|
||||
<use fig_no_balanced_switch.png>
|
||||
Package pdftex.def Info: fig_no_balanced_switch.png used on input line 395.
|
||||
(pdftex.def) Requested size: 198.0011pt x 204.25052pt.
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
<fig_preprocessing.png, id=102, 998.932pt x 513.5185pt>
|
||||
File: fig_preprocessing.png Graphic file (type png)
|
||||
<use fig_preprocessing.png>
|
||||
Package pdftex.def Info: fig_preprocessing.png used on input line 426.
|
||||
(pdftex.def) Requested size: 360.0pt x 185.0624pt.
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[6] [7 <./fig_no_balanced_switch.png> <./fig_preprocessing.png>] [8]
|
||||
(./paper.aux)
|
||||
Package rerunfilecheck Info: File `paper.out' has not changed.
|
||||
(rerunfilecheck) Checksum: AF95E9EBA8283D2CBF07B09833C039FF;1010.
|
||||
)
|
||||
Here is how much of TeX's memory you used:
|
||||
9777 strings out of 478268
|
||||
151593 string characters out of 5846347
|
||||
458194 words of memory out of 5000000
|
||||
27673 multiletter control sequences out of 15000+600000
|
||||
475666 words of font info for 53 fonts, out of 8000000 for 9000
|
||||
1302 hyphenation exceptions out of 8191
|
||||
69i,8n,76p,781b,448s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb
|
||||
></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb
|
||||
></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb>
|
||||
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb><
|
||||
/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb></u
|
||||
sr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr
|
||||
/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/lo
|
||||
cal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></usr/local
|
||||
/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/local/
|
||||
texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy5.pfb></usr/local/te
|
||||
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/texl
|
||||
ive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/local/texli
|
||||
ve/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/local/texlive
|
||||
/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfb>
|
||||
Output written on paper.pdf (8 pages, 1034024 bytes).
|
||||
PDF statistics:
|
||||
196 PDF objects out of 1000 (max. 8388607)
|
||||
140 compressed objects within 2 object streams
|
||||
38 named destinations out of 1000 (max. 500000)
|
||||
81 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
\BOOKMARK [1][-]{section.1}{\376\377\0001\000.\000\040\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n}{}% 1
|
||||
\BOOKMARK [1][-]{section.2}{\376\377\0002\000.\000\040\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n\000s}{}% 2
|
||||
\BOOKMARK [1][-]{section.3}{\376\377\0003\000.\000\040\000O\000u\000t\000e\000r\000p\000l\000a\000n\000a\000r\000i\000t\000y\000\040\000o\000f\000\040\000l\000e\000v\000e\000l\000\040\000c\000o\000m\000p\000o\000n\000e\000n\000t\000s}{}% 3
|
||||
\BOOKMARK [2][-]{section*.1}{\376\377\000W\000h\000e\000n\000\040\000d\000o\000e\000s\000\040\000a\000\040\000b\000a\000l\000a\000n\000c\000e\000d\000\040\000s\000u\000r\000f\000a\000c\000e\000\040\000s\000w\000i\000t\000c\000h\000\040\000e\000x\000i\000s\000t\000?}{section.3}% 4
|
||||
\BOOKMARK [2][-]{section*.2}{\376\377\000P\000r\000e\000p\000r\000o\000c\000e\000s\000s\000i\000n\000g\000\040\000t\000o\000w\000a\000r\000d\000\040\000b\000a\000l\000a\000n\000c\000e\000d\000\040\000s\000w\000i\000t\000c\000h\000e\000s}{section.3}% 5
|
||||
@@ -0,0 +1,453 @@
|
||||
%% filename: amsart-template.tex
|
||||
%% version: 1.1
|
||||
%% date: 2014/07/24
|
||||
%%
|
||||
%% American Mathematical Society
|
||||
%% Technical Support
|
||||
%% Publications Technical Group
|
||||
%% 201 Charles Street
|
||||
%% Providence, RI 02904
|
||||
%% USA
|
||||
%% tel: (401) 455-4080
|
||||
%% (800) 321-4267 (USA and Canada only)
|
||||
%% fax: (401) 331-3842
|
||||
%% email: tech-support@ams.org
|
||||
%%
|
||||
%% Copyright 2008-2010, 2014 American Mathematical Society.
|
||||
%%
|
||||
%% This work may be distributed and/or modified under the
|
||||
%% conditions of the LaTeX Project Public License, either version 1.3c
|
||||
%% of this license or (at your option) any later version.
|
||||
%% The latest version of this license is in
|
||||
%% http://www.latex-project.org/lppl.txt
|
||||
%% and version 1.3c or later is part of all distributions of LaTeX
|
||||
%% version 2005/12/01 or later.
|
||||
%%
|
||||
%% This work has the LPPL maintenance status `maintained'.
|
||||
%%
|
||||
%% The Current Maintainer of this work is the American Mathematical
|
||||
%% Society.
|
||||
%%
|
||||
%% ====================================================================
|
||||
|
||||
% AMS-LaTeX v.2 template for use with amsart
|
||||
%
|
||||
% Remove any commented or uncommented macros you do not use.
|
||||
|
||||
\documentclass{amsart}
|
||||
|
||||
\usepackage{hyperref}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{graphicx}
|
||||
|
||||
\newtheorem{theorem}{Theorem}[section]
|
||||
\newtheorem{lemma}[theorem]{Lemma}
|
||||
\newtheorem{proposition}[theorem]{Proposition}
|
||||
|
||||
\theoremstyle{definition}
|
||||
\newtheorem{definition}[theorem]{Definition}
|
||||
\newtheorem{example}[theorem]{Example}
|
||||
\newtheorem{xca}[theorem]{Exercise}
|
||||
\newtheorem{conjecture}[theorem]{Conjecture}
|
||||
\newtheorem{question}[theorem]{Question}
|
||||
\newtheorem{observation}[theorem]{Observation}
|
||||
|
||||
\theoremstyle{remark}
|
||||
\newtheorem{remark}[theorem]{Remark}
|
||||
|
||||
\numberwithin{equation}{section}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\title{Level Switching}
|
||||
|
||||
% Remove any unused author tags.
|
||||
|
||||
% author one information
|
||||
\author{Eric Bauerfeld}
|
||||
\address{}
|
||||
\curraddr{}
|
||||
\email{}
|
||||
\thanks{}
|
||||
|
||||
|
||||
\subjclass[2010]{Primary }
|
||||
|
||||
\keywords{}
|
||||
|
||||
\date{}
|
||||
|
||||
\dedicatory{}
|
||||
|
||||
\begin{abstract}
|
||||
\end{abstract}
|
||||
|
||||
\maketitle
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
\section{Definitions}
|
||||
|
||||
Throughout, $G = (V, E)$ is a plane maximal planar graph (a triangulation)
|
||||
with a fixed planar embedding $\Pi_G$. We write $|V| = n$, so $|E| = 3n - 6$
|
||||
and $G$ has $2n - 4$ triangular faces.
|
||||
|
||||
\begin{definition}[Level source]
|
||||
A \emph{level source} of $G$ is either:
|
||||
\begin{itemize}
|
||||
\item a face $F$ of $G$ (all vertices of $F$ are level-0 sources), or
|
||||
\item a vertex $v$ of degree 3 (the singleton $\{v\}$ is a level-0 source).
|
||||
\end{itemize}
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.85\textwidth]{fig_level_source.png}
|
||||
\caption{The two kinds of level source on a 7-vertex triangulation $T$
|
||||
(K\textsubscript{4} with vertices $4,5,6$ stacked into the three
|
||||
interior faces). Left: the face source $S = \{0,1,2\}$
|
||||
(level-0 vertices are the corners of the highlighted triangle).
|
||||
Right: the degree-$3$ vertex source $S = \{4\}$.}
|
||||
\label{fig:level-source}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Levels]
|
||||
Given a level source $S \subseteq V$, the \emph{level} of $v \in V$ is
|
||||
$\ell_G(v) = \mathrm{dist}_G(v, S)$, the graph distance from $v$ to the nearest
|
||||
source vertex.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.55\textwidth]{fig_levels.png}
|
||||
\caption{BFS levels from the degree-$3$ vertex source $S = \{4\}$.
|
||||
The source is level $0$, its three neighbours are level $1$, and the
|
||||
remaining vertices are level $2$. Colour encodes the level.}
|
||||
\label{fig:levels}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Level cycle]
|
||||
A \emph{level cycle} of $G$ (with respect to a level source $S$) is a
|
||||
simple cycle in $G$ all of whose vertices have the same level.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.55\textwidth]{fig_level_cycle.png}
|
||||
\caption{A level cycle in the triangulation of Figure~\ref{fig:levels}.
|
||||
The triangle $1\!-\!2\!-\!3$ is a simple cycle whose three vertices all
|
||||
lie at level $1$, so it is a level cycle at level $1$.}
|
||||
\label{fig:level-cycle}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Edge switch]
|
||||
\label{def:edge-switch}
|
||||
Let $G$ be a triangulation with level source $S$, and let $e = uv$ be an
|
||||
edge of a level cycle of $G$. The \emph{edge switch} at $e$ is the edge
|
||||
flip on $e$: writing $uvw$ and $uvx$ for the two triangular faces of $G$
|
||||
containing $e$, the edge $uv$ is removed and the edge $wx$ is added. As
|
||||
with any edge flip, the result is a triangulation on the same vertex set
|
||||
provided $w$ and $x$ are non-adjacent in $G$.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.95\textwidth]{fig_edge_switch.png}
|
||||
\caption{An edge switch on the level cycle of
|
||||
Figure~\ref{fig:level-cycle}. The chosen cycle edge $1\!-\!2$ is shared
|
||||
by the triangular faces $(0,1,2)$ and $(1,2,4)$; the switch deletes
|
||||
$1\!-\!2$ (red, left) and inserts $0\!-\!4$ (green, right). Vertex
|
||||
colours indicate the original levels in $G$.}
|
||||
\label{fig:edge-switch}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Parity subgraph]
|
||||
Let $G$ be a triangulation with level source $S$, and let $G'$ be a triangulation
|
||||
on the same vertex set as $G$. The \emph{even parity subgraph} $E_{G,S}(G')$ is
|
||||
the subgraph of $G'$ induced by $\{v \in V : \ell_G(v) \equiv 0 \pmod 2\}$. The
|
||||
\emph{odd parity subgraph} is defined analogously for odd $\ell_G$.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{fig_parity_subgraph.png}
|
||||
\caption{Parity subgraphs of $G' = T$ with respect to the level structure of
|
||||
Figure~\ref{fig:levels} (here we take $G = G' = T$). Left: $T$ with vertices
|
||||
coloured by $\ell_G \bmod 2$ (blue $=$ even, orange $=$ odd). Middle: the
|
||||
even parity subgraph $E_{G,S}(G')$, induced on $\{0, 4, 5, 6\}$; only
|
||||
edges with both endpoints even appear. Right: the odd parity subgraph
|
||||
$O_{G,S}(G')$, induced on $\{1, 2, 3\}$; the highlighted triangle shows
|
||||
that $O_{G,S}(G')$ is not bipartite for this choice of $G'$.}
|
||||
\label{fig:parity-subgraph}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Facial depth]
|
||||
\label{def:facial-depth}
|
||||
Let $L_k$ be drawn with the outerplanar embedding inherited from $\Pi_G$,
|
||||
let $D$ be the dual graph of this drawing with the outer face removed,
|
||||
and let $\mathcal{B}$ be the set of inner faces of $L_k$ whose bounding
|
||||
level cycle contains at least one edge of the outer cycle of $L_k$. The
|
||||
\emph{facial depth} of an inner face $F$ of $L_k$ is
|
||||
\[
|
||||
\mathrm{depth}(F) \;=\; \min_{F' \in \mathcal{B}} \mathrm{dist}_D(F, F'),
|
||||
\]
|
||||
with the convention $\mathrm{depth}(F) = \infty$ if no such $F'$ exists.
|
||||
An inner face is \emph{isolated} if $\mathrm{depth}(F) \geq 1$.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.6\textwidth]{fig_facial_depth.png}
|
||||
\caption{Facial depths in a maximal outerplanar graph on $12$ vertices.
|
||||
The six green ear-triangles share an edge with the outer $12$-cycle and
|
||||
so lie in $\mathcal{B}$ (depth $0$). The three yellow ``in-between''
|
||||
triangles $(0,2,4),(4,6,8),(0,8,10)$ have only diagonal edges but each
|
||||
is dual-adjacent to ears, giving them $\mathrm{depth} = 1$. The central
|
||||
triangle $(0,4,8)$ is also all-diagonal; its dual neighbours are the
|
||||
three depth-$1$ triangles, so it is isolated with
|
||||
$\mathrm{depth} = 2$.}
|
||||
\label{fig:facial-depth}
|
||||
\end{figure}
|
||||
|
||||
\begin{definition}[Surface switch]
|
||||
\label{def:surface-switch}
|
||||
A \emph{surface switch} is an edge switch (Definition~\ref{def:edge-switch})
|
||||
applied to an edge incident to two level cycles, one of facial depth $d$
|
||||
and the other of facial depth $d - 1$.
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}[Balanced surface switch]
|
||||
\label{def:balanced-surface-switch}
|
||||
Let $\sigma$ be a surface switch on an edge $e = uv$ separating an inner
|
||||
face $F$ of $L_k$ of depth $d \geq 1$ from an adjacent inner face
|
||||
$F' = uvx$ of depth $d - 1$. We say $\sigma$ is \emph{balanced} if each
|
||||
of the two edges of $\partial F'$ other than $uv$ (namely $ux$ and $vx$)
|
||||
either lies on the outer cycle of $L_k$ or is shared with an inner face
|
||||
of $L_k$ of depth $d - 2$.
|
||||
\end{definition}
|
||||
|
||||
When $d = 1$ the condition reduces to ``both $ux$ and $vx$ lie on the
|
||||
outer cycle of $L_k$'', because no inner face has depth $-1$; in that
|
||||
case $F'$ is a triangular ``ear'' hanging off $uv$.
|
||||
|
||||
\section{Outerplanarity of level components}
|
||||
\label{sec:outerplanar-components}
|
||||
|
||||
For each integer $k \geq 0$ and each $(G, S)$, write $L_k$ for the
|
||||
subgraph of $G$ induced by the level-$k$ vertices. A \emph{level
|
||||
component} of $G$ (with respect to $S$) is a connected component of
|
||||
some $L_k$.
|
||||
|
||||
\begin{theorem}
|
||||
\label{thm:outerplanar-component}
|
||||
For every plane triangulation $G$ and every level source $S$ of $G$,
|
||||
every level component of $G$ is outerplanar.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
Since every subgraph of an outerplanar graph is outerplanar, it suffices
|
||||
to show that each level subgraph $L_k$ is outerplanar. For $k = 0$,
|
||||
$L_0$ is either a single vertex (when $S$ is a degree-$3$ vertex) or
|
||||
the triangle bounding the source face (when $S$ is a face), both
|
||||
outerplanar.
|
||||
|
||||
Fix $k \geq 1$ and let $D_k$ be the drawing of $L_k$ inherited from
|
||||
$\Pi_G$. Let $F^\ast$ be the face of $D_k$ containing the source.
|
||||
Suppose for contradiction that some $u \in L_k$ does not lie on
|
||||
$\partial F^\ast$, so $u$ lies on the boundary of some other face of
|
||||
$D_k$. Take any path $P$ in $G$ from $v_0 \in S$ to $u$. As a curve in
|
||||
$\Pi_G$, $P$ starts in $F^\ast$ and ends at a point off $\partial
|
||||
F^\ast$, so it must transition from $F^\ast$ to a different face of
|
||||
$D_k$; in a planar embedding this can happen only at a vertex of
|
||||
$D_k$, that is, at a level-$k$ vertex $w$ on $P$. Either $w \neq u$
|
||||
(so $P$ has length $\geq \mathrm{dist}_G(S, w) + 1 \geq k + 1$), or
|
||||
$w = u$ (contradicting $u \notin \partial F^\ast$). Since every
|
||||
$S$-to-$u$ path has length $\geq k + 1$, $\mathrm{dist}_G(S, u) \geq
|
||||
k + 1$, contradicting $u \in L_k$.
|
||||
\end{proof}
|
||||
|
||||
\begin{lemma}
|
||||
\label{lem:depth-descent}
|
||||
Let $C$ be a level component of $G$ with respect to $S$, drawn with the
|
||||
outerplanar embedding inherited from $\Pi_G$, and let $D$ be its
|
||||
inner-face dual. If $F$ is an inner face of $C$ with
|
||||
$\mathrm{depth}(F) = d > 0$, then $F$ is dual-adjacent to an inner
|
||||
face $F'$ with $\mathrm{depth}(F') = d - 1$.
|
||||
\end{lemma}
|
||||
|
||||
\begin{proof}
|
||||
By Theorem~\ref{thm:outerplanar-component}, $C$ is outerplanar, so the
|
||||
inner-face dual $D$ is a forest (a standard fact; a tree when $C$ is
|
||||
$2$-connected).
|
||||
|
||||
Each leaf $F_\ell$ of $D$ contains a single interior edge of $C$, so
|
||||
the remaining edges of $\partial F_\ell$ lie on the outer cycle of $C$.
|
||||
In particular $F_\ell$ has at least one outer-cycle edge, so
|
||||
$F_\ell \in \mathcal{B}$ and $\mathrm{depth}(F_\ell) = 0$. Hence every
|
||||
tree component of $D$ contains an element of $\mathcal{B}$, so the
|
||||
depths of all of its vertices are finite.
|
||||
|
||||
Choose a shortest path $F = F_0, F_1, \ldots, F_d = F^\ast$ in $D$ from
|
||||
$F$ to some $F^\ast \in \mathcal{B}$ realising $\mathrm{depth}(F) = d$.
|
||||
The suffix $F_1, \ldots, F_d$ witnesses $\mathrm{depth}(F_1) \leq d - 1$.
|
||||
If $\mathrm{depth}(F_1) \leq d - 2$, prepending the edge $F\,F_1$ to a
|
||||
witnessing path would give $\mathrm{depth}(F) \leq d - 1$, contradicting
|
||||
$\mathrm{depth}(F) = d$. Hence $\mathrm{depth}(F_1) = d - 1$, and we
|
||||
may take $F' := F_1$.
|
||||
\end{proof}
|
||||
|
||||
\begin{proposition}
|
||||
\label{prop:balanced-descent}
|
||||
Let $\sigma$ be a balanced surface switch on the edge $e = uv$ separating
|
||||
$F$ (depth $d \geq 1$) from $F' = uvx$ (depth $d - 1$), and let
|
||||
$G' = G - uv + wx$ be the result of the underlying edge flip, with
|
||||
$uvw, uvx$ the two triangular faces of $G$ at $uv$. Then in $L_k'$ (the
|
||||
level-$k$ subgraph of $G'$, with the level assignment of $G$):
|
||||
\begin{enumerate}
|
||||
\item the level cycle $\partial F$ is destroyed; and
|
||||
\item one or two new inner faces appear in $L_k'$, each of depth exactly
|
||||
$d - 1$.
|
||||
\end{enumerate}
|
||||
\end{proposition}
|
||||
|
||||
\begin{proof}
|
||||
The flip removes $uv$ from $G$, so $\partial F$ is no longer a cycle of
|
||||
$L_k'$, proving (1). For (2) we split on whether the new edge $wx$
|
||||
re-enters $L_k$.
|
||||
|
||||
\textbf{Case (i): $\{w, x\} \not\subseteq L_k$.} Then $L_k' = L_k - uv$.
|
||||
The faces $F$ and $F'$ merge into a single new inner face $\widetilde F$
|
||||
with boundary $(\partial F \cup \partial F') \setminus \{uv\}$. The dual
|
||||
neighbours of $\widetilde F$ in $L_k'$ are exactly the former neighbours
|
||||
of $F$ and $F'$ other than each other; in particular they include all
|
||||
inner faces previously adjacent to $F'$ across $ux$ or $vx$, whose depths
|
||||
are at most $d - 2$ by Lemma~\ref{lem:depth-descent} applied to $F'$
|
||||
(when $d \geq 2$). Thus $\mathrm{depth}(\widetilde F) \leq d - 1$.
|
||||
|
||||
For the matching lower bound, every neighbour of $\widetilde F$ has depth
|
||||
$\geq d - 2$ (neighbours inherited from $F$ have depth $\geq d - 1$;
|
||||
neighbours inherited from $F'$ have depth $\geq d - 2$). When $d \geq 2$,
|
||||
neither $F$ nor $F'$ has an outer-cycle edge, so neither does
|
||||
$\widetilde F$, giving $\mathrm{depth}(\widetilde F) \geq d - 1$. When
|
||||
$d = 1$, $F' \in \mathcal{B}$ and its outer-cycle edge (necessarily
|
||||
distinct from the interior edge $uv$) survives on $\partial \widetilde F$,
|
||||
so $\widetilde F \in \mathcal{B}'$ and
|
||||
$\mathrm{depth}(\widetilde F) = 0 = d - 1$. In either case
|
||||
$\mathrm{depth}(\widetilde F) = d - 1$, giving the unique new face
|
||||
required by~(2).
|
||||
|
||||
\textbf{Case (ii): $\{w, x\} \subseteq L_k$.} Then $F = uvw$ and
|
||||
$F' = uvx$ are triangular faces of $L_k$, and $L_k' = L_k - uv + wx$.
|
||||
The chord $wx$ splits the quadrilateral $\partial(F \cup F')$ into two
|
||||
triangular faces $A = uwx$ and $B = vwx$ of $L_k'$. We show
|
||||
$\mathrm{depth}(A) = \mathrm{depth}(B) = d - 1$.
|
||||
|
||||
By symmetry it suffices to handle $A$. The dual neighbours of $A$ in
|
||||
$L_k'$ are $A_{uw}$ (the inner face across $uw$, unchanged from $L_k$),
|
||||
$A_{ux}$ (the inner face across $ux$, unchanged), and $B$ (across the
|
||||
new edge $wx$). By balancedness of $\sigma$ applied to the edge $ux$:
|
||||
\begin{itemize}
|
||||
\item if $ux$ lies on the outer cycle of $L_k$, it remains on the outer
|
||||
cycle of $L_k'$, so $A \in \mathcal{B}'$ and $\mathrm{depth}(A) = 0$
|
||||
(which equals $d - 1$ because the balanced-with-outer-cycle case forces
|
||||
$d = 1$); or
|
||||
\item if $A_{ux}$ is an inner face, balancedness gives
|
||||
$\mathrm{depth}(A_{ux}) = d - 2$, so
|
||||
$\mathrm{depth}(A) \leq 1 + (d - 2) = d - 1$.
|
||||
\end{itemize}
|
||||
|
||||
For the lower bound in the second sub-case ($d \geq 2$): $A$'s edges are
|
||||
$uw$ (an edge of $F$, interior because $F$ has depth $d \geq 1$), $wx$
|
||||
(new, not on the outer cycle), and $ux$ (interior in this sub-case), so
|
||||
$A \notin \mathcal{B}'$. Moreover every neighbour of $A$ has depth $\geq
|
||||
d - 2$: $A_{uw}$ inherits depth $\geq d - 1$ from being a former
|
||||
neighbour of $F$, $A_{ux}$ has depth $d - 2$, and $B$ has depth $\geq
|
||||
d - 2$ by the same argument applied symmetrically. Therefore
|
||||
$\mathrm{depth}(A) \geq d - 1$, and combined with the upper bound,
|
||||
$\mathrm{depth}(A) = d - 1$.
|
||||
\end{proof}
|
||||
|
||||
\subsection*{When does a balanced surface switch exist?}
|
||||
|
||||
For a chord $uv$ of a maximal outerplanar graph, the \emph{span} of $uv$
|
||||
is the minimum, over the two arcs from $u$ to $v$ on the outer cycle,
|
||||
of the number of outer-cycle vertices strictly between them.
|
||||
|
||||
\begin{observation}
|
||||
\label{obs:span1-balanced-d1}
|
||||
For $d = 1$, an inner face $F$ admits a balanced surface switch on some
|
||||
edge iff at least one edge of $F$ has span $1$ in the outer cycle of
|
||||
$L_k$. The opposite triangle across that edge -- using the single
|
||||
outer-cycle vertex between its endpoints -- is then an ear of $F$ in
|
||||
$\mathcal{B}$, satisfying the $d = 1$ form of
|
||||
Definition~\ref{def:balanced-surface-switch}.
|
||||
\end{observation}
|
||||
|
||||
The smallest maximal-outerplanar configuration violating this is a
|
||||
$9$-vertex outer cycle triangulated so that the unique interior face
|
||||
$F = (0,3,6)$ has spans $(2,2,2)$ on its three edges
|
||||
(Figure~\ref{fig:no-balanced}). Each depth-$0$ neighbour of $F$ carries
|
||||
exactly one outer-cycle edge, not two, so none qualifies as an ear of
|
||||
$F$; no balanced surface switch is available.
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.55\textwidth]{fig_no_balanced_switch.png}
|
||||
\caption{$9$-vertex maximal outerplanar $L_k$. $F = (0,3,6)$ has
|
||||
$\mathrm{depth} = 1$ and all three of its edges have span $2$, so none
|
||||
of $F$'s depth-$0$ neighbours is an ear. No balanced surface switch is
|
||||
available on $F$.}
|
||||
\label{fig:no-balanced}
|
||||
\end{figure}
|
||||
|
||||
\subsection*{Preprocessing toward balanced switches}
|
||||
|
||||
When $F$ has depth $d \geq 1$ but admits no balanced surface switch,
|
||||
perform a single (unbalanced) surface switch on any edge of $F$ shared
|
||||
with a depth-$(d-1)$ neighbour. By Proposition~\ref{prop:balanced-descent}
|
||||
the result is at least one new depth-$(d-1)$ face; in Case~(ii) it is
|
||||
accompanied by a new depth-$d$ face $A$ that replaces $F$ as the next
|
||||
candidate. The hope is that the resulting $A$ admits a balanced
|
||||
surface switch, or that iterating the preprocessing eventually exposes
|
||||
one.
|
||||
|
||||
\begin{example}
|
||||
\label{ex:preprocessing}
|
||||
On the $9$-vertex example, the (unbalanced) surface switch on edge
|
||||
$uv = 03$ -- with $F' = (0,2,3)$, third vertex $x = 2$, and $w = 6$ --
|
||||
flips $03 \mapsto 26$ in $G$ and produces $A = (0,2,6)$ at depth $1$.
|
||||
The new face has spans $(1, 3, 2)$ on its edges, and the ear
|
||||
$(0,1,2)$ across the span-$1$ edge $02$ is now a balanced
|
||||
surface-switch target on $A$ (Figure~\ref{fig:preprocessing}).
|
||||
\end{example}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{fig_preprocessing.png}
|
||||
\caption{One step of preprocessing on the $9$-vertex example. Left:
|
||||
$F = (0,3,6)$ has no edge of span $1$; the chosen surface-switch edge
|
||||
$uv = 03$ (red) is unbalanced. Right: after the switch $03 \mapsto 26$
|
||||
(green), the new depth-$1$ face $A = (0,2,6)$ has its edge $02$ (red)
|
||||
at span $1$, exposing the ear $(0,1,2)$ as a balanced surface-switch
|
||||
target.}
|
||||
\label{fig:preprocessing}
|
||||
\end{figure}
|
||||
|
||||
We do not have a general termination theorem. The natural candidate
|
||||
monovariant for $d = 1$ is the minimum span among edges of the current
|
||||
depth-$1$ face that are shared with a depth-$0$ neighbour; in
|
||||
Example~\ref{ex:preprocessing} this drops from $2$ to $1$ in a single
|
||||
step. Whether such a monovariant strictly decreases under every
|
||||
unbalanced surface switch -- and a corresponding statement for $d \geq
|
||||
2$, where balancedness depends on depth-$(d-2)$ structure rather than
|
||||
just spans -- remains open.
|
||||
|
||||
\begin{question}
|
||||
\label{q:preprocessing-terminates}
|
||||
Does iterated preprocessing reach a balanced surface switch in finitely
|
||||
many steps from every initial configuration? Equivalently, is there a
|
||||
monovariant on the inner-face structure of $L_k$ that strictly decreases
|
||||
at every unbalanced surface switch on a maximum-depth face?
|
||||
\end{question}
|
||||
|
||||
\end{document}
|
||||