Skip to content

Batch elimination — what happens when the batch is everyone

Every statement of instant-runoff voting says "eliminate the candidate with the fewest first choices." Almost none of them say what to do when two candidates are tied for fewest. One standard answer — the one the Stanford Encyclopedia uses, and the one pref_voting implements — is to remove all of them in a single step. That reads like a harmless shortcut, and usually it is. But push it and it does something startling: sometimes every remaining candidate is tied for last, the batch takes the whole field, and the count stops with nobody to elect. The convention's answer is that all of them tie for the win — and on a perfectly symmetric profile that is not a cop-out, it is the only answer a fair rule is allowed to give.

Level: 301 · deep dive

Part of the Ties & Tie-Breaking hub · the theorem underneath it: Ties Are Forced · the sibling convention: Parallel Universe Tiebreaking · the methods affected: RCV-IRV (Hare) · Coombs

In the literature this rule is "drop them all" (Taylor & Pacelli, 2006), listed alongside Parallel Universe Tiebreaking in Tie-Breaking: STAR vs RCV-IRV § 5. That page names it in a sentence; this one works it.


The idea in three steps

The whole thing is one clause with two consequences, and it is much easier to follow if the three are separated:

  1. The tie clause. "Eliminate the candidate with the fewest first choices" is undefined when several are tied for fewest. Batch elimination defines it: remove them all, in one step.
  2. The batch can be total. Nothing stops "all candidates tied for fewest" from meaning all candidates. When it does, the elimination step empties the field.
  3. The stopping rule. With nobody left, the count halts and reports every candidate in that final batch as tied for the win.

Step 3 is the one that surprises people, and it is the one with a real argument behind it. It is not "the method broke." On the profiles where it usually fires, a tie is the only result an anonymous and neutral rule can produce.

Step 1 — the tie clause the textbooks skip

Ties Are Forced catalogues four ways to resolve a tie at the end of a count. Parallel Universe Tiebreaking covers the harder one: a tie in the middle, over who to eliminate, where the choice reshapes every round after it. That page lists three answers, and batch elimination is the second:

Answer What it does What it costs
Pick one break the tie by lot, statute, or a seeded RNG, then continue down that single path the result is arbitrary, and the arbitrariness is invisible in the report
Batch-eliminate remove all candidates tied for last in one step can delete a candidate who would have survived — and, as below, can delete everybody
PUT branch on every legal elimination, union the winners the winner set can grow; the search is combinatorial

Batch elimination's appeal is that it needs no lot, no seed, and no statute. It is a rule, not a coin, so it keeps the method anonymous and neutral. That is exactly why the strange behaviour below is the price of something worth having, rather than an oversight.

Step 2 — the smallest election where the batch takes everything

Three voters, three candidates, rotating ballots — the runnable case is batch_all_out_cycle_c3_b3:

Voter Ballot
1 Amy > Bruno > Clara
2 Bruno > Clara > Amy
3 Clara > Amy > Bruno
Abridged for the lesson — not verbatim engine output
First choices:  Amy 1 · Bruno 1 · Clara 1      majority = 2 of 3 → nobody has it
Fewest first choices: Amy, Bruno and Clara      ← all three, tied
Batch-eliminate all of them  →  no candidates remain  →  STOP
Result: Amy, Bruno and Clara TIE for the win

That is the entire mechanism. There is no round two, because there is nothing to transfer to.

And Coombs empties too, by the mirror route. Coombs eliminates the candidate ranked last by the most voters instead of first by the fewest. On these ballots each candidate is last exactly once — Clara on ballot 1, Amy on ballot 2, Bruno on ballot 3 — so Coombs' batch is the whole field as well. Both ends of the ballot give up at the same moment, which is a good sign that what is running out is not the rule but the information.

Step 3 — why "everybody ties" is the correct answer here, not a shrug

Look at the three ballots again and rename the candidates: Amy → Bruno, Bruno → Clara, Clara → Amy. The ballots become Bruno>Clara>Amy, Clara>Amy>Bruno, Amy>Bruno>Clarathe same three ballots, listed in a different order.

That is the whole argument:

  • Anonymity says reordering the ballots cannot change the outcome. So the relabelled election must produce the same result as the original.
  • Neutrality says relabelling the candidates must permute the outcome the same way. So if Amy won the original, Bruno must win the relabelled one.

