四舍五入浮动,同时保持总和相等

Fra*_* O. 2 python

我有一个总计为整数的浮点数列表。由于种种原因,我必须使用for循环x 进行迭代,x是列表中的每个浮点数,但是由于range()函数的参数必须是整数,因此每个浮点数必须取整。但是,我希望循环的总数保持等于原始浮点数的总和,通常不将其总计为四舍五入的总和。您将如何解决这个问题?谢谢。

小智 7

最近,我不得不解决一个类似的问题,并决定对我的各个项目来说,通用化一个Python解决方案并将其打包就足够了。结帐iteround


Shm*_*afi 5

好吧,这有点数学化:

你有一系列实数 Xi 他们的总和等于 N sum(Xi) = N

让我们将每个实数分解为其下限整数和残差实部(0 到 1 之间): Xi = Ri + fi

现在,您需要一系列与 Xi 非常接近的整数 Yi,但它们都是整数,并且总和为 N。我们可以像这样分解它们:Yi = Ri + Fi(其中 Fi 是 0 或 1 的整数)。

现在我们需要: sum(Yi) = sum(Xi) = N

如果你打破这个规则,你将得到这个方程作为解决方案的要求: sum(Fi) = sum(fi) = N - sum(Ri)

让我们表示:K = N - sum(Ri)

现在解决办法很简单,选择fi值最大的K个元素,将其对应的Fi赋值为1;将另一个 Fi 指定为 0。

现在您有了 Yi 的值,在您的情况下是循环大小

这是它的代码:

def round_series_retain_integer_sum(xs):
    N = sum(xs)
    Rs = [round(x) for x in xs]
    K = N - sum(Rs)
    assert K == round(K)
    fs = [x - round(x) for x in xs]
    indices = [i for order, (e, i) in enumerate(reversed(sorted((e,i) for i,e in enumerate(fs)))) if order < K]
    ys = [R + 1 if i in indices else R for i,R in enumerate(Rs)]
    return ys


xs = [5.2, 3.4, 2.1, 7.3, 3.25, 6.25, 8.2, 9.1, 10.1, 55.1]
ys = round_series_retain_integer_sum(xs)

print xs, sum(xs)
print ys, sum(ys)
Run Code Online (Sandbox Code Playgroud)

我想我没有任何错误,即使有,我也希望你能明白