第一章 毫厘千里之差——大O概念 (1.1,1.2节)
图灵:提出计算机的数学模型
冯
⋅
\cdot
⋅诺伊曼:确定了计算机通用的系统结构
高德纳:奠定了计算机算法的基础
1.1 算法的规范化和量化度量
人类第一台电子计算机:ENIAC——一台专用计算机,专门用于解决研制长程火炮过程中的计算问题。
世界上第一台程序控制的通用电子计算机:EDVAC——涵盖了一种通用的计算机的体系结构。
“冯·诺依曼体系结构”:冯·诺依曼在客观上将计算机分为了软硬件两部分。
早期没有注重程序质量,后面在商业上开始普及后,对程序的合理性、效率、占用资源就开始讲究了。这都需要计算机的算法理论支撑。
高德纳:奠定计算机算法基础的人,牛逼经历如下:
1. 计算机算法分析的鼻祖,提出了评估计算机算法的标准。
2. 编写了计算机科学领域的“圣经”——《计算机程序设计艺术》一书(共4卷)。(一般人就这一项成果就封神了吧…)
3. 迄今为止最年轻的图灵奖获得者。
4. 自己写了一个排版软件,即著名的TeX(后来被人做成了更方便使用的LaTeX)。
5. 硅谷地区众多图灵奖获得者中名气最大、最会编程的人:硅谷地区聚集了很多图灵奖获得者,有一段时间他们每年要进行编程比赛,高德纳总是用一台最慢的计算机获得第一名。
这就是传说中的高德纳(小声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)提出了算法复杂度的概念(二人后来因此获得了图灵奖)。最早将算法复杂度严格量化衡量的就是高德纳,他也因此被誉为“算法分析之父”。今天,全世界的计算机领域都以高德纳的思想为准。
高德纳的思想主要包括以下三个部分:
- 在比较算法的快慢时,只需要考虑数据量特别大,大到近乎无穷大时的情况。理由是计算机的发明是为了处理大量的数据的。
- 决定算法快慢的因素虽然可能有很多,但是所有的因素都可以被分为两类:
第一类是不随数据量变化的因素,
第二类是随数据量变化的因素。
例如有两种算法:第一种的运算次数是 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 N2≫NlogN,所以第二种的算法比第一种好。(只考虑与数据量有关的因素和数据量特别大的情况)
插播:
例题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趋近于无穷大时比值只差一个常数,那么它们就被看成同一个数量级的函数。
而在计算机科学中相应的算法,也就被认为是具有相同的复杂度。
- 两种算法在复杂度上相差哪怕只有一点点,
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