[NLPCamp] 时间复杂度与空间复杂度-算法工程师不可忽略的重要指标

本文从时间复杂度和空间复杂度的概念出发,结合Python代码分析其计算方法。介绍了渐进时间复杂度,总结了时间和空间复杂度的计算规则,还以递归实现的斐波那契数列为例进行计算。此外,讲解了用于计算含递归调用算法时间复杂度的Master Theorem。

引言:

算法复杂度是算法工程师容易忽略的指标,尤其对于转入AI行业的算法工程师们,可能对算法复杂度的概念更是陌生,但是实际情况中,算法的复杂度会直接影响算法的执行效率,是非常重要的评估指标,本文从时间复杂度和空间复杂度的概念出发,结合实际的一些代码分析时间复杂度与空间复杂度,并总结了一些评估时间复杂度和空间复杂度的一点小小的经验,如果有说错的地方,希望大神们帮忙指正、赐教。

正文:

在实现算法的时候,通常会从两方面考虑算法的复杂度,即时间复杂度和空间复杂度。顾名思义,时间复杂度用于度量算法的计算工作量;空间复杂度用于度量算法占用的内存空间。

 

渐进时间复杂度:

理论上来说,时间复杂度是算法运算所消耗的时间,但是对于一个算法来说,评估运行时间是很难的,因为针对不同大小的输入数据,算法处理所要消耗的时间是不同的,因此通常关注的是时间频度,即算法运行计算操作的次数,记为T(n),其中n称为问题的规模。同样,因为n是一个变量,n发生变化时,时间频度T(n)也在发生变化,我们称时间复杂度的极限情形称为算法的“渐近时间复杂度”,记为O(n)。因为我们没办法用通常的评估方式来评估所有算法的时间复杂度,因此使用渐进时间复杂度表示算法的时间复杂度,下文中的时间复杂度均表示渐进时间复杂度。

我们在这里放一个python算法的例子来解释一下:

def f(n):
	a,b=0,0#运行消耗t0时间
	for i in range(n):#运行一次平均消耗t1时间
		a = a + rand()#运行一次平均消耗t2时间
	for j in range(n):#运行一次平均消耗t3时间
		b = b + rand()#运行一次平均消耗t4时间

 

在这个例子中,我们分别计算f(n)函数的时间复杂度与空间复杂度。根据代码上执行的平均时间假设,计算出来执行f(n)的时间为T(n)=t0+(t1+t2)*n+(t3+t4)*n=t0+(t1+t2+t3+t4)*n;而函数中申请了两个变量a,b,占用内存空间为2。上述T(n)是我们对函数f(n)进行的准确时间复杂度的计算。但实际情况中,输入规模n是影响算法执行时间的因素之一。在n固定的情况下,不同的输入序列也会影响其执行时间。当n值非常大的时候,T(n)函数中常数项t0以及n的系数(t1+t2+t3+t4)对n的影响也可以忽略不计了,因此这里函数f(n)的时间复杂度我们可以表示为O(n)。我们再来看空间复杂度,跟时间复杂度表示类似,也可以用极限的方式来表示空间复杂度(但是貌似没有渐进空间复杂度的说法),因为这里只声明了2个变量,因此空间复杂度也是常数阶的,因此这里空间复杂度计算为O(1)。

 

时间复杂度与的计算方法:

因为我们计算的是极限状态下的时间复杂度,因此存在两种特性:

1.按照函数数量级角度来说,相对增长低的项对相对增长高的项产生的影响很小,可忽略不计。

2.最高项系数对最高项的影响也很小,因此也可以忽略不计。针对第1点,常见的时间复杂度有:常数阶:常数阶:O(1),对数阶:O(log_2 n),线性阶:O(n),k次方阶:O(n^K),指数阶:O(2^n)。

根据上述两种特性,总结时间复杂度的计算方法:

1.只取相对增长最高的项,去掉低阶项;

2.去掉最高项的系数;

3.针对常数阶,取时间复杂度为O(1)。

 

空间复杂度:

空间复杂度指的是算法在内存上临时占用的空间,包括程序代码所占用的空间,输入数据占用的空间和变量占用的空间。在递归运算时,由于递归计算是需要使用堆栈的,所以需要考虑堆栈操作占用的内存空间大小。空间复杂度的计算也遵循渐进原则,即参考时间复杂度与空间复杂度计算方法项。

 

空间复杂度的计算方法:

1.通常只考虑参数表中为形参分配的存储空间和为函数体中定义的局部变量分配的存储空间(比如变量a=0在算法中空间复杂度为O(1);list_a=[0,1,....,n]的空间复杂度为O(n);set(list_a)的空间复杂度为O(1))。

2.递归函数情况下,空间复杂度等于一次递归调用分配的临时存储空间的大小乘被调用的次数。

