Sie sind auf Seite 1von 7

CS/ECE 374 Homework 4 Solutions Fall 2016

1. Consider the following restricted variant of the Tower of Hanoi puzzle. The pegs are numbered
0, 1, and 2, and your task is to move a stack of n disks from peg 1 to peg 2. However, you are
forbidden to move any disk directly between peg 1 and peg 2; every move must involve peg 0.
Describe an algorithm to solve this version of the puzzle in as few moves as possible. Exactly
how many moves does your algorithm make?

Solution: The following recursive algorithm moves the top n disks from the source peg src
(either 1 or 2) to the destination peg dst (either 1 or 2), where every move uses peg 0.
(The forbidden peg never changes, so we can hard-code it into the algorithm.)

ForbiddenHanoi(n, src, dst):


if n > 0
ForbiddenHanoi(n − 1, src, dst)
move disk n from peg src to peg 0
ForbiddenHanoi(n − 1, dst, src)
move disk n from peg 0 to peg dst
ForbiddenHanoi(n − 1, src, dst)

The initial call is ForbiddenHanoi(n, 1, 2).


The number of moves satisfies the recurrence T (n) = 3T (n − 1) + 2. We can easily
verify by induction that T (n) = 3n − 1.
Here is a complete proof of correctness. Let n be an arbitrary non-negative integer,
and assume that ForbiddenHanoi(m, a, b) correctly moves m disks from a to b for every
non-negative integer m < n. If n = 0 the algorithm correctly does nothing, so assume
n > 0.
By the inductive hypothesis, the first recursive call correctly moves the top n − 1 disks
from src to dst. The second line moves disk n from src to peg 0, which is legal because all
smaller disks are on peg dst. By the inductive hypothesis, the second recursive call correctly
moves the top n − 1 disks from dst to src. The fourth line moves disk n from peg 0 to dst
which is legal because all smaller disks are on peg src. Finally, by the inductive hypothesis,
the first recursive call correctly moves the top n − 1 disks from src to dst.
Put more simply: The algorithm is correct because every line is correct (by the inductive
hypothesis) and the lines are in the right order. Put even more simply: The algorithm is
obviously correct. „

Rubric: 10 points =
• 2 for an English specification
– No credit for the rest of the problem if this is missing. — See
Cardinal Sin #2: “Declare all your variables”
– A specification is a description of what problem the algorithm is supposed
to solve, not how the algorithm solves that problem.
– The specification must actually use the input parameters of the algorithm.
• 1 for specifying the initial function call
• 5 for a correct algorithm. This is not the only correct description.
• 2 for time analysis (1 for “O(3n )”)
• No proof of correctness required.

1
CS/ECE 374 Homework 4 Solutions Fall 2016

2. Consider the following cruel and unusual sorting algorithm.

Cruel(A[1 .. n]):
if n > 1
Cruel(A[1 .. n/2])
Cruel(A[n/2 + 1 .. n])
Unusual(A[1 .. n])
Unusual(A[1 .. n]):
if n = 2
if A[1] > A[2] 〈〈the only comparison!〉〉
swap A[1] ↔ A[2]
else
for i ← 1 to n/4 〈〈swap 2nd and 3rd quarters〉〉
swap A[i + n/4] ↔ A[i + n/2]
Unusual(A[1 .. n/2]) 〈〈recurse on left half 〉〉
Unusual(A[n/2 + 1 .. n]) 〈〈recurse on right half 〉〉
Unusual(A[n/4 + 1 .. 3n/4]) 〈〈recurse on middle half 〉〉

Notice that the comparisons performed by the algorithm do not depend at all on the values in the
input array; such a sorting algorithm is called oblivious. Assume for this problem that the input
size n is always a power of 2.

(a) Prove by induction that Cruel correctly sorts any input array.

Solution: The only difference between Cruel and Mergesort is that Cruel calls
Unusual instead of Merge. So to prove that Cruel correctly sorts, it suffices to
prove that Unusual behaves exactly like Merge.

Lemma 1. For any array A[1 .. n] such that n is a power of 2, the subarray A[1 .. n/2]
is sorted, and the subarray A[n/2 + 1 .. n] is sorted, calling Unusual(A[1 .. n]) correctly
sorts the entire array A[1 .. n].

