Counting

The comparisons that name the answer

Returning the 4,000 smallest of 65,536 keys in order needs 61,536 comparisons to eliminate the rest and 42,100 to order the ones returned. That was the floor, 103,636, and a tournament made 125,388. What the floor never charged is saying which 4,000 come back. Charge that, and the floor is 125,341. On the same input the tournament is 47 comparisons above it, and for every k up to a hundred it is exactly on it.

Two floors that can be added found a floor under returning the kk smallest of nn keys in order by splitting comparisons according to their loser. At least nkn - k comparisons must have a key that is not returned as their loser, since every such key has to lose once. At least log2k!\lceil \log_2 k! \rceil must have a returned key as their loser, because the returned keys have to be put in order and only comparisons among them can do that. The two sets are disjoint, so the charges add. At n=65,536n = 65{,}536 and k=4,000k = 4{,}000 that floor was 103,636, against a knockout tournament’s 125,388.

It ended by naming what the two charges leave out. An algorithm has to know which kk keys are smallest, not just order some keys and eliminate others. A comparison between a returned key and one that is not returned establishes part of that boundary. Neither charge pays for it.

That boundary has a price, it can be written down, and at the sizes where the exact optimum can be solved it accounts for almost the whole gap.

The third charge

A way of seeing the cost is to hand the answer back one key at a time. Naming the smallest key means choosing it from nn. Naming the second means choosing it from the remaining n1n - 1, and so on down to the (k1)(k-1)-th output, chosen from nk+2n - k + 2. Picking those out in order distinguishes n(n1)(nk+2)=n!/(nk+1)!n(n-1)\cdots(n-k+2) = n!/(n-k+1)! possibilities, so it costs at least log2\log_2 of that many comparisons. What remains is to find the kk-th output. That is the minimum of the nk+1n - k + 1 keys not yet named, and finding a minimum of nk+1n - k + 1 keys takes nkn - k comparisons, each losing a key that is not returned.

Put together:

nk+log2n!(nk+1)!n - k + \left\lceil \log_2 \frac{n!}{(n-k+1)!} \right\rceil

The argument above is a way to see the shape and not a proof, because it assumes the algorithm works in the order the answer is described. A proof has to show that no algorithm can share comparisons between the two parts, and a bound of exactly this form is established for selection problems in the literature, by Fussenegger and Gabow. The measurement below is a check that does not depend on either the sketch or the citation. It solves the problem exactly where it can be solved, and it checks whether the bound is ever violated or loose.

At the two ends the bound is exactly what it should be. At k=1k = 1 the logarithm is of 11 and the floor is n1n - 1, the known cost of a minimum. At k=nk = n it is log2n!\log_2 n!, the sorting floor. In between it is larger than the earlier two-part floor. That floor charged log2k!\log_2 k! for putting the outputs in order, and this one charges log2n!/(nk+1)!\log_2 n!/(n-k+1)! for naming all but one of them in order, which is more whenever kk is less than nn.

Naming the set, less a little

Two floors that can be added asked a specific question about the missing charge: does the boundary cost track log2(nk)\lceil \log_2 \binom{n}{k} \rceil, the bits needed to name the set of returned keys, or something smaller? The new floor answers it by arithmetic.

What the new floor adds to the old one is the difference between naming k1k - 1 outputs in order and ordering kk outputs:

log2n!(nk+1)!log2k!  =  log2(nk)log2nk+1k.\log_2 \frac{n!}{(n-k+1)!} - \log_2 k! \;=\; \log_2 \binom{n}{k} - \log_2 \frac{n-k+1}{k}.

So the boundary costs the bits that name the set, less log2\log_2 of the ratio of keys not returned to keys returned. At n=65,536n = 65{,}536 and k=4,000k = 4{,}000, naming the set is 21,720.6 bits and the naming charge is 21,704.7, sixteen bits less. At k=16,000k = 16{,}000 the two are 52,542.5 and 52,526.9. At six keys and k=2k = 2 they are 3.9 and 1.6. The answer to the earlier question is that the boundary tracks the set’s information content almost exactly, and the few bits by which it falls short are the elimination work that also tells the algorithm something about the boundary. Each of the nkn - k losing comparisons tells an algorithm that its loser is not returned, and that is part of naming the set. The formula credits that overlap once, as a logarithm, and no more.

