摘要:1.计算领域的核心理念2.渐进记法3.图与树的实现4.提防黑盒子html
1.计算领域的核心理念python
算法---一个执行过程,包含了可以解决某个特定问题的有限步骤集。(图灵机能够理解为是这个待解决问题的正规描述形式)git
图灵机---计算领域的理论核心,图灵机有着各类不一样的具体实现,但每种实现均可以看作一个有限状态机:由一个有限的状态集(包括已完成部分)与各类用于触发读写操做及不一样状态切换的潜在符号共同组成。(能够将其看作机器运行所需的规则)。github
随机存取机---适用于更细粒度上的算法分析,从标准单处理器计算机中简化出的一种抽象模型,比如有一块能够直接存取的内存,而不是同图灵机那样的可滚动的纸带。算法
应具有的属性:数据库
问题---就目标而言,问题实际就是输入与输出之间的某种关系,更精确的讲,就是指一组集合对之间的数学意义上的关系,而且借由指定这种关系的过程,问题会被肯定下来。编程
编码---对输入 0 1 编码,问题实例的大小,能够简单当作编码它所需的内存大小(一般与编码自己的确切属性没太大关系)。网络
2.渐进记法数据结构
append insert 的例子;并发
研究算法分析时要关注的重点:常数单位上的差距(一般取决于一些特定事物如通用编程语言的性能,硬件速度等);焦点 集中在那些可以独立于具体实现以外的属性。
2.1. 渐进记法是用于分析算法与数据结构的重要工具,核心思想为提供一种资源保护形式,主要用于分析某项功能在应对必定规模参数输入时所须要的资源(时间 内存 等)
渐进记法使用由希腊字母构成的记号体系。Ο记法表明渐进上界,Ω记法表明渐进下界,Θ记法表明前两种记法的交集。
2.2. 渐进记法 简化了咱们面临的数学问题。
时间复杂度 | 相关名称 | 相关示例及说明 |
Θ(1) | 常数级 | 哈希表的查询与修改 |
Θ(lgn) | 对数级 | 二分搜索 |
Θ(n) | 线性级 | 列表遍历 |
Θ(nlgn) | 线性对数级 | 任意值得最优化排序,其复杂度等同于Θ(lgn!) |
Θ(n2) | 平方级 | 拿n个对象进行相互比对 |
Θ(n3) | 立方级 | Floyd-Warshall算法 |
Ο(nk) | 多项式级 | 基于n的k层嵌套循环(k为整数,k>0) |
Ω(kn) | 指数级 | 每n项产生一个子集(k>1) |
Θ(n!) | 阶乘级 | 对n个值执行全排列操做 |
多项式级与指数级分割着易处理问题和难处理问题,仅通常而言。
几条简单规则:加法运算中,只以阶数最高的被加数为准;乘法运算中,常数因子忽略不计;保持相关上下界的严谨性;Θ(f) + Θ(g) = Θ(f+g);Θ(f) * Θ(g) = Θ(f*g)。
三种重要状况:1.最好状况(理想输入时的运行时间)2.最坏状况(所能给的最佳保证)3.平均状况(回避)
实证式算法评估:1.当没有把握时,就把可能的解决方案都试一遍。2.用timeit模块进行计时:
import timeit timeit.timeit("x = 2 + 2") $命令行环境调用 $ python -m timeit -s"omport mymodule as m" "m.myfunction()"
3.使用profiler找出瓶颈:给出关于执行时间都都花在哪里的详细信息,从而肯定代码中须要优化的部分。当主函数是main()时,执行下列代码,能够给出各个函数的运行时间。(可使用Python Call Graph 工具可视化的看到代码的调用状况)
import cProfile cProfile.run('main()')
4.绘制出结果。matplotlib绘制工具包
5.根据计时比对结果作出判断
6.经过相关实验对渐进时间作出判断
3.图Graph与树Tree的实现
图结构能够用来表现彷佛全部类型的结构与系统,而树结构只是图结构的一种特殊状况但至关广泛。若是咱们的问题能够用树结构来描述时,基本上已经有了有效的解决方案。
从七桥问题开始:全面介绍图论 https://www.jiqizhixin.com/articles/2018-03-11-2 (https://medium.freecodecamp.org/i-dont-understand-graph-theory-1c96572a1401)
数据结构与算法 图论 https://zhuanlan.zhihu.com/p/25498681
入门图论与网络分析 含python代码 https://www.jiqizhixin.com/articles/2018-08-07-16
3.1邻接列表
#简单明了的邻接集表示方法 a,b,c,d,e,f,g,h = range(8) N = [ {b,c,d,e,f}, #a {c,e}, #b {d}, #c {e}, #d {f}, #e {c,g,h}, #f {f,h}, #g {f,g}, #h ] >>>b in N[a] True >>>len(N[f]) 3
若是某些代码存在于某个源文件里,而咱们又想在交互解释其中研究的话,使用python的 - i 开关来运行:
python -i listing.py
#其余表示方法 #邻接列表 成员检测时速度放缓 a,b,c,d,e,f,g,h = range(8) N = [ [b,c,d,e,f], #a [c,e], #b [d], #c [e], #d [f], #e [c,g,h], #f [f,h], #g [f,g], #h ] #加权邻接字典 a,b,c,d,e,f,g,h = range(8) N = [ {b:2,c:1,d:3,e:9,f:4], #a {c:4,e:3}, #b {d:5}, #c {e:1}, #d {f:2}, #e {c:5,g:6,h:7}, #f {f:2,h:6}, #g {f:3,g:4}, #h ] #邻接集的字典表示法 相似字符类的邻接列表(成本略低) a,b,c,d,e,f,g,h = range(8) N = { 'a': set('bcdef'), #a 'b': set('ce'), #b 'c': set('d'), #c 'd': set('e'), #d 'e': set('f'), #e 'f': set('cgh'), #f 'g': set('fh'), #g 'h': set('fg'), #h } #一个图的最佳表示法 取决于 咱们要用它作什么
3.2邻接矩阵
节点编号从0 到V-1,用0 和1 来充当真值(无权图中),对角线上的值全为0 ,在无向图邻接矩阵关于对角线对称相等,
#用嵌套list实现的邻接矩阵 a,b,c,d,e,f,g,h = range(8) N = [ [0,1,1,1,1,1,0,0], #a [0,0,1,0,1,0,0,0], #b [0,0,0,1,0,0,0,0], #c [0,0,0,0,1,0,0,0], #d [0,0,0,0,0,1,0,0], #e [0,0,1,0,0,1,0,0], #f [0,0,0,0,0,1,0,1], #g [0,0,0,0,0,1,1,0], #h ] #能够更改不一样的权值 #非法的权值就设置为极大值, float('inf') inf = float('inf') #权值为 inf
3.3树的实现
树自己就是图的特殊状况,但许多特定问题用特定的树结构更容易实现。
#简单的树结构 表示为二叉列表 >>>T = [["a","b"],["c"],["d",["e","f"]]] >>>T[0][1] 'b' >>>T[2][1][0] 'e' #二叉树类 class Tree: def __init__(self,left,right): self.left = left self.right = right >>>t = Tree(Tree("a","b"),Tree("c","d")) >>>t.right.left 'c' #多路搜索类 class Tree: def __init__(self,kids,next=None): self.kids = self.val = kids self.next = next >>>t = Tree(Tree("a"),Tree("b",Tree("c",Tree("d"))))) >>>t.kids.next.next.val 'c'
参考:Bunch模式 http://www.javashuo.com/article/p-tjuduhxl-cz.html
3.4存在多种表示法
空泛的判断句子没有,咱们更应该针对具体问题思考该任务的渐进性能。
最主要的为以上介绍的两种。另外,需注意编程中没有注意就用到的图实现(隐式)
参考:图结构库
python-graph : https://github.com/pmatiello/python-graph
Graph-tool : https://graph-tool.skewed.de/
此外还有 Pygr 基于图结构的数据库 Gato基于图结构的动画工具箱 PADS基于图结构的算法集
4.提防黑箱子
编程时,咱们必须依赖一些并非本身编写的组件,称为黑箱子。不注意的话,Python和机器自己的不少机制会成为咱们的绊脚石。
4.1隐性平方级操做
4.2浮点运算的麻烦
5.小结
基础概念,渐进记法与图结构,黑箱子......
加油 嘿嘿嘿!