summaryrefslogtreecommitdiff
path: root/project/templates/stvcount.html
blob: 02b47ec8bbd644bd3d974c9fdfe230f3e2050de6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

{% extends "base.html" %}



{% block title %}Single Transferable Vote Counter{% endblock %}



{% block style %}
    <link href="/css/stvcount.css" rel="stylesheet">
{% endblock %}



{% block content %}

<h4>Single Transferable Vote Counter</h4>

<p>Git repository: <a href="/cgit/cgit.cgi/stv-count">Link</a></p>

<h5>19/2/2017</h5>

<p>To give an incredibly brief summary of <a href="https://en.wikipedia.org/wiki/Parliament_of_Australia"
target="_blank">Australia's political system</a>, both the Federal Parliament and most of the State
Parliaments are bicameral. The lower houses are generally elected by Instant Runoff, while the upper
houses generally have half elections using Single Transferable Vote. There are exceptions and a whole
lot of differing details, but that's the overall pattern.</p>

<p>In 2016, however, the Federal Parliament underwent a Double Dissolution, causing the entirety of
both houses to go to an election. This had the outcome of 20 out of 76 seats going to third parties
in the upper house, a record number. Even more than the 18 there were prior. As the entire purpose of
a Double Dissolution is to break deadlocks in parliament, to have the outcome go in the
<a href="http://www.abc.net.au/news/2016-07-03/crabb-election-2016-is-lose-lose-for-malcolm-turnbull/7565840"
target="_blank">complete opposite direction</a> probably caused some dismay from Malcolm Turnbull
and his Liberal/National government.</p>

<p>This raises the question: Would they have been better off had a normal election happened instead?</p>

<p>To calculate the likely outcome, the ballot preference data is needed. That's the easy part, as
the Australian Electoral Commission makes that available
<a href="http://results.aec.gov.au/20499/Website/SenateDownloadsMenu-20499-Csv.htm" target="_blank">here</a>
in the 'Formal preferences' section. Then, a program is needed to execute the STV algorithm, which is
as follows:</p>

<ol>
    <li>Set the quota of votes required for a candidate to win.</li>
    <li>Allocate the ballot papers according to first preference to each of the candidates for
        initial vote totals.</li>
    <li>Mark any candidate who has reached or exceeded the quota as elected.</li>
    <li>If any elected candidate has more votes than the quota, transfer the excess to the other
        candidates according to the next applicable preference.</li>
    <li>If no further candidates meet the quota, the candidate with the fewest votes is eliminated
        and their votes are transferred to the others according to next applicable preference.</li>
    <li>Repeat steps 3-5 until all seats are filled.</li>
</ol>

<p>Seems simple enough, right? Except not really. There is a surprising amount of complexity in there, and most
of it is to do with how to transfer votes around. So, in addition, there are the specifics for the version
used for the Australian Senate:</p>

<ul>
    <li>Voters are given the option of voting either "above the line" or "below the line". The latter is
        standard STV. The former used to be a group voting ticket, but for 2016 and later it is treated as
        a shorthand way of voting, as per instructions
        <a href="http://www.aec.gov.au/Voting/How_to_vote/Voting_Senate.htm" target="_blank">here</a>.</li>
    <li>There are <a href="http://www.aec.gov.au/Elections/candidates/files/ballot-paper-formality-guidelines.pdf"
        target="_blank">specific guidelines</a> on what constitutes a correctly filled out ballot. This is
        important for parsing the formal preference data.</li>
    <li>The <a href="https://en.wikipedia.org/wiki/Droop_quota" target="_blank">Droop quota</a> is used.</li>
    <li>All votes are transferred from elected candidates at a fraction of their value, as per the
        <a href="https://en.wikipedia.org/wiki/Counting_single_transferable_votes#Gregory" target="_blank">
        Gregory Method</a>. This can result in fractions with surprisingly large numerators and denominators.
        This also results in occasional discarding of fractional votes during transfers.</li>
    <li>Should the next applicable preference of a ballot be a candidate who has already been elected, that
        preference is ignored and the ballot is transferred to the next preference.</li>
    <li>If the number of remaining candidates is equal to one more than the number of remaining vacancies,
        the candidates with the highest vote totals at that point are considered elected.</li>
</ul>

