《计算之魂》第1章 毫厘千里之差——大O概念

第一章 毫厘千里之差——大O概念 (1.1,1.2节)

图灵:提出计算机的数学模型
⋅ \cdot 诺伊曼:确定了计算机通用的系统结构
高德纳:奠定了计算机算法的基础

1.1 算法的规范化和量化度量

人类第一台电子计算机:ENIAC——一台专用计算机,专门用于解决研制长程火炮过程中的计算问题。
世界上第一台程序控制的通用电子计算机:EDVAC——涵盖了一种通用的计算机的体系结构。
“冯·诺依曼体系结构”:冯·诺依曼在客观上将计算机分为了软硬件两部分。

早期没有注重程序质量,后面在商业上开始普及后,对程序的合理性、效率、占用资源就开始讲究了。这都需要计算机的算法理论支撑。

高德纳:奠定计算机算法基础的人,牛逼经历如下:

1. 计算机算法分析的鼻祖,提出了评估计算机算法的标准。

2. 编写了计算机科学领域的“圣经”——《计算机程序设计艺术》一书(共4卷)。(一般人就这一项成果就封神了吧…)

3. 迄今为止最年轻的图灵奖获得者。

4. 自己写了一个排版软件,即著名的TeX(后来被人做成了更方便使用的LaTeX)。

5. 硅谷地区众多图灵奖获得者中名气最大、最会编程的人:硅谷地区聚集了很多图灵奖获得者,有一段时间他们每年要进行编程比赛,高德纳总是用一台最慢的计算机获得第一名。
这就是传说中的高德纳(小声bb: 果然强者从不吝啬头发)
这就是传说中的高德纳(小声bb: 果然强者从不吝啬头发)

思考题1.1

世界上还有什么产品类似于计算机,是软硬件分离的?( 难度系数1颗星)
个人作答:

- 智能设备
现在的家居智能化,各种智能家居设备感觉都是软硬件分离,就算不是,也在朝着这个目标发展,比如扫地机器人,智能电饭煲,智能洗衣机等,都是植入软件,然后用wifi控制即可。

- 网络设备
如交换机和服务器(这…似乎也算是计算机?)

1.2 大数和数量级的概念

例子:哪个算法更好
场景1:使用1万个数据进行测试,算法A运行1毫秒,算法B则需要运行10毫秒。
场景2:使用100万个数据进行测试,算法A运行10000毫秒,算法B运行6000毫秒。

看场景1,是A更好;场景2又是B运行速度更快。然而,需要制定一个明确的、一致的标准,而不是不同场景算法好坏不同。

1965年尤里斯·哈特马尼斯(Juris Hartmanis)和理查德·斯特恩斯(Richard Stearns)提出了算法复杂度的概念(二人后来因此获得了图灵奖)。最早将算法复杂度严格量化衡量的就是高德纳,他也因此被誉为“算法分析之父”。今天,全世界的计算机领域都以高德纳的思想为准。

高德纳的思想主要包括以下三个部分:

  1. 在比较算法的快慢时,只需要考虑数据量特别大,大到近乎无穷大时的情况。理由是计算机的发明是为了处理大量的数据的。
  2. 决定算法快慢的因素虽然可能有很多,但是所有的因素都可以被分为两类:
    第一类是不随数据量变化的因素,
    第二类是随数据量变化的因素。
    例如有两种算法:第一种的运算次数是 3 N 2 3N^2 3N2,其中 N N N是处理的数据量;第二种则是 100 N l o g N 100NlogN 100NlogN,其中的3和100都是常数,与数据量 N N N无关,当 N → ∞ N\rightarrow \infty N时, N 2 ≫ N l o g N N^2\gg NlogN N2NlogN,所以第二种的算法比第一种好。(只考虑与数据量有关的因素和数据量特别大的情况)

插播:
例题1.2中 1 0 100 10^{100} 10100的计算:10万= 1 0 5 10^{5} 105 20 20 20个单词的组合可能个数: ( 1 0 5 ) 20 = 1 0 100 (10^{5})^{20}=10^{100} (105)20=10100

讨论算法复杂度时,只考虑N趋近于无穷大时和 N N N相关的那部分。我们可以把一种算法的计算量或者占用空间的大小,写成 N N N的一个函数 f ( N ) f(N) f(N)。这个函数的边界(上界或者下界)可以用数学上的大O概念来限制。
大O概念的定义:如果两个函数 f ( N ) f(N) f(N) g ( N ) g(N) g(N),在 N N N趋近于无穷大时比值只差一个常数,那么它们就被看成同一个数量级的函数。
而在计算机科学中相应的算法,也就被认为是具有相同的复杂度。

  1. 两种算法在复杂度上相差哪怕只有一点点, N N N很大之后,效率可能就差出万亿倍了。
    如果一个算法的复杂度由一高一低的两部分 f ( N ) f(N) f(N) g ( N ) g(N) g(N)组成,即 f ( N ) + g ( N ) f(N)+g(N) f(N)+g(N),后面数量级低的那部分可以直接省略,也就是说 O ( f ( N ) + g ( N ) ) = O ( f ( N ) ) O(f(N)+g(N))=O(f(N)) O(f(N)+g(N))=O(f(N))。这在数学上显然不成立,但是在计算机算法上是被认可的。

思考题1.2

如果一个程序只运行一次,在编写它的时候,你是采用最直观但是效率较低的算法,还是依然寻找复杂度最优的算法?(难度系数2颗星)
个人作答:
这就要看解决问题的具体算法复杂度了,如果典型的 N N N很大,那肯定需要寻找复杂度最优的算法,如上面第3点所说:两种算法在复杂度上相差哪怕只有一点点, N N N很大之后,效率可能就差出万亿倍。所以寻找最优算法效率反而更高。

1.3节笔记链接:
https://blog.csdn.net/weixin_41794514/article/details/126463994?spm=1001.2014.3001.5501

猜你喜欢

转载自blog.csdn.net/weixin_41794514/article/details/126346613