计算大数的加权平均值
我想要得到几个数字的加权平均值。基本上我有:
Price - 134.42
Quantity - 15236545
可以有少至一个或两个或多达五十或六十对价格和数量。我需要弄清楚价格的加权平均值。基本上,加权平均值应该给对象提供非常小的权重
Price - 100000000.00
Quantity - 3
以及更多对上面的那对。
我现在的公式是:
((price)(quantity) + (price)(quantity) + ...)/totalQuantity
到目前为止,我做到了这一点:
double optimalPrice = 0;
int totalQuantity = 0;
double rolling = 0;
System.out.println(rolling);
Iterator it = orders.entrySet().iterator();
while(it.hasNext()) {
System.out.println("inside");
Map.Entry order = (Map.Entry)it.next();
double price = (Double)order.getKey();
int quantity = (Integer)order.getValue();
System.out.println(price + " " + quantity);
rolling += price * quantity;
totalQuantity += quantity;
System.out.println(rolling);
}
System.out.println(rolling);
return rolling/totalQuantity;
问题是我很快就将“滚动”变量最大化了。
我怎样才能真正得到加权平均值?
没有找到相关结果
已邀请:
7 个回复
物崎巩
碧肮械淌设
和
使用
,并且只在末尾划分它们。这具有更好的数值稳定性,因为最后只有一个浮点除法,其他所有都是整数运算。
基本上是无界限的,所以你不应该遇到任何溢出。 编辑:对不起,只有在重新阅读时我才注意到你的价格是
。也许值得通过将它乘以100然后转换为ѭ7来规避这一点 - 因为我在你的例子中看到它在小数点右边正好有两位数 - 然后在结尾处除以100,尽管这有点像黑客攻击。
呕蹿尉
表示
,使用
表示
。划分后(注意,你将它向后移动;它应该是滚动/ totalQuantity),你可以返回一个BigDecimal,或者在精度不足的情况下使用
。
你换
和总重量
。知道两者然后给你平均值
。问题是
和
是大量的溢出,即使你只是想要适度大小的
。 例如,下一步增加了
的重量和
的值。你想通过仅使用
的值找到新的和ѭ23,只有当
和
以某种方式“湮灭”时才会出现在相同分数的分子和分母中。这是不可能的,正如我将展示的那样。 此迭代中需要添加的值自然是
这不能简化到
和
消失的程度。你也可以找到
你为了得到下一个平均值而乘以q的因素;但是,
和
仍然存在。所以没有聪明的解决方案。 其他人提到了任意精度变量,这是一个很好的解决方案。
和
的大小随着条目的数量线性增长,整数/浮点数的内存使用和计算速度随着值的大小呈对数增长。所以性能是O(log(n)),不像灾难,如果
不知何故是多个数字的倍数。
素汞读
变量。正如@Ash指出的那样,它可以代表高达约37ѭ的值。我能想到的唯一可能性就是你的输入中有一些不好的值。 (也许真正的问题是你正在失去精确度......) 其次,你使用
来表示订单是奇怪的,可能会被打破。您目前使用它的方式,您不能代表涉及两个或更多具有相同价格的物品的订单。
喷乡顾沥沪
,
将满足。 溢出问题可以通过存储“运行平均值”并用每个新条目更新它来解决。即,让 a_n =(sum_ {i = 1} ^ n x_i * w_i)/(sum_ {i = 1} ^ n w_i) 对于n = 1,...,N。您从a_n = x_n开始然后添加 d_n:= a_ {n + 1} - a_n 它。 d_n的公式是 d_n =(x_ {n + 1} - w_ {n + 1} * a_n)/ W_ {n + 1} 其中W_n:= sum_ {i = 1} ^ n w_n。你需要跟踪W_n,但是这个问题可以通过将它存储为
来解决(它可以,因为我们只对平均值感兴趣)。您也可以标准化权重,如果您知道所有权重都是1000的倍数,则将它们除以1000。 为了获得更高的准确性,您可以使用补偿求和。 抢先说明:这里使用浮点运算是可以的。
的相对精度为2E-16。 OP平均为正数,因此不会出现取消错误。任意精度算术的支持者都没有告诉你的是,除了舍入规则之外,在它给你提供比IEEE754浮点运算更多精度的情况下,这将带来显着的内存和性能成本。浮点运算是由非常聪明的人(Kahan教授等人)设计的,如果有一种方法可以比浮点数提供更低的算术精度,他们就会这样做。 免责声明:如果你的权重是完全疯狂的(一个是1,另一个是10000000),那么我不是百分百肯定你是否会得到令人满意的准确性,但你可以在一些例子中测试它,当你知道答案应该是什么时。
犀耽澄协吻