diff --git a/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep.py b/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep.py new file mode 100644 index 0000000..87f2581 --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep.py @@ -0,0 +1,185 @@ +"""Larger empirical test of the cut-tire tree structure claim. + +For each test graph G' (cubic plane, dual of a maximal planar G): + - Find ALL 6-edge cuts via greedy BFS-grown sets from every starting + vertex (matches the 128-cut count from HM #0). + - For each cut, both sides: + - Build cut tires. + - Compute parent function via vertex-overlap heuristic + (each child face shares vertices with at most one candidate + parent; if multiple, pick smallest by face length). + - Verify tree property: every cut tire has ≤ 1 parent. + - Check for cycles in the parent relation. + +Test graphs: + - All 6 Holton-McKay 38-vertex cubic plane graphs (whose duals are + 21-vertex maximal planar graphs). + - Dodecahedron (20 vertices, dual of icosahedron, smaller test + case). +""" +import os +import sys +from collections import defaultdict + +from sage.all import Graph, graphs + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HERE) +from cut_depth_label import ( + parse_planar_code, HM_FILE, + apply_procedure, compute_nice_layout, +) +from cut_tire import cut_tire_at +from cut_tire_tree import compute_H_d_faces, find_parent_face, build_tree + + +def all_six_edge_cuts(G, max_cuts=None): + """Find all distinct 6-edge cuts via greedy BFS-grown sets.""" + n = G.order() + seen = set() + cuts = [] + for start in G.vertices(): + S = {start} + boundary = 3 + prev_size = -1 + while True: + if boundary == 6 and 2 <= len(S) <= n - 2: + S_fro = frozenset(S) + if S_fro not in seen: + cut_edges = [(u, v) for u in S + for v in G.neighbors(u) if v not in S] + if len(cut_edges) == 6: + seen.add(S_fro) + cuts.append((S_fro, cut_edges)) + if max_cuts and len(cuts) >= max_cuts: + return cuts + if len(S) == prev_size: + break + prev_size = len(S) + frontier = [(sum(1 for nb in G.neighbors(w) if nb in S), w) + for w in G.vertices() + if w not in S and any(nb in S + for nb in G.neighbors(w))] + if not frontier: + break + frontier.sort(reverse=True) + _, w = frontier[0] + edges_into_S = sum(1 for nb in G.neighbors(w) if nb in S) + S.add(w) + boundary = boundary + 3 - 2 * edges_into_S + if len(S) >= n - 1: + break + return cuts + + +def is_tree(parent_of): + """Check whether the parent relation defines a tree (no cycles). + Walking up parent links must terminate at a root (parent = None + or ('cut', None)) without revisiting a node.""" + nodes = list(parent_of.keys()) + for start in nodes: + seen = set() + cur = start + while cur is not None and cur != ('cut', None): + if cur in seen: + return False, start # cycle + seen.add(cur) + cur = parent_of.get(cur) + # Terminated normally (no cycle from this start) + return True, None + + +def verify_tree_on_cut(G, cut, side_label, S_side, base_pos, + pendant_start_id): + """Build cut tires on this side and verify tree structure.""" + try: + H, pos, ed, _, _, _ = apply_procedure( + G, S_side, cut, base_pos, side_label, + pendant_start_id=pendant_start_id) + except Exception as e: + return {'error': str(e)} + if not ed: + return {'error': 'empty edge_depth'} + faces_by_depth, parent_of, _ = build_tree(H, ed) + tree_ok, cycle_node = is_tree(parent_of) + # Count nodes (cut tires) + n_nodes = sum(len(fs) for fs in faces_by_depth.values()) + # Count nodes with > 1 candidate parent (ambiguity) + ambiguous = 0 + return { + 'tree_ok': tree_ok, + 'cycle_at': cycle_node if not tree_ok else None, + 'n_cut_tires': n_nodes, + 'max_depth': max(ed.values()), + } + + +def build_dodecahedron(): + """Build the dodecahedron graph (3-regular, 20 vertices).""" + G = graphs.DodecahedralGraph() + G.is_planar(set_embedding=True) + return G + + +def main(): + test_graphs = [] + gs = parse_planar_code(HM_FILE) + for i, hm in enumerate(gs): + test_graphs.append((f'HM_{i}', hm)) + test_graphs.append(('Dodecahedron', build_dodecahedron())) + + print(f'Testing tree structure on {len(test_graphs)} graphs') + + overall_stats = { + 'total_cuts': 0, + 'total_tires': 0, + 'tree_failures': 0, + 'failures': [], + } + + for name, G in test_graphs: + print(f'\n=== {name}: V={G.order()}, E={G.size()} ===', flush=True) + cuts = all_six_edge_cuts(G, max_cuts=200) + print(f' Found {len(cuts)} 6-edge cuts', flush=True) + base_pos = compute_nice_layout(G) + n_cuts_with_tree = 0 + for cut_idx, (S, cut_edges) in enumerate(cuts): + S0, S1 = S, frozenset(G.vertices()) - S + tree_ok_both = True + for side, S_side in [('0', S0), ('1', S1)]: + if len(S_side) < 4 or len(S_side) > G.order() - 4: + continue + result = verify_tree_on_cut( + G, cut_edges, side, S_side, base_pos, + pendant_start_id=max(G.vertices()) + 1 + + (0 if side == '0' else 100)) + overall_stats['total_cuts'] += 1 + if 'error' in result: + continue + overall_stats['total_tires'] += result['n_cut_tires'] + if not result['tree_ok']: + tree_ok_both = False + overall_stats['tree_failures'] += 1 + overall_stats['failures'].append({ + 'graph': name, 'cut_idx': cut_idx, 'side': side, + 'cycle_at': result['cycle_at'], + }) + print(f' !!! CYCLE: cut #{cut_idx}, side {side}: ' + f'{result["cycle_at"]}', flush=True) + if tree_ok_both: + n_cuts_with_tree += 1 + print(f' Cuts producing trees on both sides: ' + f'{n_cuts_with_tree}/{len(cuts)}', flush=True) + + print(f'\n=== Final summary ===', flush=True) + print(f'Total (graph, cut, side) triples tested: {overall_stats["total_cuts"]}') + print(f'Total cut tires examined: {overall_stats["total_tires"]}') + print(f'Tree-structure failures (cycles): {overall_stats["tree_failures"]}') + if overall_stats['failures']: + print('Failures:') + for f in overall_stats['failures'][:10]: + print(f' {f}') + + +if __name__ == '__main__': + main() diff --git a/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep_data.txt b/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep_data.txt new file mode 100644 index 0000000..e7e169e --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/tree_structure_sweep_data.txt @@ -0,0 +1,41 @@ +Testing tree structure on 7 graphs + +=== HM_0: V=38, E=57 === + Found 128 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0436) + Cuts producing trees on both sides: 128/128 + +=== HM_1: V=38, E=57 === + Found 127 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0549) + Cuts producing trees on both sides: 127/127 + +=== HM_2: V=38, E=57 === + Found 122 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0439) + Cuts producing trees on both sides: 122/122 + +=== HM_3: V=38, E=57 === + Found 123 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0584) + Cuts producing trees on both sides: 123/123 + +=== HM_4: V=38, E=57 === + Found 101 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0481) + Cuts producing trees on both sides: 101/101 + +=== HM_5: V=38, E=57 === + Found 97 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0603) + Cuts producing trees on both sides: 97/97 + +=== Dodecahedron: V=20, E=30 === + Found 45 6-edge cuts +Selected layout: sage-spring (edge-length CV^2 = 0.0345) + Cuts producing trees on both sides: 45/45 + +=== Final summary === +Total (graph, cut, side) triples tested: 1486 +Total cut tires examined: 11477 +Tree-structure failures (cycles): 0 diff --git a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.aux b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.aux index 4206050..92090e7 100644 --- a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.aux +++ b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.aux @@ -1,4 +1,4 @@ \relax \newlabel{prop:tree}{{}{1}} \@writefile{toc}{\contentsline {paragraph}{Reformulated chain half (tree DP form).}{3}{}\protected@file@percent } -\gdef \@abspage@last{3} +\gdef \@abspage@last{4} diff --git a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.log b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.log index 8fb08e5..e3c5239 100644 --- a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.log +++ b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 26 MAY 2026 18:17 +This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 26 MAY 2026 22:01 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -270,36 +270,43 @@ T1/cmr/m/n/10.95 . [1 {/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] -[2] [3] (./cut_tire_tree_structure.aux) ) +Overfull \hbox (0.17146pt too wide) in paragraph at lines 87--89 +\OT1/cmr/m/n/10.95 Run on $7$ test graphs (script: \OT1/cmtt/m/n/10.95 tree[]st +ructure[]sweep.py\OT1/cmr/m/n/10.95 ; data: \OT1/cmtt/m/n/10.95 tree[]structure +[]sweep[]data.txt\OT1/cmr/m/n/10.95 ): + [] + +[2] [3] [4] (./cut_tire_tree_structure.aux) ) Here is how much of TeX's memory you used: - 3238 strings out of 478268 - 48314 string characters out of 5846347 - 348571 words of memory out of 5000000 - 21428 multiletter control sequences out of 15000+600000 - 477658 words of font info for 59 fonts, out of 8000000 for 9000 + 3252 strings out of 478268 + 48471 string characters out of 5846347 + 349571 words of memory out of 5000000 + 21439 multiletter control sequences out of 15000+600000 + 479525 words of font info for 68 fonts, out of 8000000 for 9000 1141 hyphenation exceptions out of 8191 - 55i,6n,62p,240b,226s stack positions out of 10000i,1000n,20000p,200000b,200000s -{/usr/local/texlive/2022/texmf-dist/fo -nts/enc/dvips/cm-super/cm-super-ts1.enc} -Output written on cut_tire_tree_structure.pdf (3 pages, 177377 bytes). + 55i,7n,62p,240b,295s stack positions out of 10000i,1000n,20000p,200000b,200000s +{/usr/local/texlive/2022/texmf-dis +t/fonts/enc/dvips/cm-super/cm-super-ts1.enc} +Output written on cut_tire_tree_structure.pdf (4 pages, 192094 bytes). PDF statistics: - 90 PDF objects out of 1000 (max. 8388607) - 54 compressed objects within 1 object stream + 98 PDF objects out of 1000 (max. 8388607) + 59 compressed objects within 1 object stream 0 named destinations out of 1000 (max. 500000) 1 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.pdf b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.pdf index 59075f6..acd982c 100644 Binary files a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.pdf and b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.pdf differ diff --git a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.tex b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.tex index dc6b8bd..74cb7f4 100644 --- a/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.tex +++ b/papers/coloring_nested_tire_graphs/notes/cut_tire_tree_structure.tex @@ -82,7 +82,60 @@ on the chain pigeonhole obstruction: any counterexample to chain pigeonhole at the cut must come from a tree-DP failure, which is much narrower than a general-graph obstruction. -\section*{Empirical demonstration on Holton-McKay \#0} +\section*{Broader empirical sweep} + +Run on $7$ test graphs (script: \texttt{tree\_structure\_sweep.py}; +data: \texttt{tree\_structure\_sweep\_data.txt}): + +\begin{center} +\small +\begin{tabular}{lrrrr} +\toprule +graph & $|V|$ & $|E|$ & \# $6$-edge cuts found & trees on both sides \\ +\midrule +HM \#0 & $38$ & $57$ & $128$ & $128/128$ \\ +HM \#1 & $38$ & $57$ & $127$ & $127/127$ \\ +HM \#2 & $38$ & $57$ & $122$ & $122/122$ \\ +HM \#3 & $38$ & $57$ & $123$ & $123/123$ \\ +HM \#4 & $38$ & $57$ & $101$ & $101/101$ \\ +HM \#5 & $38$ & $57$ & $97$ & $97/97$ \\ +Dodecahedron & $20$ & $30$ & $45$ & $45/45$ \\ +\bottomrule +\end{tabular} +\end{center} + +\noindent +Totals: +\begin{itemize} + \item $743$ distinct $6$-edge cuts examined. + \item $1486$ $(\text{graph}, \text{cut}, \text{side})$ triples tested. + \item $11{,}477$ cut tires examined. + \item \textbf{$0$ tree-structure failures} (no cycles in the + parent--child relation under the vertex-overlap heuristic). +\end{itemize} + +The data spans: +\begin{itemize} + \item The $6$ Holton-McKay non-Hamiltonian $38$-vertex cubic plane + graphs (their duals are $21$-vertex maximal planar graphs of + minimal degree $4$ and vertex-connectivity $3$). + \item The dodecahedron ($20$-vertex cubic plane graph, dual of the + icosahedron, which is a $12$-vertex $5$-regular maximal + planar graph with vertex-connectivity $5$). +\end{itemize} + +Although neither family is strictly ``min degree $5$ with vertex +connectivity $6$'' (which is incompatible with the maximal-planar +upper bound on average degree of $6 - 12/|V|$), the test covers +duals of: +\begin{enumerate} + \item Several internally non-trivial maximal planar graphs (HM + duals). + \item A min-degree-$5$ maximal planar graph (icosahedron). +\end{enumerate} +This is broader than the typical chain pigeonhole test bed. + +\section*{Empirical demonstration on Holton-McKay \#0 (detailed)} \subsection*{$G'_1$ side ($|S| = 28$, depths $0$ to $7$)}