考虑下面的四个百分比,表示为
数字:
13.626332%
47.989636%
9.596008%
28.788024%
-----------
100.000000%
我需要将这些百分比表示为整数。如果我简单地使用
,我最终得到了101%的结果。
14 + 48 + 10 + 29 = 101
如果我使用
,我最终得到了总共97%的结果。
13 + 47 + 9 + 28 = 97
什么是一个好的算法来表示任何数量的百分比作为整数,同时仍然保持总数为100%?
编辑
:在阅读了一些评论和答案后,显然有很多方法可以解决这个问题。
在我看来,为了保持数字的真实性,“正确”的结果是将总体误差最小化的结果,其定义是相对于实际值的舍入将引入多少误差:
value rounded error decision
----------------------------------------------------
13.626332 14 2.7% round up (14)
47.989636 48 0.0% round up (48)
9.596008 10 4.0% don't round up (9)
28.788024 29 2.7% round up (29)
在平局(3.33,3.33,3.33)的情况下,可以做出任意决定(例如3,4,3)。
发布于 2012-11-21 11:27:56
由于这里的答案似乎都不能很好地解决这个问题,下面是我的半模糊版本,使用
得分点
function foo(l, target) {
var off = target - _.reduce(l, function(acc, x) { return acc + Math.round(x) }, 0);
return _.chain(l).
sortBy(function(x) { return Math.round(x) - x }).
map(function(x, i) { return Math.round(x) + (off > i) - (i >= (l.length + off)) }).
value();
}
foo([13.626332, 47.989636, 9.596008, 28.788024], 100) // => [48, 29, 14, 9]
foo([16.666, 16.666, 16.666, 16.666, 16.666, 16.666], 100) // => [17, 17, 17, 17, 16, 16]
foo([33.333, 33.333, 33.333], 100) // => [34, 33, 33]
foo([33.3, 33.3, 33.3, 0.1], 100) // => [34, 33, 33, 0]
发布于 2012-11-21 07:02:02
有许多方法可以做到这一点,只要您不关心对原始小数数据的依赖。
第一个也可能是最流行的方法是
最大余数法
这基本上是:
四舍五入
求和与100的差值
通过按项目小数部分的降序将1添加到项目来分配差值
在你的例子中,它是这样的:
13.626332%
47.989636%
9.596008%
28.788024%
如果你取整数部分,你会得到
13
47
9
28
加起来是97,你还想再加3个。现在,您看一下小数部分,它们是
.626332%
.989636%
.596008%
.788024%
取最大的,直到总数达到100。所以你会得到:
14
48
9
29
或者,您可以简单地选择显示一个小数位而不是整数值。因此,数字将是48.3和23.9,等等。这将使100的方差减少很多。
发布于 2012-11-21 06:43:55
也许做到这一点的“最好”方法(引用“最佳”是一个主观术语)是保持你所在位置的连续(非整数)计数,并进行四舍五入。
那个
价值。
然后将其与历史一起使用,以确定应该使用什么值。例如,使用您给出的值:
Value CumulValue CumulRounded PrevBaseline Need
--------- ---------- ------------ ------------ ----
0
13.626332 13.626332 14 0 14 ( 14 - 0)
47.989636 61.615968 62 14 48 ( 62 - 14)
9.596008 71.211976 71 62 9 ( 71 - 62)
28.788024 100.000000 100 71 29 (100 - 71)
---
100
在每个阶段,您不会对数字本身进行舍入。取而代之的是,您可以对
累积
值并计算出从前一个基线达到该值的最佳整数-该基线是前一行的累积值(四舍五入)。
这行得通,因为你是
注释
在每个阶段都会丢失信息,而是更智能地使用信息。“正确的”四舍五入的值在最后一列,您可以看到它们的总和为100。
在上面的第三个值中,您可以看到这与盲目舍入每个值之间的区别。而
通常会四舍五入为
,累积的
正确地向下舍入为
-这意味着只有
需要添加到以前的基线
..。
这也适用于“有问题的”序列,如三个粗略的-
值,其中
一个
其中有几个应该四舍五入:
Value CumulValue CumulRounded PrevBaseline Need
--------- ---------- ------------ ------------ ----
0
33.333333 33.333333 33 0 33 ( 33 - 0)
33.333333 66.666666 67 33 34 ( 67 - 33)
33.333333 99.999999 100 67 33 (100 - 67)
---
100
https://stackoverflow.com/questions/13483430
复制相似问题