This is the adversary’s view of the same charge, the one the adversary who hides the edge described for connectivity. An adversary answering an algorithm that wants the kk smallest keeps as many possible sets alive as it can. Each comparison can at most halve them, whatever the comparison is also doing, so an algorithm must ask enough questions to cut (nk)\binom{n}{k} sets down to one. The earlier floor counted comparisons by their losers and never counted sets, which is why it missed this.

Solved exactly up to six keys

The exact optimum for returning the kk smallest in order comes from the same kind of game the floor a merge cannot reach solved for merging. A state of knowledge is the transitive closure of the comparisons made so far, stored as one bitmask per key of the keys known to be smaller. The answer is settled when kk keys form a chain, the jj-th with exactly j1j - 1 keys known below it, and every other key is known to be above the whole chain. There are 4,231 such partial orders on five labelled keys and 130,023 on six, and the solve visits all of them. At four keys and below it agrees with an older solver that works on sets of permutations and shares no representation with it.

Solved exactly up to six elements, the floor that names the outputs is the optimum in 16 of 18 cases, and the best earlier floor in 13For each n from 3 to 6 and each k, the exact fewest comparisons that return the k smallest in order on the worst input, found by solving over every partial order of the elements, beside the floor that names the outputs and the best earlier floor. 3, k = 1: optimum 2, naming 2, earlier 2; 3, k = 2: optimum 3, naming 3, earlier 3; 3, k = 3: optimum 3, naming 3, earlier 3; 4, k = 1: optimum 3, naming 3, earlier 3; 4, k = 2: optimum 4, naming 4, earlier 4; 4, k = 3: optimum 5, naming 5, earlier 5; 4, k = 4: optimum 5, naming 5, earlier 5; 5, k = 1: optimum 4, naming 4, earlier 4; 5, k = 2: optimum 6, naming 6, earlier 5; 5, k = 3: optimum 7, naming 7, earlier 6; 5, k = 4: optimum 7, naming 7, earlier 7; 5, k = 5: optimum 7, naming 7, earlier 7; 6, k = 1: optimum 5, naming 5, earlier 5; 6, k = 2: optimum 7, naming 7, earlier 5; 6, k = 3: optimum 9, naming 8, earlier 7; 6, k = 4: optimum 10, naming 9, earlier 9; 6, k = 5: optimum 10, naming 10, earlier 10; 6, k = 6: optimum 10, naming 10, earlier 10. The naming floor misses the optimum by one at n = 6, k = 3 and n = 6, k = 4.k, the number handed back123456n = 3n = 4n = 5n = 6223333334455554465→676→777775575→797→810910101010naming reaches itstill one shortearlier floor already didlarge: the optimum · small: earlier → naming floor130,023 partial orders at six
Fig. 1 For n from 3 to 6 and every k, the exact fewest comparisons that return the k smallest in order on the worst input, with the best earlier floor and the naming floor beneath. The naming floor equals the optimum in 16 of 18 cases, the earlier floor in 13. It raises five into six at n = 5, k = 2, six into seven at n = 5, k = 3, and five into seven at n = 6, k = 2. It is one short at n = 6, k = 3, where the optimum is 9, and at n = 6, k = 4, where it is 10.

The three cells where the naming floor lifts the earlier one to the optimum are the cells that essay could not explain. At six keys and k=2k = 2 the earlier floor said five and the optimum is seven. The naming floor says seven exactly: four comparisons to eliminate, plus log26=3\lceil \log_2 6 \rceil = 3 to name the smallest. The earlier floor charged log22!=1\lceil \log_2 2! \rceil = 1 for putting two keys in order and nothing for knowing that those two were the right two. Knowing that is worth two further comparisons at six keys, and at 65,536 keys it is worth tens of thousands.

The naming floor is never above the optimum, in any of the eighteen cases. A floor that exceeded the optimum anywhere would be refuted, and none of the eighteen cases does. It is also not always exact. At six keys with k=3k = 3 or 44 the optimum is one higher. So a gap remains, it is at most one comparison at these sizes, and the naming floor does not explain it. The cells it lifts are the ones where the earlier floor was weakest, middle values of kk on the larger sizes.

What the parts are worth at scale

