Explain how to implement the algorithm \(\textsc{Permute-By-Sorting}\) to handle the case in which two or more priorities are identical. That is, your algorithm should produce a uniform random permutation, even if two or more priorities are identical.
When two or more priorities are identical, we need a tie-breaking mechanism to ensure the relative order of tied elements is also randomized. Without this, elements with the same priority would maintain their original relative order, introducing bias.
The key insight is to create a composite key for sorting that combines the random priority with the original index. When priorities are equal, we break ties using a secondary randomized criterion.
Method 1: Two-Level Priority
Assign each element two values:
Primary priority: Random value from \([1, n^3]\)
Secondary priority: Random value from \([1, n^3]\) (or even \([1, n^2]\))
Sort by the primary priority first, then by the secondary priority for ties.
In the sort, elements are compared first by \(P\)[\(i\)]. If \(P\)[\(i\)] = \(P\)[\(j\)], then we compare \(Q\)[\(i\)] and \(Q\)[\(j\)].
The probability of two elements having identical composite keys \((P[i], Q[i]) = (P[j], Q[j])\) is \(1/n^6\), which is negligibly small. The probability that all \(n\) composite keys are unique is at least \(1 - n(n-1)/(2n^6) > 1 - 1/n^3\), which approaches 1 very quickly.
Method 2: Random Tiebreaker Values
A simpler approach assigns each element a unique tiebreaker that’s used only when priorities collide:
However, this method is less robust because it doesn’t fully randomize ties when there are more than two elements with the same priority (for example, if three elements all have the same priority, their relative order is still determined by their original indices).
Without proper tie-breaking, the algorithm would use the sorting algorithm’s default behavior for equal elements, which is typically stable sorting (maintaining original relative order). This would bias the output permutation.
For example, if \(P = [5, 3, 3, 7]\) for array \(A = [a, b, c, d]\), a stable sort would produce \([b, c, a, d]\), always keeping \(b\) before \(c\). With randomized tie-breaking, \([c, b, a, d]\) becomes equally likely, preserving uniformity.