ドント方式投票の計算

選挙も終わり、自民党と民主党が入れ替わってしまいましたが、本当に民意が反映されているかどうかは疑問なのですが、ドント方式 - 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

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png