《python算法笔记》(二)基础知识

1.计算机的核心概念


  • 图灵论文《论数字计算在决断难题中的应用》是现代计算机科学的基石。他提出的图灵机概念成为了计算机理论的核心概念。
  • 图灵机(Turing machine):A Turing machine is a simple
    (abstract) device that can read from, write to, and move along an infinitely long strip of paper
  • 实际中的机器有所不同,但都叫做有限状态机(finite state machine).
    有限状态机(finite state machine):it has a finite set of states (some
    of which indicate that it has finished), and every symbol it reads potentially triggers reading and/or
    writing and switching to a different state. You can think of this machinery as a set of rules.
    这些看似简单的机器完全的概述了计算机的本质。

  • 算法(Algorithm):An algorithm is a procedure, consisting of a finite set of steps (possibly including loops and
    conditionals) that solves a given problem in finite time.

  • 图灵机就是一种模型,准确的描述算法解决问题的过程
    现代计算机用存储器块取代了纸带,就是我们所熟知的内存(Random-Access machine)
  • 图灵机是一种抽象的简化的标准单处理计算机,并有以下特点:
    1.顺序执行
    2.标准的基础操作(例如算数,比较和内存存取)花费常量时间。
    3.计算机字节(常量时间能够处理的值得大小)并不是无限制的。

决断难题(Entscheidungsproblem):David Hilbert提出的问题,是否存在一个算法来判断数学陈述的正确性

2.渐进符号


  • O:上界
  • Ω:下界
  • Θ:上下综合
  • 渐进时间复杂度的常见例子

复杂度 名称 例子
Θ(1) 常量时 哈希表的查找修改
Θ(lgn) 对数 二插树搜索
Θ(n) 线性 便利列表
Θ(nlgn) 对数线性 最佳排序算法
Θ(n2) 二次方 n个对象相互比较
Θ(n3) 三次方 floyd-warshall最短路径算法
Θ(nk) 多项式 k层嵌套循环
Θ(kn) 指数 处理n个元素的每个子集(k=2)
Θ(n!) 结成 处理n个值的每个顺序
  • 三种重要的情况
    1.最佳情况:
    2.最坏情况
    3.平均情况

  • 算法的经验评估
    算法设计的目的是获得低的渐进运行时间(设计高效的算法),算法工程的目的是减少那个渐进复杂度下的隐藏的常量。
    1.先用直接发解决问题,在考虑优化算法。
    2.使用timeit来计算时间
    3.用分析工具来发现瓶颈
    4.画下你的结果
    5.在你以运行时间比较为基础做出结论时要当心随机误差。
    for else 结构富国循环没有过早的被break终止,则执行 else的子句
  • 3.实现图和树

    3.1图的实现(临接表/临接矩阵)

    2-1 A Straightforward Adjacency Set Representation

    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
    ]

    2-2 Adjacency Lists

    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
    ]

    2-3 Adjacency dicts with Edge Weights

    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:8},                        # c
        {e:7},                        # d
        {f:5},                        # e
        {c:2, g:2, h:2},              # f
        {f:1, h:6},                   # g
        {f:9, g:8}                    # h
    ]

    2-4 Dict with Adjacency Sets

    N = {
        'a':set('bcdef'),
        'b':set('ce'),
        'c':set('d'),
        'd':set('e'),
        'e':set('f'),
        'f':set('cgh'),
        'g':set('fh'),
        'h':set('fg'),
    }

    2-5 An Adjacency Matrix, Implemented with Nested Lists

    a, b, c, d, e, f, g, h = range(8)
    #     a b c d e f g h
    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,0,1,1],    # f
         [0,0,0,0,0,1,0,1],    # g
         [0,0,0,0,0,1,1,0]]    # h

    2-6 A Weight Matrix with Infinite Weight for Missing Edges

    a, b, c, d, e, f, g, h = range(8)
    _ = float('inf')
    #     a b c d e f g h
    W = [[0,2,1,3,9,4,_,_],    # a
         [_,0,4,_,3,_,_,_],    # b
         [_,_,0,8,_,_,_,_],    # c
         [_,_,_,0,7,_,_,_],    # d
         [_,_,_,_,0,5,_,_],    # e
         [_,_,2,_,_,0,2,2],    # f
         [_,_,_,_,_,1,0,6],    # g
         [_,_,_,_,_,9,8,0]]    # h

    3.2树的实现

    2-7 A Binary Class

    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'

    2-8 A Multiway Tree Class

    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 Pattern(一个灵活的类,允许你在构造器中制定任一属性)

    class Bunch(dict):
        def __init__(self, *args, **kwds):
            super(Bunch, self).__init__(*args, **kwds)
            self.__dict__ = self
    
     >>> T = Bunch
     >>> t = T(left=T(left="a", right="b"), right=T(left="c"))
     >>> t.left
     {'right': 'b', 'left': 'a'}
     >>> t.left.right
     'b'
     >>> t['left']['right']
     'b'
     >>> "left" in t.right
     True
     >>> "right" in t.right
     False

    3.3图和树还有其他表示方法,具体的实现要结合具体的问题

    哈希:为任意一个对象计算出一个整数

    4.小心黑盒子(底层实现)

    如果不知道底层实现可能会增加算法的时间复杂度。
    例如:

    1.check in list and set

    >>> from random import randrange
    >>> L = [randrange(10000) for i in range(1000)]
    >>> 42 in L
    False
    >>> S = set(L)
    >>> 42 in S
    False
    由于list其实是array,所以对list进行check的时间复杂度是线性的,set是经过哈希的,所以对lset进行check的时间复杂度是常量时间。
    

    2.构造字符串

    >>> s = ""
    >>> for chunk in input():
    ...
    s += chunk

    它起作用,因为在python中做了一些聪明的优化,但是如果到达一定的大小,优化就会崩塌,时间复杂度就会上升到二次方。每一次+=操作都会创建一个新的字符串。一个更好的方法是:

    >>> chunks = []
    >>> for chunk in input():
    ...
    chunks.append(chunk)
    ...
    >>> s = ''.join(chunks)

    更进一步的简化

    >>> s = ''.join(input())

    3.Floats的麻烦
    float的精度不高,在要求高精度的情况下请用decimal

    你可能感兴趣的:(算法,笔记,python)