Proof: Let A[1 .. n] be an arbitrary array such that n is a power of 2, and the two
subarrays A[1 .. n/2] and A[n/2 + 1 .. n] are each sorted. Assume that Unusual
correctly sorts any array whose length is a power of 2 smaller than n and whose first
and second halves are sorted.
To simplify notation, we name the four quarters of A as follows:

A1 := A[1 .. n/4],
A2 := A[n/4 + 1 .. n/2],
A3 := A[n/2 + 1 .. 3n/4],
A4 := A[3n/4 + 1 .. n].

These names refer to the array addresses, not the array contents. By assumption,
the subarrays A1 ∪ A2 and A3 ∪ A4 are initially sorted. We separately track the four
quartiles of A through the execution of Unusual(A). There are three cases to consider.
• First, consider the smallest n/4 elements of A.
– The smallest n/4 elements of A all initially lie in the subarrays A1 and A3 .
– After the for-loop swaps A2 and A3 , the smallest n/4 elements of A lie in
A1 ∪ A2 . Moreover, the subarrays A1 and A2 are still sorted.

2
CS/ECE 374 Homework 4 Solutions Fall 2016

– The inductive hypothesis implies that the first recursive call to Unusual sorts
A1 ∪ A2 . Thus, after this call, A1 contains the n/4 smallest elements of A in
sorted order.
– The rest of Unusual does not modify A1 .
• Next, consider the largest n/4 elements of A.
– The largest n/4 elements all initially lie in the subarrays A2 and A4 .
– After the for-loop swaps A2 and A3 , the largest n/4 elements of A lie in
A3 ∪ A4 . Moreover, the subarrays A3 and A4 are still sorted.
– The first recursive call to Unusual does not modify A3 or A4 .
– The inductive hypothesis implies that the second recursive call to Unusual
sorts A3 ∪ A4 . Thus, after this call, A4 contains the n/4 largest elements of A
in sorted order.
– The rest of Unusual does not modify A4 .
• Finally, consider the (n/4 + 1)th through (3n/4)th smallest elements of A, which
we call the middle elements.
– The first recursive call to Unusual moves all middle elements out of A1 .
– The second recursive call to Unusual moves all middle elements out of A4 .
– At this point, all middle elements lie in the subarrays A2 and A3 , but possibly
in the wrong order. However, A2 is sorted and A3 is sorted.
– The inductive hypothesis implies that the third recursive call to Unusual
sorts A2 ∪ A3 , putting each middle element into its correct location.
We conclude that Unusual correctly sorts the entire array A[1 .. n]. ƒ
Cruel’s correctness now follows immediately from the correctness of MergeSort. „

Rubric: 6 points =
+ 5 for proving Unusual=Merge (standard induction rubric)
+ 1 for proving Cruel=Mergesort

(b) Prove that Cruel would not correctly sort if we removed the for-loop from Unusual.

Solution: With this modification, Cruel([3, 4, 1, 2]) returns the array [3, 1, 4, 2]. „
(c) Prove that Cruel would not correctly sort if we swapped the last two lines of Unusual.

Solution: With this modification, Cruel([3, 4, 1, 2]) returns the array [1, 3, 2, 4]. „
(d) What is the running time of Unusual? Justify your answer.

Solution: The running time of Unusual satisfies the recurrence T (n) = 3T (n/2) +
O(n). The recursion tree technique (with geometrically increasing level sums)—or
the analysis of Karatsuba’s algorithm in the lecture notes—gives us the solution
T (n) = O(n lg 3 ). „
(e) What is the running time of Cruel? Justify your answer.

Solution: The analysis in part (d) implies that the running time of Cruel satisfies
the recurrence T (n) = 2T (n/2) + O(nlg 3 ). The recursion tree technique (with
geometrically decreasing level sums) gives us the solution T (n) = O(n lg 3 ). „

Rubric: 1 point each for parts (b)–(e).

3
CS/ECE 374 Homework 4 Solutions Fall 2016

3. You are a visitor at a political convention (or perhaps a faculty meeting) with n delegates. Each
delegate is a member of exactly one political party. It is impossible to tell which political party
any delegate belongs to. In particular, you will be summarily ejected from the convention if you
ask. However, you can determine whether any pair of delegates belong to the same party or not
simply by introducing them to each other. Members of the same party always greet each other
with smiles and friendly handshakes; members of different parties always greet each other with
angry stares and insults.