我们这里以递归方法实现的斐波那契数列为例:

def fib(n):
    if n < 3: 
        return 1
    else:
        return fib(n-2)+fib(n-1)

斐波那契数列的序列依次为1,1,2,3,5,8,13.....特点是,当数列的长度大于等于3时,数列中任意位置的元素值等于该元素前两位元素之和。

1.计算时间复杂度:O(2^n)。计算方法:通过归纳证明的方法,我们尝试计算数列中第8个元素的值的递归调用次数,为了方便观察,我把外层括号替换为了大括号。fib(8)=fib(7)+fib(6)={fib(6)+fib(5)}+{fib(5)+fib(4)}=({fib(5)+fib(4)}+{fib(4)+fib(3)})+({fib(4)+fib(3)}+{fib(3)+fib(2)})=.....这里太多我就不一一写出了。不难发现,每次调用递归时,递归调用次数都是以程序中调用递归次数即2的指数形式增长的。第一层递归时,调用了2次fib(n)函数;第二层递归时,第一层的2次递归调用分别又要调用2次,即调用了2^2次;第三层递归调用了2^3次,以此规律,不难算出时间复杂度为O(2^n)

2.计算空间复杂度:O(n)。计算方法:我们同样使用归纳证明的方法,尝试推导数列中第6个元素值的内存占用情况。调用函数fib(6),此时因为有形参n传递,在栈中为n申请内存资源,我们为了方便,以fib(6)表示栈中元素。此时栈中有fib(6);我们根据函数内的递归调用关系,为了计算fib(6),我们需要fib(5)和fib(4)的值,此时发生形参传递,栈中有fib(6),fib(5),fib(4);为了计算fib(4),我们需要fib(3)和fib(2)的值,此时栈中有fib(6),fib(5),fib(4),fib(3),fib(2),但是由于fib(2)=1,此时fib(2)函数计算完成,fib(2)出栈,此时栈中有fib(6),fib(5),fib(4),fib(3)。为了计算fib(3),需要fib(2)和fib(1)的值,此时栈中有fib(6),fib(5),fib(4),fib(3),fib(2),fib(1)。但是fib(2)=1,fib(1)=1,计算完成,fib(2)和fib(1)出栈。此时得到fib(3)的值为2,fib(3)出栈;由此出栈顺序,fib(4),fib(5),fib(6)也会随计算完成出栈。不难发现,在此次递归计算的过程中,内存中最多消耗了6个内存资源,由归纳证明法得出fib(n)的空间复杂度为O(n)。

 

Master Theorem(主方法):

Master Theorem是为了计算含有递归调用的算法的时间复杂度的。因为算法中如果含有递归调用算法的情况下使用归纳证明的方法计算时间复杂度是相当困难的,因此我们需要利用Master Theorem来帮我们计算复杂情况下的算法的时间复杂度,Master Theorem定理如下:

Master Theorem的一般形式是T(n) = a T(n / b) + f(n), a >= 1, b > 1。递归项f(n)理解为一个高度为log_b n 的a叉树, 这样总时间频次为 (a ^ log_b n) - 1, 右边的f(n)假设为 nc 那么我们对比一下这两项就会发现 T(n)的复杂度主要取决于 log_b a 与 f(n) 的大小。(log_b a表示以b为底,a的对数)因此我总结了使用Master Theorem的三种case的简单判断:

1.计算log_b a的值,比较n^(log_b a)与f(n)的大小。

2.若n^(log_b a)>f(n),时间复杂度为O(n^(log_b a)) (case 1)

3.若n^(log_b a)<f(n),时间复杂度为O(f(n)) (case 3)

4.若n^(log_b a)=f(n),时间复杂度为O(n^(log_b a)*(log n)^k+1) (case 2) (其中k值为f(n)中如果有log对数项时,该对数项的指数为k,例如,如果f(n)=log n ,k=1;f(n)=n,k=0)

 

可能公式理解起来有点困难,举几个例子来加深理解:

常规套路呢,就是比较n^(log_b a)与f(n)的值了,比较出来就可以套用上述公式,但是一定要注意公式中的限制条件,如a必须为常数项等。

以上是关于时间复杂度和空间复杂度计算的所有内容了,写的比较渣,如果有写错或者理解错的地方,还请大神们多多指教。

