算法导论·动态规划·DNA距离
原书习题 15-5 第二部分
#encoding:utf-8
from collections import namedtuple
x = 'GATCGGCAT'
y = 'CAATGTGAATC'
x_ = [''] * (len(x)+len(y))
y_ = [''] * (len(x)+len(y))
costs = namedtuple('Costs',['copy','replace','delete','insert','twiddle','kill'])(-1,float('inf'),2,2,float('inf'),float('inf'))
m = len(x)
n = len(y)
i = j = 0 # pointers to src strs x and y
i_ = j_ = 0 # pointer to dist strs x_ and y_
def copy():
global x,y,x_,y_,i,j,i_,j_,costs
x_[i_] = y_[j_] = x[i]
i += 1
j += 1
i_ += 1
j_ += 1
def replace():
raise Exception('No replace')
def delete():
global x,y,x_,y_,i,j,i_,j_,costs
x_[i_]=x[i]
y_[j_] = ' '
i += 1
i_ += 1
j_ += 1
# j += 1
def insert():
global x,y,x_,y_,i,j,i_,j_,costs
x_[i_] = ' '
y_[j_] = y[j]
# i += 1
j += 1
i_ += 1
j_ += 1
def twiddle():
raise Exception('No twiddle')
def kill():
raise Exception('No kill')
def finish():
global x,y,x_,y_
# print (x,y)
print (''.join(x_))
print (''.join(y_))
def dynamic_prog():
global x,y,m,n,costs,i,j,x_,y_
EMPTY = (0,'',None)
MAX = (float('inf'),'',None)
FINISH = (0,'finish',None)
memo = {}#(i,j)->(cost,op,next_node)
memo[(m,n)] = FINISH
def get_memo(i_,j_):
if i_>m or j_>n:
return MAX
return memo[(i_,j_)]
# while i>=0 and j >= 0:
for i_ in range(m,-1,-1):
for j_ in range(n,-1,-1):
print(i_,j_)
if i_ == m and j_ == n:
continue
min_cost = MAX
if i_ < m and j_ < n and x[i_] == y[j_]:
c = costs.copy + get_memo(i_+1,j_+1)[0]
if c<min_cost[0]:
min_cost = (c,'copy',(i_+1,j_+1))
if i_ < m and j_ < n:
c = costs.replace + get_memo(i_+1,j_+1)[0]
if c<min_cost[0]:
min_cost = (c,'replace',(i_+1,j_+1))
if j_ < n:
c = costs.insert + get_memo(i_,j_+1)[0]
if c<min_cost[0]:
min_cost = (c,'insert',(i_,j_+1))
if i_ < m:
c = costs.delete + get_memo(i_+1,j_)[0]
if c<min_cost[0]:
min_cost = (c,'delete',(i_+1,j_))
if i_ < m - 1 and j_ < n - 1 and x[i_] == y[j_+1] and x[i_+1] == y[j_]:
c = costs.twiddle + get_memo(i_+2,j_+2)[0]
if c<min_cost[0]:
min_cost = (c,'twiddle',(i_+2,j_+2))
if i_ == n:
c = costs.kill
if c<min_cost[0]:
min_cost = (c,'kill',(m,n))
memo[i_,j_] = min_cost
#output the result
p = get_memo(0,0)
while p[2] != None:
eval('{}()'.format(p[1]))
print(p,'\n\tx_:[{}],\n\ty_:[{}]'.format(''.join(x_),''.join(y_)))
p = get_memo(*p[2])
finish()
if __name__ == '__main__':
# memoization()
dynamic_prog()