CLRS第十五章思考题5-8

###思考题15-5
a)这个问题有点类似最长公共子序列,因此类似的定义 X i = x [ 1 , 2... i ] , Y j = y [ 1 , 2... j ] X_i=x[1,2...i],Y_j=y[1,2...j] Xi=x[1,2...i],Yj=y[1,2...j]。子问题就是确定一个最优操作序列使得 X i X_i Xi 转换为 Y j Y_j Yj,其中 0 ≤ i ≤ m , 0 ≤ j ≤ n 0\le i\le m,0\le j\le n 0im,0jn。原始的问题是 X m → Y n X_m\rightarrow Y_n XmYn
c [ i , j ] c[i,j] c[i,j] X i → Y j X_i\rightarrow Y_j XiYj 的一个最优解决代价,然后有:

  1. 最后一步是复制操作,则必有 x [ i ] = y [ j ] x[i]=y[j] x[i]=y[j],子问题就变成 X i − 1 → Y j − 1 X_{i-1}\rightarrow Y_{j-1} Xi1Yj1 X i → Y j X_i\rightarrow Y_j XiYj 的最优解一定包括 X i − 1 → Y j − 1 X_{i-1}\rightarrow Y_{j-1} Xi1Yj1 的最优解。因此有 c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( c o p y ) c[i,j]=c[i-1,j-1]+cost(copy) c[i,j]=c[i1,j1]+cost(copy)

  2. 最后一步是替换操作,则必有 x [ i ] ≠ y [ j ] x[i]\ne y[j] x[i]̸=y[j],同时假定替换操作不能替换成要被替换的字符本身,比如不能把字符 a a a 替换成字符 a a a。所以 c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( r e p l a c e ) c[i,j]=c[i-1,j-1]+cost(replace) c[i,j]=c[i1,j1]+cost(replace)

  3. 最后一步是旋转操作,则有 x [ i ] = y [ j − 1 ] , x [ i − 1 ] = y [ j ] x[i]=y[j-1],x[i-1]=y[j] x[i]=y[j1],x[i1]=y[j],同时也隐含了 i , j ≥ 2 i,j\ge 2 i,j2。子问题就变成了 X i − 2 → Y j − 2 X_{i-2}\rightarrow Y_{j-2} Xi2Yj2,此时有 c [ i , j ] = c [ i − 2 , j − 2 ] + c o s t ( t w i d d l e ) c[i,j]=c[i-2,j-2]+cost(twiddle) c[i,j]=c[i2,j2]+cost(twiddle)

  4. 最后一步是删除操作,对 x , y x,y x,y 没有限制,子问题就变成了 X i − 1 → Y j X_{i-1}\rightarrow Y_j Xi1Yj,得 c [ i , j ] = c [ i − 1 , j ] + c o s t ( d e l e t e ) c[i,j]=c[i-1,j]+cost(delete) c[i,j]=c[i1,j]+cost(delete)

  5. 最后一步是插入操作,对 x , y x,y x,y 没有限制。子问题就变成了 X i → Y j − 1 X_i\rightarrow Y_{j-1} XiYj1,得 c [ i , j ] = c [ i , j − 1 ] + c o s t ( i n s e r t ) c[i,j]=c[i,j-1]+cost(insert) c[i,j]=c[i,j1]+cost(insert)

  6. 最后一步是终止操作,我们必须完成 X m → Y n X_m\rightarrow Y_n XmYn,也就是说必须是 i = m , j = n i=m,j=n i=m,j=n。终止操作可以看成是多次的删除操作,子问题变成 X i → Y n , 0 ≤ i &lt; m X_i\rightarrow Y_n,0\le i&lt;m XiYn,0i<m。得 c [ m , n ] = min ⁡ 0 ≤ i &lt; m { c [ i , n ] + c o s t ( k i l l ) } c[m,n]=\min \limits_{0\le i&lt;m}\{c[i,n]+cost(kill)\} c[m,n]=0i<mmin{c[i,n]+cost(kill)}

最后来处理基本的情况,即 i = 0 i=0 i=0 或者 j = 0 j=0 j=0 X 0 , Y 0 X_0,Y_0 X0,Y0 都是空串,从 X 0 → Y j X_0\rightarrow Y_j X0Yj 只需插入 j j j 次即可,所以 c [ 0 , j ] = j ⋅ c o s t [ i n s e r t ] c[0,j]=j·cost[insert] c[0,j]=jcost[insert],类似的 X i → Y 0 X_i\rightarrow Y_0 XiY0 只需删除 i i i 次即可, c [ i , 0 ] = i ⋅ c o s t [ d e l e t e ] c[i,0]=i·cost[delete] c[i,0]=icost[delete]。然后 c [ 0 , 0 ] = 0 c[0,0]=0 c[0,0]=0

