Randomized rounding

From HandWiki
Revision as of 14:30, 6 February 2024 by AstroAI (talk | contribs) (simplify)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

In computer science and operations research, randomized rounding[1] is a widely used approach for designing and analyzing approximation algorithms.[2][3]

Many combinatorial optimization problems are computationally intractable to solve exactly (to optimality). For such problems, randomized rounding can be used to design fast (polynomial time) approximation algorithms—that is, algorithms that are guaranteed to return an approximately optimal solution given any input.

The basic idea of randomized rounding is to convert an optimal solution of a relaxation of the problem into an approximately-optimal solution to the original problem. The resulting algorithm is usually analyzed using the probabilistic method.

Overview

The basic approach has three steps:

  1. Formulate the problem to be solved as an integer linear program (ILP).
  2. Compute an optimal fractional solution [math]\displaystyle{ x }[/math] to the linear programming relaxation (LP) of the ILP.
  3. Round the fractional solution [math]\displaystyle{ x }[/math] of the LP to an integer solution [math]\displaystyle{ x' }[/math] of the ILP.

(Although the approach is most commonly applied with linear programs, other kinds of relaxations are sometimes used. For example, see Goemans' and Williamson's semidefinite programming-based Max-Cut approximation algorithm.)

In the first step, the challenge is to choose a suitable integer linear program. Familiarity with linear programming, in particular modelling using linear programs and integer linear programs, is required. For many problems, there is a natural integer linear program that works well, such as in the Set Cover example below. (The integer linear program should have a small integrality gap; indeed randomized rounding is often used to prove bounds on integrality gaps.)

In the second step, the optimal fractional solution can typically be computed in polynomial time using any standard linear programming algorithm.

In the third step, the fractional solution must be converted into an integer solution (and thus a solution to the original problem). This is called rounding the fractional solution. The resulting integer solution should (provably) have cost not much larger than the cost of the fractional solution. This will ensure that the cost of the integer solution is not much larger than the cost of the optimal integer solution.

The main technique used to do the third step (rounding) is to use randomization, and then to use probabilistic arguments to bound the increase in cost due to the rounding (following the probabilistic method from combinatorics). Therein, probabilistic arguments are used to show the existence of discrete structures with desired properties. In this context, one uses such arguments to show the following:

Given any fractional solution [math]\displaystyle{ x }[/math] of the LP, with positive probability the randomized rounding process produces an integer solution [math]\displaystyle{ x' }[/math] that approximates [math]\displaystyle{ x }[/math] according to some desired criterion.

Finally, to make the third step computationally efficient, one either shows that [math]\displaystyle{ x' }[/math] approximates [math]\displaystyle{ x }[/math] with high probability (so that the step can remain randomized) or one derandomizes the rounding step, typically using the method of conditional probabilities. The latter method converts the randomized rounding process into an efficient deterministic process that is guaranteed to reach a good outcome.

Example: the set cover problem

The following example illustrates how randomized rounding can be used to design an approximation algorithm for the set cover problem. Fix any instance [math]\displaystyle{ \langle c, \mathcal S\rangle }[/math] of set cover over a universe [math]\displaystyle{ \mathcal U }[/math].

Computing the fractional solution

For step 1, let IP be the standard integer linear program for set cover for this instance.

For step 2, let LP be the linear programming relaxation of IP, and compute an optimal solution [math]\displaystyle{ x^* }[/math] to LP using any standard linear programming algorithm. This takes time polynomial in the input size. The feasible solutions to LP are the vectors [math]\displaystyle{ x }[/math] that assign each set [math]\displaystyle{ s \in\mathcal S }[/math] a non-negative weight [math]\displaystyle{ x_s }[/math], such that, for each element [math]\displaystyle{ e\in\mathcal U }[/math], [math]\displaystyle{ x' }[/math] covers [math]\displaystyle{ e }[/math]—the total weight assigned to the sets containing [math]\displaystyle{ e }[/math] is at least 1, that is,

[math]\displaystyle{ \sum_{s\ni e} x_s \ge 1. }[/math]

The optimal solution [math]\displaystyle{ x^* }[/math] is a feasible solution whose cost

[math]\displaystyle{ \sum_{s\in\mathcal S} c(S)x^*_s }[/math]

is as small as possible. Note that any set cover [math]\displaystyle{ \mathcal C }[/math] for [math]\displaystyle{ \mathcal S }[/math] gives a feasible solution [math]\displaystyle{ x }[/math] (where [math]\displaystyle{ x_s=1 }[/math] for [math]\displaystyle{ s\in\mathcal C }[/math], [math]\displaystyle{ x_s=0 }[/math] otherwise). The cost of this [math]\displaystyle{ \mathcal C }[/math] equals the cost of [math]\displaystyle{ x }[/math], that is,

[math]\displaystyle{ \sum_{s\in\mathcal C} c(s) = \sum_{s\in\mathcal S} c(s) x_s. }[/math]

In other words, the linear program LP is a relaxation of the given set-cover problem.

Since [math]\displaystyle{ x^* }[/math] has minimum cost among feasible solutions to the LP, the cost of [math]\displaystyle{ x^* }[/math] is a lower bound on the cost of the optimal set cover.

Randomized rounding step

In step 3, we must convert the minimum-cost fractional set cover [math]\displaystyle{ x^* }[/math] into a feasible integer solution [math]\displaystyle{ x' }[/math] (corresponding to a true set cover). The rounding step should produce an [math]\displaystyle{ x' }[/math] that, with positive probability, has cost within a small factor of the cost of [math]\displaystyle{ x^* }[/math].Then (since the cost of [math]\displaystyle{ x^* }[/math] is a lower bound on the cost of the optimal set cover), the cost of [math]\displaystyle{ x' }[/math] will be within a small factor of the optimal cost.

As a starting point, consider the most natural rounding scheme:

For each set [math]\displaystyle{ s\in\mathcal S }[/math] in turn, take [math]\displaystyle{ x'_s = 1 }[/math] with probability [math]\displaystyle{ \min(1,x^*_s) }[/math], otherwise take [math]\displaystyle{ x'_s = 0 }[/math].

With this rounding scheme, the expected cost of the chosen sets is at most [math]\displaystyle{ \sum_s c(s) x^*_s }[/math], the cost of the fractional cover. This is good. Unfortunately the coverage is not good. When the variables [math]\displaystyle{ x^*_s }[/math] are small, the probability that an element [math]\displaystyle{ e }[/math] is not covered is about

[math]\displaystyle{ \prod_{s\ni e} 1-x^*_s \approx \prod_{s\ni e} \exp(-x^*_s) = \exp\Big(-\sum_{s\ni e}x^*_s\Big) \approx \exp(-1). }[/math]

So only a constant fraction of the elements will be covered in expectation.

To make [math]\displaystyle{ x' }[/math] cover every element with high probability, the standard rounding scheme first scales up the rounding probabilities by an appropriate factor [math]\displaystyle{ \lambda \gt 1 }[/math]. Here is the standard rounding scheme:

Fix a parameter [math]\displaystyle{ \lambda \ge 1 }[/math]. For each set [math]\displaystyle{ s\in\mathcal S }[/math] in turn,
take [math]\displaystyle{ x'_s = 1 }[/math] with probability [math]\displaystyle{ \min(\lambda x^*_s, 1) }[/math], otherwise take [math]\displaystyle{ x'_s = 0 }[/math].

Scaling the probabilities up by [math]\displaystyle{ \lambda }[/math] increases the expected cost by [math]\displaystyle{ \lambda }[/math], but makes coverage of all elements likely. The idea is to choose [math]\displaystyle{ \lambda }[/math] as small as possible so that all elements are provably covered with non-zero probability. Here is a detailed analysis.


Lemma (approximation guarantee for rounding scheme)

Fix [math]\displaystyle{ \lambda = \ln (2|\mathcal U|) }[/math]. With positive probability, the rounding scheme returns a set cover [math]\displaystyle{ x' }[/math] of cost at most [math]\displaystyle{ 2\ln(2|\mathcal U|) c\cdot x^* }[/math] (and thus of cost [math]\displaystyle{ O(\log |\mathcal U|) }[/math] times the cost of the optimal set cover).

(Note: with care the [math]\displaystyle{ O(\log |\mathcal U|) }[/math] can be reduced to [math]\displaystyle{ \ln(|\mathcal U|)+O(\log\log|\mathcal U|) }[/math].)

Proof

The output [math]\displaystyle{ x' }[/math] of the random rounding scheme has the desired properties as long as none of the following "bad" events occur:

  1. the cost [math]\displaystyle{ c\cdot x' }[/math] of [math]\displaystyle{ x' }[/math] exceeds [math]\displaystyle{ 2\lambda c\cdot x^* }[/math], or
  2. for some element [math]\displaystyle{ e }[/math], [math]\displaystyle{ x' }[/math] fails to cover [math]\displaystyle{ e }[/math].

The expectation of each [math]\displaystyle{ x'_s }[/math] is at most [math]\displaystyle{ \lambda x_s^* }[/math]. By linearity of expectation, the expectation of [math]\displaystyle{ c\cdot x' }[/math] is at most [math]\displaystyle{ \sum_s c(s)\lambda x_s^*=\lambda c\cdot x^* }[/math]. Thus, by Markov's inequality, the probability of the first bad event above is at most [math]\displaystyle{ 1/2 }[/math].

For the remaining bad events (one for each element [math]\displaystyle{ e }[/math]), note that, since [math]\displaystyle{ \sum_{s\ni e} x^*_s \ge 1 }[/math] for any given element [math]\displaystyle{ e }[/math], the probability that [math]\displaystyle{ e }[/math] is not covered is

[math]\displaystyle{ \begin{align} \prod_{s\ni e} \big(1-\min(\lambda x^*_s,1) \big) & \lt \prod_{s\ni e} \exp({-}\lambda x^*_s) = \exp\Big({-}\lambda \sum_{s\ni e} x^*_s \Big) \\ & \le \exp({-}\lambda) = 1/(2|\mathcal U|). \end{align} }[/math]

(This uses the inequality [math]\displaystyle{ 1+z\le e^z }[/math], which is strict for [math]\displaystyle{ z \ne 0 }[/math].)

Thus, for each of the [math]\displaystyle{ |\mathcal U| }[/math] elements, the probability that the element is not covered is less than [math]\displaystyle{ 1/(2\mathcal U) }[/math].

By the union bound, the probability that one of the [math]\displaystyle{ 1+|\mathcal U| }[/math] bad events happens is less than [math]\displaystyle{ 1/2 + |\mathcal U|/(2\mathcal U)=1 }[/math]. Thus, with positive probability there are no bad events and [math]\displaystyle{ x' }[/math] is a set cover of cost at most [math]\displaystyle{ 2\lambda c\cdot x^* }[/math]. QED

Derandomization using the method of conditional probabilities

The lemma above shows the existence of a set cover of cost [math]\displaystyle{ O(\log(|\mathcal U|)c\cdot x^* }[/math]). In this context our goal is an efficient approximation algorithm, not just an existence proof, so we are not done.

One approach would be to increase [math]\displaystyle{ \lambda }[/math] a little bit, then show that the probability of success is at least, say, 1/4. With this modification, repeating the random rounding step a few times is enough to ensure a successful outcome with high probability.

That approach weakens the approximation ratio. We next describe a different approach that yields a deterministic algorithm that is guaranteed to match the approximation ratio of the existence proof above. The approach is called the method of conditional probabilities.

The deterministic algorithm emulates the randomized rounding scheme: it considers each set [math]\displaystyle{ s\in\mathcal S }[/math] in turn, and chooses [math]\displaystyle{ x'_s \in\{0,1\} }[/math]. But instead of making each choice randomly based on [math]\displaystyle{ x^* }[/math], it makes the choice deterministically, so as to keep the conditional probability of failure, given the choices so far, below 1.

Bounding the conditional probability of failure

We want to be able to set each variable [math]\displaystyle{ x'_s }[/math] in turn so as to keep the conditional probability of failure below 1. To do this, we need a good bound on the conditional probability of failure. The bound will come by refining the original existence proof. That proof implicitly bounds the probability of failure by the expectation of the random variable

[math]\displaystyle{ F = \frac{c\cdot x'}{2\lambda c\cdot x^*} + |\mathcal U^{(m)}| }[/math],

where

[math]\displaystyle{ \mathcal U^{(m)}= \Big\{ e  : \prod_{s\ni e} (1-x'_s) = 1\Big\} }[/math]

is the set of elements left uncovered at the end.

The random variable [math]\displaystyle{ F }[/math] may appear a bit mysterious, but it mirrors the probabilistic proof in a systematic way. The first term in [math]\displaystyle{ F }[/math] comes from applying Markov's inequality to bound the probability of the first bad event (the cost is too high). It contributes at least 1 to [math]\displaystyle{ F }[/math] if the cost of [math]\displaystyle{ x' }[/math] is too high. The second term counts the number of bad events of the second kind (uncovered elements). It contributes at least 1 to [math]\displaystyle{ F }[/math] if [math]\displaystyle{ x' }[/math] leaves any element uncovered. Thus, in any outcome where [math]\displaystyle{ F }[/math] is less than 1, [math]\displaystyle{ x' }[/math] must cover all the elements and have cost meeting the desired bound from the lemma. In short, if the rounding step fails, then [math]\displaystyle{ F \ge 1 }[/math]. This implies (by Markov's inequality) that [math]\displaystyle{ E[F] }[/math] is an upper bound on the probability of failure. Note that the argument above is implicit already in the proof of the lemma, which also shows by calculation that [math]\displaystyle{ E[F] \lt 1 }[/math].

To apply the method of conditional probabilities, we need to extend the argument to bound the conditional probability of failure as the rounding step proceeds. Usually, this can be done in a systematic way, although it can be technically tedious.

So, what about the conditional probability of failure as the rounding step iterates through the sets? Since [math]\displaystyle{ F \ge 1 }[/math] in any outcome where the rounding step fails, by Markov's inequality, the conditional probability of failure is at most the conditional expectation of [math]\displaystyle{ F }[/math].

Next we calculate the conditional expectation of [math]\displaystyle{ F }[/math], much as we calculated the unconditioned expectation of [math]\displaystyle{ F }[/math] in the original proof. Consider the state of the rounding process at the end of some iteration [math]\displaystyle{ t }[/math]. Let [math]\displaystyle{ S^{(t)} }[/math] denote the sets considered so far (the first [math]\displaystyle{ t }[/math] sets in [math]\displaystyle{ \mathcal S }[/math]). Let [math]\displaystyle{ x^{(t)} }[/math] denote the (partially assigned) vector [math]\displaystyle{ x' }[/math] (so [math]\displaystyle{ x^{(t)}_s }[/math] is determined only if [math]\displaystyle{ s\in S^{(t)} }[/math]). For each set [math]\displaystyle{ s\not\in S^{(t)} }[/math], let [math]\displaystyle{ p_s = \min(\lambda x^*_s, 1) }[/math] denote the probability with which [math]\displaystyle{ x'_s }[/math] will be set to 1. Let [math]\displaystyle{ \mathcal U^{(t)} }[/math] contain the not-yet-covered elements. Then the conditional expectation of [math]\displaystyle{ F }[/math], given the choices made so far, that is, given [math]\displaystyle{ x^{(t)} }[/math], is

[math]\displaystyle{ E[F | x^{(t)}] ~=~ \frac{\sum_{s\in S^{(t)}} c(s) x'_s + \sum_{s\not\in S^{(t)}} c(s) p_s}{2\lambda c\cdot x^*} ~+~ \sum_{e\in \mathcal U^{(t)}}\prod_{s\not\in S^{(t)}, s\ni e} (1-p_s). }[/math]

Note that [math]\displaystyle{ E[F | x^{(t)}] }[/math] is determined only after iteration [math]\displaystyle{ t }[/math].

Keeping the conditional probability of failure below 1

To keep the conditional probability of failure below 1, it suffices to keep the conditional expectation of [math]\displaystyle{ F }[/math] below 1. To do this, it suffices to keep the conditional expectation of [math]\displaystyle{ F }[/math] from increasing. This is what the algorithm will do. It will set [math]\displaystyle{ x'_s }[/math] in each iteration to ensure that

[math]\displaystyle{ E[F|x^{(m)}] \le E[F|x^{(m-1)}] \le \cdots \le E[F|x^{(1)}] \le E[F|x^{(0)}] \lt 1 }[/math]

(where [math]\displaystyle{ m=|\mathcal S| }[/math]).

In the [math]\displaystyle{ t }[/math]th iteration, how can the algorithm set [math]\displaystyle{ x'_{s'} }[/math] to ensure that [math]\displaystyle{ E[F|x^{(t)}] \le E[F|S^{(t-1)}] }[/math]? It turns out that it can simply set [math]\displaystyle{ x'_{s'} }[/math] so as to minimize the resulting value of [math]\displaystyle{ E[F|x^{(t)}] }[/math].

To see why, focus on the point in time when iteration [math]\displaystyle{ t }[/math] starts. At that time, [math]\displaystyle{ E[F|x^{(t-1)}] }[/math] is determined, but [math]\displaystyle{ E[F|x^{(t)}] }[/math] is not yet determined --- it can take two possible values depending on how [math]\displaystyle{ x'_{s'} }[/math] is set in iteration [math]\displaystyle{ t }[/math]. Let [math]\displaystyle{ E^{(t-1)} }[/math] denote the value of [math]\displaystyle{ E[F|x'^{(t-1)}] }[/math]. Let [math]\displaystyle{ E^{(t)}_0 }[/math] and [math]\displaystyle{ E^{(t)}_1 }[/math], denote the two possible values of [math]\displaystyle{ E[F|x^{(t)}] }[/math], depending on whether [math]\displaystyle{ x'_{s'} }[/math] is set to 0, or 1, respectively. By the definition of conditional expectation,

[math]\displaystyle{ E^{(t-1)} ~=~ \Pr[x'_{s'}=0] E^{(t)}_0 + \Pr[x'_{s'}=1] E^{(t)}_1. }[/math]

Since a weighted average of two quantities is always at least the minimum of those two quantities, it follows that

[math]\displaystyle{ E^{(t-1)} ~\ge~ \min( E^{(t)}_0, E^{(t)}_1 ). }[/math]

Thus, setting [math]\displaystyle{ x'_{s'} }[/math] so as to minimize the resulting value of [math]\displaystyle{ E[F | x^{(t)}] }[/math] will guarantee that [math]\displaystyle{ E[F | x^{(t)}] \le E[F | x^{(t-1)}] }[/math]. This is what the algorithm will do.

In detail, what does this mean? Considered as a function of [math]\displaystyle{ x'_{s'} }[/math] (with all other quantities fixed) [math]\displaystyle{ E[F | x^{(t)}] }[/math] is a linear function of [math]\displaystyle{ x'_{s'} }[/math], and the coefficient of [math]\displaystyle{ x'_{s'} }[/math] in that function is

[math]\displaystyle{ \frac{c_{s'}}{2\lambda c\cdot x^*} ~-~ \sum_{e\in s'\cap \mathcal U_{t-1}}\prod_{s\not\in S^{(t)}, s\ni e} (1-p_s). }[/math]

Thus, the algorithm should set [math]\displaystyle{ x'_{s'} }[/math] to 0 if this expression is positive, and 1 otherwise. This gives the following algorithm.

Randomized-rounding algorithm for set cover

input: set system [math]\displaystyle{ \mathcal S }[/math], universe [math]\displaystyle{ \mathcal U }[/math], cost vector [math]\displaystyle{ c }[/math]

output: set cover [math]\displaystyle{ x' }[/math] (a solution to the standard integer linear program for set cover)

  1. Compute a min-cost fractional set cover [math]\displaystyle{ x^* }[/math] (an optimal solution to the LP relaxation).
  2. Let [math]\displaystyle{ \lambda \leftarrow \ln(2|\mathcal U|) }[/math]. Let [math]\displaystyle{ p_s \leftarrow \min(\lambda x^*_{s},1) }[/math] for each [math]\displaystyle{ s\in\mathcal S }[/math].
  3. For each [math]\displaystyle{ s'\in\mathcal S }[/math] do:
    1. Let [math]\displaystyle{ \mathcal S \leftarrow \mathcal S - \{s'\} }[/math].   ([math]\displaystyle{ \mathcal S }[/math] contains the not-yet-decided sets.)
    2. If    [math]\displaystyle{ \frac{c_{s'}}{2\lambda c\cdot x^*} \gt \sum_{e\in s'\cap\mathcal U} \prod_{s\in \mathcal S, s\ni e}(1-p_s) }[/math]
      then set [math]\displaystyle{ x'_s\leftarrow 0 }[/math],
      else set [math]\displaystyle{ x'_s\leftarrow 1 }[/math] and [math]\displaystyle{ \mathcal U\leftarrow\mathcal U - s' }[/math].
        ([math]\displaystyle{ \mathcal U }[/math] contains the not-yet-covered elements.)
  4. Return [math]\displaystyle{ x' }[/math].

lemma (approximation guarantee for algorithm)

The algorithm above returns a set cover [math]\displaystyle{ x' }[/math] of cost at most [math]\displaystyle{ 2\ln(2|\mathcal U|) }[/math] times the minimum cost of any (fractional) set cover.

proof

The algorithm ensures that the conditional expectation of [math]\displaystyle{ F }[/math], [math]\displaystyle{ E[F \,|\, x^{(t)}] }[/math], does not increase at each iteration. Since this conditional expectation is initially less than 1 (as shown previously), the algorithm ensures that the conditional expectation stays below 1. Since the conditional probability of failure is at most the conditional expectation of [math]\displaystyle{ F }[/math], in this way the algorithm ensures that the conditional probability of failure stays below 1. Thus, at the end, when all choices are determined, the algorithm reaches a successful outcome. That is, the algorithm above returns a set cover [math]\displaystyle{ x' }[/math] of cost at most [math]\displaystyle{ 2\ln(2|\mathcal U|) }[/math] times the minimum cost of any (fractional) set cover.

Remarks

In the example above, the algorithm was guided by the conditional expectation of a random variable [math]\displaystyle{ F }[/math]. In some cases, instead of an exact conditional expectation, an upper bound (or sometimes a lower bound) on some conditional expectation is used instead. This is called a pessimistic estimator.

Comparison to other applications of the probabilistic method

The randomized rounding step differs from most applications of the probabilistic method in two respects:

  1. The computational complexity of the rounding step is important. It should be implementable by a fast (e.g. polynomial time) algorithm.
  2. The probability distribution underlying the random experiment is a function of the solution [math]\displaystyle{ x }[/math] of a relaxation of the problem instance. This fact is crucial to proving the performance guarantee of the approximation algorithm --- that is, that for any problem instance, the algorithm returns a solution that approximates the optimal solution for that specific instance. In comparison, applications of the probabilistic method in combinatorics typically show the existence of structures whose features depend on other parameters of the input. For example, consider Turán's theorem, which can be stated as "any graph with [math]\displaystyle{ n }[/math] vertices of average degree [math]\displaystyle{ d }[/math] must have an independent set of size at least [math]\displaystyle{ n/(d+1) }[/math]. (See this for a probabilistic proof of Turán's theorem.) While there are graphs for which this bound is tight, there are also graphs which have independent sets much larger than [math]\displaystyle{ n/(d+1) }[/math]. Thus, the size of the independent set shown to exist by Turán's theorem in a graph may, in general, be much smaller than the maximum independent set for that graph.

See also

References

  1. Raghavan, Prabhakar; Tompson, Clark D. (1987), "Randomized rounding: A technique for provably good algorithms and algorithmic proofs", Combinatorica 7 (4): 365–374, doi:10.1007/BF02579324, http://techreports.lib.berkeley.edu/accessPages/CSD-85-242.html .
  2. Randomized algorithms. Cambridge University Press. 1995-08-25. ISBN 978-0-521-47465-8. https://books.google.com/books?id=QKVY4mDivBEC&q=randomized+rounding. 
  3. Vazirani, Vijay (2002-12-05). Approximation algorithms. Springer Verlag. ISBN 978-3-540-65367-7. https://books.google.com/books?id=EILqAmzKgYIC&q=%22randomized+rounding%22. 
  4. Young, Neal E. (2002). "Randomized Rounding without Solving the Linear Program". arXiv:cs/0205036.
  5. Young, Neal. "Oblivious randomized rounding". https://algnotes.info/on/obliv/. 

Further reading

  • Althöfer, Ingo (1994), "On sparse approximations to randomized strategies and convex combinations", Linear Algebra and Its Applications 199: 339–355, doi:10.1016/0024-3795(94)90357-3 
  • Hofmeister, Thomas; Lefmann, Hanno (1996), "Computing sparse approximations deterministically", Linear Algebra and Its Applications 240: 9–19, doi:10.1016/0024-3795(94)00175-8 
  • Lipton, Richard J.; Young, Neal E. (1994), "Simple strategies for large zero-sum games with applications to complexity theory", STOC '94: Proceedings of the twenty-sixth annual ACM symposium on theory of computing, New York, NY: ACM, pp. 734–740, doi:10.1145/195058.195447, ISBN 978-0-89791-663-9