【问题标题】:Sampling data from a large array从大数组中采样数据
【发布时间】:2013-11-13 13:46:36
【问题描述】:

基本上我有一个非常大的对象数组,我需要删除 10% 的最不合适的对象。

每个对象都有一个与之关联的适应度变量(一个双精度变量)。我没有一个数字来确定一个对象是否合适,我只想要一堆中最不合适的。

检索(采样)最不合适的对象的最佳方法是什么?

一种方式可以是随机选择让方式 20%,对数据进行排序,然后删除 10%。但我认为这不是一个非常聪明的方法。

另一种方法是始终保持数组排序,然后删除前 10%。但我认为这不是很好,因为您必须在插入/更新时始终对数组进行排序,这是一个很大的开销..

【问题讨论】:

  • 你为什么不试试健身订购的Priority Queue?然后只需拨打remove() 直到您清除了 10%?
  • 谢谢,我不知道优先队列,让我试试
  • @thegrinner 我意识到我不能使用优先队列,因为我需要能够使用它们的索引位置来检索元素。还有其他我可以使用的数据结构吗?

标签: java arrays sampling


【解决方案1】:

设 k 为 yourCollection.length() * 0.1n = yourCollection.length()

找到第 k 个最小的元素(QuickSelect 或 5 的中位数),其中关键是您的健康状况。我们称之为p。这可以在O(n) 中完成。

然后遍历集合,移除所有fitness小于p.fitness的item。我们有一个O(n) 解决方案。

或者,您可以使用key=fitnessO(n) 中创建一个堆,并在O(k * log(n)) 中从中删除k 元素。

【讨论】:

  • 谢谢。有点迷糊,能不能说的详细点?将健身作为关键是一个好主意吗?因为它会不断更新。
  • @RegUser : 你能提供更多关于使用的信息吗?假设适应度可以在恒定时间内计算,第一个解决方案在O(n) 中运行,即使是多个移除一起("O(n) + 9/10 O(n) + 81/100 O(n)" ... ~ O(n),参见en.wikipedia.org/wiki/Geometric_progression)。如果您想要更快的单个删除,您可以维护一个记录树并存储子树的大小,这样您就可以在O(k + log n) 中找到您的集合。但这需要对树进行额外维护,如果经常更新适应度,它会变慢。
  • 使用改进的遗传算法求解TSP。在每一代之后,我都想删除 10% 的最差个体,而无需迭代整个种群,并且计算能力非常低 - 最重要的是它是高效的。
  • 如果你的程序有一个类似loop(update all the fitnesses, then remove the worst 10%)的部分,我会坚持第一个解决方案。因为维护一个智能结构比直接的方法成本更高。请注意,如果您不介意在某些适应度相同的情况下不精确地设置 10%,则无需再次遍历您的数组,并且可以使用 QuickSelect 结果。
  • 一般来说,没有更好的解决方案。当你更新你的适应度时,你完全改变了输入。如果我们能够在亚线性时间内挑选出最低的 10%,我们也可以比O(n log m) 更快地排序(仅使用比较)。这太好了,不幸的是,事实证明这是不可能的。
猜你喜欢
  • 2021-08-08
  • 1970-01-01
  • 2014-12-28
  • 2019-03-19
  • 1970-01-01
  • 2021-06-03
  • 2019-01-02
  • 2017-06-01
  • 1970-01-01
相关资源
最近更新 更多