【发布时间】:2010-12-28 05:32:19
【问题描述】:
编辑:由于似乎没有人阅读此链接的原始问题,所以让我在这里介绍一下它的概要。
正如其他人所问的那样,最初的问题是,在给定大量值的情况下,总和将超过 Double 的数据类型所持有的值,如何计算这些值的平均值。
有几个答案说要按组计算,比如取 50 和 50 个数字,然后计算这些组内的平均值,然后最后取所有这些组的平均值,然后将它们组合起来得到最终的平均值。
我的立场是,除非你能保证所有这些值都可以分成多个大小相同的集合,否则你不能使用这种方法。有人敢在这里问这个问题,为了提供答案,所以就在这里。
基本上,给定任意数量的值,其中:
- 我事先知道值的数量(但同样,如果你不知道,你的答案会有什么变化?`)
- 我无法收集所有数字,也无法对它们求和(对于您的编程语言中的普通数据类型而言,总和太大了)
如何计算平均值?
这里的问题的其余部分概述了如何拆分成相同大小的集合的方法以及存在的问题,但我真的很想知道如何做到这一点。
请注意,我对数学非常了解,知道在数学理论方面,计算 A[1..N]/N 的总和会给我一个平均值,让我们假设有原因它不那么简单,我需要拆分工作负载,并且值的数量不一定可以被 3、7、50、1000 或其他任何值整除。
换句话说,我所追求的解决方案必须是通用的。
从这个问题:
我的立场是,将工作负载分成几组是不好的,除非你能确保这些组的大小相等。
编辑:最初的问题是关于特定数据类型可以容纳的上限,因为他总结了很多数字(作为示例给出的计数是 10^9) ,数据类型无法容纳总和。由于这是原始解决方案中的一个问题,我假设(这是我的问题的先决条件,很抱歉错过了这一点)数字太大而无法给出任何有意义的答案。
所以,直接除以值的总数就行了。正常 SUM/COUNT 解决方案失败的最初原因是 SUM 会溢出,但我们假设,对于这个问题,SET-SET/SET-SIZE 会下溢,或者其他什么。
重要的是我不能简单地求和,我不能简单地除以总值。如果我不能做到这一点,我的方法是否有效,我可以做些什么来解决它?
让我概述一下问题。
假设您要计算数字 1 到 6 的平均值,但您不能(无论出于何种原因)通过对数字求和、对数字进行计数、然后将总和除以计数来实现。换句话说,你不能简单地做 (1+2+3+4+5+6)/6。
换句话说,SUM(1..6)/COUNT(1..6) 已经出局了。我们在这里不考虑 NULL(如数据库中的 NULL)。
该问题的几个答案暗示能够将被平均的数字分成若干组,例如 3、50 或 1000 个数字,然后为此计算一些数字,然后最后组合这些值以获得最终平均值。
我的立场是,这在一般情况下是不可能的,因为这会使一些数字,出现在最后一组中的数字,或多或少比前一组中的所有数字更有价值,除非你可以拆分所有数字将数字分成大小相等的集合。
例如,要计算 1-6 的平均值,您可以将其分成 3 个数字的集合,如下所示:
/ 1 2 3 \ / 4 5 6 \
| - + - + - | + | - + - + - |
\ 3 3 3 / \ 3 3 3 / <-- 3 because 3 numbers in the set
---------- -----------
2 2 <-- 2 because 2 equally sized groups
这给了你这个:
2 5
- + - = 3.5
2 2
(注意:(1+2+3+4+5+6)/6 = 3.5,所以这里是正确的)
但是,我的观点是,一旦无法将多个值拆分为多个相同大小的集合,这种方法就会崩溃。例如,包含素数值的序列 1-7 呢?
一种类似的方法,不会一次性对所有值求和,并计算所有值,是否可行?
那么,有这样的方法吗?如何计算满足以下条件的任意数量值的平均值:
- 无论出于何种原因,我都无法采用正常的总和/计数方法
- 我事先知道值的数量(如果我不知道,那会改变答案吗?)
【问题讨论】:
-
@Lasse V. Karlsen:我只是想让你看到下面 (stackoverflow.com/questions/1931359/…) 我解决了一般问题。您可以使用我的方法通过按您喜欢的方式对集合进行分区来计算平均值。特别是,我的方法适用于并行化。
标签: language-agnostic math average