数据结构与算法:算法分析

目录

实验研究
常用函数
渐近分析 

一.实验研究(Experimental studies)

1.运行时间测量

  • 时钟时间 time.time()
  • CPU时间 time.clock()
  • 基准时间 timeit.timeit()

在执行算法的时候,我们可以通过改变输入规模的大小和记录花费的时间来研究运行时间。

在python中使用time模块的time函数来记录算法的运行时间:

from time import time
start_time=time()
run algorithm
end_time=time()
elapsed=end_time-start_time #运行时间

由于许多进程使用计算机的CPU,所以在测试时,运行时间也将取决于在计算机上运行的其他进程。所以一个更公平

的衡量标准是计算CPU cycles,会使用到time.clock()函数。但是即使使用这种方法,在同一电脑上执行同一算法,

测试结果也可能不同,它取决于电脑的系统,所以在python中更好的方法是使用timeit模块。

 2.实验研究中的挑战/困难

  • 实验中两个算法的运行时间很难直接进行比较除非实验在相同的硬件和软件环境中执行
  • 实验中只能完成有限的输入规模,所以一些重要的输入可能会被遗漏掉
  • 一个算法必须完全执行才能研究它的实验运行时间(实验研究中最严重的缺点)

3.超越实验分析

为了分析算法的运行时间而不执行实验,我们直接对一个算法的高级描述(可以是一个实际的代码片段或者是

语言无关的伪代码(pseudo-code))进行分析。我们定义一系列的基本操作:

• Assigning an identifier to an object
• Determining the object associated with an identifier
• Performing an arithmetic operation (for example, adding two numbers)
• Comparing two numbers
• Accessing a single element of a Python list by index
• Calling a function (excluding operations executed within the function)
• Returning from a function

不去确定每个基本操作的具体时间,我们只需记录每个基本操作的执行次数,并使用 t 来衡量算法的执行时间。

4.最坏情况分析和最好情况分析

最坏情况分析比平均情况分析容易的多,它只需要识别最坏情况的输入,对我们来说比较简单。

二.常用函数

1.The Constant Function-常数函数

  f(n)=c

2.The Logarithm Function-对数函数

  f(n)=logbn ,n>1

通常情况下,会忽略掉基数:logn=log2n

性质:对于任何实数a>0,b>1,c>0,d>1,

 3.The Linear Function-线性函数

  f(n)=n

 4.The N-Log-N Function

  f(n)=nlogn

 5.The Quadratic Function-二次函数

  f(n)=n2

 6.The Cubic Function and Other Polynomials-立方函数和其他多项式

  立方函数:f(n)=n3

  多项式:

 7.The Exponential Function-指数函数

  f(n)=bn

三.渐近分析

1.渐近记号

01--大O记号

定义--O(g(n))={f(n):存在正常数c和n0,使对所有的n≥n0,有0≤f(n)≤c*g(n)}

理解--O(g(n))是一个函数集合,f(n)是满足条件的一个函数,

大O记号在一个常数因子内给出一个函数的上界。

02--大Ω记号

定义--Ω(g(n))={f(n):存在正常数c和n0,使对所有的n≥n0,有0≤c*g(n)≤f(n)}

理解--在这里,大Ω记号给出了一个函数的下界。

03--大Θ记号

定义--Θ(g(n))={f(n):存在正常数c1,c2和n0,使对所有的n≥n0,有0≤c1*g(n)≤f(n)≤c2*g(n)}

理解--对于任一函数f(n),若存在正常数c1,c2,当n充分大时,f(n)能被夹在c1*g(n)和c2*g(n)之间

如图所示,三种记号的图例:

2.举例分析

01--Analysis of the Maximum-Finding Algorithm

查找最大值代码如下

def find_max(data):
    biggest = data[0]
    for val in data:
        if val > biggest :
            biggest = val
    return biggest 

分析--我们在这里分析的是biggest别赋值的次数:

最坏情况下,data如果以递增顺序排列,biggest需要被赋值n-1次,该赋值语句运行时间为O(n)

但是如果data是随机的排列的。在循环中,只有当val>biggest的时候,biggest才会被赋值。如果序列是随机的顺序,

循环到第j个元素时,第j个元素是前j个元素中最大值得概率为1/j,所以biggest被赋值的次数=1+1/2+1/3...+1/n.

根据下面这个定理,可以得知biggest赋值语句运行时间为O(logn)

02--Three-Way Set Disjointness

有3个序列A,B,C,假设每个序列里面没有重复的元素,但是三个序列中会有相同的元素。

disjoint1函数用来判断三个序列中是否含有元素x既存在A中,又存在B中还有C中。

def disjoint1(A,B,C):
    for a in A:
        for b in B:
            for c in C:
                if a==b==c:
                    return False
    return True

分析--从代码中很容易看出----最坏情况下,该算法的运行时间为O(n3)

加强版:disjoint2函数如下

def disjoint2(A,B,C):
    for a in A:
        for b in B:
            if a==b:
                for c in C:
                    if a==c:
                        return False
    return True

分析--最坏情况下,该算法的运行时间为O(n2)。最坏情况下,A中的每个元素都和B中的都一样,

则C中的循环执行n次,所以A和C中循环运行时间为O(n),B中循环运行时间为O(n2).所以最坏

情况下,该算法的运行时间为O(n2)。

03--Element Uniqueness

和上个例子相关的问题就是集合中每个元素是独一无二的问题。

第一种解决方法是使用嵌套循环,外层index为j,内层index为k,k从j+1开始遍历数组。代码如下:

def unique1(S):
    for j in range(len(S)):
        for k in range(j+1,len(s)):
            if S[j]==S[k]:
                return False
    return True

 分析--第一次执行外层循环时,内层循环执行n-1次,第二次执行外层循环时,内层循环执行n-2次,

