coloring_nested_tire_graphs: cycle sources, tire-tree decomposition, seam lemma
Definition 1.1 (Level source) is broadened: a level source is now a set
that is either a single vertex or a simple cycle, splitting the old
notion into 'vertex source' and 'cycle source'. Downstream theorems
(Prop 1.7, Lemma 1.8, Thm 1.17) remain stated for vertex sources but
are referenced by the new material with cycle sources.
New Theorem 1.19 (Tire-tree decomposition): for any tread T in
T(G, {v_0}) at depth d >= 1 with outer cycle C_T, the sub-graph G_T
inside C_T on the side away from v_0 is a triangulated disk; taking
C_T as a cycle source, T(G_T, C_T) is canonically iso to the
sub-tree of T(G, {v_0}) rooted at T. Proof in three steps:
(D1) triangulated-disk via Jordan curve, (D2) level-shift
ell_{G_T}(.) = ell_G(.) - d via shortest-path stays in R_T, (D3)
component-of-G'_k bijection with descendants of T.
Figure fig_tire_tree_decomposition.png (and its generator
experiments/draw_tire_tree_decomposition.py) illustrates the
decomposition on a 13-vertex, 5-level example with four nested seams
C_{T_R}, C_{T_L}, C_{T_{LL}}, C_{T_{LLL}}; the generator script
verifies the level-shift assertion on this instance. Vertex
positions are hand-tuned in TikZiT and copied back; the right-panel
labels are rotated relative to the parent G to emphasise the new
role of C_{T_L} as cycle source.
New Definition 1.21 (Seam): a seam is the outer-boundary cycle
B_out^{(T)} of a non-root tread T, separating G into the seam
interior G_T and seam exterior G_C^{ext}. Notation Col(X | C) for
boundary-restricted 4-colourings is also defined here.
New Definition 1.22 (Partial tire tree): G_{T_r}^{circle} =
G_{T_r} with V(C_{T_r}) removed, i.e. the strict interior of the
triangulated disk inside the seam.
New Lemma 1.23 (Seam edges shared by <= one other depth-d seam):
an edge on the seam of a depth-d tread T is in the seam of at most
one other depth-d tread T'. Proof via inner-dual-of-outerplanar-
is-a-tree: C_T bounds a face of the parent's O^{(T_p)} (outerplanar),
so each edge of O^{(T_p)} lies in at most two of its bounded face
cycles, giving at most one sibling seam containing e.
New Conjecture 1.24 (Seam structure of minimum 4CT counterexamples,
sketch): a hypothetical minimum 4CT counterexample has bilateral
colourability, bilateral incompatibility, Birkhoff's seam-length
>= 6 bound, and an innermost obstruction at a leaf tread T^* whose
seam interior is one of a finite list of minimal seam configurations,
with the boundary palette restriction propagating outward along the
root-to-T^* obstruction chain.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,480 @@
|
||||
"""Draw the tire-tree decomposition for Theorem~\\ref{thm:tire-tree-decomposition}.
|
||||
|
||||
Uses a Tutte embedding (barycentric solve with the outer face fixed on a
|
||||
convex polygon) to give a planar straight-line layout.
|
||||
|
||||
Panel (a): G with 13 vertices, 5 levels (v_0 at level 0; L_1, L_2, L_3, L_4
|
||||
on subsequent levels). Tutte outer face = h-g_1-g_2 (the deepest face from
|
||||
v_0), so v_0 ends up roughly central and the outer triangle is "outermost"
|
||||
in BFS-from-v_0 distance. Tree-of-treads has 5 nodes:
|
||||
T_0
|
||||
/ \\
|
||||
T_R T_L
|
||||
|
|
||||
T_LL
|
||||
|
|
||||
T_LLL
|
||||
|
||||
Panel (b): G_{T_L} on 10 vertices, with Tutte outer face = C_{T_L} = {a,c,d}.
|
||||
Levels in G_{T_L} satisfy ell_{G_{T_L}}(.) = ell_G(.) - 1 on V(G_{T_L});
|
||||
T(G_{T_L}, C_{T_L}) is the chain T_L -> T_LL -> T_LLL.
|
||||
"""
|
||||
import math
|
||||
import os
|
||||
import networkx as nx
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.lines import Line2D
|
||||
|
||||
OUT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build G.
|
||||
# ---------------------------------------------------------------------------
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from(['v0', 'a', 'b', 'c', 'd', 'e',
|
||||
'f1', 'f2', 'f3', 'g1', 'g2', 'g3', 'h'])
|
||||
|
||||
# v_0 fan
|
||||
for v in ['a', 'b', 'c', 'd']:
|
||||
G.add_edge('v0', v)
|
||||
# L_1 4-cycle
|
||||
G.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')])
|
||||
# Chord a-c (outside L_1 in the planar embedding)
|
||||
G.add_edge('a', 'c')
|
||||
# e-fan (Region R)
|
||||
for v in ['a', 'b', 'c']:
|
||||
G.add_edge('e', v)
|
||||
# f-triangle (Region L)
|
||||
G.add_edges_from([('f1', 'f2'), ('f2', 'f3'), ('f3', 'f1')])
|
||||
# Annular L_1 -> f-triangle: f_1~{a,d}, f_2~{d,c}, f_3~{a,c}
|
||||
G.add_edges_from([
|
||||
('f1', 'a'), ('f1', 'd'),
|
||||
('f2', 'd'), ('f2', 'c'),
|
||||
('f3', 'a'), ('f3', 'c'),
|
||||
])
|
||||
# g-triangle (inside f-triangle)
|
||||
G.add_edges_from([('g1', 'g2'), ('g2', 'g3'), ('g3', 'g1')])
|
||||
# Annular f-triangle -> g-triangle: f_1~{g_1, g_3}, f_2~{g_2, g_3}, f_3~{g_1, g_2}
|
||||
G.add_edges_from([
|
||||
('f1', 'g1'), ('f1', 'g3'),
|
||||
('f2', 'g2'), ('f2', 'g3'),
|
||||
('f3', 'g1'), ('f3', 'g2'),
|
||||
])
|
||||
# h-fan (inside g-triangle)
|
||||
for v in ['g1', 'g2', 'g3']:
|
||||
G.add_edge('h', v)
|
||||
|
||||
assert G.number_of_edges() == 3 * G.number_of_nodes() - 6, (
|
||||
f"G not a triangulation: |E|={G.number_of_edges()}, "
|
||||
f"expected {3 * G.number_of_nodes() - 6}"
|
||||
)
|
||||
|
||||
level_G = nx.shortest_path_length(G, source='v0')
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tutte embedding.
|
||||
# ---------------------------------------------------------------------------
|
||||
def tutte_embedding(graph, outer_face_cyclic, outer_radius=3.0,
|
||||
angle_offset_deg=90.0, outer_weight=1.0):
|
||||
"""Compute (weighted) Tutte embedding.
|
||||
|
||||
outer_face_cyclic: list of vertices on the outer face, in cyclic order.
|
||||
Outer vertices are fixed on a regular polygon of given radius; every
|
||||
interior vertex is placed at a convex combination of its neighbours'
|
||||
positions (solved as a linear system). Edges incident to an outer
|
||||
vertex carry weight `outer_weight`; interior-interior edges carry
|
||||
weight 1. All weights positive, so Tutte's theorem still gives a
|
||||
planar straight-line embedding. Larger `outer_weight` pulls interior
|
||||
vertices more strongly toward the outer triangle, spreading them out.
|
||||
"""
|
||||
n_outer = len(outer_face_cyclic)
|
||||
outer_positions = {}
|
||||
for i, v in enumerate(outer_face_cyclic):
|
||||
angle = math.radians(angle_offset_deg + i * 360 / n_outer)
|
||||
outer_positions[v] = (outer_radius * math.cos(angle),
|
||||
outer_radius * math.sin(angle))
|
||||
|
||||
outer_set = set(outer_face_cyclic)
|
||||
interior = [v for v in graph.nodes() if v not in outer_set]
|
||||
interior_idx = {v: i for i, v in enumerate(interior)}
|
||||
m = len(interior)
|
||||
if m == 0:
|
||||
return outer_positions
|
||||
|
||||
A = np.zeros((m, m))
|
||||
bx = np.zeros(m)
|
||||
by = np.zeros(m)
|
||||
|
||||
for v in interior:
|
||||
i = interior_idx[v]
|
||||
for u in graph.neighbors(v):
|
||||
w = outer_weight if u in outer_set else 1.0
|
||||
A[i, i] += w
|
||||
if u in outer_set:
|
||||
bx[i] += w * outer_positions[u][0]
|
||||
by[i] += w * outer_positions[u][1]
|
||||
else:
|
||||
j = interior_idx[u]
|
||||
A[i, j] -= w
|
||||
|
||||
x = np.linalg.solve(A, bx)
|
||||
y = np.linalg.solve(A, by)
|
||||
|
||||
pos = dict(outer_positions)
|
||||
for v in interior:
|
||||
i = interior_idx[v]
|
||||
pos[v] = (float(x[i]), float(y[i]))
|
||||
return pos
|
||||
|
||||
|
||||
def stretch_radially(pos, outer_face_cyclic, alpha=0.6):
|
||||
"""Stretch interior positions radially outward from the outer-face centroid.
|
||||
|
||||
Outer vertices are unchanged; for each interior vertex at radius r from
|
||||
the outer-face centroid, replace r by r' = R^(1-alpha) * r^alpha, where
|
||||
R is the radius of the outer vertices. With alpha < 1 this is a concave
|
||||
stretch that pushes small radii outward. Angles are preserved, so
|
||||
planarity of the underlying Tutte embedding is preserved.
|
||||
"""
|
||||
outer_set = set(outer_face_cyclic)
|
||||
outer_positions = [pos[v] for v in outer_face_cyclic]
|
||||
Cx = sum(p[0] for p in outer_positions) / len(outer_positions)
|
||||
Cy = sum(p[1] for p in outer_positions) / len(outer_positions)
|
||||
R = max(math.sqrt((p[0] - Cx)**2 + (p[1] - Cy)**2)
|
||||
for p in outer_positions)
|
||||
|
||||
new_pos = {}
|
||||
for v, p in pos.items():
|
||||
if v in outer_set:
|
||||
new_pos[v] = p
|
||||
continue
|
||||
dx, dy = p[0] - Cx, p[1] - Cy
|
||||
r = math.sqrt(dx * dx + dy * dy)
|
||||
if r < 1e-10:
|
||||
new_pos[v] = (Cx, Cy)
|
||||
continue
|
||||
r_new = (R ** (1 - alpha)) * (r ** alpha)
|
||||
scale = r_new / r
|
||||
new_pos[v] = (Cx + dx * scale, Cy + dy * scale)
|
||||
return new_pos
|
||||
|
||||
|
||||
# Panel (a) positions: hand-tuned in TikZiT and copied back here so the
|
||||
# matplotlib panel matches the .tikz layout the user is editing on Desktop.
|
||||
# The chord a-c is drawable as a straight line at these positions; the
|
||||
# d-a edge passes through f_1, so it's drawn as a slight Bezier curve.
|
||||
pos_G = {
|
||||
'v0': ( 0.00, 6.0),
|
||||
'a': (-5.50, -5.0),
|
||||
'b': (-2.75, 3.0),
|
||||
'c': ( 1.75, 3.0),
|
||||
'd': ( 8.00, -5.0),
|
||||
'e': (-1.50, 1.5),
|
||||
'f1': ( 1.50, -5.0),
|
||||
'f2': ( 4.00, -1.0),
|
||||
'f3': (-0.75, -1.0),
|
||||
'g1': ( 0.70, -3.0),
|
||||
'g2': ( 1.45, -1.5),
|
||||
'g3': ( 2.30, -3.0),
|
||||
'h': ( 1.55, -2.5),
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# G_{T_L}: subgraph inside C_{T_L} = {a, c, d}.
|
||||
# ---------------------------------------------------------------------------
|
||||
C_TL = {'a', 'c', 'd'}
|
||||
V_GTL = C_TL | {'f1', 'f2', 'f3', 'g1', 'g2', 'g3', 'h'}
|
||||
G_TL = G.subgraph(V_GTL).copy()
|
||||
level_GTL = nx.multi_source_dijkstra_path_length(G_TL, C_TL)
|
||||
|
||||
for v in V_GTL:
|
||||
assert level_GTL[v] == level_G[v] - 1
|
||||
|
||||
# Tutte for G_{T_L}: outer face = a-d-c (= C_{T_L}, the seam itself).
|
||||
# Cyclic order matches the planar boundary: a -> d -> c.
|
||||
outer_face_GTL = ['a', 'd', 'c']
|
||||
pos_GTL = tutte_embedding(G_TL, outer_face_GTL, outer_radius=2.8,
|
||||
angle_offset_deg=90, outer_weight=3.0)
|
||||
pos_GTL = stretch_radially(pos_GTL, outer_face_GTL, alpha=0.6)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Edge sets.
|
||||
# ---------------------------------------------------------------------------
|
||||
C_TR_edges = [('a', 'b'), ('b', 'c'), ('a', 'c')]
|
||||
C_TL_edges = [('a', 'd'), ('d', 'c'), ('a', 'c')]
|
||||
C_TLL_edges = [('f1', 'f2'), ('f2', 'f3'), ('f3', 'f1')]
|
||||
C_TLLL_edges = [('g1', 'g2'), ('g2', 'g3'), ('g3', 'g1')]
|
||||
fan_edges = [('v0', v) for v in ['a', 'b', 'c', 'd']]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tree inset helper.
|
||||
# ---------------------------------------------------------------------------
|
||||
def draw_tree_inset(parent_ax, position, tree_nodes, tree_edges, node_pos,
|
||||
label_text, highlight=None, title=None,
|
||||
xlim=(-1.4, 1.4), ylim=(-3.6, 0.6)):
|
||||
ax = parent_ax.inset_axes(position)
|
||||
for u, v in tree_edges:
|
||||
x0, y0 = node_pos[u]
|
||||
x1, y1 = node_pos[v]
|
||||
ax.plot([x0, x1], [y0, y1], color='black', lw=1.4, zorder=1)
|
||||
for n in tree_nodes:
|
||||
x, y = node_pos[n]
|
||||
is_hi = highlight and n in highlight
|
||||
ax.scatter([x], [y], s=380, color='#fde68a' if is_hi else '#e5e7eb',
|
||||
edgecolors='black', linewidths=1.8 if is_hi else 1.0, zorder=3)
|
||||
ax.text(x, y, label_text[n], ha='center', va='center',
|
||||
fontsize=7.5, fontweight='bold', zorder=4)
|
||||
ax.set_xlim(*xlim); ax.set_ylim(*ylim)
|
||||
ax.set_aspect('equal')
|
||||
ax.set_xticks([]); ax.set_yticks([])
|
||||
if title:
|
||||
ax.set_title(title, fontsize=8.5, pad=2)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_edgecolor('#9ca3af')
|
||||
spine.set_linewidth(0.8)
|
||||
ax.patch.set_facecolor('#f9fafb')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Draw.
|
||||
# ---------------------------------------------------------------------------
|
||||
LEVEL_COLOR = {
|
||||
0: '#1e293b',
|
||||
1: '#475569',
|
||||
2: '#94a3b8',
|
||||
3: '#cbd5e1',
|
||||
4: '#f1f5f9',
|
||||
}
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(16, 9))
|
||||
|
||||
|
||||
def _vertex_label(name):
|
||||
"""Render 'f1' as 'f_1' (subscript) and 'v0' as 'v_0' for display."""
|
||||
if len(name) >= 2 and name[0].isalpha() and name[1:].isdigit():
|
||||
return f'{name[0]}_{{{name[1:]}}}'
|
||||
return name
|
||||
|
||||
|
||||
def draw_panel(ax, graph, pos, levels, seams, fan, title, xlim, ylim,
|
||||
text_color_threshold=4, label_map=None):
|
||||
"""seams: list of (edges, color, width) tuples; fan: edges list or None.
|
||||
label_map: optional dict mapping vertex names to displayed names (so the
|
||||
panel can show a relabelled version of the graph)."""
|
||||
nx.draw_networkx_edges(graph, pos, ax=ax, edge_color='#d1d5db', width=1.1)
|
||||
if fan is not None:
|
||||
nx.draw_networkx_edges(graph, pos, edgelist=fan, ax=ax,
|
||||
edge_color='#3b82f6', width=1.5, style='dashed')
|
||||
for edges, color, width in seams:
|
||||
nx.draw_networkx_edges(graph, pos, edgelist=edges, ax=ax,
|
||||
edge_color=color, width=width)
|
||||
for v, (x, y) in pos.items():
|
||||
lev = levels[v]
|
||||
text_color = 'white' if lev < text_color_threshold else 'black'
|
||||
display_name = (label_map or {}).get(v, v)
|
||||
ax.scatter([x], [y], s=520, color=LEVEL_COLOR[lev],
|
||||
edgecolors='black', linewidths=1.0, zorder=3)
|
||||
ax.text(x, y, f'${_vertex_label(display_name)}$\n$\\ell{{=}}{lev}$',
|
||||
ha='center', va='center',
|
||||
color=text_color, fontsize=7, fontweight='bold', zorder=4)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_xlim(*xlim); ax.set_ylim(*ylim)
|
||||
ax.set_title(title, fontsize=10.5, pad=5)
|
||||
|
||||
|
||||
# Compute panel limits from the Tutte positions, with padding.
|
||||
def compute_limits(pos, pad=0.5):
|
||||
xs = [p[0] for p in pos.values()]
|
||||
ys = [p[1] for p in pos.values()]
|
||||
return (min(xs) - pad, max(xs) + pad), (min(ys) - pad, max(ys) + pad)
|
||||
|
||||
|
||||
xlim_a, ylim_a = compute_limits(pos_G, pad=0.6)
|
||||
xlim_b, ylim_b = compute_limits(pos_GTL, pad=0.6)
|
||||
|
||||
# ============================================================================
|
||||
# Panel (a): G -- positions match Desktop/tire_tree_decomposition.tikz.
|
||||
# Draw all non-seam edges as plain gray (no separate dashed fan style here,
|
||||
# to match the TikZiT version). Edge a-d at y = -5 would pass through f_1
|
||||
# if drawn straight, so we render it (and seam C_{T_L}'s a-d component) as
|
||||
# a slight Bezier curve via FancyArrowPatch.
|
||||
# ============================================================================
|
||||
ax = axes[0]
|
||||
|
||||
# Non-seam edges as straight gray lines; a-d and v_0-a are drawn curved
|
||||
# below.
|
||||
_curved_pairs = [{'a', 'd'}, {'v0', 'a'}]
|
||||
non_seam_edges = [e for e in G.edges
|
||||
if set(e) not in _curved_pairs
|
||||
and set(e) not in (set(s) for s in C_TR_edges + C_TL_edges
|
||||
+ C_TLL_edges + C_TLLL_edges)]
|
||||
nx.draw_networkx_edges(G, pos_G, edgelist=non_seam_edges, ax=ax,
|
||||
edge_color='#d1d5db', width=1.1)
|
||||
|
||||
# Curved edges (FancyArrowPatch). a-d dodges f_1; v_0-a is bent for
|
||||
# visual balance (mirrors the TikZiT `bend right`).
|
||||
from matplotlib.patches import FancyArrowPatch
|
||||
def add_curved(ax, p_from, p_to, *, color, lw, rad, ls='-', zorder=2):
|
||||
ax.add_patch(FancyArrowPatch(
|
||||
posA=p_from, posB=p_to,
|
||||
arrowstyle='-', connectionstyle=f'arc3,rad={rad}',
|
||||
color=color, linewidth=lw, linestyle=ls, zorder=zorder,
|
||||
))
|
||||
add_curved(ax, pos_G['a'], pos_G['d'], color='#d1d5db', lw=1.1, rad=0.15)
|
||||
add_curved(ax, pos_G['v0'], pos_G['a'], color='#d1d5db', lw=1.1, rad=0.25)
|
||||
|
||||
# Seams (straight, since the layout is now planar with straight chord).
|
||||
# Order: bottom first (C_{T_LL}, C_{T_LLL}), then chord/L_1 seams on top.
|
||||
nx.draw_networkx_edges(G, pos_G,
|
||||
edgelist=[('f1', 'f2'), ('f2', 'f3'), ('f3', 'f1')],
|
||||
ax=ax, edge_color='#9333ea', width=2.2)
|
||||
nx.draw_networkx_edges(G, pos_G,
|
||||
edgelist=[('g1', 'g2'), ('g2', 'g3'), ('g3', 'g1')],
|
||||
ax=ax, edge_color='#0d9488', width=2.0)
|
||||
nx.draw_networkx_edges(G, pos_G,
|
||||
edgelist=[('a', 'b'), ('b', 'c')],
|
||||
ax=ax, edge_color='#ea580c', width=2.4)
|
||||
nx.draw_networkx_edges(G, pos_G,
|
||||
edgelist=[('a', 'c'), ('d', 'c')],
|
||||
ax=ax, edge_color='#dc2626', width=2.8)
|
||||
add_curved(ax, pos_G['a'], pos_G['d'], color='#dc2626', lw=2.8, rad=0.15, zorder=4)
|
||||
|
||||
# Vertices.
|
||||
for v, (x, y) in pos_G.items():
|
||||
lev = level_G[v]
|
||||
text_color = 'white' if lev < 4 else 'black'
|
||||
ax.scatter([x], [y], s=520, color=LEVEL_COLOR[lev],
|
||||
edgecolors='black', linewidths=1.0, zorder=5)
|
||||
ax.text(x, y, f'${_vertex_label(v)}$\n$\\ell{{=}}{lev}$',
|
||||
ha='center', va='center',
|
||||
color=text_color, fontsize=7, fontweight='bold', zorder=6)
|
||||
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
# The a-d arc bulges below y=-5 by ~ rad * |a - d| / 2 ≈ 1.0 with rad=0.15;
|
||||
# pad the y range so it isn't clipped.
|
||||
xlim_a, ylim_a = compute_limits(pos_G, pad=0.8)
|
||||
ylim_a = (ylim_a[0] - 1.2, ylim_a[1])
|
||||
ax.set_xlim(*xlim_a); ax.set_ylim(*ylim_a)
|
||||
ax.set_title(
|
||||
r"$(a)$ $G$: 13 vertices, BFS levels $\ell_G \in \{0,1,2,3,4\}$,"
|
||||
"\n"
|
||||
r"four nested seams $C_{T_R}, C_{T_L}, C_{T_{LL}}, C_{T_{LLL}}$ "
|
||||
r"(chord $a$-$c$ drawn straight in this layout).",
|
||||
fontsize=10.5, pad=5,
|
||||
)
|
||||
|
||||
tree_pos_a = {
|
||||
'T_0': (0.0, 0.0),
|
||||
'T_R': (-0.7, -1.0),
|
||||
'T_L': (0.7, -1.0),
|
||||
'T_LL': (0.7, -2.0),
|
||||
'T_LLL': (0.7, -3.0),
|
||||
}
|
||||
tree_labels = {
|
||||
'T_0': r'$T_0$', 'T_R': r'$T_R$', 'T_L': r'$T_L$',
|
||||
'T_LL': r'$T_{LL}$', 'T_LLL': r'$T_{LLL}$',
|
||||
}
|
||||
draw_tree_inset(
|
||||
axes[0], [0.70, 0.42, 0.28, 0.55],
|
||||
tree_nodes=['T_0', 'T_R', 'T_L', 'T_LL', 'T_LLL'],
|
||||
tree_edges=[('T_0', 'T_R'), ('T_0', 'T_L'),
|
||||
('T_L', 'T_LL'), ('T_LL', 'T_LLL')],
|
||||
node_pos=tree_pos_a, label_text=tree_labels,
|
||||
highlight={'T_L', 'T_LL', 'T_LLL'},
|
||||
title=r'$\mathcal{T}(G, \{v_0\})$',
|
||||
xlim=(-1.4, 1.4), ylim=(-3.6, 0.6),
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# Panel (b): G_{T_L}. Vertex names are rotated relative to the parent G
|
||||
# (a->c, c->d, d->a; f_1->f_3, f_2->f_1, f_3->f_2; g_1->g_2, g_2->g_3,
|
||||
# g_3->g_1; h stays h) -- the relabelling emphasises the new role of
|
||||
# C_{T_L} as cycle source, with the boundary now naturally read as
|
||||
# {a, c, d} in cyclic order from a position the user picked.
|
||||
# ============================================================================
|
||||
GTL_LABEL_MAP = {
|
||||
'a': 'c', 'c': 'd', 'd': 'a',
|
||||
'f1': 'f3', 'f2': 'f1', 'f3': 'f2',
|
||||
'g1': 'g2', 'g2': 'g3', 'g3': 'g1',
|
||||
'h': 'h',
|
||||
}
|
||||
|
||||
draw_panel(
|
||||
axes[1], G_TL, pos_GTL, level_GTL,
|
||||
seams=[
|
||||
(C_TL_edges, '#dc2626', 2.8),
|
||||
(C_TLL_edges, '#9333ea', 2.2),
|
||||
(C_TLLL_edges, '#0d9488', 2.0),
|
||||
],
|
||||
fan=None,
|
||||
title=(
|
||||
r"$(b)$ $G_{T_L}$ (Tutte embedding, outer face $C_{T_L} = \{a,c,d\}$):"
|
||||
" 10 vertices, cycle source $C_{T_L}$,\n"
|
||||
r"$\ell_{G_{T_L}}(\cdot) = \ell_G(\cdot) - 1$; "
|
||||
r"$\mathcal{T}(G_{T_L}, C_{T_L})$ is the chain $T_L \to T_{LL} \to T_{LLL}$."
|
||||
),
|
||||
xlim=xlim_b, ylim=ylim_b,
|
||||
text_color_threshold=3,
|
||||
label_map=GTL_LABEL_MAP,
|
||||
)
|
||||
|
||||
sub_tree_pos = {
|
||||
'T_L': (0.0, 0.0),
|
||||
'T_LL': (0.0, -1.0),
|
||||
'T_LLL': (0.0, -2.0),
|
||||
}
|
||||
draw_tree_inset(
|
||||
axes[1], [0.70, 0.42, 0.28, 0.55],
|
||||
tree_nodes=['T_L', 'T_LL', 'T_LLL'],
|
||||
tree_edges=[('T_L', 'T_LL'), ('T_LL', 'T_LLL')],
|
||||
node_pos=sub_tree_pos, label_text=tree_labels,
|
||||
highlight={'T_L', 'T_LL', 'T_LLL'},
|
||||
title=r'$\mathcal{T}(G_{T_L}, C_{T_L})$',
|
||||
xlim=(-1.0, 1.0), ylim=(-2.6, 0.4),
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# Legend + suptitle
|
||||
# ============================================================================
|
||||
legend = [
|
||||
Line2D([0], [0], marker='o', color='w', label=r'$\ell = 0$',
|
||||
markerfacecolor=LEVEL_COLOR[0], markeredgecolor='black', markersize=10),
|
||||
Line2D([0], [0], marker='o', color='w', label=r'$\ell = 1$',
|
||||
markerfacecolor=LEVEL_COLOR[1], markeredgecolor='black', markersize=10),
|
||||
Line2D([0], [0], marker='o', color='w', label=r'$\ell = 2$',
|
||||
markerfacecolor=LEVEL_COLOR[2], markeredgecolor='black', markersize=10),
|
||||
Line2D([0], [0], marker='o', color='w', label=r'$\ell = 3$',
|
||||
markerfacecolor=LEVEL_COLOR[3], markeredgecolor='black', markersize=10),
|
||||
Line2D([0], [0], marker='o', color='w', label=r'$\ell = 4$',
|
||||
markerfacecolor=LEVEL_COLOR[4], markeredgecolor='black', markersize=10),
|
||||
Line2D([0], [0], color='#ea580c', lw=2.4, label=r'seam $C_{T_R}$'),
|
||||
Line2D([0], [0], color='#dc2626', lw=2.8, label=r'seam $C_{T_L}$'),
|
||||
Line2D([0], [0], color='#9333ea', lw=2.2, label=r'seam $C_{T_{LL}}$'),
|
||||
Line2D([0], [0], color='#0d9488', lw=2.0, label=r'seam $C_{T_{LLL}}$'),
|
||||
]
|
||||
fig.legend(handles=legend, loc='lower center', ncol=5, fontsize=9.5,
|
||||
framealpha=0.95, columnspacing=1.8)
|
||||
|
||||
fig.suptitle(
|
||||
r"Tire-tree decomposition (Theorem 1.19): every tread $T$ is the root "
|
||||
r"of its own tree of tire treads $\mathcal{T}(G_T, C_T)$.",
|
||||
fontsize=12, y=0.96,
|
||||
)
|
||||
fig.subplots_adjust(top=0.88, bottom=0.16, left=0.02, right=0.98, wspace=0.05)
|
||||
|
||||
out = os.path.join(OUT_DIR, 'fig_tire_tree_decomposition.png')
|
||||
fig.savefig(out, dpi=180, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
|
||||
print(f'G: |V|={G.number_of_nodes()}, |E|={G.number_of_edges()}, '
|
||||
f'levels {sorted(set(level_G.values()))}')
|
||||
print(f'G_TL: |V|={G_TL.number_of_nodes()}, |E|={G_TL.number_of_edges()}, '
|
||||
f'levels {sorted(set(level_GTL.values()))}')
|
||||
print(f'verified level shift (D2): ell_GTL(v) = ell_G(v) - 1 for all '
|
||||
f'{len(V_GTL)} v in V(G_TL)')
|
||||
print(f'panel (a): hand-tuned positions (see Desktop/tire_tree_decomposition.tikz)')
|
||||
print(f'Tutte (G_TL): outer face = {outer_face_GTL}')
|
||||
print(f'wrote {out}')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 364 KiB |
@@ -30,6 +30,14 @@
|
||||
\newlabel{rem:count-general-outerplanar}{{1.16}{10}}
|
||||
\newlabel{thm:tread-tree}{{1.17}{10}}
|
||||
\newlabel{rem:tree-multiple-children}{{1.18}{11}}
|
||||
\newlabel{thm:tire-tree-decomposition}{{1.19}{12}}
|
||||
\newlabel{rem:tree-coloring-factorisation}{{1.20}{13}}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Tire-tree decomposition (Theorem\nonbreakingspace 1.19\hbox {}) on a $13$-vertex maximal planar example $G$ with five BFS levels. $(a)$ $G$ with vertex source $v_0$ and $\ell _G \in \{0,1,2,3,4\}$; four nested seams are highlighted, $C_{T_R} = \{a,b,c\}$ (orange), $C_{T_L} = \{a,c,d\}$ (red, including the chord $a$-$c$ shared with $C_{T_R}$), $C_{T_{LL}} = \{f_1, f_2, f_3\}$ (purple), $C_{T_{LLL}} = \{g_1, g_2, g_3\}$ (teal). Inset: the rooted tree of tire treads $\mathcal {T}(G, \{v_0\})$ branches at $T_0$ into the leaf $T_R$ (containing $e$) and a chain $T_L \to T_{LL} \to T_{LLL}$ (the highlighted sub-tree). $(b)$ The disk $G_{T_L}$ inside the seam $C_{T_L}$, drawn standalone with $C_{T_L}$ as cycle source and vertex labels rotated to match the new (cycle-source) role of the boundary triangle. $\ell _{G_{T_L}}(\cdot ) = \ell _G(\cdot ) - 1$ on $V(G_{T_L})$ (verified by the generator script), and $\mathcal {T}(G_{T_L}, C_{T_L})$ is the chain $T_L \to T_{LL} \to T_{LLL}$, iso to the highlighted sub-tree of $(a)$.}}{14}{}\protected@file@percent }
|
||||
\newlabel{fig:tire-tree-decomposition}{{5}{14}}
|
||||
\newlabel{def:seam}{{1.21}{14}}
|
||||
\newlabel{def:partial-tire-tree}{{1.22}{15}}
|
||||
\newlabel{lem:seam-edge-shared}{{1.23}{15}}
|
||||
\newlabel{conj:seam-counterexample}{{1.24}{15}}
|
||||
\bibcite{tait-original}{1}
|
||||
\bibcite{bauerfeld-depth}{2}
|
||||
\bibcite{bauerfeld-nested-tire-duals}{3}
|
||||
@@ -38,6 +46,5 @@
|
||||
\newlabel{tocindent1}{17.77782pt}
|
||||
\newlabel{tocindent2}{0pt}
|
||||
\newlabel{tocindent3}{0pt}
|
||||
\newlabel{rem:tree-coloring-factorisation}{{1.19}{12}}
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{12}{}\protected@file@percent }
|
||||
\gdef \@abspage@last{12}
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{16}{}\protected@file@percent }
|
||||
\gdef \@abspage@last{16}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 27 MAY 2026 04:39
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 27 MAY 2026 22:18
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
@@ -498,58 +498,76 @@ e
|
||||
<fig_dual_depth.png, id=25, 642.8015pt x 606.265pt>
|
||||
File: fig_dual_depth.png Graphic file (type png)
|
||||
<use fig_dual_depth.png>
|
||||
Package pdftex.def Info: fig_dual_depth.png used on input line 124.
|
||||
Package pdftex.def Info: fig_dual_depth.png used on input line 128.
|
||||
(pdftex.def) Requested size: 251.9989pt x 237.67276pt.
|
||||
|
||||
[2 <./fig_dual_depth.png>]
|
||||
<fig_tire_example.png, id=31, 559.64081pt x 375.804pt>
|
||||
File: fig_tire_example.png Graphic file (type png)
|
||||
<use fig_tire_example.png>
|
||||
Package pdftex.def Info: fig_tire_example.png used on input line 179.
|
||||
Package pdftex.def Info: fig_tire_example.png used on input line 183.
|
||||
(pdftex.def) Requested size: 280.79956pt x 188.56097pt.
|
||||
[3 <./fig_tire_example.png>] [4] [5] [6]
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[7] [8] [9] [10] [11] [12] (./paper.aux) )
|
||||
[7] [8] [9] [10] [11] [12]
|
||||
<fig_tire_tree_decomposition.png, id=72, 1101.3145pt x 633.9685pt>
|
||||
File: fig_tire_tree_decomposition.png Graphic file (type png)
|
||||
<use fig_tire_tree_decomposition.png>
|
||||
Package pdftex.def Info: fig_tire_tree_decomposition.png used on input line 10
|
||||
98.
|
||||
(pdftex.def) Requested size: 341.9989pt x 196.86678pt.
|
||||
|
||||
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[13] [14 <./fig_tire_tree_decomposition.png>]
|
||||
Overfull \hbox (1.78508pt too wide) in paragraph at lines 1228--1230
|
||||
[]\OT1/cmr/m/n/10 Length lower bound (Birkhoff). \OT1/cmr/m/it/10 Ev-ery non-tr
|
||||
ivial seam $\OML/cmm/m/it/10 C$ \OT1/cmr/m/it/10 of $\OML/cmm/m/it/10 G$ \OT1/c
|
||||
mr/m/it/10 has $\OMS/cmsy/m/n/10 j\OML/cmm/m/it/10 V\OT1/cmr/m/n/10 (\OML/cmm/m
|
||||
/it/10 C\OT1/cmr/m/n/10 )\OMS/cmsy/m/n/10 j ^^U
|
||||
[]
|
||||
|
||||
[15] [16] (./paper.aux) )
|
||||
Here is how much of TeX's memory you used:
|
||||
14048 strings out of 478268
|
||||
279229 string characters out of 5846347
|
||||
563840 words of memory out of 5000000
|
||||
31872 multiletter control sequences out of 15000+600000
|
||||
14061 strings out of 478268
|
||||
279616 string characters out of 5846347
|
||||
563910 words of memory out of 5000000
|
||||
31884 multiletter control sequences out of 15000+600000
|
||||
478218 words of font info for 62 fonts, out of 8000000 for 9000
|
||||
1302 hyphenation exceptions out of 8191
|
||||
84i,12n,89p,1156b,803s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
</usr/local/texlive/2022/texmf-dist/f
|
||||
onts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/texmf-dist/fo
|
||||
nts/type1/public/amsfonts/cm/cmbx8.pfb></usr/local/texlive/2022/texmf-dist/font
|
||||
s/type1/public/amsfonts/cm/cmcsc10.pfb></usr/local/texlive/2022/texmf-dist/font
|
||||
s/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/cmmi5.pfb></usr/local/texlive/2022/texmf-dist/fonts/ty
|
||||
pe1/public/amsfonts/cm/cmmi6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type
|
||||
1/public/amsfonts/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/
|
||||
public/amsfonts/cm/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/pu
|
||||
blic/amsfonts/cm/cmmi9.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/publ
|
||||
ic/amsfonts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public
|
||||
/amsfonts/cm/cmr5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/am
|
||||
sfonts/cm/cmr6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfo
|
||||
nts/cm/cmr7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts
|
||||
/cm/cmr8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm
|
||||
/cmr9.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cm
|
||||
sy10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cms
|
||||
y5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6
|
||||
.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.p
|
||||
fb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy9.pfb
|
||||
></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb>
|
||||
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></
|
||||
usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pf
|
||||
b></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msbm1
|
||||
0.pfb>
|
||||
Output written on paper.pdf (12 pages, 618557 bytes).
|
||||
84i,12n,89p,1168b,803s 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/cmbx8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/am
|
||||
sfonts/cm/cmcsc10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/am
|
||||
sfonts/cm/cmex10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/ams
|
||||
fonts/cm/cmmi10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsf
|
||||
onts/cm/cmmi5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfon
|
||||
ts/cm/cmmi6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts
|
||||
/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/c
|
||||
m/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/
|
||||
cmmi9.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cm
|
||||
r10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr5
|
||||
.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr6.pf
|
||||
b></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb><
|
||||
/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></us
|
||||
r/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr9.pfb></usr/l
|
||||
ocal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/lo
|
||||
cal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy5.pfb></usr/loca
|
||||
l/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6.pfb></usr/local/
|
||||
texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/te
|
||||
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy9.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></usr/local/tex
|
||||
live/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msbm10.pfb>
|
||||
Output written on paper.pdf (16 pages, 927226 bytes).
|
||||
PDF statistics:
|
||||
177 PDF objects out of 1000 (max. 8388607)
|
||||
107 compressed objects within 2 object streams
|
||||
192 PDF objects out of 1000 (max. 8388607)
|
||||
116 compressed objects within 2 object streams
|
||||
0 named destinations out of 1000 (max. 500000)
|
||||
23 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
28 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -87,8 +87,12 @@ 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 any vertex $v \in V$; we write
|
||||
$S = \{v\}$ for the level-0 source.
|
||||
A \emph{level source} of $G$ is a set $S \subseteq V$ that is either
|
||||
\begin{itemize}
|
||||
\item a single vertex $\{v\}$ (a \emph{vertex source}), or
|
||||
\item a set inducing a simple cycle in $G$ --- i.e.\ $G[S]$ is a
|
||||
simple cycle of length $\geq 3$ (a \emph{cycle source}).
|
||||
\end{itemize}
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}[Levels]
|
||||
@@ -932,6 +936,186 @@ of Remark~\ref{rem:hamilton-cycle-spoke-only}) with a non-empty
|
||||
interior, $T_p$ has exactly one child.
|
||||
\end{remark}
|
||||
|
||||
\begin{theorem}[Tire-tree decomposition]
|
||||
\label{thm:tire-tree-decomposition}
|
||||
Let $G$ be a maximal planar graph with planar embedding $\Pi_G$ and let
|
||||
$v_0 \in V(G)$. The tree of tire treads $\mathcal{T}(G, \{v_0\})$ of
|
||||
Theorem~\ref{thm:tread-tree} \emph{decomposes $G$ into nested tires}:
|
||||
it is a finite rooted tree, rooted at the depth-$0$ tread containing
|
||||
$v_0$, whose nodes (tire treads) partition the bounded faces of $G$
|
||||
(Theorem~\ref{thm:tread-partition}).
|
||||
|
||||
This decomposition is moreover \emph{self-similar}. For any tread $T$
|
||||
in $\mathcal{T}(G, \{v_0\})$ at depth $d \ge 1$, with outer-boundary
|
||||
cycle $C_T := B_{\mathrm{out}}^{(T)}$, let $G_T$ be the sub-graph of $G$
|
||||
induced by $C_T$ together with all vertices of $G$ lying in the closed
|
||||
planar region $R_T \subset |\Pi_G|$ bounded by $C_T$ on the side of
|
||||
$C_T$ away from $v_0$. Then:
|
||||
\begin{enumerate}
|
||||
\item[(D1)] $G_T$, with the embedding inherited from $\Pi_G$, is a
|
||||
\emph{triangulated disk}: every bounded face is a triangle,
|
||||
and the outer face is bounded by $C_T$.
|
||||
\item[(D2)] Taking $C_T$ as a cycle source of $G_T$ (so $C_T$ has
|
||||
level $0$ in $G_T$ and the BFS-from-$C_T$ levels in $G_T$
|
||||
equal $\ell_G(\cdot) - d$ on $V(G_T)$), the construction of
|
||||
Theorem~\ref{thm:tread-tree} extends to give a rooted tree
|
||||
of tire treads $\mathcal{T}(G_T, C_T)$ whose depth-$0$ root
|
||||
tread has $B_{\mathrm{out}} = C_T$ and inner outerplanar
|
||||
graph $O = O^{(T)}$.
|
||||
\item[(D3)] $\mathcal{T}(G_T, C_T)$ is canonically iso to the sub-tree
|
||||
of $\mathcal{T}(G, \{v_0\})$ rooted at $T$, preserving
|
||||
outer-boundary cycles, inner outerplanar graphs, and the
|
||||
parent--child face correspondence.
|
||||
\end{enumerate}
|
||||
|
||||
In short: pick any vertex $v_0 \in V(G)$ to root the global tree
|
||||
$\mathcal{T}(G, \{v_0\})$ describing the whole graph; pick any tread $T$
|
||||
in this tree; then $T$ is itself the root of a local tree
|
||||
$\mathcal{T}(G_T, C_T)$ describing the triangulated disk of $G$ inside
|
||||
$C_T$, with $C_T$ as cycle source. Maximal planar graphs decompose
|
||||
into nested trees of tire treads.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
\emph{Decomposition.} Theorem~\ref{thm:tread-tree} gives the rooted
|
||||
tree structure of $\mathcal{T}(G, \{v_0\})$, with root the depth-$0$
|
||||
tread containing $v_0$; Theorem~\ref{thm:tread-partition} gives that
|
||||
its tire treads partition the bounded faces of $G$. Finiteness of
|
||||
the tree is immediate from finiteness of $G$.
|
||||
|
||||
\emph{(D1) $G_T$ is a triangulated disk.} By
|
||||
Lemma~\ref{lem:tire-component} applied to the component of $G'_d$ that
|
||||
gives rise to $T$, the outer boundary $C_T = B_{\mathrm{out}}^{(T)}$ is
|
||||
a simple cycle in $L_d^G$. By the Jordan curve theorem, $C_T$
|
||||
separates $|\Pi_G| \setminus C_T$ into two open regions; $R_T$ is the
|
||||
closure of the one not containing $v_0$. The bounded faces of $G_T$ in
|
||||
its inherited embedding are exactly the bounded faces of $G$ contained
|
||||
in $R_T$, each of which is a triangle since $G$ is a triangulation.
|
||||
The unbounded face of $G_T$'s embedding is the complement of $R_T$,
|
||||
whose boundary is $C_T$.
|
||||
|
||||
\emph{(D2) Level shift.} We show $\mathrm{dist}_{G_T}(v, C_T) =
|
||||
\ell_G(v) - d$ for every $v \in V(G_T)$. When $v \in C_T$ both sides
|
||||
equal $0$, so fix $v \in V(G_T) \setminus C_T$.
|
||||
|
||||
\smallskip
|
||||
|
||||
\emph{Step 1: $\mathrm{dist}_G(v, C_T) = \ell_G(v) - d$.} A shortest
|
||||
$G$-path from $v$ to $v_0$ must visit $C_T$, since $v$ and $v_0$ lie in
|
||||
different open regions of $|\Pi_G| \setminus C_T$; let $w$ be its first
|
||||
$C_T$-vertex. The $v$-to-$w$ sub-path has length $\ge \mathrm{dist}_G(v,
|
||||
C_T)$ and the $w$-to-$v_0$ sub-path has length $\ell_G(w) = d$, so
|
||||
$\ell_G(v) \ge \mathrm{dist}_G(v, C_T) + d$. Conversely, concatenating
|
||||
a shortest $G$-path from $v$ to a nearest $C_T$-vertex $w'$ with a
|
||||
shortest $G$-path from $w'$ to $v_0$ gives a $v$-to-$v_0$ path of
|
||||
length $\mathrm{dist}_G(v, C_T) + d$, so $\ell_G(v) \le
|
||||
\mathrm{dist}_G(v, C_T) + d$.
|
||||
|
||||
\smallskip
|
||||
|
||||
\emph{Step 2: $\mathrm{dist}_{G_T}(v, C_T) = \mathrm{dist}_G(v, C_T)$.}
|
||||
The inequality $\ge$ is automatic since $G_T \subseteq G$. For $\le$,
|
||||
pick a shortest $G$-path $\pi$ from $v$ to $C_T$; we may assume $\pi$
|
||||
has no internal vertex in $C_T$ (truncate otherwise). Any internal
|
||||
vertex of $\pi$ then lies in the same open region of $|\Pi_G| \setminus
|
||||
C_T$ as $v$, i.e.\ in $R_T \setminus C_T \subseteq V(G_T)$; every edge
|
||||
of $\pi$ has both endpoints in $V(G_T)$ and so lies in $E(G_T)$. Hence
|
||||
$\pi$ is a path in $G_T$ realising $\mathrm{dist}_G(v, C_T)$.
|
||||
|
||||
\smallskip
|
||||
|
||||
Combining the two steps yields $\mathrm{dist}_{G_T}(v, C_T) = \ell_G(v)
|
||||
- d$, as claimed.
|
||||
|
||||
\emph{(D3) Tree iso.} By (D2), $L_k^{G_T} = L_{d+k}^G \cap V(G_T)$ for
|
||||
every $k \ge 0$. For a bounded face $f$ of $G_T$, dual depth in $G_T$
|
||||
equals $\min_{u \in V(f)} \ell_{G_T}(u) = \min_{u \in V(f)} \ell_G(u) -
|
||||
d = \delta_G(d_f) - d$. Hence the inner-dual subgraph $(G_T)'_{k}$ at
|
||||
depth $k$ in $G_T$ is the induced subgraph of $G'_{d+k}$ on the faces
|
||||
of $G$ lying in $R_T$, and two such faces are dual-adjacent in $G_T'$
|
||||
iff they are dual-adjacent in $G'$ (the shared edge is in $E(G_T)$).
|
||||
|
||||
\smallskip
|
||||
|
||||
\emph{Step 3: components of $(G_T)'_{k}$ are precisely the depth-$(d+k)$
|
||||
descendants of $T$ in $\mathcal{T}(G, \{v_0\})$.} We show by induction
|
||||
on $k$ that a component $C'$ of $G'_{d+k}$ has $F_{C'} \subseteq R_T$
|
||||
iff $C'$ is a depth-$(d+k)$ descendant of $T$.
|
||||
|
||||
For $k = 0$: the components of $G'_d$ are the depth-$d$ treads; the
|
||||
component giving rise to $T$ has its faces in $T$'s tread region
|
||||
$R \subseteq R_T$, while any other depth-$d$ tread $T''$ has
|
||||
$C_{T''}$ disjoint from $C_T$ and lying in a different bounded face of
|
||||
$O^{(T_p'')}$ at depth $d - 1$, hence $R_{T''} \cap R_T = \emptyset$.
|
||||
|
||||
For $k \ge 1$: by Theorem~\ref{thm:tread-tree}, each component $C'$ of
|
||||
$G'_{d+k}$ has a unique parent $C'_p$ at depth $d+k-1$, with
|
||||
$B_{\mathrm{out}}^{(C')}$ bounding a face of $O^{(C'_p)}$; equivalently
|
||||
$R_{C'}$ lies inside that bounded face, hence inside $R_{C'_p}$. By
|
||||
the induction hypothesis $R_{C'_p} \subseteq R_T$ iff $C'_p$ is a
|
||||
descendant of $T$ at depth $d+k-1$, and $R_{C'} \subseteq R_{C'_p}$, so
|
||||
$R_{C'} \subseteq R_T$ iff $C'$ is a descendant of $T$ at depth $d+k$.
|
||||
|
||||
\smallskip
|
||||
|
||||
\emph{Step 4: tread data and child--face correspondence.} The
|
||||
Tire-component lemma (Lemma~\ref{lem:tire-component}) and the
|
||||
source-side simple-cycle property
|
||||
(Proposition~\ref{prop:no-level-d-pinch}) extend verbatim to the
|
||||
cycle-sourced triangulated disk $(G_T, C_T)$: the proofs use only
|
||||
the triangular structure of bounded faces, the local arrangement of
|
||||
faces around each vertex's rotation, and the connectivity of the BFS
|
||||
ball $G_T[L_{<k}^{G_T}]$ (which holds for every $k \ge 1$ since
|
||||
$L_0^{G_T} = V(C_T)$ is connected as a cycle and each higher level is
|
||||
BFS-adjacent to the previous). Applied to each component of
|
||||
$(G_T)'_{k}$, the lemma produces a tire graph with outer boundary
|
||||
$B_{\mathrm{out}}$, inner outerplanar graph $O$, and tread region $R$
|
||||
identical to those produced by the corresponding component of
|
||||
$G'_{d+k}$ in $\mathcal{T}(G, \{v_0\})$, since these data depend only
|
||||
on level-$d+k$ and level-$(d+k+1)$ vertices and the bounded faces in
|
||||
between --- all of which are unchanged when restricting to $G_T$.
|
||||
|
||||
The depth-$0$ case ($k = 0$) gives a single component, namely the one
|
||||
producing $T$, with root tread $B_{\mathrm{out}} = C_T$ and $O = O^{(T)}$.
|
||||
|
||||
The parent--child face correspondence of
|
||||
Theorem~\ref{thm:tread-tree} is preserved: for any tread $T'$ in
|
||||
$\mathcal{T}(G_T, C_T)$ at depth $k$, its children correspond to
|
||||
non-trivial bounded faces of $O^{(T')}$, and the bounded faces of
|
||||
$O^{(T')}$ together with the descendant-side interior of each are
|
||||
identical in $G_T$ and in $G$.
|
||||
|
||||
Combining Steps 3 and 4: the bijection $C' \leftrightarrow C'$
|
||||
(component of $(G_T)'_{k}$ to corresponding component of $G'_{d+k}$
|
||||
inside $R_T$) lifts to a rooted-tree iso $\mathcal{T}(G_T, C_T) \to
|
||||
\text{sub-tree of } \mathcal{T}(G, \{v_0\}) \text{ rooted at } T$,
|
||||
preserving outer boundaries, inner outerplanar graphs, and the
|
||||
parent--child face correspondence.
|
||||
\end{proof}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.95\textwidth]{fig_tire_tree_decomposition.png}
|
||||
\caption{Tire-tree decomposition
|
||||
(Theorem~\ref{thm:tire-tree-decomposition}) on a $13$-vertex maximal
|
||||
planar example $G$ with five BFS levels. $(a)$ $G$ with vertex source
|
||||
$v_0$ and $\ell_G \in \{0,1,2,3,4\}$; four nested seams are
|
||||
highlighted, $C_{T_R} = \{a,b,c\}$ (orange), $C_{T_L} = \{a,c,d\}$
|
||||
(red, including the chord $a$-$c$ shared with $C_{T_R}$),
|
||||
$C_{T_{LL}} = \{f_1, f_2, f_3\}$ (purple), $C_{T_{LLL}} = \{g_1, g_2, g_3\}$
|
||||
(teal). Inset: the rooted tree of tire treads $\mathcal{T}(G, \{v_0\})$
|
||||
branches at $T_0$ into the leaf $T_R$ (containing $e$) and a chain
|
||||
$T_L \to T_{LL} \to T_{LLL}$ (the highlighted sub-tree).
|
||||
$(b)$ The disk $G_{T_L}$ inside the seam $C_{T_L}$, drawn standalone
|
||||
with $C_{T_L}$ as cycle source and vertex labels rotated to match the
|
||||
new (cycle-source) role of the boundary triangle.
|
||||
$\ell_{G_{T_L}}(\cdot) = \ell_G(\cdot) - 1$ on $V(G_{T_L})$ (verified
|
||||
by the generator script), and $\mathcal{T}(G_{T_L}, C_{T_L})$ is the
|
||||
chain $T_L \to T_{LL} \to T_{LLL}$, iso to the highlighted sub-tree
|
||||
of $(a)$.}
|
||||
\label{fig:tire-tree-decomposition}
|
||||
\end{figure}
|
||||
|
||||
\begin{remark}
|
||||
\label{rem:tree-coloring-factorisation}
|
||||
Combining Theorem~\ref{thm:tread-partition} (treads partition
|
||||
@@ -950,6 +1134,136 @@ This is the structural setup underlying the chain-pigeonhole
|
||||
program for tire treads.
|
||||
\end{remark}
|
||||
|
||||
\begin{definition}[Seam]
|
||||
\label{def:seam}
|
||||
A \emph{seam} of a maximal planar graph $G$ is a simple cycle
|
||||
$C \subset G$ such that, for some vertex $v_0 \in V(G)$, $C =
|
||||
B_{\mathrm{out}}^{(T)}$ for some non-root tread $T$ in
|
||||
$\mathcal{T}(G, \{v_0\})$.
|
||||
|
||||
By Theorem~\ref{thm:tire-tree-decomposition}, every seam $C$ separates
|
||||
$G$ into:
|
||||
\begin{itemize}
|
||||
\item the \emph{seam interior} $G_T$, the triangulated disk on the
|
||||
$T$-descendant side of $C$;
|
||||
\item the \emph{seam exterior} $G_C^{\mathrm{ext}} := G \setminus
|
||||
\mathrm{int}(G_T)$, the triangulated polygon with outer face
|
||||
bounded by $C$ on the side containing $v_0$;
|
||||
\end{itemize}
|
||||
both sharing $C$. A seam is \emph{non-trivial} if both
|
||||
$V(G_T) \setminus V(C)$ and $V(G_C^{\mathrm{ext}}) \setminus V(C)$ are
|
||||
non-empty.
|
||||
|
||||
For any seam $C$ and either side $X \in \{G_T, G_C^{\mathrm{ext}}\}$,
|
||||
write
|
||||
\[
|
||||
\mathrm{Col}(X \mid C) \;:=\; \bigl\{\, c|_{V(C)} \;:\; c \text{ a
|
||||
proper $4$-colouring of } X \,\bigr\} \;\subseteq\; \{1,2,3,4\}^{V(C)}
|
||||
\]
|
||||
for the set of $C$-restricted $4$-colourings induced by $4$-colourings
|
||||
of $X$ (each element is a proper $4$-colouring of the cycle $C$).
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}[Partial tire tree]
|
||||
\label{def:partial-tire-tree}
|
||||
Let $T_r$ be a tire tread in $\mathcal{T}(G, S)$ with outer boundary
|
||||
cycle $C_{T_r} = B_{\mathrm{out}}^{(T_r)}$, and let $G_{T_r}$ be the
|
||||
triangulated disk inside $C_{T_r}$ given by
|
||||
Theorem~\ref{thm:tire-tree-decomposition}. The \emph{partial tire
|
||||
tree} with root $T_r$, written $G_{T_r}^{\circ}$, is the induced
|
||||
subgraph of $G$ on the vertex set
|
||||
$V(G_{T_r}) \setminus V(C_{T_r})$ ---
|
||||
i.e.\ $G_{T_r}$ with the seam-cycle vertices removed.
|
||||
|
||||
Equivalently, $V(G_{T_r}^{\circ})$ is the set of vertices of $G$
|
||||
strictly inside $C_{T_r}$ on the side away from the level source,
|
||||
and $E(G_{T_r}^{\circ})$ consists of the edges of $G$ both of whose
|
||||
endpoints lie in this strict interior. The tree-of-tire-treads
|
||||
structure of $G_{T_r}^{\circ}$ is the sub-tree of $\mathcal{T}(G, S)$
|
||||
rooted at $T_r$, with $T_r$'s outer boundary peeled away.
|
||||
\end{definition}
|
||||
|
||||
\begin{lemma}[Seam edges are shared by at most one other depth-$d$ seam]
|
||||
\label{lem:seam-edge-shared}
|
||||
Let $G$ be a maximal planar graph with single-vertex level source
|
||||
$S = \{v_0\}$, fix $d \ge 1$, and let $e \in E(G)$ be an edge lying on
|
||||
the seam $C_T = B_{\mathrm{out}}^{(T)}$ of some tire tread
|
||||
$T \in \mathcal{T}(G, S)$ at depth $d$. Then there is at most one
|
||||
other tire tread $T' \in \mathcal{T}(G, S)$ at the same depth $d$ with
|
||||
$e \in C_{T'}$.
|
||||
\end{lemma}
|
||||
|
||||
\begin{proof}
|
||||
By Theorem~\ref{thm:tread-tree}, $C_T$ is the boundary cycle of a
|
||||
bounded face of the parent's inner outerplanar graph $O^{(T_p)}$,
|
||||
where $T_p \in \mathcal{T}(G, S)$ is the parent of $T$ at depth
|
||||
$d - 1$. The inner dual of an outerplanar graph is a tree (a forest,
|
||||
if the outerplanar graph is disconnected), so each edge of
|
||||
$O^{(T_p)}$ lies on at most two of its bounded face cycles. Hence
|
||||
$e$ lies on at most one other bounded face cycle of $O^{(T_p)}$,
|
||||
corresponding (Theorem~\ref{thm:tread-tree}, child--face bijection)
|
||||
to at most one sibling of $T$ at depth $d$ whose seam contains $e$.
|
||||
\end{proof}
|
||||
|
||||
\begin{conjecture}[Seam structure of minimum $4$CT counterexamples, sketch]
|
||||
\label{conj:seam-counterexample}
|
||||
Suppose the Four Colour Theorem fails: there exists a maximal planar
|
||||
graph that is not $4$-colourable. Let $G$ be a \emph{minimum} such
|
||||
counterexample (with $|V(G)|$ minimal among non-$4$-colourable maximal
|
||||
planar graphs). Then:
|
||||
|
||||
\medskip
|
||||
|
||||
\noindent\emph{Restatement-of-classical content.}
|
||||
\begin{itemize}
|
||||
\item[(C1)] \emph{Bilateral colourability.} For every non-trivial seam
|
||||
$C$ of $G$, both $\mathrm{Col}(G_T \mid C)$ and
|
||||
$\mathrm{Col}(G_C^{\mathrm{ext}} \mid C)$ are non-empty.
|
||||
\item[(C2)] \emph{Bilateral incompatibility.} For every non-trivial
|
||||
seam $C$,
|
||||
\[
|
||||
\mathrm{Col}(G_T \mid C) \;\cap\;
|
||||
\mathrm{Col}(G_C^{\mathrm{ext}} \mid C) \;=\; \emptyset.
|
||||
\]
|
||||
\item[(C3)] \emph{Length lower bound (Birkhoff).} Every non-trivial
|
||||
seam $C$ of $G$ has $|V(C)| \ge 6$.
|
||||
\end{itemize}
|
||||
|
||||
(C1) and (C2) together restate ``$G$ is a counterexample whose every
|
||||
internal cut by a seam splits into two colourable pieces with
|
||||
incompatible boundary palettes''; (C1) follows from minimality applied
|
||||
to each side after closing the polygonal outer face by a single apex,
|
||||
(C2) from $G$ itself being non-$4$-colourable. (C3) is Birkhoff's
|
||||
internally-$6$-connected condition restated in the seam language.
|
||||
|
||||
\medskip
|
||||
|
||||
\noindent\emph{Substantive (speculative) content.}
|
||||
\begin{itemize}
|
||||
\item[(C4)] \emph{Innermost obstruction.} There exists a vertex source
|
||||
$v_0 \in V(G)$ and a \emph{leaf} tread $T^* \in
|
||||
\mathcal{T}(G, \{v_0\})$ (a tread with no children in the
|
||||
tree-of-treads) such that:
|
||||
\begin{enumerate}
|
||||
\item[(i)] the seam interior $G_{T^*}$ is, up to plane
|
||||
iso, one of a finite list of \emph{minimal seam
|
||||
configurations}, characterized by their boundary
|
||||
palette $\mathrm{Col}(G_{T^*} \mid C_{T^*})$ being a
|
||||
specific proper subset of the proper $4$-colourings
|
||||
of the cycle $C_{T^*}$;
|
||||
\item[(ii)] the path in $\mathcal{T}(G, \{v_0\})$ from the
|
||||
root $T_0$ to $T^*$ is an \emph{obstruction chain}:
|
||||
$\mathrm{Col}(G_T \mid C_T)$ is monotonically
|
||||
restricted (under the natural pull-back along
|
||||
parent--child seams of
|
||||
Remark~\ref{rem:tree-coloring-factorisation}) as $T$
|
||||
descends from the root to $T^*$, with the final
|
||||
restriction at $T^*$ being incompatible with the
|
||||
$v_0$-side palette.
|
||||
\end{enumerate}
|
||||
\end{itemize}
|
||||
\end{conjecture}
|
||||
|
||||
\begin{thebibliography}{9}
|
||||
|
||||
\bibitem{tait-original}
|
||||
|
||||
Reference in New Issue
Block a user