Files
math-research/plane_diamond_coloring.py
T
didericis 88031c9d73 Replace counterexample with minimal n=13 graph found by exhaustive search
Adds search_counterexample_comprehensive iterating Sage's planar_graphs
generator across all maximal planar graphs of bounded order. Exhaustive
enumeration through order 13 (9150+49566 triangulations) yields exactly
one graph with no plane diamond coloring, at order 13. Updates Theorem
2.6 to assert minimality and uniqueness, and replaces the figure and
edge list with the smaller counterexample.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 12:52:30 -04:00

102 lines
4.2 KiB
Python

"""Plane diamond coloring on maximal planar graphs."""
from typing import Any
from sage.all import Graph, graphs # type: ignore[attr-defined] # pylint: disable=no-name-in-module
from lib.colored_graphs import canonize_and_save_graph
def get_plane_diamond_scaffold(g: Graph, v: Any) -> Graph:
"""
Return the diamond scaffold of g relative to v.
The diamond scaffold is the spanning subgraph of g obtained by removing
every edge whose endpoints lie in the same level of the distance
partition of g from v.
"""
distances = dict(g.breadth_first_search(v, report_distance=True))
scaffold = g.copy()
scaffold.delete_edges([(x, y) for x, y in g.edges(labels=False) if distances[x] == distances[y]])
return scaffold
def has_plane_diamond_coloring_at_root(g: Graph, u: Any) -> bool:
"""
Return True iff g admits a proper 4-coloring with two color classes
parity-separated by the BFS distance partition from u.
Equivalent to 4-colorability of the auxiliary graph H_u obtained by
adjoining vertices v_a, v_b to g, with v_a adjacent to every odd-parity
layer vertex, v_b adjacent to every even-parity layer vertex, and a
v_a v_b edge.
"""
distances = dict(g.breadth_first_search(u, report_distance=True))
odd_vertices = [v for v in g.vertices() if distances[v] % 2 == 1]
even_vertices = [v for v in g.vertices() if distances[v] % 2 == 0]
h = g.copy()
v_a = max(g.vertices()) + 1
v_b = v_a + 1
h.add_vertex(v_a)
h.add_vertex(v_b)
h.add_edges([(v_a, w) for w in odd_vertices])
h.add_edges([(v_b, w) for w in even_vertices])
h.add_edge(v_a, v_b)
return h.chromatic_number() <= 4
def has_plane_diamond_coloring(g: Graph) -> bool:
"""Return True iff some root vertex of g witnesses a plane diamond coloring."""
return any(has_plane_diamond_coloring_at_root(g, u) for u in g.vertices())
def search_counterexample(n: int, num_trials: int) -> Graph | None:
"""
Sample random maximal planar graphs of order n and return the first one
with no plane diamond coloring, or None if none is found.
"""
for trial in range(num_trials):
g = graphs.RandomTriangulation(n)
if not has_plane_diamond_coloring(g):
print(f"Counterexample found on trial {trial + 1}")
return g
if (trial + 1) % 10 == 0:
print(f"Checked {trial + 1}/{num_trials} graphs of order {n}, no counterexample yet")
return None
def search_counterexample_comprehensive(max_order: int, min_order: int = 4) -> list[Graph]:
"""
Iterate through every maximal planar graph of order in [min_order, max_order]
and return all those without a plane diamond coloring.
"""
counterexamples: list[Graph] = []
for n in range(min_order, max_order + 1):
checked = 0
for g in graphs.planar_graphs(n, minimum_connectivity=3, maximum_face_size=3):
checked += 1
if not has_plane_diamond_coloring(g):
print(f"Counterexample at order {n} (graph #{checked}): {g.graph6_string()}")
counterexamples.append(g)
if checked % 100 == 0:
print(f" order {n}: checked {checked} graphs, {len(counterexamples)} counterexamples so far")
print(f"order {n} done: {checked} triangulations checked")
return counterexamples
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "comprehensive":
max_order = int(sys.argv[2]) if len(sys.argv) > 2 else 10
min_order = int(sys.argv[3]) if len(sys.argv) > 3 else 4
counterexamples = search_counterexample_comprehensive(max_order, min_order)
print(f"Found {len(counterexamples)} counterexamples in orders {min_order}..{max_order}")
for g in counterexamples:
canonize_and_save_graph(g)
else:
n = int(sys.argv[1]) if len(sys.argv) > 1 else 12
num_trials = int(sys.argv[2]) if len(sys.argv) > 2 else 100
counterexample = search_counterexample(n, num_trials)
if counterexample is None:
print(f"No counterexample found in {num_trials} random triangulations of order {n}")
else:
canonical, graph_dir = canonize_and_save_graph(counterexample)
print(f"Counterexample saved to {graph_dir}")