I have a set of variables S, and a boolean function f defined on S as follows:
f(x1, x2, … xn) = True iff f(xi, xj) = True ∀ 1 ≤ i ≤ n ∀ 1 ≤ j ≤ n, n > 1, else False.
f(a, b) is known and f(a, a) is True ∀ a, b in S.
I would appreciate some help in designing a fast algorithm that can return all subsets of S upon which f returns True.
As an example, let S = [a, b, c] and f(a, b) = f(b, c) = f(a, c) = True. The algorithm should then return [[a, b], [a, c], [b, c], [a, b, c]].
I have thought of four strategies to improve on brute force search:
1) The order of parameters of f doesn’t matter.
2) Use the fact that f(a, a) is True and f(xi, xj) = f(xj, xi) so only i < j needs checking.
2) Use the fact that f(x1, x2, … xn+1) = f(x1, x2, … xn) ∧ (f(xi, xn+1) ∀ 1 ≤ i ≤ n) where ∀ denotes iterated conjunction.
3) note that 2) implies that if f(x1, x2, … xn) returns False, then f(x1, x2, … xn+Δ) also does, potentially reducing the solution space.
4) Returning False as soon as soon as f(xi, xj) is false for some i, j.
If you want to write some code, I would appreciate it if you could give it in python.
Many thanks.
The two-argument function
f(a, b)can be seen as a symmetric, reflexive relation on S, which can be seen as an undirected graph.Viewed that way,
f(x1, ..., xn)is true iff{x1, ..., xn}forms a complete subgraph.From there, you end up at the clique problem which, unfortunately, turns out to be NP-complete. In other words, a fast algorithm is unlikely to exist.