Let there be a set $S$ and denote by $P=2^S$ the power set of $S$. We are given a finite subset $L = \{p_0, \ldots, p_{n-1}\}$ of $P$ and we are allowed to transform the set as follows: if two sets $p_i$ and $p_j$ share some elements, i.e. $p_i \cap p_j \neq \emptyset$, remove both $p_i$ and $p_j$ from $L$ but add their union $p_i \cup p_j$ to $L$.
What is the algorithmically fastest way to reach a state where there is no further (or almost no further) transformation of $L$ possible?
One simple way to achieve that goal is to compare all elements with each other and perform a transformation if possible, repeat until no changes are possible.
Pseudo C++-code using std::vector:
vector<Set> L = ...;
int n = L.size();
bool hasChanged = true;
while (hasChanged) {
hasChanged = false;
for(int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (!isDisjoint(L[i], L[j])) {
// remove L[i] and L[j]
swap(L.back(), L[i]);
L.pop_back();
swap(L.back(), L[j]);
L.pop_back();
// add their union
L.push_back(getUnion(L[i], L[j]));
hasChanged = true;
i -= 1; // we don't want to skip the swapped element
break;
}
}
}
}
This algorithm takes $\frac{n^2-n}{2}$ comparisions in the best case and $\sum_{k=1}^n \frac{k^2-k}{2}$ comparions in the worst case. Naturally the number of comparisons needed depends on the ordering of the elements in the vector.
To provide some less abstract context: I have a set of line segments which i want to reduce. So the idea is to connect lines which are "close" to each other. A connected line does not necessarily share start or endpoints with its original lines but it can be connected to other lines in the set. How do I connect all the lines until there is no further improvement possible in the fastest way possible?