【问题标题】:What Big-O equation describes my search?什么 Big-O 方程描述了我的搜索?
【发布时间】:2012-03-22 11:22:05
【问题描述】:

我有一个排序的双精度数组(实际上是纬度),它们相对均匀地分布在 -10 到 -43 的范围内。现在,如果我对该列表进行二进制搜索,我会得到 O(log N)。

但是,我可以通过查找表来进一步优化,其中我有 34 个键(-10 到 -43),然后可以直接跳转到该数字的起点。

例如:-23.123424 首先查找键 23 并知道所有 -23 值的起止范围。然后我可以从中间进行二进制搜索。

我的 Big-O 会是什么样子?

【问题讨论】:

  • 听起来您正在尝试实现非常类似于skip list
  • @BrianRoach 虽然,即使是跳过列表也具有 O(log n) 查找复杂度。与普通二叉树相比,它们的唯一优势是它们的自动平衡特性。

标签: big-o binary-search


【解决方案1】:

仍然是 O(log n)。考虑:在整数查找表中查找起始索引需要恒定的时间,因此该部分不会添加任何内容。然后是 O(log n) 进行二进制搜索。实际上,它大约需要 log n/34,因为您希望搜索一个平均小 34 倍的数组(这些值分布在 34 个不同的间隔中,边界从 -43 到 -10),但不考虑常量乘数-O 表示法。

【讨论】:

  • 和 log(n / 34) = log(n) - log(34)。所以这里甚至没有一个常数乘数。
【解决方案2】:

它仍然是O(log N),但是对于减少的数据集(认为 N 的值更小)。

由于查找表提供了 ca。 1/34,接近二分搜索的 1/32 或 5 步,如果这真的有帮助,您可能需要进行基准测试:具有大量缓存未命中和一个或另一个错误分支预测/管道的附加代码路径清除可能会使这比直接二进制搜索慢。

此外,如果内存表的查找时间是瓶颈,您可能需要考虑将您的纬度表示为 Int32 值 - 绝对足够精确,但搜索速度要快得多。

【讨论】:

  • 除了速度之外,还有另一个原因是使用 32 位整数而不是浮点来表示任何角度(包括纬度和经度):使用浮点,接近零的值具有更高的可用精度(更多小数位无损存储)并且远离零的值更少。然而,没有充分理由说明离赤道较近的点应该比其他点更精确地存储。整数缩放后,0 表示 0,2147483648 表示 π 弧度等价于定点小数,非常适合此应用。
  • 我一定会这样做的!一个巨大的回报,因为我已经将数据生成到一个文件中,所以我将预先转换为 32 位。非常好。
  • @Celada 当然你是对的,但我怀疑这对现实世界的影响很小:我怀疑 OQ 中的 -10 和 -43 之间的值具有浮点精度,这要好得多比数据(GPS?)质量。此外,数据来源是float,因此重新缩放不会引入新的精度,原始数据中不存在该精度。尽管如此,我们同意int 是可行的方法。
【解决方案3】:

听起来您的优化会有所帮助,但我认为它仍然被认为是 O(log N),因为您仍然需要搜索确切的值。如果它直接带你到值,那将是 O(1)

这是 Big-Oh 分析的限制。它没有考虑到您减少了必须搜索的值的数量。

【讨论】:

  • 当然可以,但只有在优化导致要搜索的元素数量的渐近复杂度降低时,它才会有所不同。 Big-Oh 实际上只不过是算法所需的渐近操作数。
【解决方案4】:

您的概念与interpolation search 的概念很接近,除了它不是只在键的组成部分上“插值”一次,而是递归地使用插值来智能地驱动二分搜索。由于您的域相对统一,因此预期的运行时间是O(log log n)

【讨论】:

  • 在代码中会这样:我有 -23.1234,所以我跳到“大致”-23 的百分比在 -10 到 -43 之间。然后我看一下这个值,说它是-33。那么我现在在 -10 到 -33 之间跳跃某个百分比,等等?
  • @peterept 正确。输入越统一,您就越有可能跳转到正确的条目。
猜你喜欢
  • 2016-07-01
  • 2010-11-22
  • 1970-01-01
  • 2012-02-20
  • 2019-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多