Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 为什么线性搜索的时间复杂度仍然是O(N)?_Search_Time Complexity - Fatal编程技术网

Search 为什么线性搜索的时间复杂度仍然是O(N)?

Search 为什么线性搜索的时间复杂度仍然是O(N)?,search,time-complexity,Search,Time Complexity,我突然想到,线性搜索并没有真正打开,因为必须处理缓存未命中。这让我想知道为什么线性搜索仍然被宣传为具有时间复杂性?难道不应该考虑内存单元与CPU的距离吗?此外,由于光速引起的信号传播是任何人都无法逃避的物理限制。在这里,我讨论的是经典计算,而不是量子计算 让我们快速分析一下现实世界中线性搜索算法的合理界限。让我们假设一个无限小的CPU被封装在球形存储单元的中心。每个单元使用恒定数量的晶体管k实现。每单位体积的晶体管数量为rho。CPU对每个存储单元都有一条读/写线和一条数据线,假装路由这些线不是

我突然想到,线性搜索并没有真正打开,因为必须处理缓存未命中。这让我想知道为什么线性搜索仍然被宣传为具有时间复杂性?难道不应该考虑内存单元与CPU的距离吗?此外,由于光速引起的信号传播是任何人都无法逃避的物理限制。在这里,我讨论的是经典计算,而不是量子计算

让我们快速分析一下现实世界中线性搜索算法的合理界限。让我们假设一个无限小的CPU被封装在球形存储单元的中心。每个单元使用恒定数量的晶体管k实现。每单位体积的晶体管数量为rho。CPU对每个存储单元都有一条读/写线和一条数据线,假装路由这些线不是问题,CPU在任何时刻都只能读/写单个位。在这里,我们需要找到在N个内存位上执行线性搜索所需的时间

没有足够的代表发布图片,但这里有一个链接到一个图表,我试图说明这个问题

球面半径

所需的总体积为N*k/rho。给定包含所有存储单元所需的球体半径为R,我们得到了4/3*pi*R^3=N*k/rho,或者对于某个常数a,R=a*N^1/3

元素壳dVr

在由驻留在其中的dV*rho/k内存位组成的图中,考虑一个元素壳dVr=4*pi*r^2*dr灰壳。CPU需要不少于2*r/c的时间来读取/更新驻留在此dV中的内存位,首先断言r/W线,然后等待来自内存单元的应答,其中c是光速

积分dt

与驻留在dVr中的所有存储单元进行接口所用的时间由dt=dV中的单元数*与每个单元进行接口所用的时间=8*pi*rho*r^3*dr/k*c=b*r^3*dr(对于某个常数b)。所用的总时间T是b*r^3相对于r的积分,从r=0..a*N^1/3,我们得到T=b*a^4*N^4/3/4=ON^4/3

我认为这种分析并不过分,因为到目前为止,计算机系统中的三级缓存并不少见。很快,谁知道可能会有多层内存模型,其中内存单元与CPU的距离可以被认为是连续的


PS:对于那些感兴趣的人来说,存储单元在磁盘上线性排列和均匀排列的情况的时间复杂度分别为^2和^3/2。我相信晶体管分布在一个球体中的情况是CPU和内存单元之间高效接口的最佳方式。

算法是基于理论的,时间复杂度是在图灵机器的基础上计算的,在图灵机器中,内存本身被认为与标准计算机不同还有许多其他的自动机,它们以不同的方式处理内存和操作。复杂性描述了一种模式,在给定一组应执行的基本指令的情况下,基本操作将采用这种模式来计算问题的答案。因此,时间复杂度是存在的。您提到的复杂性大多是非常细粒度的优化,除非您正在做一些非常特定于时间的事情,否则这些优化并不是真正必要的。当您决定使用哪种算法时,这种分析没有标准算法分析那么重要


就我所关心的而言,我不会太在意这些细微的数字,这些数字会因CPU和其他因素的不同而有所不同,我会考虑什么会更快地完成我所需要的。这些被称为微优化,旨在利用特定于硬件的更改,通常应该留到最后。在大多数情况下,所有或大多数硬件都会表现出相同或接近相同的复杂性,也有一些例外,如SSE优化。

计算复杂性与算法执行的操作数量有关,并且没有考虑到实际计算机执行算法时的非线性行为

最好说性能比复杂性更重要


后缀trie算法也是一个类似的例子,据报道,Ukkonen的算法是线性的,由于内存局部性差,其性能往往比其他复杂度更高的算法差

在计算big-O时,将程序的成本视为指向n空间的向量会有所帮助,其中n是您正在分析的维度数

其中一个轴是计算复杂性,这是我们的大O。因为我们一直使用单一运行作为复杂性的代表,我使用“松散运行”来表示具有一些定义输入的代表性程序,我们可以选择计算复杂性读取:lo 作为一个鉴别器。我将big-O更名为comp_complexity,以澄清问题:

Cost(program, n) -> <comp_complexity(program, n)>
我们可以添加一系列影响计算复杂性的因素:空间复杂性,或者运行程序的挂钟时间。所以我们添加了额外的维度,我选择了a作为时钟时间的任意输入:

Cost(p,n,m,a) -> <comp_complexity(p,n,m), 
   space_complexity(p,n,m), 
   wall_clock(p,n,m,a)>
所以Cost返回一个函数向量,根据它们的输入返回一些Cost。我们可能追求的是给定实际成本的大小,|成本'泡沫|排序,| 10,20,1.3 |,或者更可能的是,该成本的某些预测的大小。在现实生活中,我们可能在典型的非线性最大搜索中一次解决一个问题,希望有一些美丽的理想解决方案。我们当然忽略了隐藏成本,但我们调查的目的是减少我们设定的预测量,如果不是针对整个输入范围,那么可能是针对某个小窗口。为了降低成本向量的大小,我们可以投入精力来降低与其任何轴相关的成本,无论是计算复杂性还是方法的完整运行时间,或者可能是所涉及代码的维护成本


所以,为了回答你的问题,线性搜索分析的一个维度是其内部循环的复杂性,Big-O,Cost=。这并不意味着它是算法成本的最大贡献者,但如果这种一维投影是我们所关注的,那么在改进我们已有的东西时,它提供了一种比较的方法。

这不是理论计算机科学网站的吗?这不是一个很好的答案,但它的精神是正确的。对于使用某种形式描述的算法,计算时间复杂度。。。图灵机、随机存取、PDA等。一个简单的答案可能是,RAM中的线性搜索处于启用状态,如果在您的模型下它未处于启用状态,则使用不同的形式主义。。。还有更多的权力给你。@Patrick87我觉得很难真正解释这一点,但如果有什么可以改进的地方,我会尽力让我知道。我认为你的答案基本上是可以的,但有点不精确。。。例如,图灵机与内存存储的工作方式和访问方式密切相关。在很多方面,自动机只是在记忆如何工作方面有所不同。@Patrick87这就是我想说的我想我应该更仔细地选择我的单词。
Cost(p,n,m,a) -> <comp_complexity(p,n,m), 
   space_complexity(p,n,m), 
   wall_clock(p,n,m,a)>