# How Voting Systems Work 4, Exercise 3: how often do Copeland and Minimax disagree? # Random profiles: 5 groups of 2 to 8 voters, 4 candidates, seeded (assumed model). # Count profiles with no Condorcet winner, and among those, how often the two methods # pick different single winners. import itertools import random def pairwise(ballots): names = sorted(ballots[0]) return {(x, y): sum(1 for b in ballots if b.index(x) < b.index(y)) for x in names for y in names if x != y} random.seed(4) perms = list(itertools.permutations(("Ana", "Bo", "Cy", "Di"))) trials = 5000 no_winner = differ = 0 for _ in range(trials): groups = [(random.randint(2, 8), random.choice(perms)) for _ in range(5)] ballots = [r for count, r in groups for _ in range(count)] wins, n = pairwise(ballots), len(ballots) names = sorted(ballots[0]) if any(all(wins[x, y] > n / 2 for y in names if y != x) for x in names): continue no_winner += 1 cope = {x: sum((wins[x, y] > wins[y, x]) - (wins[x, y] < wins[y, x]) for y in names if y != x) for x in names} mini = {x: max([wins[y, x] for y in names if y != x and wins[y, x] > wins[x, y]], default=0) for x in names} c = [x for x in names if cope[x] == max(cope.values())] m = [x for x in names if mini[x] == min(mini.values())] if len(c) == 1 and len(m) == 1 and c != m: differ += 1 print("profiles with no Condorcet winner:", no_winner, "of", trials) print("single winners that differ:", differ) # Output when run: # profiles with no Condorcet winner: 892 of 5000 # single winners that differ: 6