关于算法的时间复杂度(度量算法执行时间的两种方法、渐进时间复杂度、时间复杂度的几个性质、渐进估算、常见的渐进时间复杂度排序)

目录

度量算法执行时间的两种方法

事后统计法(Post Hoc Analysis):

事前统计法(Pre Hoc Analysis):

渐进时间复杂度

时间复杂度的几个性质

渐进估算

常见的渐进时间复杂度排序


度量算法执行时间的两种方法

算法的时间复杂度一般是指程序运行从开始到结束所需的时间。

算法执行时间需通过依据该算法编制的程序在计算机上运行所消耗的时间来度量,而度量算法执行时间通常有两种方法:事后统计法和事前估算法。

事后统计法是将算法实现后,计算其时间和空间开销,从而确定算法的效率。然而时间和空间开销的计算与计算机软硬件环境相关。同一个算法在不同的机器上执行所花的时间不同,可见这种方法存在明显缺陷,因此我们一般采用事前估算法来评估算法的效率。

事后统计法和事前统计法各自具有的一些优点和缺点:

事后统计法(Post Hoc Analysis):

**优点**:

1. 实用性:事后统计法适用于已经发生的事件和数据收集,因此在一些情况下,它是唯一可行的方法。

2. 数据充分:在使用事后统计法时,我们通常可以利用完整的数据集,包括详细的历史数据,以进行深入的分析。

3. 具体问题解决:可以使用事后统计法来解决具体的问题,如异常事件的分析、错误的原因追溯等。

**缺点**:

1. 反应性:事后统计法只能应用于已经发生的事件,也就是说我们必须先执行相关程序,因此我们无法预测未来事件,只能根据过去的经验做出决策。

2. 无法控制变量:在事后统计法中,我们不能直接控制或操纵变量,因此无法进行实验性的研究。

3. 样本偏差:根据已经发生的事件进行统计分析可能会受到样本选择偏差的影响,因此得出的结论可能不太可靠。

事前统计法(Pre Hoc Analysis):

**优点**:

1. 预测性:事前统计法允许我们在事件发生前进行分析和预测,从而可以采取预防措施或制定未来计划。

2. 控制变量:我们可以在事前统计法中控制和操纵变量,以便进行实验性的研究和测试不同的假设。

3. 减少偏见:通过在研究设计中考虑随机抽样和双盲试验等技术,我们可以减少样本选择偏见和实验者偏见。

**缺点**:

1. 不适用于所有情况:事前统计法需要提前计划和准备,因此可能不适用于某些突发事件或紧急情况。

2. 数据不足:在事前统计法中,我们可能没有足够的数据来支持分析或决策,特别是对于新兴领域或少见事件。

3. 成本高昂:事前统计法可能需要大量资源和时间来收集数据和进行实验,因此成本较高。

综上所述,事后统计法和事前统计法各有其适用的情况和限制。在决定使用哪种方法时,通常需要考虑问题的性质、可用数据、时间和资源等因素。在某些情况下,两种方法可以结合使用,以获得更全面的分析和决策支持。

渐进时间复杂度

要理解清楚渐进时间复杂度我们需要先了解几个概念。

首先,什么是问题规模

你先思考一下有哪些会影响算法执行时间的因素?

我给你列出了几个(这里排序确实与重要程度有关):

1、算法选用的策略的优劣:

使用高效的算法策略可以显著减少执行时间。比如,一个具有较低时间复杂度的算法通常比一个时间复杂度较高的算法执行得更快。在某些情况下,选择最佳算法可能涉及到更多的内存使用,这可能会导致额外的计算时间来读取和写入内存。

2、问题规模,实例特征:

较小的问题规模通常意味着执行时间较短,因为算法需要处理的数据量更少。如果问题规模非常大,执行时间可能会显著增加,因为算法必须处理更多的数据。

算法的时间复杂度不仅与问题题规模相关,实例特征(如数据分布)也可以影响算法的执行时间。例如,在包含n个元素的数组中找给给定元素x,设算法从左向右搜索,如果待搜索的元素x正好是第一个元素,则所需的查找时间最短,这就是算法的最好情况;如果待搜索的元素x是最后一个元素或不在数组中,则是算法的最坏情况;如果需要多次在数组中查找概率检验每个数组元素,则是算法时间开销的平均情况

