We have long considered showing the existence of a linear time algorithm for a problem to be the gold standard of achievement. Indeed, it is hard to imagine doing much better than that, since for any nontrivial problem, it would seem that an algorithm must consider all of the input in order to make a decision.
Any algorithm operating on a dataset and deciding whether all members of the dataset follow a particular property must operate in time because we must look at every datapoint in the dataset. Imagine that you want to check if any of the students in your class failed an exam. In order to check this, you have to look at each student’s exam. But you are only dealing with students. What if your class consisted of students? How long would it take to look at each student’s exam?
Some datasets contain millions or billions of entries. We now have to ask the question whether it is more important to know whether there is one outlier in the dataset or whether the dataset is generally uniform. Going back to our previous example, is it more beneficial to know exactly how many students failed the exam or know with high confidence that of the students did not fail. What if I tell you that the second question results in a much smaller runtime than the first?
And this is really the appeal of sublinear time algorithms. Rather than looking at all the inputs in a dataset, we can look at a few select inputs to discern a pattern. But this also means that we have to refine some of the definitions we are operating under, and, perhaps, lower our expectations of what we want to find in a dataset.
To start, we can no longer define whether a dataset is or is not a certain quality. Instead we need to discern whether the dataset is probably pretty close to having the quality. (Um, that’s a lot of wishy-washy modifiers!) Defined formally, this concept is called property testing.
Definition 1: An input to a function, , is -close to satisfying a property if there is some that satisfies , and and differ in at most places (where is the number of elements in and ). Otherwise, is said to be -far from satisfying . [Rubinfeld 2006]
Definition 2: A property testing algorithm for property given input with elements and must satisfy:
- If satisfies , then the algorithm accepts (outputs “PASS”) with probability greater than or equal to .
- If is -far from satisfying , then the algorithm rejects (outputs “FAIL”) with probability greater than or equal to .
There are two things to note about the definitions. First, property testing does not specify what happens when an input is -close to a property. The algorithm can either pass or fail with arbitrary probability in this case. Second, the probability is arbitrarily set since lower errors may be found by running the algorithm repeatedly and taking the majority answer.
You can view a comprehensive list of why property testing is useful here [Ron 2001], but the key idea is that property testing eliminates all the “bad” inputs so you don’t have to waste valuable computational time and resources on these inputs. After narrowing down your inputs to a select few which pass the test, then you can run your full-blown (linear time!) algorithm on those inputs.
To see an example of property testing, let’s start with graph bipartiteness. Testing whether a graph is bipartite takes runtime in the worst case (where is the number of vertices in the graph) because it requires looking at all the vertices and edges in the graph using either depth first search or breadth first search. In order to use the notion of property testing, we can transform the problem to the following:
Definition 3: A graph, , is -close to bipartite if a bipartite graph can be created by deleting at most edges in . Otherwise, it is -far from bipartite.
Definition 4: A graph, , is -far from bipartite if partitions of , the are edges such that or .
- Choose a random sample, , of vertices.
- Find the induced subgraph of by querying if for every pair of vertices, and , in .
- Perform a DFS or BFS of to determine if it is bipartite. If it is bipartite, output “PASS.” Otherwise, output “FAIL.”
We can see that this algorithm actually has a one-sided error rather than the two-sided error defined above. If a graph is bipartite, then all subgraphs of the given graph are also bipartite. Thus, TEST-BIPARTITE outputs “PASS” with probability when the input graph is bipartite. All we have left to show is that if the input graph is -far from bipartite, then the algorithm will output “FAIL” with probability at least .
To prove this, we assume that the input graph to TEST-BIPARTITE is -far from bipartite. Using Definition 4, we can introduce two different subsets of vertices that will help us prove the above property:
- Choose a random sample of vertices, , where .
- Choose a random sample of pairs of vertices, for , where .
We can consider and to be subsets of since the sizes of both are .
Let’s first consider the case when all nodes in are connected to all nodes in (i.e. given and ). If we look at a bipartition of into , then we can induce a bipartition of if the graph is bipartite: , if shares an edge with a vertex in , place in and vice versa. If has an edge with a vertex in both and , then arbitrarily choose to place in either or . If for every partition of , we cannot find a partition of s.t. is a bipartition, then we know that the original graph, , is not bipartite and TEST-BIPARTITE outputs “FAIL.”
Given our assumption that every node in is connected to a node in , we can compute the probability that we will catch a vertex, , that does not satisfy a partition where is a vertex in and is a vertex in :
Consequently, the probability that we have no violating edges is:
From our definition of and , we know that . If we let and the total number of partitions of is , then, the probability that one (or more) of the partitions is a bipartite partition is (excluding the trivial case when ):
Therefore, the probability when is -far from bipartite that TEST-BIPARTITE outputs “FAIL” is . But this is only for the case when all nodes in are connected to all nodes in . If this is not the case, we need to show that is adjacent to at least “bad” edges for every partition with high probability in order for the proof to hold. In fact, we can show that is adjacent to at least “bad” edges.
Definition 5: is a “high degree” vertex if else is a low-degree vertex.
If we choose , then the probability that a “high degree” node in does not have an edge to any node in is:
Let represent the set of “high degree” nodes in . Then the expected number of “high degree” nodes in that does not have an edge to nodes in is:
By the Markov inequality, the probability that number of “high degree” nodes in that do not have any edges to nodes in is greater than is given by:
So, with probability we have edges adjacent to “high degree” in that have no edges to nodes in and edges that are adjacent to “low degree” edges (regardless of whether or not they are in and are adjacent to nodes in ). Therefore, because we have a total number of “bad” edges, we have edges adjacent to nodes in .
Therefore, we have shown that is adjacent to edges with probability and our proof from before holds.
What we’ve managed to show through all the math is that the TEST-BIPARTITE algorithm satisfies the condition for property testing.
You’ve probably noticed that the actual algorithm for property testing of graph bipartiteness is not too complex, but the process of proving that the algorithm satisfies the conditions for a property testing algorithm is much (much!) more involved. If you’re interested in learning more about sublinear algorithms, you can take a look at these class sites here and here. It is a very new field of algorithms and hence very exciting!