Prove intertwining-tree ⟺ Hamiltonian-dual; test the 6 Holton-McKay duals
- Add Theorem: maximal planar G is an intertwining tree iff its dual G* is Hamiltonian (Tait-style Jordan-curve argument). Consequence: smallest non-intertwining-tree triangulations are the 6 duals of the 38-vertex Holton-McKay graphs, at n=21. - Load the 6 graphs from McKay's authoritative planar_code file (nonham38m4.pc), verified: 38 vertices, cubic, planar, non-Hamiltonian. - All 6 duals confirmed not intertwining trees (exhaustive 2^20 check). - 2 of 6 duals are themselves Even Level Graphs (sources 9, 10), hence derived level graphs -- first cases where the derived disjunct does work the intertwining-tree disjunct cannot. - Remaining 4: bounded E/O-orbit search inconclusive; status open. This is the first genuinely undetermined instance of the conjecture. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"""Parse plantri -a output for 5-connected triangulations at n=21 and
|
||||
check each for the intertwining-tree property (equivalently, whether its
|
||||
dual is Hamiltonian)."""
|
||||
import subprocess
|
||||
import networkx as nx
|
||||
import time
|
||||
|
||||
PLANTRI = '/Users/didericis/Code/math-research/plantri/plantri'
|
||||
|
||||
|
||||
def parse_plantri_a(line):
|
||||
"""Parse one line of plantri -a output into a networkx graph.
|
||||
Format: 'n adj0,adj1,...' where adj_i is a string of letters."""
|
||||
parts = line.strip().split(' ', 1)
|
||||
n = int(parts[0])
|
||||
adj_lists = parts[1].split(',')
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from(range(n))
|
||||
for i, adj in enumerate(adj_lists):
|
||||
for ch in adj:
|
||||
j = ord(ch) - ord('a')
|
||||
G.add_edge(i, j)
|
||||
return G
|
||||
|
||||
|
||||
def is_intertwining_tree(G):
|
||||
"""Search all 2-partitions for one giving two induced trees."""
|
||||
nodes = list(G.nodes())
|
||||
n = len(nodes)
|
||||
for mask in range(1, 2 ** (n - 1)):
|
||||
A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1]
|
||||
B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)]
|
||||
if not B:
|
||||
continue
|
||||
if nx.is_tree(G.subgraph(A)) and nx.is_tree(G.subgraph(B)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
out = subprocess.run([PLANTRI, '-c5', '-a', '21'],
|
||||
capture_output=True, text=True)
|
||||
lines = [l for l in out.stdout.splitlines() if l.strip()]
|
||||
print(f'{len(lines)} triangulations to check')
|
||||
|
||||
t0 = time.time()
|
||||
n_inter = 0
|
||||
non_inter = []
|
||||
for idx, line in enumerate(lines):
|
||||
G = parse_plantri_a(line)
|
||||
if G.number_of_nodes() != 21 or G.number_of_edges() != 3 * 21 - 6:
|
||||
print(f' line {idx}: parse issue, n={G.number_of_nodes()}, '
|
||||
f'm={G.number_of_edges()}')
|
||||
continue
|
||||
if is_intertwining_tree(G):
|
||||
n_inter += 1
|
||||
else:
|
||||
non_inter.append(idx)
|
||||
if (idx + 1) % 50 == 0:
|
||||
print(f' ...{idx+1}/{len(lines)} done '
|
||||
f'({time.time()-t0:.1f}s), {n_inter} intertwining so far')
|
||||
print(f'\nResult: {n_inter}/{len(lines)} are intertwining trees')
|
||||
print(f'Non-intertwining-tree (dual non-Hamiltonian): {non_inter}')
|
||||
print(f'elapsed: {time.time()-t0:.1f}s')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,74 @@
|
||||
"""Parse McKay's planar_code file of the 6 non-Hamiltonian 38-vertex
|
||||
cubic planar graphs, verify them, and build their duals (21-vertex
|
||||
triangulations)."""
|
||||
import networkx as nx
|
||||
|
||||
|
||||
def parse_planar_code(path):
|
||||
"""Parse a >>planar_code<< file. Returns list of (G, embedding-order)."""
|
||||
with open(path, 'rb') as f:
|
||||
data = f.read()
|
||||
header = b'>>planar_code<<'
|
||||
assert data.startswith(header), data[:20]
|
||||
pos = len(header)
|
||||
graphs = []
|
||||
while pos < len(data):
|
||||
n = data[pos]
|
||||
pos += 1
|
||||
adj = {i: [] for i in range(n)}
|
||||
for v in range(n):
|
||||
while True:
|
||||
w = data[pos]
|
||||
pos += 1
|
||||
if w == 0:
|
||||
break
|
||||
adj[v].append(w - 1) # 1-indexed -> 0-indexed
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from(range(n))
|
||||
for v in range(n):
|
||||
for w in adj[v]:
|
||||
G.add_edge(v, w)
|
||||
graphs.append((G, adj))
|
||||
return graphs
|
||||
|
||||
|
||||
def is_hamiltonian(G, time_limit_nodes=10_000_000):
|
||||
"""Backtracking Hamiltonicity check (good for cubic graphs)."""
|
||||
nodes = list(G.nodes())
|
||||
n = len(nodes)
|
||||
adj = {v: list(G.neighbors(v)) for v in nodes}
|
||||
start = nodes[0]
|
||||
visited = {start}
|
||||
count = [0]
|
||||
|
||||
def bt(v, depth):
|
||||
count[0] += 1
|
||||
if count[0] > time_limit_nodes:
|
||||
raise TimeoutError
|
||||
if depth == n:
|
||||
return start in adj[v]
|
||||
for w in adj[v]:
|
||||
if w not in visited:
|
||||
visited.add(w)
|
||||
if bt(w, depth + 1):
|
||||
return True
|
||||
visited.discard(w)
|
||||
return False
|
||||
|
||||
return bt(start, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
graphs = parse_planar_code('/tmp/nonham38m4.pc')
|
||||
print(f'Parsed {len(graphs)} graphs from McKay planar_code file')
|
||||
for i, (G, adj) in enumerate(graphs):
|
||||
n = G.number_of_nodes()
|
||||
m = G.number_of_edges()
|
||||
degs = sorted(set(dict(G.degree()).values()))
|
||||
planar = nx.check_planarity(G)[0]
|
||||
try:
|
||||
ham = is_hamiltonian(G)
|
||||
except TimeoutError:
|
||||
ham = 'timeout'
|
||||
print(f' graph {i}: n={n}, m={m}, degrees={degs}, '
|
||||
f'planar={planar}, hamiltonian={ham}')
|
||||
Binary file not shown.
@@ -0,0 +1,61 @@
|
||||
"""For each of the 6 Holton-McKay graphs (38-vertex non-Hamiltonian cubic
|
||||
planar), build the dual (21-vertex triangulation), confirm it is NOT an
|
||||
intertwining tree, then test whether it is a valid derived level graph."""
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/Users/didericis/Code/math-research/papers/'
|
||||
'level_resolutions_of_maximal_planar_graphs/experiments')
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import networkx as nx
|
||||
import time
|
||||
from load_holton_mckay import parse_planar_code
|
||||
from tutte_dual_treecolor import dual_triangulation
|
||||
|
||||
|
||||
def is_intertwining_tree(G, time_limit=120.0):
|
||||
"""Search all 2-partitions for two induced trees. Time-limited."""
|
||||
nodes = list(G.nodes())
|
||||
n = len(nodes)
|
||||
t0 = time.time()
|
||||
checked = 0
|
||||
for mask in range(1, 2 ** (n - 1)):
|
||||
checked += 1
|
||||
if checked % 200000 == 0 and time.time() - t0 > time_limit:
|
||||
return None, checked
|
||||
A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1]
|
||||
B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)]
|
||||
if not B:
|
||||
continue
|
||||
if nx.is_tree(G.subgraph(A)) and nx.is_tree(G.subgraph(B)):
|
||||
return (tuple(sorted(A)), tuple(sorted(B))), checked
|
||||
return False, checked
|
||||
|
||||
|
||||
def main():
|
||||
graphs = parse_planar_code('/tmp/nonham38m4.pc')
|
||||
print(f'{len(graphs)} Holton-McKay graphs loaded\n')
|
||||
|
||||
for i, (G, adj) in enumerate(graphs):
|
||||
D, faces = dual_triangulation(G)
|
||||
n = D.number_of_nodes()
|
||||
m = D.number_of_edges()
|
||||
is_tri = (m == 3 * n - 6)
|
||||
print(f'graph {i}: dual has n={n}, m={m}, triangulation={is_tri}')
|
||||
|
||||
# Verify NOT intertwining tree
|
||||
t0 = time.time()
|
||||
result, checked = is_intertwining_tree(D, time_limit=180.0)
|
||||
dt = time.time() - t0
|
||||
if result is False:
|
||||
print(f' intertwining tree: NO '
|
||||
f'(checked all {checked} partitions, {dt:.1f}s) '
|
||||
f'[consistent with non-Hamiltonian dual]')
|
||||
elif result is None:
|
||||
print(f' intertwining tree: search timed out after {checked} '
|
||||
f'partitions ({dt:.1f}s)')
|
||||
else:
|
||||
print(f' intertwining tree: YES (UNEXPECTED) partition={result}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,167 @@
|
||||
"""Test the disjunction on the Tutte graph dual: a 25-vertex
|
||||
triangulation whose dual is a Tait counterexample. By the
|
||||
intertwining-tree⇔dual-Hamiltonian equivalence, the dual is not
|
||||
intertwining tree. So the conjecture requires it to be a derived level
|
||||
graph.
|
||||
|
||||
Approach: backward BFS from G in the E/O-switch graph. A predecessor of
|
||||
H is H' = H - wx + uv where uv is the diagonal of wx's quadrilateral in
|
||||
H and uv has same-parity endpoints (so the forward switch on uv in H' is
|
||||
valid).
|
||||
|
||||
For each candidate vertex-labelling of G (each potential level source
|
||||
in some Even Level Graph), we BFS backward and check if any reached state
|
||||
is itself an Even Level Graph for that labelling.
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/Users/didericis/Code/math-research/papers/'
|
||||
'level_resolutions_of_maximal_planar_graphs/experiments')
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import networkx as nx
|
||||
import time
|
||||
from tutte_dual_treecolor import dual_triangulation
|
||||
from test_conjecture import (
|
||||
bfs_levels, is_even_level_graph,
|
||||
)
|
||||
|
||||
|
||||
def is_tree(subg):
|
||||
return nx.is_tree(subg) if subg.number_of_nodes() > 0 else True
|
||||
|
||||
|
||||
def is_intertwining_tree(G, time_limit=10.0):
|
||||
"""Search for a 2-partition (A, B) such that G[A] and G[B] are trees.
|
||||
Returns the partition or None. Time-limited."""
|
||||
nodes = list(G.nodes())
|
||||
n = len(nodes)
|
||||
t0 = time.time()
|
||||
for mask in range(1, 2 ** (n - 1)):
|
||||
if time.time() - t0 > time_limit:
|
||||
return None # timed out, unknown
|
||||
A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1]
|
||||
B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)]
|
||||
if not A or not B:
|
||||
continue
|
||||
if is_tree(G.subgraph(A)) and is_tree(G.subgraph(B)):
|
||||
return (tuple(A), tuple(B))
|
||||
return False # no partition works
|
||||
|
||||
|
||||
def planar_diagonal(G, u, v):
|
||||
"""Given edge uv in triangulation G, return the diagonal of the
|
||||
quadrilateral around uv (= the two third vertices of the triangles
|
||||
at uv)."""
|
||||
ok, emb = nx.check_planarity(G)
|
||||
if not ok:
|
||||
return None
|
||||
f1 = emb.traverse_face(u, v)
|
||||
f2 = emb.traverse_face(v, u)
|
||||
if len(f1) != 3 or len(f2) != 3:
|
||||
return None
|
||||
w = next(x for x in f1 if x != u and x != v)
|
||||
x = next(y for y in f2 if y != u and y != v)
|
||||
if w == x:
|
||||
return None
|
||||
return (w, x)
|
||||
|
||||
|
||||
def backward_predecessors(G, labels):
|
||||
"""Yield (G', uv, wx) where G' →forward G via switching uv (E/O in
|
||||
labels). For each edge wx of G whose diagonal uv has same-parity
|
||||
endpoints AND uv is not already an edge of G."""
|
||||
for u, v in list(G.edges()):
|
||||
diag = planar_diagonal(G, u, v)
|
||||
if diag is None:
|
||||
continue
|
||||
w, x = diag
|
||||
if labels[w] % 2 != labels[x] % 2:
|
||||
continue # diagonal not E/O, can't be reverse-switched
|
||||
if G.has_edge(w, x):
|
||||
continue # would create multi-edge
|
||||
Gp = G.copy()
|
||||
Gp.remove_edge(u, v)
|
||||
Gp.add_edge(w, x)
|
||||
yield Gp, (u, v), (w, x)
|
||||
|
||||
|
||||
def find_elg_via_backward_bfs(G_start, labels, max_states=50000,
|
||||
time_limit=120.0):
|
||||
"""BFS backward from G_start. If we hit a triangulation that is an
|
||||
Even Level Graph for the same labelling (specifically, where the
|
||||
labels match BFS levels from some source in this triangulation),
|
||||
return it."""
|
||||
t0 = time.time()
|
||||
seen = {frozenset(frozenset(e) for e in G_start.edges())}
|
||||
frontier = [G_start]
|
||||
rounds = 0
|
||||
while frontier and len(seen) < max_states:
|
||||
if time.time() - t0 > time_limit:
|
||||
return None, len(seen), rounds, 'timed out'
|
||||
new = []
|
||||
for H in frontier:
|
||||
# Check if H is an Even Level Graph for some source
|
||||
# whose BFS levels match `labels` mod 2.
|
||||
for v in H.nodes():
|
||||
is_elg, lvls = is_even_level_graph(H, frozenset({v}))
|
||||
if not is_elg or lvls is None:
|
||||
continue
|
||||
# Check if lvls parities match labels mod 2 (up to swap)
|
||||
same = all(lvls[u] % 2 == labels[u] % 2 for u in H.nodes())
|
||||
opp = all(lvls[u] % 2 != labels[u] % 2 for u in H.nodes())
|
||||
if same or opp:
|
||||
return H, len(seen), rounds, ('match' if same else 'swapped')
|
||||
for Hp, uv, wx in backward_predecessors(H, labels):
|
||||
sig = frozenset(frozenset(e) for e in Hp.edges())
|
||||
if sig in seen:
|
||||
continue
|
||||
seen.add(sig)
|
||||
new.append(Hp)
|
||||
if len(seen) >= max_states:
|
||||
break
|
||||
if len(seen) >= max_states:
|
||||
break
|
||||
frontier = new
|
||||
rounds += 1
|
||||
return None, len(seen), rounds, 'exhausted' if not frontier else 'capped'
|
||||
|
||||
|
||||
def main():
|
||||
G_orig = nx.tutte_graph()
|
||||
D, _ = dual_triangulation(G_orig)
|
||||
n = D.number_of_nodes()
|
||||
print(f'Tutte graph dual: n={n}, edges={D.number_of_edges()}')
|
||||
|
||||
# Confirm not intertwining tree (we already know this, but verify)
|
||||
print('Verifying NOT intertwining tree (time-limited)...')
|
||||
result = is_intertwining_tree(D, time_limit=60.0)
|
||||
if result is False:
|
||||
print(' confirmed: no 2-tree partition exists')
|
||||
elif result is None:
|
||||
print(' search timed out; cannot confirm')
|
||||
else:
|
||||
print(f' SURPRISE: is intertwining tree with partition {result}')
|
||||
|
||||
# Try various labellings: BFS from each vertex of D, take levels.
|
||||
# For each labelling, do backward BFS to find ELG.
|
||||
print('\nSearching for backward path to an Even Level Graph...')
|
||||
for src in list(D.nodes())[:5]: # first 5 sources
|
||||
labels = bfs_levels(D, frozenset({src}))
|
||||
print(f' source={src}, label distribution: '
|
||||
f'even={sum(1 for l in labels.values() if l % 2 == 0)}, '
|
||||
f'odd={sum(1 for l in labels.values() if l % 2 == 1)}')
|
||||
result, n_states, rnds, status = find_elg_via_backward_bfs(
|
||||
D, labels, max_states=20000, time_limit=60.0)
|
||||
if result is not None:
|
||||
print(f' FOUND ELG ancestor ({status}, '
|
||||
f'{n_states} states, {rnds} rounds)')
|
||||
return
|
||||
else:
|
||||
print(f' no ELG ancestor found ({status}, '
|
||||
f'{n_states} states, {rnds} rounds)')
|
||||
|
||||
print('No ELG found in backward orbit with the labellings tried.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -34,13 +34,18 @@
|
||||
\newlabel{sec:even-level-graphs}{{4}{3}{Even Level Graphs}{section.4}{}}
|
||||
\newlabel{def:even-level-graph}{{4.1}{3}{Even Level Graph}{theorem.4.1}{}}
|
||||
\newlabel{thm:even-level-4colorable}{{4.2}{3}{}{theorem.4.2}{}}
|
||||
\citation{holton-mckay}
|
||||
\newlabel{def:derived-level-graph}{{4.3}{4}{Derived level graph}{theorem.4.3}{}}
|
||||
\newlabel{def:intertwining-tree}{{4.4}{4}{Intertwining tree}{theorem.4.4}{}}
|
||||
\newlabel{thm:intertwining-iff-hamiltonian-dual}{{4.5}{4}{}{theorem.4.5}{}}
|
||||
\newlabel{conj:every-triangulation-derived}{{4.6}{4}{}{theorem.4.6}{}}
|
||||
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{Empirical status}}{4}{section*.1}\protected@file@percent }
|
||||
\bibcite{holton-mckay}{1}
|
||||
\newlabel{tocindent-1}{0pt}
|
||||
\newlabel{tocindent0}{14.69437pt}
|
||||
\newlabel{tocindent1}{17.77782pt}
|
||||
\newlabel{tocindent2}{0pt}
|
||||
\newlabel{tocindent3}{0pt}
|
||||
\newlabel{def:derived-level-graph}{{4.3}{4}{Derived level graph}{theorem.4.3}{}}
|
||||
\newlabel{def:intertwining-tree}{{4.4}{4}{Intertwining tree}{theorem.4.4}{}}
|
||||
\newlabel{conj:every-triangulation-derived}{{4.5}{4}{}{theorem.4.5}{}}
|
||||
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{Empirical status}}{4}{section*.1}\protected@file@percent }
|
||||
\gdef \@abspage@last{4}
|
||||
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{The boundary case $n = 21$}}{5}{section*.2}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{5}{section*.3}\protected@file@percent }
|
||||
\gdef \@abspage@last{5}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 21 MAY 2026 18:03
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 21 MAY 2026 20:44
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
@@ -353,12 +353,12 @@ Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
|
||||
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
|
||||
e
|
||||
))
|
||||
<fig_levels.png, id=24, 454.21695pt x 391.34206pt>
|
||||
<fig_levels.png, id=32, 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 108.
|
||||
(pdftex.def) Requested size: 198.0011pt x 170.59666pt.
|
||||
<fig_level_cycle.png, id=26, 452.04884pt x 391.34206pt>
|
||||
<fig_level_cycle.png, id=34, 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 122.
|
||||
@@ -369,12 +369,12 @@ LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map} <./fig
|
||||
_levels.png>]
|
||||
<fig_edge_switch.png, id=48, 859.65166pt x 378.33345pt>
|
||||
<fig_edge_switch.png, id=56, 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 141.
|
||||
(pdftex.def) Requested size: 341.9989pt x 150.51671pt.
|
||||
<fig_parity_subgraph.png, id=50, 1076.46165pt x 319.79475pt>
|
||||
<fig_parity_subgraph.png, id=58, 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 159.
|
||||
@@ -384,15 +384,24 @@ Package pdftex.def Info: fig_parity_subgraph.png used on input line 159.
|
||||
LaTeX Warning: `h' float specifier changed to `ht'.
|
||||
|
||||
[2 <./fig_level_cycle.png> <./fig_edge_switch.png>] [3 <./fig_parity_subgraph.p
|
||||
ng>] [4] (./paper.aux)
|
||||
ng>] [4]
|
||||
|
||||
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
|
||||
(hyperref) removing `math shift' on input line 324.
|
||||
|
||||
|
||||
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
|
||||
(hyperref) removing `math shift' on input line 324.
|
||||
|
||||
[5] (./paper.aux)
|
||||
Package rerunfilecheck Info: File `paper.out' has not changed.
|
||||
(rerunfilecheck) Checksum: DC9FD452C972FF1938BE7060890FAD7C;765.
|
||||
(rerunfilecheck) Checksum: AECCB746CF11915BCB68F1E7FF8075A7;1047.
|
||||
)
|
||||
Here is how much of TeX's memory you used:
|
||||
9727 strings out of 478268
|
||||
150592 string characters out of 5846347
|
||||
451778 words of memory out of 5000000
|
||||
27640 multiletter control sequences out of 15000+600000
|
||||
9737 strings out of 478268
|
||||
150746 string characters out of 5846347
|
||||
453840 words of memory out of 5000000
|
||||
27645 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,427s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
@@ -409,10 +418,10 @@ texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/te
|
||||
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/local/tex
|
||||
live/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/local/texli
|
||||
ve/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfb>
|
||||
Output written on paper.pdf (4 pages, 530171 bytes).
|
||||
Output written on paper.pdf (5 pages, 545810 bytes).
|
||||
PDF statistics:
|
||||
145 PDF objects out of 1000 (max. 8388607)
|
||||
103 compressed objects within 2 object streams
|
||||
25 named destinations out of 1000 (max. 500000)
|
||||
61 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
162 PDF objects out of 1000 (max. 8388607)
|
||||
119 compressed objects within 2 object streams
|
||||
30 named destinations out of 1000 (max. 500000)
|
||||
77 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
\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 [1][-]{section.4}{\376\377\0004\000.\000\040\000E\000v\000e\000n\000\040\000L\000e\000v\000e\000l\000\040\000G\000r\000a\000p\000h\000s}{}% 4
|
||||
\BOOKMARK [2][-]{section*.1}{\376\377\000E\000m\000p\000i\000r\000i\000c\000a\000l\000\040\000s\000t\000a\000t\000u\000s}{section.4}% 5
|
||||
\BOOKMARK [2][-]{section*.2}{\376\377\000T\000h\000e\000\040\000b\000o\000u\000n\000d\000a\000r\000y\000\040\000c\000a\000s\000e\000\040\000n\000\040\000=\000\040\0002\0001}{section.4}% 6
|
||||
\BOOKMARK [1][-]{section*.3}{\376\377\000R\000e\000f\000e\000r\000e\000n\000c\000e\000s}{}% 7
|
||||
|
||||
Binary file not shown.
@@ -257,12 +257,47 @@ vertex set can be partitioned into two sets $A$ and $B$ such that
|
||||
both induced subgraphs $G[A]$ and $G[B]$ are trees.
|
||||
\end{definition}
|
||||
|
||||
\begin{theorem}
|
||||
\label{thm:intertwining-iff-hamiltonian-dual}
|
||||
A maximal planar graph $G$ is an intertwining tree if and only if its
|
||||
dual $G^\ast$ has a Hamiltonian cycle.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
($\Rightarrow$) Let $V(G) = A \sqcup B$ with $G[A]$ and $G[B]$ trees.
|
||||
Every triangular face $\{x,y,z\}$ of $G$ meets both $A$ and $B$: if all
|
||||
three vertices were in $A$ the triangle would be a cycle in the tree
|
||||
$G[A]$, and likewise for $B$. Draw a closed curve through the faces of
|
||||
$G$ separating the $A$-vertices from the $B$-vertices within each face.
|
||||
Since every face is split, the curve visits every face exactly once and
|
||||
crosses an edge of $G$ precisely when that edge joins $A$ to $B$; it is
|
||||
therefore a Hamiltonian cycle of $G^\ast$.
|
||||
|
||||
($\Leftarrow$) Let $H$ be a Hamiltonian cycle of $G^\ast$. Drawn in the
|
||||
plane, $H$ is a Jordan curve visiting every face of $G$ once; let $A$
|
||||
and $B$ be the vertices of $G$ interior and exterior to $H$. The
|
||||
$2n-4$ edges of $H$ cross exactly the edges of $G$ between $A$ and $B$,
|
||||
leaving $(3n-6)-(2n-4) = n-2$ edges inside $G[A]$ and $G[B]$ together.
|
||||
The edges inside $A$ lie in the disk bounded by $H$ and span $A$
|
||||
without enclosing a face (each face is cut by $H$), so $G[A]$ is a tree;
|
||||
likewise $G[B]$.
|
||||
\end{proof}
|
||||
|
||||
\begin{conjecture}
|
||||
\label{conj:every-triangulation-derived}
|
||||
Every maximal planar graph is a valid derived level graph of some Even
|
||||
Level Graph, an intertwining tree, or both.
|
||||
\end{conjecture}
|
||||
|
||||
By Theorem~\ref{thm:intertwining-iff-hamiltonian-dual}, the
|
||||
intertwining-tree disjunct fails for $G$ exactly when $G^\ast$ is a
|
||||
counterexample to Tait's conjecture. The smallest such $G^\ast$ have
|
||||
$38$ vertices (Holton--McKay~\cite{holton-mckay}, exactly $6$ graphs),
|
||||
so the smallest triangulations that are not intertwining trees occur at
|
||||
$n = 21$ and there are exactly $6$ of them. Below $n = 21$ every
|
||||
maximal planar graph is an intertwining tree, which is why the
|
||||
disjunction holds trivially in that range.
|
||||
|
||||
\subsection*{Empirical status}
|
||||
|
||||
For each isomorphism class of maximal planar graphs on $n$ vertices,
|
||||
@@ -284,4 +319,43 @@ $12$ & $7595$ & $0$ & $1$ & $7594$ & $0$ & holds \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
\subsection*{The boundary case $n = 21$}
|
||||
|
||||
The first triangulations that are \emph{not} intertwining trees are the
|
||||
six duals of the Holton--McKay graphs, at $n = 21$. For the disjunction
|
||||
to survive at $n = 21$, each of these six must be a valid derived level
|
||||
graph. We find:
|
||||
\begin{itemize}
|
||||
\item All six duals are confirmed not intertwining trees (exhaustive
|
||||
check of all $2^{20}-1$ vertex bipartitions), consistent with
|
||||
Theorem~\ref{thm:intertwining-iff-hamiltonian-dual}.
|
||||
\item Two of the six are themselves Even Level Graphs (for a suitable
|
||||
source vertex), hence trivially valid derived level graphs. So the
|
||||
disjunction holds for them through the derived-level-graph disjunct --
|
||||
the first instances where that disjunct does work the intertwining-tree
|
||||
disjunct cannot.
|
||||
\item The remaining four are not Even Level Graphs for any source. A
|
||||
bounded backward $E/O$-orbit search (tens of thousands of states, a
|
||||
handful of source labellings) found no Even Level Graph in their
|
||||
orbits, but this is far too shallow relative to the orbit size at
|
||||
$n = 21$ to be conclusive; their status as derived level graphs is
|
||||
open.
|
||||
\end{itemize}
|
||||
Thus at $n = 21$ the disjunction is confirmed for two of the six
|
||||
critical iso classes and undetermined for the other four. Settling
|
||||
those four -- equivalently, deciding $E/O$-orbit reachability from an
|
||||
Even Level Graph -- is the first genuinely open instance of the
|
||||
conjecture, and calls for either a better reachability algorithm or a
|
||||
structural invariant of $E/O$-orbits.
|
||||
|
||||
\begin{thebibliography}{9}
|
||||
|
||||
\bibitem{holton-mckay}
|
||||
D.~A. Holton and B.~D. McKay.
|
||||
\emph{The smallest non-Hamiltonian 3-connected cubic planar graphs have
|
||||
38 vertices}.
|
||||
Journal of Combinatorial Theory, Series B, 45(3):305--319, 1988.
|
||||
|
||||
\end{thebibliography}
|
||||
|
||||
\end{document}
|
||||
|
||||
Reference in New Issue
Block a user