我有一个正在运行的整数流,如何在任何时间点从该流中获取最大的k个元素。
答案 0 :(得分:15)
最简单的解决方案是填充min-heap大小k
。
首先,使用第一个k
元素填充堆。
接下来,对于流中的每个元素 - 检查它是否大于堆的头部,如果是 - 弹出当前头部,然后插入新元素。
在流中的任何时刻 - 堆都包含最大的k
元素。
此算法为O(nlogk)
,其中n
是到目前为止在流中遇到的元素数。
另一种解决方案,在某些情况下,在渐近复杂性方面稍微复杂但理论上更好,是保留2k
元素的数组。
首先,加载前2k个元素。
运行Selection Algorithm,找出最高k
。放弃其余部分,此时数组中只剩下k
个元素。
现在,再次使用下一个k
元素填充数组,然后重复。
在每个点上,数组包含k
个最大元素,最多k
个元素不是最大的元素。您可以为此阵列上的每个查询运行选择算法。
运行时分析:
维护阵列:每个选择算法都是O(2k) = O(k)
。每k
个元素执行一次,n/k
次,如果n
表示到目前为止看到的元素数量,则为O(n/k * 2k) = O(n)
。
此外,每个查询都是O(k)
,如果查询的数量为Q
,则会为我们提供O(n + Q*k)
运行时。
为了提高效率,我们需要Q*k < nlogk
Q*k < nlogk
Q < n/k * logk
因此,如果如上所述限制查询的数量,则此解决方案在渐近复杂度方面可能更有效。
在实践中,获得top k通常是通过使用min-heap解决方案来完成的,至少在我看到它需要的时候。
答案 1 :(得分:0)
def gse(y_true, y_pred):
# some tensor operation on y_pred and y_true
return K.mean(K.square(y_pred - y_true), axis=-1)
nsmallest或nlargest方法采用参数k和要在其中找到最小/最大元素的数组