软件设计师(八)算法设计与分析

算法被公认为是计算机科学的基石,算法理论研究的是算法的设计技术和分析技术。

一、算法设计和分析的基本概念

1、算法 (Algorithm)

算法:是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作。

一个算法有5 个重要特性:有穷性、确定性、可行性、输入、输出。

2、算法设计

算法设计技术,也称算法设计策略。

经常采用的算法设计技术主要有分治法、动态规划法、贪心法、回溯法、分支限界法、概率算法、近似算法。

3、算法分析

求解一个问题可能会有多种算法可以选择,选择的主要标准首先是算法的正确性、可靠性、简单性和易理解性,其次是算法的时间复杂度和空间复杂度要低,这是算法分析技术的主要内容。

算法分析是指对一个算法所需要的资源进行估算,这些资源包括内存、通信带宽、计算机硬件和时间等,所需要的资源越多,该算法的复杂度就越高。

复杂度分析主要包括时间复杂度和空间复杂度分析。

4、算法的表示

常用的表示算法的方法有自然语言、流程图、程序设计语言和伪代码等

二、算法分析基础

1、时间复杂度

算法的时间复杂度分析主要是分析算法的运行时间, 即算法执行所需要的基本操作数。

将算法的时间复杂度分析分为 3 种情况。

  • 最佳情况:
    使算法执行时间最少的输入。
  • 最坏情况
    使算法执行时间最多的输入。
  • 平均情况
    算法的平均运行时间

下式给出了一般算法在平均情况下的复杂度分析。
T ( n ) = ∑ i = 1 m p i ∗ t i T(n) = \displaystyle\sum_{i=1}^{m} p_i* t_i T(n)=i=1∑mpi∗ti

其中, p i p_i pi表示第 i i i类输入发生的概率; t i t_i ti 表示第 i i i类输入的执行时间,输入分为 m m m 类.

2、渐进符号

a n 2 + b n + c an^2 +bn+c an2+bn+c,仅考虑 n 2 n^2 n2

当输入规模大到只有与运行时间的增长量级有关时,就是在研究算法的渐进效率。也就是说,从极限角度看,只关心算法运行时间如何随着输入规模的无限增长而增长。

下面简单介绍 3 种常用的标准方法来简化算法的渐进分析:

  • O O O记号:用该记号给出一个算法运行时间的渐进上界。
  • Ω \Omega Ω记号:用该记号给出一个算法运行时间的渐进下界。
  • Θ \Theta Θ记号:用该记号给出一个算法运行时间的渐进上界和渐进下界,即渐进紧致界


    10 n 2 + 4 n + 2 10n^2 +4n+2 10n2+4n+2,仅考虑 n 2 n^2 n2,
    O O O是算法运行时间的渐进上界,比 n 2 n^2 n2大的满足
    Ω \Omega Ω是算法运行时间的渐进下界,比 n 2 n^2 n2小的满足
    Θ \Theta Θ是算法运行时间的渐进紧致界, n 2 n^2 n2满足

3、递归式

从算法的结构上看,算法可以分为非递归形式和递归形式。

递归形式的方法:

(1)展开法

将递归式中等式右边的项根据递归式进行替换,称为展开。展开后的项被再次展开,如此下去,直到得到一个求和表达式,得到结果

(2)代换法

这一名称来源于当归纳假设用较小值时,用所猜测的值代替函数的解。在用代换法解递归式时需要 3 个步骤:猜测解的形式;用数学归纳法证明猜测的正确性;求出使解真正有效的常数。

(3)递归树法

在递归树中,每一个结点都代表递归函数调用集合中一个子问题的代价。将树中每一层内结点的代价相加得到一个每层代价的集合,再将每层的代价相加得到递归式所有层的总代价。当用递归式表示分治算法的时间复杂度时,递归树方法尤其有用。

(4)主方法

主方法也称为主定理,给出了求解以下形式的递归式的快速方法

三、分治法

