Tutorial 8: Compensatory systems with re-apportionment¶
In this tutorial we will learn how to re-locate seats obtained in compensatory districts to the original districts.
Norway - Stortinget¶
The country is divided among 19 multi-seat constituencies using the highest averages method with modified Sainte-Laguë divisors (first divisor 1.4).
A compensatory district based on special mixed member system will allocate a maximum of 169 seats:
Each constituency can only be adjusted by 1 extra seat.
A party must reach a 4% of the valid vote and must be present in th 19 constituencies.
Seats won by any excluded party will be subtracted from the levelling seats.
If a party gains more seats than the ones indicated by the mixed member allocation (overhang seats), that party is excluded, and the extra seats will be subtracted from the levelling seats.
The adjustment allocation will be repeated until no party is excluded.
The adjustment will re-use the first vote aggregated by name and alliance.
Once the levelling seats have been computed, the system requires the seats to be re-apportioned to the original constituencies. The seats are reallocated using the original Sainte-Laguë divisor method. Instead of absolute votes, this step uses the party/district votes divided by the district quota.
Define the multi-seat constituencies: the property
max_adjustment_seatsis set to 1 to limit the number of seats the district will be compensated with.1- name: valgdistrikter 2 type: group 3 aggregate: true 4 divisions: 5 - name: : Østfold [1] 6 seats: 8 7 max_adjustment_seats: 1 8 candidates: ... 9 ... 10 - name: Finnmark Finnmárku [20] 11 seats: 4 12 max_adjustment_seats: 1 13 candidates: ...
Add the compensatory district:
1- name: compensatory 2 type: compensatory 3 mode: exclude_overhang_parties 4 exclude: any{ valid_votes < 4% | valgdistrikter.districts < 19 => id } 5 first_vote: id[valgdistrikter:-1] 6 candidates: id[valgdistrikter:-1] 7 seats: 169 8 skip_initial_seats: yes 9 subtract_excluded_candidates: yes
The mode
EXCLUDE_OVERHANG_PARTIESwill exclude partis with overhang seats from the compensatory allocation. This is complemented withsubtract_excluded_candidates, which will subtract the seats obtained by parties excluded by restrictions.Now, the seats computed in the compensatory district need to be assigned to the original constituencies. We will use a node of type
reapportionment:1- name: reapportionment 2 type: reapportionment 3 method: highest_averages 4 method_params: 5 divisor_f: sainte_lague 6 # the score is votes / district quota 7 relative: quota 8 # the quota is relative to valid vote 9 total_votes: valid_votes 10 # look for adjustment seats in the node `compensatory` 11 adjustment: compensatory 12 # look for the original candidates in `valgdistrikter` 13 candidates: valgdistrikter 14 # use this node to compute the score 15 first_vote: valgdistrikter
That’s it, we can compose the full schema:
1name: Stortinget 2021 2type: group 3method: highest_averages 4method_params: 5 divisor_f: sainte_lague_1.4 6divisions: 7 8- name: compensatory 9 type: compensatory 10 mode: exclude_overhang_parties 11 exclude: any{ valid_votes < 4% | valgdistrikter.districts < 19 => id } 12 first_vote: id[valgdistrikter:-1] 13 candidates: id[valgdistrikter:-1] 14 seats: 169 15 skip_initial_seats: yes 16 subtract_excluded_candidates: yes 17 18- name: reapportionment 19 type: reapportionment 20 method: highest_averages 21 method_params: 22 divisor_f: sainte_lague 23 # the score is votes / district quota 24 relative: quota 25 # the quota is relative to valid vote 26 total_votes: valid_votes 27 # look for adjustment seats in the node `compensatory` 28 adjustment: compensatory 29 # look for the original candidates in `valgdistrikter` 30 candidates: valgdistrikter 31 # use this node to compute the score 32 first_vote: valgdistrikter 33 34- name: valgdistrikter 35 type: group 36 aggregate: true 37 divisions: 38 - name: : Østfold [1] 39 seats: 8 40 max_adjustment_seats: 1 41 candidates: ... 42 ... 43 - name: Finnmark Finnmárku [20] 44 seats: 4 45 max_adjustment_seats: 1 46 candidates: ...
Iceland - Alþingi¶
The Icelandic system is similar to the one used in Norway, with some differences:
There are 6 multi-seat constituencies, allocated by d’Hondt divisors method.
There are 9 levelling seats that are allocated resuming the previous allocation.
Any party that reaches the 5% of total vote can partipate in the adjustment process.
The re-apportionment of a seats occurs just after a new levelling seat is allocated.
The re-apportionment score is relative to the district vote.
Define the multi-seat constituencies: the property
max_adjustment_seatsis set to 1 to limit the number of seats the district will be compensated with.1- name: kjördæmi 2 type: group 3 aggregate: yes 4 divisions: 5 6 - name: Norðvesturkjördæmi [Northwest] 7 seats: 7 8 max_adjustment_seats: 1 9 candidates: ... 10 ... 11 - name: Reykjavíkurkjördæmi Norður [Reykjavik North] 12 seats: 9 13 max_adjustment_seats: 2 14 candidates: ...
Add the compensatory district:
1- name: compensatory district 2 type: compensatory 3 mode: additional_member 4 seats: 9 5 skip_initial_seats: yes 6 exclude: votes < 5% 7 first_vote: alliance[kjördæmi:-1] 8 candidates: alliance[kjördæmi]
Add the re-apportionment district:
1- name: adjustment seats to constituencies 2 type: reapportionment 3 # seats are re-located one by one 4 strategy: parallel 5 # score relative to district vote 6 relative: votes 7 adjustment: compensatory district 8 candidates: kjördæmi 9 first_vote: kjördæmi
Now, the full schema:
1name: Alþingi Íslendinga - 2013 2type: group 3method: highest_averages 4method_params: 5 divisor_f: dhondt 6divisions: 7 8- name: compensatory district 9 type: compensatory 10 mode: additional_member 11 seats: 9 12 skip_initial_seats: yes 13 exclude: votes < 5% 14 first_vote: alliance[kjördæmi:-1] 15 candidates: alliance[kjördæmi] 16 17- name: adjustment seats to constituencies 18 type: reapportionment 19 # seats are re-located one by one 20 strategy: parallel 21 # score relative to district vote 22 relative: votes 23 adjustment: compensatory district 24 candidates: kjördæmi 25 first_vote: kjördæmi 26 27- name: kjördæmi 28 type: group 29 aggregate: yes 30 divisions: 31 32 - name: Norðvesturkjördæmi [Northwest] 33 seats: 7 34 max_adjustment_seats: 1 35 candidates: ... 36 ... 37 - name: Reykjavíkurkjördæmi Norður [Reykjavik North] 38 seats: 9 39 max_adjustment_seats: 2 40 candidates: ...
Denmark - Folketing¶
The Danish system uses two levels of districts: provinces and constituencies.
The first step allocates seats at each constituency using the d’Hondt divisors method. No threshold restrictions apply. Independent candidates are allowed.
The levelling seats will compensate for the whole country using the largest remainder method with a Hare quota. In order to participate in the process, a candidate must comply some restrictions:
The party must reach 2% of vote.
If a party has won 1 constituency seat, it will be allowed to participate.
If a party reaches a Hare quota in 2 of the 3 provinces (at least the provincial votes/seats ratio), it will be allowed to participate.
Those levelling seats will be re-apportioned to provinces first, and then from provinces to constituencies.
The re-apportionment from levelling seats to provinces will use the Sainte-Laguë divisors methods, and each province is limited to a maximum of adjustment seats. The score is not relative. There is one step per district:
leveling seats |
provinces |
|---|---|
party 1 |
party 1 @ province 1 |
… |
|
party 1 @ province N |
|
… |
… |
party P |
party P @ province N |
The re-apportionment from provinces to constituencies will use the Danish divisors method. There is one step per candidate.
provinces |
district |
|---|---|
party 1 @ province 1 |
party 1 @ district 1.1 |
… |
|
party 1 @ district 1.D |
|
party 2 @ province 1 |
party 2 @ district 1.1 |
… |
… |
party P @ province N |
party P @ district N.D’ |
Root node: default method is defined here.
1name: Folketing - 2015 2type: group 3method: highest_averages 4method_params: 5 divisor_f: dhondt 6divisions:
Provinces and constituencies. Independent candidates should set
max_seats: 1.1- name: provinces 2 type: group 3 aggregate: yes 4 divisions: 5 6 - name: "Hovedstaden (Capital)" 7 key: Hovedstaden 8 type: group 9 aggregate: yes 10 groupby: id 11 max_adjustment_seats: 11 12 divisions: ... 13 14 - name: "Sjælland-Syddanmark (Zealand and South Denmark)" 15 key: Sjælland-Syddanmark 16 type: group 17 aggregate: yes 18 groupby: id 19 max_adjustment_seats: 15 20 divisions: ... 21 22 - name: "Midtjylland-Nordjylland (Central and North Jutland)" 23 key: Midtjylland-Nordjylland 24 type: group 25 aggregate: yes 26 groupby: id 27 max_adjustment_seats: 14 28 divisions: ...
Each province will generate aggregated results by party ids. A maximum number of adjustment seats is specified.
Compensatory district. 175 seats will be allocated nation-wide to parties using a mixed-member strategy (allocation from scratch where already allocated seats will be subtracted).
1- name: compensatory district 2 type: compensatory 3 mode: mixed_member 4 seats: 175 5 method: largest_remainder 6 method_params: 7 quota_f: hare 8 # threshold 2 9 exclude: votes < 2% 10 # quota 1 11 # hare quorum 2 (TODO) 12 include: provinces.alliance_seats >= 1 => alliance 13 first_vote: alliance[provinces:-1] 14 candidates: alliance[provinces:-1] 15 skip_initial_seats: yes
The second criterion for inclusion can’t be represented as a restriction yet (my apologies), but don’t worry, it has never been used until today (as far as I know).
First re-apportionment: compensatory to provinces.
1- name: global adjustment seats to provinces 2 key: reapp1 3 type: reapportionment 4 strategy: district 5 # score is not relative 6 relative: no 7 method: highest_averages 8 method_params: 9 divisor_f: sainte_lague 10 # levelling seats to parties 11 adjustment: compensatory district 12 # the score will be taken from provinces 13 candidates: provinces 14 # adjustment seats will be projected to provinces 15 first_vote: provinces
Second re-apportionment: provinces to constituencies.
1- name: province adjustment seats to constituencies 2 key: reapp2 3 type: reapportionment 4 strategy: candidate 5 # the score is not relative 6 relative: no 7 method: highest_averages 8 method_params: 9 divisor_f: danish 10 # we take the seats from the first re-apportionment 11 adjustment: reapp1 12 # the score will be taken from constituencies 13 candidates: provinces:-1 14 # seats will be projected to constituencies 15 first_vote: provinces:-1
Final schema:
1name: Folketing - 2015
2type: group
3method: highest_averages
4method_params:
5 divisor_f: dhondt
6divisions:
7
8- name: compensatory district
9 type: compensatory
10 mode: mixed_member
11 seats: 175
12 method: largest_remainder
13 method_params:
14 quota_f: hare
15 # threshold 2
16 exclude: votes < 2%
17 # quota 1
18 # hare quorum 2 (TODO)
19 include: provinces.alliance_seats >= 1 => alliance
20 first_vote: alliance[provinces:-1]
21 candidates: alliance[provinces:-1]
22 skip_initial_seats: yes
23
24- name: global adjustment seats to provinces
25 key: reapp1
26 type: reapportionment
27 strategy: district
28 # score is not relative
29 relative: no
30 method: highest_averages
31 method_params:
32 divisor_f: sainte_lague
33 # levelling seats to parties
34 adjustment: compensatory district
35 # the score will be taken from provinces
36 candidates: provinces
37 # adjustment seats will be projected to provinces
38 first_vote: provinces
39
40- name: province adjustment seats to constituencies
41 key: reapp2
42 type: reapportionment
43 strategy: candidate
44 # the score is not relative
45 relative: no
46 method: highest_averages
47 method_params:
48 divisor_f: danish
49 # we take the seats from the first re-apportionment
50 adjustment: reapp1
51 # the score will be taken from constituencies
52 candidates: provinces:-1
53 # seats will be projected to constituencies
54 first_vote: provinces:-1
55
56- name: provinces
57 type: group
58 aggregate: yes
59 divisions:
60
61 - name: "Hovedstaden (Capital)"
62 key: Hovedstaden
63 type: group
64 aggregate: yes
65 groupby: id
66 max_adjustment_seats: 11
67 divisions: ...
68
69 - name: "Sjælland-Syddanmark (Zealand and South Denmark)"
70 key: Sjælland-Syddanmark
71 type: group
72 aggregate: yes
73 groupby: id
74 max_adjustment_seats: 15
75 divisions: ...
76
77 - name: "Midtjylland-Nordjylland (Central and North Jutland)"
78 key: Midtjylland-Nordjylland
79 type: group
80 aggregate: yes
81 groupby: id
82 max_adjustment_seats: 14
83 divisions: ...