分析算法的数学

386 阅读10分钟

在这篇文章中,我们将探讨分析算法和计算时间复杂度所涉及的数学问题。在我们进入正文之前,首先我们要了解什么是算法。基本上,算法不过是用来执行一项特定任务的一些步骤。在计算机科学中,我们说算法是我们需要执行的步骤,以完成一项特定的任务。

重要的是,我们在分析算法时需要非常小心。算法需要被分析,因为它可以帮助我们发现我们的代码或程序是否有效。在分析算法时,会用到很多数学知识。所以这篇文章就是围绕着这一点展开的。我们将看到基本的数学概念和Big Oh符号,渐近分析等。因此,让我们开始吧。

内容表

  1. 底限和上限函数
  2. 2的倍数
  3. 对数和指数
  4. 算术和几何级数
  5. 因数
  6. 排列和组合
  7. 加泰罗尼亚语数
  8. 分析算法
  9. 渐近分析

首先,我们将看到一些用于分析算法的基本数学公式或概念。

下限和上限函数

  1. 我们将从学习floor和ceil函数开始。

Floor函数返回小于或等于一个数字的最大整数。例如:
如果一个数字是2.6,那么floor(2.6)返回2。

Ceil函数返回大于或等于一个数字的最大整数。例如:
如果一个数字是 18.4,那么 floor(2.6) 返回 19。

2的倍数

  1. 当我们谈论计算机科学时,我们首先想到的是二进制数,并由此产生了2的的概念。当我们想把二进制数转换成十进制数时,就必须使用2的幂的概念。在各种应用中,我们必须利用2的幂的帮助,特别是在比特操作中。

记住初始值的2的幂值有助于快速进行与编程有关的计算。

  • 20= 1
  • 21= 2
  • 22= 4
  • 23= 8
  • 24= 16
  • 25= 32
  • 26= 64
  • 27= 128
  • 28= 256
  • 29= 512
  • 210= 1024 ~ 1000 =103
  • 211= 2048
  • 212= 4096

对数和指数

  1. 现在我们来探讨一下对数和指数。我们都知道对数和指数,它们的属性。重要的是,它们在分析算法方面起着非常重要的作用。我们将看到它们是如何被用于确定算法所需的时间或空间的。在计算机科学中,log2x告诉我们需要多少比特来保持x值。比如我们看到log2256=8,这就告诉我们,8位可以容纳256个数字。我知道你们知道对数和指数的属性,但我有责任向你们解释所有的属性。

对数的含义。

如果logBA=C,那么。CB=A

其中

  • B是对数的基数。在大多数计算中,B没有被提及。在编程中,默认情况下,B被认为是2。在数学中,B默认等于e(欧拉常数)。
  • 注意,在分析算法的特定情况下,你可能需要考虑B的其他值。考虑这个3路分区快速排序的案例。

对数的特性

  • 对数A/B = 对数A - 对数B
  • 对数AB=对数A+对数B
  • 对数AB= B对数A

与y=x(线性函数)相比,log x图形增长缓慢。

指数特性

  • AB+C=AB*AC
  • B =AlogAB
  • ABC= (AB)C

与y=x(线性函数)或对数函数相比,exp(x)图形增长得非常快。

算术和几何级数

  1. 让我们来了解一下级数的情况。在数学中,有三种标准的级数,即算术级数、几何级数和谐波级数。最常见的算术级数是在分析算法时使用的,当我们要找到任何算法的时间复杂性。

算术级数是一种级数或数字系列,其中两个相邻元素之间的差等于任何两个相邻元素之间的差。例如:1,2,3,4,5,6是一个AP,因为每个相邻元素之间的差值是1。大多数情况下,我们必须使用自然数之和的公式,它来自AP之和。

1 + 2 + 3 + 4 + ...+ n = n*(n+1)/2

AP之和 = (n/2) * (2a+(n-1)d)

其中。

  • n是序列中的总数字
  • a是第一项
  • d是公差。

这将有助于我们在寻找正方形或立方体之和的时候。

10+20+ ...+n0= N

11+21+ ...+n1= N * (N+1) / 2

12+22+ ...+n2= (N * (N+1) * (2 * N+1))/6

13+23+ ...+n3= (N2* (N+1)2) / 4

几何级数是一种相邻元素之间有共同比率的级数。例如:2,4,8,16...是一个GP,因为有共同的比率,即4/2 = 8/4 = 16/8 = 2

GP之和=(1-an+1)/(1-a)

其中a是公共比率。

像n个自然数的总和一样,我们也可以定义n个自然数的平方和的公式,也可以定义n个自然数的立方的总和。

这些快速序列将帮助你分析算法。

A0+A1+ ...+an-1=an- 1

20+21+ ...+2n-1=2n- 1

阶乘

阶乘是1到N的所有数字的乘法,N的阶乘表示为N!。

N! = 1 * 2 * ...* (N-1) * N

0的阶乘被认为是1。

0! = 1

1! = 1

排列和组合

  1. 另一个在分析算法或解决特定问题时最常使用的数学概念是关于排列和组合

在理解排列和组合之前,我们需要了解阶乘。当我们写下n!这是什么意思?它基本上告诉我们,我们可以用多少种方式来排列一个大小为n的数字。比如我们有一个数字234,那么我们可以排列这个数字的总方式是n!比如我们可以有243,324,342,432,423,234。这个数字总共有6种可能的排列方式,如果我们进行n!或3!就会发现是6。

排列组合。它基本上是对一些给定数量的元素进行排列,每次都是一个或整个。

