1、问题、问题实例、算法的概念区分。

一个例子说明一下:

问题:判断一个正整数N是否为素数   #问题是需要解决的一个需求

问题实例:判断1314是否为素数? #问题实例是该问题的一个具体例子

算法:解决这个问题的一个计算过程描述。   #算法是对计算过程的严格描述

2、算法的性质。

有穷性、能行性、确定性、终止性、输入/输出。

3、算法的描述

自然语言(容易歧义)

自然语言+数学公式(简单方便,还是歧义)

严格形式描述(比如图灵机模型,非常麻烦,难以阅读)

类似编程语言描述

伪代码的形式

该书主要是采用后两者的描述方式进行的。

4、算法与程序的区别

对算法的描述中,有一种就是用编程语言来进行描述。基于这种认识,程序可以看做是采用编程语言进行描述算法的一种实现。但是程序自己的特点又跟具体编程语言的实现有关系。因此,一般我们把抽象描述一个计算过程称之为算法。而把一个计算在某种语言的实现称之为程序。

5、算法设计与分析

介绍了6种算法设计模式

枚举法(枚举全部、找出最优解)、贪心法(根据已有信息,先部分求解,再基于部分得到完整的解)、分治法(将一个复杂问题化解为很多简单的子问题,对这些子问题分别求解,并组合起来得到复杂问题的解)、动态规划法(对于一些复杂的问题,不能一下求解出来。在求解步骤中,不断积累已知信息,然后动态选择已知的最好求解路径)、回溯法(通过探索方式求解,当选择一个方向探索时发现无解,就回溯到前面探索的那个路口往其他方向继续探索,直到得出解)、分支界限法(回溯法的改良版本,它是在探索的过程中,根据已知的信息如果发现这个选择是错误的,就及早将其删除,用来缩小求解空间,加速问题求解的过程)。

当然,这些算法模式是可以混合使用的。

在计算过程中算法是会不断消耗资源的,包括空间资源跟时间资源。而弄清楚算法耗费资源的多少就是算法分析的主要任务。

6、算法的代价及其度量

当一个算法消耗资源时,那么怎么来度量消耗的资源就成为了一个问题。因为计算的代价通常与实例的规模有关系(比如计算1013是否为素数与计算1001313130113是否为素数所花费的时间通常是不同的),因此,人们提出一个方法就是把一个计算开销定义为问题规模的函数。

也就是说,算法分析就是针对一个具体的算法,来确定一个函数关系。这个函数以问题实例的规模n为参量,来反映出这个算法在处理规模n的问题时所消耗的时间(或者空间)代价。

还有一些问题。

1>对于同一个问题,如果它的衡量标准不统一的话,那么得到的算法代价就会差距很大

例如计算素数问题,按照整数的数值作为标准和按照数字串长度作为标准是完全不一样的。这里,整数的数值与其数字串长度有着指数的关系。因此肯定这两个不同标准下得到的算法分析将也会差异很大。

2>对于同一个问题,即使对于同样规模的实例,计算的代价也可能不同

例如同样100个十进制整数,如果为偶数的话,很快就能得出结果。如果为奇数,则要花费很长的时间。

针对这些情况,我们在度量算法的时候。存在几种考虑:

算法A完成工作最少需要多长时间?  #这个没有意义,因为它没有代表价值。

算法A完成工作最长需要多长时间?   #在实际中,最主要是关注这种情况。

算法A完成工作平均需要多长时间?   #对算法A的一个全面评价,但是没有保证。

由于这些问题,对于一个算法分析,给出一个具体精确的描述通常是非常困难的。因此退而求其次,我们设法估算算法复杂性的量级。这样,对于算法的时间和空间性质,最重要的是其量级和趋势,这些是算法代价中的主要部分,而常量因子可以忽略不计了。

基于这些考虑,提出”大O记法“来描述算法的性质。

其中最常用是下面的一组渐进复杂度函数:

O(1)、O(logn)、O(n)、O(nlogn)、O(n²)、O(n³)、O(2n)

从图中就可以看出,随着实例规模的增大,它的算法复杂度增长趋势明显差异很大。算法的复杂度越高,其实施的代价随着规模增大而增大长的速度就快。

当然,这种算法复杂度的分析是具有实际的意义的。

比如,预测天气预报的程序,如果在今天晚上7点之前不能计算出预测明天的结果,那么这个算法就毫无意义。

解决同一问题的不同算法

例子:求斐波那契数列

1>递归算法

def fib(n):

  if n < 2:

    return1

  return fib(n-1) + fib(n-2)

2>递推算法

def fib(n):

  f1, f2 = 1, 1

  for i in range(1, n):

    f1, f2 = f2, f1+f2

  return f2

当使用递归算法的时候,它的时间代价是呈指数增长的。因此,当n比较大时候,这一计算就需要很长的一段时间。

当使用递推算法的时候,它的时间代价是呈线性增长的。所以,相比较递归算法,这个有明显的时间优势。

7、算法分析

算法分析的目的是为了推导出算法的复杂度。书中给出了一些简单的规则

1> 基本操作

其时间复杂度为O(1)。如果是函数调用,应该将其时间复杂度带入,参与整体时间复杂度的计算。

2> 加法规则(顺序复合)

如果算法时两个部分的顺序复合,其复杂度是这两个部分的复杂度之和。

T(n) = T1(n)  + T2(n) = O(T1(n)) + O(T2(n)) = O(max(T1(n), T2(n)))

