算法设计搬运(1)——basics

前言

算法的重要性不言而喻,也是因为个人刚刚修完算法课,所以利用这个假期看看笔记再整理一下所学内容。
这篇文章及后续(如果有)主要是围绕南加 csci-5701 这门课的内容整理。此外还可能会以 Algorithm Design2 这本书为补充。(因为我并没有买Victor自己新编的教材,所以以下所有“ 书 ”都指 Algorithm Design)
虽然这门课是号称研究生级别的课程,但整体来讲本科生学习难度应该也可以接受。Basics(书的前三章)几乎完全覆盖了本科数据结构的所有内容。课程后面主要讲了了贪心算法、分治法、动态规划、网络流问题、线性规划和NP问题。此外书还介绍了PSPACE、近似算法、局部搜索和随机算法。这部分我还没啃完,应该不属于搬运的范畴。

1. Basics

1.1 Runtime Complexity

书中这里的叫法是 Asymptotic Order of Growth,介绍了三种 notation。O Ω \Omega Ω Θ \Theta Θ

  • O 对应 worst-case runtime complexity,算法的下限 。
    def: f(n) = O(g(n)), if there exists constants c > 0 and n0 > 0 that for all n ≥ n0,we have f(n) ≤ c·g(n). 也就是说对于足够大的n,函数 f 和 g,f(n) = O(g(n)) 当存在一常数c使任意大的n都有 f(n) ≤ c·g(n)。(f is upper-bounded by g(n))。
  • Ω \Omega Ω ,lower bound,表示下限。
    def: f(n) = Ω(g(n)), if there exists constants c > 0 and n0 > 0 that for all n ≥ n0,we have f(n) ≥ c·g(n). 也就是说对于足够大的n,函数 f 和 g,f(n) = Ω(g(n)) 当存在一常数c使任意大的n都有 f(n) ≥ c·g(n)。(f is lower-bounded by g(n))。
  • Θ \Theta Θ, tight bound. 如果 f(n) = O(g(n)) 且 f(n) = Ω(g(n)),则 g 是 f 的tight bound。

这里一般会有两种问题,一种是给一堆 function,按照 O 排序;另一种则是 T/F 判断。
比较排序会常用到换底公式 3(多次)和斯特林公式4
例1: 按照 O 给下列公式排序 ( log ⁡ n ) ! , 4 log ⁡ n , log ⁡ n , 2 log ⁡ n , n log ⁡ log ⁡ n , 2 2 log ⁡ n , n 1 log ⁡ n (\log n)!,4^{\log n}, \sqrt{\log n}, \sqrt{2}^{\log n}, n^{\log \log n}, 2^{\sqrt{2\log n}}, n^{\frac{1}{\log n}} (logn)!4logn,logn ,2 logn,nloglogn,22logn ,nlogn1
T/F 则比较直接,优先举反例判断F。
例2: For non-descending f(n), g(n), f(n) = O(g(n)), then 2f(n) = O(2g(n))?
False,反例: f(n) = 2n, g(n) = n, 满足 f(n) = O(g(n))。不存在c,使22n ≤ c·2n
书上关于这部分还多了一些定理,比如Transitivity和Sum of Functions等,但都很浅显。

1.2 lower bound for sorting

由前面的比较排序问题,自然而然地引到了sorting。不过Victor并没有在这回顾什么排序算法,而是先介绍了一个定理。

  • Theorem (1.1):Comparison-based sorting must be Ω(nlogn)

Proof. 如果我们按照比较来排序,那么逐个比较的过程可以用一颗树来表示(下图a)。
decision tree

每一个叶子节点都是可能的结果,n!个。而比较的次数则是该叶子节点的高度。而最多的比较次数为树的高度。注意这并非一棵满二叉树,如果将其补满(图b),则叶子节点数量为2h。由于我们将其补满,则有2h ≥ n!    ⟹    \implies h ≥ log(n!) ≈ \approx log(nn)= nlogn.

这里还有两个例题,关于时间复杂度的分析。
例3:

int [] L, int n
while(n>0):
  find_max(L,n)
  n /= 4

O(n)的复杂度,find_max()是线性查找,L等比例缩减。(如果到后面分治法,利用Master Theorem瞪一眼就出来了,但是在review这里还是要分析)

例4:

string bigO(int n){
  if(n==0) return 'a'
  string str = bigO(n-1)
  return str+str
}

O(2n) 复杂度。注意在这里str+str的字符串拼接,在实现上是线性时间的复杂度,而非O(1),所以递归整体复杂度为O(2n) 。

