CS/SE 2C03. Sample solutions to the assignment 1. Total of this assignment is 131pts, but 100% = 111pts. There are 21 bonus points. Each assignment is worth 7%. If you think your solution has been marked wrongly, write a short memo stating where marking in wrong and what you think is right, and resubmit to me during class, office hours, or just slip under the door to my office. The deadline for a complaint is 2 weeks after the assignment is marked and returned. 1.[10] Using only definition of O(f(n)) prove that the following statements are true: a.[2] (23n1200 + n2 log n + 15)/2n +105= O(1) Let c=144. Let n1 be the solution for n1200 = 2n, then, when n ≥ n1, n1200 ≤ 2n. Let n2 be the solution for n2 log n = 2n, then, when n ≥ n2, n2 log n ≤ 2n. Let n3 = 4, then, when n ≥ n3, 15 ≤ 2n. Let n0 = max(n1, n2, n3), then, n1200 ≤ 2n, n2 log n ≤ 2n, 15 ≤ 2n. Therefore, (23n1200 + n2 log n + 15)/2n +105 144 hold. b.[2] 5n3 2n + n3n = O(4n ) Let c=6, n0=16=24. First n3 = 23logn, and n2 = (4/3)(2/(log4/3))logn (check it by apply logarithm for both side) For all n 16, 5n32n = 5*23logn2n 5*2n2n = 5*4n n23n = (4/3)(2/(log4/3))logn * 3n (4/3)n * 3n = 4n Then, 5*n32n + n23n 6*4n hold. c.[2] max(n(log n) 2 ,n(n-1)/6)=O(n 2 ) Let c=1, n0=128 = 27, for all n 27, First, We can show by induction, for all m=7, m2 2m-1 For all n n0, 2m-1 n 2m-1, for some m, and m > 7. Therefore, (log n)2 m2 2m-1 n log n n1/2 n(logn)2 n*n = n2. n(n-1)/6 n(n-1) n*n = n2. Then, max(n(logn)2, n(n-1)/6) n2 hold. d.[2] nlog n 8 + n 3/2 = O(n 3/2 ) Let c=9, n0=128 = 27, for all n 27, From part (c), (log n)2 n log n n1/2 Hence, nlog n 8 + n 3/2 = 8*nlog n + n3/2 8*n*n1/2 + n3/2 = 9*n3/2 e.[2] 5nlog n + n3/2 = O(n2) Let c=6, n0=2. For all n 2, log n n, and n1/2 n. Then, 5nlog n + n3/2 6*n2 hold. 1 2.[10] Using only definition of O(f(n)) prove that the following statements are false: a.[2] (n2 + 2n +3)/(log n + 1) = O(n) For all c 0, take n0 = c2. For all n c, (n2 + 2n +3)/(log n + 1) c*n3/2/(log n + 1) c*n*n1/2/(log n+1) c*n hold. b.[2] n /(1500n1/3 + 56)=O(1) For all c 0, take n0 = (2000c)3/2. For all n n0, n /(1500n1/3 + 56) = n1/3 *n2/3/(1500n1/3 + 56) = 2000c* n1/3/(1500n1/3 + 56) c hold c.[2] max(n3 +n+1,10nlog n)=O(n2 ) For all c 0, take n0 = 10c. For all n 10c, n3 10c*n2 10nlog n Then, max(n3 +n+1,10nlog n) = n3 +n+1 10c*n2 c*n2 hold. d.[2] log n2 + n1/3 = O(1) For all c 0, take n0 = c3. For all n n0, log n2 + n1/3 log n2 + (c3) 1/3 = log c + c c hold. e.[2] (log n + n1/4 )/5 = O(log n) For all c 0, take n0 = (5c)8. For all n n0, log n + n1/4 log n + n1/8*n1/8 log n + 5c*n1/8 5c*log n hold. 3.[3] Suppose the function f(n) satisfy the following, there is n0 such that for each n > n0, f(n) ≥ f(n+1). Prove that f(n) = O(1). Let c = f(n0). Clearly, for all n > n0, f(n) ≥ c by the condition given above. 4.[5] Show that n! = O(nn ) but n! ≠ O(2n ). [2] Let c=1, n0=1. For all n 1, n! = n*(n-1)*(n-2)…*1n*n*n…*n= nn. So, n! = O(nn ). [3] For all c 0, take n0 = 4c. For all n 4c, n = n*(n-1)…3*2*1 4c*(n-1)…3*2*1 c*2*(n-1)…*3*2*2 c*2*2…*2*2*2 = c*2n hold So, n! ≠ O(2n ). 5.[6] Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies: a. T(n)=4T(n/2)+n b. T(n)=4T(n/2)+n2 c. T(n)=4T(n/2)+n3 We will use Master Theorem. In all cases a=4, b=2. Let α=log24 = 2. a.[2] Case 1 with ε = 1, as f(n)=n = nα-1. Hence T(n) = ϴ(nα) = ϴ(n2). b.[2] Case 2, as f(n)=n2 = nα. Hence T(n) = ϴ(nαlogn) = ϴ(n2logn). 2 Case 3 with ε = 1, as f(n)=n3 = nα+1, and af(n/b) = 4(n3/23)= 0.5n3<cn3=cf(n) for any c>1. Hence T(n) = ϴ(f(n)) = ϴ(n3). 6.[4] Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies: a. T(n)=5T(n/3)+log n b. T(n)=9T(n/3)+n2 We will use Master Theorem. a[2] a=5, b=3. Let α=log35 = 1.464974. Here f(n) = log n, so for ε = 0.4, we have f(n) = log n < n < nα-ε = n1.064974. By Case 1, T(n) = ϴ(nα) = ϴ(n1.464974). b[2] a=9, b=3, α=log39 = 2, f(n) = n2, so Case 2, i.e. T(n) = ϴ(nαlogn) = ϴ(n2logn). c.[2] 7.[7] Solve the following recurrence where T(1)=1 and T(n) for n≥2 satisfies T(n) = 2T(n/2)+nlogn Hint. Master Theorem does not work here, see Lecture Notes. We can use expansion. T(n) = 2T(n/2)+nlogn = 2(2T(n/4)+(n/2)log(n/2)) + nlog n = 4T(n/4) + 2n/2 log(n/2) + nlog n = 4T(n/4) + n(log(n/2)+log n)= ………. = 2k T(n/(2k)) +n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) For k=log n we have T(n/(2k)) = 1 and the expansion stops. Since 2log k = klog 2 = k, we have 2k T(n/(2k)) + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) = k + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) < k + n k log n = log n + nlog2n < cnlog2n, for any c ≥1. Hence T(n) = O(n log2n). Bonus [4]. We can also show that T(n)=Ω(n log2n), T(n)=ϴ(n log2n). We have: k + n (log (n/(2k)) + log (n/(2k-1)) + …+ log (n/2)+log n) > k + n k log(n/(2k)) = {since k=log n and 2log k = klog 2 = k} log n + n log n log (n/k) = log n + n log2 n – n log n log(log n). Since for example for n>36, log(log n) < 0.5 log n, we have: log n + n log2 n – n log n log(log n) > log n + n log2 n – 0.5 n log2 n = log n + 0.5 n log2 n > 0.5 n log2 n, so T(n)=Ω(n log2n). 8.[8] Solve the following recurrences where T(1)=1 and T(n) for n≥2 satisfies: a. T(n)=T(n-1)+ n2 b. T(n)=2T(n-1)+1 We will use expansion. a.[3] T(n) = T(n-1) + n2 = T(n-2) + 2 n2 = T(n-3) + 3 n2 = …. = T(n-k) + k n2 For k = n-1, T(n-k) = T(1) = 1 and the expansion stops. Hence: T(n-k) + k n2 = T(1) + (n-1) n2 = 1 + n3 – n2 < 2n3, so O(n3). Bonus[2]. For n>2, 0.5n3 > n2, hence 1 + n3 – n2 > 1 + 0.5n3 > 0.5n3, so Ω(n3), i.e. ϴ(n3). 3 b.[5] T(n)=2T(n-1)+1 = 2 (T(n)=2(2T(n-2)+1)+1 = 4 T(n-2) + 2 + 1 = 4(2T(n-3)+1) + 2 + 1 = 8 T(n-3) + 4 +2 + 1 = ....= 2k T(n-k) + 2k + 2k-1 +... + 22 + 21 + 20 Since 2k + 2k-1 +... + 22 + 21 + 20 = 2k+1-1, we have: 2k T(n-k) + 2k + 2k-1 +... + 22 + 21 + 20 = 2k T(n-k) + 2k+1-1 The expansion stops when k=n-1 as T(1)=1, and then we have: 2k T(n-k) + 2k+1-1 = 2n-1 T(1) + 2n-1+1-1 = 2n-1 + 2n -1 < 2×2n, so O(2n) This is not so important in this case as the following: T(n)=2n-1 + 2n -1>2n, so Ω(2n), i.e. ϴ(2n). 9.[18] Give, using “big O” notation, the worst case running times of the following procedures as a function of n. Provide some calculation/justification. Just a formula only is not sufficient. a.[3] procedure P1(n:integer); var i,j,k : integer; begin for i:=1 to n do if ( n<>n/3 and n<>(n+1)/2) then begin for j:=1 to n do begin C[i,j]:=0; for k:=n/2+2 to n do C[i,j]:=C[i,j]*A[i,k]; for k:=1 to n do C[i,j]:=C[i,j] + A[i,k]*B[k,j]; for k:=1 to (n-1)/2 do C[i,j]:=C[i,j]*A[i,k]; end end else begin C[i,j]:=A[i,j]; for k:=n/3 to n/2 do C[i,j]:=C[i,j]*A[i,k]; end The solutions do not need to be so precise s these below! T(n) = ni=1 max(T1,T2) = ni=1 max(nj=1T3, C1+T4) = ni=1 max(nj=1 (C2+(2k=n/2 C3) + (nk=1 C4) +(n/2k=1 C5)), C1+(n/2k=n/3 C6)) = ni=1 max(nj=1 (C2+ O(n)+ O(n)+O(n)), C1+O(n)) = ni=1 max(O(n2), O(n)) = ni=1O(n2) = O(n3) b.[3] procedure P2(n:integer); var i,j,k,l : integer; begin for i:=5 to 5*n do 4 for j:=i-1 to 200000000000000000 do for k:=j/2 to n*n do for l:=i to n*j {some statement requiring O(1) time} end T(n) = 5ni=5T’ = 5ni=5(200000000000000000j=i-1T’’) = 5ni=5(200000000000000000j=i-1(n*nk=j/2T’’’)) = 5ni=5(200000000000000000j=i-1(n*nk=j/2(n*jl=iO(1)))) = 5ni=5(200000000000000000j=i-1(n*nk=j/2O(n*j-i))) = 5ni=5(200000000000000000j=i-1O((n2-j/2)*(n*j-i))) = 5ni=5O(n2*(n-i)) = O(n4) But, by a more careful analysis, for the out most loop, when “i” is from 1 to 200000000000000000, T’ is O(n3); but, when “i” is from 200000000000000001 to 10n, T’ should be O(1), which is for the evaluation of the predicate if “i” is greater than 200000000000000000. So, T(n) = 5ni=5T’ = (5n-5)(1) = O(n) c.[4] function F(n:integer):integer; begin if n<=1 then return(1) else return(F(n div 3)+2*F(n div 2)) end T(n) = C + T(n div 3) +T(n div 2) T1(n) = C + 2*T1 (n div 3) = (1+2)C +22T1 (n div 32) = (1+2+22)C +23T1 (n div 32)…. = (1+2+22+…+2m)C +2mT1 (1) where m ~ logn/log3 = (2m-1)C + 2mC’ = O(2m) = O(2 logn/log3) = O(n1/log3) T2(n) = C + 2*T2 (n div 2) = (1+2)C +22T2 (n div 22) = (1+2+22)C +23T2 (n div 22)…. = (1+2+22+…+2(m-1))C +2mT1 (1) where m~logn = (2m-1)C + 2mC’ = O(2m) =O(n) So, T1(n) T(n) T2 (n), and T(n)=O(T2 (n))= O(n) d.[4] function G(n:integer):integer; begin if n<=1 then return(1) else return(G(n div 3)+G(n div 2)+G(n div 2)) end T(n) = C + T(n div 3) +2*T(n div 2) T1(n) = C + 3*T1 (n div 3) = (1+3)C +32T1 (n div 32) = (1+3+32)C +33T1 (n div 33)…. 5 = (1+3+32+…+3m-1)C +3mT1 (1) where m ~ logn/log3 m m m logn/log3 = (3 -1)C + 3 C’ = O(3 ) = O(3 ) = O(n) T2(n) = C + 3*T2 (n div 2) = (1+3)C + 32T2 (n div 22) = (1+3+32)C +33T3 (n div 22)…. = (1+3+32+…+3(m-1))C +3mT1 (1) where m~logn m m m log3 = (3 -1)C/2 + 3 C’ = O(3 ) =O(n ) So, T1(n) T(n) T2 (n), and T(n)=O(T2 (n))= O(nlog3) e.[4] Below the function F(n) is the function from (c) above and G(x) is the function from d above procedure P3(n:integer); var i,j,x,y : integer; begin for i:=1 to n do if i mod 3 = 1 then begin for j:=i to n do x:=x+1; for j:=20000 downto n do x:=x+y; for j:=1 to i do F(n)+G(n) end end T(n) = ni=1T1 = ni=1 1/3 *(T2+T3+T4) = ni=1 1/3 *(nj=iO(1) +20000j=nO(1)+ ij=1(O(n) + O(nlog3))) = ni=1 1/3 *(O(n-i) +O(1)+ O(nlog3 * i)) = O(n2+log3) 10.[25] Do Problem 4 on page 23 of Kleinberg and Tardos. It is a variation of the perfect stable matching problem. Solution: The basic strategy is to let every free student s apply for hospitals in order of his/her preference. If the hospital h he/she is applying for has positions available than h takes s. Or if all the positions are taken but h prefer s than at least one of its currently accepted students, then h will replace the least preferable student s’ with s, and s’ will be free. This process will continue until all free students have applied for all hospitals. Let S be a linked list of all free students and H an array of hospitals of length m. Each hospital h has a linked list employee[h] of students representing the current students it has accepted. Each student s has a linked list of hospitals employer[s] representing the hospitals that he/she has not applied for. Pseudo-code: Initialization: every student s is free and employer[s] is all the hospitals sorted in order of s’s preference. For every hospital, employee[h] is empty. While there is any free student s such that employer[s] is not empty 6 for every such student s let h1 be the first element in employer[h] (highest rank hospital in s’s list). if h1 still has positions available then add s into proper position of employee[h1], keep employee[h1] sorted in order of h1’s preference. else if Rank(s) > Rank(tail) add s into proper position of employee[h], delete tail (lowest rank student) from list. Delete h from employer[tail]. Tail becomes free student. else delete h1 from employer[s] The algorithm given above always terminates and produces a stable matching. Termination: Proof. In each loop, either an empty position is taken by a free student s, or a hospital is deleted from a student’s (either s or tail) hospital list. There is a finite number of empty positions and there are finite number of hospitals in students’ lists. Note that neither empty positions nor students’ hospital lists increase. Therefore eventually all free students will have an empty hospital list. Then the program will terminate. Stability: The matching produced by this program is stable. Proof. Let’s consider the first case of instability. Suppose when the program terminates, s in hospital h has lower rank than a free student s’. Since s’ is free and applied for all hospitals, it is not assigned to h because of two possible reasons: either s’ was rejected when applying for h, or he/she was replaced by some other student s” whose rank of preference is higher than s’. In either of these two cases, all students assigned to h at the time have higher rank than s’. And the rank is only going higher in the future. Therefore a student s with lower rank cannot stay in h when the program terminates, a contradiction! The second case of instability. Suppose when the program terminates, s in hospital h has lower rank of preference than a student s’ in hospital h’, and s’ prefers h to h’. Since s’ must have applied for h before applying to h’, he/she was not assigned to h because of two possible reasons: either s’ was rejected when applying for h, or it was replaced by some other student s” whose rank is higher than s’. In either case all students assigned to h at that time have higher rank than s’. And the rank is going to be higher in the future. Therefore a student s with lower rank cannot stay in h when the program terminates, a contradiction again! Hence the matching is stable. 11.[14] Do Problem 5 on page 24 of Kleinberg and Tardos. a.[8] Strong instability. The following algorithm guarantee a perfect matching with no strong instability. Let Pref1 be a given set of both men and women preferences that involve ties. We replace all ties by arbitrary total order extensions, for example a preference with ties {3,4} →{1,5,6} →{2,7} could be replaced by 4 →3 →5 →1→6 →2 →7, or by 3 →4 →1 →5→6 →2 →7, etc. We do such changes 7 for all rankings with ties. Let Pref2 be this new set of preferences. Since Pref2 keeps all preferences of Pref1, only indifferences are changed into arbitrary preferences, a strong instability of Pref1 implies standard instability of Pref2. We then apply a standard GaleShapley algorithm for the set of preferences Pref2. The outcome is a perfect stable matching , it does not contain any standard instability, so it does not contain any strong instability with respect to Pref1 either. Hence the strong instability can be avoided. b.[6] Weak instability. It may happen. Suppose that one gender is absolutely indifferent to the other. For example for all women all men are indifferent, no woman has any preference, all men all tied on all lists. Suppose we have two men m and m’, and two women w and w’, and both women have no preference, i.e. w→{m,m’}, w’→{m,m’}. Men however have the following identical preferences: m→w,w’, m’→w,w’. We have then two perfect matchings { m →w, m’ →w’ } and { m →w’, m’ →w }. The former has a weak instability (w is indifferent to both m and m’, while m’ prefers w), and the latter has also a weak instability (w is indifferent to both m and m’, while m prefers w). 12.[15] Bonus question. Write the most efficient program (in pseudo code) to compute f(n)f(n), where f(n)=nn . Hint. Do you know that nn can be implemented with O(log n) complexity? The idea is based on the following scheme: n^n(n: :non-negative-integer) if n<0 then write(error) else if n=1 or n=0 then n^n ←1 else if n is even and n>0 then n^n:=n^n(n/2)2 else n^n ← n^n(n/2)2 ×n where a is the biggest integer smaller or equal to a, for example 3.7 = 3. Here we have Tn^n(n) = Tn^n(n/2)+ c, Tn^n(1)=1, so by Master Theorem Tn^n(n) = ϴ(logn). We calculate n^n(n) first, and let a = n^n(n) = nn. Then we call n^n(a), and now the outcome is f(n)f(n). Formally: F(n: : non-negative-integer) a ← n^n(n); F ← n^n(a) The complexity is Tn^n(n)+Tn^n(nn), and Tn^n(nn) is a dominating factor. But log nn = n log n, so TF(n) = ϴ(n log n). 8
© Copyright 2024