# How Voting Systems Work 2, Exercise 2: how often does a loser change the result? # One-dimensional race (assumed model): voters and candidates sit at random # points on a line from 0 to 1, and each voter ranks candidates by distance. # Count how often removing a losing candidate changes the plurality winner. import random from collections import Counter def plurality_winner(positions, voters): counts = Counter(min(positions, key=lambda c: abs(positions[c] - v)) for v in voters) top = max(counts.values()) return sorted(c for c, n in counts.items() if n == top) random.seed(31) trials = 3000 for k in (3, 4, 5): changed = 0 for _ in range(trials): voters = [random.random() for _ in range(101)] positions = {f"C{i}": random.random() for i in range(k)} base = plurality_winner(positions, voters) loser = next(c for c in sorted(positions) if c not in base) smaller = {c: p for c, p in positions.items() if c != loser} if plurality_winner(smaller, voters) != base: changed += 1 print(f"{k} candidates: withdrawing one loser changed the winner in {changed / trials:.1%} of {trials} races") # Output when run: # 3 candidates: withdrawing one loser changed the winner in 24.1% of 3000 races # 4 candidates: withdrawing one loser changed the winner in 23.3% of 3000 races # 5 candidates: withdrawing one loser changed the winner in 23.5% of 3000 races