(a) Suppose more than half of the delegates belong to the same political party. Describe and
analyze an efficient algorithm that identifies every member of this majority party.

Solution (divide and conquer; 6/7): I’ll describe a recursive algorithm to identify
one member of the majority party. After this algorithm runs, we can identify all
members of the majority party in O(n) additional time, by introducing the chosen
representative to everyone else.
(1) Split the delegates roughly in half. Send one half to the left side of the room, the
other half to the right side of the room.
(2) Recursively find a member of the majority party for the delegates on the left. Call
her Elle.
(3) Recursively find a member of the majority party for the delegates on the right.
Call him Ari.
(4) Introduce Elle and Ari to everyone (including each other) in O(n) time.
(5) Whoever gets more friendly handshakes is a member of the majority party.
Here’s the same algorithm in pseudocode:
OneInMajority(D[1 .. n]):
if n = 1
return D[1]
` ← OneInMajority(D[1 .. dn/2e])
r ← OneInMajority(D[dn/2e + 1 .. n])
`count ← 0; rcount ← 0
for i ← 1 to n
if SameParty(`, D[i])
`count ← `count + 1
if SameParty(r, D[i])
rcount ← rcount + 1
if `count > rcount
return `
else
return r

To prove this algorithm correct, we must verify two claims:

Lemma 2. OneInMajority always returns an element of its input array, even if there
is no majority.

Proof: If n = 1, the algorithm returns D[1]. Otherwise, the algorithm always returns
either ` or r; the inductive hypothesis implies that ` is an element of D[1 .. dn/2e]
and r is an element of D[dn/2e + 1 .. n]. ƒ

Lemma 3. OneInMajority returns a member of the majority party if there is one.

4
CS/ECE 374 Homework 4 Solutions Fall 2016

Proof: Assume there is a majority party. That party must contain more than half of
the first dn/2e delegates, or more than half of the last bn/2c delegates, or possibly both.
Thus, the inductive hypothesis implies that either ` or r is a member of the majority
party. The previous lemma implies that both ` and r are delegates, even if their
half of the delegates has no majority party, so their parties are always well-defined.
The for-loop counts how many people are in `’s party and in r’s party and returns
whichever party is larger. ƒ

The running time of this algorithm obeys the mergesort recurrence T (n) =
2T (n/2) + O(n), so the algorithm runs in O(n log n) time. „

Rubric: 6 points = 1 for base case + 2 for recursive case + 2 for proof of correctness
(= ½ for Lemma 2 + 1½ for Lemma 3) + 1 for time analysis.

Solution (divide and conquer, 7/7): I’ll describe a recursive algorithm to identify
one member of the majority party. After this algorithm runs, we can identify all
members of the majority party in O(n) additional time, by introducing the chosen
representative to everyone else.
(1) Pair up the delegates, and introduce each pair to each other.
(a) If a pair hate each other, remind them of the first rule of Fight Club and kick
them out.
(b) If a pair like each other, invite one of the pair to the VIP room and send the
other one home.
(2) If n is odd, invite the last delegate the to VIP room.
(3) Recursively find a member of the majority party for the VIPs.
OneInMajority(D[1 .. n]):
if n = 1
return D[1]
m←0
for i ← 1 to bn/2c
if SameParty(D[2i − 1], D[2i])
m← m+1
VIP[m] ← D[2i]
if n is odd
m← m+1
VIP[m] ← D[n]
return OneInMajority(VIP[1 .. m])

We prove this algorithm correct by induction, paying careful attention to the case
where n is odd. There are two cases to consider.
• The algorithm is trivially correct when n = 1.
• So suppose n > 1. Again, let m denote the number of majority delegates, and
let ` be the number of majority delegates invited to the VIP room. Then exactly
m − ` majority delegates are not invited to the VIP room; of those, at most ` were
paired with other majority delegates.¹ So at least m − 2` majority delegates were
¹When n is odd and D[n] is a majority element, only ` − 1 majority delegates are paired with other majority
delegates.

5
CS/ECE 374 Homework 4 Solutions Fall 2016

paired with minority delegates. Thus, at least m − 2` minority delegates were


paired with majority candidates, leaving at most (n − m)− (m − 2`) = n − 2m + 2`
remaining minority delegates, so at most n/2 − m + ` minority delegates are
VIPs. Since m > n/2, the number of minority VIPs is strictly less than `. So the
induction hypothesis implies that the recursive call correctly returns a majority
delegate.
The running time obeys the recurrence T (n) ≤ O(n) + T (dn/2e), because at most half
the delegates become VIPs. Ignoring the ceiling in the recursive argument, we get a
descending geometric series, so overall the algorithm runs in O(n) time.² „

Rubric: 7 points = 1 for base case + 2 for recursive pairing + 1 for correctly dealing
with odd n + 2 for proof of correctness + 1 for time analysis.

Solution (iterative, 7/7): I’ll describe a simple iterative algorithm to identify one
member of the majority party in O(n) time; this algorithm was discovered by Robert
S. Boyer and J Strother Moore in 1980.³ After this algorithm runs, we can identify all
members of the majority party in O(n) additional time, by introducing the chosen
representative to everyone else.
BoyerMooreVote(D[1 .. n]):
count ← 0
for i ← 1 to n
if count = 0
winner ← i
count ← 1
else if SameParty(winner, i)
count ← count + 1
else
count ← count − 1
return winner

We can prove this algorithm correct as follows. At the end of the ith iteration of
the loop, the first i delegates can be partitioned into two (possibly empty) subsets:
• Exactly count members of winner’s party, and
• Exactly (i − count)/2 pairs of delegates, where the delegates in each pair are in
two different parties.
In particular, among the first i delegates, at most (i − count)/2 are not in winner’s
party. Thus, when the algorithm ends, at most (n − count)/2 ≤ n/2 delegates are
not in winner’s party. Since some party has strictly more than n/2 members (by
assumption), that must be the final winner’s party. „

Rubric: 7 points = 3 for correct algorithm + 3 for proof of correctness + 1 for time
analysis.

²In fact, the number of introductions is exactly n − #1(n), where #1(n) is the number of 1s in the binary
representation of n. This is the best possible.
³No, I’m not missing a period; J was Moore’s complete first name. Single-letter names are more common than most
people think; Jeff’s wife’s middle name is the letter H (no period). On the other hand, Jeff’s dad’s middle name is Jay.

6
CS/ECE 374 Homework 4 Solutions Fall 2016

Rubric (general for part (a)): These are not the only correct solutions, and these
solutions are more detailed than necessary for full credit. Partial credit for slower/more
limited solutions:
• 4 points for any algorithm that is correct and runs in O(n) time when there are
exactly two parties.
• 2 points for any correct O(n2 )-time (or slower) algorithm. Beware that many
algorithms run in quadratic time when the first n/4 delegates belong to distinct
parties.

(b) Now suppose precisely p political parties are present and one party has a plurality: more
delegates belong to that party than to any other party. Please present a procedure to pick
out the people from the plurality party as parsimoniously as possible. Do not assume that
p = O(1).

Solution: The following algorithm finds one member of the plurality party in O(n p)
time by brute force. We repeatedly find a delegate that is not already assigned to a
party, and introduce them to everyone. After p passes, we know the party of every
delegate.
OneInPlurality(D[1 .. n]):
for i ← 1 to n
Party[i] ← 0
maxCount ← 0
for j ← 1 to p
count ← 0
for i ← 1 to n
if Party[i] 6= 0
〈〈do nothing〉〉
else if Count[ j] = 0
Party[i] ← j
rep ← i
count ← count + 1
else if SameParty(i, rep)
Party[i] ← j
count ← count + 1
if maxCount < count
maxCount ← count
maxRep ← rep
return maxRep

We can find all members of the plurality party in O(n) additional time, by introduc-
ing the plurality representative to everyone else (or by more careful bookkeeping). „

Rubric: 3 points = 2 for algorithm + 1 for running time. This is not the only correct
solution, but it is the best possible running time. In particular, when p = n − 1, we must
introduce every pair of delegates in the worst case to find the single pair that is in the
same party.

Das könnte Ihnen auch gefallen