-
Notifications
You must be signed in to change notification settings - Fork 3
[Model] PartitionIntoCliques #834
Description
Motivation
PARTITION INTO CLIQUES (P26) from Garey & Johnson, A1.1 GT15. A classical NP-complete problem useful for reductions. Equivalent to graph coloring on the complement graph: G can be partitioned into K cliques if and only if the complement graph of G is K-colorable. This duality makes it a natural companion to KColoring.
Associated rules:
- [Rule] GRAPH K-COLORABILITY to PARTITION INTO CLIQUES #844: GRAPH K-COLORABILITY → PartitionIntoCliques (complement graph construction, Karp 1972)
- [Rule] PARTITION INTO CLIQUES to MinimumCoveringByCliques #889: PartitionIntoCliques → MinimumCoveringByCliques
Definition
Name: PartitionIntoCliques
Canonical name: PARTITION INTO CLIQUES
Reference: Garey & Johnson, Computers and Intractability, A1.1 GT15
Mathematical definition:
INSTANCE: Graph G = (V,E), positive integer K ≤ |V|.
QUESTION: Can the vertices of G be partitioned into k ≤ K disjoint sets V_1, V_2, . . . , V_k such that, for 1 ≤ i ≤ k, the subgraph induced by V_i is a complete graph?
Variables
- Count: n = |V| variables (one per vertex)
- Per-variable domain: {0, 1, ..., K-1}, indicating which clique the vertex belongs to
- Meaning: Variable i = j means vertex i is assigned to clique group V_j. A valid assignment requires that for every pair of vertices u, v assigned to the same group j, the edge {u, v} is present in E (i.e., each group induces a complete subgraph).
Schema (data type)
Type name: PartitionIntoCliques
Variants: graph topology (graph type parameter G)
| Field | Type | Description |
|---|---|---|
graph |
SimpleGraph |
The undirected graph G = (V, E) |
num_cliques |
usize |
The bound K on the number of cliques |
Notes:
- This is a satisfaction (decision) problem:
Value = Or, implementing feasibility semantics. - Key getter methods:
num_vertices()(= |V|),num_edges()(= |E|),num_cliques()(= K). - No weight type is needed (purely structural question).
- Equivalent to KColoring on the complement graph: color classes in the complement are independent sets, which are cliques in G.
Complexity
- Decision complexity: NP-complete (Karp, 1972, where it was called CLIQUE COVER). Transformation from GRAPH K-COLORABILITY via complement graph. Remains NP-complete for all fixed K >= 3. Solvable in polynomial time for K <= 2.
- Best known exact algorithm: O*(2^n) via inclusion-exclusion, since the problem is equivalent to chromatic number computation on the complement graph. The complement construction does not change the number of vertices.
- Concrete complexity expression:
"2^num_vertices"(fordeclare_variants!) - Special cases:
- K <= 2: polynomial time
- Graphs with no K_4 subgraph: remains NP-complete (related to PARTITION INTO TRIANGLES construction)
- Chordal graphs: polynomial time (Gavril, 1972)
- Circular arc graphs: polynomial time given arc representation (Gavril, 1974)
- Comparability graphs: polynomial time (Golumbic, 1977)
- Perfect graphs: polynomial time (clique cover number equals chromatic number of complement)
- References:
- R. M. Karp (1972). "Reducibility among combinatorial problems." In Complexity of Computer Computations, Plenum Press.
- A. Björklund, T. Husfeldt, M. Koivisto (2009). "Set Partitioning via Inclusion-Exclusion." SIAM J. Comput. 39(2), pp. 546-563.
Extra Remark
Full book text:
INSTANCE: Graph G = (V,E), positive integer K ≤ |V|.
QUESTION: Can the vertices of G be partitioned into k ≤ K disjoint sets V_1, V_2, . . . , V_k such that, for 1 ≤ i ≤ k, the subgraph induced by V_i is a complete graph?
Reference: [Karp, 1972] (there called CLIQUE COVER). Transformation from GRAPH K-COLORABILITY.
Comment: Remains NP-complete for edge graphs [Arjomandi, 1977], for graphs containing no complete subgraphs on 4 vertices (see construction for PARTITION INTO TRIANGLES in Chapter 3), and for all fixed K ≥ 3. Solvable in polynomial time for K ≤ 2, for graphs containing no complete subgraphs on 3 vertices (by matching), for circular arc graphs (given their representation as families of arcs) [Gavril, 1974a], for chordal graphs [Gavril, 1972], for comparability graphs [Golumbic, 1977].
How to solve
- It can be solved by (existing) bruteforce — enumerate all assignments of vertices to K groups and check that each group induces a complete subgraph.
- It can be solved by reducing to integer programming — binary variables x_{v,j} for vertex v in clique j, constraints enforcing partition (each vertex in exactly one group) and clique validity (non-adjacent vertices cannot share a group). Companion rule issue to be filed separately.
- Other: Equivalent to KColoring on complement graph; any graph coloring algorithm applies after complementation.
Example Instance
Instance 1 (YES — partition into cliques exists):
Graph G with 6 vertices {0, 1, 2, 3, 4, 5} and 9 edges, K = 3:
- Edges: {0,1}, {0,2}, {1,2}, {3,4}, {3,5}, {4,5}, {0,3}, {1,4}, {2,5}
- Partition: V_1 = {0, 1, 2}, V_2 = {3, 4, 5}
- V_1: edges {0,1}, {0,2}, {1,2} all present — K_3 ✓
- V_2: edges {3,4}, {3,5}, {4,5} all present — K_3 ✓
- Answer: YES (only 2 cliques needed; 66 valid partitions out of 729 total with K=3)
Instance 2 (NO — no partition into K cliques exists):
Graph G with 5 vertices {0, 1, 2, 3, 4} and 5 edges, K = 2:
- Edges: {0,1}, {1,2}, {2,3}, {3,4}, {4,0} (a 5-cycle C_5)
- The largest cliques in C_5 are edges (size 2); no triangles exist.
- Any clique covers at most 2 vertices. With K=2, we cover at most 4 vertices; the 5th needs a 3rd clique.
- Example: {0,1} and {2,3} are cliques, but vertex 4 is left uncovered. Clique cover number = 3.
- Answer: NO (0 valid partitions out of 32 with K=2)
Python validation script
from itertools import product
def count_valid(n, edges, K):
edge_set = set()
for u, v in edges:
edge_set.add((u,v)); edge_set.add((v,u))
count = 0
for assign in product(range(K), repeat=n):
valid = True
for c in range(K):
members = [v for v in range(n) if assign[v] == c]
for i in range(len(members)):
for j in range(i+1, len(members)):
if (members[i], members[j]) not in edge_set:
valid = False; break
if not valid: break
if not valid: break
if valid: count += 1
return count
# Instance 1: YES
e1 = [(0,1),(0,2),(1,2),(3,4),(3,5),(4,5),(0,3),(1,4),(2,5)]
assert count_valid(6, e1, 3) == 66
print("Instance 1: 66/729 valid (YES)")
# Instance 2: NO (C5, K=2)
e2 = [(0,1),(1,2),(2,3),(3,4),(4,0)]
assert count_valid(5, e2, 2) == 0
print("Instance 2: 0/32 valid (NO)")Metadata
Metadata
Assignees
Labels
Type
Projects
Status