Which Voting System Should I Choose?
Suppose you have to run a vote to select the best option(s) from a set of possible choices. It may be a meeting with your coworkers to select the technology you will use for an upcoming project, or you have to run some kind of competition where participants submit their work. The first step is obviously to choose a voting system, but which one should you choose?
The experiment🔗
To test that, I took the empirical approach. That is, I wrote this simple simulation in C++. How does it work? Well it basically tries to simulate a real-life vote. One run of a simulated vote takes in only the number of voters, choices and winners. Then it randomly generates every voter’s opinions of each choice as an integer from -100 to 100 following a uniform distribution. Positive values obviously mean positive opinions and likewise for negative ones.
The next step is to simulate the voters voting. I selected the following most popular and simplest voting systems for my little experiment:
- approval voting - a voter casts a vote for each choice if he has a positive opinion of it.
- score voting - a voter gives every choice a score from 0 to 9 that is a linear function of the voter’s opinion of it.
- first-past-the-post (FPTP) - a voter casts one vote for his one favorite choice.
- ranked voting - similar to score voting but the voter ranks all n choices instead and his first favorite candidate gets n-1 points, the second - n-2 points, … and the last - 0 points. This is called Borda count to be exact.
In each system the choice(s) with the highest sum of votes/points win. I, of course, assume that the voters are sincere. There does exist the whole universe of tactical voting but I decided that it’s out of the scope of this project and it wouldn’t contribute anything useful when examining the real-life use cases I provided.
I also added two more meta voting systems: random and best. As you can probably guess, random just picks a random set of winners and best picks the set with the highest linear voter satisfaction (more on that later). On a side note, you can think of the voting systems as being approximation algorithms for the outcome with the highest satisfaction.
Having chosen the winners in every voting system, we have to somehow evaluate the voters’ satisfaction with (i.e. opinions of) the elected winners. I came up with the following satisfaction evaluation methods:
- linear - a voter’s satisfaction with a winning choice is just his opinion of it.
- square - same as linear but the opinion is squared.
- discrete - either 100 or -100 based on whether the voter’s opinion of a winning choice is positive or not.
- favorites - 100 if the voter’s opinion of a winning choice is at least as good as the worst of his preferred winners and -100 otherwise.
You can also define linear and square satisfactions with a given choice relative to the voter’s favorite choice, that is: opinion of choice - opinion of favorite + 100, but the resulting order of voting systems stays the same. The linear method seemed to me to be the most natural one and the simplest as well, so I made it the main one.
A voter’s satisfaction with all the winners is the weighted average of his satisfactions with the winners where a winner’s weight is the importance of that winner (winner count - winner’s rank + 1). At the end, I sum the voters’ satisfactions and divide that by the number of voters to get the average satisfaction with a winning choice.
So the results for one simulated vote is a table of the calculated average satisfactions for every voting system-satisfaction evaluation method pair. The simulation is run repeatedly a certain number of times (automatically chosen so that all the test cases take approximately the same time) and the average of all votes is taken as the final result for a given test case (the number of voters, choices and winners).
The results🔗
In the end, after running the simulation I got the following results:
voterc: 20 choicec: 10 winnerc: 3 simc: 1666666
best: 15.74 11.86 23.49 -18.61
score: 15.65 11.75 23.59 -18.69
ranked: 15.01 11.32 22.40 -17.59
approval: 13.52 9.06 26.78 -21.94
first-past-the-post: 12.22 9.14 18.24 -12.85
random: 0.00 0.01 -0.01 -39.50
voterc: 20 choicec: 10 winnerc: 1 simc: 5000000
best: 19.94 15.04 29.73 -66.88
score: 19.84 14.91 29.85 -67.11
ranked: 19.03 14.36 28.35 -66.25
approval: 17.12 11.47 33.90 -71.50
first-past-the-post: 11.06 9.46 13.42 -55.38
random: -0.00 -0.00 -0.01 -79.50
voterc: 20 choicec: 2 winnerc: 1 simc: 25000000
best: 7.33 5.52 10.95 15.16
score: 7.29 5.47 11.00 15.08
approval: 6.30 4.22 12.48 13.04
first-past-the-post: 5.93 4.47 8.85 18.11
ranked: 5.93 4.47 8.85 18.11
random: -0.00 0.00 -0.00 0.50
voterc: 1000 choicec: 10 winnerc: 3 simc: 33333
best: 2.22 1.67 3.32 -36.65
score: 2.21 1.66 3.33 -36.66
ranked: 2.09 1.58 3.12 -36.54
approval: 1.92 1.29 3.81 -37.02
first-past-the-post: 1.69 1.26 2.53 -35.80
random: -0.01 -0.00 -0.01 -39.51
voterc: 1000 choicec: 10 winnerc: 1 simc: 100000
best: 2.83 2.13 4.22 -77.90
score: 2.81 2.11 4.24 -77.92
ranked: 2.66 2.01 3.98 -77.84
approval: 2.45 1.64 4.85 -78.38
first-past-the-post: 1.42 1.22 1.72 -76.39
random: -0.00 -0.00 -0.01 -79.50
voterc: 1000 choicec: 2 winnerc: 1 simc: 500000
best: 1.04 0.78 1.55 2.57
score: 1.03 0.78 1.55 2.56
approval: 0.90 0.60 1.78 2.29
first-past-the-post: 0.84 0.64 1.26 3.00
ranked: 0.84 0.64 1.26 3.00
random: 0.00 0.00 -0.00 0.50
A few things to note here:
- The columns are the satisfactions calculated with the methods in the order I gave earlier.
- The program automatically orders the voting systems by their achieved linear satisfaction.
- You will definitely want to compile the code with
-O3
and-march=native
(for GCC) to get the best performance, because it took my computer 11 minutes and a half to run it, even with optimizations on. - The simulation does involve random numbers, so you may get slightly different results when running it yourself.
Some observations:
- The less voters there are, the more they are satisfied as a whole.
- Score voting is only slightly worse than the maximum possible satisfaction.
- The discrete method favors approval voting and score voting, and favorites - FPTP and ranked voting.
- With only two choices, ranked voting and FPTP are identical.
- With more choices, there is no voting system that satisfies everyone in the favorites method.
Conclusions🔗
As I had predicted, first-past-the-post voting (FPTP) is the worst of all and by a considerable margin, yet it is still frequently chosen as the “natural” and “fair” option instead of approval voting (such as in the United States presidential elections), which FPTP is trivial to convert to. The results of this simulation are thus yet another argument against FPTP. My original motivation for writing this article was exactly to warn people of the FPTP trap. Continuing, if you have more resources and are willing to require some more effort from yourself and your voters, then an even better option than approval voting is scored or ranked voting.
I’m by no means a voting system expert, so take what I say here with a pinch of salt. Feel free to build upon my simulation, there are more things that you can tweak that I haven’t already tweaked myself. You can, for example, try playing around with the opinion distribution and see if that changes anything significantly. There are also many other, probably better voting systems that I didn’t consider and which you could try implementing yourself. You may have to parallelize the code though to make it run in a reasonable amount of time while maintaining low dispersion of the results.