ドント方式投票の計算
選挙も終わり、自民党と民主党が入れ替わってしまいましたが、本当に民意が反映されているかどうかは疑問なのですが、ドント方式 - Wikipedia という議席を分配する方式があるそうです。
いつものように ドント方式投票の計算 - みずぴー日記 にインスパイヤされていますが、なかなか計算をどうやって解くか悩む問題です。 ここでは、配列に格納し、その中の最大値を求めた上で商を求め、その配列の値を書き換えながら議席数に達するまで while 文でループさせていますが、他にも解法があると思います。
#! /usr/local/bin/nawk -f
# dhondt.awk
# ドント方式での議席数を求める
# usage: nawk -f dhondt.awk
BEGIN {
# 日本語版 Wikipedia より
seat = 7;
vote[1] = 340000;
vote[2] = 280000;
vote[3] = 160000;
vote[4] = 60000;
vote[5] = 15000;
# 配列の個数をカウントする
# gawk の場合には length() で計算できる
for (i in vote) {
init_vote[i] = vote[i];
num_party++;
}
# 初期状態を表示
printf("init\t");
for (i = 1; i <= num_party; i++) {
printf("%d\t", vote[i]);
}
print "";
while (sum_seat != seat) {
# 最大値を求める
max = 0;
max_idx = 0;
for (idx in vote) {
if (max < vote[idx]) {
max = vote[idx];
max_idx = idx;
}
}
# 商を計算
vote[max_idx] = init_vote[max_idx] / (++s[max_idx] + 1);
sum_seat++;
# 途中経過を表示
printf("seat %d\t", sum_seat);
for (i = 1; i <= num_party; i++) {
printf("%d\t", vote[i]);
}
print "";
}
# 最終獲得議席数を表示
printf("total %d\t", sum_seat);
for (i = 1; i <= num_party; i++) {
printf("%d\t", s[i]);
}
print "";
}
ここでは途中経過も表示させるようにしています。
$ gawk -f dhondt.awk init 340000 280000 160000 60000 15000 seat 1 170000 280000 160000 60000 15000 seat 2 170000 140000 160000 60000 15000 seat 3 113333 140000 160000 60000 15000 seat 4 113333 140000 80000 60000 15000 seat 5 113333 93333 80000 60000 15000 seat 6 85000 93333 80000 60000 15000 seat 7 85000 70000 80000 60000 15000 total 7 3 3 1 0 0
というわけでドント方式 - Wikipedia は合っているとなったのですが、どうなんでしょうか?
ちなみにD'Hondt method - Wikipedia, the free encyclopedia で書かれてある例題を実行してみると以下のようになります。
init 340000 280000 160000 60000 40000 seat 1 170000 280000 160000 60000 40000 seat 2 170000 140000 160000 60000 40000 seat 3 113333 140000 160000 60000 40000 seat 4 113333 140000 80000 60000 40000 seat 5 113333 93333 80000 60000 40000 seat 6 85000 93333 80000 60000 40000 seat 7 85000 70000 80000 60000 40000 seat 8 68000 70000 80000 60000 40000 seat 9 68000 70000 53333 60000 40000 total 9 4 3 2 0 0




