我知道这是一个有点老生常谈的话题,但我已经达到了从已经回答的内容中获得的帮助的极限。
这是针对Rosalind 项目问题 LREP的。我正在尝试在字符串中找到最长的 k-peated 子字符串,并且已经为我提供了后缀树,这很好。我知道我需要用每个节点的后代叶子的数量来注释后缀表,然后找到具有>=k
后代的节点,最后找到这些节点中最深的。从理论上讲,我已经准备好了。
我从以下资源中获得了很多帮助(哎呀,我只能发布 2 个):
我可以获取从根到每个叶子的路径,但我不知道如何预处理树,以便我可以从每个节点获取后代的数量。我有一个单独的算法,它适用于小序列,但它具有指数复杂性,所以对于较大的东西,它需要的时间太长了。我知道使用 DFS 我应该能够以线性复杂度执行整个任务。为了使这个算法起作用,我需要能够在不到 5 分钟的时间内获得最长的 k-peat 的 ~40,000 长度的字符串。
这是一些示例数据(第一行:sequence
,第二行:k
,后缀表格式:parent child location length
):
CATACATAC$
2
1 2 1 1
1 7 2 1
1 14 3 3
1 17 10 1
2 3 2 4
2 6 10 1
3 4 6 5
3 5 10 1
7 8 3 3
7 11 5 1
8 9 6 5
8 10 10 1
11 12 6 5
11 13 10 1
14 15 6 5
14 16 10 1
输出应该是CATAC
.
使用以下代码(从LiteratePrograms修改)我已经能够获取路径,但是在更长的序列上仍然需要很长时间才能解析出每个节点的路径。
#authors listed at
#http://en.literateprograms.org/Depth-first_search_(Python)?action=history&offset=20081013235803
class Vertex:
def __init__(self, data):
self.data = data
self.successors = []
def depthFirstSearch(start, isGoal, result):
if start in result:
return False
result.append(start)
if isGoal(start):
return True
for v in start.successors:
if depthFirstSearch(v, isGoal, result):
return True
# No path was found
result.pop()
return False
def lrep(seq,reps,tree):
n = 2 * len(seq) - 1
v = [Vertex(i) for i in xrange(n)]
edges = [(int(x[0]),int(x[1])) for x in tree]
for a, b in edges:
v[a].successors.append(v[b])
paths = {}
for x in v:
result = []
paths[x.data] = []
if depthFirstSearch(v[1], (lambda v: v.data == x.data), result):
path = [u.data for u in result]
paths[x.data] = path
我想做的是descendants >= k
在找到深度之前对树进行预处理以找到满足要求的节点。我什至还没有弄清楚我将如何计算深度。虽然我想我会有一些字典来跟踪路径中每个节点的深度然后求和。
所以,我的第一个最重要的问题是:“我如何预处理带有后代叶子的树?”
我的第二个不那么重要的问题是:“在那之后,我怎样才能快速计算深度?”
PS我应该声明这不是家庭作业或类似的东西。我只是一个生物化学家,试图通过一些计算挑战来扩展我的视野。