1
- #Uses python3
2
1
import os
3
2
import sys
4
3
import itertools
7
6
# There're |V| vertices, let v be a vertice: 1 <= v <= 500
8
7
# There're 3 colors, let c be a color: 1 <= c <= 3
9
8
# Let Xvc be a literal that corresponds to a vertice v colored with c:
10
- # A vertice must be colored only once:
11
- # (Xv1 V Xv2 V Xv3)(-Xv1 V -Xv2)(-Xv1 V -Xv3)(-Xv2 v -Xv3)
12
- # Let (u, w) 2 vertices adjacent to v: u, v, w must have different colors:
9
+ # E.g., for v = 1
10
+ # X11 = 3 * 0 + 1 = 1
11
+ # X12 = 2
12
+ # X13 = 3
13
+ # E.g., for v = 2
14
+ # X11 = 3 * (2 - 1) + 1 = 4
15
+ # X12 = 5
16
+ # X13 = 6
17
+ # A vertice must be colored:
18
+ # (Xv1 V Xv2 V Xv3)
19
+ # A vertice can't have 2 different colors at the same time: it must be colored only once:
20
+ # (-Xv1 V -Xv2)(-Xv1 V -Xv3)(-Xv2 v -Xv3)
21
+ # Vertice (u, w) adjacents to v must have different colors:
13
22
# (Xv1 V Xu1 V Xw1)(-Xv1 V -Xu1)(-Xv1 V -Xw1)(-Xu1 V -Xw1)
14
23
# (Xv2 V Xu2 V Xw2)(-Xv2 V -Xu2)(-Xv2 V -Xw2)(-Xu2 V -Xw2)
15
24
# (Xv3 V Xu3 V Xw3)(-Xv3 V -Xu3)(-Xv3 V -Xw3)(-Xu3 V -Xw3)
@@ -25,17 +34,12 @@ def exactly_one_of(literals):
25
34
if len (literals ) >= len (colors ):
26
35
clauses .append ([l for l in literals ])
27
36
37
+ not_same_value (literals )
38
+
39
+ def not_same_value (literals ):
28
40
for pair in itertools .combinations (literals , 2 ):
29
41
clauses .append ([- l for l in pair ])
30
42
31
- def vertices_list_num (vertices_list ):
32
- list_num = 0
33
- for v in vertices_list :
34
- list_num *= 10
35
- list_num += v
36
-
37
- return list_num
38
-
39
43
def create_sat_clauses (n , edges ):
40
44
41
45
adjacency_list = [[] for _ in range (n )]
@@ -46,30 +50,29 @@ def create_sat_clauses(n, edges):
46
50
clauses_set = set ()
47
51
for i in range (n ):
48
52
49
- v = i + 1
53
+ v = i + 1
50
54
51
55
# Clause 1: vertice v has exactly color:
52
56
exactly_one_of ([vertice_color_num (v , color ) for color in colors ])
53
57
54
- if len (adjacency_list ) == 0 :
55
- continue
56
-
57
- adjacency_list [i ].append (v )
58
- adjacency_list [i ].sort ()
59
- list_num = vertices_list_num (adjacency_list [i ])
60
-
61
- # If 2 vertices have the same adjacency list, then it's not necessary to generate clauses of the 2nd vertice
62
- if list_num in clauses_set :
58
+ if len (adjacency_list [i ]) == 0 :
63
59
continue
64
- clauses_set .add (list_num )
65
-
66
- for color in colors :
67
-
68
- # Clause 2: A color c appears exactly once on vertices v and its adjacent vertices:
69
- literals = []
70
- for u in adjacency_list [i ]:
71
- literals .append (vertice_color_num (u , color ))
72
- exactly_one_of (literals )
60
+
61
+ # Clause 2: 2 adjacent vertices must have different colors
62
+ # Clauses corresponding to an edge A --- B must be generated only once
63
+ for a in adjacency_list [i ]:
64
+ edge_num = max (a , v ) * 1000 + min (a , v )
65
+
66
+ if edge_num in clauses_set :
67
+ continue
68
+
69
+ clauses_set .add (edge_num )
70
+
71
+ for color in colors :
72
+ literals = []
73
+ literals .append (vertice_color_num (v , color ))
74
+ literals .append (vertice_color_num (a , color ))
75
+ not_same_value (literals )
73
76
74
77
def print_equisatisfiable_sat_formula (n ):
75
78
0 commit comments