【发布时间】:2009-04-27 06:53:15
【问题描述】:
假设我有一个浮点数数组,按排序(假设升序)顺序,其总和已知为整数N。我想将这些数字“四舍五入”为整数,同时保持它们的总和不变。换句话说,我正在寻找一种将浮点数数组(称为fn)转换为整数数组(称为in)的算法,这样:
- 两个数组的长度相同
- 整数数组的总和是
N - 每个浮点数
fn[i]与其对应的整数in[i]之间的差小于 1(如果必须,则等于 1) - 鉴于浮点数按排序顺序 (
fn[i] <= fn[i+1]),整数也将按排序顺序 (in[i] <= in[i+1])
鉴于这四个条件都满足,最小化舍入方差的算法 (sum((in[i] - fn[i])^2)) 是可取的,但这不是什么大问题。
例子:
[0.02, 0.03, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14] => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] [0.1, 0.3, 0.4, 0.4, 0.8] => [0, 0, 0, 1, 1] [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] => [0, 0, 0, 0, 0, 0, 0, 0, 0, 1] [0.4, 0.4, 0.4, 0.4, 9.2, 9.2] => [0, 0, 1, 1, 9, 9] 更可取 => [0, 0, 0, 0, 10, 10] 是可以接受的 [0.5, 0.5, 11] => [0, 1, 11] 很好 => [0, 0, 12] 在技术上是不允许的,但我会在紧要关头接受它回答 cmets 中提出的一些优秀问题:
- 两个数组都允许重复元素(尽管我也有兴趣了解仅在浮点数组不包含重复时才有效的算法)
- 没有单一的正确答案 - 对于给定的浮点输入数组,通常有多个整数数组满足这四个条件。
- 我想到的应用程序是 - 这有点奇怪 - 在 MarioKart 游戏中将积分分配给排名靠前的玩家 ;-) 我自己从未真正玩过这款游戏,但在观看其他人时我注意到有 24积分分布在前 4 名选手中,我想知道如何根据完成时间分配积分(因此,如果某人以较大的领先优势完成比赛,他们将获得更大的积分份额)。游戏将总点数作为整数进行跟踪,因此需要进行这种四舍五入。
为了好奇,这里是 the test script 我用来识别哪些算法有效。
【问题讨论】:
-
您想将小数部分从浮点数数组中分离出来?
-
如果你有一个包含 1000 个 .001 的数组会发生什么?你希望它如何表现?是否允许重复?
-
@ojblass:在这种情况下,您会将其中的 999 个向下舍入为 0,然后将最后一个向上舍入为 1。这将满足要求。
-
我在应用程序(估算软件)中看到了这一点,其中所有内容都四舍五入到美元并且底线数字必须匹配。
-
还有另一个相关问题:stackoverflow.com/questions/13483430/…
标签: algorithm language-agnostic rounding