How a group turns individual rankings into one winner — and why every rule can be "unfair"
Each voter has a strict ranking of the candidates. A voting rule takes the whole preference profile and returns one winner. The catch: different reasonable rules pick different winners from the very same ballots.
This lab uses one editable election. Edit the blocs below, pick a preset, then walk the tabs to see how Plurality, Plurality + Runoff, Borda, STV, Condorcet and Kemeny each decide — and where they disagree.
▸ Politics & governance — elections, parliaments and referenda turn millions of individual preferences into one collective decision; participatory budgeting even lets citizens vote directly on how public money is spent.
▸ Distributed systems — to stay consistent when machines crash, a cluster must agree on one coordinator (a "leader"). A node becomes leader only after collecting votes from a majority / quorum; a split vote (tie) stalls progress, so real clusters use odd sizes and randomised election timeouts to break symmetry.
▸ Blockchain consensus — proof-of-stake and Byzantine-fault-tolerant protocols vote (weighted by stake) on the next valid block, reaching agreement even when some participants are faulty or adversarial.
▸ Multi-agent systems & robotics — independent agents or swarm robots vote to commit to a shared plan or target, so the team acts coherently instead of pulling in different directions.
▸ Peer review & hiring committees — reviewers' or interviewers' individual rankings are aggregated into one accept / hire decision — a small-scale election that inherits all the same paradoxes.
Two closely-related rules on the same ballots: plain Plurality, and what changes once you add a runoff. Edit the ballots once below — both visualizations update together.
The simplest rule: count only each voter's 1st choice; most first-place votes wins. It ignores everything below the top — which is why a strong but divisive candidate can win with well under half the vote, and why "spoiler" candidates matter.
Bolt a runoff onto plurality and you get the Two-Round System — exactly how France elects its President (also Brazil and many others). Round 1 is plain plurality; the top two candidates always advance to a Round 2 runoff, where every ballot backs whichever of the two finalists it ranks higher. Coming first in Round 1 does not win the election — even the leader must win the runoff. (A Round-1 absolute majority would win outright, but in France that has never happened.) Unlike IRV it never transfers beyond the top two.
Use the whole ranking. With m candidates, a 1st place is worth m−1 points, 2nd m−2, … last 0. Sum across all voters; highest total wins. Borda rewards broadly-acceptable candidates over narrowly-loved ones.
STV fills several seats proportionally. A candidate is elected on reaching the Droop quota ⌊v/(seats+1)⌋+1. Surplus above quota transfers fractionally to next preferences (Gregory method); if nobody meets quota the lowest is eliminated and their ballots transfer at full value. With one seat, STV is exactly Instant-Runoff.
Run every head-to-head match using the full rankings. A Condorcet winner is a candidate who would beat every other candidate in a one-on-one majority vote. Many people consider this the "rightful" winner — yet famous rules (Plurality, IRV) can fail to elect it, and sometimes it doesn't exist at all.
Majorities can be cyclic. With three voters ranking A>B>C, B>C>A, C>A>B: a majority prefers A over B, another majority B over C, and yet another C over A — a rock-paper-scissors with no Condorcet winner. Group preference can be irrational even when every individual is perfectly rational. The diagram below is this exact example.
A rule is Condorcet-consistent if it always elects the Condorcet winner whenever one exists. Surprisingly few common rules are:
Kemeny's rule finds the full consensus ranking, not just a winner — it is a social welfare function. Let na≻b be the number of voters who prefer a to b. For a candidate ranking σ, every pair where a ≻σ b makes the nb≻a voters who disagree unhappy.
Total unhappiness K(σ) = Σ(a,b) : a ≻σ b nb≻a
Select the ranking σ* with minimum total unhappiness. As a social choice function, the winner is simply the top alternative of σ*. (Minimising disagreement is exactly the dual of maximising the voters' pairwise agreement — both pick the same σ*.) Kemeny is Condorcet-consistent and the maximum-likelihood estimate of a "true" order under noisy voters.
Across every tab you've seen one unsettling fact: the same ballots elect different winners depending on the rule. Kenneth Arrow (1951) proved this is unavoidable — it earned him the Nobel Prize.
With 3 or more candidates, the only ranked voting rule that simultaneously satisfies Unanimity, Independence of Irrelevant Alternatives and Unrestricted domain is a dictatorship. Equivalently — no rule can satisfy all four fairness criteria at once:
Independence of Irrelevant Alternatives demands that society's ranking of two candidates depend only on how voters rank those two — never on some unrelated third option. Both Plurality and Borda break it. Pick an example and step through: a candidate who can't win still flips the result, even though not one voter changed their mind about the candidates that matter.
The trick is to hunt for a hidden dictator. Assume some rule obeys Unanimity and IIA with 3 or more options — four short steps then force it to be a dictatorship.
Step 1 · One option always sits at an extreme. Pick an option B and look only at profiles where every voter puts B either dead-first or dead-last. Then society must put B first or last too. If society instead slipped B into the middle (some A above B, B above some C), you could swap A and C on every ballot — nobody's opinion of B moves, so by IIA society still has A above B and B above C, hence A above C. But you just made everyone prefer C to A, and Unanimity says society must agree. Contradiction — so B stays at an extreme.
Step 2 · One voter is pivotal. Start with B last on every ballot — society ranks B last. Now flip voters to B-first one at a time. Once everyone has flipped, society ranks B first. So a single voter's flip tipped society's B from last to first. Slide through it below — that is the pivotal voter.
Step 3 · The pivot secretly controls every other pair. That same voter n* decides more than just B. Take any two other options A and C. Build one profile: leave B exactly where the march had it, but let the pivot rank A › B › C. Now read those same ballots two ways:
▸ Compare only A vs B: the ballots are identical to the step just before the pivot flipped, where society had B at the bottom — so society puts A above B.
▸ Compare only B vs C: the ballots are identical to the step just after it flipped, where society had B on top — so society puts B above C.
Chain them — A › B › C — so society ranks A above C. But by IIA society's A-vs-C verdict may depend only on how people rank A vs C, and the pivot is the one voter we pinned: everyone else could rank A vs C however they like and the answer wouldn't budge. So the pivot alone decides A vs C — and the same trick works for every pair, fixing society's entire ranking.
Step 4 · That's a dictatorship. With 3+ options, the only rule satisfying Unanimity + IIA is one where a single voter always gets their way. No "fair" rule survives — which is exactly Arrow's theorem. ∎
Gibbard–Satterthwaite adds the strategic twist: every non-trivial rule is also manipulable — some voter can get a better outcome by ranking insincerely. There is no perfect voting system; each rule simply trades off different harms.
Aggregating many independent opinions isn't only how a group elects a leader — it is one of the most reliable tricks in machine learning. Independent models (or agents) each cast a vote; combined, they cancel one another's errors and beat any single member. Below are four places where the exact ideas from this lab — plurality, majority, weighted and "soft" votes — quietly power real AI systems.
Train several different classifiers, then let them vote on each prediction. Hard voting takes the majority predicted label (plurality of the rule book above). Soft voting averages the classifiers' predicted class probabilities and picks the arg-max — so a single very confident model can outweigh two lukewarm ones, much like a weighted Borda score. Soft voting usually wins when the base models are well-calibrated.
📖 Read more: Voting Classifier on GeeksforGeeks ↗
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
clf1 = LogisticRegression()
clf2 = SVC(probability=True) # soft voting needs probabilities
clf3 = DecisionTreeClassifier()
# Hard voting -> majority predicted label
hard = VotingClassifier(
estimators=[('lr', clf1), ('svc', clf2), ('dt', clf3)],
voting='hard')
# Soft voting -> arg-max of the averaged class probabilities
soft = VotingClassifier(
estimators=[('lr', clf1), ('svc', clf2), ('dt', clf3)],
voting='soft', weights=[2, 1, 1]) # optionally weight each model
soft.fit(X_train, y_train)
print(soft.predict(X_test))
print(soft.score(X_test, y_test))In cooperative multi-agent RL, decentralised agents each hold their own policy yet must commit to one joint action — otherwise they pull in different directions. A simple, robust coordinator is a vote: every agent proposes the action its policy prefers, and the team executes the plurality choice. This breaks symmetry (a tie stalls the team — exactly the split-vote problem from the Intro tab), aligns swarm robots on a shared target, and turns many noisy local policies into one stable team move.
import numpy as np
from collections import Counter
# Each cooperative agent proposes one discrete team action.
def agent_action(policy, obs):
return int(np.argmax(policy(obs))) # greedy local proposal
def vote_team_action(agents, obs):
proposals = [agent_action(a.policy, obs) for a in agents]
# Plurality vote -> the action most agents agree on (ties: lowest id)
team = Counter(proposals).most_common(1)[0][0]
return team, proposals
team, proposals = vote_team_action(agents, obs)
print("proposals:", proposals, "-> team:", team)A plain DQN can only explore with crude ε-greedy randomness. Bootstrapped DQN (Osband et al., 2016) instead trains an ensemble of K Q-value "heads" on one shared network torso, each head fit to its own bootstrap sample of the replay buffer — so the heads disagree exactly where data is scarce. Two votes fall out of this. To act, it samples a single head per episode and follows it greedily — coherent, temporally-extended "deep" exploration (posterior sampling). To exploit, the heads take a majority vote over their greedy action. Their disagreement is a free estimate of epistemic uncertainty — pointing the agent at states still worth exploring.
📄 Paper: Deep Exploration via Bootstrapped DQN (Osband et al., 2016) ↗
import numpy as np
# Bootstrapped DQN keeps K Q-heads on a shared torso, each
# trained on its own bootstrap mask of the replay buffer.
K = 10
def act_explore(q_heads, obs):
head = np.random.randint(K) # sample ONE head per episode
return int(np.argmax(q_heads[head](obs))) # follow it -> deep exploration
def act_exploit(q_heads, obs):
votes = [int(np.argmax(h(obs))) for h in q_heads]
return np.bincount(votes).argmax() # ensemble majority vote
def uncertainty(q_heads, obs):
qs = np.stack([h(obs) for h in q_heads])
return qs.std(0).mean() # disagreement = epistemic uncertaintyAsk a language model to reason step-by-step, then sample several independent chains of thought at non-zero temperature. Different chains may slip on different steps, but the correct answer tends to be reached by the most paths. Returning the majority answer across samples — plain plurality voting — gives a large accuracy boost over any single chain.
A random forest trains many decision trees, each on a bootstrap sample of the data and a random subset of features, so the trees make uncorrelated errors. For a prediction every tree votes for a class and the forest returns the majority (regression averages instead). Decorrelated voters are the whole point — it's the variance-reduction argument behind "the wisdom of crowds."
The same rules, everywhere. Hard voting is plurality; soft voting is a weighted score in the spirit of Borda; MARL action-voting and leader election are plurality consensus; self-consistency and random forests are majority rule. Every method you toured in this lab reappears the moment an AI system has to turn many opinions into one decision — and so do its paradoxes.
Edit the ballots freely — type bloc sizes, reorder preferences with ◀ ▶, add or remove blocs — and every voting rule recomputes its winner side by side, live. This is the same shared election that drives all the other tabs (the STV seat count is set on the STV tab).