所以最坏情况下,内层循环共执行(n-1)+(n-2)+...+2+1=n(n-1)/2,运行时间为O(n2)

第二种解决方法是先将序列进行排序,再进行比较,代码如下:

def unique2(S):
    temp=sorted(S)
    for j in range(1,len(S)):
        if S[j-1]==S[j]:
            return False
    return True

分析--代码中使用python内置函数sorted()对序列进行排序,排序算法保证了最坏运行时间为O(nlogn)。

排序完成后,循环序列运行时间为O(n)。所以该算法最坏运行时间为O(nlogn)

Data Structures and Algorithmin Python讲的很细。

初步的算法分析算是看完了,进度这么慢,只能假期来凑喽

注:转载请注明出处

  

时间: 2024-10-13 17:23:30

数据结构与算法:算法分析的相关文章

Python数据结构与算法--算法分析

在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义域是输入数据的长度,值域通常是执行步骤数量(时间复杂度)或者存储器位置数量(空间复杂度).算法分析是计算复杂度理论的重要组成部分. 本文地址:http://www.cnblogs.com/archimedes/p/python-datastruct-algorithm-analysis.html,转

Python数据结构与算法--List和Dictionaries

Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还是牺牲了不常用的操作的性能来成全常用功能. 本文地址:http://www.cnblogs.com/archimedes/p/python-datastruct-algorithm-list-dictionary.html,转载请注明源地址. 设计者有很多的选择,使他们实现list的数据结构.这些选

数据结构与算法1

数据结构与算法(一),概述 转载请注明出处:http://www.cnblogs.com/wangyingli/p/5919297.html 数据结构学了有一年的时间了,但是一直没有好好的总结一下,现在回想起来,感觉好像都不怎么记得了.所以接下来一段时间我将重新学习一下,算是温故而知新了.本着「分享是一种美德」的精神,我将把我的学习总结记录下来,并与大家分享. 本节的主要内容有: 一.数据结构 1.定义 2.关于数据结构的几个术语 3.逻辑结构与物理结构 二.抽象数据类型 三.算法 四.算法的复

数据结构和算法之时间复杂度和空间复杂度

前言 上一篇<数据结构和算法>中我介绍了数据结构的基本概念,也介绍了数据结构一般可以分为逻辑结构和物理结构.逻辑结构分为集合结构.线性结构.树形结构和图形结构.物理结构分为顺序存储结构和链式存储结构.并且也介绍了这些结构的特点.然后,又介绍了算法的概念和算法的5个基本特性,分别是输入.输出.有穷性.确定性和可行性.最后说阐述了一个好的算法需要遵守正确性.可读性.健壮性.时间效率高和存储量低.其实,实现效率和存储量就是时间复杂度和空间复杂度.本篇我们就围绕这两个"复杂度"展开

数据结构与算法系列研究三——字符串

字符串的研究和KMP算法分析和实现 一.串的定义 串是计算机非数值处理的基本对象.串是一种特殊的线性表,它的每个结点仅由一个字符组成,并且单个元素是无意义的.    1.串(string):是由0个或多个字符组成的有限序列,记作:          S="a1a2...an"  (n>=0)          其中:S是串名,两个双引号括起来的字符序列为串的值.双引号不属于串.                   ai(1<=i<=n)为字母.数字或其它符号.    

java数据结构与算法之顺序表与链表深入分析

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 ??数据结构与算法这门学科虽然在大学期间就已学习过了,但是到现在确实也忘了不少,因此最近又重新看了本书-<数据结构与算法分析>加上之前看的<java数据结构>也算是对数据结构的进一步深入学习了,于是也就打算

《数据结构与算法》和《设计模式》之开门见山篇

老生常谈的话题,大家都知道程序是由数据和指令构成,数据结构和算法很重要,可是我就是没有时间去仔细琢磨这东东啊.借口!在国内浮躁的IT氛围之大环境影响下,确实要做到想大学时那样,从头到尾把数据结构的东西看个遍真的很难. 有人认为数据结构这东西平时根本就用不上,最多可能会用到诸如链表和一些排序算法而已,而这些东西随便在网上度娘一下就一大堆.你顺手“借鉴一下”,Copy下,调试了没问题.你大可以说你自己会了.而且你还是“站在巨人的肩上”.用小沈阳的话“有意思吗”,“没意思”.有人认为数据结构这东西太难

用python语言讲解数据结构与算法总述(一)

关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem Solving with Algorithms and Data Structures Using Python>,地址为:http://interactivepython.org/runestone/static/pythonds/index.html是英文的,写的不错,里面代码的实现也很详细,很多有趣的例子,于

数据结构与算法-怎样计算时间复杂度

今天我们来谈一下怎样计算时间复杂度. 时间复杂度概念:(百度版) 同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率. 算法分析的目的在于选择合适算法和改进算法. 计算机科学中,算法的时间复杂度是一个函数,它定量描写叙述了该算法的执行时间. 这是一个关于代表算法输入值的字符串的长度的函数.时间复杂度经常使用大O符号表述,不包含这个函数的低阶项和首项系数.使用这样的方式时.时间复杂度可被称为是渐近的.它考察当输入值大小趋近无穷时的情况. 注意:本文承接上一篇<数据结构与算法-

数据结构与算法-如何计算时间复杂度

今天我们来谈一下如何计算时间复杂度. 时间复杂度概念:(百度版) 同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率.算法分析的目的在于选择合适算法和改进算法. 计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间.这是一个关于代表算法输入值的字符串的长度的函数.时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数.使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况. 注意:本文承接上一篇<数据结构与算法-函数的渐近增长