At a few keys the three charges are a few comparisons each. At 65,536 keys they are not, and their proportions change with kk.

The floor under the smallest 4,000 of 65,536, in parts: 61,536 to eliminate, 42,100 to order, and 21,705 more to name themThe 125,341 comparisons the naming floor demands, split into the n − k = 61,536 that must eliminate the elements not returned, the ⌈log₂ k!⌉ = 42,100 the outputs' own order needs, and the 21,705 by which naming the first k − 1 outputs in order, ⌈log₂ n!/(n − k + 1)!⌉ bits, exceeds ordering them. The earlier floor stopped after the first two, at 103,636. A tournament on one shuffled input makes 125,388, 47 above the full floor.stacked, in comparisonseliminate the n − k: 61,536order the k outputs: 42,100name the first k − 1: 21,705tournament 125,388n = 65,536, k = 4,000earlier floor 103,636 · naming floor 125,341
Fig. 2 The naming floor for the 4,000 smallest of 65,536, in parts: 61,536 comparisons to eliminate the keys not returned, 42,100 to put the 4,000 in order, and 21,705 more to name the first 3,999, since naming them in order costs that much beyond ordering them. The earlier floor stopped after the first two parts, at 103,636. The full floor is 125,341, and a tournament on one shuffled input makes 125,388.

At k=4,000k = 4{,}000 the naming charge is 21,705 comparisons, a sixth of the floor and within 47 of the whole gap between the old floor and the tournament. Adding it moves the floor to within 47 comparisons of what the tournament made on this input. Two floors that can be added said that at most seventeen per cent of the tournament’s work at this point could be removed by any method, and quite possibly none of it. The new floor shrinks the first figure to at most 0.04%. That is still a comparison between a worst-case floor and one input’s count, and it is the part of this that needs saying carefully.

The floor under the smallest 16,000 of 65,536, in parts: 49,536 to eliminate, 200,378 to order, and 52,527 more to name themThe 302,441 comparisons the naming floor demands, split into the n − k = 49,536 that must eliminate the elements not returned, the ⌈log₂ k!⌉ = 200,378 the outputs' own order needs, and the 52,527 by which naming the first k − 1 outputs in order, ⌈log₂ n!/(n − k + 1)!⌉ bits, exceeds ordering them. The earlier floor stopped after the first two, at 249,914. A tournament on one shuffled input makes 303,245, 804 above the full floor.stacked, in comparisonseliminate the n − k: 49,536order the k outputs: 200,378name the first k − 1: 52,527tournament 303,245n = 65,536, k = 16,000earlier floor 249,914 · naming floor 302,441
Fig. 3 The same split at k = 16,000 of 65,536: 49,536 to eliminate, 200,378 to order and 52,527 more to name, for a floor of 302,441 against the earlier 249,914. The tournament makes 303,245 on the same input, 804 above.

At k=16,000k = 16{,}000 ordering dominates, since log216,000!\log_2 16{,}000! is two hundred thousand comparisons. The naming charge has grown to 52,527 but is a smaller share, about one sixth again. Elimination has fallen to 49,536 because fewer keys are thrown away. The earlier floor is 17% short of the new one here, as it was at k=4,000k = 4{,}000, and the tournament’s distance to the new floor has grown to 804 comparisons, 0.27%.

Set side by side, the three parts describe how the problem changes as kk grows. At k=10k = 10 the floor is 65,670 comparisons: 65,526 to eliminate, 22 to order ten keys and 122 more to name them. Almost everything is elimination, and the problem is essentially finding a minimum. At k=4,000k = 4{,}000 elimination is 49% of the floor, ordering 34% and naming 17%. At k=16,000k = 16{,}000 ordering has taken over at 66%, elimination is down to 16% and naming stays at 17%. Near k=nk = n the problem is a sort and the floor is the sorting floor.

Naming holds a roughly constant share across the middle of the range, and that is the part that explains the earlier floor’s pattern. That floor was missing a sixth of the true floor across a wide band of kk, and its ratio to the tournament rose with kk and then fell at the ends. The shape came from the share of a charge it was not making, not from any feature of the tournament.

The tournament against the new floor

The whole sweep shows how close the tournament stays and where it starts to pull away.

