【我的理解】函数的增长,大O记号

背景

当我们在描述一个任务所消耗的时间时,一般我们会将任务中的所有步骤所消耗的时间相加,得到总时间,例如:

    总消耗时间=步骤1消耗时间+步骤2消耗时间+......+步骤n消耗时间

如果我们将这里的步骤消耗的时间用 指令执行的次数*指令执行一次的时间 来替换,就是一个算法所消耗的总时间。但是理想与现实总是存在差距的,我们并不能用这种方式来计算算法的总耗时。这里关键的问题在于,不同的编程语言,不同的编译器,不同的CPU,缓存等等因素都将导致执行一次操作的时间各不相同。如果将这些因素统统考虑进去,那么在描述算法复杂度上将寸步难行。

    为此我们需要丢弃这些外部因素,转而只考虑算法中关键操作的执行次数。虽然这样做,使得我们无法精确描述算法的耗时,但是却可以了解大致的趋势。这就是所谓的 渐进分析法

渐进分析法

   一种描述函数在极限附近的行为的方法。

    最常用的是 用一个函数(通常更加简单)来描述另一个函数,在变量趋于∞时的行为。(可以看出来,这种方法得到结论是相对的)。

大O的定义

令f和g为从实数集到实数集的函数。如果存在常数C和k使得只要当x>k时就有|f(x)|<=Cg(x)。我们就说f(x)是O(g(x))的。

从定义中可以得到几个关键信息:

  1.     f和g是定义域和陪域都是实数集的函数
  2.     f和g存在一个关系,即f(x)<=Cg(x)
  3.     f和g的这种关系,必须是在x>k时才成立

换句话说,当变量x的值大于k时,函数f小于或等于函数g乘以C,这个不等式恒成立。

再进一步说,当变量x的值在区间(k,∞)时,函数f的y值小于等于函数g的y值的C倍,也就是函数f的增长比函数g的增长的C倍慢。

所以f(x)是O(g(x))的的意思就是,当x无限增长时,函数f的增长慢与函数的g某个固定的倍数。

大O的定义是对渐进分析法的一种实际应用,通过函数g来描述函数f的相对变化趋势。

其中让我比较困惑的是定义中的C这个常量的含义:用一个较简单的函数并将其扩大C倍,来与另一个函数比较。如下图:


这里的较简单函数g(x)=x²,用其来描述另一个函数f(x)=x²+2x+1。可以看出函数g与函数f并没有任何相交的地方,但是在乘以常数C=4后,Cg(x)与f(x)在k=1处有一个交点,x>k=1之后,函数f(x)始终小于Cg(x)。这样我们就用函数g来描述了函数f的相对增长速度。我们说,当C=4,x>1时,函数f的增长比函数g慢,C和k称为f(x)是O(g(x))的关系的凭证。
    因此我对C的理解为,当我们用一个函数g来描述另一个函数f的相对增长关系时,必须至少相交点,为了使之相交,将函数g扩大C倍,如果它们已经存在交点,C可以为1。所以只要能使它们相交,C可以取不同值,这样f(x)是O(g(x))的关系的凭证就不止一对,可以有很多。
    f(x)是O(g(x)) 告诉我们 f(x)比Cg(x)增长得慢,但满足这种关系的f(x)可能存在多个,所以f(x)是O(g(x))也就告诉我们f(x)∈O(g(x)),即所有满足O(g(x))关系的函数的集合。

猜你喜欢

转载自blog.csdn.net/paxhujing/article/details/80158932