《算法设计与分析》一一2.1 数学运算背后的算法操作

简介: 本节书摘来自华章出版社《算法设计与分析》一 书中的第2章,第2.1节,作者:黄宇 著 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.1 数学运算背后的算法操作

虽然我们已经熟知很多数学概念与性质,但是从算法设计与分析的角度来看,还需要进一步将这些数学的概念与算法的运作联系起来。下面就从这一角度来讨论几组算法设计与分析中常用的数学概念与性质。
2.1.1 取整x和x
我们熟知取整函数的定义:下取整函数x表示不超过x的最大整数;上取整函数x表示不小于x的最小整数。需要取整函数的本质原因在于算法分析中涉及的一些量往往是某种离散对象的个数,它必然是正整数。例如,算法的代价是关键操作的个数,问题的规模经常表示为输入元素的个数、输入数值的比特数等。但是算法分析所需的一些数学函数,其结果却不一定是整数。此时我们经常需要使用取整函数使得结果的表述是准确的。
例如在折半查找中(参见9.1节算法32),当对数组A[1..n]进行折半时,中点大致在n+12的位置。但是精确来说,折半的位置是数组的某个下标,其必然为整数。所以我们可以借助取整函数,将折半的位置严格表示为n+12或者n+12。再如,在进行合并排序(参见6.2节)的时候,问题的规模不断缩小到原来的12。大致经过log2n次递归,问题规模降低到大小为1的基础情况(base case)。因为递归的次数必然是一个正整数,严格地讲是经过了log2n次递归,问题的规模缩小到1。
2.1.2 对数log n
对数logab的概念大家是熟悉的。需要特别提醒的是,对数符号的使用由于不同领域习惯的不同经常带来一些歧义。在本书中,我们用log n 表示log2n,用lnn表示自然对数logen,用lg n表示常用对数log10n。在算法设计与分析中,至少3类重要的算法操作与对数log n紧密关联,并且通过分析我们发现这3类算法操作之间也有着本质的联系。
●折半:当划分规模为n的问题的时候,大约经过log n次划分,问题规模会降到规模为常数的基础情况。不同的划分方法(如两等分、三等分或者不均匀的某种划分)、不同的基础情况(基础情况的规模可能是1也可能是稍大的某个常数值),其结果会有细节上的不同,但是具体的值总是log n乘以某个系数。
●二叉树:一个n个节点的完美二叉树(定义见附录B),它的高度为log n。对于更一般的情况,一棵平衡二叉树的高度大致为log n  ≌饫锏摹捌胶狻笔且桓霾皇 分精确的概念,进一步的讨论可以参考9.2节平衡二叉搜索树的例子和10.2.2节平衡根树的例子。  ?
平衡二叉树的高度和上面讨论的“折半至基础情况的次数”之间有紧密的联系。为了简化讨论,我们考虑完美二叉树。一个有n个节点的完美二叉树有n+12个叶节点,即大约有一半的节点为叶节点。当去掉树中所有的叶节点时,从高度的角度看,树的高度减少1;从节点数目的角度看,节点数目减少一半。因此完美二叉树的高度与折半至基础情况的次数均为log n。更进一步,如果按层从上到下,每层从左到右将完美二叉树的节点分别标为1,2,3,4…,如图2.1所示,则二叉树的分层可以看作对正整数的一个等价类划分,而log n 是划分的依据:1|2,3|4,5,6,7|8,9,…,15|16…上述的整数划分可以帮助我们得出一些与对数、取整函数相关的更深入的结论(如习题2.2),而这些结论会在分析相关算法的过程中发挥重要的作用。
●二进制数的比特数:一个十进制的自然数n的二进制表示所需的比特数为log n+1。这跟前面讨论的折半同样有着密切的关联。当我们将一个二进制数右移一位时,从二进制表示的角度看,比特数减1;从数值的角度看,数值变为原来的12。因此整数n二进制表示的比特数,也就大致等于将n折半至基础情况的次数,即log n。
图2.1 完美二叉树节点按层标号
2.1.3 阶乘n!
对于n个不同的元素,其全排列的个数为n!,而对排列的计数在算法设计与分析中有着诸多应用。例如,对于待排序的n个元素,它们输入时的初始顺序是这些元素所有n!种排列中的某一种,而它们排好序后的结果,也是所有排列中的某一种。对于n个不同元素的排序,如果假设所有可能的输入等概率出现,则每种输入出现的概率为1n!。
阶乘是一个连乘形式,如果对它取对数则变成求和形式,而连乘和求和都不易处理。为此,我们可以利用Stirling公式,将阶乘转换成更易于处理的闭形式。具体而言,对于n≥1,有:2πnnen表2.1 Stirling公式的误差
近似 n≥1 n≥10 n≥100 n≥10002πnnen <10%< 1% <0.1%<0.01% 2πnnene112n <1%<0.01 % <0.0001%<0.000001%
2.1.4 常见级数求和∑ni=1f(i)
求和与算法分析的关系非常紧密。算法经常需要反复对输入的元素进行处理,如多轮的循环或者递归,而多轮处理中关键操作的计数往往体现为某种级数的求和。算法的平均情况时间复杂度的定义本身就是级数求和的形式。为此,熟练掌握一些常用数列的求和对算法分析是很有必要的。
●多项式级数(polynomial series):我们分别给出3组多项式级数,其中一次方的情况是大家熟知的算术级数(arithmetic series);k次方的情况对于算法设计与分析来说,更有用的是记住其使用Θ记号(详见2.2节的定义)表述的结果。∑ni=1i=n(n+1)2
∑ni=1i2=13nn+12(n+1)
∑ni=1ik=Θ1k+1nk+1
●几何级数(geometric series):一般形式为:∑ki=0ari=ark+1-1r-1它的两个常用的特例是a=1,r=2或者12的情况:∑ki=012i=2-12k
∑ki=02i=2k+1-1与多项式级数类似的是,在算法分析中我们需要记住几何级数使用Θ记号的形式:∑ki=0ari=Θ(rk)其直观含义是,公比不等于1的几何级数的和(的渐近增长率)就等于最大的那一项,其余项均可以忽略。
●算术几何级数(arithmetic-geometric series):∑ki=1i・2i=(k-1)2k+1+2
●调和级数(harmonic series):∑ki=11i=lnk+γ+εk这里γ是欧拉常数;εk是一个小量,它近似为12k,且随着k的增加而趋于0。
●斐波那契数列(Fibonacci numbers):Fn=Fn-1+Fn-2,n≥2
F0=0,F1=1斐波那契数列的第n项为:Fn=151+52n-1-52n2.1.5 期望E[X]
随机变量及其期望值的概念与算法分析有着本质的关联。算法的平均情况时间复杂度的定义就是一种期望值。正如我们在1.3.3节所定义的,算法的复杂度是一个随机变量,对于不同的输入复杂度是不同的。如果知道算法输入的概率分布,进而计算出算法复杂度的概率分布,则我们可以将算法复杂度的期望值定义为算法的平均情况时间复杂度。
根据对抽象算法分析的讨论,我们知道算法的代价是通过对关键操作的执行进行计数而得出的。如果集中关注单个关键操作的执行情况,则可以为之引入一类特别的随机变量:指标随机变量(indicator random variable)。指标随机变量与某个随机事件e相关联,其定义如下所示。
定义2.1(指标随机变量)Xi=I{事件ei}=1,事件ei发生
0,事件ei未发生很容易验证,指标随机变量的期望值E[Xi]就等于事件ei发生的概率。
指标随机变量在分析算法的平均情况时间复杂度的过程中有广泛的应用。以基于比较的排序算法为例,假设有待排序元素Z={z1,z2,…,zn}。我们定义指标随机变量Xij=I{zi和zj发生了比较},则排序的代价可以用指标随机变量表示为:X=∑n-1i=1∑nj=i+1Xij进而排序算法的平均情况时间复杂度可以表示为:E[X]=E∑n-1i=1∑nj=i+1Xij基于指标随机变量的帮助,我们就将分析算法平均情况时间复杂度的问题变成了求一个复杂随机变量的期望值的问题。该期望值的直接求解往往是困难的,但是基于期望值的线性特征(linearity of expectation),我们可以显著地简化这一问题。
定理2.1 (期望值的线性特征) 给定任意随机变量X1,X2,…,Xk和它们的线性函数h(X1,X2,…,Xk),我们有:E[h(X1,X2,…,Xk)]=h(E[X1],E[X2],…,E[Xk])需要特别强调的是,这里的任意k个随机变量,无论它们是否独立,上述等式均成立。最常用的多个随机变量的线性函数就是它们的求和,即:E∑ni=1xi=∑ni=1E[xi]基于期望值的线性特征,我们可以进一步推进上述排序算法的分析:E[X]=E∑n-1i=1∑nj=i+1Xij
=∑n-1i=1∑nj=i+1E[Xij]
=∑n-1i=1∑nj=i+1Pr{zi和zj发生了比较}这样,我们就把一个复杂随机变量的期望值的分析分解成了单个(和关键操作紧密相关的)随机事件发生概率的分析。结合具体算法的具体情况,我们可以分析这些关键操作相关的事件发生的概率,再通过级数求和最终得出算法的平均情况时间复杂度。我们将在6.1.3节使用这一方法对快速排序的平均情况时间复杂度进行深入分析。

相关文章
|
3月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
104 3
|
14天前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
62 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
15天前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
24天前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
33 6
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
79 1
|
3月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
3月前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
4月前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
78 4
|
4月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
86 1
|
4月前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
273 19

热门文章

最新文章