由于忽略了常量因子,加法等于求最大值,所以取T1(n) 和 T2(n)中复杂度较高的一个。

3> 乘法规则(循环结构)

如果算法是一个循环,循环体将执行T1(n)次,每次执行需要T2(n)时间,那么:

T(n) = T1(n)  * T2(n) = O(T1(n)) * O(T2(n)) = O(T1(n) * T2(n))

4> 取最大规则(分支结构)

如果算法时条件分支,两个分支的时间复杂性分别为T1(n)和T2(n),那么:

T(n) = O(max(T1(n), T2(n)))

利用一个例子计算一下:

for i in range(n):

  for  j in range(n):

    x = 0.0   #O(1)

    for k in range(n):

      x = x + m1[i][k] * m2[k][j]    #O(1)

    m[i][j] = x      #O(1)

x = x + m1[i][k] * m2[k][j]  这个操作是基本操作O(1)。

在for k in range(n)这个循环体内,它要执行n次。因此,这里就是O(1) * n = O(n)

在for  j in range(n)这个循环体内,执行一次需要的时间为O(1) * n + O(1) + O(1) = O(max(O(n), O(1), O(1))) = O(n),而它也需要执行n次。因此这里就是O(n) * n = O(n²)

在for i in range(n)这个循环内,执行一次需要时间为O(n²),它也需要执行n次。因此整个算法时间复杂度为O(n³)。

8、python的计算代价

时间开销

python的很多基本操作并不是常量时间的。因此,需要我们在写程序的时候要注意使用合适的数据结构。在书中列举了很多,比如list的一般加入/删除。还有dict操作的查询和加入新的关键码(平均是O(1),但是最坏的是O(n),主要是利用哈希表技术构造成的)

空间开销

python关于空间开销有两个问题需要注意。

1> python的组合对象没有设置最大的元素个数。当对一个表不断添加元素,后来又删除元素,让表变小,但是占用的存储空间并不会变少。

2> python有着自己的存储管理系统,会将不用的对象进行回收(也就是python的垃圾回收机制)。

最后,还有一点需要注意。就是在考虑程序开发的时候,不但要选择比较好的算法,还要考虑如何做出良好的实现。例如:

def test1(n):

  lst = []

  for i in range(n*10000):

    lst = lst + [i]

  return lst

def test4(n):

  return lst(range(n*10000))

上面的两种方式都能建立一个包含0-10000的整数,但是test1毫无必要的构造了很多的复杂结构,这样使整个算法的时间代价变得更高,从而损害了其可用性。这种情况就是高级语言程序中存在的一些“效率陷阱”。

python数据结构与算法之算法和算法分析的更多相关文章

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

    在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义 ...

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

    Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还 ...

  3. Python 数据结构和算法

    阅读目录 什么是算法 算法效率衡量 算法分析 常见时间复杂度 Python内置类型性能分析 数据结构 顺序表 链表 栈 队列 双端队列 排序与搜索 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归 ...

  4. python数据结构与算法

    最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...

  5. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  6. Python数据结构与算法?

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  7. Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  8. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

  9. python 数据结构与算法之排序(冒泡,选择,插入)

    目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习 ...

  10. python数据结构与算法——链表

    具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向 ...

随机推荐

  1. Java第一次实训课

    //1.1 声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果. package mingye; public class Exc { public static voi ...

  2. java线程学习之wait方法

    wait 等待方法是让线程进入等待队列,使用方法是 obj.wait(); 这样当前线程就会暂停运行,并且进入obj的等待队列中,称作“线程正在obj上等待”. 如果线程想执行 wait 方法,线程必 ...

  3. 远程执行shell脚本的小技巧

    很多时候需要批量跑脚本执行任务,但又不想分发再执行,而是直接一条命令下去就跑脚本,该怎么玩比较嗨? 例如以下脚本: #!/bin/bash echo "$@" echo " ...

  4. Windows 下安装 Memcached

    Windows 下安装 Memcached 官网上并未提供 Memcached 的 Windows 平台安装包,我们可以使用以下链接来下载,你需要根据自己的系统平台及需要的版本号点击对应的链接下载即可 ...

  5. IDEA上的项目托管到码云步骤

    IDEA上的项目托管到码云步骤:1.安装Git2.idea上配置Git    Setting-Version Control-Git    把git.exe改为安装的Git的执行路径如:D:\Prog ...

  6. topcoder srm 630 div1 (2-SAT and SCC template)

    problem1 link 首先计算任意两点的距离.然后枚举选出的集合中的两个点,判断其他点是否可以即可. problem2 link 假设字符串为$s$,长度为$n$.那么对于$SA$中的两个排名$ ...

  7. 如何安装mariadb服务器和解决 can't connect to local mysql server through socket...

    故障现象, ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.s ...

  8. vscode打开django项目pylint提示has not "object" member

    vscode 打开 django 项目提示 has not "object" member 是因为 Django 动态地将属性添加到所有模型类中,所以 ide 无法解析. 解决方案 ...

  9. visual studio code——运行python

    How to run Python in Visual Studio Code Getting Started with Python in VS Code python教程 vs code 安装py ...

  10. MySQL中select、insert、update批量操作语句

    项目中经常的需要使用批量操作语句对数据进行操作,使用批量语句的时候需要注意MySQL数据库的条件限制,这里主要是数据的大小限制,这里对批量插入.批量查找及批量更新的基础操作进行下简单的汇总. 1.批量 ...