源码直接下载地址: https://pan.quark.cn/s/1c143f32ee83 华为作为全球领先的通信设备供应商,其产品系列广泛涉及各类网络设备,其中包括我们接下来要探讨的上网卡产品。华为上网卡驱动程序是一种专门为华为品牌旗下多种型号上网卡开发的软件模块,其主要功能在于保障这些设备计算机操作系统的无缝对接。涉及的型号涵盖EC8189、EC226、EC169C、EC360、EC1260、EC1261、EC189、EC122、EC150以及EC168,这些均是由华为公司推出的移动宽带调制解调器,旨在通过移动网络实现便捷的互联网接入服务。驱动程序在计算机系统中的地位举足轻重,它充当了硬件设备操作系统之间的媒介,负责对硬件设备发出的指令进行解读和执行,并将操作系统的指令传递给硬件设备。华为上网卡驱动程序的及时更新和精准安装是保障设备稳定运作和性能达到最优的关键因素。"天翼宽带安装程序V1.3.3.exe"是由中国电信提供的一个整合性软件包,内含华为上网卡的驱动程序及配套的管理工具。用户可借助此安装程序来执行华为上网卡的相关驱动安装及更新,同步享受中国电信的3G或4G网络服务。版本标识V1.3.3代表软件经过迭代优化,通常包含了对错误的修正、性能的改善以及新功能的引入。 "SetupInfo.xml"作为安装程序的配置文档,其中收录了安装流程中的各项设定和元数据信息,例如安装流程、文件定位、依赖条件等。它是安装程序在执行时参照和遵循的纲领,旨在确保安装流程按既定方案进行。文件名"CT_HW_EVDO_Driver"或许指向华为的EVDO(Evolution-Data Optimized)驱动程序,EVDO是一种3G无线通信规范,具备高速数据传输的特性。该驱动可...
内容概要:本文围绕【博士论文复现】基于小信号扫频辨识的光伏并网逆变器正负序交互稳定性分析展开,结合Matlab代码Simulink仿真实现,系统研究了光伏并网逆变器在弱电网环境下的正负序阻抗建模交互稳定性问题。重点采用小信号扫频法进行系统辨识,获取逆变器的正负序阻抗特性,并通过奈奎斯特稳定判据等方法分析其在不同电网强度下的稳定性表现。文中详细阐述了扫频激励信号的设计原理、频域响应数据的提取处理流程、阻抗模型的拟合验证方法等关键技术环节,实现了对逆变器在复杂电网条件下动态交互行为的精确刻画。该研究不仅深入揭示了新能源并网系统中潜在的宽频振荡机理,也为提升系统稳定性、优化控制器设计提供了坚实的理论依据和有效的技术手段。; 适合人群:具备电力电子、自动控制及电力系统基础知识,从事新能源并网、电力系统稳定性研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 掌握基于小信号扫频法的电力电子装置阻抗建模方法;② 深入理解光伏并网逆变器在弱电网下的正负序交互稳定性机理;③ 学习并复现高水平博士论文中的核心仿真技术,提升科研实践能力;④ 为实际工程中新能源并网系统的稳定性分析、振荡问题诊断控制器优化设计提供理论支持和技术参考。; 阅读建议:学习者应结合提供的Matlab代码Simulink模型,深入理解扫频辨识的原理实现步骤,重点关注锁相环、电流控制环等关键模块对系统阻抗特性的影响,并尝试改变系统参数以观察稳定性变化,从而加深对理论知识的掌握。
代码转载自:https://pan.quark.cn/s/a4b39357ea24 OPC(OLE for Process Control)是由微软推出的一种应用于工业自动化场景下的数据交换规范,其目的是使多样化的自动化装置软件平台之间能够实现信息互通。在本项研究中,我们集中探讨的是一个运用C#语言构建的完整OPC客户端的源代码实现。该客户端具备OPC服务器建立连接、获取或设置数据的能力,从而促成设备间的协同工作。鉴于C#是.NET框架的核心编程语言,并且拥有丰富的类库资源及强大的面向对象支持,它特别适合用于开发此类工业环境的应用程序。接下来将针对OPC客户端源代码中可能涉及的核心技术要点进行详尽的阐述: 1. **OPC Foundation .NET库**:为了在C#环境下实现OPC通信功能,开发人员通常会选择采用OPC Foundation提供的.NET库,例如OPC-UA .NET Standard或OPC Classic .NET。这些库提供了操作OPC服务器的必要API,涵盖了建立连接、遍历服务器节点、读取写入数据等一系列操作。 2. **OPC连接配置**:客户端在运行前必须先OPC服务器建立通信通道。这一过程通常需要配置服务器的位置信息、身份验证凭证(包括用户名和密码)以及连接的详细参数。在源代码中,可能会包含一个`Connect()`方法来处理这些连接细节。 3. **数据项订阅机制**:OPC客户端通过向服务器订阅数据项来实时获取数据更新。在订阅阶段,客户端会指定需要监控的数据项的唯一标识,并设定当数据发生变化时触发的回调函数。在C#编程语言中,这一过程可能通过`AddSubscription()`和`AddItem()`方法来完...
代码转载自:https://pan.quark.cn/s/a4b39357ea24 软件测试面试问题 本文收录软件测试面试过程中常见的面试题.一些问题是从网上搜罗而来,剔除了不合时宜的;一些则是自己总结的面试题.很多的问题是开放性的,并没有确切的标准答案. 目录 常见问题 测试用例设计问题 测试管理问题 自动化测试问题 性能测试问题 数据库问题 操作系统问题 算法问题 * 数据结构 * 排序 * 其它 Java面试题 * 基础知识 * JVM * 并发编程 * JDBC * Servlet&JSP Spring * Spring MVC * Srping Boot Mybatis 常见问题 软件测试的目的是什么? 软件测试的一般流程是怎么样的? 常见的测试类型有哪些? 分别说明一下? 测试用例设计常用的方法有哪些?详细说明一下? 解释下单元测试,集成测试,系统测试以及验收测试? 探索性测试是什么? 应该怎么做? 什么是冒烟测试,如何有效的开展冒烟测试? 一条高质量的缺陷记录(Bug)应该具有哪些内容? 缺陷的生命周期是怎样的? Alpha测试Beta测试的区别? 你认为做好软件测试应该具备哪些素质? 作为测试人员,在开发人员沟通过程中,如何有效的提高沟通效率和效果? 你觉得软件测试工程师在一个团队中,都需要做什么? 有什么价值? 你对软件测试最大的兴趣是什么? 你对自己的职业规划是什么? 在你以往的工作中,发现的影响大或印象深刻的Bug是什么? 为什么? 在你以往的经历中,解决过的最困难的问题是什么? 在你以往的工作或学习中,你最大的收获是什么?学到了什么? 你认为做好软件测试应该具备哪些素质? 在没有任何文档的情况下,你如何开展测试? 测试用例设计问题 测试用例...
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 ### 关键技术要点详述 #### 一、简述 SH1106属于一款单片CMOS OLED/PLED驱动集成电路,其主要用于有机/聚合物发光二极管点阵图形显示系统的构建。该集成电路能够支持高达132x64像素的显示能力,并且特别针对共阴极类型的OLED面板进行了优化设计。它整合了对比度调节功能、显示数据存储器、振荡装置以及高效的DC-DC变换模块,从而有效降低了所需外部元件的数量并减少了能源消耗。 #### 二、核心特性 1. **最高分辨率支持**:能够驱动132x64像素点阵面板。 2. **内存集成**:内置了132x64位的SRAM空间,用于保存显示数据。 3. **工作电压范围**: - 逻辑电源电压(VDD1):1.65V至3.5V - DC-DC电源电压(VDD2):3.0V到4.2V - OLED工作电压(VPP): - 外部供电模式:7.0V至13.0V - 内置供电模式:7.4V至9.0V 4. **最大段输出电流值**:200μA。 5. **最大公共端输出电流**:27mA。 6. **接口种类**: - 8位6800系列并行接口 - 8位8080系列并行接口 - 3线或4线串行外设接口(SPI) - 400kHz高速I2C总线接口 7. **可编程帧速率多路复用比设置**。 8. **行列重映射支持**:提供行重映射和列重映射(列地址编码)功能。 9. **垂直滚动实现**。 10. **内置振荡装置**。 11. **内置电荷泵电路输出**:允许通过编程进行调节。 12. **256级对比度调节**:适用于单色被动式OLED面板。 13. **节能...
内容概要:本文档系统阐述了基于虚拟同步发电机(VSG)技术的风力发电储能系统并网的Simulink仿真研究,重点在于通过VSG控制策略增强风储联合系统的并网稳定性、频率调节能力和惯性响应特性。文档涵盖了VSG控制、下垂控制、构网型变流器、多机并联运行、故障穿越等核心技术,并提供了丰富的电力系统仿真案例,如风电功率平抑、储能协同控制、微电网优化调度等,全面展示风储系统在动态响应、功率协调暂态稳定方面的建模方法分析手段。作为一系列新能源并网技术仿真资源的一部分,该资料强调科研过程中工具应用创新思维的深度融合。; 适合人群:具备电力系统、自动化、电气工程等相关专业背景,熟练掌握MATLAB/Simulink仿真平台,从事新能源并网、微电网控制、储能系统集成电力电子控制研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①开展风储联合系统的动态建模并网控制策略仿真研究;②深入理解和复现虚拟同步发电机在提升电网惯性和频率支撑能力中的关键技术;③为撰写硕士论文、EI期刊论文提供高可信度的仿真模型支持复现依据。; 阅读建议:建议结合文中提及的其他相关仿真资源(如微电网能量管理、储能优化配置等)进行体系化学习,优先掌握VSG的核心控制原理Simulink建模流程,并通过对比不同控制策略(如下垂控制、虚拟阻抗、多机协调)的仿真结果,深化对系统动态行为的理解分析能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值