假设我有一个浮点数数组,该数组以已排序(假设升序)的顺序排列,其和已知为整数N。我想将这些数字“舍入”为整数,同时保持它们的总和不变。换句话说,我正在寻找一种将浮点数数组(称为 fn)转换为整数数组(称为in)的算法,使得:
N
fn
in
fn[i]
in[i]
fn[i] <= fn[i+1]
in[i] <= in[i+1]
在满足这四个条件的情况下,最好使用一种使舍入方差(sum((in[i] - fn[i])^2))最小的算法,但这并不是什么大问题。
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]在技术上是不允许的,但我会紧紧抓住它
要回答评论中提出的一些优秀问题:
出于好奇,这里是我用来确定哪些算法起作用的测试脚本。
这是应该完成任务的一种算法。与其他算法的主要区别在于,此算法始终按正确的顺序舍入数字。 最小化舍入误差。
该语言是一些伪语言,可能源自JavaScript或Lua。应该说明一下。注意一个基于索引的索引(对于循环,x到y更好。
// Temp array with same length as fn. tempArr = Array(fn.length) // Calculate the expected sum. arraySum = sum(fn) lowerSum = 0 -- Populate temp array. for i = 1 to fn.lengthf tempArr[i] = { result: floor(fn[i]), // Lower bound difference: fn[i] - floor(fn[i]), // Roundoff error index: i } // Original index // Calculate the lower sum lowerSum = lowerSum + tempArr[i].result end for // Sort the temp array on the roundoff error sort(tempArr, "difference") // Now arraySum - lowerSum gives us the difference between sums of these // arrays. tempArr is ordered in such a way that the numbers closest to the // next one are at the top. difference = arraySum - lowerSum // Add 1 to those most likely to round up to the next number so that // the difference is nullified. for i = (tempArr.length - difference + 1) to tempArr.length tempArr.result = tempArr.result + 1 end for // Optionally sort the array based on the original index. array(sort, "index")