Skip to content

Connected Components (CC) ​

Problem Definition ​

Given an undirected graph, partition its nodes into connected components and label every node with an identifier for the component it belongs to. A common labeling scheme, used here, is to label each node with the smallest node identifier reachable from it — nodes end up sharing a label exactly when they are in the same component.

Test Data ​

# Undirected edges are represented in both directions
UEdge("a", "b");
UEdge("b", "a");
UEdge("b", "c");
UEdge("c", "b");
UEdge("d", "e");
UEdge("e", "d");

Node(x) distinct :- UEdge(x, _);

Solution ​

# Every node starts out labeled with itself
CC(x) Min= x :- Node(x);

# A node's label shrinks to the smallest label among its neighbors
CC(x) Min= CC(y) :- UEdge(x, y);

Expected Results ​

+------+--------------+
| col0 | logica_value |
+------+--------------+
| a    | a            |
| b    | a            |
| c    | a            |
| d    | d            |
| e    | d            |
+------+--------------+

Nodes a, b, and c form one component labeled a (its smallest member), while d and e form a separate component labeled d. The label propagates through the graph one hop per recursive iteration until it stabilizes.

TIP

Both rules use the same aggregation operator (Min=). Mixing a plain = base case with an aggregating recursive case on the same predicate is not allowed — see Aggregation in Recursion.