我想将浮点数数组转换为整数数组。整数应加起来为一个给定的值,并且它们的值应与缩放后的输入数组相似。
换句话说,完美结果由input_float / sum_of_floats * target_sum
计算。示例:给定浮点数0.1, 0.2, 0.5
和目标总和16,则输出应为2, 4, 10
。
可悲的是,实际上这些数字并不是那么好,所以我想将误差与实际值完美的结果相比要最小。
例如,如果目标为17,则应为2, 4, 11
。第一个浮点数转换为0.1 / 0.8 * 17 = 2.125
。第二和第三个分别对应于4.25
和10.6
。显然,10.6应该四舍五入。
但是,仅在0.5边界处取整并不总是足够的。首先,在病理情况下,将输入1, 1
缩放为总和3:其中一个值必须为2,其他值必须为1,因此有两个等效的解决方案。
第二,我们可能需要四舍五入方法:给定0.1, 0.1, 0.3
和目标8,我们得到0.1 / 0.5 * 8 = 1.6 => 2
和0.3 / 0.5 * 8 = 4.8 => 5
,总计为2 + 2 + 5 = 9
而不是8。
对于此示例,什么是好的解决方案?这些是我想到的:
1, 1, 6
1, 2, 5
2, 2, 4
从1.6 - 1
等处,我们看到第一个具有绝对错误0.6, 0.6, 1.2
。我通常想平方和求和,所以我们得到:
1, 1, 6
-> (1.6 - 1)^2 + (1.6 - 1)^2 + (4.8 - 6)^2 = 0.36 + 0.36 + 1.44 = 2.16
1, 2, 5
-> (1.6 - 1)^2 + (1.6 - 2)^2 + (4.8 - 5)^2 = 0.36 + 0.16 + 0.04 = 0.56
2, 2, 4
-> (1.6 - 2)^2 + (1.6 - 2)^2 + (4.8 - 4)^2 = 0.16 + 0.16 + 0.64 = 0.96
因此,应首选1, 2, 5
(或2, 1, 5
)。
我实现了一个近似求解器,该函数考虑剩余的空间(目标总和减去当前总和)来缩放值,大多数情况下都可以。我认为,除了改进它之外,我认为这是现有良好解决方案的普遍问题。但是,我找不到它-您能指出我吗?
我使用类似C / C ++ / C#的语言工作,但这里只关心通用算法。
答案 0 :(得分:1)
考虑下一个简单的方法:
让我们求和S
。
缩放所有值,并为每个缩放的v
制作一对Int(v), Frac(v)
,计算整数部分的总和-例如ISum
,然后以最大的分数递增S-ISum
对的整数部分零件
答案 1 :(得分:1)
您可能很高兴知道自己正处于最佳解决方案的门口。有两个基本步骤:
确定最接近的直接缩放比例解决方案,无论是上方还是下方 所需的目标金额。您的帖子显示您已掌握 这部分。
出于说明的目的,我们假设您仍比目标总和少2(整数差)。现在,您将遍历您的解决方案整数2次(每单位差一个)。您需要找到可以在您的“善意”指标中增加最少的元素添加1
的元素(幸运的是,该元素具有所有正确的数学属性,可将其分离,迭代解决方案)。将1
添加到一个元素,然后向后旋转并再次执行(在某些情况下, 可以是相同的元素,并且值范围很广)。
这会让您找到解决方案吗?
答案 2 :(得分:1)
这是一个在政治上研究得令人惊讶的问题。确切的问题是如何在具有不同价值数的人群之间按比例分配席位。例如,我们遇到了如何在各州和multiple methods have been used之间分配国会席位的问题。
每种方法的权衡略有不同。一些倾向于将更多的整数分配给大桶。一些到更少。在政治背景下,我们通常希望每个人都有代表。
您已选择最小化四舍五入误差的平方和。为此,我认为只需为舍入以下的每个最小整数赋值,然后根据您想要的更多小数的顺序对其进行排序,然后将剩余的舍入分配到顶部。
如果您尝试最小化比率差异的平方和,您将得到一个截然不同的答案。
答案 3 :(得分:1)
在python中:
def convert(weights, target):
ideals = [v/sum(weights) * target for v in weights]
candidates = [int(math.floor(t)) for t in ideals]
while (sum(candidates) < target):
err = [(c-i)*(c-i) for c,i in zip(candidates, ideals)]
candidates[err.index(max(err)]+=1
return candidates