1.3 Trees & Graphs

  • Theorem (1.2). G=(V,E) is undirected graph, then all following statements are equivalent:
    • (i) G is a tree.
    • (ii) Every 2 vertuces of G are connected by a unique path.
    • (iii) G is connected and |V| = |E|+1

Proof.
(i)    ⟹    \implies (ii). 证明Uniqueness, 反证法。假设存在某两点之间路径不唯一,则其不是树。与假设相悖。
(ii)    ⟹    \implies (iii). 证明 |V| = |E|+1, 利用归纳法证明,induction on vertices.
base case: 两个点一条边,|V|=2,|E|=1,满足。
Induction Hypothesis: for |V| < k, we have |V| = |E|+1
Induction Step: to prove |V| = |E| +1 when |V| = k+1.
finding bridge
因为两点间路径唯一,所以总可以找到一条 x-y bridge,使 x ∈ \in G1, y ∈ \in G2,此时G1、G2都适用于 IH 假设,|V|=|V1| + |V2| = |E1| + 1 + |E2| + 1 = |E| + 1.(核心总在与如何使用 IH

  • Theorem (1.3). In a undirected simple graph G=(V,E), there are at most V(V-1)/2 edges.

Proof. 略(皮)。

图的表示
邻接表、邻接矩阵(略)

1.3.1 图的遍历

BFS: 略
DFS: 略
再略就要吐了,补充几个书上的定理和证明。

  • Theorem (3.4).5 Let T be a breadth-first search tree, let x and y be nodes in T belonging to layers Li and Lj respectively, and let (x,y) be an edge of G. Then i and j differ by at most 1.

Proof. 反证法,假设 ij 相差多于1,不妨设 i < j - 1,xLi,则当从 x 出发的边在被检查时,所有发现的点都在 Li+1 或 之前。因此 y 一定最晚也在 Li+1 或之前被发现了,与假设矛盾。

  • Theorem (3.5). The set R produced at the end of the BFS is precisely the connected component of G containing s.

Proof. 证明precise,利用反证法,若一点 w 不属于R,则不存在 (s,w) 路径。
假设存在点 w 不属于R,却存在 (s,w) 路径。则必有 (s,u) 和 (v,w) 路径,其中 u $\in $R, v 是路径上第一个 set R 之外的点。由此存在 (u,v) 路径,而此时与BFS停止条件矛盾。

  • Theorem (3.6). For given recursive call DFS(u), all nodes that are marked “Explored” between the invocation and the end of this recursive call are descendants of u in T.

Proof. 略。

  • Theorem (3.7). Let T be a depth-first search tree, let x and y be nodes in T, and let (x,y) be an edge of G that is not an edge of T. Then one of x or y is an ancestor of the other.

Proof. 不妨设 x 先被DFS调用,则 y 在DFS(x)结束时,被标记为"Explored",而当刚进入调用时 y 并未被发现,所以必然是x调用过程中某一点发现 y,按 (3.6)yx 祖先。

  • Theorem (3.8). For any two nodes s and t in a graph, their connected components are either identical or disjoint.

Proof. 略。

1.3.2 Topological Sort

Topological Sort: 基于遍历寻找入度为0的点。(略)

Discussion Problem 1: 给出一个线性时间算法来判断图 G 的强连通性。
**解:**一般看到图的线性时间算法都是基于遍历的。设计算法的问题要首先给出算法,然后证明正确性,最后给出复杂度。按照书上的说法,

The algorithm to solve the problem is very clean as well and most of our work will be spent in proving that it is correct and giving an acceptable bound on the amount of time it takes to terminate with an answer.

这个题主要是强连通,那么就是任意两点间有往返路径。如果从某一点s出发遍历只可以保证s到任一点都存在路径,暴力方法则需要对于每个点进行遍历验证是否都可以访问到其他点,复杂度O(VE)。因为需要线性,所以不能问个点遍历。一个正确的解可以考虑从 s 进行遍历(DFS或BFS),在对 G 的所有边进行反向处理得到 G,在对 *G*从 s 遍历。判断是否两次所有点都可以被访问到。
correctness. 只提供个思路吧, G 中从 s 遍历保证了对于任意点 u, v 存在 (s, u)和 (s, v) 路径,而 G中再从 s 遍历,所有访问的点u, *v*在 G 中存在 (u, s), (v, s) 路径。如果两次遍历都能访问到所有其他点,那么对于任意两点,存在 (s, u), (s, v) 和 (u, s), (v, s) 路径    ⟹    \implies 存在 (u, v), (v, u) 路径。
Complexity. 反向操作使用邻接矩阵作为input的话,即转置,只需线性遍历整个表,O(E), 两次遍历O(V+E),整体线性时间。

1.3.3 Planar Graphs

Definition: A connected graph is planar if it can be drawn in the plane with each edge drawn as a continuous curve such that no two edges cross.

planar graph

  • Theorem (1.4). (Euler’s Formula) If G is a connected graph with V vertices, E edges and F faces, then V - E + F = 2.

Proof. Induction on edges.
*base case * 一条边两个点,face = 1. 2-1+1=2, holds.
IH 假设 |E| = k 时,定理成立
IS 证明 |E| = k + 1 依然成立。此时我们删掉一条边来使用 IH,而删掉的边可能在两种位置。

  • case 1 该边在一个环路上。此时删掉该边,V = V 不变,|E| = k , F = F - 1。而 GIH 有 V - E + F = 2,由此 V - E + F = V - E +1+ F -1 = 2。
  • case 2 该边不在环路上。则删掉该边,造成不连通的部分,而 GG’’ 都符合 IH,此时对于二者 F 不变,而 E 和 V 减少相同,依然成立。

proof

  • Theorem (1.5). In any simple connected planar graph with at least 3 vertices, E ≤ 3V - 6.

Proof. 分情况讨论。如果无环,那么E = V - 1,2V - 6 ≥ 0,E ≤ V + 2V - 6. 如果有环,那么对于所有 ∑ \sum_{}^{} (edge, face) ≥ 3F,因为每一个面至少由3个边包围。又因为每一条边之至多关联两个面,所以 ∑ \sum_{}^{} (edge, face) ≤ 2E. 因此由 (1.4),6 = 3V - 3E + 3F ≤ 3V - E    ⟹    \implies E ≤ 3V - 6.

  • Lemma 1. For any simple planar graph G, the average degree of G is strictly less than 6.

Proof. 当V ≤ 3, K3的 degree ≤ 6. 每个点的平均degree = 2 E V \frac{2E}{V} V2E, 由(1.5), E ≤ 3V - 6, Degree ≤ 6 V − 12 V \frac{6V - 12}{V} V6V12 = 6 - 12 V \frac{12}{V} V12.

1.3.4 Coloring planar graph

这里简单介绍了一下图着色问题——给每个点着色,以使没有相邻接的点颜色相同。
对于任意图,后面 NP 问题时会讲到,对于2色以上着色是NP-hard的, reduce from SAT.

而对于平面图,是可以有多项式时间的solution的。在这里有一个(6-colorable)定理。

  • Theorem (1.6). Every simple planar graph can be colored with at most 6 colors.

Proof. Induction on vertices.
base case V ≤ 6, 不超过六个点一定六色可着。
IH V = k 时,G 满足 6-colorable.
IS V = k +1 时,G 依然满足。
Lemma 1, G 中一定存在 degree ≤ 5的点 u。因此将 u 删掉,G’’ 满足 IH,六色可着。再把 u 加回来,因为 u 至多有五个邻居,最多消耗掉五种颜色,所以 u 一定可以用第六色着,因此 G 依然满足六色可着。

书里这部分内容其实已经到了第三章了,但是Victor自己憋的教材把它放在了第一章。书中第二章介绍了几种经典的问题,第二章回顾了算法分析的基础和数据结构(数组、列表、队列、栈和堆),第三章涉及图的基础主要讲BFS、DFS和实现及应用问题,连通性、以及拓扑排序。后面就紧跟贪婪、分治…一一对应的来解决前面提出的经典问题——可以认为是建模解决问题的过程吧。再看Victor的教材,第一章从复杂度问题到后面涵盖了BFS、DFS、拓扑排序、连通性和平面图最后稍微引入了图着色问题。第二章开始再回到复杂度问题——amortized analysis,第三章专门讲了一个lecture的堆——算法设计书里一小节的内容。后面算法的每个大章就好像单拎出来一个一样。你得承认也许Victor编的教材内容不丰富,而且联系不够紧密。但他赚钱是把好手啊,手动滑稽。


  1. Analysis of Algorithms(算法分析) ↩︎

  2. <> by Jon Kleinberg and Eva Tardos ↩︎

  3. log ⁡ a n = log ⁡ b n log ⁡ b a \log_an = \frac{\log_bn}{\log_ba} logan=logbalogbn ↩︎

  4. n ! ≈ 2 π n ( n e ) n n !\approx \sqrt{2\pi n}(\frac{n}{e})^n n!2πn (en)n ↩︎

  5. (3.4)-(3.8)都是书中编号 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值