例子。如果我们要从总共n个元素中找出r个元素的排列,那么我们的公式为

nPr= n! /(n-r)!

组合。它是对给定数量的元素的选择,每次都是一个或整个。这些选择是所有可能的不同选择。

例子。如果我们想从总共n个元素中选择一些r元素,那么我们的公式为

nCr= n!/(r!*(n-r)!)

序列中的元素数量。

N/2, N/4, N/8, N/16, ..., 1 = logN的元素数

作为一个广义的方程。

N/B, N/(B2), N/(B3), N/(B4), ..., 1 =logBN的元素数

加泰罗尼亚数

  1. 加泰罗尼亚数。这是另一个数学概念。它是一个正整数的序列,其中序列中的第n项,表示为Cn,在以下公式中可以找到。

Cn= (2 * n)!/ ((n+1)!* n!)

现在,如果我们用1,2,3来代替n的值来定义一个序列,我们会得到。

1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, ...

加泰罗尼亚数直接关系到我们可以通过连接没有两条线段交叉的顶点,将一个n形(五边形、六边形、七边形)分割成多少个三角形。可能性的数量等于Cn-2。

例子。如果我们想找出将五边形转化为三角形的方法,使连接顶点的两条线段都不交叉。

一个五边形有五条边,所以我们需要把n=3放入加泰罗尼亚数字公式中,找到C5-2,或者C3。我们得到的答案是5,这意味着有5种方法可以将五边形转换成三角形,使连接顶点的两条线段不交叉。

分析算法。

当我们听到分析算法时,我们脑海中出现的第一个词是时间和空间复杂性。

时间复杂度:它是一个算法完成一个特定任务所需的总时间。
空间复杂度
:它是一个算法在执行程序时使用的总空间或内存。

为了找到时间和空间的复杂性,我们将使用渐进分析法,但在此之前,让我们了解在计算时间和空间复杂性时有哪些不同的情况。

  1. 最佳情况。它可以被定义为在任何输入大小'n'的情况下,算法完成一项任务所需的最小时间量。
  2. 平均情况。它可以被定义为一个算法在任何输入大小'n'下完成任务所需的平均时间。
  3. 最坏情况。它可以被定义为一个算法在任何输入大小'n'下完成任务所需的最大时间量。

渐进式分析

一个算法的资源通常被表示为关于输入的函数。如果我们想有效地研究函数的增长,我们将函数简化为

f(n) =an2+bn+c

然后我们看到主导项是n2,所以我们忽略其他的项,只使用这个项。

渐近分析是一种表示极限行为的技术。它可以用来分析一个算法在大数据集上的性能。任何函数在n->infinityn时都被称为渐进等价于n2,它被符号化地写成f(n)近似等于n2。

有3种符号被用来计算算法的运行时间。它们是。

  1. Big-oh符号。它是表达算法运行时间上限的正式方法。函数f(n)=O(g(n))只存在于当且仅当存在一个正常数c,使得f(n)<= c*g(n)。这里g(n)是函数f(n)的上界,因为g(n)的增长速度比f(n)快。

  2. 欧米茄记号。它是表达算法运行时间的下限的正式方法。它与Big-oh记法完全相反。函数f(n)=Ω(g(n))只存在于当且仅当存在一个正常数c,使得f(n)>= c*g(n)。这里g(n)是函数f(n)的下限,因为g(n)比f(n)增长缓慢。

  3. Theta符号。它是表达算法运行时间的严格约束的正式方法。这种记法是最精确和准确的记法。函数f(n)=Θ(g(n))存在,当且仅当存在两个正常数c1,c2,使得_c1g(n)<=f(n)<=c2g_(n)。这意味着f(n)位于c1g(n)和c2g(n)之间,这就是为什么它是紧约束。

我们通常用Big-Oh来表示算法的运行时间,但如果我们用theta符号来表示它,会更准确。

考虑一个程序。

x:=0;
for i=1 to n do
 for j=1 to n do
   x:=x+1;

现在在这段代码中,如果我们想找到它所花费的时间,那么我们该怎么做。渐进式符号和分析在这个时候出现了。我们可以看到有两个嵌套循环在迭代,x被递增的总次数就是执行的总指令数。
所以从数学上讲,1+2+3+4+...+n=n*(n+1)/2
现在我们必须看到主导项,在这种情况下就是n2。所以时间复杂度将是O(n2

)。

让我们举一个泡点排序的小代码片断的例子,试着理解如何计算运行时间。

for i=1 to n-1 
    for j=1 to n-i-1 
        if a[j]>a[j+1])
            a[j]<->a[j+1]   //swapping

在这种情况下,我们将使用冒泡排序技术对我们的数组元素进行排序。
分析。如果我们有n个元素,那么在第一遍会做n-1次比较,在第二遍会做n-2次,以此类推。因此,总的比较将是:
(n-1)+(n-2)+(n-3)+...+1 = n*(n-1)/2
(
正如我们上面看到的AP总和)
在这个过程中,主导项是n2,所以时间复杂性为O(n2

)

。让我们来分析一些情况。

最好的情况。当我们有一个已经排序的数组时,时间复杂度将是O(n),远远好于O(n2)。

平均情况。当我们有两个或更多的元素没有被排序,在这种情况下,所花费的时间将是O(n2)。

最坏的情况。当我们有一个降序排列的数组时,那么时间复杂度将再次达到O(n2)。

现在我们已经看到了一些分析算法时使用的基本数学概念,所以我想在OpenGenus结束这篇文章。

谢谢你,
祝你阅读愉快。