The complexity class of #P problems
Recently, I had an assignment in one of my courses - Beyond NP-Completeness, to present the complexity class of #P (Sharp-P) problems based on L.G. Valiant’s paper on complexity of computing the permanent of a matrix.
This post is an attempt to explain the paper as I found very limited number of resources on the internet where this topic is discussed in detail, one of the sightings being a lecture by Professor Erik Demaine under MIT open courseware which can be found on youtube.
Before we begin, it is strongly recommended to familiarize yourself with the following:
- The classes P, NP, NP-Hard, NP-Complete
- Poly-time reductions
- The class FP
- The notion of an Oracle
So let’s begin with the permanent, which is defined for an n x n matrix A as:
Before proceeding, let’s understand what this means, and what we want to compute.
A closer look at the permanent tells us that if we change all the negative signs in the expression of the determinant of a matrix to positive signs, it will indeed become the Permanent. To show this with an example: Consider the matrix,
The determinant of
Valiant comments on the complexity of the problem of finding the permanent of a (0-1) matrix, for which he defines the class #P. To put it easily, #P problems are the counting problems associated with the decision problems in class NP. It is a class of function problems, and not decision problems (where the answer is a simple yes/no). An NP problem of the form “Does there exist a solution that satisfies X?” usually corresponds to the #P problem “How many solutions exist which satisfy X?”. Here goes the example of a #P problem:
#SAT - Given a boolean formula
Defining #P completeness
To define completeness in this class of problems, we need to bring in Oracle Turing Machines and the class FP. Oracle machines are those which have access to an oracle that can magically solve the decision problem for some language
Back to the problem
Now let’s get back to the permanent. We take a special case of the permanent problem where we put a constraint that the input matrix is a (0, 1) matrix, that is, all the entries of the given matrix are either 0 or 1. Let us look at this problem of finding the permanent of a binary matrix with a different perspective. Imagine that the given matrix A is an adjacency matrix of a bipartite graph
Now if we look at the term inside the summation, that is
Now we shall move on to prove the Valiant’s theorem which says that finding permanent for a binary matrix is #P-complete. We already proved it is in #P, so now all remains for us is to prove that it is in #P-Hard, that is all #P problems can be reduced to this problem in the way explained earlier in this post (where completeness is defined for #P problems). For this, we look at the problem of finding the permanent as a different graph problem.
Consider A = adjacency matrix of a weighted and directed graph with n nodes (We are talking about a general matrix now, not a binary matrix). We define two things now:
- Cycle Cover of a graph G: A set of cycles (subgraphs of G in which all vertices have indegree = 1 and outdegree = 1) which contains all vertices of G
- Weight of a cycle cover: Product of weights of edges involved in the cover
Now, with a good observation, we can conclude that
Proceeding with the proof, we will attempt to reduce an instance of the 3-SAT problem to an instance of the cycle cover problem. The methodology and examples are directly taken from the original paper. We begin with a boolean formula given to us in 3-CNF form.
We construct graph G by superposing the following the structures:
- A Track
for each variable - An Interchange
for each clause - For each literal
such that or , a Junction at which interchange and track meet. - The interchanges also have internal junctions, which are exactly same as above
Example: Let’s take some formula F where:
For this example, the following are the structures:
Track |
Interchange |
---|---|
![]() |
![]() |
The small shaded regions are the junctions, which are themselves a network of nodes and edges represented by the adjacency matrix,
Why this matrix is valued exactly with these numbers will be clear as we proceed. This is a very crucial part. Let’s note some important things:
- Each junction (represented by
) has external connections only via nodes 1 and 4 - Taking
as the matrix leftover after deleting rows a and columns b, we note the following properties of the matrix : . . . . .
Using these properties, we can draw very good insights. Let’s look at routes in the graph. A route is a cycle cover. If we consider all the routes which have the same set of edges outside of the junctions, then we can call a route bad if:
- It ignores a junction
In this case, the cycle cover will have the ignored junction to be covered, so it will come separately as a product in the term. But , so it will make the whole term 0 and thus will not contribute to the cycle cover. - It enters and leaves a junction at the same end
This case is bad because , so if nodes 1, 2, 3 or 2, 3, 4 remain (only one of the ends is covered) then again these nodes will separately come as a cycle and make that whole term 0. Thus no contribution to the total number of cycle covers - It enters at node 1 of a junction, jumps to node 4 and then leaves out
This case leaves out nodes 2 and 3 of a junction, so they have to be covered in a separate cycle, but , so this will again make the term 0 and contribute nothing in the total number of cycle covers
So the only choice we have is to enter at either node 1 or node 4 and leave at the opposite end after covering nodes 2 and 3 if we want to make that route count towards the total number of cycle covers (the value of the permanent). Now if we go by this only choice, the contribution to the cycle will be 4, as
In any track
- All junctions on the left side are picked by the track and those on the right side are picked by interchanges
- The vice-versa of the above
These two cases correspond to whether
Now observe the interchanges. Each interchange has 5 junctions, 3 of which are connected to a corresponding track, which consists of the variable that is present in that particular clause, and 2 are internal junctions, which are of the same structure as a normal junction. A careful observation tells us that the whole of an interchange (all the five junctions) cannot be picked up by a route, in fact, all 3 of the external junctions can never be picked up in a route by the interchange, so at least one of the 3 junctions connected to tracks must be picked up by a track, this constraint being synonymous to the fact that we need at least one literal in the clause to be true, to make the whole clause true.
Now the total number of good routes (cycle covers) exactly corresponds to the total number of satisfying variable assignments for the boolean formula
Let’s get on to finding the permanent of a 0-1 matrix now. It is a great thing to note that though the problem of finding a perfect matching in a bipartite graph
To prove this, we will reduce the permanent problem to the 0-1 permanent problem. First, we need to make the weights of all the edges non-negative. Doing this is easy with modular arithmetic. We can compute
Since the number of primes
So now we have a matrix where all the entries are non-negative. We have to reduce this to a form where all entries are either 0 or 1, to prove that the permanent problem is reducible to the 0-1 permanent problem. We can do so in two ways, by transforming the original graph to an equivalent graph.
- As mentioned in the original paper, Fig. 2 by forming self-loops proportional to the weight of the edge.
- First, convert all the edges to widgets such that all the edges in the resultant graph have weights which are powers of 2. Then all edges that are powers of 2 can be easily transformed to widgets where we only have 0-1 edges. All the while proving that the initial and final graphs are equivalent.
The first method is mentioned in the paper, so I will be explaining the second perspective here. Images are taken from Wikipedia. First, we transform the graph
To prove the correspondence, take two cases for a cycle cover C of the graph
- If edge u-v was not in C, then to cover all the edges in the transformed graph, we must use all the self-loops, so the total contribution = 1 in the product, and hence we have no change in the output. This is as good as not considering the edge u-v in the original graph
- If edge u-v was present in C, then in all the corresponding cycle covers in
, there must be a path from u to v. We can see that there are total such paths and they sum up to
Hence graphs
This is the transformation from
- If edge u-v was not a part of C, the only way to form a cycle cover (taking all vertices) is to take all the self-loops
- If edge u-v was present in C, then in any cycle cover of
there must be a path from u to v. At each step from u to v, we have 2 choices, and such a choice has to be taken times, so we have a total of different possible paths from u to v, so it will contribute overall, same as the weight of the u-v edge in
Thus the problem of finding the permanent of a 0-1 matrix, and equivalently the problem of finding the number of perfect matchings in a bipartite graph
I have talked about more #P-complete problems and their proofs in this post.