[EM] Biproportional representation (was Re: Preferential voting system where a candidate may win multiple seats)

Vidar Wahlberg canidae at exent.net
Mon Jul 29 10:22:54 PDT 2013


On Mon, Jul 29, 2013 at 01:36:49PM +0200, Kristofer Munsterhjelm wrote:
> On 07/28/2013 04:37 PM, Vidar Wahlberg wrote:
>>Upper apportionment:
>>- Party seats are apportioned using unmodified Sainte-Laguë based on
>>   national votes. If desirable the first divisor may be modified, or a
>>   election threshold may be set to prevent fragmentation, but I've not
>>   done this.
> 
> Apportionment according to divisor methods can be done in two ways:
> either explicitly (like Sainte-Laguë) or by a round-and-adjust
> method (like Webster). If I understand you correctly, your
> biproportional program uses the Webster method, i.e. you pick x so
> that
> SUM k=1...n round(support[k] * x)
> equals the desired number of seats.
> 
> I don't know how to turn a given explicit divisor method into a
> given rounding method, so how would you implement modified
> Sainte-Laguë this way?

I may misunderstand you here, but in the upper apportionment I used
unmodified Sainte-Laguë. That is, exactly how it's done in counties
today (excluding leveling seat), just on the national vote count and
with 169 seats.
As of modifying Sainte-Laguë that would only mean modifying the first
divisor, which would have very little impact when 169 seats are to be
apportioned. Although, I did try this and that resulted in "Miljøpartiet
de Grønne" not winning a seat.

Since my last mail I've implemented preferential election (redo upper
apportionment until all parties have at least n seats, each rerun
excluding the party with least votes, transfering them to the next
preference). I chose to use "n seats" instead of "x percent" as I only
entered data for the 10 largest parties and thus would have to hard code
the total amount of votes to get a correct vote percentage, but I
digress.

>>- District seats are determined externally and thus not apportioned in
>>   this implementation.
> 
> A similar trick could be used to implement a threshold if desired.
> It would be complicated, though, something like:
> 
> 1. Do a county-by-county count.
> 2. Parties below the threshold have their number of seats fixed to
> the number of seats they got "directly".
> 3. Fixing these parties' number of seats, determine the number of
> seats for the other parties by national Sainte-Laguë: each party
> gets a seat as in Sainte-Laguë, but when a party below the threshold
> have got all their seats according to 2., remove that party from the
> count.
> 4. Use the result as the target for the number of party seats.
> 
> I'd still rather use an absolute but lower threshold, though; or
> none at all, like you're doing.

Regretably I'm not quite following you here. To try to explain the
method in short:
In upper apportionment you decide how many seats each party gets, this
is the final result and will not be changed (but where they receive the
seats is yet to be decided). Seats in districts/counties are determined
externally. Here is the only place we use Sainte-Laguë. If we want some
sort of threshold or preferential election, it must be done here.
In the lower apportionment each party initially receives "169 *
partyVotesInDistrict / totalVotes" seats (rounded to nearest integer).
After this the amount of seats a party/district should receive is
corrected using party multipliers & district multipliers. There's no
Sainte-Laguë or anything else, only rounding the fraction to the nearest
integer. You'll see the fraction I'm talking about in the table at the
end of this mail.

>>The PDF I used as reference says you should use the maximum multiplier
>>when you're to increase the number of seats, and the minimum multiplier
>>when you're to decrease the number of seats. I'm not entirely sure why
>>this is recommended, if someone have insight on this then please share.
> 
> I would guess this makes the method converge more quickly, but I'm
> not sure. Perhaps try and see if it does?

This is likely. I gave it a shot and it converged on an answer after
just 6 iterations (3 party multipliers, 3 district multipliers).
With the current code this is not as robust as the average when
considering the issues rounding errors give, but as you mention later
rounding errors could be fixed by using rational numbers.
I don't think the D language got rational numbers yet so I'll probably
have to figure out something on my own if I can't find any useful
resources (or switch language, but I've grown fond of the D language for
tasks like this).

> On the other hand, one could argue that one should use the minimal
> multiplier when increasing and the maximal when decreasing. Say
> there's a somewhat sophisticated opponent that objects by saying
> "You got the current outcome by multiplying the votes by certain
> adjustment factors. Well, I can make Rødt get every single seat with
> the right adjustment factors, too, so this is not democratic".
> Against an objection like that, the closer the factors are to 1, the
> better; and so, when increasing the strength of a party (or
> district) to increase the number of seats, one should increase it by
> as little as possible that gets the job done, and similarly when
> decreasing.

Well, no, you can't make Rødt win every single seat in the lower
apportionment, because in the upper apportionment both party seats and
district seats are decided and those decisions are final.
I don't have a heavy math background, but I don't think there are that
many possible solutions when your only tools are to either multiply
seats for party in all districts or seats in district for all parties,
you can't increase/decrease seats for one party in one district without
either modifying seats in all district for that party or modifying seats
for all parties in that district.

> The method itself will partly make votes unequal by weighting them
> to match the district totals you have already specified. However, it
> will not be quite as biased as just preweighting all the vote
> counts, since the party axis is based on the unweighted votes.

