算法的复杂性分析

2023-05-16

算法的复杂性分析

文章目录

  • 算法的复杂性分析
    • 0、 算法评价的基本原则
    • 1、影响程序运行时间的因素
    • 2、算法复杂度
      • 2.1 算法的时间复杂度
      • 2.2 渐进表示法
        • 2.2.1 运行时间的上界
        • 2.2. 运行时间的下界
        • 2.2.3 运行时间的准确界
    • 3、总结
    • 4、参考


在这里插入图片描述


0、 算法评价的基本原则

评价一个算法的好坏实际就是评价一个程序的好坏。通常一个好的算法应该应考虑达到以下目标。

1.正确性(correctness)

一个好的算法的前提就是算法的正确性。不正确的算法没有任何意义。

2 可读性(Readability)

算法主要是为了人的阅读与交流,其次才是机器的执行。

3.健壮性(Robustness)和可靠性

  • 健壮性是指当输入数据非法时,算法也能适当地做出反应或进行处理。

  • 正确性和健壮性是相互补充的。

  • 程序的可靠性指一个程序在正常情况下能正确地工作,而在异常情况下也能做出适当处理。

  1. 效率(efficiency)
  • 效率包括运行程序所花费的时间以及运行这个程序所占用的资源(占用的存储空间 )。算法应该有效使用存储空间,并具有高的时间效率。

  • 对于规模较大的程序,算法的效率问题是算法设计必须面对的一个关键问题,目标是设计复杂性尽可能低的算法。

  1. 简明性(simplicity)
  • 算法应该思路清晰、层次分明、容易理解、利于编码和调试,即算法简单,程序结构简单。

  • 简单的算法效率不一定高,要在保证一定效率的前提下力求得到简单的算法。

  1. 最优性(optimality)
  • 指求解某类问题中效率最高的算法。最优性与所求问题自身的复杂程度有关。

1、影响程序运行时间的因素

  • 程序所依赖的算法

求解同一个问题的不同算法,其程序运行时间一般不同。

  • 问题的规模和输入数据

程序的一次运行是针对所求解问题的某一特定实例而言的。因此分析算法性能需要考虑的一个基本问题是所求解问题实例的规模,即输入数据量,必要时也考虑输出的数据量。

  • 计算机系统的性能

算法运行所需要的时间还依赖于计算机的硬件系统和软件系统。

2、算法复杂度

算法的复杂度主要包括时间复杂度和空间复杂度。

2.1 算法的时间复杂度

算法的时间复杂度指算法运行所需时间,也指执行算法所需要的计算工作量。

  • 度量算法的工作量

一个算法是由基本运算和控制结构(顺序、选择、循环)构成的,则算法执行时间取决于两者的综合效果。

通常的做法是:从算法中选取一种对于所研究的问题来说是基本的运算,以该基本运算重复执行的次数作为算法的工作量。

例如:在考虑两个矩阵相乘时,可以将两个实数之间的乘法运算作为基本运算,而对于所用的加法(或减法)运算可以忽略不计。

  • 算法所执行的基本运算次数还与问题的规模有关。例如:两个20阶矩阵相乘与两个3阶矩阵相乘所需要的基本运算(即两个实数的乘法)次数显然是不同的。前者需要更多的运算次数,因此,在分析算法的工作量时,还必须对问题的规模进行度量。

综上所述,算法的工作量用算法所执行的基本运算次数来度量,而算法所执行的基本运算次数是问题规模的函数。即算法的工作量=f(n),n是问题的规模。

  • 算法的执行时间绝大部分花在循环和递归上

对于循环语句的时间代价一般用以下三条原则分析:

1)对于一个循环,循环次数乘以每次执行简单语句的数目即为其时间代价。

2)对于多个并列循环,可先计算每个循环的时间代价,然后按加法规则计算总代价。

3)对于多层嵌套循环,一般可按乘法规则计算。但如果嵌套是有条件的,为精确计算其时间代价,要仔细累加循环中简单语句的实际执行数目,以确定其时间代价。

2.2 渐进表示法

一般来说,当N单调增加且趋于∞时,T(N)也将单调增趋于∞。对于T(N),如果存在函数T’(N),使得当N→∞时有(T(N)-T’(N))/T(N)→0,那么我们就说T’(N)是T(N)当N→∞时的渐进性态。在数学上,T’(N)是T(N)当N→∞时的渐进表达式。例如:3N2+4NlogN+7与3N2, 3N2是3N2+4NlogN+7的渐近表达式。