Naming which elements come back raises the floor at k = 4,000 of 65,536 from 103,636 to 125,341, and the tournament makes 125,388Returning the k smallest of 65,536 in order. The best earlier floor, the largest of the losers, the information count and the losers plus the outputs' own order: 65,535, 65,535, 65,548, 65,656, 65,961, 68,023, 73,066, 103,636, 252,921, 954,037. The floor that also charges naming the outputs, n − k + ⌈log₂ n!/(n − k + 1)!⌉: 65,535, 65,550, 65,670, 66,120, 67,020, 71,519, 80,509, 125,341, 302,441, 954,037. A knockout tournament on one shuffled input: 65,535, 65,550, 65,670, 66,120, 67,020, 71,520, 80,512, 125,388, 303,245, 965,656, at k = 1, 2, 10, 40, 100, 400, 1,000, 4,000, 16,000, 65,536. Both axes are logarithmic.11010010³10⁴10⁵10⁶k, the number handed backcomparisonstournament, measuredfloor that names the outputsbest earlier floorn = 65,536, one shuffled inputthe floors are worst-case, the count is one input
Fig. 4 Returning the k smallest of 65,536 in order, for k from 1 to 65,536. The tournament on one shuffled input makes 65,535, 65,550, 65,670, 66,120, 67,020, 71,520, 80,512, 125,388, 303,245 and 965,656 comparisons. The naming floor is 65,535, 65,550, 65,670, 66,120, 67,020, 71,519, 80,509, 125,341, 302,441 and 954,037. The best earlier floor is lower everywhere except the two ends. Both axes are logarithmic.

For k=1,2,10,40k = 1, 2, 10, 40 and 100100, the tournament’s count on this input equals the naming floor exactly. At k=400k = 400 it is one above, at 1,0001{,}000 three above, at 4,0004{,}000 forty-seven above. The distance only becomes visible past k=16,000k = 16{,}000. At k=nk = n the tournament has become merge sort, as the count of the part that was read found, and its 965,656 comparisons are 1.2% above the sorting floor.

The formula shows why the two agree for small kk. A tournament finds the minimum in n1n - 1 comparisons, which is the elimination charge and the first naming step together. Each later output costs one replay down the tree, about log2n\log_2 n comparisons. The naming charge for the jj-th output is log2(nj+1)\log_2(n - j + 1) bits, which for small jj is only a hair under log2n\log_2 n, so each replay pays almost exactly its naming charge. As jj grows the charge falls further below log2n\log_2 n while the replay does not shrink with it, and the excess accumulates. Which replays contribute each extra comparison is not traced here.

Against the floor that names the outputs, the tournament is exactly on it for small k and 1.0004 at k = 4,000; the heap method sits near 1.9 throughoutComparisons each method makes to return the k smallest of 65,536 in order, divided by the floor n − k + ⌈log₂ n!/(n − k + 1)!⌉, for k from 1 to 65,536. Tournament: 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0004, 1.0027, 1.0122. Heap, then pop k: 1.8849, 1.8849, 1.8851, 1.8859, 1.8873, 1.8940, 1.9054, 1.9361, 1.9665, 1.9864. Select, then sort k: 2.0803, 2.0831, 2.0797, 2.0700, 2.0681, 1.9931, 1.8519, 1.7152, 1.3363, 1.1043. One shuffled input; the two randomised methods are means over eight seeds. Both axes are logarithmic.11010010³10⁴11.52k, the number handed backcomparisons ÷ the naming floortournamentheap, then pop kselect, then sort kn = 65,536, one shuffled input1 is the floor
Fig. 5 Each method’s comparisons divided by the naming floor, for k from 1 to 65,536 on one shuffled input. The tournament is 1.0000 through k = 1,000, 1.0004 at 4,000, 1.0027 at 16,000 and 1.0122 at n. Building a heap and popping k runs from 1.885 to 1.986. Selecting the k-th smallest and then sorting the k runs from 2.08 at small k down to 1.104 at n.

Against the new floor, the other methods’ distances become meaningful too. Building a heap and popping kk times sits near 1.9 at every kk. Heap construction and the first pop cost about 1.88n1.88\,n comparisons where the floor needs n1n - 1, and each further pop costs about 2log2n2 \log_2 n, thirty comparisons, where naming needs about sixteen. Neither ratio depends much on kk, and the plate is flat. Selecting and then sorting is about twice the floor at small kk, because a randomised selection spends roughly two comparisons per key to find the boundary, averaged over the eight seeds. It approaches the floor as kk grows and sorting dominates, reaching 1.10 at k=nk = n, which is the sort’s own distance to log2n!\log_2 n!.

