zoukankan      html  css  js  c++  java
  • 算法设计与分析 概念复习

    概念,知识汇总

    一 算法的概念

    解决一个计算问题的过程:

    判断能计算否, 判断能行计算否, 算法设计与分析,用编程语言实现算法,在计算机系统上运行算法

    计算 : 可由一个给定计算模型机械地执行的规则或计算步骤序列称为该计算模型的一个计算

    算法: 是一个满足下列5个条件的计算:

    1. 终止性:有限步内必须停止(有穷性)
    2. 确定性:每步都是严格定义和确定的动作
    3. 能行性:每个动作都能被精确地机械执行
    4. 输 入:具有满足给定约束条件的输入
    5. 输 出:产生满足给定约束条件的结果.

    问题: 一个问题是一个关系P subseteq Input× imesOutput.同时P也可以表示为以下形式

    P == {<a,b>aInput and bOutput<a,b>| a in Input and b in Output},即P表示为一个二元组集合

    问题实例: 问题P 的一个实例是P 的一个二元组. 二元组(<9,6,7,3>,< 3,6,7,9>)是 SORT 问题的一个实例

    问题和问题的实例的区别:

    1.问题是一个二元组集合,问题实例是一个二元组

    2.一个算法求解一个 完整的问题 ,而不是仅求解一个问题的一个或几个实例 .

    P类问题:能在多项式时间内可解的问题。(等价于: 确定性计算机”能够在“多项式时间”解决的所有问题.)

    NP类问题:在多项式时间内“可验证”的问题。(等价于: 非确定性计算机”能够在“多项式时间”解决的所有问题.)

    也就是说,不能判定这个问题到底有没有解,而是猜出一个解来在多项式时间内证明这个解是否正确。即该问题的猜测过程是不确定的,而对其某一个解的验证则能够在多项式时间内完成。P类问题属于NP问题,但NP类问题不一定属于P类问题。

    NPC问题:1.存在这样一个NP问题 2.所有的NP问题都可以约化成它。

    换句话说,只要解决了这个问题,那么所有的NP问题都解决了。

    NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。

    NP -Hard问题:所有的NP问题都可以约化成的问题.

    就是说,NP-Hard问题要比 NPC问题的范围广,NP-Hard问题没有限定属于NP

    Non-NP问题:在多项式时间内无法验证的问题.(等价于: 非确定计算机不能再多项式时间内求解的问题)

    NP难题”: 若一个问题在多项式时间内可验证, 那么它在多项式时间内是否一定可解?

    即证明或推翻P=NP

    算法分析

    1. 算法的正确性分析
    2. 算法的复杂性分析

    算法分析的目的:

    算法分析分为算法正确性分析和复杂性分析

    算法正确性分析确保算法对符合要求的输入在有限时间内能产生正确的结果

    算法的复杂性分析,分析算法对不同输入所需资源量,为求解一个问题选择最佳算法、最佳设备

    算法正确性: 一个算法是正确的,如果它对于每一个输入都最终停止,而且产生正确的输出.

    不正确的算法: 1.存在输入使其不停止 2.存在输入使其得出错误结果

    程序调试只能证明算法错误,不能证明算法正确

    如何证明算法的正确性:

    普通算法的正确性证明:1.对所有输入都停止 2.对所有输入都产生正确的结果

    近似/随机算法的正确性证明: 1.对所有输入都停止 2.对所有输入都产生近似正确/极少数不正确解

    算法的复杂度分析

    分析时间复杂度

    分析空间复杂度

    时间复杂度: 时间复杂度描述的是一个函数,该函数描述算法的运行时间随着问题规模的增长的变化情况

    空间复杂度: 空间复杂度描述的是一个函数,该函数描述算法占用内存空间随问题规模增长的变化情况

    实例的时间复杂度: 算法对特定输入产生结果所需要的的原子操作数

    实例的空间复杂度: 算法对特定输入产生结果所需要的储存空间大小

    问题的复杂性可研究那些方面?

    •固有复杂性
    •复杂性上 、 下界
    •平均复杂性
    •复杂性问题的分类 P=NP?
    •公理复杂性理论:抽象复杂性研究

    优化问题: 求解代价最小的可行解的问题

    一个问题的最优解不一定是唯一的
    举例:最短路径,旅行商、任务调度等问题
    因此我们也可以说:优化问题就是给定一个代价函数,在问题的解空间中搜索具有最小或最大代价的优化解

    问题的下界: 用于解决该问题的任意算法所需要的最小时间复杂度

    问题的下界是不唯一的, 通常指:最坏情况下界

    问题的下界的意义

    计算出问题的复杂度下界可以告诉我们当前算法是否最优,是否还可以优化

    排序的复杂度下界: Ω(n)

    通过比较的排序的复杂度下界: Ω(nlogn)

    循环不变量:数据或数据结构的关键性质

    循环不变量的证明:

    证明分三个阶段
    (1)初始 阶段 :循环开始前循环不变量成立
    (2)循环 阶段 :循环体每执行一次 循环不变量成立
    (3)终止 阶段 :算法结束后,循环不变量保证算法正确

    应用: 证明最长公共子序列, 凸壳 的正确性


    二 算法的数学基础

    计算函数的阶:

    1. 算法执行时间随问题规模增长而增长的阶(增长率).
    2. 执行时间函数的主导项

    同阶: 设f(n)和g(n)是正值函数。如果
    c1,c2&gt;0,n0,n&gt;n0,c1g(n)f(n)c2g(n)exist c1 , c 2 &gt;0, n_0 , forall n&gt;n_0 , c_1 g(n) le f(n) le c_2 g(n),则称f(n)与g(n)同阶,记作f(n)= θ heta(g(n)) 。

    低阶 : 设f(n)和g(n)是正值函数。如果$ exist c>0, n_0 , forall n>n_0 , f(n)le cg(n)$,则称f(n)比g(n)低阶或g( n )是 f ( n ) 的 上 界 , 记 作 f ( n ) = O ( g ( n ) ) 。

    高阶: 设f(n)和g(n)是正值函数。如果c&gt;0,n0,n&gt;n0,f(n)cg(n)exist c&gt;0, n_0 , forall n&gt;n_0 , f(n) ge cg(n),则称f(n)比g(n)高阶或g(n)
    是f(n)的下界,记作f(n)= ΩOmega (g(n)) 。

    严格低阶 设f(n)和g(n)是正值函数。如果c&gt;0,n0,n&gt;n0,f(n)&lt;cg(n)forall c&gt;0, exist n_0 , forall n&gt;n 0 , f(n)&lt;cg(n),则称f(n)严格比g(n)低阶或g(n)是f(n)的严格上界,记作f(n)=o(g(n)) 。

    严格高阶 设f(n)和g(n)是正值函数。如果$forall c>0, exist n_0 , forall n>n_0 , f(n)>cg(n) $,则称f(n)严格比g(n)高阶或g(n)是f(n)的严格下界,记作f(n)= ωomega (g(n)) 。

    解递归方程的3种方法:

    1. 替换方法:
      先猜测方程的解, 然后用数学归纳法证明 .
    2. 迭代方法:
      把方程转化为一个和式, 然后用估计和的方法来求解.
    3. Master方法:
      求解型为T(n)=aT(n/b)+f(n)的递归方程

    Master方法

    目的: 求解T(n)=aT(n/b)+f(n)T(n) = aT(n/b)+f(n)类型的方程, 要求a >=1 ,b >1 是常数, f(n)是正函数

    比较$f(n) 和 g(n) = n^{lg_ba} $的大小

    1. 若f(n) > g(n),且存在c, n 使得af(n/b) <= cf(n)恒成立, 则T(n)=θ(f(n))T(n) = heta (f(n))
    2. 若f(n) < g(n),则T(n)=θ(g(n))T(n) = heta (g(n))
    3. 若f(n),g(n)同阶,则T(n)=θ(f(n)logn)T(n) = heta (f(n)log n)
    4. 若f(n)与 (g(n)logkng(n)log^kn) 同阶则T(n)=θ(g(n)logk+1n)T(n) = heta (g(n)log^{k+1} n)

    三 分治算法

    思想

    当问题规模较大时不好解决,但当问题规模小到一定程度就十分容易的时候, 我们就将大问题分解成一系列小问题求解,然后合并小问题的解得到大问题的解.

    使用条件

    (1)该问题的规模缩小到一定的程度就可以容易地解决;
    (2)该问题可以分解为若干个规模较小的问题
    (3)利用该问题分解出的子问题的解可以合并为该问题的解;
    (4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

    设计:
    1. 问题划分: 将问题划分成一系列相似的子问题(子问题不一定相同)
    2. 递归求解: 递归地调用算法求解每个子问题
    3. 合并: 合并子问题的解得到整个问题的解
    分析:
    1. 分析每个步骤的复杂性
    2. 建立复杂性的递归方程
    3. 求解递归方程得到复杂性
    递归方程

    T(n)= O(1) if ncn le c // 边界条件

    T(n)=aT(n/b)+D(n)+C(n) if $ n>c$

    分治算法应用:

    寻找最大最小值, 寻找第k大的数, 寻找最近点对, 快排, 整数乘法, 凸壳, 快速傅里叶变换

    减治算法: 将原始计算问题转化为其中某一个子问题的计算问题,如二分查找

    与分治算法相比: 减治算法的解即一个子问题的解; 得到问题的解不需要合并子问题


    四 动态规划

    思想

    把原始问题划分成一系列子问题
    求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时直接存取,不重复计算,节省计算时间
    自底向上地求解子问题

    条件

    优化子结构: 问题的最优解包含其子问题的最优解

    重叠子问题: 在问题的求解过程中 很多子问题的解将被多次使用

    设计

    1.分析优化解的结构
    2.递归地定义最优解的代价(递归方程)
    3.递归地划分子问题,直至不可分
    4.自底向上地求解各个子问题
    ​ 计算优化解的代价并保存之,​ 获取构造最优解的信息
    5.(根据构造最优解的信息)构造优化解

    分析

    分析最优子结构时候成立(反证法)

    分析重叠子问题是否成立(具体问题具体分析)

    根据给出的算法分析时间和空间复杂度

    应用

    矩阵链乘法, 最长公共子序列LCS, 0/1背包问题, 最优二叉搜索树


    五 贪心算法

    思想

    求解最优化问题的算法包含一系列步骤, 每一步都有一组选择, 作出在当前看来最好的选择, 希望通过作出局部优化选择达到全局优化选择

    最优解条件

    1.贪心选择: 所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。

    2.最优子结构: 一个问题的最优解包含其剩余子问题的最优解

    设计
    1. 设计贪心选择方法
    2. 证明对于该贪心选择方法,问题有优化子结构
    3. 证明对于该贪心选择方法,问题有贪心选择性
    4. 根据贪心选择方法设计算法
    分析

    根据算法分析时间复杂度和空间复杂度

    优化子结构证明: 反证法

    贪心选择性证明

    1.归纳法: 对算法步数归纳或问题规模归纳,即证明在每一步做得都比其它算法好 从而最终产生了一个最优解

    2.交换论证法:在保证最优性不变前提下 从一个最优解逐步替换 最终得到贪心算法的解

    应用

    流中的增广路算法, Dijkstra的单源最短路径, krusal, prim,

    硬币兑换, 活动安排

    动态规划与贪心算法区别

    1. 贪心是一种特殊的动态规划,动态规划的本质是独立的子问题,而贪心则是每次可以找到最优的独立子问题。
    2. 可用贪心不一定可用动态规划, 可用动态规划不一定可用贪心
    3. 动态规划以自底向上方式,先解决小子问题,再解决大子问题;每一步做出的选择通常依赖于子问题的解
      贪心算法以自顶向下方式, 逐步进行贪心选择,不断减少子问题规模;在每一步做出当前最好选择,然后求解剩余子问题;每次选择既不依赖于子问题的解,也不依赖于未来的选择

    六 树搜索

    树搜索: 很多问题的解可以表示成为树, 解为树的节点或路径, 求解这些问题可以转化为树来进行搜索的问题

    树搜索方法

    1. 爬山法(Hill Climbing)
    2. 最佳优先搜索(Best First Search Strategy)
    3. 分支界限法(Branch and Bound Strategy)

    1.爬山法

    基本思想

    爬山策略使用贪心方法确定搜索的方向, 是 一种优化的深度优先搜索策略
    – 爬山策略使用启发式测度来排序节点扩展的顺序
    – 使用什么启发式测度与问题本身相关

    算法
    1. 构造由根组成的单元素栈S;
    2. If Top(S)点 是目标节点 Then 停止;
    3. Pop(S);
    4. S 的子节点 按照其启发测度 由大到
      小的顺序压入S;
    5. If S空 空 Then 败 失败 Else goto 2.

    2.最佳优先搜索

    思想

    • 结合深度优先和广度优先的优点于一个方法
    • 根据一个评价函数, 在目前产生的所有节点中选择
    具有最小评价函数值的节点进行扩展.
    • 具有全局优化观念, 而爬山策略仅具有局部优化观念.

    算法
    1. 使用评价函数构造一个堆 堆H, 首先构造由根
      组成的单元素堆;
    2. If H 的根r点 是目标节点 Then 停止;
    3. 从H 中删除r, 把r 的子节点插入H;
    4. If H空 空 Then 败 失败 Else goto 2.
    3.分支界限法
    思想

    – 迅速找到一个可行解
    – 将该可行解作为优化解的一个界限
    – 利用界限裁剪解空间, 提高求解的效率

    原理

    – 产生分支的机制( 使用前面的任意一种策略): 爬山法 或 Best-First
    – 产生一个界限( 可以通过发现可能解)
    – 进行分支界限搜索, 即剪除不可能产生优化解的分支

    算法( 使用爬山法产生分支)

    1. 建立根结点, 其权值为解代价下界;
    2. 使用爬山法, 类似于拓扑排序序列树生成算法求解问题, 每产生一个结点, 其权值为加工后的代价矩阵对应元素加其父结点权值;
    3. 一旦发现一个可能解, 将其代价作为界限, 循环地进行分支界限搜索: 剪掉不能导致优化解的子解, 使用爬山法继续扩展新增节点, 直至发现优化解.
    A*算法
    思想

    – A* 算法使用Best-first 策略进行搜索
    – 在某些情况下, 我们一旦得到了一个解 , 它一定是优化解,于是算法可以停止
    – 无需搜索整个解空间

    A*算法与最佳优先的不同

    在于代价函数的定义不一样,最佳优先只看已走路程,但A *还要看下个最短节点

    A*与分支界限策略的不同

    分支界限策略是为了剪掉不能达到优化解的分支
    分支界限策略的关键是 “ 界限",而 A *算法并没有界限

    分支界限得到一个解否不能确定其就是最优解,但A*算法可以


    七 平摊分析

    平摊分析与平均情况分析: 平摊分析不牵涉到概率。这种分析保证了在最坏情况下每个操作具有平均性能。

    平摊分析目的: 分析给定数据结构上的n个操作代价上界

    平摊分析的三种方法
    1. 聚集方法
    2. 会计方法
    3. 势能方法

    注意: 只有聚集分析才求每个操作的平摊代价,其余两个方法求总的平摊代价

    注意: 每个操作的实际操作不能为负数, 但某些操作的均摊代价可以为负数

    1.聚集方法

    将总的代价平摊到每个操作上: 先确定n个操作的序列的总代价的上界T(n)。每个操作的平摊代价可表示为T(n)/n;

    每个操作被赋予相同代价

    2.会计方法

    思想

    这种方法对操作序列中的某些操作先“多记帐”,将多记的部分作为对数据结构中的特定对象上预付的存款存起来。在该序列中稍后要用到这些存款以补偿那些对它们记的“帐”少于其实际代价的操作。

    原理

    一个操作序列中有不同类型的操作; 不同类型的操作的操作代价各不相同, 于是我们为每种操作分配不同的平摊代价, 平摊代价可能比实际代价大,也可能比实际代价小:

    平摊代价比实际高:一部分用于支付,多余部分作为 余额 附加在数据结构的具体对象上
    平摊代价比实际低时:余额 用来补充 支付实际代价

    会计方法要时刻注意余额不能为负数,即平摊总代价大于实际总代价.

    3.势能方法

    原理

    在会计方法中,如果操作的平摊代价比实际代价大,我们将余额与数据结构的数据对象相关联,
    势能方法把Credit余额与整个数据结构关联,所有的这样的余额之和,构成数据结构的势能:
    如果操作的平摊代价大于操作的实际代价,势能增加
    如果操作的平摊代价小于操作的实际代价,要用数据结构的势能来支付实际代价,势能减少


    八 图算法

    流网络: 是一个无自环的有向图G=(V, E),
    (1) 图中的每条边(u, v)$in $E有一个非负的容量值c(u, v) >= 0。if (u, v) inE c(u, v) >=0;
    (2) 有两个特殊结点s, t$in $V,s称为源结点(source),t称为汇点(sink)
    (3) For vVforall v in V, 存在一个s到t经过v的路径s ==> v ==> t.

    流网络是连通的除源结点外,每个结点都至少有一条进入的边,所以|E| >=|V|-1

    (Flow)

    在这里插入图片描述

    剩余网络(余图)

    在这里插入图片描述

    增广路径: 剩余网络中的一条由源结点s到汇点t的一条路径p

    流网络的割

    在这里插入图片描述

    最大流最小割定理: 一个最大流的值实际上等于一个最小割的容量

    预流(preflow): 在每个中间阶段,允许到达结点的流量比离开结点的流量多

    饱和推送: 如果push(u,v)操作后, c f (u,v) =0. 称边(u,v) 达到饱和状态,如果一条边达到饱和状态,它将从剩余网络中消失

    匹配(Matching): 给定图G(V,E),一个匹配是由其一组没有公共端点的不是圈的边构成的集合。

    • 极大匹配:不能再通过添加边使其变大的匹配 即:不存在 eE 满足 M {e} 也是匹配
    • 最大匹配: |M|最大的匹配
    • 完美匹配:浸润了所有结点的匹配 即 |M|=n/2

    顶点覆盖: 图G(V,E)的一个顶点覆盖是指顶点集合CinV ,C包含每条边上的至少一个端点

    定理: 如果G是一个二部图,则G中最大匹配的大小等于G的最小顶点覆盖的大小


    九 字符串匹配

    1.Rabin-Karp 算法

    思想

    – 将字符串的比较转化成数的比较
    – 运用了初等数论:两个数相对于第三个数模等价

    2.有限自动机与字符串匹配

    思想

    有限自动机就是构建出一个满足某个特定模式的判断系统

    3.Knuth-Morris-Pratt 算法

    思想

    充分利用已经比较过的字符信息来提高效率

    4.Boyer-Moore 算法

    思想

    采用三种技巧
    – 逆向搜索:从P的后面开始搜索
    – 坏字符启发式规则: 如果坏字符T[i]没有出现在模式P中,则直接将模式串移动到坏字符的下一个字符
    – 好后缀启发式规则

  • 相关阅读:
    Python内置函数(14)——delattr
    Python内置函数(13)——complex
    Python内置函数(12)——compile
    Python内置函数(11)——classmethod
    Python内置函数(10)——chr
    Python内置函数(9)——callable
    Python内置函数(8)——bytes
    Python内置函数(7)——bytearray
    Python内置函数(6)——bool
    Python内置函数(4)——ascii
  • 原文地址:https://www.cnblogs.com/lee3258/p/11997787.html
Copyright © 2011-2022 走看看