16 October 2010

Sainte-Laguë method or "Uddatalsmetoden"

I created a class in Java to calculate allocation of seats in a paralament with Sainte-Laguë method.

import java.util.*;

/**
 * Method for is allocating seats proportionally for representative assemblies with party list
 * voting systems. Or to calculate an even percentage number given some proportional factor
 * 
 *  In Swedish this is called "Uddatalsmetoden"
 * 
 * @author Lennart Schedin
 *
 * @param <T> The type of object base
 */
public class SainteLagueMethod<T> {
  private static class SainteLagueObject<T> {
    private T party;
    private double votes;
    private int mandates;
    SainteLagueObject(T party, double votes) {
      this.party = party;
      this.votes = votes;
      this.mandates = 0;
    }
   
    private double getCompareNumer() {
      return votes / (2 * mandates + 1);
    }
  }
 
  public Map<T, Integer> calculateMandate(Map<T, Integer> partiesVotes, int mandates) {
    List<SainteLagueObject<T>> objectList = new ArrayList<SainteLagueObject<T>>();
    for (T party : partiesVotes.keySet()) {
      Integer votes = partiesVotes.get(party);
      objectList.add(new SainteLagueObject<T>(party, votes));
    }

    return distributeMandates(objectList, mandates);
  }

  private Map<T, Integer> distributeMandates(List<SainteLagueObject<T>> objectList, int mandates) {
    while (mandates > 0) {
      SainteLagueObject<T> winner = findOneWinner(objectList);
      winner.mandates = winner.mandates + 1;
      mandates--;
    }
   
    Map<T, Integer> resultList = new HashMap<T, Integer>();
    for (SainteLagueObject<T> object : objectList) {
      resultList.put(object.party, object.mandates);
    }
   
    return resultList;
  }
 
  private SainteLagueObject<T> findOneWinner(List<SainteLagueObject<T>> objectList) {
    SainteLagueObject<T> winner = null;
    for (SainteLagueObject<T> current : objectList) {
      if (winner == null) {
        winner = current;
      }
      if (current.getCompareNumer() > winner.getCompareNumer()) {
        winner = current;
      }
    }
    return winner;
  }
}

No comments:

Post a Comment