Both cannot hold with a single winner. The only outcome that satisfies both is the set {Amy, Bruno, Clara} — a genuine three-way tie, forced by symmetry alone. This is Moulin's proposition at its smallest, and this repo already runs the six-voter version of the same profile as reinf_north_c3_b6_rr, where Ranked Robin reaches the same dead end from the pairwise direction and falls to the lot.

So when someone says a total batch is "the only result possible for an anonymous and neutral voting method," on this profile they are right — and it is worth being precise about which profiles that covers.

What it costs — a three-way tie in an election that has a clear winner

Change exactly one ballot. Voter 2 now says Bruno>Amy>Clara instead of Bruno>Clara>Amy — the runnable case is batch_all_out_condorcet_c3_b3:

Voter Ballot
1 Amy > Bruno > Clara
2 Bruno > Amy > Clara
3 Clara > Amy > Bruno

That swap breaks the cycle and hands the election an undisputed Condorcet winner: Amy beats Bruno 2–1 and beats Clara 2–1. She is preferred head-to-head to everybody.

It changes nothing about the instant-runoff count. First choices are still 1–1–1, nobody has a majority, all three are still tied for fewest — so the batch is still total, and batch IRV still reports a three-way tie.

Count Result
Batch instant-runoff {Amy, Bruno, Clara} — total batch, tie
Coombs {Amy} — Clara is last on 2 ballots to Bruno's 1 and Amy's 0, so exactly one candidate is cut and the count proceeds
Ranked Robin / Copeland {Amy}

This is the honest cost, and it is precise. The symmetry defence from step 3 does not apply here, because this profile is not symmetric — a fair rule can absolutely name a winner, and two of them do. Batch elimination declines to, because its tie clause looks only at first-choice counts and this profile is tied there. The convention's problem is not that it produces ties; it is that it produces them in elections that did not need one.

Note which way the Hare/Coombs comparison falls here. Coombs is usually sold as the center-squeeze fix; this is a second, quieter advantage — reading the bottom of the ballot gives the elimination step a different signal to work with, so it runs out of information less often.

It is not a round-one curiosity

The field can empty at any round. batch_all_out_round2_c4_b6 adds a fourth candidate whom every voter ranks dead last:

Abridged for the lesson — not verbatim engine output
Round 1:  Alex 2 · Bella 2 · Colin 2 · Dev 0    Dev is the unique fewest → out alone
                                                 (nobody ranked Dev first → nothing transfers)
Round 2:  Alex 2 · Bella 2 · Colin 2            majority = 4 of 6 → nobody has it
                                                 all three tied for fewest → batch takes the field
Result: Alex, Bella and Colin tie.  Dev does not.

Dev's exclusion is what Pareto buys you. Every voter prefers all three others to Dev, so no rule worth defending can seat him — which is exactly the job Pareto does in Moulin's proposition: anonymity and neutrality force a tie among the symmetric candidates, and Pareto is what keeps a universally-rejected candidate out of it. Without it, "we could not separate the good candidates" would slide into "so let's call it a four-way tie."

What this repo's engine does instead — a ladder, then a coin

Our vendored RCV-IRV engine (pyrankvote) does not batch. It has a tiebreak ladder, and it is a better one than it usually gets credit for — _cmp_candidate_vote_counts in pyrankvote/helpers.py breaks a first-choice tie on most second choices, then third, then fourth, and only falls to random.choice once it runs out of ranks. Structurally that is STAR's ladder: use the ballots while they still say something, and flip a coin only when they have stopped.

So the honest statement is narrower than "the engine flips a coin on ties." It is: the coin is reached only when the candidates are tied at every rank — which is exactly the profile this page is about, and exactly the dead rung by another name.

The control case proves the ladder works. Run all six row-orderings of the Condorcet-winner profile above, where second choices are Amy 2, Bruno 1, Clara 0 — all six elect Amy. The ladder has information, it uses it, and the row order is irrelevant.

Now the perfect cycle, where each candidate holds exactly one first, one second and one third choice, so the ladder is dead on arrival:

--- RCV / Instant-Runoff Voting (single winner) ---
  Batch elimination empties the field — the perfect cycle
 Tabulating 3 ballots (ranked ballots).

