Download Solution to Problems - Foundation in Engineering, Mathematics | ENEE 641 and more Assignments Electrical and Electronics Engineering in PDF only on Docsity!
Solution to Problem 15-
Note: we will assume that no word is longer than will fit into a line, i.e., l i ≤ M for all i. First, we’ll make some definitions so that we can state the problem more uniformly. Special cases about the last line and worries about whether a sequence of words fits in a line will be handled in these definitions, so that we can forget about them when framing our overall strategy.
• Define extras [ i , j ] = M − j + i − ∑ kj = ilk to be the number of extra spaces at the end of a line
containing words i through j. Note that extras may be negative.
- Now define the cost of including a line containing words i through j in the sum, we want to minimize:
3
[ , ] 0(. ., ,..., ' ),
[ , ] 0 , [ , ] 0( cos 0),
( [ , ]).
if extras i j i e words i j don t fit
lc i j if j n and extras i j last line ts
extras i j otherwise
By making the line cost infinite when the words don’t fit on it, we prevent such an arrangement from being part of a minimal sum, and by making the cost 0 for the last line (if the words fit), we prevent the arrangement of the last line from influencing the sum being minimized.
We want to minimize the sum of lc over all lines of the paragraph.
Our subproblems are how to optimally arrange words 1 , … , j , where j =1,… , n.
Consider an optimal arrangement of words 1 , … , j. Suppose we know that the last line, which
ends in word j , begins with word i. The preceding lines, therefore, contain words 1 , … , i − 1. In
fact, they must contain an optimal arrangement of words 1 , … , i − 1. (Insert your favorite cut-and-
paste argument here.)
Let c [ j ] be the cost of an optimal arrangement of words 1 , … , j. If we know that
the last line contains words i , … , j , then c [ j ] = c [ i −1]+ lc [ i , j ]. As a base case, when we’re
computing c [1], we need c [0]. If we set c [0] = 0, then c [1] = lc [1 , 1], which is what we want.
But of course we have to figure out which word begins the last line for the subproblem of words
1 , … , j. So we try all possibilities for word i , and we pick the one that gives the lowest cost. Here,
i ranges from 1 to j. Thus, we can define c [ j ] recursively by
1
[ ] min ( [ 1] [ , ]) 0.
i j
if j
c j c i lc i j if j
≤ ≤
Note that the way we defined lc ensures that
- all choices made will fit on the line (since an arrangement with lc =∞ cannot be chosen as the minimum), and
- the cost of putting words i , … , j on the last line will not be 0 unless this really is the last line of
the paragraph ( j = n ) or words i... j fill the entire line.
We can compute a table of c values from left to right, since each value depends only on earlier values. To keep track of what words go on what lines, we can keep a parallel p table that points to
where each c value came from. When c [ j ] is computed, if c [ j ] is based on the value of c [ k − 1], set p [ j ] = k. Then after c [ n ] is computed, we can trace the pointers to see where to break the lines. The last line starts at word p [ n ] and goes through word n. The previous line starts at word p [ p [ n ]] and goes through word p [ n ] − 1, etc. In pseudocode, here’s how we construct the tables:
P RINT -NEATLY ( l , n , M )
> Compute extras [ i , j ] for 1 ≤ i ≤ j ≤ n.
for i ← 1 to n
do extras [ i , i ] ← M − l i
for j ← i + 1 to n
do extras [ i , j ]← extras [ i , j − 1] − l j − 1
> Compute lc [ i , j ] for 1 ≤ i ≤ j ≤ n.
for i ← 1 to n do for j ← i to n
do if extras [ i , j ] < 0
then lc [ i , j ]←∞
elseif j = n and extras [ i , j ] ≥ 0
then lc [ i , j ] ← 0
else lc [ i , j ] ←( extras [ i , j ] )^3
> Compute^ c [^ j ] and^ p [^ j ] for 1^ ≤^ j^ ≤^ n.
c [0] ← 0 for j ← 1 to n do c [ j ]←∞ for i ← 1 to j
do if c [ i − 1] + lc [ i , j ] < c [ j ]
then c [ j ] ← c [ i − 1] + lc [ i , j ]
p [ j ] ← i return c and p
Quite clearly, both the time and space are Θ(^ n^2 ).
In fact, we can do a bit better: we can get both the time and space down to Θ( nM ).
The key observation is that at most ⎡⎢ M / 2⎤⎥ words can fit on a line. (Each word is at least one
character long, and there’s a space between words.) Since a line with words i ,... , j contains j −
i + 1 words, if j − i + 1 > ⎡⎢ M / 2⎤⎥then we know that lc [ i , j ] = ∞. We need only compute and
the X i → Y j problem must include an optimal solution to the X i − 1 → Y j − 1 problem. The cut-and-paste argument applies. Thus, assuming that the last
operation was a copy, we have c [ i , j ] = c [ i − 1 , j − 1] + cost (copy ).
- If it was a replace, then we must have had x [ i ] ≠ y [ j ]. (Here, we assume that we cannot replace a character with itself. It is a straightforward modification if we allow replacement of a character with itself.) We have the same optimal substructure argument as for copy, and assuming that the last operation was
a replace, we have c [ i , j ] = c [ i − 1 , j − 1] + cost (replace ).
- If it was a twiddle, then we must have had x [ i ] = y [ j − 1] and x [ i − 1] = y [ j ], along with
the implicit assumption that i , j ≥ 2. Now our sub-problem
is X i − 2 → Y j − 2 and, assuming that the last operation was a twiddle, we have
c [ i , j ] = c [ i − 2 , j − 2] + cost (twiddle ).
- If it was a delete, then we have no restrictions on x or y. Since we can view delete as removing a character from X i and leaving Yj alone, our sub-problem is X i − 1 → Y j. Assuming that the last operation was a delete, we have
c [ i , j ] = c [ i − 1 , j ] + cost (delete ).
- If it was an insert, then we have no restrictions on x or y. Our sub-problem is X i → Y j − 1. Assuming that the last operation was an insert, we have
c [ i , j ] = c [ i , j − 1] + cost (insert ).
- If it was a kill, then we had to have completed converting X m to Yn , so that the current problem must be the X m → Y n problem. In other words, we must have i = m and j = n. If we think of a kill as a multiple delete, we can get
any Xi → Y n , where 0 ≤ i < m , as a sub-problem. We pick the best one,
and so assuming that the last operation was a kill, we have
c [ m , n ] = min 0 ≤ i < m { c [ i , n ]} + cost (kill ).
We have not handled the base cases, in which i = 0 or j = 0. These are easy. X 0 and Y 0 are the empty strings. We convert an empty string into Y j by
a sequence of j inserts, so that c [0 , j ] = j · cost (insert ). Similarly, we convert
X i into Y 0 by a sequence of i deletes, so that c [ i , 0] = i · cost (delete ). When
i = j = 0, either formula gives us c [0 , 0] = 0, which makes sense, since
there’s no cost to convert the empty string to the empty string.
For i , j > 0, our recursive formulation for c [ i , j ] applies the above formulas in
the situations in which they hold:
c[i - 1, j - 1] + cost(copy) if x[i ] = y[ j ] ,
c[i - 1, j - 1] + cost(replace) if x[i ] y[ j ] ,
c[i - 2, j - 2] + cost(twiddle) if i, j 2,x[i ] = y[ j -1],and x[i -1] = y[ j ] ,
c[i, j ] = min c[i
0 i<m
- 1, j ] + cost(delete) always ,
c[i, j -1] + cost(insert) always,
min {c[i, n]} + cost(kill) ≤ if i = m and j = n.
Like we did for LCS, our pseudocode fills in the table in row-major order, i.e., row-by-row from top to bottom, and left to right within each row. Column-major order (column-by-column from left to right, and top to bottom within
each column) would also work. Along with the c [ i , j ] table, we fill in the table
op [ i , j ], holding which operation was used.
E DIT -DISTANCE ( x , y , m , n )
for i ← 0 to m
do c [ i , 0] ← i · cost (delete )
op [ i , 0] ← DELETE
for j ← 0 to n
do c [0 , j ] ← j · cost (insert )
op [0 , j ] ← INSERT
for i ← 1 to m do for j ← 1 to n
do c [ i , j ]←∞
if x [ i ] = y [ j ]
then c [ i , j ] ← c [ i − 1 , j − 1] + cost (copy )
op [ i , j ] ← COPY
if x [ i ] ≠ y [ j ] and c [ i − 1 , j − 1] + cost (replace ) < c [ i , j ]
then c [ i , j ] ← c [ i − 1 , j − 1] + cost (replace )
op [ i , j ] ← REPLACE (by y [ j ])
if i ≥ 2 and j ≥ 2 and x [ i ] = y [ j − 1] and x [ i − 1] = y [ j ] and
c [ i − 2 , j − 2] + cost (twiddle ) < c [ i , j ]
then c [ i , j ] ← c [ i − 2 , j − 2] + cost (twiddle )
op [ i , j ] ← TWIDDLE
if c [ i − 1 , j ] + cost (delete ) < c [ i , j ]
then c [ i , j ] ← c [ i − 1 , j ] + cost (delete )
i ‘ ← k
j ‘ ← j
OP -S EQUENCE ( op , i ‘ , j ‘ )
print op [ i , j ]
This procedure determines which subproblem we used, recurses on it, and then prints its own last operation. b. The DNA-alignment problem is just the edit-distance problem, with
cost (copy ) = − 1 ,
cost (replace ) = + 1 ,
cost (delete ) = + 2 ,
cost (insert ) = + 2 ,
and the twiddle and kill operations are not permitted. The score that we are trying to maximize in the DNA-alignment problem is precisely the negative of the cost we are trying to minimize in the edit-distance problem. The negative cost of copy is not an impediment, since we can only apply the copy operation when the characters are equal.
Solution to Exercise 16.1-
Let S be the set of n activities. The “obvious” solution of using G REEDY -ACTIVITY -S ELECTOR to find a maximum- size set S 1 of compatible activities from S for the first lecture hall, then using it again to find a maximum-size set S 2 of compatible activities from S − S 1 for the
second hall, (and so on until all the activities are assigned), requires Θ( n^2 )time
in the worst case. Moreover, it can produce a result that uses more lecture halls
than necessary. Consider activities with the intervals {[1 , 4 ), [2 , 5 ), [6 , 7 ), [4 , 8 )}.
GREEDY -ACTIVITY -S ELECTOR would choose the activities with intervals [1 , 4 )
and [6 , 7 ) for the first lecture hall, and then each of the activities with intervals
[2 , 5 ) and [4 , 8 ) would have to go into its own hall, for a total of three halls used.
An optimal solution would put the activities with intervals [1 , 4 ) and [4 , 8 ) into one
hall and the activities with intervals [2 , 5 ) and [6 , 7 ) into another hall, for only two
halls used. There is a correct algorithm, however, whose asymptotic time is just the time
needed to sort the activities by time— O ( n lg n ) time for arbitrary times, or possibly
as fast as O ( n ) if the times are small integers.
The general idea is to go through the activities in order of start time, assigning each to any hall that is available at that time. To do this, move through the set of events consisting of activities starting and activities finishing, in order of event
time. Maintain two lists of lecture halls: Halls that are busy at the current event-time t (because they have been assigned an activity i that started at si ≤ t but
won’t finish until f i > t ) and halls that are free at time t. (As in the activity-selection
problem in Section 16.1, we are assuming that activity time intervals are half open—i.e., that if si ≥ f j , then activities i and j are compatible.) When t is the start time of some activity, assign that activity to a free hall and move the hall from the free list to the busy list. When t is the finish time of some activity, move the activity’s hall from the busy list to the free list. (The activity is certainly in some hall, because the event times are processed in order and the activity must have started before its finish time t , hence must have been assigned to a hall.) To avoid using more halls than necessary, always pick a hall that has already had an activity assigned to it, if possible, before picking a never-used hall. (This can be done by always working at the front of the free-halls list—putting freed halls onto the front of the list and taking halls from the front of the list—so that a new hall doesn’t come to the front and get chosen if there are previously-used halls.) This guarantees that the algorithm uses as few lecture halls as possible: The algorithm will terminate with a schedule requiring m ≤ n lecture halls. Let activity i be the first activity scheduled in lecture hall m. The reason that i was put in the m- th lecture hall is that the first m − 1 lecture halls were busy at time si. So at this time there are m activities occurring simultaneously. Therefore any schedule must use at least m lecture halls, so the schedule returned by the algorithm is optimal.
Run time:
- Sort the 2 n activity-starts/activity-ends events. (In the sorted order, an activity-ending
event should precede an activity-starting event that is at the same time.) O ( n lg n ) time for
arbitrary times, possibly O ( n ) if the times are restricted (e.g., to small integers).
- Process the events in O ( n ) time: Scan the 2 n events, doing O ( 1 ) work for each (moving a hall from one list to the other and possibly associating an activity with it).
Total: O ( n + time to sort )
[The idea of this algorithm is related to the rectangle-overlap algorithm in Exercise 14.3-7.]
Solution to Exercise 16.2-
The solution is based on the optimal-substructure observation in the text: Let i be the highest-
numbered item in an optimal solution S for W pounds and items 1 , … , n. Then S ‘ = S − { i } must
be an optimal solution for W − ω i pounds and items 1 , … , i − 1, and the value of the solution S is
vi plus the value of the subproblem solution S ‘.
we continue tracing with c [ i − 1 , ω ]. Otherwise item i is part of the solution, and we continue tracing with c [ i − 1 , ω − ω i ].
The above algorithm takes Θ( nW ) time total:
- Θ( nW )to fill in the c table: ( n + 1 ) ·( W + 1 ) entries, each requiringΘ(1) time to compute.
- O ( n ) time to trace the solution (since it starts in row n of the table and moves up one row at each step).