总结就是如下:
c [ i , j ] = min ⁡ { c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( c o p y ) if x[i]=y[j] c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( r e p l a c e ) if x[i]!= y[j] c [ i , j ] = c [ i − 2 , j − 2 ] + c o s t ( t e i d d l e ) if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j] c [ i , j ] = c [ i − 1 , j ] + c o s t ( d e l e t e ) c [ i , j ] = c [ i , j − 1 ] + c o s t ( i n s e r t ) c [ m , n ] = min ⁡ 0 ≤ i &lt; m { c [ i , n ] + c o s t ( k i l l ) } if i=m,j=n c[i,j]=\min \begin{cases} c[i,j]=c[i-1,j-1]+cost(copy)&amp; \text{if x[i]=y[j]}\\ c[i,j]=c[i-1,j-1]+cost(replace)&amp; \text{if x[i]!= y[j]}\\ c[i,j]=c[i-2,j-2]+cost(teiddle)&amp; \text{if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j]}\\ c[i,j]=c[i-1,j]+cost(delete)\\ c[i,j]=c[i,j-1]+cost(insert)\\ c[m,n]=\min \limits_{0\le i&lt;m}\{c[i,n]+cost(kill)\} &amp; \text{if i=m,j=n} \end{cases} c[i,j]=minc[i,j]=c[i1,j1]+cost(copy)c[i,j]=c[i1,j1]+cost(replace)c[i,j]=c[i2,j2]+cost(teiddle)c[i,j]=c[i1,j]+cost(delete)c[i,j]=c[i,j1]+cost(insert)c[m,n]=0i<mmin{c[i,n]+cost(kill)}if x[i]=y[j]if x[i]!= y[j]if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j]if i=m,j=n
类似 LCS,按行优先开始计算。

EDIT-DISTANCE(x, y,m, n)
	let c[0...m, 0...n] and op[0...m, 0...n] be new arrays
	for i = 0 to m
		c[i, 0] = i·cost(delete)
		op[i, 0] = DELETE
	for j = 0 to n
		c[0, j] = j cost(insert)
		op[0, j] = INSERT
	for i = 1 to m
		for j = 1 to n
			c[i, j] = ∞ 
			if x[i] == y[j] 
				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]
				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]
				c[i, j]  = c[i-2, j-2] + cost(twiddle)
				op[i, j]  = TWIDDLE
			if c[i-1, j] + cost(delete) < c[i, j]
				c[i, j] = c[i-1, j] + cost(delete)
				op[i, j] = DELETE
			if c[i, j-1] + cost(insert) < c[i, j] 
				c[i, j] = c[i, j-1] + cost(insert)
				op[i, j] = INSERT(y[j])
	for i = 0 to m - 1
		if c[i, n] + cost(kill) < c[m, n]
			c[m, n] = c[i, n] + cost(kill)
			op[m, n] = KILL i
	return c and op

时空复杂度都是 Θ ( m n ) \Theta(mn) Θ(mn),若要保存 KILL 操作,还需要保存 killed 操作的下标 i 来帮助我们重建最优操作序列。

OP-SEQUENCE(op, i, j)
	if i == 0 and j == 0
		return
	if op[i, j] == COPY or op[i, j] == REPLACE
		i' = i-1
		j' = j-1
	elseif op[i, j] == TWIDDLE
		i' = i-2
		j' = j-2
	elseif op[i, j] == DELETE
		i' = i-1
		j' = j
	elseif op[i, j] == INSERT // don’t care yet what character is inserted
		i' = i
		j' = j-1
	else // must be KILL, and must have i = m and j = n
		let op[i, j]  == KILL k
		i' = k
		j' = j
	OP-SEQUENCE(op, i', j')
	print op[i, j] 

b)只允许下面四种操作,其余两种操作禁止。
cost(copy) = -1 ;
cost(replace) = +1 ;
cost(delete) = +2 ;
cost(insert) = +2 ;

因此 DNA 对齐问题就转换为求最小化编辑距离代价的负数。

###思考题15-6
使用动态规划,令 c [ x ] c[x] c[x] 表示员工 x x x 的交际评分,我们希望找出所有员工的子集 S S S 使得当 x ∈ S   且   p a r e n t [ x ] ∉ S x\in S\ 且\ parent[x]\notin S xS  parent[x]/S 时有最大的 ∑ x ∈ S c [ x ] \sum \limits_{x\in S}c[x] xSc[x]
M ( x ) M(x) M(x) 表示以 x x x 为根节点的子树且 x x x 被邀请时的最大交际评分, M ′ ( x ) M&#x27;(x) M(x) 表示以 x x x 为根节点的子树且 x x x 不被邀请时的最大交际评分,然后得到:
M ( x ) = c [ x ] + ∑ y ∈ ( p a r e n t [ y ] = x ) M ′ ( y ) M ′ ( x ) = ∑ y ∈ ( p a r e n t [ y ] = x ) max ⁡ { M ( y ) , M ′ ( y ) } M(x)=c[x]+\sum \limits_{y\in (parent[y]=x)}M&#x27;(y)\\M&#x27;(x)=\sum \limits_{y\in (parent[y]=x)}\max \{M(y),M&#x27;(y)\} M(x)=c[x]+y(parent[y]=x)M(y)M(x)=y(parent[y]=x)max{M(y),M(y)}
上面的第一个式子表示员工 x x x 的交际评分以及 x x x 的直接下属 y y y 不被邀请时以 y y y 为根节点的子树的交际评分;第二个式子表示从员工 x x x 的直接下属(不包括 x x x)中邀请以员工 y y y 为根节点的子树的交际评分的最大值。

