Karol Łacina’s Website

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:

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 (ie. opinions of) the elected winners. I came up with the following satisfaction evaluation methods:

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:

Some observations:

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.