3、使用的程序语言:

某些编程语言(如C++、Rust)具有更高的执行效率,因此可以使算法运行得更快。

选择较慢的编程语言(如Python)可能导致较长的执行时间,尤其是对于计算密集型任务。

4、编译程序产生的机器代码质量:

高质量的编译器可以将源代码优化为更有效率的机器代码,从而减少执行时间。

低质量的编译器可能无法实现最佳性能,导致执行时间增加。

5、计算机执行指令的速度:

更快的处理器和更快的内存访问速度可以加速算法的执行。新一代硬件通常比旧硬件执行得更快。如果硬件性能较低,算法执行时间可能较长。

前两者都是与设计方法有关的,而后三者与运行程序的计算机软硬件环境有关。

现在让我们抛开与计算机软硬件相关的因素,那么影响算法时间效率的最主要问题就是问题规模

问题规模通常指算法的输入量,我们一般用整数 n 表示。例如:用相同的算法对10个元素进行处理和对10000000……个数据进行处理显然是不同的。

一个算法的时间开销与算法中语句的执行次数成正比。算法中语句执行次数越多,它的时间开销就越大。此时就涉及到语句频度的概念。

那么,什么是语句频度

一个算法中的语句执行次数称为语句频度。

一般情况下,算法中基本运算执行次数用 T(n) 表示,若有问题规模 n 的某个函数 f(n),使存在自然数 n0,正常数 c,当 n >= n0 时,T(n) <= cf(n),则称 f(n) 是 T(n) 的渐进上界,记为:

T(n) = O( f(n) )

大O记号表示算法的一种渐进时间复杂度,也常简称为时间复杂度。

渐进时间复杂度用以表达一个算法运行时间的上界,估计算法的执行时间的数量级。

终于,我们可以得到渐进时间复杂度的具体定义了……

渐进时间复杂度是一种用于分析算法性能的概念,它描述了算法在处理不同规模的输入数据时所需的计算资源(主要是时间)的增长趋势。通常用大O记号(O-notation)来表示,它提供了算法运行时间的上界估计,表示算法的运行时间不会超过某个特定函数的增长速度。

时间复杂度的几个性质

1. 渐进性:时间复杂度是一种渐进性描述,它关注的是问题规模 n 趋向无穷大时的增长趋势。因此,我们通常关心的是算法在大规模数据上的性能表现,而不是精确的运行时间。

2. 上界估计:时间复杂度表示的是最坏情况下的运行时间上界,即在所有可能的输入情况下,算法的运行时间都不会超过 f(n)。这有助于我们对算法的性能有一个保守的估计。

3. 大O记号:大O记号(O-notation)是常用的表示时间复杂度的符号。例如,如果一个算法的时间复杂度为 O(n),则表示算法的运行时间与问题规模 n 成线性增长。

4. 简化比较:时间复杂度的目的是简化算法之间的比较,而不是精确测量运行时间。通过使用大O记号,我们可以更容易地确定哪个算法在大规模数据上更有效率,而不需要具体的测量。

5. 选择合适的算法:时间复杂度帮助我们选择最适合特定问题的算法。例如,如果一个算法的时间复杂度是 O(n^2),而另一个是 O(n logn),在大规模数据上,后者通常更快。

时间复杂度是算法分析的重要工具,它允许我们估计算法在不同规模的输入数据上的性能表现,并帮助我们选择最优算法以解决特定问题。在算法设计和分析中,理解时间复杂度是提高计算效率和优化算法的关键一步。

渐进估算

