数据结构可快速查找最近的浮点值

时间:2014-07-08 17:19:52

标签: c# database optimization data-structures

如果我有一堆以下数据,我应该使用哪种数据结构:

MyData
{
    float ValueA;
    float ValueB;
    object OtherInfo;
}

我需要快速找到符合此类条件的所有MyData个实例:

0.5 <= ValueA <= 0.7    AND    0.2 <= ValueB <= 0.9

找到这些项目很简单,但我需要尽快完成。是否有适合这种情况的数据结构?我不介意用尽额外的记忆。

我目前的想法是有一个排序列表,按ValueA排序。然后我会进行二分搜索以找到具有ValueA&gt; = 0.5的第一个项目,并迭代直到我得到一个具有ValueA&gt;的项目。 0.7。对于每次迭代,我检查ValueB是否介于0.2和0.9之间。我将所有匹配项放在输出数据集中。

有更好/更快的方法吗?

顺便说一句,我正在使用C#。

4 个答案:

答案 0 :(得分:3)

interval tree符合您的需求。示例实现(我尚未测试)at Codeplex。更多here

更新:区间树与相关结构(段树)的比较如下:What are the differences between segment trees, interval trees, binary indexed trees and range trees?

答案 1 :(得分:2)

您的问题是二维的,但您只是在一个维度上优化搜索空间。 quadtree是适当的数据结构;你应该没有困难在C#中找到合适的实现。如果您想要其他替代方案,那么只需搜索2D空间分区算法。这基本上就是你在这里做的事情; ValueA和ValueB可以被视为2D坐标,即使它们不是它们实际代表的那些。

答案 2 :(得分:2)

您可以使用单个列表执行此操作,该列表首先在ValueA上排序,然后在ValueB上排序。所以,如果你有这些项目:

  A    B
{0.5, 0.7}
{0.3, 0.1}
{0.5, 0.2}
{0.5, 0.4}
{0.2, 0.3}

您可以在列表中订购:

{0.2, 0.3}
{0.3, 0.1}
{0.5, 0.2}
{0.5, 0.4}
{0.5, 0.7}

在LINQ中按两个条件排序非常简单:

var sortedList = theList.OrderBy(s => s.ValueA).ThenBy(s => s.ValueB).ToList();

您还可以通过将自定义比较委托传递给Sort方法来就地排序列表。

现在,根据搜索:0.5 <= ValueA <= 0.7 && 0.2 <= ValueB <= 0.9,您可以执行以下操作:

  1. 二进制搜索以找到第一个值> = 0.5的ValueA。请拨打此startA
  2. 二进制搜索以查找最后一个&lt; = 0.7的ValueA。请拨打此endA
  3. 二进制搜索区间[startA..endA],查找第一个值>&gt; = 0.2的ValueB。请拨打此startB
  4. 二进制搜索间隔[startA..endA]以查找最后一个&lt; = 0.9的ValueB。请拨打此endB
  5. 您要查找的项目位于[startB..endB]区间。

    请注意,如果您要迭代[startB..endB]范围内的所有项目,则不必执行最后一次二进制搜索,因为您可以在迭代期间将其过滤掉。

答案 3 :(得分:1)

在此解决方案中,我将数据合并到列表中,其中每个列表包含widthX by widthY框内的所有数据点。如果您的数据在valA=[0,1], valB=[0,2]范围内,并且您将网格划分为.1个.1个bins(如代码所示),则searchList(4,12)是一个包含所有值的列表,{{1} }和.4 <= valA <= .5

此解决方案仅对相当紧凑的相当大的输入数组有效。如果有任何极端异常值,您将创建许多不必要的箱。

如果查询是在“自然”(I.E. .1,.01)边界上,则效果最好,但这不是必需的。您必须手动循环1.2 <= valB <= 1.3以过滤掉不需要的元素。

搜索查询非常简单 - 在每个维度上找到你的最小/最大分档,并循环遍历其间的所有分档。

searchList(i,j)