《趣题学算法》—第0章0.5节算法分析

简介:

本节书摘来自异步社区《趣题学算法》一书中的第0章0.5节算法分析,作者徐子珊,更多章节内容可以访问云栖社区“异步社区”公众号查看。

0.5 算法分析
解决同一问题的不同算法所消耗的计算机系统的时间(占用处理器的时间)和空间(占用内部存储器空间)资源量可能有所不同。算法运行所需要的资源量称为算法的复杂性。一般来说,解决同一问题的算法,需要的资源量越少,我们认为越优秀。计算算法运行所需资源量的过程称为算法复杂性分析,简称为算法分析。理论上,算法分析既要计算算法的时间复杂性,也要计算它的空间复杂性。然而,算法的运行时间都是消耗在已存储的数据处理上的,从这个意义上说,算法的空间复杂性不会超过时间复杂性。出于这个原因,人们多关注于算法的时间复杂性分析。本书中除非特别说明,所说的算法分析,局限于对算法的时间复杂性分析。

算法的运行时间,就是执行基本操作的次数。所谓基本操作,指的是计算机能直接执行的最简单的不可再分的操作。例如对数据进行的算术运算和逻辑运算,以及将数据存储于内存的某个单元。考虑算法0-1,当序列A的元素个数为N时:

GET-THE-INVERSION(A) 
1 N← length[A]                             耗时1个单位
2 count←0                                  耗时1个单位
3 for j← N downt o 2                       耗时N个单位
4   do for i←1 to j-1                      耗时=N(N+1)/2-1个单位
5        do if A[i]>A[j]                   耗时=N(N+1)/2个单位    
6              then count←count+1          耗时不超过=N(N+1)/2个单位
7 return count                      +)    耗时1个单位         
                                           3N2/2+N/2+2

具体地说,第1、2、7行各消耗1个单位时间,总数为3,第3行做N次j与2的比较耗时N,第4行作为外层循环的循环体中一个操作,每次被执行时做j次i与j−1的比较,所以总耗时为N+(N−1)+…+2=N(N+1)/2-1。相仿地,第5、6行作为内层循环的循环体每次被重复j−1次,但它们也在外层循环的控制之下,所以两者的耗时为2(1+ 2+…+N−1)=N(N−1)。把它们相加得到

N+3+N(N+1)/2-1+N(N-1)

                 =N+2+N2/2+N/2+N2-N

                 =3N2/2+N/2+2

一般而言,算法的时间复杂性与输入的规模(算法0-1中序列A的元素个数)相关。规模越大,需要执行的基本操作就越多,当然运行时间就越长。此外,即使问题输入的规模一定,不同的输入也会导致运行时间的不同。对固定的输入规模,使得运算时间最长的输入所消耗的运行时间称为算法的最坏情形时间。通常,人们以算法的最坏情形时间来衡量算法的时间复杂性,并简称为算法的运行时间。例如,在上述的算法0-1的分析中,第3~6行的嵌套循环的循环体的每次重复,第6行并非必被执行,所以我们说其耗时“不超过sumnolimits_{i=1}^{N-1}{i}=N(N+1)/2个单位”。但我们要考虑的是最坏情形时间,所以运行时间是按N(N+1)/2加以计算的。

对于算法的输入规模为n的运行时间,常记为T(n)。以算法0-1的GET-THE- INVERSION(A)过程为例,数组A[1..N]的元素个数N越大,运行时间T(N)=3N2/2+N/2+2的值就越大。

对算法0-2而言,设其对输入规模为N的运行时间为T(N)。

GET-THE-INVERSION(A, N) 
1 if N<2                              耗时1个单位
2     then return                     耗时不超过1个单位
3 for i←1 to N-1                      耗时N个单位
4     do if A[i]>A[N]                 耗时N-1个单位
5      then count←count+1             耗时不超过N-1个单位
6 GET-THE-INVERSION(A, N-1)      +)  耗时T(N-1)   
                                 T(N)=T(N−1)+3N-1

这是一个在等式两端都含有未知式T的方程,称为递归方程。递归方程可以用迭代法来解,即

T(N)=T(N-1)+3N-1

                =T(N-2)+3(N-1)+3N-2

                =T(N-3)+3(N-2)+3(N-1)+3N-3

                ……

                =T(1)+3*2+…+3(N-1)+3N-(N-1)

                =2+3(1+2+3+…+N)-3-N+1

                =3N(N+1)/2-N

                =3N2/2+N/2

显然,这算法0-1的运行时间大同小异。注意,式中的T(1)指的是算法0-2的第2个参数N=1时的运行时间。显然,这将仅执行其中1~2行的操作,耗时为2个单位。

相关文章
|
2月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
63 4
|
4月前
|
数据采集 机器学习/深度学习 算法
|
4月前
|
人工智能 算法 BI
第一周算法设计与分析 D : 两面包夹芝士
这篇文章介绍了解决算法问题"两面包夹芝士"的方法,通过找出两个数组中的最大最小值,计算这两个值之间的整数个数,包括特判不存在整数的情况。
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
3月前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
63 4
|
3月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
45 1
|
2月前
|
算法
PID算法原理分析及优化
【10月更文挑战第6天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
3月前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
141 19
|
4月前
|
算法
算法设计与分析作业
这篇文章是关于算法设计与分析的作业,其中包含了两个算法实现:一个是使用分治算法实现的十进制大整数相乘(包括加法、减法和乘法函数),并进行了正确性和健壮性测试;另一个是使用快速排序思想实现的分治查找第K小元素的程序,并分析了其平均和最坏时间复杂度。
算法设计与分析作业