Add level resolutions of maximal planar graphs paper
Migrate the paper content into the amsart template and include the supporting experiments scripts.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
Coverage analysis: for each pair (n, target-class restriction), check whether
|
||||
every iso-class in the restriction is reachable as a level resolution of
|
||||
some triangulation on n vertices.
|
||||
"""
|
||||
import networkx as nx
|
||||
import time
|
||||
from level_cycles import all_level_resolutions
|
||||
from triangulation_gen import enumerate_all_triangulations
|
||||
|
||||
|
||||
def iso_class(G, reps):
|
||||
for i, r in enumerate(reps):
|
||||
if nx.is_isomorphic(G, r):
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
||||
def resolution_classes(G, reps):
|
||||
return {iso_class(Gp, reps) for Gp, _, _, _ in all_level_resolutions(G)}
|
||||
|
||||
|
||||
def min_degree(G):
|
||||
return min(d for _, d in G.degree())
|
||||
|
||||
|
||||
def coverage_report(n, target_filter=None, source_filter=None):
|
||||
"""
|
||||
target_filter / source_filter: callables G -> bool, or None for "any".
|
||||
"""
|
||||
print(f"\n{'='*60}\nn = {n}\n{'='*60}")
|
||||
t0 = time.time()
|
||||
reps = enumerate_all_triangulations(n)
|
||||
print(f"Total iso-classes: {len(reps)}")
|
||||
|
||||
if source_filter is None:
|
||||
sources = list(range(len(reps)))
|
||||
print(f"Sources: all {len(sources)}")
|
||||
else:
|
||||
sources = [i for i, G in enumerate(reps) if source_filter(G)]
|
||||
print(f"Sources (filtered): {len(sources)}")
|
||||
|
||||
if target_filter is None:
|
||||
targets = set(range(len(reps)))
|
||||
else:
|
||||
targets = {i for i, G in enumerate(reps) if target_filter(G)}
|
||||
print(f"Targets: {len(targets)} iso-classes")
|
||||
for i in sorted(targets):
|
||||
deg = sorted((d for _, d in reps[i].degree()), reverse=True)
|
||||
print(f" T{i}: degree {deg}")
|
||||
|
||||
reached, sources_per_target = set(), {i: [] for i in targets}
|
||||
for src_i in sources:
|
||||
prod = resolution_classes(reps[src_i], reps) & targets
|
||||
for p in prod:
|
||||
sources_per_target[p].append(src_i)
|
||||
reached |= prod
|
||||
|
||||
print("\nCoverage:")
|
||||
for i in sorted(targets):
|
||||
sources_list = sources_per_target[i]
|
||||
status = "REACHED" if sources_list else "UNREACHABLE"
|
||||
s = ", ".join(f"T{j}" for j in sources_list[:6])
|
||||
if len(sources_list) > 6:
|
||||
s += f", ... ({len(sources_list)} total)"
|
||||
elif not sources_list:
|
||||
s = "(none)"
|
||||
print(f" T{i}: {status} via {s}")
|
||||
|
||||
uncov = targets - reached
|
||||
print(f"\nUncovered: {sorted(uncov)}")
|
||||
print(f"Time: {time.time()-t0:.1f}s")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# General coverage (any source, any target)
|
||||
for n in [6, 7]:
|
||||
coverage_report(n)
|
||||
|
||||
# md3 sources -> md4 targets
|
||||
print("\n\n" + "#"*60)
|
||||
print("md3 sources -> md4 targets")
|
||||
print("#"*60)
|
||||
for n in [6, 7, 8]:
|
||||
coverage_report(n, target_filter=lambda G: min_degree(G) >= 4)
|
||||
Reference in New Issue
Block a user