算法复杂性在渐近意义下的记号有:O、Ω、Θ等,分别表达运行时间的上界、运行时间的下界、运行时间的准确界等

2.2.1 运行时间的上界

设函数f(n)和g(n)是定义在非负整数集合上的正函数,如果存在正整数n0和正常数c,使得当n≥n0时,有f(n)≤cg(n),就称f(n)的阶至多是O(g(n)),记做f(n) = O(g(n)),称为大O记号(big O notation)。如图所示。

tp1

例如

  • f(n) = 2n2+3,g(n)=n2

当n≥3时,2n2+3≤3*n2,所以,可选c=3,n0 = 3。对于n≥n0,f(n)= 2n2+3≤3n2,所以,f(n) = O(n2),即2n2+3=O(n2)。

  • f(n) = n!= O(nn)

对于n≥1,有n(n-1)(n-2) … 1≤nn,因此,可选c=1,n0=1。对于n≥n0,f(n)= n!≤nn,所以,f(n) = O(nn)。

  • 10n2 + 9≠O(n)

使用反证法,假定存在c和n0,使得对于n≥n0,10n2 + 9≤cn始终成立,那么有10n + 9/n≤c,即n≤c/10-9/(10n)总成立。但此不等式不可能总成立,取n=c/10+1时,该不等式便不再成立。

定理1: 如果f(n)=amnm+am-1nm-1+…+a1nn+a0是m次多项式,且am>0,则f(n)=O(nm)。

证明如下:

在这里插入图片描述

  • 规则

加法规则

O(f(n))+O(g(n))=O(max(f(n),g(n)))
O(f(n))+O(g(n))=O(f(n)+g(n))

