我需要编写代码,以根据列表中“基本”值的相对权重在整个列表中按比例分配一个值。只需将“基本”值除以“基本”值之和,然后将该因子乘以原始值即可在一定程度上按比例分配作品:

proratedValue = (basis / basisTotal) * prorationAmount;

但是,此计算的结果必须随后四舍五入为整数值。四舍五入的效果意味着列表中所有项目的proratedValue之和可能与原始prorationAmount不同。

谁能解释如何应用“无损”按比例分配算法,该算法尽可能精确地在列表中按比例分配值,而不会出现舍入错误?

最佳答案

简单的算法草图在这里...

  • 的运行总计从零开始。
  • 对第一项执行标准的“将基础除以总量,然后乘以比例数量”。
  • 将运行总计的原始值存储在其他位置,然后将您刚刚在#2中计算出的金额相加。
  • 将运行总计的旧值和新值都舍入为整数(不要修改现有值,将它们舍入为单独的变量),并取其差。
  • 在步骤4中计算的数字是分配给当前基准的值。
  • 为每个基础重复步骤2-5。

  • 这样可以保证按比例分配的总金额等于输入按比例分配的金额,因为您实际上从未修改过运行总额(您只对它的取整后的值用于其他计算,而不会回写)。现在解决了整数舍入之前的问题,因为舍入误差将随着时间的推移累加到运行总计中,并最终将值推向另一个方向越过舍入阈值。

    基本示例:
    Input basis: [0.2, 0.3, 0.3, 0.2]
    Total prorate: 47
    
    ----
    
    R used to indicate running total here:
    
    R = 0
    
    First basis:
      oldR = R [0]
      R += (0.2 / 1.0 * 47) [= 9.4]
      results[0] = int(R) - int(oldR) [= 9]
    
    Second basis:
      oldR = R [9.4]
      R += (0.3 / 1.0 * 47) [+ 14.1, = 23.5 total]
      results[1] = int(R) - int(oldR) [23-9, = 14]
    
    Third basis:
      oldR = R [23.5]
      R += (0.3 / 1.0 * 47) [+ 14.1, = 37.6 total]
      results[1] = int(R) - int(oldR) [38-23, = 15]
    
    Fourth basis:
      oldR = R [37.6]
      R += (0.2 / 1.0 * 47) [+ 9.4, = 47 total]
      results[1] = int(R) - int(oldR) [47-38, = 9]
    
    9+14+15+9 = 47
    

    关于c# - 将值按比例分配(按比例分配)到一组值中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1925691/

    10-13 08:40