借助数学函数进行算法效率的对比分析

▲ 《程序员数学 从零开始》:如果没有必要的数学知识,几行简单的代码就会变成学习中的绊脚石

如何进行算法分析呢?

分别运行解决同一个问题的两个算法进行比较在很多时候并不理想,面对这样的困难迫使我们求助于数学工具,虽然我们不能对一个还没有完整实现的程序使用运行比较法,但却能通过数学分析了解程序性能的大致轮廓并预估改进版本的有效性。

大多数算法都有影响运行时间的主要参数

,这里的
是所解决问题的大小的抽象度量,比如对于一个排序算法来说,
是待排序元素的个数。我们的目标是尽可能地使用简单的数学公式,用
表达出程序的运行效率。

函数的增长

对于将要比较的两个算法,我们并不满足于简单地描述为“一个算法比另一个算法快”,而是希望能够通过数学函数直观地感受到二者的差异,具体来说,是希望知道“一个算法比另一个算法快多少”。

一些函数在算法分析中极为常见:

  1. 。如果程序中的大多数指令只运行

    次或几次,与问题的规模无关,我们就说程序运行的时间是常量的。小高斯的算法就是典型的常量时间。
  2. 。随着问题规模的增长,程序运行时间增长较慢,可以认为程序的运行时间小于一个大常数。虽然对数的底数会影响函数的值,但影响不大。鉴于计算机是

    进制的,所以通常取
    为底数,
    ,这与数学中略有差别(数学中
    )。当
    时,
    ;当
    增长了
    倍时,
    ,仅有略微的增长;只有当
    增长到
    时,
    才翻倍。如果一个算法是把一个大问题分解为若干个小问题,而每个小问题的运行时间是常数,那么我们认为这个算法的运行时间是
    ,二分查找就其中的典型。
  3. 。比

    稍大,当问题规模翻倍时,运行时间比翻倍少一点;当
    增长了
    倍时,程序运行时间增长
    倍。开销是 √N 时间的程序通常对程序的终止条件做了处理,比如,在判断一个数是否是素数时,边界值是这个数的平方根,而不是这个数本身。
  4. 。这就是通常所说的线性时间,如果问题规模增大了

    倍,程序运行时间也增大
    倍。
    的蛮力求和法就是线性时间,这类方法通常带有一个以问题规模为终点的循环。
  5. 。当问题规模翻倍时,如果运行时间比翻倍多一点,我们就简单地说程序运行的时间是

    。当
    时,
    ;如果 N=2048 ,
    都是把一个大问题分解为若干个能过在常数时间内运行的小问题,区别在于是否需要合并这些小问题,如果合并,就是
    ;如果不合并,就是
    。大多数归并问题的运行时间可以简单地看作
  6. 。如果问题规模翻倍,运行时间增长

    倍;问题规模增长
    倍,运行时间增长
    倍。
  7. 。如果问题规模翻倍,运行时间增长

    倍;问题规模增长
    倍,运行时间增长
    倍。
  8. 。真正要命的增长。如果

    翻倍后,
    。复杂问题的蛮力法通常具有这样的规模,这类算法通常不能应用于实际。

来看一下这些函数的增长曲线,如图 1 所示。

以上函数能够帮助我们直观地理解算法的运行效率,让我们很容易区分出快速算法和慢速算法。大多数时候,我们都简单地把程序运行的时间称为“常数”、“线性”、“平方次”等。对于小规模的问题,算法的选择不那么重要,一旦问题达到一定规模,算法的优劣就会立马体现出来。代码 4-2 展示了当问题规模是

的增长规模。

▼ 代码 2: 函数的增长规模 C4_2.py

01 import math
02
03 fun_list = ['lgN', 'sqrt(N)', 'N', 'NlgN', '$N^2$', 'N^3'] # 函数列表
04 print(' ' * 10, end='')
05 for f in fun_list:
06     print('%-15s' % f, end='')
07 print('n', '-' * 100)
08
09 N_list = [10 ** n for n in range(7)] # 问题规模
10 for $N$ in N_list: # 函数在不同问题规模下的增长
11     print('%-8s%-2s' % (N, '|'), end='')
12     print('%-15d' % round(math.log2(N)), end='')
13     print('%-15d' % round(math.sqrt(N)), end='')
14     print('%-15d' % N, end='')
15     print('%-15d' % round(N * math.log2(N)), end='')
16     print('%-15d' % $N$ ** 2, end='')
17     print(N ** 3)

运行结果如图 4.2 所示。

图 2 告诉我们,在问题规模是

的时候,所有算法都同样有效,问题规模越大,不同复杂度的算法运行效率相差得越大。
增长的太过迅猛,作为一个另类单独列出。

▼ 代码 3:

的增长
01 for $N$ in range(10, 110, 10):
02 print('2**{0} = {1}'.format(N, 2 ** N))

运行结果如图 3 所示。

这些运行结果告诉我们,有些时候,选择正确的算法是解决问题的唯一途径。对于函数的输出结果来说,如果把

看作
秒,那么
就是
秒,超过
分半。这意味着对于一个规模是
的问题来说,一个是
复杂度的算法可以立刻得出结果,
复杂度的算法耗时约
秒,
复杂度的算法耗时将超过
小时,
复杂度则需要
万多年!也许我们可以忍受一运行
秒或
小时的程序,但一定没法容忍有生之年看不到结果的程序。

