有没有办法从阵列平均值计算数组元素的平均距离,只需“访问”每个数组元素一次? (我搜索算法)
示例:
Array : [ 1 , 5 , 4 , 9 , 6 ]
Average : ( 1 + 5 + 4 + 9 + 6 ) / 5 = 5
Distance Array : [|1-5|, |5-5|, |4-5|, |9-5|, |6-5|] = [4 , 0 , 1 , 4 , 1 ]
Average Distance : ( 4 + 0 + 1 + 4 + 1 ) / 5 = 2
简单算法需要2次传递。
第1遍)读取并累加值,然后将结果除以数组长度,以计算数组元素的平均值。
第二遍)读取值,累计每个与先前计算的平均值的距离,然后将结果除以数组长度,以找到元素与数组平均值的平均距离。
这两个传球完全相同。它是计算一组值的平均值的经典算法。第一个是数组元素的输入,第二个是元素与数组平均值的距离。
计算平均值可以修改为不累积值,但是当我们顺序读取数组中的元素时,会“动态”计算平均值。
公式为:
Compute Running Average of Array's elements
-------------------------------------------
RA[i] = E[i] {for i == 1}
RA[i] = RA[i-1] - RA[i-1]/i + A[i]/i { for i > 1 }
其中A [x]是位置x处的数组元素,RA [x]是位置1和x(运行平均值)之间数组元素的平均值。
我的问题是:
是否有类似的算法,用于计算“在运行中”(当我们读取数组的元素时),元素与数组平均值的平均距离?
问题是,当我们读取数组的元素时,数组的最终平均值是未知的。只知道运行平均值。因此,计算与运行平均值的差异将不会产生正确的结果。我想,如果存在这样的算法,它可能应该具有“能力”来补偿每个新元素读取的误差。
答案 0 :(得分:2)
我认为你不能比O(n log n)做得更好。
假设数组已排序。然后我们可以将它分成小于平均值的元素和大于平均值的元素。 (如果某些元素等于平均值,则无关紧要。)假设前k个元素小于平均值。那么平均距离是
D =((x ave -x 1 )+(x ave -x 2 )+ (x ave -x 3 )+ ... +(x ave -x k )+(x k + 1 -x ave )+(x k + 2 -x ave )+ ... + (X <子>名词子> -x <子> AVE 子>))/ N
=( - x 1 )+( - x 2 )+( - x 3 )+ ... +(-x k )+(x k + 1 )+(x k + 2 )+ ... +(x n )+(n-2k)x ave )/ n
=([元素之和高于平均值] - [元素之和低于平均值] +(n-2k)x ave )/ n
您可以通过从两端开始工作来一次性计算这一点,并调整(当前未知的)平均值的限制。 这将是O(n),并且排序是O(n logn)(它们也许可以在相同的操作中完成),所以整个事情是O(n logn)。
答案 1 :(得分:1)
双通道方法的唯一问题是您需要重新读取或存储第二遍的整个序列。显而易见的改进是维护数据结构,以便在平均值发生变化时调整绝对差值之和。
假设您通过观察一个巨大的数字将平均值更改为一个非常大的值。现在比较一下由于观察到一个不那么大的值而导致的变化。您将能够计算两个绝对差值之和的差异,因为两个平均值都高于所有其他数字,因此所有绝对值都会减少两个巨大平均值之间的差异。这种可预测的变化会持续到平均值达到标准数中观察到的最高值,这一变化可以让您找出观察到的最高值。
通过运行此类实验,您可以恢复在推入数字之前观察到的数字集,以运行实验。因此,您用来跟踪绝对差异总和的任何聪明的数据结构都能够存储观察到的数字集合(除了顺序,以及观察到相同数字的多个副本的情况)几乎是您所做的存储第二遍所见的所有数字。所以我认为对于绝对差异总和的情况并不存在诀窍,因为存在差异的平方,其中您关注的大多数信息仅由一对数字(和,平方和)来描述。
答案 2 :(得分:1)
如果l2范数(平均距离平方)是正确的那么它是:
sqrt(sum(x^2)/n - (sum(x)/n)^2)
平均x ^ 2的平方根减去平均x的平方。
它被称为variance(实际上,上面是方差的平方根,称为标准偏差,是典型的“传播度量”)。
请注意,这对异常值比您最初要求的措施更敏感。
答案 3 :(得分:0)
您的后续内容将您的上下文描述为从纹理中读取HLSL。如果滤波器占用空间为2的幂并且与原始图像中相同的2次幂边界对齐,则可以使用MIP贴图查找滤波器区域的平均值。
例如,对于8x8滤波器,预先计算MIP链下三级的MIP映射,其元素将是每个8x8区域的平均值。然后,从该MIP级别纹理读取的单个纹理将为您提供8x8区域的平均值。不幸的是,这不适用于将滤波器滑动到任意位置(在本例中不是8的倍数)。
您可以利用中间MIP级别来尽可能地利用4x4或2x2区域的MIP平均值来减少纹理读取次数,但这会使算法复杂化。