ROUND 1
Candidate      Votes  Status
-----------  -------  --------
Amy                1  Hopeful
Bruno              1  Hopeful
Clara              1  Rejected

FINAL RESULT
Candidate      Votes  Status
-----------  -------  --------
Amy                2  Elected
Bruno              1  Rejected
Clara              0  Rejected


Winner(s) — RCV / Instant-Runoff Voting (single winner)
  Amy

Amy, cleanly and reproducibly — and for no reason found on the ballots. Run the identical three ballots in a different row order and the answer changes. All six orderings, same votes, same voters, only the typing order different:

Row order Winner
Amy · Bruno · Clara Amy
Amy · Clara · Bruno Amy
Bruno · Amy · Clara Bruno
Bruno · Clara · Amy Bruno
Clara · Amy · Bruno Clara
Clara · Bruno · Amy Clara

The winner is always the first row's first choice. That is not a neutrality failure — it is an anonymity failure, the more basic of the two: who cast which ballot is supposed to be the one thing a voting rule provably ignores, and here the data-entry order decides the election.

The mechanism, since "it's random" would be the wrong summary. The engine sets random.seed(0) so counts reproduce run to run, and they do. But sorted() feeds the comparator pairs in an order determined by the input list, and that list is built in order of each candidate's first appearance across the ballot rows. A fixed seed therefore pins the sequence of coin flips, not the candidate each flip lands on. Seeding buys reproducibility across runs and buys nothing at all across ballot orderings — and nothing in the report says which of the two you are looking at.

This reframes the comparison the PUT page sets up. Its table warns that batch elimination "can delete a candidate who would have survived" — true, and this page adds the other half: once the ladder is dead, the alternatives are worse. A published lot order spends neutrality in advance and in public, which is defensible. Spending anonymity by accident, on whichever ballot happened to be typed first, is not.

Stated fairly, then: the defect is not the ladder and not the seed. It is that the report draws no distinction between a winner the ballots chose and a winner the file order chose. → engine limitations.

What a certified tabulator does instead

pref_voting says what the method does; our engine says what one teaching implementation does. Neither is what a county runs. So these four cases were also put through RCTab v2.1.0 — the federally-tested, state-certified tabulator that counts real US elections — via rctab_crosscheck.py. Three findings, and the first is the least interesting.

1. It agrees on every winner. Amy, Amy, Alex, Anna — the same four this repo reports. Our arithmetic is the arithmetic jurisdictions run. (What that is not is a verdict on IRV: certifying an implementation says nothing about the method, and every critique on this page survives RCTab counting perfectly.)

2. It is anonymous where we are not. Re-run each case under every ordering of the ballot rows — the sweep that gives our engine three different winners in the table above — and RCTab does not move:

Case Row orderings RCTab This repo's engine
Perfect cycle (3 ballots) 6 Amy 6/6 Amy 2, Bruno 2, Clara 2
Condorcet winner present 6 Amy 6/6 Amy (ladder has information)
Parallel universes (4 ballots) 24 Anna 24/24 Anna

The six-voter round-2 case is absent from that table on purpose: 6 ballots is 720 orderings, which is 720 JVM launches, and the sweep was not run. No anonymity claim is made for it either way.

3. Its arbitrariness is declared instead of accidental. RCTab still has to break the dead tie, and it still decides the election — but the lever is tiebreakMode, and under useCandidateOrder the lever is the candidate order written in the config file. Vary it on the perfect cycle and you get the same three winners our row-order sweep produced:

Declared candidate order Winner
Amy, Bruno, Clara Amy
Amy, Clara, Bruno Clara
Bruno, Amy, Clara Amy
Bruno, Clara, Amy Bruno
Clara, Amy, Bruno Clara
Clara, Bruno, Amy Bruno

And it says so, in the audit log, every time:

Abridged for the lesson — RCTab audit lines, not a full report
INFO: Candidate "Clara" lost a tie-breaker in round 1 against "Amy" and "Bruno".
      Each candidate had 1 vote(s). The selected candidate appeared latest in the
      tie-breaking permutation list.
INFO: Candidate "Amy" was elected in round 2 with 2 votes.

That is the whole comparison in one line: both engines are arbitrary on a dead tie; only one of them tells you. Our winner turns on the order the ballot rows were typed, which nobody thinks of as a rule and no report mentions. RCTab's turns on a value an auditor can read in the config before the count and find named in the log after it. The parallel-universes case makes the point sharpest — this page's criticism is that our report "never mentions" treating a 2–2 final round as a loss for Blake, and RCTab makes the identical call while printing it:

Abridged for the lesson — RCTab audit lines, not a full report
INFO: Candidate "Anna" won a tie-breaker in round 2 against "Blake".
      Each candidate had 2 vote(s). The selected candidate appeared earliest in
      the tie-breaking permutation list.

A note on the round structure. RCTab also prints the rounds the method has, where our engine collapses them: on the six-voter case it eliminates Dev alone in round 1 (0 votes), reaches the genuine three-way tie in round 2, and breaks it — matching pref_voting's account of the profile, where pyrankvote rejects Colin and Dev side by side in a single round. If you are reading these cases to understand the count rather than to test the engine, RCTab's report is the more faithful picture.

Cross-checked against an engine nobody here wrote

Per this library's standing rule, the claims above are confirmed against pref_voting (Holliday & Pacuit), whose instant_runoff and coombs both implement the batch convention:

Profile instant_runoff coombs copeland LH engine
Perfect cycle (3 voters) {Amy, Bruno, Clara} {Amy, Bruno, Clara} {Amy, Bruno, Clara} Amy — row-order dependent
Condorcet winner present (3 voters) {Amy, Bruno, Clara} {Amy} {Amy} Amy
Round-2 batch (6 voters, 4 candidates) {Alex, Bella, Colin} {Alex, Bella, Colin} {Alex, Bella, Colin} Alex
uv run python -c "from pref_voting.profiles import Profile; from pref_voting.iterative_methods import instant_runoff, coombs; p=Profile([[0,1,2],[1,0,2],[2,0,1]]); print(instant_runoff(p), coombs(p))"

The honest limits

  1. This is a small-electorate and simulation concern. A total batch needs every remaining candidate to hold exactly the same first-choice count. Among thousands of ballots that is astronomically rare, and the same caveat the rest of this hub carries applies here undiminished. What it is not is a curiosity you can define away — see the theorem.
  2. It is a convention, not a law. Real statutes overwhelmingly pick one candidate by lot and continue. Batch elimination is the convention of the academic literature and the reference implementations; do not describe it as "how IRV works" without saying which IRV. Which RCV-IRV? catalogues the others.
  3. It fixes none of IRV's real problems. Center squeeze, non-monotonicity and exhausted ballots come from the elimination structure, not from its tie clause. Citing the batch convention as a repair would be exactly the overreach this library warns against.
  4. "Batch elimination" also names a different thing — and the certified tabulator implements that one, not this one. In statute — North Carolina's, for one — it usually means dropping every candidate who is mathematically out of reach at once, purely to speed a hand count. RCTab's batchElimination flag is exactly that rule: Tabulator.runBatchElimination sums tallies low-to-high and cuts only where the sum "fails to equal or exceed the next-lowest candidate vote total," so candidates who are merely tied are never batched — the sum of a tied group always reaches the next tally. Switching the flag on changes nothing in any of the cases on this page, and RCTab structurally cannot empty the field. Two rules, one name, opposite behaviour on a dead tie; see Hare § batch. This page is about the tie clause.

Sources

  • Alan D. Taylor & Allison M. Pacelli, Mathematics and Politics (2nd ed., Springer, 2006) — the named statement of the rule, "drop them all," together with the observation that it only terminates if you declare everyone eliminated in the final round to be co-winners. This library already cited it in Tie-Breaking: STAR vs RCV-IRV § 5; this page is the worked version. Lean: neutral; a textbook.
  • Eric Pacuit, "Voting Methods," Stanford Encyclopedia of Philosophy — states Hare and Coombs with the batch convention, removing all of the poorly-performing candidates in each round. Lean: neutral; the standard reference.
  • Wesley H. Holliday & Eric Pacuit, pref_votinginstant_runoff, coombs and their _put variants; the cross-check engine used above. Lean: neutral; an academic library.
  • Hervé Moulin, The Strategy of Social Choice (North-Holland, 1983) — the forced-tie proposition behind step 3. Via Ties Are Forced.
  • Clyde Coombs, A Theory of Data (1964) — the Coombs rule. Via RCV-IRV (Coombs).