上文 [遇见] 授权节选自北大出版社《程序员数学从零开始》,本书刚好参与京东每满100-50活动, 感兴趣的朋友可以关注下:

270余幅插图+90余段Python代码+20余个原理剖析,教你学会程序员必须掌握的数学及算法背后的数学原理。

inrange函数_掌握这些数学函数,你会在算法效率的分析时经常用到相关推荐

  1. 算法分析的目的_掌握这些数学函数,你会在算法效率的分析时经常用到

    算法分析应该怎么做? 在许多情况下,分别运行两种算法来解决同一问题是不理想的,面对这一困难,我们只好求助于数学工具,虽然我们无法对一个尚未完全实现的程序进行比较,但是通过数学分析,我们可以理解程序性能 ...

  2. 函数平移口诀_呆哥数学函数合集——函数的图形变换来啦【4】

    函数图像变幻莫测哈哈哈 呆哥今天给你们整理的要点!注意查收! [电子档领取] 如果想要获取往期电子版讲义.数学笔记手写稿 可以加我微信:daigemath666备注:一轮复习讲义电子版或手写稿 4. ...

  3. 画分段函数_秃头节:“函数”段子已出炉高中数学题型分析

    高中数学函数题型整理解析版 函数图像 有关函数图象识别问题的常见题型及解题思路(1)由函数的定义域,判断图象左右的位置,由函数的值域,判断图象的上下位置:②由函数的单调性,判断图象的变化趋势:③由函数 ...

  4. c++已知2点求中垂线_呆哥数学函数合集——函数的概念【2】

    高中数学函数基本概念,学好函数还是要先懂概念再做题. 下面是呆哥给你们整理好的基本知识要点. 不懂的可以找我私聊,在线帮你解答. 多看我专栏发的每日一题和解析,会对你们有用的 . 加油哈!离高考还有一 ...

  5. Sql Server函数全解(二)数学函数

      数学函数主要用来处理数值数据,主要的数学函数有:绝对值函数,三角函数(包括正弦函数,余弦函数,正切函数,余切函数).对数函数,随机函数等.在错误产生时,数学函数将返回空值null.本次介绍各种数学 ...

  6. 编写分段函数子函数_编写自己的函数

    编写分段函数子函数 PYTHON编程 (PYTHON PROGRAMMING) In Python, you can define your own functions. 在Python中,您可以定义 ...

  7. matlab的数学函数,matlab中常见数学函数的使用

    matlab中常见数学函数的使用 MATLAB 基本知识 Matlab 的内部常数 pi 圆周率 exp(1) 自然对数的底数 e i 或 j 虚数单位 Inf 或 inf 无穷大 Matlab 的常 ...

  8. Sql Server函数全解二数学函数

    阅读目录 1.绝对值函数ABS(x)和返回圆周率的函数PI() 2.平方根函数SQRT(x) 3.获取随机函数的函数RAND()和RAND(x) 4.四舍五入函数ROUND(x,y) 5.符号函数SI ...

  9. mysql独有的函数_数据库之MySQL函数(一)

    一.数学函数 1.绝对值函数 ABS(x) :返回 x 的绝对值 mysql> select ABS(2),ABS(-2.3),ABS(-22); 返回的结果如下: 数学学得好的大佬应该知道(本 ...

最新文章

  1. ResNeXt——与 ResNet 相比,相同的参数个数,结果更好:一个 101 层的 ResNeXt 网络,和 200 层的 ResNet 准确度差不多,但是计算量只有后者的一半...
  2. java 面向对象 — 继承
  3. python_sting字符串的方法及注释
  4. Speedment 3.0的新功能
  5. Linux下nm和ldd 命令
  6. Javascript常用的设计模式详解
  7. srpg 胜利条件设定_英雄联盟获胜条件
  8. 基于jsp+Spring+mybatis的SSM企业门户网站设计和实现
  9. vb mysql边记录边统计_VB与Access连接,检索、核对、处理数据
  10. 【4】axios 获取数据
  11. python airflow_airflow python 包采坑指南
  12. Fall 2020 Berkeley cs61a hw02答案
  13. 《电脑音乐制作实战指南:伴奏、录歌、MTV全攻略》——第1篇 获取伴奏篇 第1章 MIDI音乐伴奏的获取与制作 1.1 电脑MIDI音乐与设备的介绍...
  14. 成本更低、更优观看体验——自研S265编解码器解析
  15. fatal error C1083:/fatal error C1010: 错误处理
  16. 从零搭建一款PC页面编辑器PC-Dooring
  17. window10使用bat脚本配置ip和dns
  18. NSDP协议PORTAL服务器源码
  19. golang中获取字符串长度的办法
  20. 领导者必备的13个管理套路,用好了,下属死心塌地为你卖命

热门文章

  1. 51CTO博客首页看到我了
  2. vs2008生成lib文件
  3. shell 中${b-2} and ${b:-2}
  4. Dell Latitude D630 无法wubi安装Kubuntu
  5. 初创公司 经营_LibreCorps指导人道主义初创公司如何运行开源方式
  6. devops失败的原因_为什么害怕失败是一种无声的DevOps病毒
  7. 开发人员安全问题_开发人员需要了解的安全性
  8. github初学者指南_GitHub初学者指南
  9. 前端:HTML/06/表单,表单元素(单行文本域,单行密码域,单选按钮,复选框,下拉列表,文本区域,上传文件域,各种按钮,隐藏域,lt;caption表格标题)
  10. Bootstrap CSS编码规范之选择器使用规范