diff --git a/papers/dual_decomposition_minimal_counterexamples/experiments/draw_reduced_dual_steps.py b/papers/dual_decomposition_minimal_counterexamples/experiments/draw_reduced_dual_steps.py new file mode 100644 index 0000000..c351acc --- /dev/null +++ b/papers/dual_decomposition_minimal_counterexamples/experiments/draw_reduced_dual_steps.py @@ -0,0 +1,174 @@ +"""Draw the four steps of the reduced-dual construction (Definition 2.1). + +Uses the dodecahedron G' = dual of the icosahedron, with F_v the inner pentagon, +as built in reduced_dual.py. Produces fig_reduced_dual_step{1..4}.png. +""" +import os +import math +import matplotlib.pyplot as plt +from matplotlib.patches import Polygon +from matplotlib.lines import Line2D + +from reduced_dual import build_dual, apply_reduction + +OUT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +GRAY = '#9ca3af' +DARK = '#374151' +GHOST = '#fca5a5' +DEG2 = '#f59e0b' +APEX = '#16a34a' +CHORD = '#2563eb' +FACE = '#fef9c3' + + +def draw_edges(ax, G, pos, nodes=None, **kw): + for u, v in G.edges(): + if nodes is not None and (u not in nodes or v not in nodes): + continue + (x0, y0), (x1, y1) = pos[u], pos[v] + ax.plot([x0, x1], [y0, y1], **kw) + + +def draw_nodes(ax, pos, nodes, **kw): + xs = [pos[v][0] for v in nodes] + ys = [pos[v][1] for v in nodes] + ax.scatter(xs, ys, **kw) + + +def face_F_polygon(pos): + """The new central face F: decagon alternating b_i, c_i clockwise.""" + order = [] + for i in range(5): + order += [('b', i), ('c', i)] + return [pos[v] for v in order] + + +def base_canvas(title): + fig, ax = plt.subplots(figsize=(8.5, 8.5)) + ax.set_aspect('equal') + ax.axis('off') + ax.set_title(title, fontsize=12) + return fig, ax + + +def main(): + Gp, pos, Fv = build_dual() + res = apply_reduction(Gp, pos, Fv, i=0) + Ghat, npos, A = res['Ghat'], res['pos'], res['A'] + v_n, apex_nbrs, chord = res['v_n'], res['apex_nbrs'], res['chord'] + + survivors = [v for v in Gp if v not in Fv] # b, c, d families + surv_set = set(survivors) + deg2 = list(A) # the five b_i + + # surviving edges (both endpoints survive) vs deleted edges (touch an a_i) + surv_edges = [(u, v) for u, v in Gp.edges() + if u in surv_set and v in surv_set] + del_edges = [(u, v) for u, v in Gp.edges() + if u not in surv_set or v not in surv_set] + + def draw_surviving(ax): + ax.add_patch(Polygon(face_F_polygon(pos), closed=True, + facecolor=FACE, edgecolor='none', zorder=0)) + for u, v in surv_edges: + (x0, y0), (x1, y1) = pos[u], pos[v] + ax.plot([x0, x1], [y0, y1], color=GRAY, lw=1.6, zorder=1) + others = [v for v in survivors if v not in deg2] + draw_nodes(ax, pos, others, s=120, color=DARK, zorder=3) + + def draw_ghosts(ax): + for u, v in del_edges: + (x0, y0), (x1, y1) = pos[u], pos[v] + ax.plot([x0, x1], [y0, y1], color=GHOST, lw=1.2, ls='--', zorder=1) + draw_nodes(ax, pos, Fv, s=120, color='white', edgecolors=GHOST, + linewidths=1.5, zorder=2) + for v in Fv: + ax.plot(*pos[v], marker='x', color=GHOST, ms=8, zorder=3) + + # ----- Step 1: delete F_v's boundary; five degree-2 vertices on face F ----- + fig, ax = base_canvas( + "Step 1: delete the five dual vertices on $\\partial F_v$.\n" + "Their outer neighbours drop to degree 2 (orange) and lie on a new " + "face $F$ (shaded).") + draw_surviving(ax) + draw_ghosts(ax) + draw_nodes(ax, pos, deg2, s=260, color=DEG2, edgecolors='black', + linewidths=1.0, zorder=4) + cx = sum(pos[('a', i)][0] for i in range(5)) / 5 + cy = sum(pos[('a', i)][1] for i in range(5)) / 5 + ax.text(cx, cy, '$F$', fontsize=16, ha='center', va='center', + color='#a16207', zorder=5) + ax.legend(handles=[ + Line2D([0], [0], marker='x', color=GHOST, lw=0, label='deleted (was $\\partial F_v$)'), + Line2D([0], [0], marker='o', color='w', markerfacecolor=DEG2, + markeredgecolor='black', label='degree-2 vertex'), + ], loc='upper left', fontsize=10) + fig.savefig(os.path.join(OUT_DIR, 'fig_reduced_dual_step1.png'), + dpi=170, bbox_inches='tight'); plt.close(fig) + + # ----- Step 2: order the five degree-2 vertices clockwise as A_0..A_4 ----- + fig, ax = base_canvas( + "Step 2: list the degree-2 vertices clockwise around $F$ as " + "$A_0,\\dots,A_4$.") + draw_surviving(ax) + draw_nodes(ax, pos, deg2, s=300, color=DEG2, edgecolors='black', + linewidths=1.0, zorder=4) + for k, v in enumerate(A): + x, y = pos[v] + ax.annotate(f'$A_{k}$', (x, y), textcoords='offset points', + xytext=(0, 0), ha='center', va='center', fontsize=10, + fontweight='bold', color='black', zorder=5) + # outward label too + ax.annotate(f'$A_{k}$', (x * 1.18, y * 1.18), ha='center', va='center', + fontsize=12, color='#a16207', zorder=5) + fig.savefig(os.path.join(OUT_DIR, 'fig_reduced_dual_step2.png'), + dpi=170, bbox_inches='tight'); plt.close(fig) + + # ----- Step 3: add v_n joined to A_i, A_{i+1}, A_{i+2} ----- + fig, ax = base_canvas( + "Step 3: add a vertex $v_n$ joined to $A_i, A_{i+1}, A_{i+2}$ " + "(here $i=0$).") + draw_surviving(ax) + draw_nodes(ax, pos, deg2, s=300, color=DEG2, edgecolors='black', + linewidths=1.0, zorder=4) + for k, v in enumerate(A): + ax.annotate(f'$A_{k}$', (pos[v][0] * 1.18, pos[v][1] * 1.18), + ha='center', va='center', fontsize=12, color='#a16207', zorder=5) + for u in apex_nbrs: + (x0, y0), (x1, y1) = npos[v_n], pos[u] + ax.plot([x0, x1], [y0, y1], color=APEX, lw=2.4, zorder=5) + draw_nodes(ax, npos, [v_n], s=320, color=APEX, marker='s', + edgecolors='black', linewidths=1.0, zorder=6) + ax.annotate('$v_n$', npos[v_n], textcoords='offset points', xytext=(0, 14), + ha='center', fontsize=12, fontweight='bold', color=APEX, zorder=7) + fig.savefig(os.path.join(OUT_DIR, 'fig_reduced_dual_step3.png'), + dpi=170, bbox_inches='tight'); plt.close(fig) + + # ----- Step 4: add chord A_{i+3} A_{i+4}; the reduced dual ----- + fig, ax = base_canvas( + "Step 4: add the edge $A_{i+3} A_{i+4}$. The result $\\widehat{G}'_{v,i}$ " + "is again cubic and planar.") + draw_surviving(ax) + draw_nodes(ax, pos, deg2, s=300, color=DEG2, edgecolors='black', + linewidths=1.0, zorder=4) + for k, v in enumerate(A): + ax.annotate(f'$A_{k}$', (pos[v][0] * 1.18, pos[v][1] * 1.18), + ha='center', va='center', fontsize=12, color='#a16207', zorder=5) + for u in apex_nbrs: + (x0, y0), (x1, y1) = npos[v_n], pos[u] + ax.plot([x0, x1], [y0, y1], color=APEX, lw=2.4, zorder=5) + draw_nodes(ax, npos, [v_n], s=320, color=APEX, marker='s', + edgecolors='black', linewidths=1.0, zorder=6) + ax.annotate('$v_n$', npos[v_n], textcoords='offset points', xytext=(0, 14), + ha='center', fontsize=12, fontweight='bold', color=APEX, zorder=7) + (x0, y0), (x1, y1) = pos[chord[0]], pos[chord[1]] + ax.plot([x0, x1], [y0, y1], color=CHORD, lw=2.8, zorder=5) + fig.savefig(os.path.join(OUT_DIR, 'fig_reduced_dual_step4.png'), + dpi=170, bbox_inches='tight'); plt.close(fig) + + print("wrote fig_reduced_dual_step1..4.png to", OUT_DIR) + + +if __name__ == '__main__': + main() diff --git a/papers/dual_decomposition_minimal_counterexamples/experiments/reduced_dual.py b/papers/dual_decomposition_minimal_counterexamples/experiments/reduced_dual.py new file mode 100644 index 0000000..2d9caeb --- /dev/null +++ b/papers/dual_decomposition_minimal_counterexamples/experiments/reduced_dual.py @@ -0,0 +1,184 @@ +"""Reduced dual: construction and verification. + +Test input is the icosahedron G (the unique 5-regular triangulation, n=12). +Its dual G' is the dodecahedron (a cubic plane graph, 20 vertices). We pick a +degree-5 vertex v of G -- equivalently a pentagonal face F_v of G' -- and apply +the reduced-dual construction of Definition 2.1: + + 1. delete the 5 dual vertices on the boundary of F_v (and incident edges), + leaving 5 degree-2 vertices on a new face F; + 2. order those 5 vertices clockwise around F as A_0..A_4; + 3. add a vertex v_n joined to A_i, A_{i+1}, A_{i+2}; + 4. add an edge A_{i+3} A_{i+4}. + +We verify the result is again a cubic plane graph, and report the triangulation +it is the dual of (its face count = the primal vertex count), to see how the +vertex count changes relative to n. + +The dodecahedron is built directly in its concentric "Schlegel" layout with +F_v the inner pentagon, so the figures (draw_reduced_dual_steps.py) are clean. +""" +import math +import networkx as nx + +# --------------------------------------------------------------------------- +# Build G' = dodecahedron with concentric positions; F_v = inner pentagon. +# Vertex families a (inner pentagon), b, c, d (outer pentagon), 5 each. +# Angles increase *clockwise* (90 - 72*i deg) so index order is clockwise. +# --------------------------------------------------------------------------- +def build_dual(): + pos = {} + R = {'a': 1.0, 'b': 2.2, 'c': 3.6, 'd': 4.8} + for i in range(5): + for fam in ('a', 'b'): + th = math.radians(90 - 72 * i) + pos[(fam, i)] = (R[fam] * math.cos(th), R[fam] * math.sin(th)) + for fam in ('c', 'd'): + th = math.radians(90 - 72 * i - 36) # offset half a step + pos[(fam, i)] = (R[fam] * math.cos(th), R[fam] * math.sin(th)) + + Gp = nx.Graph() + Gp.add_nodes_from(pos) + for i in range(5): + Gp.add_edge(('a', i), ('a', (i + 1) % 5)) # inner pentagon + Gp.add_edge(('a', i), ('b', i)) # spokes a-b + Gp.add_edge(('b', i), ('c', i)) # b-c + Gp.add_edge(('b', i), ('c', (i - 1) % 5)) # b-c (other side) + Gp.add_edge(('c', i), ('d', i)) # spokes c-d + Gp.add_edge(('d', i), ('d', (i + 1) % 5)) # outer pentagon + + Fv_boundary = [('a', i) for i in range(5)] # inner pentagon + return Gp, pos, Fv_boundary + + +# --------------------------------------------------------------------------- +# Face / dual helpers. +# --------------------------------------------------------------------------- +def faces_of(G): + """Return the list of faces (each a list of vertices) of a plane graph.""" + ok, emb = nx.check_planarity(G) + assert ok, "graph is not planar" + seen, faces = set(), [] + for u in emb: + for v in emb[u]: + if (u, v) not in seen: + faces.append(emb.traverse_face(u, v, mark_half_edges=seen)) + return faces + + +def dual_of(G): + """Combinatorial dual (all faces, including outer) of a plane graph.""" + faces = faces_of(G) + edge_faces = {} + for fi, face in enumerate(faces): + for j in range(len(face)): + e = frozenset((face[j], face[(j + 1) % len(face)])) + edge_faces.setdefault(e, []).append(fi) + D = nx.MultiGraph() + D.add_nodes_from(range(len(faces))) + for e, fs in edge_faces.items(): + if len(fs) == 2: + D.add_edge(fs[0], fs[1]) + elif len(fs) == 1: # shouldn't happen for 2-connected G + pass + return D, faces + + +# --------------------------------------------------------------------------- +# The reduced-dual construction. +# --------------------------------------------------------------------------- +def clockwise_order(verts, pos): + """Order verts clockwise around their centroid, starting from the topmost.""" + cx = sum(pos[v][0] for v in verts) / len(verts) + cy = sum(pos[v][1] for v in verts) / len(verts) + ang = {v: math.atan2(pos[v][1] - cy, pos[v][0] - cx) for v in verts} + ccw = sorted(verts, key=lambda v: ang[v]) # counterclockwise + cw = list(reversed(ccw)) # clockwise + start = max(range(len(cw)), key=lambda k: pos[cw[k]][1]) # topmost first + return cw[start:] + cw[:start] + + +def apply_reduction(Gp, pos, Fv_boundary, i=0): + """Apply Definition 2.1 and return a dict capturing each stage.""" + Ghat = Gp.copy() + npos = dict(pos) + + # (1) delete the 5 boundary dual vertices of F_v + Ghat.remove_nodes_from(Fv_boundary) + deg2 = [v for v in Ghat if Ghat.degree(v) == 2] + assert len(deg2) == 5, f"expected 5 degree-2 vertices, got {len(deg2)}" + + # (2) order them clockwise around the new face F + A = clockwise_order(deg2, pos) + + # (3) new vertex v_n joined to A_i, A_{i+1}, A_{i+2} + apex_nbrs = [A[(i + k) % 5] for k in range(3)] + ax = sum(npos[v][0] for v in apex_nbrs) / 3 + ay = sum(npos[v][1] for v in apex_nbrs) / 3 + v_n = 'v_n' + npos[v_n] = (ax * 0.55, ay * 0.55) # pull toward the 3 nbrs + Ghat.add_node(v_n) + for u in apex_nbrs: + Ghat.add_edge(v_n, u) + + # (4) chord between the remaining two + chord = (A[(i + 3) % 5], A[(i + 4) % 5]) + Ghat.add_edge(*chord) + + return { + 'Ghat': Ghat, 'pos': npos, 'A': A, 'v_n': v_n, + 'apex_nbrs': apex_nbrs, 'chord': chord, + 'deleted': list(Fv_boundary), + } + + +def main(): + Gp, pos, Fv = build_dual() + + # --- verify G' is the dodecahedron = dual of the icosahedron --- + assert nx.check_planarity(Gp)[0] + assert all(d == 3 for _, d in Gp.degree()), "G' not cubic" + assert nx.is_isomorphic(Gp, nx.dodecahedral_graph()), "G' is not dodecahedron" + Dico, _ = dual_of(Gp) + Dico = nx.Graph(Dico) + print(f"G (icosahedron) : dual of G' has {Dico.number_of_nodes()} vertices, " + f"degrees {sorted({d for _, d in Dico.degree()})}") + print(f"G' (dodecahedron): {Gp.number_of_nodes()} vertices, " + f"{Gp.number_of_edges()} edges, " + f"{len(faces_of(Gp))} faces; cubic={all(d==3 for _,d in Gp.degree())}") + + # --- apply the reduced-dual construction --- + res = apply_reduction(Gp, pos, Fv, i=0) + Ghat = res['Ghat'] + cubic = all(d == 3 for _, d in Ghat.degree()) + planar = nx.check_planarity(Ghat)[0] + ghat_simple = (nx.number_of_selfloops(Ghat) == 0) # Graph: no parallels + nfaces = len(faces_of(Ghat)) + print() + print(f"reduced dual G^_v,i : {Ghat.number_of_nodes()} vertices, " + f"{Ghat.number_of_edges()} edges, {nfaces} faces") + print(f" cubic : {cubic}") + print(f" planar : {planar}") + print(f" simple : {ghat_simple}") + + # --- the triangulation it is dual to --- + Dred_multi, _ = dual_of(Ghat) + Dred = nx.Graph(Dred_multi) + dred_simple = (Dred.number_of_edges() == Dred_multi.number_of_edges()) + is_tri = all(len(f) == 3 for f in faces_of(Dred)) if planar else None + print() + print(f"dual of reduced dual : {Dred.number_of_nodes()} vertices " + f"(= faces of G^), degree seq " + f"{sorted((d for _, d in Dred.degree()), reverse=True)}") + print(f" is a triangulation : {is_tri}") + print(f" simple : {dred_simple}") + + n = Dico.number_of_nodes() + print() + print(f"VERTEX COUNT: G has n = {n}; reduced triangulation has " + f"{Dred.number_of_nodes()} (change = " + f"{Dred.number_of_nodes() - n}).") + + +if __name__ == '__main__': + main() diff --git a/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step1.png b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step1.png new file mode 100644 index 0000000..01f5fc4 Binary files /dev/null and b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step1.png differ diff --git a/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step2.png b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step2.png new file mode 100644 index 0000000..0557dc6 Binary files /dev/null and b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step2.png differ diff --git a/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step3.png b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step3.png new file mode 100644 index 0000000..01eee21 Binary files /dev/null and b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step3.png differ diff --git a/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step4.png b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step4.png new file mode 100644 index 0000000..007d206 Binary files /dev/null and b/papers/dual_decomposition_minimal_counterexamples/fig_reduced_dual_step4.png differ diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.aux b/papers/dual_decomposition_minimal_counterexamples/paper.aux index 3275f16..5de24eb 100644 --- a/papers/dual_decomposition_minimal_counterexamples/paper.aux +++ b/papers/dual_decomposition_minimal_counterexamples/paper.aux @@ -8,4 +8,8 @@ \newlabel{tocindent1}{17.77782pt} \newlabel{tocindent2}{0pt} \newlabel{tocindent3}{0pt} -\gdef \@abspage@last{2} +\@writefile{toc}{\contentsline {section}{\tocsection {}{2}{The reduced dual}}{2}{}\protected@file@percent } +\newlabel{def:reduced-dual}{{2.1}{2}} +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces The four steps of Definition\nonbreakingspace 2.1\hbox {}, illustrated on $G' = $ the dodecahedron (dual of the icosahedron) with $F_v$ the inner pentagon and $i = 0$. Top left: delete the five boundary vertices of $F_v$, leaving five degree-$2$ vertices on a new face $F$. Top right: order them clockwise as $A_0,\dots ,A_4$. Bottom left: add $v_n$ joined to $A_0, A_1, A_2$. Bottom right: add the chord $A_3 A_4$, giving the cubic plane graph $\setbox \z@ \hbox {\mathsurround \z@ $\textstyle G$}\mathaccent "0362{G}'_{v,0}$.}}{3}{}\protected@file@percent } +\newlabel{fig:reduced-dual-steps}{{1}{3}} +\gdef \@abspage@last{3} diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.fdb_latexmk b/papers/dual_decomposition_minimal_counterexamples/paper.fdb_latexmk index c123391..add52c5 100644 --- a/papers/dual_decomposition_minimal_counterexamples/paper.fdb_latexmk +++ b/papers/dual_decomposition_minimal_counterexamples/paper.fdb_latexmk @@ -1,5 +1,5 @@ # Fdb version 3 -["pdflatex"] 1779488879 "paper.tex" "paper.pdf" "paper" 1779488879 +["pdflatex"] 1779490218 "paper.tex" "paper.pdf" "paper" 1779490219 "/usr/local/texlive/2022/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 "" "/usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1246382020 1004 54797486969f23fa377b128694d548df "" "/usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1246382020 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 "" @@ -21,7 +21,9 @@ "/usr/local/texlive/2022/texmf-dist/fonts/tfm/public/cm/cmti8.tfm" 1136768653 1504 1747189e0441d1c18f3ea56fafc1c480 "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb" 1248133631 34811 78b52f49e893bcba91bd7581cdc144c0 "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb" 1248133631 32001 6aeea3afe875097b1eb0da29acd61e28 "" + "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb" 1248133631 30251 6afa5cb1d0204815a708a080681d4674 "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb" 1248133631 36299 5f9df58c2139e7edcf37c8fca4bd384d "" + "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb" 1248133631 36281 c355509802a035cadc5f15869451dcee "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb" 1248133631 35752 024fb6c41858982481f6968b5fc26508 "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb" 1248133631 32762 224316ccc9ad3ca0423a14971cfa7fc1 "" "/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb" 1248133631 32726 0a1aea6fcd6468ee2cf64d891f5c43c8 "" @@ -54,8 +56,12 @@ "/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map" 1647878959 4410336 7d30a02e9fa9a16d7d1f8d037ba69641 "" "/usr/local/texlive/2022/texmf-var/web2c/pdftex/pdflatex.fmt" 1665017617 2826443 7e98410c533054b636c6470db83a27bc "" "/usr/local/texlive/2022/texmf.cnf" 1647878952 577 209b46be99c9075fd74d4c0369380e8c "" - "paper.aux" 1779488879 395 3d9d6ecb308d4771fc574ef59dbc631f "pdflatex" - "paper.tex" 1779488875 3976 7b376fa4f80996836d72b6d62b391567 "" + "fig_reduced_dual_step1.png" 1779490218 117795 4da7754ac28df9e809cfa1069e081c53 "" + "fig_reduced_dual_step2.png" 1779490218 96839 4f94c996220a2758dd0ff21ebdb9b2be "" + "fig_reduced_dual_step3.png" 1779490218 102877 d2a5db5532697441e3150e2ad26b9173 "" + "fig_reduced_dual_step4.png" 1779490218 107439 b30c7a68e32660f9bd3a8070bdb96944 "" + "paper.aux" 1779490219 1214 93cc6b97abaa1c8b9c54e346f15b0d5f "pdflatex" + "paper.tex" 1779490059 7089 91fabcb0498579524cd3a441fd2aa0f4 "" (generated) "paper.aux" "paper.log" diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.fls b/papers/dual_decomposition_minimal_counterexamples/paper.fls index 7514dbf..65b1555 100644 --- a/papers/dual_decomposition_minimal_counterexamples/paper.fls +++ b/papers/dual_decomposition_minimal_counterexamples/paper.fls @@ -227,10 +227,32 @@ INPUT /usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm1 INPUT /usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm OUTPUT paper.pdf INPUT /usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map +INPUT ./fig_reduced_dual_step1.png +INPUT ./fig_reduced_dual_step1.png +INPUT fig_reduced_dual_step1.png +INPUT ./fig_reduced_dual_step1.png +INPUT ./fig_reduced_dual_step1.png +INPUT ./fig_reduced_dual_step2.png +INPUT ./fig_reduced_dual_step2.png +INPUT fig_reduced_dual_step2.png +INPUT ./fig_reduced_dual_step2.png +INPUT ./fig_reduced_dual_step2.png +INPUT ./fig_reduced_dual_step3.png +INPUT ./fig_reduced_dual_step3.png +INPUT fig_reduced_dual_step3.png +INPUT ./fig_reduced_dual_step3.png +INPUT ./fig_reduced_dual_step3.png +INPUT ./fig_reduced_dual_step4.png +INPUT ./fig_reduced_dual_step4.png +INPUT fig_reduced_dual_step4.png +INPUT ./fig_reduced_dual_step4.png +INPUT ./fig_reduced_dual_step4.png INPUT paper.aux INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb +INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb +INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb INPUT /usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.log b/papers/dual_decomposition_minimal_counterexamples/paper.log index 771e216..e6855e1 100644 --- a/papers/dual_decomposition_minimal_counterexamples/paper.log +++ b/papers/dual_decomposition_minimal_counterexamples/paper.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) 22 MAY 2026 18:27 +This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 22 MAY 2026 18:50 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -192,31 +192,63 @@ File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv e )) [1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] -[2] (./paper.aux) ) +Overfull \hbox (41.917pt too wide) in paragraph at lines 143--145 +[]\OT1/cmr/m/n/10 List the five degree-$2$ ver-tices in clock-wise or-der aroun +d $\OML/cmm/m/it/10 F$ \OT1/cmr/m/n/10 as $\OML/cmm/m/it/10 A \OT1/cmr/m/n/10 = + (\OML/cmm/m/it/10 A[]; A[]; A[]; A[]; A[]\OT1/cmr/m/n/10 )$. + [] + + +File: fig_reduced_dual_step1.png Graphic file (type png) + +Package pdftex.def Info: fig_reduced_dual_step1.png used on input line 163. +(pdftex.def) Requested size: 172.79846pt x 166.55775pt. + +File: fig_reduced_dual_step2.png Graphic file (type png) + +Package pdftex.def Info: fig_reduced_dual_step2.png used on input line 164. +(pdftex.def) Requested size: 172.79846pt x 170.39505pt. + +File: fig_reduced_dual_step3.png Graphic file (type png) + +Package pdftex.def Info: fig_reduced_dual_step3.png used on input line 165. +(pdftex.def) Requested size: 172.79846pt x 170.39505pt. + +File: fig_reduced_dual_step4.png Graphic file (type png) + +Package pdftex.def Info: fig_reduced_dual_step4.png used on input line 166. +(pdftex.def) Requested size: 172.79846pt x 171.44409pt. + +LaTeX Warning: `h' float specifier changed to `ht'. + +[2] [3 <./fig_reduced_dual_step1.png> <./fig_reduced_dual_step2.png> <./fig_red +uced_dual_step3.png> <./fig_reduced_dual_step4.png>] (./paper.aux) ) Here is how much of TeX's memory you used: - 2983 strings out of 478268 - 41531 string characters out of 5846347 - 338080 words of memory out of 5000000 - 21033 multiletter control sequences out of 15000+600000 + 3014 strings out of 478268 + 42429 string characters out of 5846347 + 340098 words of memory out of 5000000 + 21059 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,242b,225s stack positions out of 10000i,1000n,20000p,200000b,200000s - -Output written on paper.pdf (2 pages, 142068 bytes). + 69i,8n,76p,664b,225s stack positions out of 10000i,1000n,20000p,200000b,200000s + +Output written on paper.pdf (3 pages, 490295 bytes). PDF statistics: - 66 PDF objects out of 1000 (max. 8388607) - 39 compressed objects within 1 object stream + 88 PDF objects out of 1000 (max. 8388607) + 48 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) + 21 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.pdf b/papers/dual_decomposition_minimal_counterexamples/paper.pdf index 2bf363c..2fc2725 100644 Binary files a/papers/dual_decomposition_minimal_counterexamples/paper.pdf and b/papers/dual_decomposition_minimal_counterexamples/paper.pdf differ diff --git a/papers/dual_decomposition_minimal_counterexamples/paper.tex b/papers/dual_decomposition_minimal_counterexamples/paper.tex index 1e25b9c..7dc490c 100644 --- a/papers/dual_decomposition_minimal_counterexamples/paper.tex +++ b/papers/dual_decomposition_minimal_counterexamples/paper.tex @@ -115,4 +115,63 @@ $G$, a contradiction. Hence $\delta(G) \ge 5$. \end{proof} +\section{The reduced dual} + +Write $G'$ for the dual of $G$: since $G$ is a triangulation, $G'$ is a cubic +plane graph in which each vertex of $G$ corresponds to a face of $G'$, each face +of $G$ to a vertex of $G'$, and each edge to a dual edge. A vertex of $G$ of +degree $k$ corresponds to a $k$-gonal face of $G'$. + +By Lemma~\ref{lem:mindeg}, $\delta(G) \ge 5$, and Euler's formula gives +$\sum_{u \in V(G)}(6 - \deg u) = 12$, so $G$ has a vertex of degree exactly $5$ +(indeed at least twelve). Fix such a vertex $v$. Its dual face $F_v$ is a +pentagon, bounded by the five dual vertices corresponding to the five faces of +$G$ incident to $v$. + +\begin{definition}[Reduced dual] +\label{def:reduced-dual} +Let $v$ be a degree-$5$ vertex of $G$ with pentagonal dual face $F_v$, and fix an +index $i \in \{0,1,2,3,4\}$. The \emph{reduced dual} $\widehat{G}'_{v,i}$ is the +plane graph obtained from $G'$ as follows. +\begin{enumerate} + \item Delete the five dual vertices on the boundary of $F_v$, together with all + edges incident to them. Each deleted vertex is cubic, with two edges on + $\partial F_v$ and one edge leaving $F_v$; deleting the five boundary + vertices therefore removes the five external edges as well, dropping their + five outer endpoints from degree $3$ to degree $2$. These five degree-$2$ + vertices lie on the boundary of a single face $F$ of the resulting graph. + \item List the five degree-$2$ vertices in clockwise order around $F$ as + $A = (A_0, A_1, A_2, A_3, A_4)$. + \item Add a new vertex $v_n$ and join it to $A_i$, $A_{i+1}$, and $A_{i+2}$ + (indices mod $5$) by three new edges. + \item Add a new edge between $A_{i+3}$ and $A_{i+4}$ (indices mod $5$). +\end{enumerate} +\end{definition} + +\begin{remark} +Steps (3) and (4) restore cubicity: $A_i, A_{i+1}, A_{i+2}$ each gain one edge to +$v_n$ and $A_{i+3}, A_{i+4}$ each gain the new edge, so all five return to degree +$3$, and $v_n$ has degree $3$. Since $A_i,\dots,A_{i+2}$ and $A_{i+3}, A_{i+4}$ +are each consecutive along $\partial F$, the new vertex and edge can be drawn +inside $F$ without crossings, so $\widehat{G}'_{v,i}$ is again a cubic plane +graph. The construction depends on the choice of $i$ up to the rotational +symmetry of $A$. +\end{remark} + +\begin{figure}[h] +\centering +\includegraphics[width=0.48\textwidth]{fig_reduced_dual_step1.png}\hfill +\includegraphics[width=0.48\textwidth]{fig_reduced_dual_step2.png}\\[0.5em] +\includegraphics[width=0.48\textwidth]{fig_reduced_dual_step3.png}\hfill +\includegraphics[width=0.48\textwidth]{fig_reduced_dual_step4.png} +\caption{The four steps of Definition~\ref{def:reduced-dual}, illustrated on +$G' = $ the dodecahedron (dual of the icosahedron) with $F_v$ the inner +pentagon and $i = 0$. Top left: delete the five boundary vertices of $F_v$, +leaving five degree-$2$ vertices on a new face $F$. Top right: order them +clockwise as $A_0,\dots,A_4$. Bottom left: add $v_n$ joined to $A_0, A_1, A_2$. +Bottom right: add the chord $A_3 A_4$, giving the cubic plane graph +$\widehat{G}'_{v,0}$.} +\label{fig:reduced-dual-steps} +\end{figure} + \end{document}