Against the larger of the two original floors the tournament was 1.97 at k=4,000k = 4{,}000, and against their sum it was 1.21. Against a floor that charges for naming the answer, the tournament is essentially optimal at every kk below a quarter of nn, and the heap is almost twice the floor everywhere.

Where the floor leaves room for design

A floor that is nearly met changes what a design question means. For the tournament at small kk nothing is left to improve in the comparison count, so improvements have to come from somewhere else. One run, four counts, four answers is the reminder that comparisons are one count among several. A tournament stores a tree of 2n2n entries and moves keys through it on every replay, while building a heap is done in place. The heap pays roughly twice the floor in comparisons and nothing in extra space, the tournament pays the floor in comparisons and a tree in space, and which one wins depends on how the costs are weighted.

What the floor does rule out is a cleverer comparison strategy for small kk. Before it, the earlier floor left a fifth of the tournament’s work unexplained at k=4,000k = 4{,}000, and a reader could reasonably have looked for a method that saved it. After it, the unexplained part is 47 comparisons in 125,388, and a search for a better method at that size is a search for less than a tenth of a per cent. The floor under every comparison sort did the same service for sorting, closing merge sort’s gap to within a couple of per cent. Closing a gap like this does more for a design question than any single measurement of a method can.

What the floor settles, and what the comparison does not

The floor is a worst-case statement. No algorithm returns the kk smallest in order on every input in fewer comparisons than it states. The tournament’s count is from one shuffled input. So “the tournament equals the floor at k=100k = 100” means that on this input it used exactly the number of comparisons no algorithm can beat on its worst input. It does not say the tournament’s own worst case equals the floor. A tournament’s cost depends on the input only through the replay paths, which are nearly fixed by the tree’s shape. Its worst case is therefore unlikely to be far above this count, but nothing here measures it.

Settled, by exact solve: at every size from three to six keys and every kk, the naming floor is at most the optimum and at least the earlier floor, and it equals the optimum in 16 of 18 cases against the earlier floor’s 13. At four keys and below two independent solvers agree.

Settled, by arithmetic: at 65,536 keys the naming charge adds 21,705 comparisons at k=4,000k = 4{,}000 and 52,527 at k=16,000k = 16{,}000. It adds nothing at k=1k = 1 or k=nk = n.

Not settled:

The two cases at six keys. The optimum exceeds the naming floor by one at k=3k = 3 and k=4k = 4. A fourth charge might explain them, or they might be the kind of gap that the floor a merge cannot reach found for merging, where no single comparison divides the remaining possibilities evenly enough and the ceiling rounds against the algorithm. Seven keys, with 6,129,859 partial orders, is where that would show, and it is beyond what is solved here.

The tournament’s worst case. One input was measured. The claim that no other method can save more than 0.04% at k=4,000k = 4{,}000 holds only for methods measured on inputs no easier than this one.

Still open: the tournament’s own worst case

The tournament’s excess over the naming floor has a candidate source: the tree keeps its original depth while the keys it still holds shrink, so each late replay pays for levels that no longer carry a full bit. If that is the source, the excess should depend on where nkn - k sits relative to powers of two, and a tournament that rebuilt its tree whenever the remaining keys halved should remove most of it, at the cost of the rebuild.

The measurement that follows computes the tournament’s worst case exactly at small nn with the same partial-order solve, restricted to the tournament’s own sequence of questions. At large nn it searches for bad inputs by the hill-climbing the worst case found by climbing used for sorts. Then it builds the rebuilding variant and compares both against the naming floor at every kk. The prediction is that the ordinary tournament’s worst case lies within one comparison per output of the floor, and that the rebuilding variant is exact until kk passes half of nn. If both hold, the gap left by the floor at large kk is a property of one algorithm’s tree, not of the problem.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

The objects this essay names

Each one links to every other essay that touches it.

Adversary argumentComparison countExhaustive searchFalsificationHeapHonest limitInformation floorLower boundOutput-sensitivePartial orderSelectionWorst case