"""Dump candidate invariants for bridge-derived vs non-bridge-derived triangulations at small n, to spot a separating (necessary) condition.""" 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 from triangulation_gen import enumerate_all_triangulations from exhaustive_bridge import valid_parity_partitions from small_n_probe import is_bridge_derived def per_partition_stats(G): """For each valid partition return dict of invariants.""" rows = [] for labels in valid_parity_partitions(G): ev = [v for v in G.nodes() if labels[v] == 0] od = [v for v in G.nodes() if labels[v] == 1] SE, SO = G.subgraph(ev), G.subgraph(od) ce = nx.number_connected_components(SE) co = nx.number_connected_components(SO) be = SE.number_of_edges() - len(ev) + ce bo = SO.number_of_edges() - len(od) + co rows.append(dict(be=be, bo=bo, ee=SE.number_of_edges(), eo=SO.number_of_edges(), ce=ce, co=co, ne=len(ev), no=len(od))) return rows def summarize(G): rows = per_partition_stats(G) tb = [r['be'] + r['bo'] for r in rows] cross = [G.number_of_edges() - r['ee'] - r['eo'] for r in rows] # does some partition make BOTH parity subgraphs forests (be=bo=0)? forests = any(r['be'] == 0 and r['bo'] == 0 for r in rows) return dict(min_tb=min(tb), max_tb=max(tb), nparts=len(rows), min_cross=min(cross), max_cross=max(cross), both_forest=forests) def main(n): tris = enumerate_all_triangulations(n) print(f'n={n}: {len(tris)} triangulations', flush=True) bd_stats, nb_stats = [], [] for G in tris: s = summarize(G) if is_bridge_derived(G): bd_stats.append(s) else: nb_stats.append(s) def col(stats, key): return sorted(set(s[key] for s in stats)) for key in ['min_tb', 'max_tb', 'min_cross', 'max_cross']: print(f' {key:10s} bridge={col(bd_stats,key)} ' f'NONbridge={col(nb_stats,key)}', flush=True) print(f' both_forest exists? bridge={sorted(set(s["both_forest"] for s in bd_stats))}' f' NONbridge={sorted(set(s["both_forest"] for s in nb_stats))}', flush=True) # separator check: any min_tb value unique to one class? bd_min = set(s['min_tb'] for s in bd_stats) nb_min = set(s['min_tb'] for s in nb_stats) print(f' min_tb only-in-bridge: {bd_min - nb_min}; ' f'only-in-NONbridge: {nb_min - bd_min}', flush=True) print(f' both_forest: bridge {sum(s["both_forest"] for s in bd_stats)}/{len(bd_stats)}, ' f'NONbridge {sum(s["both_forest"] for s in nb_stats)}/{len(nb_stats)}', flush=True) if __name__ == '__main__': main(int(sys.argv[1]) if len(sys.argv) > 1 else 9)