# Algorithm Note --- [toc] --- ## Complexity ### some technique $n^n>n!>c^n>n^c>n^2>n\log n>n>\sqrt{n}>\log n$ binary have $\log n$ usually ### big O $f(n)=O(g(n))$ $f(n)\leq C\times g(n), \exists\ C>0\ \forall\ n\geq n_0$ ### big Theta $f(n)=\Theta(g(n))$ $C_1\times g(n)\leq f(n)\leq C_2*g(n), \exists\ C_1>0, C_2>0\ \forall\ n\geq n_0$ ### big Omega $f(n)=\Omega(g(n))$ $C\times g(n)\leq f(n), \exists\ C>0\ \forall\ n\geq n_0$ ## Master Theorem if the time like this $T(n) = aT(\frac{n}{b}) + f(n)$ than $T(n) = \Theta(n^{\log_ba})+\sum\limits_{i=1}^{\log_bn-1}a^if(\frac{n}{b^i})$ let $\sum\limits_{i=1}^{\log_bn-1}a^if(\frac{n}{b^i}) = pf(n)$ and you can observe that $pf(n)$ is near $O(f(n))$ ### case 1 if $f(n) = O(n^{\log_ba-\epsilon})\ \exists\epsilon>0$ that mean $\frac{f(n)}{n^{\log_ba}}<1$ than $T(n) = \Theta(n^{\log_ba})$ ### case 2 if $f(n) = \Theta(n^{\log_ba})$ that mean $\frac{f(n)}{n^{\log_ba}}$ is a constant than $T(n) = \Theta(n^{\log_ba}\log n)$ ### case 3 if $f(n) = \Omega(n^{\log_ba+\epsilon})\ \exists\ \epsilon>0$ **and** $af(\frac{n}{b})\leq cf(n),\exists\ c<1$ than $T(n) = \Theta(f(n))$ some prove $\sum\limits_{i=1}^{\log_bn-1}a^if(\frac{n}{b^i}) \leq\sum\limits_{i=1}^{\log_bn-1}c^if(n)+O(1)\leq f(n)\sum\limits_{i=1}^{\infty}c^i+O(1)=O(f(n))$ ## sorting ### Comparison sort #### bubble sort ```pseudo= FUNCTION BUBBLE-SORT(array[n]) for i from 1 to n for j from 1 to n-i-1 if(array[j] > array[j+1]) swap(array[j], array[j+1]) ``` - stable ##### Complexity - time - best case $O(n^2)$ - worst case $O(n^2)$ - average case $O(n^2)$ - extra space - O(1) #### selection sort ```pseudo= FUNCTION SELETION-SORT(array[n]) for i from 1 to n min = array[i] for j from i to n min = min(min, array[j]) swap(min, array[i]) ``` - stable ##### complexity - time - best case $O(n)$ - worst case $O(n^2)$ - average case $O(n^2)$ - extra space - O(1) #### insertion sort ```pseudo= FUNCTION INSERTION-SORT(array[n]) for i from 1 to n now = i while now-1>=1 and array[now]<array[now-1] swap(array[now], array[now-1]) now-=1 ``` - stable ##### complexity - time - best case $O(n)$ - worst case $O(n^2)$ - average case $O(n^2)$ - extra space - O(1) #### quick sort ```pseudo= FUNCTION partition(array[n], L, R) pivot=array[R] i=L-1 for j from L to R-1 if array[j]<=pivot swap(A[++i], A[j]) ++i swap(A[i], A[R]) return i FUNCTION QUICK-SORT(array[n], L, R) if L>=R or L<0 return p=partition(array, L,R) QUICK-SORT(array, L, p-1) QUICK-SORT(array, p+1, R) ``` - unstable ##### complexity - time - best case $O(nlogn)$ - worst case $O(n^2)$ - average case $O(nlogn)$ - extra space - O(1) #### merge sort ```pseudo= FUNCTION MERGE-SORT(array[n], L, R) // 0~n-1 if R-L<=1 // [L,R) have only 1 element return MERGE-SORT(array, L, MID(L,R)) MERGE-SORT(array, MID(L,R), R) nowL = L nowR = MID(L, R) nowt = 0 temp[R-L] while nowL<MID(L,R) and nowR < R if array[nowL]<=array[nowR] temp[nowt] = array[nowL] nowL += 1 else temp[nowt] = array[nowR] nowR += 1 nowt += 1 while nowL<MID(L, R) temp[nowt] = array[nowL] nowL += 1 nowt += 1 while nowR<R temp[nowt] = array[nowR] nowR += 1 nowt += 1 ``` - stable ##### complexity - time - best case $O(n\log n)$ - worst case $O(n\log n)$ - average case $O(n\log n)$ - extra space - O(n) ##### inverse pair add inverse pair count when `array[nowL]>array[nowR]` #### heap sort - just heap and pop all element ```pseudo= FUNCTION HEAPIFY(array[n]) for i from 1 to n now = i while now>1 if(array[now/2]<array[now]) swap(array[now/2],array[now]) FUNCTION HEAP-SORT(array[n]) HEAPIFY(array) for i from n to 1 swap(array[1], array[i]) now = i while now*2<i left = array[now*2] if now*2+1<i right = array[now*2+1] if(left>right) next = now*2 else(left>right) next = now*2+1 if(array[next]>array[now]) swap(array[next], array[now]) now = next else break ``` - unstable ##### complexity - time - best case $O(n\log n)$ - worst case $O(n\log n)$ - average case $O(n\log n)$ - extra space - O(1) ### linear time sort #### counting sort ```pseudo= FUNCTION COUNTING-SORT(array[n]) C = unordered_map<int, int> for i from 1 to n C[array[i]]+=1 prev = 0 for i in C i.second += prev prev = i.second temp[n] = {0} for i from n to 1 temp[C[array[i]]] = array[i] C[array[i]]-=1 for i from 1 to n array[i] = temp[i] ``` - stable ##### complexity - time - best case $O(n+K)$ - worst case $O(n+K)$ - average case $O(n+K)$ - extra space - O(K) (K is meaning max element of array) #### radix sort ```pseudo= FUNCTION RADIX-SORT(array[n]) d = digit of max number i = 10^d while i>=1 bucket[10] = {vector} for j from 1 to n digit = (array[j]/i) % 10 bucket[digit].append(array[j]) c = 1 for j from 0 to 9 for k from 1 to bucket[j].size array[c] = bucket[j][k] c+=1 i/=10; ``` - time - best case $O(dn)$ - worst case $O(dn)$ - average case $O(dn)$ d is meaning digit of max number - extra space - O(d) (K is meaning max element of array) ## Devide and Conquer ### binary search it can find 0 and 1 meeting point of a bool array like $[0,0,0,0,...,0,1,1,1,...,1]$ ``` FUNCTION BINARY-SEARCH(bool-array[n]) l = 1, r = n while(l<=r) m = MID(l, r) if(bool-array[m]) r = mid-1 else l = mid+1 return l ``` complexity $O(logN)$ ### Binary Exponentiation find a^b in fast way ```pseudo= FUNCTION POWER(a, b) if b == 0 return 1 if b == 1 return a p = POWER(a, b/2) p = p*p if(b is odd) p *=a return p ``` complexity $O(logN)$ ### matrix multiplication $\begin{bmatrix} r s \\ t u\end{bmatrix}=\begin{bmatrix} a b \\ c d\end{bmatrix}\times\begin{bmatrix} e f \\ g h\end{bmatrix}$ $P_1=a\times(f-h), P_2=(a+b)\times h,P_3=(c+d)\times e, P_4=d\times(g-e)$ $P_5=(a+d)\times(e+h), P_6=(b-d)\times (g+h),P_7=(a-c)\times (e+f)$ $r=P_5+P_4-P_2+P_6$ $s=P_1+P_2$ $s=P_3+P_4$ $u=P_5+P_1-P_3-P_7$ there have 7 multiplication, 18 add/sub $T(n) = 7T(\frac{n}{2})+18\times n^2$ => by master theorem - $n^{log_ba}=n^{log_27}$ - $18n^2=O(n^{log_27-log_2\frac{7}{4}})=O(n^2)$ - $T(n) = \Theta(n^{log_27})$ ### Closest-Pair Problem sort points by x,y each time cut at middle find two side Closest-Pair by recursive find middle 7 points(distance in min(left,right)) and use brute-force ```pseudo= FUNCTION CLOSEST-PAIR(points[n], l, r) if(r-l+1 == 1){ return 0 } if(r-l+1 == 2){ return dis(points[l], points[r]) } m = mid(l, r) left = CLOSEST-PAIR(points, l, mid) right = CLOSEST-PAIR(points, mid+1,r) d = min(left, right) strip = [] for i from 1 to n if dis(points[i], points[m])<d strip.append(points[i]) b = find closest pair by brute-force return min(b, d) ``` ### convex hull scan line ```pseudo= FUNCTION CONVEX-HULL(points[n]) sort points by x,y h = [] //convex hull for i from 1 to n //lower hull if(h.size >= 2 and cross(h[-2], h[-1], points[i])<0) h.pop_back() h.push_back(points[i]) h.pop_back() reverse points t = h.size for i from 1 to n //upper hull if(h.size -y >= 2 and cross(h[-2], h[-1], points[i])<0) h.pop_back() h.push_back(points[i]) h.pop_back() return h ``` ## Dynamic Programming ### rod cutting $price(n) = max(price(n-l[i])+p[i])$ complexity:$O(np)$ ### LCS ### memory $O(n^2)$ $lcs[i][j] = max(lcs[i-1][j], lcs[i][j-1])\ if\ s1_i\neq s2_j$ $lcs[i][j] = lcs[i-1][j-1]+1 \ if\ s1_i==s2_j$ complexity:$O(n^2)$ ### Edit distance $ed[i][j] = \min(ed[i-1][j-1]+(x_i\neq y_i), ed[i-1][j]+1, ed[i][j-1]+1)$ complexity:$O(N^2)$ ### Knapsack ``` for j fomr 1 to n for w from W to 1 dp[i] = max(dp[i-w[j]]+c[j]) ``` complexity:$O(NK)$ ### best binary search tree $cost =\sum\limits_{i=1}^{n}p_i\times d(k_i)+\sum\limits_{i=0}^{n}q_i\times d(d_i)+\sum\limits_{i=1}^{n}p_i+\sum\limits_{i=1}^{n}q_i$ $dp[i][j]$ is optimal expected cost for $k[i,j]$ $w[i][j] = \sum\limits_{l=i}^{j}p_l+\sum\limits_{l=i-1}^{j}q_l=w[i][j-1]+p_j+q_j$ $root[i][j]$ is which is the root of $subtree[i,j]$ $dp[i][j] = min(dp[i][r-1]+dp[r+1][j]+w[i][j])$ Complexity: $O(n^3)$ ## Greedy when we at each previous statment, choose optimal solution the general solution will be the optimal too ### Activity-Selection Problem Given the time table of activities, select a **maximum-size**subset of mutually compatible activities #### with dp method $dp[i,j]=max(dp[i,k]+dp[k,j]+1)$ complexity: $O(n^3)$ #### greedy each time choose the earliest finish time consider nonempty sub-problem S, $a_m$ be an activity in S with earliest finish time $a_m$ is included in some maximum-size subset of mutually compatible activities of S ##### prove let A be an solution by S $a_j$ be the activity in A with the earliest finish time case 1: $a_j = a_m$: correct case 2: $a_j \neq a_m$ - let $A' = A- a_j\cup a_m$ - A' is an optimal solution - because activities in A' are disjoint - |A| = |A'| - A' is a maximum-size subset of S, it include $a_m$ why 0-1 kanpsack problen can't use greedy? ### Huffman codes coding:mapping alphabet, sign to some binary code e.g. ascii code(mapping char to a number), Morse Code(use binary sequence express number), prefix code #### prefix code - can always be represented by binary tree - characters can onlt at leaf #### Huffman on binary tree, node value is meaning appear time and left is meaning 0, right is meaning 1 A = {f: 5, e:9, c:12, b:13, d: 16, a:45} ![image](https://hackmd.io/_uploads/S1RSqZkVR.png) cost:sum of weighted depth of leaves with minimum cost:optimal tree ##### prove clame: x, y be the lowest frequencies exist an optimal prefix code for x,y **have same length only diff on last bit** let $T^*$ be an optimal tree.a,b be 2 sibling leaves->deepest in $T^*$ ![image](https://hackmd.io/_uploads/HJ3tQMyVR.png) Create T' that a, b is lowest frequencies as x,y $cost(T^*)\geq cost(T')$ - $cost(T^*)-cost(T')$ ![image](https://hackmd.io/_uploads/ByfeCzyE0.png) $cost(T^*)=C+fxdx+fydy+fada+fbdb$ $cost(T')=C+fxda+fydb+fadx+fbdy$ $cost(T^*)-cost(T')=fxdx-fxda+fydy-fydb+fada-fadx+fbdb-fbdy$ $=fx(dx-da)+fy(dy-db)+fa(da-dx)+fb(db-dy)$ $=(fx-fa)(dx-da)+(fy-fb)(dy-db)$ $\because fx<fa, fy<fb, da>dx, db>dy$ $fx-fa<0, dx-da<0 \rightarrow (fx-fa)(dx-da)>0$ $fy-fb<0, dy-db<0 \rightarrow (fy-fb)(dy-db)>0$ $\therefore cost(T^*)-cost(T')>=0$ cost of T' is better then $T^*$ $\rightarrow$if the deepest nodes is the lowest frequencies ### didnt get optimal solution #### 0-1 knapsack if we use greedy "chooce best cp value"->value per pound is highest then pack size:50 item 1:60/10(cp:6) item 2:100/20 (cp:5) item 3:120/30 (cp:4) choose:1->5 =>total value is 160 but answer is take 2 3, value is 220 **not optimal solution** "take the largest value" pack size:50 item 1: 20/20 item 2: 30/30 item 3: 40/50 choose: 3=>total value is 40 but answer is take 1 2, value is 50 **not optimal solution** "take the lightest weights" pack size:50 item 1: 1/1 item 2: 60/50 item 3: 1/30 choose: 1,3=>total value is 2 but answer is take 2, value is 60 Fractional knapsack: can take part of item ->can greedy ## Graph ### defination: - G(V,E):we have a graph name G,it with vertices set V, edges set E on this graph - |V|:number of vertices, |E|:number of edges - Sparse graph:$|E|<<|V|^2$,Dense graph:$|E|\apporx|V|^2$ - degree of a vertex - number of it neighbot - at directed graph: - in-degree:the edge point to this vertex - out-degree:the edge start from this vertex - degree of graph : max(deg(V)) - directed:the edge have directed(E(u,v) not meaning v can go to u) ### representations #### adjacency list ![image](https://hackmd.io/_uploads/rkpFOLk40.png) | node | directed | undirected | |:----:|:-------- |:---------- | | 1 | ->2->3 | ->2->3 | | 2 | ->4->5 | ->1->4->5 | | 3 | ->4->6 | ->1->4->6 | | 4 | | ->2->3->6 | | 5 | | ->2 | | 6 | ->4 | ->3->4 | 1->2->3 2->1->4->5 3->1->4->6 4->2->3->6 5->2 6->3->4 each node have a list to record which node it can rich E(u,v): for directed graph - adjList[u] push back v for undirected graph - adjList[u] push back v - **adjList[v] push back u** #### adjacency matrix make a $n^2$ bool matrix $adjmat[u][v]$ is meaning E(u,v) is exist or not if it is undirected $adjmat[u][v] = adjmat[v][u]$ ### traversal all example is this graph ![image](https://hackmd.io/_uploads/rJe-FLJEC.png) #### Breadth-first search(BFS) use queue to record what we want to go next start from s **FIRST IN FIRST OUT** init:queue(s) bold:**now poping**, ~~strikethrough~~:visited *italics*:now pushing | round | check | queue | | ----- | ----- |:----------------------- | | 1 | s | **s** *w* *r* | | 2 | w | **w** r *t* *x* | | 3 | r | **r** t x *v* | | 4 | t | **t** x v *u* *x* | | 5 | x | **x** v u x *t* *y* | | 6 | v | **v** u x t y | | 7 | u | **u** x t y *t* *x* *y* | | 8 | ~~x~~ | **x** t y t x y | | 9 | ~~t~~ | **t** y t x y | | 10 | ~~y~~ |**y** t x y | | 11 | ~~t~~ | **t** x y | | 12 | ~~x~~ | **x** y | | 13 | ~~y~~ | **y** | - always go the shortest path that start from starting point (weight of edge is 1) #### Depth-first search(DFS) use stack to record what we want to go next **FIRST IN LAST OUT** init:stack(s) ##### add time stamps start time and end time ![image](https://hackmd.io/_uploads/Byk64PkER.png) for edge u,v - tree edge: v is not start - back edge: v is start but not end - finished/cross edge : v is end ### Directed acyclic graph (DAG) a directed graph without cycle - check it's DAG - DFS has no back edge #### Topological sort given a dag find a order that if E(u,v), than u appear before v calculate start, end time **sort by decreasing order of end time** $O(V+E)$ ##### correctness ``` node n{ s=>start time f=>end time } ``` if E(u,v) is an edge of g u.f>v.f - if this edge is - tree edge:u.f>v.f - if u.f<v.f ->that mean we pop v before u, but stack like (...,v,u...) - **must pop u first** - back edge:impossible(it's DAG) - finished/cross edge edge:u.f>v.f - if u.f<v.f ->that mean we pop v before u, but stack like (...,v,...,(end v)u...) ### Stronly connected components(SCC) for a directed graph G(V,E) have the sub graph G' that for all node pair(u, v) of G' have at least 1 path from u to v ![image](https://hackmd.io/_uploads/HyaSdPJEA.png) ### Kosaraju's Algorithm calculate the end time of all vertices by dfs compute the $G^T$(transpose of G)=> $E(u,v)->E(v,u)$ dfs the $G^T$ with the order of decreasing end time and we can find the components by dfs $O(V+E)$ #### correctness ##### obs 1 if G have 2 SCC C(u,v), C'(u',v'), E(u,u') if path v'->v exist then it contain path u->u'->v', v'->v->u u, v' are reachable each other->C, C' is same SCC =>P(v'->v) not exist if C,C' are distinct SCC ##### obs2 if G have 2 SCC C(...,u), C'(v...), E(u,v) for all vertex on C's end time > vertex on C' - case 1 - start time of C<C' - it start from C, when go to C', it can't go back to C(otherwise C,C' are in same SCC) - so when C have vertex end, all vertex of C' end - case 2 - start time of C>C' - it start from C', it can't go to C(otherwise C,C' are in same SCC) - so when C have vertex start, all vertex of C' end - end time of C >= start time of C all > end time of C ##### obs3 if $G^T$ have (u,v)from C->C' for all vertex on C's end time < vertex on C' **same as obs2** therefore C' have no edge to other component in $G^T$ ### Minimum Spanning Tree(MST) ![image](https://hackmd.io/_uploads/SJ4c1u1N0.png =50%x) get a tree T from undirected graph G which connect all vertex and don't have cycle with minimum cost W **GREEDY METHOD** $O(ElogV)$ #### Kruskal init all vertex u in $SET_u$ each time find the edge(u,v) with smallest weight(sort edges by weight) $if\ FIND-SET(u)\neq FIND-SET(v)$ $MST = MST \cup {(u,v)}$ $UNION(u,v)$ **with disjoint set** #### Prim start from a point eachtime get a vertex that can be reach and have minimum weight and didn't be connected ##### correctness cut(S, V-S):a partition of V cut respect a set A of edge:no edge in A cross cut light edge:a edge cross cut with minimal weight G(V,E):connected undirected weighted graph with vertices V, edges E A:a subset of E included some MST for G C(S,V-S) cut of G respects A L(u,v): a light edge cross (S, V-S) **L(u,v) is SAFE for A** prove about it let T be MST included A, assume T not contain L(u,v) u-v and u->...->v(simple path in T) is a cycle this cycle must contain (x,y not in A) - if(x,y) in A, then u, v is not cross(S,V-S) removing (x, y), make T to 2 components creatt $T' = T-\{(x,y)\}\cup\{(u,v)\}$ $w(T') = w(T)-w(x,y)+w(u,v)\leq w(T)$(w(u,v)<w(x,y) or u,v is not light edge) T' must be a minimum spanning tree and contains (u,v) #### Borůvka not on this exam I'll update it after exam ### single source shortest path start from s #### relax if now have edge(u, v) with weight w now u's distance is du, v's is dv du+w< dv set dv=du+w #### bellman-Ford basic on floyd warshall but best $O(|V||E|)$ ->worst $O(V^3)$ init dis(s,u) to inf, dis(s,s) = 0 repeat |V|-1 times for each edge(u,v) with weight w do relax(u,v,w) =>if s->...->u->v is better than other path from s to v:update the distance proove why repeat V-1 times - assert that G contain no negtive cycle - each node v has a shortest path from s to v=>at most V-1 edges how to know G have negtive cycle or not - if the |V|-th iteration relax the edge - because if we do V-1 times it will get shortest path if it don't have negtive cycles - but when we do the V-th times, and get better answer prove if G contain a negtive cycle $c = \{v_0,v_1,\dots ,v_k\}, v_k=v_0$ $\sum_{i=1}^{k}w(v_{i-1},v{i})<0$ if no update: $dis(v_i)\leq dis(v_{i-1})+w(v_{i-1}, v_i) \forall i$ $\sum_{i=1}^{k}dis(v_i)\leq\sum_{i=1}^{k}(dis(v_{i-1})+w(v_{i-1},v_i))$ $\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \leq\sum_{i=1}^{k}dis(v_{i-1})+\sum_{i=1}^{k}w(v_{i-1},v_i)$ $0\leq\sum_{i=1}^{k}w(v_{i-1},v_i)$ contradicts! ##### if graph is a DAG Topologically sort + DP after Topologically sort, new order is in T(T[i] is meaning i-th vertex) ``` for u in T: // see vertex in order by Topologically sort for v in G[u]: // see all edge start from u relax(u,v,w) ``` complexity:$O(|V|+|E|)$ correctness because we sort vettices in Topologically sort relax edge on path $v_0,v_1...v_n$ in order$(v_0,v_1), (v_1,v_2),...,(v_{k-1}, v_k)$ that meaning $dis(v_i)=\delta(s,v_i)$ at termination for i from 0 to k where $\delta(s,v_i)$ is shortest path from s to $v_i$ ##### if all weight is non-negative #### Dijkstra like prim, is a greddy method complexity is O(|V|log|V|) eachtime get a vertex u with minimum path from s and now can reach reach all vertex u's neighbor(all E(u, v) ) and relax all of them pseudo code ``` Q = G.v S = EMPTY SET while(Q is not EMPTY SET): u = EXTRACT-MIN(Q) // get a vertex with minimum path S = UNION(S, {u}) for all v in G[u]: RELAX(u,v,w) ``` correctness in each iteration $dis(u) = \delta(s, u)$ for the vertex added to set S =>(dis(u) will not be relaxed after) suppose $dis(u)\neq \delta(s,u)$ when u is added to the set S ![image](https://hackmd.io/_uploads/S1ajfT14A.png) shortest path P from s to u(s->...->x->y->...->u) x:the vertex in S before y (s->...->x->y) y:first vertex on P(s,u) not in S $dis(y) = \delta(s,y)\leq \delta(s,u)\leq dis(u)$ but when we choose u, and y is not in S => y is not chosen => dis(u)<dis(y) contradicts! therefore not shortest path from s to u have vertex not in S when we choose u ### All pair shortest path #### Naive run bellman-ford each vertex $O(|V|O(|V||E|))=O(|V|^2|E|)$ wtf is this ==; #### DP all sub-paths of a shortest path are shortest path ->$\delta(i,j)=\delta(i,k)+w_{kj}$ if have edge(k,j) on shortest path P(i,j) $l_{i,j}^{m}$:minimum weight of any path from i to j, contain at most m edges init: $l_{i,i}^{0} = 0$ $l_{i,j}^{1} = w_{i,j}$ otherwise :$\infty$ $l_{i,j}^{m} = min_{1\leq k\leq n}(l_{i,k}^{m-1}+w_{k,j})$ $\delta(i, j) = l_{i,j}^{n-1}$ =>$\delta(i, j)=\delta(i,k)+w_{k,j}$ ##### be better find shortest path with $L^{m-1}, W$ $L^1=W$ $L^2=L^1W=W*W$ $L^4=W^4=W^2*W^2$ ... =>need only log n times $O(n^3logn)$ #### Floyd-Warshall DP method with better way $\delta(i,j)=\delta(i,k)+ \underline{\delta{(k,j)}}$ => $l_{i,j}^{m} = \min(l_{i,j}^{m-1}, l_{i,k}^{m-1}+l_{k,j}^{m-1})$ and $l_{i,j}^{0} = w_{ij}$ and $\delta(i,j) = l_{i,j}^{n}$ Complexity:$O(n^3$) #### Johnson reweighting each vertex v have a weight h(v) and make edge weight to new weight $w'(u,v) = w(u, v)+h(u)-h(v)$ $w(p) = \delta(v_0,v_k) \iff w'(p) = \delta'(v_0, v_k)$ **w' is non neggative** ##### method add a vertex 0 and add E(0,u) for all u in G with weight 0 and vertex 0's w is also 0 $h(v) = \delta(0,v)$ => use bellman-ford compute all $w(u,v)$ to $w'(u,v) = w(u, v)+h(u)-h(v)$ $O(n^3)$ ###### a little prove $h(v) = \delta(0,v)$ $h(v) \leq h(u)+w(u,v)$ $0 \leq h(u)+w(u,v)-h(v) = w'(u,v)$ ### Flow problem #### defination a flow from s to t on a directed graph with weight on edge $w(u, v)\geq 0$ flow f(s,t) is a weight subgraph og G=>satisfies the capacity constraint and flow conservation value of flow is sum of outgoing edge of s in f capacity constraint:$0\leq f(u,v)\leq w(u,v) \forall u,v\in V$ flow conservation:$\sum_{v\in V}f(v,u) = \sum_{v\in V}f(u,v) \forall v\in V-\{s,t\}$ #### max flow ##### Ford–Fulkerson each time we find a simple path from s to t and on this path minimum weight is x all edge on this path w(u,v)-x **add a new backward edge (v,u) with weight x on residual G** ##### correctness f is a flow f' is a flow of residual graph $G_f$ =>f+f' is a flow of G f is not maximum for G iff still have path on $G_f$ from s to t ###### prove if f is maximum for G but still have path on $G_f$ from s to t =>we can find a flow g on $G_f$, and f+g is a flow of G and f+g>f (g is positive)=>f is not maximum #### min cut ![image](https://hackmd.io/_uploads/SyU1-Wc40.png) #### Bipartite match ![image](https://hackmd.io/_uploads/rk7t-Z5NR.png) each node can only match 1 node solution: add pseudo start point and end point connect it to two side with weight=1 ![image](https://hackmd.io/_uploads/SJajZb5E0.png) ### Max flow in ADA... ##### Ford–Fulkerson f:flow of G ###### residual graph R - If $f(uv) > 0$, then let $R( f )$ have an edge vu with capacity f (uv). - If $c(uv) > f (uv)$, then let $R( f )$ have an edge uv with capacity $c(uv)− f (uv)$. f:st-flow of G g:flow of R(f) iff f+g=flow of g - observation - if g(vu)>0 & $E(v,u) \notin G$, $(f+g)(uv)=f(uv)+g(uv)-g(vu)$ ###### algorithm - Let $f(uv) = 0$ for each edge uv of G. Repeat steps until R(f) does not contain an st-path. - Obtain an st-path P of $R( f )$. Let q be the minimum capacity of the edges of P. - Obtain an st-flow g of $R( f )$ by letting $g(uv) = q$ for each edge uv of P and $g(uv) = 0$ for all other edges uv of G. - Let $f = f + g$. ###### correctness - P:st-path of $R( f )$, - st-flow g of R( f ) with positive value. - By observing residual graph, h = f + g is an st-flow of G whose value is strictly larger than that of f . Thus, f is not a maximum st-flow of G. - If f is not a maximum a maximum st-flow of G, then there is an st-flow h of G whose value is strictly larger than that of f . - Let g = h − f - Verify that g is an st-flow of R( f ) - Thus, there is an st-path of R( f ) - when algorithm stop, f is max flow of s-t **observation** - Let P be an st-path whose number edges is minimized in the R( f ). - Let g be the flow for R( f ) corresponding to P. - For each vertex v of G, we have $d_R( f )(s, v) ≤ d_R( f +g)(s, v)$, where $d_H (s, v)$ for a residual graph H of G denotes the distance of s to v in the unweighted version of H. - unweighted version of H:edge length=1 (not care capacity). - P is unweighted version of R( f )'s shortest st-path. #### complexity if capacity is C:O(mC) \* **is exponential-time** if C is not limited store space is O(mlogC) \* $O(mC) \neq O(m\log C)^{O(1)} \rightarrow not polynomial$ ##### make C to mn - makes sure that the st-path P in $R( f )$ having a minimum number of edges #### some about algorithm - complexity is relative to problem size if the problem size is $\Theta(f(n))$ - linear-time algorithm:$O(f(n))$ - quadratic-time algorithm:$O(f(n)^2)$ - polynomial-time algorithm:$O(f(n))^{O(1)} = f(n)^{O(1)}$ - exponential-time algorithm:$O(1)^{f(n)}$ or more ## NP Problem ### Reducibility if $P_1$ can deduct to $P_2$ then exist a function that $f({S_1}_i)={S_2}_i$ where S is meaning answer ![image](https://hackmd.io/_uploads/S1FXAyKEC.png) like this, each 1 is mapping to 1 P:problem can slove in polynomial time NP:problem will slove with non-polynomial time can verify answer in polynomial time NP-Complete is NP and NP-Hard problem NP-Hard:**all** NP problem polynomial time reducible to this problem ### Hamiltonian Path->long path Hamiltonian Path:each node should pass once if longest-path(G, x, y, |V|-1) yes->have hamiltonian Path otherwise no ### Hamiltonian Cycle->Hamiltonian Path Hamiltonian-cycle:Hamiltonian Path and back to start point if it have a hamiltonial path start at u, end at v, and there exist E(u,v)->have Hamiltonian-cycle ### TSP Hamiltonian-cycle with minimum cost ### Hamiltonian Cycle->TSP if each cost of $E[u,v]=0$, other edge on complete graph is 1 if exist TSP with cost 0 => have Hamiltonian-cycle ### SAT problem first known NP-Complete problem input a bool formula if it have a answer let this formula been true -> yes ### Further reading [2023 ADA midtern2](https://hackmd.io/@IBuVwIraTIWJeB88sQHXpw/H1VaNbcQ6) [2023 ADA final](https://hackmd.io/@ntnuhiphop-panda/ry6weQkD6)