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