Consider the preference schedule below, in which a company’s advertising team is voting on five different advertising slogans, called A, B, C, D, and E here for simplicity.
# Math in Society 2.6 -- Instant Runoff Voting (Plurality with Elimination)
# Each entry is (number of voters, their ranking). EDIT the counts or rankings.
ads = [(3, "BCADE"), (4, "CADBE"), (4, "BDCAE"), (6, "DCAEB"), (2, "BEACD"), (1, "EADBC")]
# Pierce County: 20 and 39 voters ranked ONLY a first choice (truncated ballots),
# so those ballots are exhausted once that candidate is eliminated.
pierce = [(44, "GMB"), (14, "GBM"), (20, "G"), (70, "MGB"), (22, "MBG"), (80, "BMG"), (39, "B")]
def irv(schedule, title):
cands = sorted({c for _, r in schedule for c in r})
plur = {c: 0 for c in cands}
for n, r in schedule:
plur[r[0]] += n
p = max(plur, key=lambda c: (plur[c], c))
print(f"{title}: {sum(n for n, _ in schedule)} ballots")
print(f" plurality would elect {p} with {plur[p]} first-choice votes")
alive, rnd = set(cands), 0
while True:
tally = {c: 0 for c in alive}
for n, r in schedule:
for c in r:
if c in alive:
tally[c] += n
break
cont = sum(tally.values())
need = cont // 2 + 1
label = "initial" if rnd == 0 else f"round {rnd}"
print(f" {label:<8}" + " ".join(f"{c}:{tally[c]:>4}" for c in cands if c in alive)
+ f" majority of {cont} continuing ballots = {need}")
lead = max(tally, key=lambda c: (tally[c], c))
if tally[lead] >= need:
print(f" -> {lead} wins under IRV, {tally[lead]} of {cont}\n")
return
low = min(tally.values())
out = sorted(c for c in alive if tally[c] == low)
if len(out) == len(alive):
print(" -> everyone is tied; IRV cannot resolve this election\n")
return
if len(out) > 1:
print(f" {'':8}({', '.join(out)} tie for fewest --"
f" a real election needs a tiebreak rule)")
print(f" {'':8}fewest first-place votes: {out[0]} with {low} -- eliminated")
alive.discard(out[0])
rnd += 1
irv(ads, "Advertising slogans")
irv(pierce, "Pierce County Executive")
print("Try it: in `ads`, change (4, 'CADBE') to (8, 'CADBE') and re-run.")
print("Four extra C voters change the elimination order and hand the win to C.")
Initial votes
If this was a plurality election, note that B would be the winner with 9 first-choice votes, compared to 6 for D, 4 for C, and 1 for E.
There are total of 3+4+4+6+2+1 = 20 votes. A majority would be 11 votes. No one yet has a majority, so we proceed to elimination rounds.
Show solution
Round 1: We make our first elimination. Choice A has the fewest first-place votes, so we remove that choice
We then shift everyone’s choices up to fill the gaps. There is still no choice with a majority, so we eliminate again.
Round 2: We make our second elimination. Choice E has the fewest first-place votes, so we remove that choice, shifting everyone’s options to fill the gaps.
Notice that the first and fifth columns have the same preferences now, we can condense those down to one column.
Now B has 9 first-choice votes, C has 4 votes, and D has 7 votes. Still no majority, so we eliminate again.
Round 3: We make our third elimination. C has the fewest votes.
Condensing this down:
D has now gained a majority, and is declared the winner under IRV.