This can not be entirely correct. As said, the party seats are decided
counting all votes on a national basis. All votes are weighted equally.
On the other hand, this means that voters in Oslo decide at a greater
degree which parties win a seat in Finnmark than previously, and I
expect this to be the greatest argument against this method.
Consider it like this: If nearly all the voters of Finnmark votes for a
party that only enters the election with a party list in Finnmark, then
that party will not receive all 5 seats (ignoring leveling seat for the
sake of simplicity), because when the votes are counted on a national
level that party is only likely to receive 2 or 3 seats.
On the other hand, it's arguably not democratic that a vote in Finnmark
currently is weighted up about twice as much as a vote in Oslo.

> Floating point problems can also be solved by using a rational
> number type, for instance the one provided by the GNU multiprecision
> library. I think I read about an implementation of the Meek STV
> method doing just that - the Meek method can also run into problems
> with floating point precision in certain cases. Rational number
> types are much slower than floating point, but they are exact.

Yes, this is true. Efficiency doubtfully is a problem, the algorithm is
computationally simple and currently runs in a matter of milliseconds.
A proper implementation should use rational numbers rather than floating
point numbers, but as for "proof of concept" then floating point numbers
are good enough.

> What did the factors end up being for the parties and districts?

The party and district multipliers I did not keep through the
iterations, but the final seat table with 6 decimals looks like this:

                  |    Rodt | Sosiali | Arbeide | Senterp | Kristel | Venstre |   Hoyre | Fremskr | Miljopa | Kystpar | Pensjon |   Total
------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------
         Akershus | 0.198453| 1.002246| 5.163445| 0.421319| 0.580842| 1.176550| 3.727151| 3.940012| 0.425257| 0.007886| 0.357246|  16/ 16 
       Aust-Agder | 0.035762| 0.186704| 1.212141| 0.142898| 0.509983| 0.201805| 0.639375| 1.024406| 0.065365| 0.002023| 0.083515|   4/  4 
         Buskerud | 0.088926| 0.498345| 3.499380| 0.513567| 0.365251| 0.450516| 1.924236| 2.500443| 0.190622| 0.007308| 0.000000|   9/  9 
         Finnmark | 0.066219| 0.503434| 2.458570| 0.206260| 0.183342| 0.194287| 0.609626| 1.274027| 0.079397| 0.144055| 0.000000|   5/  5 
          Hedmark | 0.059762| 0.510621| 3.181269| 0.607742| 0.202983| 0.260362| 0.723103| 1.274146| 0.153255| 0.005437| 0.582132|   8/  8 
        Hordaland | 0.527927| 0.868583| 4.183244| 0.662581| 1.199905| 0.994832| 2.912953| 3.302304| 0.391813| 0.017348| 0.151675|  15/ 15 
  More og Romsdal | 0.060717| 0.373293| 2.608522| 0.637738| 0.878746| 0.510215| 1.441280| 2.453541| 0.084850| 0.013819| 0.000000|   9/  9 
         Nordland | 0.227033| 0.948266| 4.167533| 0.769462| 0.478546| 0.380167| 1.282828| 2.722913| 0.198231| 0.094225| 0.000000|  10/ 10 
   Nord-Trondelag | 0.055805| 0.444813| 2.590527| 0.811581| 0.293834| 0.273995| 0.559619| 1.096828| 0.072657| 0.009651| 0.000000|   6/  6 
          Oppland | 0.068501| 0.456861| 3.522933| 0.834469| 0.287376| 0.359731| 0.903595| 1.421437| 0.182918| 0.004252| 0.271319|   7/  7 
             Oslo | 0.909995| 1.779038| 5.254536| 0.127155| 0.499425| 1.516540| 3.419242| 2.788607| 0.599591| 0.006808| 0.233813|  17/ 17 
         Rogaland | 0.070655| 0.627822| 3.035000| 0.590546| 1.603605| 0.810216| 2.389540| 3.246530| 0.206869| 0.011565| 0.312340|  13/ 13 
 Sogn og Fjordane | 0.076642| 0.368251| 1.623213| 1.209121| 0.455396| 0.286415| 0.698587| 0.914401| 0.071895| 0.011707| 0.000000|   5/  5 
    Sor-Trondelag | 0.195127| 0.927169| 4.167084| 0.646465| 0.473703| 0.576824| 1.485604| 2.102149| 0.368342| 0.016563| 0.281863|  10/ 10 
         Telemark | 0.113980| 0.379380| 2.575117| 0.297440| 0.500245| 0.244340| 0.854719| 1.499267| 0.111040| 0.003974| 0.100150|   6/  6 
            Troms | 0.152230| 0.584919| 2.500971| 0.496448| 0.300842| 0.272937| 0.921738| 1.807998| 0.145519| 0.077928| 0.000000|   7/  7 
       Vest-Agder | 0.040505| 0.263102| 1.529486| 0.180526| 1.097347| 0.282566| 1.066436| 1.667742| 0.142214| 0.004931| 0.171151|   6/  6 
         Vestfold | 0.071936| 0.551658| 2.470866| 0.208507| 0.421903| 0.346524| 1.514678| 2.104030| 0.195504| 0.007915| 0.128241|   7/  7 
          Ostfold | 0.099678| 0.473405| 3.701050| 0.400825| 0.663579| 0.370810| 1.463323| 2.585628| 0.166733| 0.008232| 0.366040|   9/  9 
------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------
            Total |   2/  2 |  11/ 11 |  60/ 60 |  10/ 10 |   9/  9 |   7/  7 |  29/ 29 |  39/ 39 |   1/  1 |   0/  0 |   1/  1 | 169/169 


-- 
Regards,
Vidar Wahlberg



More information about the Election-Methods mailing list