アダムズ方式

都道府県ごとの議員定数を求めるために,「総定数×各都道府県の人口÷総人口」の小数点以下を切り上げて求めるのがアダムズ(Adams)方式である。ただし,この合計が総定数を超える場合は,超えなくなるまで「総人口」を増やす(→ 図解で納得 アダムズ方式って何?Rでの計算法)。

アダムズ方式は,新型コロナワクチンを各都道府県の人口に比例して配分する際にも使えそうである。ドント方式で配分すると,人口の非常に少ない県は割当がゼロになってしまう可能性がある。アダムズ方式ならそのようなことは起こらない。

ワクチン200箱をアダムズ方式で各都道府県に配分してみよう。

import numpy as np

都道府県 = ["北海道", "青森", "岩手", "宮城", "秋田", "山形", "福島",
            "茨城", "栃木", "群馬", "埼玉", "千葉", "東京", "神奈川",
            "新潟", "富山", "石川", "福井", "山梨", "長野", "岐阜",
            "静岡", "愛知", "三重", "滋賀", "京都", "大阪", "兵庫",
            "奈良", "和歌山", "鳥取", "島根", "岡山", "広島", "山口",
            "徳島", "香川", "愛媛", "高知", "福岡", "佐賀", "長崎",
            "熊本", "大分", "宮崎", "鹿児島", "沖縄"]

# 2019-10-01推計人口(単位1000人)
人口 = np.array([5250, 1246, 1227, 2306, 966, 1078, 1846, 2860, 1934,
                 1942, 7350, 6259, 13921, 9198, 2223, 1044, 1138, 768,
                 811, 2049, 1987, 3644, 7552, 1781, 1414, 2583, 8809,
                 5466, 1330, 925, 556, 674, 1890, 2804, 1358, 728, 956,
                 1339, 698, 5104, 815, 1327, 1748, 1135, 1073, 1602, 1453])

x = sum(人口) # 総人口

総数 = 250

while (np.sum(np.ceil(総数 * 人口 / x)) > 総数):
    x += 1

割当 = np.ceil(総数 * 人口 / x).astype(int)

for k, v in zip(都道府県, 割当):
    print(k, v)

上の方法では x += 1 が問題になることがある。人口が非常に多いと非効率になり,逆に非常に少ないと 1 ずつ動かしたのでは通り過ぎてしまうことがある。そこで,ドント方式の別解と同様な別解が便利である:

割当 = np.ones_like(人口)
for _ in range(総数 - len(人口)):
    a = 人口 / 割当
    割当[np.argmax(a)] += 1

上のコードでは,人口ゼロの都道府県はなく,総数は都道府県数以上であり,タイはないと仮定した。タイのチェックはドント方式の別解と同様に行うことができる。

都道府県ごとのアダムズ方式とドント方式の割当を並べて示す。大きいところはドント方式が,小さいところはアダムズ方式が有利なことがわかる。

北海道 10 11
青森 3 2
岩手 3 2
宮城 5 4
秋田 2 2
山形 2 2
福島 4 3
茨城 6 6
栃木 4 4
群馬 4 4
埼玉 14 15
千葉 12 13
東京 25 30
神奈川 17 19
新潟 4 4
富山 2 2
石川 3 2
福井 2 1
山梨 2 1
長野 4 4
岐阜 4 4
静岡 7 7
愛知 14 16
三重 4 3
滋賀 3 3
京都 5 5
大阪 16 19
兵庫 10 11
奈良 3 2
和歌山 2 2
鳥取 1 1
島根 2 1
岡山 4 4
広島 5 6
山口 3 2
徳島 2 1
香川 2 2
愛媛 3 2
高知 2 1
福岡 10 11
佐賀 2 1
長崎 3 2
熊本 4 3
大分 3 2
宮崎 2 2
鹿児島 3 3
沖縄 3 3

Last modified: