物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Python 与えられた整数を指定された割合に整数で分割する方法

ChatGPTに書かせた

def split_numbers(total, ratios):
    # 各割合に対応する数値を計算
    numbers = [total * ratio for ratio in ratios]

    # 小数点以下を四捨五入
    numbers = [round(number) for number in numbers]

    # 残りの誤差を調整
    total_numbers = sum(numbers)
    diff = total - total_numbers
    if diff != 0:
        # 誤差を絶対値に変換して最大の数値に加減する
        max_number = max(numbers, key=abs)
        index = numbers.index(max_number)
        numbers[index] += diff

    return numbers

# テストデータ
N = 1000
ratio = [0.2783628328539183, 0.4663412379294692, 0.24604468885458453,
         0.009096375234256444, 0.00015337537072308526, 1.4807450137480482e-06,
         9.012034550193011e-09]

# 数値の分割を計算
result = split_numbers(N, ratio)

# 結果の表示
print(result)

出力は

[278, 467, 246, 9, 0, 0, 0]

となる。暗黙としてratioのsumは1である前提である。微妙にうまく行かないケースがありそうだ。誤差調整部分を修正してみた。

def split_numbers(total, ratios):
    numbers = [total * ratio / sum(ratios) for ratio in ratios]

    diffs = [number-round(number) for number in numbers]
    numbers = [round(number) for number in numbers]

    diff = total - sum(numbers)
    
    while diff != 0:
        if diff > 0:
            index = diffs.index(max(diffs))
            numbers[index] += 1
            diffs[index] = 0
        elif diff < 0:
            index = diffs.index(min(diffs))
            numbers[index] -= 1
            diffs[index] = 0
        diff = total - sum(numbers)
    
    return numbers