<p>My implementation also includes <a href="https://en.wikipedia.org/wiki/Counting_single_transferable_votes#Bulk_exclusions"
target="_blank">bulk exclusions</a> using applied breakpoints in order to increase speed slightly and minimise
superfluous logging.</p>

<p>At this point I'm fairly sure my program provides an accurate count. However, my numbers still differ
slightly from the ones provided by the AEC's official distribution of preferences. Investigations into the
exact cause are ongoing.</p>

<h4>Results</h4>

<p>Calculations were done for each state using the formal preference data with vacancies set to 6 instead of 12,
and the results were added to the Senators elected in 2013 to find the probable outcome. The results for
ACT and NT were taken as-is, because the few Senators elected from the territories are not part of the half
election cadence anyway.</p>

<p>Computational resources required varied from approximately 50 seconds using 46MB of memory for Tasmania, to
nearly 30 minutes using 1452MB memory for NSW. The vast majority of that time was spent parsing preference data,
and the program is single threaded, so there is still room for improvement. All counts were run on a Core 2 Quad
Q9500.</p>

<table>
    <caption>Probable non-DD results by state</caption>
    <tr>
        <th colspan="2" style="width:10em;">NSW</th>
        <th colspan="2" style="width:10em;">VIC</th>
        <th colspan="2" style="width:10em;">QLD</th>
        <th colspan="2" style="width:10em;">SA</th>
        <th colspan="2" style="width:10em;">WA</th>
        <th colspan="2" style="width:10em;">TAS</th>
    </tr>
    <tr>
        <td style="background-color:#080CAB; width:8px">&#160;</td><td>Liberal</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#1456F1; width:8px;">&#160;</td><td>Liberal National</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
    </tr>
    <tr>
        <td style="background-color:#F00011; width:8px">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
    </tr>
    <tr>
        <td style="background-color:#080CAB; width:8px">&#160;</td><td>Liberal</td>
        <td style="background-color:green; width:8px;">&#160;</td><td>National</td>
        <td style="background-color:#1456F1; width:8px;">&#160;</td><td>Liberal National</td>
        <td style="background-color:#FF6300; width:8px;">&#160;</td><td>Xenophon</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
    </tr>
    <tr>
        <td style="background-color:#F00011; width:8px">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
    </tr>
    <tr>
        <td style="background-color:green; width:8px">&#160;</td><td>National</td>
        <td style="background-color:#10C25B; width:8px;">&#160;</td><td>Green</td>
        <td style="background-color:#F8F16F; width:8px;">&#160;</td><td>One Nation</td>
        <td style="background-color:#F00011; width:8px;">&#160;</td><td>Labor</td>
        <td style="background-color:#10C25B; width:8px;">&#160;</td><td>Green</td>
        <td style="background-color:#E36137; width:8px;">&#160;</td><td>Jacqui Lambie</td>
    </tr>
    <tr>
        <td style="background-color:#10C25B; width:8px">&#160;</td><td>Green</td>
        <td style="background-color:#002F5D; width:8px;">&#160;</td><td>Derryn Hinch</td>
        <td style="background-color:#1456F1; width:8px;">&#160;</td><td>Liberal National</td>
        <td style="background-color:#FF6300; width:8px;">&#160;</td><td>Xenophon</td>
        <td style="background-color:#080CAB; width:8px;">&#160;</td><td>Liberal</td>
        <td style="background-color:#10C25B; width:8px;">&#160;</td><td>Green</td>
    </tr>
</table>

<table>
    <caption>Probable non-DD Senate composition</caption>
    <tr>
        <th colspan="2" style="width:24em">Party</th>
        <th style="width:9em">Seats Won</th>
        <th style="width:9em">Continuing Senators</th>
        <th style="width:9em">Total Seats</th>
        <th style="width:9em">Difference From Actual</th>
    </tr>
    <tr>
        <td style="background-color:#080CAB; width:8px;">&#160;</td>
        <td class="left">Liberal/National Coalition</td>
        <td>17</td>
        <td>15</td>
        <td>32</td>
        <td>+2</td>
    </tr>
    <tr>
        <td style="background-color:#F00011; width:8px;">&#160;</td>
        <td class="left">Australian Labor Party</td>
        <td>14</td>
        <td>10</td>
        <td>24</td>
        <td>-2</td>
    </tr>
    <tr>
        <td style="background-color:#10C25B; width:8px;">&#160;</td>
        <td class="left">Australian Greens</td>
        <td>4</td>
        <td>4</td>
        <td>8</td>
        <td>-1</td>
    </tr>
    <tr>
        <td style="background-color:#FF6300; width:8px;">&#160;</td>
        <td class="left">Xenophon Group</td>
        <td>2</td>
        <td>1</td>
        <td>3</td>
        <td>Nil</td>
    </tr>
    <tr>
        <td style="background-color:#E36137; width:8px;">&#160;</td>
        <td class="left">Jacqui Lambie Network*</td>
        <td>1</td>
        <td>1</td>
        <td>2</td>
        <td>+1</td>
    </tr>
    <tr>
        <td style="background-color:#F9E518; width:8px;">&#160;</td>
        <td class="left">Liberal Democratic Party</td>
        <td>0</td>
        <td>1</td>
        <td>1</td>
        <td>Nil</td>
    </tr>
    <tr>
        <td style="background-color:#00CCFF; width:8px;">&#160;</td>
        <td class="left">Family First Party</td>
        <td>0</td>
        <td>1</td>
        <td>1</td>
        <td>Nil</td>
    </tr>
    <tr>
        <td style="background-color:#FFED00; width:8px;">&#160;</td>
        <td class="left">Palmer United Party*</td>
        <td>0</td>
        <td>1</td>
        <td>1</td>
        <td>+1</td>
    </tr>
    <tr>
        <td style="background-color:gray; width:8px;">&#160;</td>
        <td class="left">Glenn Lazarus Team*</td>
        <td>0</td>
        <td>1</td>
        <td>1</td>
        <td>+1</td>
    </tr>
    <tr>
        <td style="background-color:#191970; width:8px;">&#160;</td>
        <td class="left">Australian Motoring Enthusiast Party</td>
        <td>0</td>
        <td>1</td>
        <td>1</td>
        <td>+1</td>
    </tr>
    <tr>
        <td style="background-color:#F8F16F; width:8px;">&#160;</td>
        <td class="left">One Nation</td>
        <td>1</td>
        <td>0</td>
        <td>1</td>
        <td>-3</td>
    </tr>
    <tr>
        <td style="background-color:#002F5D; width:8px;">&#160;</td>
        <td class="left">Derryn Hinch's Justice Party</td>
        <td>1</td>
        <td>0</td>
        <td>1</td>
        <td>Nil</td>
    </tr>
</table>

<p>* These three parties were all part of the Palmer United Party at the 2013/2014 election, but split up mid term.</p>

<p>Surprisingly, these projected results <em>still</em> have 20 out of 76 seats held by third party candidates, despite
the half election putting them at a disadvantage. The number of third party groups the Liberal/Nationals have to
negotiate with to pass legislation (assuming Labor and Greens attempt to block) equally remains unchanged.</p> 

<p>The Greens manage to do slightly worse, even though their usual position of winning the 5th or 6th seat in most states
often allows them to obtain more representation than their primary vote would otherwise support. This can't even be
attributed to a bad 2013 result, as their primary vote both then and in 2016 was nearly identical.</p>

<p>One Nation's much reduced number of seats can be attributed to the inherent geographic bias that any system involving
electing candidates across many independent divisions has. If like-minded voters are all in one place, they
receive representation, but when the same number of voters are spread out, they get nothing. When this effect
is intentionally exploited it's called gerrymandering, but here it's merely an artifact of electing Senators from each
state separately. One Nation's support is strongest in Queensland but is relatively diffuse. Any claims of Pauline
Hanson being <a href="http://junkee.com/malcolm-turnbull-will-probably-need-pauline-hansons-support-to-pass-any-laws/82138"
target="_blank">one of the most powerful politicians in Australia</a> are thus overblown.</p>

<p>The Xenophon Group, by contrast, has the vast majority of their support concentrated in South Australia. So the result
for them remains unchanged.</p>

<p>The most noteworthy outcomes for the question though, are that the Liberal/Nationals would have obtained more seats,
and Labor would have been in a more difficult position to block the passage of legislation. Meaning that yes, the
Liberal/National government would definitely have been better off with a normal election.</p>

<p>Nice job screwing over your own party, Malcolm.</p>

{% endblock %}