如果g(n)=O(f(n)),则O(f(n))+O(g(n))=O((f(n))

乘法规则

O(f(n))*O(g(n))=O(f(n)*g(n))
O(c*f(n))=O(f(n)),c是一个正常数
f(n)=O((f(n))

tp

2.2. 运行时间的下界

设有函数f(n)和g(n)是定义在非负整数集合上的正函数,如果存在正整数n0和正常数c,使得当n≥n0时,有f(n)≥cg(n),就称f(n)的阶至少是Ω(g(n)),记做f(n) = Ω(g(n)),称为Ω记号(omega notation)。如图所示。

tp

这个定义的意义是:当n充分大时有下界,且g(n)是它的一个下界,f(n)的增长至少像g(n)那样快。它用以表示一个算法运行时间的下界。

示例

tp

定理2:如果f(n)=amnm+am-1nm-1+…+a1nn+a0是m次多项式,且am>0,则f(n)=Ω(nm)。

2.2.3 运行时间的准确界

设有函数f(n)和g(n)是定义在非负整数集合上的正函数,如果存在正整数n0和正常数c1和c2(c1 ≤c2),使得当n≥n0时,有c1 g(n)≤f(n)≤c2 g(n) ,就称f(n)的阶是Θ(g(n)),则记做f(n)=Θ(g(n)),称为Θ记号(Theta notation)。
如图所示。

tp

即f(n)=Θ(g(n))当且仅当f(n)=O(g(n))且f(n)=Ω(g(n)),此时称f(n)与g(n)同阶。这个定义的意义是:f(n)的增长像g(n)一样快。

  • 示例

tp

3、总结

算法按时间复杂度分类

  • 常见的复杂度类型如下:
1<loglogn<logn<n^(1/2)<n^(3/4)<n<nlogn<n^2<2^n<n!<2^(n^2)

凡渐近时间复杂度有多项式时间限界的算法称作多项式时间算法(polynomial time algorithm),而渐近时间复杂度为指数函数限界的算法称作指数时间算法(exponential time algorithm)。

  • 最常见的多项式时间算法的渐近时间复杂度。
O(1)<O(log n)<O(n)<O(nlog n)<O(n^2)<O(n^3)
  • 最常见的指数时间算法的渐近时间复杂度。
O(2^n)<O(n!)<O(n^n)

随着n的增大,算法在所需时间上非常悬殊。如图所示。

在这里插入图片描述

4、参考

  • 算法设计与分析(第4版)

结束!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法的复杂性分析 的相关文章

  • 棋盘覆盖问题(Java)

    棋盘覆盖问题 xff08 Java xff09 文章目录 棋盘覆盖问题 xff08 Java xff09 1 问题描述2 算法设计思路3 代码实现4 复杂度分析5 参考 1 问题描述 在一个2k 2k个方格组成的棋盘中 若恰有一个方格与其他
  • android -- 蓝牙 bluetooth (一) 入门

    前段时间在 网上看了一些关于android蓝牙的文章 xff0c 发现大部分是基于老版本 xff08 4 1以前含4 1 xff09 的源码 xff0c 虽然无碍了解蓝牙的基本原理和工作流程 xff0c 但对着4 2 2的代码看起来总是有些
  • 最优二叉搜索树问题(Java)

    最优二叉搜索树问题 xff08 Java xff09 文章目录 最优二叉搜索树问题 xff08 Java xff09 1 前置介绍2 算法设计思路2 1 最优二叉搜索树的结构2 2 一个递归算法2 3 计算最优二叉搜索树的期望搜索代价 3
  • 大数据量一次性导入MongoDB

    大数据量一次性导入MongoDB 文章目录 大数据量一次性导入MongoDB0 写在前面1 前置芝士2 mongoimport命令导入JSON文件数据失败3 db COLLECTION count 返回值不正确4 数据导入不完全5 参考资料
  • Strassen矩阵乘法问题(Java)

    Strassen矩阵乘法问题 xff08 Java xff09 文章目录 Strassen矩阵乘法问题 xff08 Java xff09 1 前置介绍3 代码实现4 复杂度分析5 参考资料 1 前置介绍 矩阵乘法是线性代数中最常见的问题之一
  • 线性时间选择(Top K)问题(Java)

    线性时间选择 xff08 Top K xff09 问题 xff08 Java xff09 文章目录 线性时间选择 xff08 Top K xff09 问题 xff08 Java xff09 1 前置介绍2 分治法求解3 代码实现4 复杂度分
  • HBase查询一张表的数据条数的方法

    HBase查询一张表的数据条数的方法 文章目录 HBase查询一张表的数据条数的方法0 写在前面1 HBase Shell的count命令2 Scan操作获取数据条数3 执行Mapreduce任务4 Hive与HBase整合5 协处理器Co
  • 校园论坛设计(Java)——介绍篇

    校园论坛设计 xff08 Java xff09 文章目录 校园论坛设计 xff08 Java xff09 0 写在前面1 项目介绍2 项目背景3 项目功能介绍3 1 总体设计图3 2 帖子模块3 3 学习模块3 4 个人信息模块3 5 数据
  • 单源最短路径问题(Java)

    单源最短路径问题 xff08 Java xff09 文章目录 单源最短路径问题 xff08 Java xff09 1 问题描述2 算法思路3 代码实现4 算法正确性和计算复杂性4 1 贪心选择性质4 2 最优子结构性质4 3 计算复杂性 5
  • 回溯法(Java)

    回溯法 xff08 Java xff09 文章目录 回溯法 xff08 Java xff09 1 引言2 回溯法2 1 定义2 2 使用场合2 3 基本做法2 4 具体做法2 5 常见例子 3 比较4 问题的解空间4 1 介绍4 2 解空间
  • 校园论坛(Java)——环境配置篇

    校园论坛 Java 环境配置篇 文章目录 校园论坛 Java 环境配置篇 1 写在前面 2 新建Maven项目 2 1 引入相关依赖 2 2 配置Tomcat环境 3 项目发布测试 4 项目代码 5 参考资料 1 写在前面 Windows版
  • 校园论坛(Java)—— 帖子模块

    校园论坛 Java 帖子模块 文章目录 校园论坛 Java 帖子模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 普通帖子中各层的设计 3 用户浏览普通帖子功能的实现 3 1 帖子发布和查看以及回复功能系统 3
  • android -- 蓝牙 bluetooth (二) 打开蓝牙

    4 2的蓝牙打开流程这一部分还是有些变化的 xff0c 从界面上看蓝牙开关就是设置settings里那个switch开关 xff0c widget开关当然也可以 xff0c 起点不同而已 xff0c 后续的流程是一样的 先来看systemS
  • 校园论坛(Java)—— 登录注册和用户信息模块

    校园论坛 Java 登录注册和用户信息模块 文章目录 校园论坛 Java 登录注册和用户信息模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 登录注册模块各层的设计 3 登录注册模块设计 3 1 用户注册功能 3
  • 校园论坛(Java)—— 考研学习模块

    校园论坛 Java 考研学习模块 文章目录 校园论坛 Java 考研学习模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 登录注册模块各层的设计 3 考研学习模块设计 3 1 浏览和查看帖子 3 2 发表帖子 3
  • 校园论坛(Java)—— 用户管理系统模块

    校园论坛 Java 用户管理系统模块 文章目录 校园论坛 Java 用户管理系统模块 toc 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 用户管理系统模块各层的设计 3 管理员管理用户功能 3 1 管理员查看普通
  • 校园论坛(Java)—— 数据报表模块

    校园论坛 Java 数据报表模块 文章目录 校园论坛 Java 数据报表模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 代码实现 3 数据报表设计 3 1 数据报表主界面的实现 3 2 发表数Top5的普通帖子
  • 校园论坛(Java)—— 校园周边模块

    校园论坛 Java 校园周边模块 文章目录 校园论坛 Java 校园周边模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 校园周边页面设计 3 校园周边模块设计 3 1 校园周边主界面的实现 3 2 增加附近的交
  • 校园论坛(Java)—— 结束篇

    校园论坛 Java 结束篇 文章目录 校园论坛 Java 结束篇 1 写在前面 2 系统总体设计 2 1 设计流程 2 2 各个页面之间的调用关系 3 系统实现的可行性 4 系统制作的局限性 5 总结 6 项目代码 1 写在前面 Windo
  • Windows远程连接Redis(Linux)

    Windows远程连接Redis xff08 Linux xff09 文章目录 Windows远程连接Redis xff08 Linux xff09 1 写在前面2 配置redis conf3 启动Redis3 1 开启redis服务3 2

随机推荐

  • 批量数据导入Neo4j的方式

    批量数据导入Neo4j的方式 文章目录 批量数据导入Neo4j的方式1 写在前面2 前置芝士3 CSV数据导入Neo4j3 1 LOAD CSV Cypher命令3 2 neo4j admin命令3 3 Kettle导入工具 4 数据导入失
  • Neo4j的Java API操作

    Neo4j的Java API操作 文章目录 Neo4j的Java API操作0 写在前面1 前置芝士2 准备工作2 1 为项目引入Neo4j依赖2 2 启动和停止 3 Java操作Neo4j4 参考资料 0 写在前面 Linux版本 xff
  • NoSQL数据库原理与应用综合项目——起始篇

    NoSQL数据库原理与应用综合项目 起始篇 文章目录 NoSQL数据库原理与应用综合项目 起始篇 0 写在前面 1 项目说明 1 1 项目背景 1 2 项目功能 2 数据集和数据预处理 2 1 数据集 2 2 数据预处理 2 2 1 图书出
  • android -- 蓝牙 bluetooth (三)搜索蓝牙

    接上篇打开蓝牙继续 xff0c 来一起看下蓝牙搜索的流程 xff0c 触发蓝牙搜索的条件形式上有两种 xff0c 一是在蓝牙设置界面开启蓝牙会直接开始搜索 xff0c 另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索 xff0c 也可能
  • 单源最短路径问题——分支限界法(Java)

    单源最短路径问题 分支限界法 xff08 Java xff09 文章目录 单源最短路径问题 分支限界法 xff08 Java xff09 1 前置芝士1 1 分支限界法求解目标1 2 分支限界法引言1 3 分支限界法基本思想1 4 两种典型
  • 符号三角形问题(Java)

    符号三角形问题 xff08 Java xff09 文章目录 符号三角形问题 xff08 Java xff09 1 前置介绍2 算法设计3 程序代码4 算法效率5 参考资料 1 前置介绍 符号三角形定义 如下图所示 xff0c 符号三角形是由
  • 装载问题 ——分支限界法(Java)

    装载问题 分支限界法 xff08 Java xff09 文章目录 装载问题 分支限界法 xff08 Java xff09 1 问题描述2 算法设计3 算法的改进4 程序代码5 参考资料 1 问题描述 有一批共n个集装箱要装上2艘载重量分别为
  • 装载问题 ——回溯法(Java)

    装载问题 回溯法 xff08 Java xff09 文章目录 装载问题 回溯法 xff08 Java xff09 1 问题描述1 1 装载问题1 2 转换问题 2 算法设计2 1 可行性约束函数2 2 上界函数2 3 解空间树2 4 剪枝函
  • 上传项目代码到Github|Gitee

    上传项目代码到Github Gitee 文章目录 上传项目代码到Github Gitee1 前置准备1 1 Git 安装1 2 在 Git 中设置用户名1 2 1 为计算机上的每个存储库设置 Git 用户名1 2 2 为一个仓库设置 Git
  • NoSQL数据库原理与应用综合项目——HBase篇

    NoSQL数据库原理与应用综合项目 HBase篇 文章目录 NoSQL数据库原理与应用综合项目 HBase篇 0 写在前面 1 本地数据或HDFS数据导入到HBase 2 Hbase数据库表操作 2 1 Java API 连接HBase 2
  • NoSQL数据库原理与应用综合项目——MongoDB篇

    NoSQL数据库原理与应用综合项目 MongoDB篇 文章目录 NoSQL数据库原理与应用综合项目 MongoDB篇 0 写在前面 1 本地数据或HDFS数据导入到MongoDB 2 MongoDB数据库表操作 2 1 Java API 连
  • NoSQL数据库原理与应用综合项目——Redis篇

    NoSQL数据库原理与应用综合项目 Redis篇 文章目录 NoSQL数据库原理与应用综合项目 Redis篇 0 写在前面 1 本地数据或HDFS数据导入到Redis 2 Redis数据库表操作 2 1 Java API 连接Redis 2
  • NoSQL数据库原理与应用综合项目——Neo4j篇

    NoSQL数据库原理与应用综合项目 Neo4j篇 文章目录 NoSQL数据库原理与应用综合项目 Neo4j篇 0 写在前面 1 本地数据或HDFS数据导入到Neo4j 2 Neo4j数据库表操作 2 1 使用Python连接Neo4j 2
  • Hadoop综合项目——二手房统计分析(起始篇)

    Hadoop综合项目 二手房统计分析 起始篇 文章目录 Hadoop综合项目 二手房统计分析 起始篇 0 写在前面 1 项目背景与功能 1 1 项目背景 1 2 项目功能 2 数据集和数据预处理 2 1 数据集 2 2 数据预处理 2 2
  • android -- 蓝牙 bluetooth (四)OPP文件传输

    在前面android 蓝牙 bluetooth xff08 一 xff09 入门文章结尾中提到了会按四个方面来写这系列的文章 xff0c 前面已写了蓝牙打开和蓝牙搜索 xff0c 这次一起来看下蓝牙文件分享的流程 xff0c 也就是蓝牙应用
  • Hadoop综合项目——二手房统计分析(MapReduce篇)

    Hadoop综合项目 二手房统计分析 MapReduce篇 文章目录 Hadoop综合项目 二手房统计分析 MapReduce篇 0 写在前面 1 MapReduce统计分析 1 1 统计四大一线城市房价的最值 1 2 按照城市分区统计二手
  • Hadoop综合项目——二手房统计分析(Hive篇)

    Hadoop综合项目 二手房统计分析 Hive篇 文章目录 Hadoop综合项目 二手房统计分析 Hive篇 0 写在前面 1 Hive统计分析 1 1 本地数据 HDFS数据导入到Hive 1 2 楼龄超过20年的二手房比例 1 3 四大
  • Hadoop综合项目——二手房统计分析(可视化篇)

    Hadoop综合项目 二手房统计分析 可视化篇 文章目录 Hadoop综合项目 二手房统计分析 可视化篇 0 写在前面 1 数据可视化 1 1 二手房四大一线城市总价Top5 1 2 统计各个楼龄段的二手房比例 1 3 统计各个城市二手房标
  • Git Bash Here和RStudio软件的问题解决

    Git Bash Here和RStudio软件的问题解决 文章目录 Git Bash Here和RStudio软件的问题解决0 写在前面1 Git软件在任务栏图标空白2 RStudio软件2 1 警告信息InormalizePath pat
  • 算法的复杂性分析

    算法的复杂性分析 文章目录 算法的复杂性分析0 算法评价的基本原则1 影响程序运行时间的因素2 算法复杂度2 1 算法的时间复杂度2 2 渐进表示法2 2 1 运行时间的上界2 2 运行时间的下界2 2 3 运行时间的准确界 3 总结4 参