1、递归的概念

递归是指子程序 (或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的常用方法。
递归,就是在运行的过程中调用自己

递归有两个基本要素:

边界条件,即确定递归到何时终止,也称为递归出口;

递归模式,即大问题是如何分解为小问题的,也称为递归体。

2、分治法的基本思想

分治法的设计思想是将一个难以直接解决的大问题分解成一些规模较小的相同问题,以便各个击破,分而治之。

分治法产生的子问题往往是原问题的较小模式,这就为递归技术提供了方便。

一般来说,分治算法在每一层递归上都有 3 个步骤。

  1. 分解。将原问题分解成一系列子问题。
  2. 求解。递归地求解各子问题。若子问题足够小,则直接求解.
  3. 合并。将子问题的解合并成原问题的解。

使用场景

  • 该问题的规模缩小到一定的程度就可以容易地解决
  • 该问题可以分解为若干个规模较小的相同问题
  • 利用该问题分解出的子问题的解可以合并为该问题的解
  • 该问题所分解出的各个子问题是相互独立的

3、分治法的典型实例

归并排序算法是成功应用分治法的一个完美的例子,其基本思想是将待排序元素分成大小大致相同的两个子序列,分别对这两个子序列进行排序,最终将排好序的子序列合并为所要求的序列。归并排序算法完全依照上述分治算法的 3 个步骤进行。

四、动态规划法

1、动态规划法的基本思想

基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

与分治法不同的是,适合用动态规划法求解的问题,经分解得到的子问题往往不是独立的。如果能够保存已解决的子问题的答案,在需要时再找出已求得的答案,这样就可以避免大量的重复计算。可以用一个表来记录所有已解决的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。

动态规划算法通常用于求解具有某种最优性质的问题。

设计动态规划算法,按照以下几个步骤进行:

  1. 找出最优解的性质,并刻画其结构特征
  2. 递归地定义最优解的值。
  3. 以自底向上的方式计算出最优值
  4. 根据计算最优值时得到的信息,构造一个最优解

对于一个给定的问题,若其具有以下两个性质,可以考虑用动态规划法来求解。

  1. 最优子结构
  2. 重叠子问题

2、动态规划法的典型实例

0-1背包问题

最长公共子序列(LCS)

五、贪心法

1、贪心法的基本思想

贪心法也经常用于解决最优化问题。

贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优。

举一个简单的贪心法例子,平时购物找钱时,为使找回的零钱的硬币数最少,从最大面值的币种开始,先尽量用大面值的币种,当不足大面值币种的金额时才去考虑下一种较小面值的币种,这就是在采用贪心法。如果只有面值分别为 1、5 和 11 单位的硬币,而希望找回总额为 15 单位的硬币,按贪心算法,应找 1 个 11 单位面值的硬币和 4 个1 单位面值的硬币,共找回5个硬币。但最优的解答应是 3 个 5 单位面值的硬币。

采用贪心法的两个性质:

  1. 最优子结构
  2. 贪心选择性质

2、贪心法的典型实例

多个活动占用教室资源

[定理 8.3] 对于任意非空子问题 S i j S_ij Sij,设 a m a_m am是 S i j S_ij Sij中具有最早结束时间的活动。那么,(1) 活动 a m a_m am在 S i j S_ij Sij的某个最大兼容活动子集中。(2)子问题 S i j S_ij Sij为空,所以选择 a m a_m am将使 S m j S_mj Smj为唯一可能非空的子问题

六、回溯法

回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当搜索到某步时,发现原先选择并不优或达不到目标,就退回一步重新选择。这种走不通就退回再走的技术就是回溯法。

  • 回溯法有"通用的解题法"之称,可以系统地搜索一个问题的所有解或任一解,是一个既带有系统性又带有跳跃性的搜索算法。

  • 过程:它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先的策略进行搜索。

  • 回溯法在用来求问题的所有解时要回溯到根,且根结点的所有子树都已被搜索遍才结束。而用来求问题的任一解时,只要搜索到问题的一个解就可以结束。

  • 这种以深度优先的方式系统地搜索问题的解的方法称为回溯法,它适用于解一些组合数较大的问题。

1、回溯法的算法框架

(1)问题的解空间

在应用回溯法解问题时,首先应明确定义问题的解空间。问题的解空间应至少包含问题的一个(最优) 解。

定义了问题的解空间后,还应将解空间很好地组织起来,使得用回溯法能方便地搜索整个解空间。通常将解空间表示为树或图的形式。例如,对于 m=3 时的 0-1 背包问题,其解空间用一棵完全二又树表示

(2)回溯法的基本思想

在确定了解空间的组织结构后,回溯法从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前扩展结点处不能再向纵深方向移动,则当前的扩展结点就成为死结点。此时,应往回移动(回溯) 至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索,直到找到所要求的解或解空间中已无活结点时为止。

综上所述,运用回溯法解题通常包含以下 3 个步骤

  1. 针对所给问题,定义问题的解空间。
  2. 确定易于搜索的解空间结构。
  3. 以深度优先的方式搜索解空间

(3)回溯法的算法框架

回溯法的算法框架有非递归和递归两种方式。

(4)回溯法的限界函数

问题的解空间往往很大,为了有效地进行搜索,需要在搜索的过程中对某些结点进行剪枝,而对哪些结点进行剪枝,需要设计限界函数来判断。因此,限界函数的设计是回溯法的一个核心问题,也是一个很难的问题。

设计限界函数的通用的指导原则是尽可能多和尽可能早地"杀掉"不可能产生最优解的活结点。

2、回溯法的典型实例

七、分支限界法

分支限界法类似于回溯法,也是一种在问题的解空间树 T T T上搜索问题解的算法。

活节点队列,当向下查询后,本身从活节点队列中去除。

回溯法 分支限界法
求解目标 找出T中满足约束条件的所有解 找出满足约束条件的最优解
搜索方式 深度优先 广度优先或最小耗费优先
搜索策略 可以回溯 每一个活结点只有一次机会成为扩展结点
核心问题(相同) 限界函数的设计 限界函数的设计

根据从活结点表中选择下一扩展结点的不同方式,将分支限界法分为两种:

  1. 队列式(FIFO,先进先出)分支限界法
  2. 优先队列式分支限界法:结点优先级

八、概率算法

一般情况下,概率算法具有以下基本特征。

  1. 概率算法的输入包括两部分,一部分是原问题的输入,另一部分是一个供算法进行随机选择的随机数序列。
  2. 概率算法在运行过程中,包括一处或多处随机选择,根据随机值来决定算法的运行路径。
  3. 概率算法的结果不能保证一定是正确的,但能限制其出错概率。
  4. 概率算法在不同的运行过程中,对于相同的输入实例可以有不同的结果,因此,对于相同的输入实例,概率算法的执行时间可能不同。

概率算法大致分为 4类:

  • 数值概率算法
    数值概率算法常用于数值问题的求解。这类算法得到的往往是近似解,且近似解的精度随计算时间的增加不断提高。
  • 蒙特卡罗 (Monte Carlo) 算法
    蒙特卡罗算法用于求问题的精确解。
  • 拉斯维加斯(LasVegas) 算法
    拉斯维加斯算法不会得到不正确的解。
  • 舍伍德 (Sherwood) 算法
    舍伍德算法总能求得问题的一个解,且所求得的解总是正确的

九、近似算法

1、基本思想

放弃求最优解,而用近似最优解代替最优解,以换取算法设计上的简化和时间复杂度的降低。

2、过程

虽然它可能找不到一个最优解,但它总会给待求解的问题提供一个解。为了具有实用性,近似算法必须能够给出算法所产生的解与最优解之间的差别或者比例的一个界限,它保证任意一个实例的近似最优解与最优解之间相差的程度。显然,这个差别越小,近似算法越具有实用性。

3、衡量近似算法性能的标准

  • 算法的时间复杂度
    近似算法的时间复杂度必须是多项式阶的,这是近似算法的基本目标
  • 解的近似程度
    近似最优解的近似程度也是设计近似算法的重要目标。近似程度与近似算法本身、问题规模,乃至不同的输入实例有关。

十、数据挖掘算法

1、数据挖掘概述

数据挖掘利用机器学习方法对多种数据,包括数据库数据、数据仓库数据、Web 数据等进行分析和挖掘。

数据挖掘的核心是算法,其主要功能包括分类、回归、关联规则和聚类等。

2、分类

分类是一种有监督的学习过程,根据历史数据预测未来数据的模型。

分类的数据对象属性分为两类,一般属性和分类属性或者目标属性。

对数据分类有两个步骤:学习模型和应用模型,在分类过程中,涉及到的数据包括训练数据集、测试数据集和未知数据。

  • 学习模型是指基于训练数据集采用分类算法建立学习模型。
  • 应用模型是指应用测试数据集的数据到学习模型中,根据输出来评估模型的好坏以及将未知数据输入到学习模型中,预测数据的类型。
    存有多种分类算法:
  • 决策树归纳
  • 朴素贝叶斯算法和贝叶斯信念网络
  • 后向传播(BP)
  • 支持向量机(SVM)

可以用混淆矩阵来评估分类模型的质量.

3、频繁模式和关联规则挖掘

挖掘海量数据中的频繁模式和关联规则可以有效地指导企业发现交叉销售机会、进行决策分析和商务管理等。

4、聚类

聚类是一种无监督学习过程。根据数据的特征,将相似的数据对象归为一类,不相似的数据对象归到不同的类中,这就是聚类,每个聚类也称为簇。"物以类聚,人以群分"就是聚类的典型描述。

聚类的典型算法有:基于划分的方法、基于层次的方法、基于密度的方法、基于网格的方法和基于统计模型的方法。

说明 算法
基于划分的方法 基于划分的方法将 n 个数据对象划分为 k 个不相交的集合,每个集合称为一个簇 典型的算法有 k-均值、k-中心点算法等
基于层次的方法 将数据对象集进行层次的分解。根据其是自底向上还是自顶向下分解,可以分为凝聚的方法和分裂的方法。 AGNES、DIANA
基于密度的方法 基于数据对象的邻域来进行聚类分析,因此可以识别各种形状的簇,以及一个数据对象可以属于多个不同的簇 DBSCAN、OPTICS 和 DENCLUE
基于网格的方法 把对象空间量化为有限个单元,形成一个网格结构。 STING、CLIQUE
基于统计模型的方法 将数据对象集看作多个服从不同分布的数据集构成,聚类的目的是识别出这些不同的分布的数据对象 EM

十一、智能优化算法

优化技术是一种以数学为基础,用于求解各种工程问题优化解的应用技术。

包括人工神经网络、混沌、遗传算法、进化规划、模拟退火、禁忌搜索及其混合优化策略等。

人工神经网络(ANN)是一个以有向图为拓扑结构的动态系统,它通过对连续或断续的输入作状态响应而进行信息处理。

模拟退火算法(SA)是一种求解全局优化算法。模拟退火算法的基本思想来源于物理退火过程、所谓物理退火过程包括 3 个阶段:加温阶段、等温阶段、冷却阶段。

禁忌搜索算法(TS)是模拟人类智力过程的一种全局搜索算法,是对局部邻域搜索的一种扩展。

相关推荐
xiaoshiguang39 分钟前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡11 分钟前
【C语言】判断回文
c语言·学习·算法
别NULL13 分钟前
机试题——疯长的草
数据结构·c++·算法
TT哇17 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
yuanbenshidiaos2 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习2 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo2 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc2 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
游是水里的游3 小时前
【算法day20】回溯:子集与全排列问题
算法