Strona główna » Algorytmy » Artykuły » Wybory metodą D'Hondta
 

Wybory metodą D'Hondta

Wstęp

Metoda D'Hondta jest stosowana w celu podziału mandatów wyborczych opartych na proporcjonalnej reprezentacji z listami partyjnymi. Stosowana jest ona podczas wyborów parlamentarnych w Polsce i innych krajach. W tym artykule zostanie opisany algorytm, który przeprowadzi wybory na jej podstawie.

Algorytm

Na wejściu dostajemy ile jest komitetów wyborczych, ile dostały głosów oraz ile mandatów jest do przydzielenia. Zakładamy, że każdy komitet wyborczy osiągnął próg wyborczy. Dla każdego komitetu obliczamy ilorazy Ii, gdzie i-ta wartość to liczba oddanych głosów na komitet K podzielona przez i. Następnie tworzymy pary (Ii, k). Następnie sortujemy pary po ilorazie i wybieramy tyle pierwszych par ile jest mandatów. Potem wystarczy policzyć ile par należy do którego komitetu. W przypadku, gdy dwa komitety mają ten sam iloraz to wpierw należy wybrać komitet, który otrzymał więcej głosów.

Przykład

Przypuścmy, że mamy 3 komitety A, B i C, które otrzymały po 540, 300 i 360 głosów. W tabeli obliczamy kolejne ilorazy. Przykładowo komitet A zdobył 540 głosów, więc I1 = 540, I2 = 270, .., I5 = 108, .. Obliczenia te wykonujemy też dla innych komitetów i najłatwiej je ułożyć w tabelce.

NazwaABC
Głosów540300360
I1540300360
I2270150180
I3180100120
I41357590
I51086072

Mamy do podziału dokładnie 5 mandatów, więc znajdujemy teraz pięć największych ilorazów. Dodatkowo zostały dopisane dwa kolejne wyniki.

IlorazKomitet
540A
360C
300B
270A
180A
Koniecmandatów
180C
150B

W tym przypadku 3 mandaty przypadają komitetowi A i po jednym mandacie komitetowi B i C. Jak można zauważyć iloraz 180 otrzymał komitet A i C, ale A miał więcej głosów, dlatego mandat najpierw otrzymał on.

Implementacja

Algorytm realizujacy metodę D'Hondta przyjmuje trzy argumenty. Są to kolejno: ilość komitetów, list zawierająca głosy oddane na każdy komitet oraz ile mandatów jest do przydzielenia.

  1. static int[] MetodaDHondta(int komitetow, int[] glosy, int mandatow)
  2. {
  3. int[] ile_mandatow = new int[komitetow];
  4. while (mandatow-- > 0)
  5. {
  6. int maks = -1;
  7. int komitet = -1;
  8. for (int i = 0; i < komitetow; i++)
  9. {
  10. int tmp = glosy[i] / (ile_mandatow[i] + 1);
  11. if (tmp > maks || (tmp == maks && glosy[i] > glosy[komitet]))
  12. {
  13. maks = tmp;
  14. komitet = i;
  15. }
  16. }
  17. if (komitet >= 0)
  18. {
  19. ile_mandatow[komitet]++;
  20. }
  21. }
  22. return ile_mandatow;
  23. }

Początkowo przygotowujemy wyzerowaną tablicę, gdzie na i-tej pozycji będzie ilość mandatów i-tego komitetu. Następnie w pętli dla każdego mandatu wyliczamy iloraz dla każdego komitetu. Iloraz jest zależny od aktualnej ilości mandatów przydzielonych komitetowi. Wybór komitetu, któremu dajemy mandat jest aktualizowany jeśli ma wyższy iloraz, albo jeśli iloraz jest równy, ale dostał więcej głosów ogólnie. Na koniec zwracana jest wyliczona tablica.

Testowanie funkcji

Do przetestowania działania algorytmu można skorzystać z poniższej funkcji, która wczyta potrzebne dane, a następnie wypisze wynik.

  1. static void Main(string[] args)
  2. {
  3. int komitetow, mandatow;
  4. Console.Write("Ile jest komitetów?\n n = ");
  5. komitetow = Convert.ToInt32(Console.ReadLine());
  6. Console.WriteLine("Ile głosów dostały kolejne komitety:");
  7. int[] glosy = new int[komitetow];
  8. string[] data = Console.ReadLine().Split(' ');
  9. for (int i = 0; i < komitetow; i++)
  10. {
  11. glosy[i] = Convert.ToInt32(data[i]);
  12. }
  13. Console.Write("Ile jest mandatów?\n m = ");
  14. mandatow = Convert.ToInt32(Console.ReadLine());
  15. int[] ile_mandatow = MetodaDHondta(komitetow, glosy, mandatow);
  16. for (int i = 0; i < komitetow; i++)
  17. {
  18. Console.WriteLine("Komitet {0} {1}", i, ile_mandatow[i]);
  19. }
  20. Console.ReadKey();
  21. }