一般情况下,我们可以通过考察一个程序中的关键操作(对算法执行时间贡献最大的操作的执行次数来计算算法的时间按复杂度。

了解了这一点,我们就可以来看看具体该如何计算一个算法的时间复杂度:

  1. 确定基本操作:首先,我们要确定算法中最主要、最耗时的操作——通常称为关键操作。这些操作是时间复杂度分析的核心。

  2. 建立基本操作的执行次数表达式:为了计算时间复杂度,我们需要建立一个表示关键操作执行次数的表达式,通常用 T(n) 来表示,其中 n 是问题规模。

  3. 简化表达式:在这一步,需要将表达式简化,去掉不必要的常数系数和低次项。这是为了关注算法在大规模数据上的增长趋势,而不是具体的执行时间。为了简化表达式,可以遵循以下规则:

    • 常数系数可忽略:常数系数不影响算法的增长趋势,所以通常可以省略不写。例如,3n^2 和 n^2 在时间复杂度分析中被认为是相同的。

    • 保留最高次项:只考虑表达式中的最高次项,因为在大规模数据上,它将主导增长趋势。其他次项、常数项和低次项都可以忽略。

  4. 确定时间复杂度符号:根据简化后的表达式,确定时间复杂度的大O记号。这是时间复杂度的最终表示,它表示算法在不同规模数据上的性能增长趋势。例如,如果简化后的表达式为 T(n) = 2n^2 + 3n + 1,那么时间复杂度可以表示为 O(n^2),因为 n^2 是最高次项。

好了,那么现在我就要向你就“简化表达式”提一个问题:

数程序步来判定算法的时间效率不是更精细吗?为啥还得在此基础上去掉低次幂和系数?

去掉低次幂还可以理解,因为随着问题规模趋向于正无穷大的时候,低次幂项值可以忽略

但是系数为何要去掉?

"程序步" :计算机科学和编程中的一个概念,通常用于描述算法或程序执行的基本操作或指令。程序步可以理解为算法执行的离散操作,每个步骤代表一个基本操作,例如赋值、条件判断、循环迭代、函数调用等。程序步用于描述算法的执行顺序和流程。

程序步的概念有助于分析和比较不同算法的性能。通过计算算法执行所需的程序步数,可以估算算法的时间复杂度。一般来说,执行步数越少,算法越高效。

在算法分析中,去掉低次幂项和系数的目的是为了关注算法的渐进行为,而不是关注具体输入大小或常数因子。这是因为算法的性能分析的主要关注点是如何随着输入规模的增长而变化,而不是具体的绝对性能。

去掉系数的原因是,系数通常取决于具体的实现、硬件、编程语言等因素,它们并不是算法本身的性质。通过去掉系数,我们可以更好地比较不同算法之间的性能,而不受特定实现的影响。

例如,如果有两个算法,一个算法A的运行时间是3n,另一个算法B的运行时间是1000n,如果我们只关注系数,似乎算法A更好。但如果我们去掉系数,它们的运行时间都是O(n),这意味着它们在输入规模增加时的性能表现是相同的。

因此,去掉系数和低次幂项是为了提供一种更通用、更抽象的方式来比较和分析不同算法的性能,以便更好地理解它们如何在大规模输入下表现。这有助于选择最适合特定问题的算法,而不受具体实现或硬件的限制。

常见的渐进时间复杂度排序

常见的渐进时间复杂度从小到大依次是:

1. O(1) —— 常数时间复杂度:
表示算法的执行时间是一个常数,不随问题规模的增加而变化。这通常是一些基本操作,如赋值、比较、算术运算等的执行时间。

2. O(log n) —— 对数时间复杂度:
表示算法的执行时间与问题规模的对数成正比。常见的例子是二分查找算法,其中问题规模每次减半。

3. O(n) —— 线性时间复杂度:
表示算法的执行时间与问题规模成线性关系。例如,对一个包含 n 个元素的数组进行线性扫描的操作。

4. O(n log n) —— 线性对数时间复杂度:
表示算法的执行时间介于线性时间和平方时间之间,通常出现在一些高效的排序算法中,如快速排序和归并排序。

5. O(n^2) —— 平方时间复杂度:
表示算法的执行时间与问题规模的平方成正比。通常出现在嵌套循环的情况下,如选择排序和插入排序。

6. O(n^k) —— 多项式时间复杂度:
表示算法的执行时间与问题规模的 k 次方成正比。k 可能是大于 2 的正整数,这意味着算法在大规模数据上的性能下降较快。

7. O(2^n) —— 指数时间复杂度:
表示算法的执行时间以指数方式增长,通常出现在某些穷举算法或递归算法中。

8. O(n!) —— 阶乘时间复杂度:
表示算法的执行时间与问题规模的阶乘成正比。这是一种极端情况,通常只出现在极其低效的算法中,对于大规模问题来说几乎不可行。

9. O(n^n) —— 指数级时间复杂度:

表示算法的执行时间与问题规模的 n 的 n 次方成正比。这是一种非常高的时间复杂度,通常只出现在极其低效的算法中,对于大规模问题来说几乎不可行。这种时间复杂度通常表明算法的性能随着问题规模的增加而急剧下降。

选择适当的时间复杂度是算法设计中的关键步骤,我们需要综合考虑问题规模、可用资源以及问题的特点。

通常,我们希望选择时间复杂度较低的算法,以在处理大规模数据时获得更高的效率。

然而,你需要记住,时间复杂度只是一个理论估计,实际的性能还受到硬件、编程语言、编译器等因素的影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 请求https的私有证书验证

一、方案描述 我这里采用RestTemplate的方式调用https请求&#xff0c;请求第三方接口获取数据&#xff0c;证书由第三方私自签发的证书&#xff0c;我们构建的是一个springboot的API项目。 1.pom文件引入jar <dependencies><dependency><groupId>org.spr…

【LeetCode】剑指 Offer <二刷>(6)

目录 题目&#xff1a;剑指 Offer 12. 矩阵中的路径 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 13. 机器人的运动范围 - 力扣&#…

自然语言处理(七):来自Transformers的双向编码器表示(BERT)

来自Transformers的双向编码器表示&#xff08;BERT&#xff09; BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种预训练的自然语言处理模型&#xff0c;由Google于2018年提出。它是基于Transformer模型架构的深度双向&#xff0…

JavaScript基础知识总结

目录 一、js代码位置 二、变量与数据类型 1、声明变量 2、基本类型&#xff08;7种基本类型&#xff09; 1、undefined和null 2、String ⭐ 模板字符串&#xff08;Template strings&#xff09; 3、number和bigint ⭐ 4、boolean ⭐ 5、symbol 3、对象类型 1、Fun…

Google云数据库的“Enterprise“和“Enterprise Plus“版怎么选

最近&#xff0c;Google Cloud SQL&#xff08;Google云上的RDS&#xff09;做了一次大的产品调整与发布&#xff1a;将原来的Cloud SQL分为了两个版本&#xff0c;分别为"Enterprise"和"Enterprise Plus"版本。本文概述了两个版本的异同&#xff0c;以帮助…

【论文爬虫】自动将论文详细信息直送notion并自动下载(含源码)

输入论文标题&#xff0c;本爬虫将自动在semanticscholar.com和arxiv.com搜索该文章&#xff0c;自动获取其日期、作者、url、摘要等信息&#xff0c;并自动发送到你提前设置好的notion数据库里&#xff0c;同时自动从arxiv下载论文&#xff0c;然后将论文的保存地址在notion页…

Python算法练习 9.11

leetcode 392 判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcd…

mysql文档--myisam存储引擎--myisam引擎全解--底层探索

阿丹&#xff1a; myisam存储引擎与innodb存储引擎战争&#xff0c;在mysql中5.5.5之前myisam还是mysql的默认存储引擎但是在5.5.5版本之后被innodb反超。 官方解释&#xff1a; MyISAM是MySQL的默认数据库引擎&#xff08;5.5版之前&#xff09;&#xff0c;由早期的ISAM所改…

时间复杂度与空间复杂度详解

时间复杂度与空间复杂度详解&#x1f996; 一、算法效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度 二、时间复杂度2.1 时间复杂度的定义2.2 大O的渐进表示法2.3 如何记录表示算法复杂度 三、空间复杂度3.1 空间复杂度的定义3.2 小试牛刀 一、算法效率 1.1 如何衡量一个算法…

PlantUML——类图(持续更新)

前言 在分析代码流程中&#xff0c;我们常常会使用到各种UML图&#xff0c;例如用例图、时序图和类图等&#xff0c;以往使用ProcessOn或亿图图示等工具&#xff0c;但是这些工具难以规范化&#xff0c;有没有一种用代码来生成图形的工具呢&#xff1f; 刚好在出差的晨会中机缘…

Day 36 贪心算法 part05 : 435. 无重叠区间 763.划分字母区间 56. 合并区间

56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;inte…

springboot MongoDB 主从 多数据源

上一篇&#xff0c;我写了关于用一个map管理mongodb多个数据源&#xff08;每个数据源&#xff0c;只有单例&#xff09;的内容。 springboot mongodb 配置多数据源 临到部署到阿里云的测试环境&#xff0c;发现还需要考虑一下主从的问题&#xff0c;阿里云买的数据库&#x…

华为OD:VLAN资源池

题目描述&#xff1a; VLANO 是一种对局域网设备进行逻辑划分的技术&#xff0c;为了标识不同的VLAN&#xff0c;引入VLAN ID(1-4094之间的整数)的概念。 定义一个VLAN ID的资源池&#xff08;下称VLAN资源池&#xff09;&#xff0c;资源池中连续的VLAN用开始VLAN-结束VLAN表…

vue+springboot+mysql的垃圾分类管理系统

1、引言 设计结课作业,课程设计无处下手&#xff0c;网页要求的总数量太多&#xff1f;没有合适的模板&#xff1f;数据库&#xff0c;java&#xff0c;python&#xff0c;vue&#xff0c;html作业复杂工程量过大&#xff1f;毕设毫无头绪等等一系列问题。你想要解决的问题&am…

离散性行业介绍及与MES系统的好处

离散型行业是指那些生产、制造或提供一种有形产品或明确定义的服务的行业&#xff0c;这些产品或服务通常可以分为离散的单位&#xff0c;而且它们的生产通常遵循一定的工序或流程。与连续型行业不同&#xff0c;离散型行业的生产过程通常是间断的&#xff0c;而不是连续的。 …

什么是lockbit勒索病毒,中了勒索病毒怎么办?勒索病毒解密,数据恢复

lockbit是一种勒索病毒&#xff0c;是一种极具破坏性的电脑病毒&#xff0c;它利用加密技术来锁定用户文件&#xff0c;并以此为条件向用户勒索钱财。lockbit病毒的传播方式有通过电子邮件附件、恶意网站、点对点网络等多种途径进行传播。这种病毒一旦侵入电脑系统&#xff0c;…

vite搭建vue3项目

参考视频 1.使用npm搭建vite项目,会自动搭建vue3项目 npm create vitelatest yarn create vite2.手动搭建vue3项目 创建一个项目名称的文件夹执行命令&#xff1a;npm init -y 快速的创建一个默认的包信息安装vite: npm i vite -D -D开发环境的依赖 安装vue,现在默认是vue3.…

【计算机视觉 | 目标检测 | 图像分割】arxiv 计算机视觉关于目标检测和图像分割的学术速递(9 月 11 日论文合集)

文章目录 一、检测相关(1篇)1.1 SegmentAnything helps microscopy images based automatic and quantitative organoid detection and analysis 二、分割|语义相关(4篇)2.1 AMLP:Adaptive Masking Lesion Patches for Self-supervised Medical Image Segmentation2.2 Grouping…

C++数据结构--红黑树

目录 一、红黑树的概念二、红黑树的性质三、红黑树的节点的定义四、红黑树结构五、红黑树的插入操作参考代码 五、代码汇总 一、红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过…

MySQL——笔试测试题

解析&#xff1a; 要查询各科目的最大分数&#xff0c;可以使用如下的SQL语句&#xff1a; SELECT coursename, MAX(score) FROM t_stuscore GROUP BY coursename; 这条SQL语句使用了MAX()聚合函数来获取每个科目的最大分数&#xff0c;并使用GROUP BY子句按照科目进行分组…