solve(x)
	M(x) = c[x]
	M'(x) = 0
	y = left-child[x]
	while y ≠ NIL
		do solve(y)
			M(x) = M(x) + M'(y)
			M'(x) = M'(x) + max{M(y),M'(y)}
			y = right-child[y]

以公司主席开始调用solve函数。接下来决定邀请人员名单。

invite(x)
	if M(x) > M'(x)
		then invite x to the party
			for all grandchildren y of x
				invite(y)
	else 
		for all children y of x
			invite(y)

最后的时间复杂度就是 O ( n ) O(n) O(n)

###思考题15-7
略,提供一个链接,有兴趣的可以看一看这里写链接内容

###思考题15-8
a) 令当前被删除的是 A [ i , j ] A[i,j] A[i,j],则第 i + 1 i+1 i+1 行应该怎么删除像素呢?当 A [ i , j ] A[i,j] A[i,j] 处于列边界时( i = 1 或 者 i = n i=1或者i=n i=1i=n),比如 i = 1 i=1 i=1,此时只有两种选择 A [ i + 1 , j ] A[i+1,j] A[i+1,j] A [ i + 1 , j + 1 ] A[i+1,j+1] A[i+1,j+1]。其他情况下都可以有三种删除像素的选择: A [ i + 1 , j − 1 ] , A [ i + 1 , j ] , A [ i + 1 , j + 1 ] A[i+1,j-1],A[i+1,j],A[i+1,j+1] A[i+1,j1],A[i+1,j],A[i+1,j+1]。也就是说对某一行的像素 p p p 来说,下一行的选择至少有两种。令 T ( i ) T(i) T(i) 表示从第 1 1 1 行到第 i i i 行可能的接缝数。当 i = 1 i=1 i=1 T ( 1 ) = n T(1)=n T(1)=n。当 i &gt; n i&gt;n i>n 时有: T ( i ) ≥ 2 T ( i − 1 ) T(i)\ge 2T(i-1) T(i)2T(i1),很容易计算得 T ( i ) = n 2 i − 1 T(i)=n2^{i-1} T(i)=n2i1。因此 T ( m ) = n 2 m − 1 T(m)=n2^{m-1} T(m)=n2m1

b) 令 d i s r [ i , j ] disr[i,j] disr[i,j] 为从 A [ i , j ] A[i,j] A[i,j] 开始的所有接缝中选择出来的接缝破坏度之和最小的一条接缝的值。基础情况是 d i s r [ m , j ] = d [ m , j ] , j = 1 , 2... n disr[m,j]=d[m,j],j=1,2...n disr[m,j]=d[m,j],j=1,2...n,递归情况下有: d i s r [ i , j ] = d [ i , j ] + min ⁡ k ∈ K { d i s r [ i + i , j + k ] } disr[i,j]=d[i,j]+\min \limits_{k\in K}\{disr[i+i,j+k]\} disr[i,j]=d[i,j]+kKmin{disr[i+i,j+k]} K K K 的取值如下:
K = { { 0 , 1 } if j=1 { − 1 , 0 , 1 } if 1&lt;j&lt;m { − 1 , 0 } if j=m K= \begin{cases} \{0,1\}&amp; \text{if j=1}\\ \{-1,0,1\}&amp; \text{if 1&lt;j&lt;m}\\ \{-1,0\}&amp; \text{if j=m} \end{cases} K={0,1}{1,0,1}{1,0}if j=1if 1<j<mif j=m
因此我们只用得到最小化的 d i s r [ 1 , j ] disr[1,j] disr[1,j] 即可。

COMPRESS-IMAGE(d)
	m = d.rows
	n = d.columns
	let disr[1..m, 1..n] and next[1..m, 1..n] be new tables
	for j = 1 to n
		disr[m, j] = d[m, j]
	for i = m - 1 downto 1
		for j = 1 to n
			low = max(-1, 1-j)
			high = min(1, n-j)
			disr[i, j] = ∞
			for k = low to high
				if disr[i + 1, j + k] < disr[i, j] 
					disr[i, j] = disr[i + 1, j + k]
					next[i, j] = j + k
			disr[i, j] = disr[i, j] + d[i, j]
			val = ∞
			start = 1
			for j = 1 to n
				if disr[1, j] < val
					val = disr[1, j]
					start = j
			print “The minimum value of the disruptive measure is ” val
			for i = 1 to m
				print “cut point at ” (i, start)
				start = next[i, start]

最后时间和空间复杂度都是 O ( m n ) O(mn) O(mn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值